X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fbuffersrc.c;h=da1cf9941ec96855ab715ce74c02aa0c51e12af4;hb=cb9dbc60db1847fcb594684b92334da54ea8757e;hp=cd56f8ca457e4c2b3d6a75e00728eed2e12a7589;hpb=04a8d5c2d7578456fc4d0a605784bf904cc42a4d;p=ffmpeg diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index cd56f8ca457..da1cf9941ec 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -25,14 +25,15 @@ #include +#include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/common.h" -#include "libavutil/fifo.h" #include "libavutil/frame.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/opt.h" #include "libavutil/samplefmt.h" +#include "libavutil/timestamp.h" #include "audio.h" #include "avfilter.h" #include "buffersrc.h" @@ -42,17 +43,17 @@ typedef struct BufferSourceContext { const AVClass *class; - AVFifoBuffer *fifo; AVRational time_base; ///< time_base to set in the output link AVRational frame_rate; ///< frame_rate to set in the output link unsigned nb_failed_requests; - unsigned warning_limit; /* video only */ int w, h; enum AVPixelFormat pix_fmt; AVRational pixel_aspect; +#if FF_API_SWS_PARAM_OPTION char *sws_param; +#endif AVBufferRef *hw_frames_ctx; @@ -63,19 +64,23 @@ typedef struct BufferSourceContext { uint64_t channel_layout; char *channel_layout_str; - int got_format_from_params; int eof; } BufferSourceContext; -#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\ +#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format, pts)\ if (c->w != width || c->h != height || c->pix_fmt != format) {\ - av_log(s, AV_LOG_INFO, "Changing frame properties on the fly is not supported by all filters.\n");\ + av_log(s, AV_LOG_INFO, "filter context - w: %d h: %d fmt: %d, incoming frame - w: %d h: %d fmt: %d pts_time: %s\n",\ + c->w, c->h, c->pix_fmt, width, height, format, av_ts2timestr(pts, &s->outputs[0]->time_base));\ + av_log(s, AV_LOG_WARNING, "Changing video frame properties on the fly is not supported by all filters.\n");\ } -#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, ch_count, format)\ +#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, ch_count, format, pts)\ if (c->sample_fmt != format || c->sample_rate != srate ||\ c->channel_layout != ch_layout || c->channels != ch_count) {\ - av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\ + av_log(s, AV_LOG_INFO, "filter context - fmt: %s r: %d layout: %"PRIX64" ch: %d, incoming frame - fmt: %s r: %d layout: %"PRIX64" ch: %d pts_time: %s\n",\ + av_get_sample_fmt_name(c->sample_fmt), c->sample_rate, c->channel_layout, c->channels,\ + av_get_sample_fmt_name(format), srate, ch_layout, ch_count, av_ts2timestr(pts, &s->outputs[0]->time_base));\ + av_log(s, AV_LOG_ERROR, "Changing audio frame properties on the fly is not supported.\n");\ return AVERROR(EINVAL);\ } @@ -100,7 +105,6 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *par switch (ctx->filter->outputs[0].type) { case AVMEDIA_TYPE_VIDEO: if (param->format != AV_PIX_FMT_NONE) { - s->got_format_from_params = 1; s->pix_fmt = param->format; } if (param->width > 0) @@ -120,7 +124,6 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters *par break; case AVMEDIA_TYPE_AUDIO: if (param->format != AV_SAMPLE_FMT_NONE) { - s->got_format_from_params = 1; s->sample_fmt = param->format; } if (param->sample_rate > 0) @@ -146,33 +149,6 @@ int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *fr return av_buffersrc_add_frame_flags(ctx, frame, 0); } -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags); - -int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) -{ - AVFrame *copy = NULL; - int ret = 0; - - if (frame && frame->channel_layout && - av_get_channel_layout_nb_channels(frame->channel_layout) != frame->channels) { - av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); - return AVERROR(EINVAL); - } - - if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame) - return av_buffersrc_add_frame_internal(ctx, frame, flags); - - if (!(copy = av_frame_alloc())) - return AVERROR(ENOMEM); - ret = av_frame_ref(copy, frame); - if (ret >= 0) - ret = av_buffersrc_add_frame_internal(ctx, copy, flags); - - av_frame_free(©); - return ret; -} - static int push_frame(AVFilterGraph *graph) { int ret; @@ -187,13 +163,18 @@ static int push_frame(AVFilterGraph *graph) return 0; } -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags) +int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) { BufferSourceContext *s = ctx->priv; AVFrame *copy; int refcounted, ret; + if (frame && frame->channel_layout && + av_get_channel_layout_nb_channels(frame->channel_layout) != frame->channels) { + av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); + return AVERROR(EINVAL); + } + s->nb_failed_requests = 0; if (!frame) @@ -205,33 +186,28 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { - switch (ctx->outputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, - frame->format); - break; - case AVMEDIA_TYPE_AUDIO: - /* For layouts unknown on input but known on link after negotiation. */ - if (!frame->channel_layout) - frame->channel_layout = s->channel_layout; - CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, - frame->channels, frame->format); - break; - default: - return AVERROR(EINVAL); - } + switch (ctx->outputs[0]->type) { + case AVMEDIA_TYPE_VIDEO: + CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, + frame->format, frame->pts); + break; + case AVMEDIA_TYPE_AUDIO: + /* For layouts unknown on input but known on link after negotiation. */ + if (!frame->channel_layout) + frame->channel_layout = s->channel_layout; + CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, + frame->channels, frame->format, frame->pts); + break; + default: + return AVERROR(EINVAL); + } } - if (!av_fifo_space(s->fifo) && - (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) + - sizeof(copy))) < 0) - return ret; - if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); - if (refcounted) { + if (refcounted && !(flags & AV_BUFFERSRC_FLAG_KEEP_REF)) { av_frame_move_ref(copy, frame); } else { ret = av_frame_ref(copy, frame); @@ -241,14 +217,8 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, } } - if ((ret = av_fifo_generic_write(s->fifo, ©, sizeof(copy), NULL)) < 0) { - if (refcounted) - av_frame_move_ref(frame, copy); - av_frame_free(©); - return ret; - } - - if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0) + ret = ff_filter_frame(ctx->outputs[0], copy); + if (ret < 0) return ret; if ((flags & AV_BUFFERSRC_FLAG_PUSH)) { @@ -273,20 +243,22 @@ static av_cold int init_video(AVFilterContext *ctx) { BufferSourceContext *c = ctx->priv; - if (!(c->pix_fmt != AV_PIX_FMT_NONE || c->got_format_from_params) || !c->w || !c->h || + if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) { av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n"); return AVERROR(EINVAL); } - if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*)))) - return AVERROR(ENOMEM); - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n", + av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d\n", c->w, c->h, av_get_pix_fmt_name(c->pix_fmt), c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den, - c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, "")); - c->warning_limit = 100; + c->pixel_aspect.num, c->pixel_aspect.den); + +#if FF_API_SWS_PARAM_OPTION + if (c->sws_param) + av_log(ctx, AV_LOG_WARNING, "sws_param option is deprecated and ignored\n"); +#endif + return 0; } @@ -308,7 +280,9 @@ static const AVOption buffer_options[] = { { "pixel_aspect", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, +#if FF_API_SWS_PARAM_OPTION { "sws_param", NULL, OFFSET(sws_param), AV_OPT_TYPE_STRING, .flags = V }, +#endif { NULL }, }; @@ -330,7 +304,7 @@ static av_cold int init_audio(AVFilterContext *ctx) BufferSourceContext *s = ctx->priv; int ret = 0; - if (!(s->sample_fmt != AV_SAMPLE_FMT_NONE || s->got_format_from_params)) { + if (s->sample_fmt == AV_SAMPLE_FMT_NONE) { av_log(ctx, AV_LOG_ERROR, "Sample format was not set or was invalid\n"); return AVERROR(EINVAL); } @@ -363,9 +337,6 @@ static av_cold int init_audio(AVFilterContext *ctx) return AVERROR(EINVAL); } - if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) - return AVERROR(ENOMEM); - if (!s->time_base.num) s->time_base = (AVRational){1, s->sample_rate}; @@ -373,7 +344,6 @@ static av_cold int init_audio(AVFilterContext *ctx) "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n", s->time_base.num, s->time_base.den, av_get_sample_fmt_name(s->sample_fmt), s->sample_rate, s->channel_layout_str); - s->warning_limit = 100; return ret; } @@ -381,13 +351,7 @@ static av_cold int init_audio(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx) { BufferSourceContext *s = ctx->priv; - while (s->fifo && av_fifo_size(s->fifo)) { - AVFrame *frame; - av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL); - av_frame_free(&frame); - } av_buffer_unref(&s->hw_frames_ctx); - av_fifo_freep(&s->fifo); } static int query_formats(AVFilterContext *ctx) @@ -457,29 +421,11 @@ static int config_props(AVFilterLink *link) static int request_frame(AVFilterLink *link) { BufferSourceContext *c = link->src->priv; - AVFrame *frame; - int ret; - - if (!av_fifo_size(c->fifo)) { - if (c->eof) - return AVERROR_EOF; - c->nb_failed_requests++; - return AVERROR(EAGAIN); - } - av_fifo_generic_read(c->fifo, &frame, sizeof(frame), NULL); - - ret = ff_filter_frame(link, frame); - return ret; -} - -static int poll_frame(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - int size = av_fifo_size(c->fifo); - if (!size && c->eof) + if (c->eof) return AVERROR_EOF; - return size/sizeof(AVFrame*); + c->nb_failed_requests++; + return AVERROR(EAGAIN); } static const AVFilterPad avfilter_vsrc_buffer_outputs[] = { @@ -487,7 +433,6 @@ static const AVFilterPad avfilter_vsrc_buffer_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .request_frame = request_frame, - .poll_frame = poll_frame, .config_props = config_props, }, { NULL } @@ -512,7 +457,6 @@ static const AVFilterPad avfilter_asrc_abuffer_outputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .request_frame = request_frame, - .poll_frame = poll_frame, .config_props = config_props, }, { NULL }