From 4207632c85b7ee72ed902238da575d34e0203f27 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 9 Apr 2023 16:50:11 +0800 Subject: [PATCH] ffmpeg --- simp_ffmpeg_input.c | 26 +++- simp_filter.c | 304 ++++++++++++++++++++++++-------------------- 2 files changed, 187 insertions(+), 143 deletions(-) diff --git a/simp_ffmpeg_input.c b/simp_ffmpeg_input.c index a1fb0ee..0b3c98a 100644 --- a/simp_ffmpeg_input.c +++ b/simp_ffmpeg_input.c @@ -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; } diff --git a/simp_filter.c b/simp_filter.c index 760263f..453aaa7 100644 --- a/simp_filter.c +++ b/simp_filter.c @@ -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; + } } } -- 2.25.1