ffmpeg
authoryu.dongliang <18588496441@163.com>
Sun, 9 Apr 2023 08:50:11 +0000 (16:50 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 9 Apr 2023 08:50:11 +0000 (16:50 +0800)
simp_ffmpeg_input.c
simp_filter.c

index a1fb0ee99c45463e309000bb9ba37b076fb33734..0b3c98a0637d1a285ce8a7034fa9611830095afe 100644 (file)
@@ -3,8 +3,8 @@
 
 static int _video_init(simp_ffmpeg_t* priv)
 {
-       AVStream* s;
-       AVCodec*  c;
+       AVStream*      s;
+       AVCodec*       c;
 
        s = priv->fmt_ctx->streams[priv->vidx];
 
@@ -33,8 +33,8 @@ static int _video_init(simp_ffmpeg_t* priv)
 
 static int _audio_init(simp_ffmpeg_t* priv)
 {
-       AVStream* s;
-       AVCodec*  c;
+       AVStream*      s;
+       AVCodec*       c;
 
        s = priv->fmt_ctx->streams[priv->aidx];
 
@@ -73,7 +73,6 @@ static int _ffmpeg_open(simp_avio_t* io, const char* path)
        if (!priv)
                return -ENOMEM;
 
-
        priv->vidx  = -1;
        priv->aidx  = -1;
 
@@ -125,12 +124,27 @@ static int _ffmpeg_open(simp_avio_t* io, const char* path)
                ret = _video_init(priv);
                if (ret < 0)
                        goto error;
+
+               io->width               = priv->vdec_ctx->width;
+               io->height              = priv->vdec_ctx->height;
+               io->pix_fmt             = priv->vdec_ctx->pix_fmt;
+               io->frame_rate          = priv-> fmt_ctx->streams[priv->vidx]->r_frame_rate;
+               io->sample_aspect_ratio = priv->vdec_ctx->sample_aspect_ratio;
+
+               io->x     = 0;
+               io->y     = 0;
+               io->vopen = 1;
        }
 
        if (priv->aidx >= 0) {
                ret = _audio_init(priv);
                if (ret < 0)
                        goto error;
+
+               io->sample_fmt  = priv->adec_ctx->sample_fmt;
+               io->sample_rate = priv->adec_ctx->time_base;
+               io->channels    = priv->adec_ctx->channels;
+               io->aopen       = 1;
        }
 
        io->priv = priv;
@@ -212,7 +226,7 @@ static int __ffmpeg_decode(simp_avio_t* io, AVCodecContext* dec_ctx, AVPacket* p
                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                        break;
                else if (ret < 0) {
-                       printf("avcodec_receive_frame error, ret: %d, %s\n", ret, av_err2str(ret));
+                       scf_loge("avcodec_receive_frame error, ret: %s\n", av_err2str(ret));
                        return ret;
                }
 
index 760263f9c8e84dfb1e3e930e07df8b4d46a4c494..453aaa774234334df616d1fc4697832db1be4308 100644 (file)
@@ -1,6 +1,6 @@
 #include"simp.h"
 
-static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const char* afilters_descr)
+static int _init_filters(simp_filter_t* f)
 {
     char args[512];
     int  ret = 0;
@@ -28,6 +28,9 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
                goto end;
        }
 
+       const char* vfilters_descr = "[in]scale=1920x1080[out]";
+       const char* afilters_descr = "[in]scale=1920x1080[out]";
+
        simp_avio_t* io;
        scf_list_t*  l;
 
@@ -44,6 +47,8 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
                                        io->frame_rate.num, io->frame_rate.den,
                                        io->sample_aspect_ratio.num, io->sample_aspect_ratio.den);
 
+                       printf("%s\n", args);
+
                        ret = avfilter_graph_create_filter(&io->vbuffersrc_ctx, buffersrc, "in", args, NULL, f->vgraph);
                        if (ret < 0)
                                goto end;
@@ -57,7 +62,6 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
                        tmp->name       = av_strdup("in");
                        tmp->filter_ctx = io->vbuffersrc_ctx;
                        tmp->pad_idx    = n;
-
                        tmp->next       = voutputs;
                        voutputs        = tmp;
                }
@@ -84,7 +88,6 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
                        tmp->name       = av_strdup("in");
                        tmp->filter_ctx = io->abuffersrc_ctx;
                        tmp->pad_idx    = n;
-
                        tmp->next       = aoutputs;
                        aoutputs        = tmp;
                }
@@ -116,11 +119,15 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
     vinputs->pad_idx    = 0;
     vinputs->next       = NULL;
 
-    if ((ret = avfilter_graph_parse_ptr(f->vgraph, vfilters_descr, &vinputs, &voutputs, NULL)) < 0)
+    if ((ret = avfilter_graph_parse_ptr(f->vgraph, vfilters_descr, &vinputs, &voutputs, NULL)) < 0) {
+               scf_loge("\n");
         goto end;
+       }
 
-    if ((ret = avfilter_graph_config(f->vgraph, NULL)) < 0)
+    if ((ret = avfilter_graph_config(f->vgraph, NULL)) < 0) {
+               scf_loge("\n");
         goto end;
+       }
 
        ret = avfilter_graph_create_filter(&f->abuffersink_ctx, abuffersink, "out", NULL, NULL, f->agraph);
     if (ret < 0)
@@ -149,11 +156,15 @@ static int _init_filters(simp_filter_t* f, const char* vfilters_descr, const cha
        if (ret < 0)
                goto end;
 
-    if ((ret = avfilter_graph_parse_ptr(f->agraph, afilters_descr, &ainputs, &aoutputs, NULL)) < 0)
-        goto end;
+       if ((ret = avfilter_graph_parse_ptr(f->agraph, afilters_descr, &ainputs, &aoutputs, NULL)) < 0) {
+               scf_loge("\n");
+               goto end;
+       }
 
-    if ((ret = avfilter_graph_config(f->agraph, NULL)) < 0)
-        goto end;
+       if ((ret = avfilter_graph_config(f->agraph, NULL)) < 0) {
+               scf_loge("\n");
+               goto end;
+       }
 
 end:
     avfilter_inout_free(&vinputs);
@@ -200,183 +211,202 @@ int simp_filter_close(simp_filter_t*  f)
        return -1;
 }
 
-static void* __filter_run(void* arg)
+static int  _filter_add_video(simp_avio_t* io)
 {
-       simp_filter_t* f = arg;
-
-       simp_avio_t*   io;
        simp_frame_t*  vf;
-       simp_frame_t*  af;
        scf_list_t*    vl;
-       scf_list_t*    al;
-       scf_list_t*    l;
-
-       while (!f->exit) {
-               scf_loge("\n");
 
-               usleep(100);
-
-               int64_t sys_time = gettime();
-               int     vn = 0;
-               int     an = 0;
+       pthread_mutex_lock(&io->mutex);
+       if (!scf_list_empty(&io->vin)) {
 
-               for (l = scf_list_head(&f->inputs); l != scf_list_sentinel(&f->inputs); l != scf_list_next(l)) {
-                       io = scf_list_data(l, simp_avio_t, list);
+               vl = scf_list_head(&io->vin);
+               vf = scf_list_data(vl, simp_frame_t, list);
 
-                       if (io->start_time == 0)
-                               io->start_time =  gettime();
+               int64_t time  = gettime() - io->start_time;
+               int64_t vtime = vf->frame->pts * av_q2d(io->frame_rate) * 1000000LL;
 
-                       int64_t time = sys_time - io->start_time;
+               scf_logi("vf->pts: %ld, vtime: %ld, time: %ld\n", vf->frame->pts, vtime, time);
 
-                       if (io->vopen) {
-                               pthread_mutex_lock(&io->mutex);
+               if (vtime < time) {
+                       scf_list_del(&vf->list);
+                       io->nb_vframes--;
+                       pthread_mutex_unlock(&io->mutex);
 
-                               if (!scf_list_empty(&io->vin)) {
+                       int ret = av_buffersrc_add_frame_flags(io->vbuffersrc_ctx, vf->frame, AV_BUFFERSRC_FLAG_KEEP_REF);
 
-                                       vl = scf_list_head(&io->vin);
-                                       vf = scf_list_data(vl, simp_frame_t, list);
+                       simp_frame_free(vf);
+                       vf = NULL;
 
-                                       int64_t vtime = vf->frame->pts * av_q2d(io->frame_rate) * 1000000LL;
+                       if (ret < 0) {
+                               scf_loge("av_buffersrc_add_frame_flags error\n");
+                               return ret;
+                       }
+               } else
+                       pthread_mutex_unlock(&io->mutex);
 
-                                       if (vtime < time) {
-                                               scf_list_del(&vf->list);
-                                               pthread_mutex_unlock(&io->mutex);
+       } else {
+               pthread_cond_signal(&io->cond);
+               pthread_mutex_unlock(&io->mutex);
+       }
 
-                                               scf_logi("vf->pts: %ld, vtime: %ld, time: %ld\n", vf->frame->pts, vtime, time);
+       return 0;
+}
 
-                                               int ret = av_buffersrc_add_frame_flags(io->vbuffersrc_ctx, vf->frame, AV_BUFFERSRC_FLAG_KEEP_REF);
+static int  _filter_add_audio(simp_avio_t* io)
+{
+       simp_frame_t*  af;
+       scf_list_t*    al;
 
-                                               simp_frame_free(vf);
-                                               vf = NULL;
+       pthread_mutex_lock(&io->mutex);
+       if (!scf_list_empty(&io->ain)) {
 
-                                               if (ret < 0) {
-                                                       scf_loge("av_buffersrc_add_frame_flags error\n");
-                                                       f->error = -1;
-                                                       goto error;
-                                               }
-                                       } else
-                                               pthread_mutex_unlock(&io->mutex);
+               al = scf_list_head(&io->ain);
+               af = scf_list_data(al, simp_frame_t, list);
 
-                               } else {
-                                       pthread_cond_signal(&io->cond);
-                                       pthread_mutex_unlock(&io->mutex);
-                               }
-       scf_loge("\n");
-                       }
+               int64_t time  = gettime() - io->start_time;
+               int64_t atime = af->frame->pts * av_q2d(io->sample_rate) * 1000000LL;
 
-                       if (io->aopen) {
-       scf_loge("\n");
-                               pthread_mutex_lock(&io->mutex);
+               if (atime < time) {
+                       scf_list_del(&af->list);
+                       pthread_mutex_unlock(&io->mutex);
 
-                               if (!scf_list_empty(&io->ain)) {
+                       scf_logi("af->pts: %ld, atime: %ld, time: %ld\n", af->frame->pts, atime, time);
 
-                                       al = scf_list_head(&io->ain);
-                                       af = scf_list_data(al, simp_frame_t, list);
+                       int ret = av_buffersrc_add_frame_flags(io->abuffersrc_ctx, af->frame, AV_BUFFERSRC_FLAG_KEEP_REF);
+                       simp_frame_free(af);
+                       af = NULL;
 
-                                       int64_t atime = af->frame->pts * av_q2d(io->sample_rate) * 1000000LL;
+                       if (ret < 0) {
+                               scf_loge("av_buffersrc_add_frame_flags error\n");
+                               return ret;
+                       }
+               } else
+                       pthread_mutex_unlock(&io->mutex);
 
-                                       if (atime < time) {
-                                               scf_list_del(&af->list);
-                                               pthread_mutex_unlock(&io->mutex);
+       } else {
+               pthread_cond_signal(&io->cond);
+               pthread_mutex_unlock(&io->mutex);
+       }
 
-                                               scf_logi("af->pts: %ld, atime: %ld, time: %ld\n", af->frame->pts, atime, time);
+       return 0;
+}
 
-                                               int ret = av_buffersrc_add_frame_flags(io->abuffersrc_ctx, af->frame, AV_BUFFERSRC_FLAG_KEEP_REF);
-                                               simp_frame_free(af);
-                                               af = NULL;
+static void* __filter_run(void* arg)
+{
+       simp_filter_t* f = arg;
 
-                                               if (ret < 0) {
-                                                       scf_loge("av_buffersrc_add_frame_flags error\n");
-                                                       f->error = -1;
-                                                       goto error;
-                                               }
-                                       } else
-                                               pthread_mutex_unlock(&io->mutex);
+       simp_avio_t*   io;
+       simp_frame_t*  vf;
+       simp_frame_t*  af;
+       scf_list_t*    l;
 
-                               } else {
-                                       pthread_cond_signal(&io->cond);
-                                       pthread_mutex_unlock(&io->mutex);
-                               }
-                       }
-               }
+       if (_init_filters(f) < 0) {
+               scf_loge("\n");
+               goto error;
        }
 
-       while (1) {
-       scf_loge("\n");
-               int ret = av_buffersink_get_frame(f->vbuffersink_ctx, f->vframe);
-
-               if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
-                       break;
-               } else if (ret < 0) {
-                       scf_loge("av_buffersink_get_frame error, ret: %s\n", av_err2str(ret));
+       while (!f->exit) {
+               sleep(2);
 
-                       f->error = ret;
-                       goto error;
-               }
+               int     vn = 0;
+               int     an = 0;
 
-               for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l != scf_list_next(l)) {
+               for (l = scf_list_head(&f->inputs); l != scf_list_sentinel(&f->inputs); l != scf_list_next(l)) {
                        io = scf_list_data(l, simp_avio_t, list);
 
-                       vf = simp_frame_alloc();
-                       if (!vf) {
-                               f->error = -ENOMEM;
-                               goto error;
+                       if (io->start_time == 0)
+                               io->start_time =  gettime();
+
+                       if (io->vopen) {
+                               f->error = _filter_add_video(io);
+                               if (f->error < 0)
+                                       goto error;
                        }
 
-                       if (av_frame_copy(vf->frame, f->vframe) < 0) {
-                               simp_frame_free(vf);
-                               vf = NULL;
+                       if (io->aopen) {
+                               f->error = _filter_add_audio(io);
+                               if (f->error < 0)
+                                       goto error;
+                       }
+               }
+
+               while (1) {
+                       int ret = av_buffersink_get_frame(f->vbuffersink_ctx, f->vframe);
+
+                       if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+                               break;
+                       } else if (ret < 0) {
+                               scf_loge("av_buffersink_get_frame error, ret: %s\n", av_err2str(ret));
 
-                               f->error = -ENOMEM;
+                               f->error = ret;
                                goto error;
                        }
 
-       scf_loge("\n");
-                       pthread_mutex_lock(&io->mutex);
-                       scf_list_add_tail(&io->vout, &vf->list);
-                       pthread_cond_signal(&io->cond);
-                       pthread_mutex_unlock(&io->mutex);
-                       vf = NULL;
-               }
-       }
+                       for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l != scf_list_next(l)) {
+                               io = scf_list_data(l, simp_avio_t, list);
 
-       scf_loge("\n");
-       while (1) {
-               int ret = av_buffersink_get_frame(f->abuffersink_ctx, f->aframe);
+                               vf = simp_frame_alloc();
+                               if (!vf) {
+                                       f->error = -ENOMEM;
+                                       goto error;
+                               }
 
-               if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
-                       break;
-               } else if (ret < 0) {
-                       scf_loge("av_buffersink_get_frame error, ret: %s\n", av_err2str(ret));
+                               if (av_frame_copy(vf->frame, f->vframe) < 0) {
+                                       simp_frame_free(vf);
+                                       vf = NULL;
 
-                       f->error = ret;
-                       goto error;
+                                       f->error = -ENOMEM;
+                                       goto error;
+                               }
+
+                               scf_loge("\n");
+                               pthread_mutex_lock(&io->mutex);
+                               scf_list_add_tail(&io->vout, &vf->list);
+                               pthread_cond_signal(&io->cond);
+                               pthread_mutex_unlock(&io->mutex);
+                               vf = NULL;
+                       }
                }
 
-       scf_loge("\n");
-               for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l != scf_list_next(l)) {
-                       io = scf_list_data(l, simp_avio_t, list);
+               scf_loge("\n");
+               while (1) {
+                       int ret = av_buffersink_get_frame(f->abuffersink_ctx, f->aframe);
 
-                       af = simp_frame_alloc();
-                       if (!af) {
-                               f->error = -ENOMEM;
+                       if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+                               break;
+                       } else if (ret < 0) {
+                               scf_loge("av_buffersink_get_frame error, ret: %s\n", av_err2str(ret));
+
+                               f->error = ret;
                                goto error;
                        }
 
-                       if (av_frame_copy(af->frame, f->aframe) < 0) {
-                               simp_frame_free(af);
-                               af = NULL;
+                       scf_loge("\n");
+                       for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l != scf_list_next(l)) {
+                               io = scf_list_data(l, simp_avio_t, list);
 
-                               f->error = -ENOMEM;
-                               goto error;
-                       }
+                               af = calloc(1, sizeof(simp_frame_t));
+                               if (!af) {
+                                       f->error = -ENOMEM;
+                                       goto error;
+                               }
 
-       scf_loge("\n");
-                       pthread_mutex_lock(&io->mutex);
-                       scf_list_add_tail(&io->aout, &af->list);
-                       pthread_cond_signal(&io->cond);
-                       pthread_mutex_unlock(&io->mutex);
-                       af = NULL;
+                               af->frame = av_frame_clone(f->aframe);
+                               if (!af->frame) {
+                                       simp_frame_free(af);
+                                       af = NULL;
+
+                                       f->error = -ENOMEM;
+                                       goto error;
+                               }
+
+                               scf_loge("\n");
+                               pthread_mutex_lock(&io->mutex);
+                               scf_list_add_tail(&io->aout, &af->list);
+                               pthread_cond_signal(&io->cond);
+                               pthread_mutex_unlock(&io->mutex);
+                               af = NULL;
+                       }
                }
        }