From: yu.dongliang <18588496441@163.com>
Date: Thu, 6 Apr 2023 09:30:06 +0000 (+0800)
Subject: tmp
X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=cb0e1da98eef7db293163a7196df5c87df2bf054;p=simplay.git

tmp
---

cb0e1da98eef7db293163a7196df5c87df2bf054
diff --git a/scf_def.h b/scf_def.h
new file mode 100644
index 0000000..c735f34
--- /dev/null
+++ b/scf_def.h
@@ -0,0 +1,38 @@
+#ifndef SCF_DEF_H
+#define SCF_DEF_H
+
+#include<stdio.h>
+#include<stdint.h>
+#include<stdlib.h>
+#include<stddef.h>
+#include<string.h>
+#include<assert.h>
+#include<errno.h>
+#include<time.h>
+#include<unistd.h>
+#include<pthread.h>
+
+#if 1
+#include<sys/time.h>
+static inline int64_t gettime()
+{
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+
+	return tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+#endif
+
+#ifdef SCF_DEBUG
+#define scf_logd(fmt, ...) printf("%s(), %d, "fmt, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define scf_logd(fmt, ...)
+#endif
+
+#define scf_logi(fmt, ...) printf("%s(), %d, info: "fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#define scf_loge(fmt, ...) printf("%s(), %d, \033[31m error:\033[0m "fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define scf_logw(fmt, ...) printf("%s(), %d, \033[33m warning:\033[0m "fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#endif
+
diff --git a/scf_list.h b/scf_list.h
new file mode 100644
index 0000000..4b5812c
--- /dev/null
+++ b/scf_list.h
@@ -0,0 +1,81 @@
+#ifndef SCF_LIST_H
+#define SCF_LIST_H
+
+#include"scf_def.h"
+
+typedef struct scf_list_s	scf_list_t;
+
+struct scf_list_s {
+	struct scf_list_s*		prev;
+	struct scf_list_s*		next;
+};
+
+static inline void scf_list_init(scf_list_t* h)
+{
+	h->prev = h;
+	h->next = h;
+}
+
+static inline void scf_list_del(scf_list_t* n)
+{
+	n->prev->next = n->next;
+	n->next->prev = n->prev;
+
+	// only to avoid some wrong operations for these 2 invalid pointers
+	n->prev = NULL;
+	n->next = NULL;
+}
+
+static inline void scf_list_add_tail(scf_list_t* h, scf_list_t* n)
+{
+	h->prev->next = n;
+	n->prev = h->prev;
+	n->next = h;
+	h->prev = n;
+}
+
+static inline void scf_list_add_front(scf_list_t* h, scf_list_t* n)
+{
+	h->next->prev = n;
+	n->next = h->next;
+	n->prev = h;
+	h->next = n;
+}
+
+#define SCF_LIST_INIT(h)	{&h, &h}
+
+#define scf_list_data(l, type, member)	((type*)((char*)l - offsetof(type, member)))
+
+#define scf_list_head(h)		((h)->next)
+#define scf_list_tail(h)		((h)->prev)
+#define scf_list_sentinel(h)	(h)
+#define scf_list_next(l)		((l)->next)
+#define scf_list_prev(l)		((l)->prev)
+#define scf_list_empty(h)		((h)->next == (h))
+
+#define scf_list_clear(h, type, member, type_free) \
+	do {\
+		scf_list_t* l;\
+		for (l = scf_list_head(h); l != scf_list_sentinel(h);) {\
+			type* t = scf_list_data(l, type, member);\
+			l = scf_list_next(l);\
+			scf_list_del(&t->member);\
+			type_free(t);\
+			t = NULL;\
+		}\
+	} while(0)
+
+#define scf_list_mov(dst, src, type, member) \
+	do {\
+		scf_list_t* l;\
+		type*       t;\
+		for (l = scf_list_head(src); l != scf_list_sentinel(src);) {\
+			t  = scf_list_data(l, type, member);\
+			l  = scf_list_next(l);\
+			scf_list_del(&t->member);\
+			scf_list_add_tail(dst, &t->member);\
+		}\
+	} while(0)
+
+#endif
+
diff --git a/scf_vector.h b/scf_vector.h
new file mode 100644
index 0000000..d4249ca
--- /dev/null
+++ b/scf_vector.h
@@ -0,0 +1,198 @@
+#ifndef SCF_VECTOR_H
+#define SCF_VECTOR_H
+
+#include"scf_def.h"
+
+typedef struct {
+	int		capacity;
+	int		size;
+	void**	data;
+} scf_vector_t;
+
+#undef  NB_MEMBER_INC
+#define NB_MEMBER_INC	16
+
+static inline scf_vector_t* scf_vector_alloc()
+{
+	scf_vector_t* v = calloc(1, sizeof(scf_vector_t));
+	if (!v)
+		return NULL;
+
+	v->data = calloc(NB_MEMBER_INC, sizeof(void*));
+	if (!v->data) {
+		free(v);
+		v = NULL;
+		return NULL;
+	}
+
+	v->capacity = NB_MEMBER_INC;
+	return v;
+}
+
+static inline scf_vector_t* scf_vector_clone(scf_vector_t* origin)
+{
+	scf_vector_t* clone = calloc(1, sizeof(scf_vector_t));
+	if (!clone)
+		return NULL;
+
+	clone->data = calloc(origin->capacity, sizeof(void*));
+	if (!clone->data) {
+		free(clone);
+		clone = NULL;
+		return NULL;
+	}
+
+	clone->capacity = origin->capacity;
+	clone->size		= origin->size;
+	memcpy(clone->data, origin->data, origin->size * sizeof(void*));
+	return clone;
+}
+
+static inline int scf_vector_cat(scf_vector_t* dst, scf_vector_t* src)
+{
+	if (!dst || !src)
+		return -EINVAL;
+
+	int size = dst->size + src->size;
+	if (size > dst->capacity) {
+
+		void* p = realloc(dst->data, sizeof(void*) * (size + NB_MEMBER_INC));
+		if (!p)
+			return -ENOMEM;
+
+		dst->data = p;
+		dst->capacity = size + NB_MEMBER_INC;
+	}
+
+	memcpy(dst->data + dst->size * sizeof(void*), src->data, src->size * sizeof(void*));
+	dst->size += src->size;
+	return 0;
+}
+
+static inline int scf_vector_add(scf_vector_t* v, void* node)
+{
+	if (!v || !v->data)
+		return -EINVAL;
+
+	assert(v->size <= v->capacity);
+
+	if (v->size == v->capacity) {
+		void* p = realloc(v->data, sizeof(void*) * (v->capacity + NB_MEMBER_INC));
+		if (!p)
+			return -ENOMEM;
+
+		v->data = p;
+		v->capacity += NB_MEMBER_INC;
+	}
+
+	v->data[v->size++] = node;
+	return 0;
+}
+
+static inline int scf_vector_del(scf_vector_t* v, void* node)
+{
+	if (!v || !v->data)
+		return -EINVAL;
+
+	assert(v->size <= v->capacity);
+
+	int i;
+	for (i = 0; i < v->size; i++) {
+
+		if (v->data[i] != node)
+			continue;
+
+		int j;
+		for (j = i + 1; j < v->size; j++)
+			v->data[j - 1] = v->data[j];
+
+		v->size--;
+
+		if (v->size + NB_MEMBER_INC * 2 < v->capacity) {
+			void* p = realloc(v->data, sizeof(void*) * (v->capacity - NB_MEMBER_INC));
+			if (p) {
+				v->data = p;
+				v->capacity -= NB_MEMBER_INC;
+			}
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+static inline void* scf_vector_find(const scf_vector_t* v, const void* node)
+{
+	int i;
+	for (i = 0; i < v->size; i++) {
+		if (node == v->data[i])
+			return v->data[i];
+	}
+	return NULL;
+}
+
+static inline int scf_vector_add_unique(scf_vector_t* v, void* node)
+{
+	if (!scf_vector_find(v, node))
+		return scf_vector_add(v, node);
+	return 0;
+}
+
+static inline void* scf_vector_find_cmp(const scf_vector_t* v, const void* node, int (*cmp)(const void*, const void*))
+{
+	int i;
+	for (i = 0; i < v->size; i++) {
+		if (0 == cmp(node, v->data[i]))
+			return v->data[i];
+	}
+	return NULL;
+}
+
+static inline int scf_vector_qsort(const scf_vector_t* v, int (*cmp)(const void*, const void*))
+{
+	if (!v || !v->data || 0 == v->size || !cmp)
+		return -EINVAL;
+
+	qsort(v->data, v->size, sizeof(void*), cmp);
+	return 0;
+}
+
+static inline void scf_vector_clear(scf_vector_t* v, void (*type_free)(void*))
+{
+	if (!v || !v->data)
+		return;
+
+	if (type_free) {
+		int i;
+		for (i = 0; i < v->size; i++) {
+			if (v->data[i]) {
+				type_free(v->data[i]);
+				v->data[i] = NULL;
+			}
+		}
+	}
+
+	v->size = 0;
+
+	if (v->capacity > NB_MEMBER_INC) {
+		void* p = realloc(v->data, sizeof(void*) * NB_MEMBER_INC);
+		if (p) {
+			v->data = p;
+			v->capacity = NB_MEMBER_INC;
+		}
+	}
+}
+
+static inline void scf_vector_free(scf_vector_t* v)
+{
+	if (v) {
+		if (v->data)
+			free(v->data);
+
+		free(v);
+		v = NULL;
+	}
+}
+
+#endif
+
diff --git a/simp.c b/simp.c
new file mode 100644
index 0000000..fe368e2
--- /dev/null
+++ b/simp.c
@@ -0,0 +1,124 @@
+#include"simp.h"
+
+static simp_avio_ops_t*  avio_array[] =
+{
+	NULL,
+};
+
+simp_frame_t* simp_frame_alloc()
+{
+	simp_frame_t* f = malloc(sizeof(simp_frame_t));
+	if (!f)
+		return NULL;
+
+	f->frame = av_frame_alloc();
+	if (!f->frame) {
+		free(f);
+		return NULL;
+	}
+
+	return f;
+}
+
+void simp_frame_free (simp_frame_t* f)
+{
+	if (f) {
+		if (f->frame)
+			av_frame_free(&f->frame);
+
+		free(f);
+	}
+}
+
+int simp_avio_open(simp_avio_t** pio, const char* type, const char* path)
+{
+	if (!pio || !type || !path)
+		return -EINVAL;
+
+	simp_avio_ops_t* ops = NULL;
+	simp_avio_t*     io  = NULL;
+
+	int i;
+	for (i = 0; avio_array[i]; i++) {
+
+		if (!strcmp(avio_array[i]->type, type)) {
+			ops =   avio_array[i];
+			break;
+		}
+	}
+
+	if (!ops)
+		return -EINVAL;
+
+	io = calloc(1, sizeof(simp_avio_t));
+	if (!io)
+		return -ENOMEM;
+
+	scf_list_init(&io->list);
+	scf_list_init(&io->vin);
+	scf_list_init(&io->ain);
+	scf_list_init(&io->vout);
+	scf_list_init(&io->aout);
+
+	io->width    = -1;
+	io->height   = -1;
+	io->channels = -1;
+
+	io->ops = ops;
+	if (ops->open) {
+
+		int ret = ops->open(io, path);
+		if (ret < 0) {
+			free(io);
+			return ret;
+		}
+	}
+
+	*pio = io;
+	return 0;
+}
+
+int simp_avio_close(simp_avio_t* io)
+{
+	if (io) {
+		if (io->ops && io->ops->close)
+			io->ops->close(io);
+
+		free(io);
+	}
+	return 0;
+}
+
+int simp_avio_run(simp_avio_t* io)
+{
+	if (io && io->ops && io->ops->run)
+		return io->ops->run(io);
+
+	return -EINVAL;
+}
+
+int simp_filter_open(simp_filter_t** pf)
+{
+
+}
+
+int simp_filter_close(simp_filter_t* f)
+{
+
+}
+
+int simp_filter_run(simp_filter_t* f)
+{
+
+}
+
+int simp_filter_add_input (simp_filter_t* f, simp_avio_t* input)
+{
+
+}
+
+int simp_filter_add_output(simp_filter_t* f, simp_avio_t* output)
+{
+
+}
+
diff --git a/simp.h b/simp.h
new file mode 100644
index 0000000..eb77bdd
--- /dev/null
+++ b/simp.h
@@ -0,0 +1,87 @@
+#ifndef SIMP_H
+#define SIMP_H
+
+#include"scf_list.h"
+
+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/avutil.h"
+#include "libavutil/opt.h"
+#include "libavfilter/avfilter.h"
+#include "libavfilter/buffersrc.h"
+#include "libavfilter/buffersink.h"
+
+typedef struct simp_avio_s       simp_avio_t;
+typedef struct simp_avio_ops_s   simp_avio_ops_t;
+
+typedef struct simp_frame_s      simp_frame_t;
+
+typedef struct simp_filter_s     simp_filter_t;
+
+
+struct simp_frame_s
+{
+	scf_list_t           list;
+	AVFrame*             frame;
+};
+
+struct  simp_avio_s
+{
+	scf_list_t           list;
+
+	scf_list_t           vin;
+	scf_list_t           ain;
+
+	scf_list_t           vout;
+	scf_list_t           aout;
+
+	int                  width;
+	int                  height;
+	enum AVPixelFormat   pix_fmt;
+	AVRational           frame_rate;
+
+	enum AVSampleFormat  sample_fmt;
+	AVRational           sample_rate;
+	int                  channels;
+
+	simp_avio_ops_t*     ops;
+	void*                priv;
+};
+
+struct  simp_filter_s
+{
+	scf_list_t           inputs;
+	scf_list_t           outputs;
+
+	AVFilterGraph*       graph;
+	AVFilterContext*     abuffersrc;
+	AVFilterContext*     abuffersink;
+	AVFilterContext*     vbuffersrc;
+	AVFilterContext*     vbuffersink;
+};
+
+struct  simp_avio_ops_s
+{
+	const char*          type;
+
+	int                (*open )(simp_avio_t* io, const char* path);
+	int                (*close)(simp_avio_t* io);
+	int                (*run  )(simp_avio_t* io);
+};
+
+simp_frame_t*  simp_frame_alloc();
+void           simp_frame_free (simp_frame_t* f);
+
+int simp_avio_open        (simp_avio_t**   pio, const char* type, const char* path);
+int simp_avio_close       (simp_avio_t*    io);
+int simp_avio_run         (simp_avio_t*    io);
+
+int simp_filter_open      (simp_filter_t** pf);
+int simp_filter_close     (simp_filter_t*  f);
+int simp_filter_run       (simp_filter_t*  f);
+
+int simp_filter_add_input (simp_filter_t*  f, simp_avio_t* input);
+int simp_filter_add_output(simp_filter_t*  f, simp_avio_t* output);
+
+#endif
+
diff --git a/simp_ffmpeg.c b/simp_ffmpeg.c
new file mode 100644
index 0000000..63f6777
--- /dev/null
+++ b/simp_ffmpeg.c
@@ -0,0 +1,239 @@
+#include"simp_ffmpeg.h"
+#include"scf_log.h"
+
+static int _video_init(simp_ffmpeg_t* priv)
+{
+	AVStream* s;
+	AVCodec*  c;
+
+	s = priv->fmt_ctx->streams[priv->vidx];
+
+	c = avcodec_find_decoder(s->codecpar->codec_id);
+	if (!c) {
+		scf_loge("decoder not found, codec_id: %d\n", s->codecpar->codec_id);
+		return -1;
+	}
+
+	priv->vdec_ctx = avcodec_alloc_context3(c);
+	if (!priv->vdec_ctx)
+		return -1;
+
+	int ret = avcodec_parameters_to_context(priv->vdec_ctx, s->codecpar);
+	if (ret < 0)
+		return -1;
+
+	ret = avcodec_open2(priv->vdec_ctx, c, NULL);
+	if (ret < 0) {
+		printf("avcodec_parameters_to_context error, ret: %d, %s\n", ret, av_err2str(ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int _audio_init(simp_ffmpeg_t* priv)
+{
+	AVStream* s;
+	AVCodec*  c;
+
+	s = priv->fmt_ctx->streams[priv->aidx];
+
+	c = avcodec_find_decoder(s->codecpar->codec_id);
+	if (!c) {
+		scf_loge("decoder not found, codec_id: %d\n", s->codecpar->codec_id);
+		return -1;
+	}
+
+	priv->adec_ctx = avcodec_alloc_context3(c);
+	if (!priv->adec_ctx)
+		return -1;
+
+	int ret = avcodec_parameters_to_context(priv->adec_ctx, s->codecpar);
+	if (ret < 0)
+		return -1;
+
+	ret = avcodec_open2(priv->adec_ctx, c, NULL);
+	if (ret < 0) {
+		printf("avcodec_parameters_to_context error, ret: %d, %s\n", ret, av_err2str(ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int _ffmpeg_open(simp_avio_t* io, const char* path)
+{
+	simp_ffmpeg_t* priv;
+	AVStream*      s;
+
+	int ret;
+	int i;
+
+	priv = calloc(1, sizeof(simp_ffmpeg_t));
+	if (!priv)
+		return -ENOMEM;
+
+	pthread_mutex_init(&priv->mutex);
+	pthread_cond_init (&priv->cond);
+
+	priv->tid   = -1;
+
+	priv->vidx  = -1;
+	priv->aidx  = -1;
+
+	ret = avformat_open_input(&priv->fmt_ctx, path, NULL, NULL);
+	if (ret < 0) {
+		scf_loge("ret: %s\n", av_err2str(ret));
+		goto error;
+	}
+
+	ret = avformat_find_stream_info(priv->fmt_ctx, NULL);
+	if (ret < 0) {
+		scf_loge("avformat_find_stream_info error, ret: %s\n", av_err2str(ret));
+		goto error;
+	}
+
+	for (i = 0; i < priv->fmt_ctx->nb_streams; i++) {
+		s  =        priv->fmt_ctx->streams[i];
+
+		if (AVMEDIA_TYPE_VIDEO == s->codecpar->codec_type)
+			priv->vidx = i;
+
+		else if (AVMEDIA_TYPE_AUDIO == s->codecpar->codec_type)
+			priv->aidx = i;
+
+		if (-1 != priv->vidx && -1 != priv->aidx)
+			break;
+	}
+
+	if (-1 == priv->vidx && -1 == priv->aidx) {
+		scf_loge("no stream found\n");
+
+		ret = -1;
+		goto error;
+	}
+
+	if (priv->vidx >= 0) {
+		ret = _video_init(priv);
+		if (ret < 0)
+			goto error;
+	}
+
+	if (priv->aidx >= 0) {
+		ret = _audio_init(priv);
+		if (ret < 0)
+			goto error;
+	}
+
+	io->priv = priv;
+	return 0;
+
+error:
+	if (priv->fmt_ctx)
+		avformat_close_input(&priv->fmt_ctx);
+
+	if (priv->vdec_ctx)
+		avcodec_close(priv->vdec_ctx);
+
+	if (priv->adec_ctx)
+		avcodec_close(priv->adec_ctx);
+
+	free(priv);
+	return ret;
+}
+
+static int _ffmpeg_close(simp_avio_t* io)
+{
+	simp_ffmpeg_t* priv;
+
+	if (io) {
+		priv = io->priv;
+
+		if (priv) {
+
+			if (priv->fmt_ctx)
+				avformat_close_input(&priv->fmt_ctx);
+
+			if (priv->vdec_ctx)
+				avcodec_close(priv->vdec_ctx);
+
+			if (priv->adec_ctx)
+				avcodec_close(priv->adec_ctx);
+
+			free(priv);
+		}
+	}
+
+	return 0;
+}
+
+void* __ffmpeg_run(void* arg)
+{
+	simp_avio_t*    io   = arg;
+	simp_ffmpeg_t*  priv = io->priv;
+	AVPacket*       pkt;
+
+	pkt = av_packet_alloc();
+	if (!pkt)
+		return NULL;
+
+	int key_frame = 0;
+
+	while (!priv->exit) {
+
+		int ret = av_read_frame(priv->fmt_ctx, pkt);
+		if (ret < 0) {
+			scf_loge("av_read_frame error, ret: %s\n", av_err2str(ret));
+			av_packet_free(&pkt);
+			break;
+		}
+
+		if (pkt->stream_index == priv->aidx) {
+
+			if (0 == key_frame) {
+				av_packet_unref(pkt);
+				continue;
+			}
+
+		} else if (pkt->stream_index == priv->vidx) {
+
+			if (pkt->flags & AV_PKT_FLAG_KEY)
+				key_frame++;
+
+			if (0 == key_frame) {
+				av_packet_unref(pkt);
+				continue;
+			}
+
+			ret = avcodec_send_packet(priv->vdec_ctx, pkt);
+			av_packet_unref(&pkt);
+			if (ret < 0) {
+				scf_loge("avcodec_send_packet error, ret: %s\n", av_err2str(ret));
+				break;
+			}
+
+			while (ret >= 0) {
+				ret = avcodec_receive_frame(priv->vdec_ctx, frame);
+			}
+
+		} else {
+			av_packet_unref(pkt);
+			continue;
+		}
+	}
+
+	return NULL;
+}
+
+static int _ffmpeg_run(simp_avio_t* io)
+{
+	simp_ffmpeg_t* priv = io->priv;
+
+	if (pthread_create(&priv->tid, NULL, __ffmpeg_run, io)) {
+		scf_loge("\n");
+		return -1;
+	}
+
+	return 0;
+}
+
diff --git a/simp_ffmpeg.h b/simp_ffmpeg.h
new file mode 100644
index 0000000..93cfda5
--- /dev/null
+++ b/simp_ffmpeg.h
@@ -0,0 +1,22 @@
+#ifndef SIMP_FFMPEG_H
+#define SIMP_FFMPEG_H
+
+#include"simp.h"
+
+typedef struct {
+	AVFormatContext*  fmt_ctx;
+	AVCodecContext*   vdec_ctx;
+	AVCodecContext*   adec_ctx;
+
+	int               vidx;
+	int               aidx;
+
+	int               exit;
+	pthread_t         tid;
+	pthread_mutex_t   mutex;
+	pthread_cond_t    cond;
+
+} simp_ffmpeg_t;
+
+#endif
+