diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2012-05-18 13:56:22 +0200 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2012-05-19 10:59:52 +0200 |
commit | aa1246ea42911bf1d193fbaa3c89b2d5a6a809ab (patch) | |
tree | 70a7be45804ebb3a39b5c74cc53d8574696f0325 | |
parent | 7997fc49ef5817bd86e24335ceba30ce6ee2332e (diff) | |
download | ffmpeg-aa1246ea42911bf1d193fbaa3c89b2d5a6a809ab.tar.gz |
lavfi: unify src_buffer and buffersrc.
Most of the code is moved to buffersrc.c
to help Git see the similarities.
src_buffer.c still contains the obsolete compatibility functions.
The format change detection code was removed as it has been
implemented directly in ffmpeg.
It can easily be brought back from the history.
-rw-r--r-- | libavfilter/Makefile | 1 | ||||
-rw-r--r-- | libavfilter/buffersrc.c | 148 | ||||
-rw-r--r-- | libavfilter/buffersrc.h | 3 | ||||
-rw-r--r-- | libavfilter/src_buffer.c | 515 |
4 files changed, 97 insertions, 570 deletions
diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 1f9d4117d1..56c931a17d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -28,6 +28,7 @@ OBJS = allfilters.o \ avfiltergraph.o \ buffer.o \ buffersink.o \ + buffersrc.o \ defaults.o \ drawutils.o \ formats.o \ diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 7cc80d8f5f..90f922ab9e 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -27,6 +27,7 @@ #include "avfilter.h" #include "buffersrc.h" #include "formats.h" +#include "internal.h" #include "vsrc_buffer.h" #include "avcodec.h" @@ -40,11 +41,13 @@ typedef struct { const AVClass *class; AVFifoBuffer *fifo; AVRational time_base; ///< time_base to set in the output link + unsigned nb_failed_requests; /* video only */ int h, w; enum PixelFormat pix_fmt; AVRational pixel_aspect; + char sws_param[256]; /* audio only */ int sample_rate; @@ -69,6 +72,44 @@ typedef struct { return AVERROR(EINVAL);\ } +static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx, + AVFilterBufferRef *ref) +{ + AVFilterLink *outlink = ctx->outputs[0]; + AVFilterBufferRef *buf; + int channels; + + switch (outlink->type) { + + case AVMEDIA_TYPE_VIDEO: + buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, + ref->video->w, ref->video->h); + if(!buf) + return NULL; + av_image_copy(buf->data, buf->linesize, + (void*)ref->data, ref->linesize, + ref->format, ref->video->w, ref->video->h); + break; + + case AVMEDIA_TYPE_AUDIO: + buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, + ref->audio->nb_samples); + if(!buf) + return NULL; + channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout); + av_samples_copy(buf->extended_data, ref->buf->extended_data, + 0, 0, ref->audio->nb_samples, + channels, + ref->format); + break; + + default: + return NULL; + } + avfilter_copy_buffer_ref_props(buf, ref); + return buf; +} + #if FF_API_VSRC_BUFFER_ADD_FRAME static int av_vsrc_buffer_add_frame_alt(AVFilterContext *buffer_filter, AVFrame *frame, int64_t pts, AVRational pixel_aspect) @@ -88,59 +129,42 @@ static int av_vsrc_buffer_add_frame_alt(AVFilterContext *buffer_filter, AVFrame } #endif -int av_buffersrc_write_frame(AVFilterContext *buffer_filter, AVFrame *frame) +int av_buffersrc_add_frame(AVFilterContext *buffer_src, + const AVFrame *frame, int flags) { - BufferSourceContext *c = buffer_filter->priv; - AVFilterBufferRef *buf; + AVFilterBufferRef *picref; int ret; - if (!frame) { - c->eof = 1; - return 0; - } else if (c->eof) - return AVERROR(EINVAL); + if (!frame) /* NULL for EOF */ + return av_buffersrc_add_ref(buffer_src, NULL, flags); - if (!av_fifo_space(c->fifo) && - (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) + - sizeof(buf))) < 0) - return ret; - - switch (buffer_filter->outputs[0]->type) { + switch (buffer_src->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: - CHECK_VIDEO_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height, - frame->format); - buf = avfilter_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE, - c->w, c->h); - av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize, - c->pix_fmt, c->w, c->h); + picref = avfilter_get_video_buffer_ref_from_frame(frame, AV_PERM_WRITE); break; case AVMEDIA_TYPE_AUDIO: - CHECK_AUDIO_PARAM_CHANGE(buffer_filter, c, frame->sample_rate, frame->channel_layout, - frame->format); - buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE, - frame->nb_samples); - av_samples_copy(buf->extended_data, frame->extended_data, - 0, 0, frame->nb_samples, - av_get_channel_layout_nb_channels(frame->channel_layout), - frame->format); + picref = avfilter_get_audio_buffer_ref_from_frame(frame, AV_PERM_WRITE); break; default: - return AVERROR(EINVAL); - } - - avfilter_copy_frame_props(buf, frame); - - if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) { - avfilter_unref_buffer(buf); - return ret; + return AVERROR(ENOSYS); } + if (!picref) + return AVERROR(ENOMEM); + ret = av_buffersrc_add_ref(buffer_src, picref, flags); + picref->buf->data[0] = NULL; + avfilter_unref_buffer(picref); + return ret; +} - return 0; +int av_buffersrc_write_frame(AVFilterContext *buffer_filter, AVFrame *frame) +{ + return av_buffersrc_add_frame(buffer_filter, frame, 0); } -int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf) +int av_buffersrc_add_ref(AVFilterContext *s, AVFilterBufferRef *buf, int flags) { BufferSourceContext *c = s->priv; + AVFilterBufferRef *to_free = NULL; int ret; if (!buf) { @@ -154,6 +178,8 @@ int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf) sizeof(buf))) < 0) return ret; + if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { + /* TODO reindent */ switch (s->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format); @@ -165,39 +191,56 @@ int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf) default: return AVERROR(EINVAL); } + } + if (!(flags & AV_BUFFERSRC_FLAG_NO_COPY)) + to_free = buf = copy_buffer_ref(s, buf); + if(!buf) + return -1; - if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) + if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) { + avfilter_unref_buffer(to_free); return ret; + } + c->nb_failed_requests = 0; return 0; } +int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf) +{ + return av_buffersrc_add_ref(s, buf, AV_BUFFERSRC_FLAG_NO_COPY); +} + +unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) +{ + return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests; +} + static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaque) { BufferSourceContext *c = ctx->priv; char pix_fmt_str[128]; - int n = 0; + int ret, n = 0; + *c->sws_param = 0; if (!args || - (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str, + (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d:%255c", &c->w, &c->h, pix_fmt_str, &c->time_base.num, &c->time_base.den, - &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) { - av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args); + &c->pixel_aspect.num, &c->pixel_aspect.den, c->sws_param)) < 7) { + av_log(ctx, AV_LOG_ERROR, "Expected at least 7 arguments, but only %d found in '%s'\n", n, args); return AVERROR(EINVAL); } - if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == PIX_FMT_NONE) { - char *tail; - c->pix_fmt = strtol(pix_fmt_str, &tail, 10); - if (*tail || c->pix_fmt < 0 || c->pix_fmt >= PIX_FMT_NB) { - av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str); - return AVERROR(EINVAL); - } - } + + if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0) + return ret; if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) return AVERROR(ENOMEM); - av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name); + av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s tb:%d/%d sar:%d/%d sws_param:%s\n", + c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name, + c->time_base.num, c->time_base.den, + c->pixel_aspect.num, c->pixel_aspect.den, c->sws_param); return 0; } @@ -335,6 +378,7 @@ static int request_frame(AVFilterLink *link) 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, &buf, sizeof(buf), NULL); diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h index 27fc2867a0..cd6492e5cb 100644 --- a/libavfilter/buffersrc.h +++ b/libavfilter/buffersrc.h @@ -27,7 +27,6 @@ #include "avfilter.h" -#if 1 enum { /** @@ -63,7 +62,6 @@ int av_buffersrc_add_ref(AVFilterContext *buffer_src, */ unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src); -#else /** * Add a buffer to the filtergraph s. * @@ -83,6 +81,5 @@ int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf); * hit. Use av_buffersrc_buffer() to avoid copying the data. */ int av_buffersrc_write_frame(AVFilterContext *s, AVFrame *frame); -#endif #endif /* AVFILTER_BUFFERSRC_H */ diff --git a/libavfilter/src_buffer.c b/libavfilter/src_buffer.c index 5bf629ce6b..981ae4d465 100644 --- a/libavfilter/src_buffer.c +++ b/libavfilter/src_buffer.c @@ -61,281 +61,12 @@ typedef struct { AVFilterContext *aresample; } BufferSourceContext; -#define FIFO_SIZE 8 - -#define CHECK_PARAM_CHANGE(s, c, width, height, format)\ - if (c->w != width || c->h != height || c->pix_fmt != format) {\ - av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\ - return AVERROR(EINVAL);\ - } - static void buf_free(AVFilterBuffer *ptr) { av_free(ptr); return; } -static void set_link_source(AVFilterContext *src, AVFilterLink *link) -{ - link->src = src; - link->srcpad = &(src->output_pads[0]); - src->outputs[0] = link; -} - -static int reconfigure_filter(BufferSourceContext *abuffer, AVFilterContext *filt_ctx) -{ - int ret; - AVFilterLink * const inlink = filt_ctx->inputs[0]; - AVFilterLink * const outlink = filt_ctx->outputs[0]; - - inlink->format = abuffer->sample_format; - inlink->channel_layout = abuffer->channel_layout; - inlink->sample_rate = abuffer->sample_rate; - - filt_ctx->filter->uninit(filt_ctx); - memset(filt_ctx->priv, 0, filt_ctx->filter->priv_size); - if ((ret = filt_ctx->filter->init(filt_ctx, NULL , NULL)) < 0) - return ret; - if ((ret = inlink->srcpad->config_props(inlink)) < 0) - return ret; - return outlink->srcpad->config_props(outlink); -} - -static int insert_filter(BufferSourceContext *abuffer, - AVFilterLink *link, AVFilterContext **filt_ctx, - const char *filt_name) -{ - int ret; - - if ((ret = avfilter_open(filt_ctx, avfilter_get_by_name(filt_name), NULL)) < 0) - return ret; - - link->src->outputs[0] = NULL; - if ((ret = avfilter_link(link->src, 0, *filt_ctx, 0)) < 0) { - link->src->outputs[0] = link; - return ret; - } - - set_link_source(*filt_ctx, link); - - if ((ret = reconfigure_filter(abuffer, *filt_ctx)) < 0) { - avfilter_free(*filt_ctx); - return ret; - } - - return 0; -} - -static void remove_filter(AVFilterContext **filt_ctx) -{ - AVFilterLink *outlink = (*filt_ctx)->outputs[0]; - AVFilterContext *src = (*filt_ctx)->inputs[0]->src; - - (*filt_ctx)->outputs[0] = NULL; - avfilter_free(*filt_ctx); - *filt_ctx = NULL; - - set_link_source(src, outlink); -} - -static inline void log_input_change(void *ctx, AVFilterLink *link, AVFilterBufferRef *ref) -{ - char old_layout_str[16], new_layout_str[16]; - av_get_channel_layout_string(old_layout_str, sizeof(old_layout_str), - -1, link->channel_layout); - av_get_channel_layout_string(new_layout_str, sizeof(new_layout_str), - -1, ref->audio->channel_layout); - av_log(ctx, AV_LOG_INFO, - "Audio input format changed: " - "%s:%s:%d -> %s:%s:%d, normalizing\n", - av_get_sample_fmt_name(link->format), - old_layout_str, (int)link->sample_rate, - av_get_sample_fmt_name(ref->format), - new_layout_str, ref->audio->sample_rate); -} - -static int check_format_change_video(AVFilterContext *buffer_filter, - AVFilterBufferRef *picref) -{ - BufferSourceContext *c = buffer_filter->priv; - int ret; - - if (picref->video->w != c->w || picref->video->h != c->h || picref->format != c->pix_fmt) { - AVFilterContext *scale = buffer_filter->outputs[0]->dst; - AVFilterLink *link; - char scale_param[1024]; - - av_log(buffer_filter, AV_LOG_INFO, - "Buffer video input changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n", - c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name, - picref->video->w, picref->video->h, av_pix_fmt_descriptors[picref->format].name); - - if (!scale || strcmp(scale->filter->name, "scale")) { - AVFilter *f = avfilter_get_by_name("scale"); - - av_log(buffer_filter, AV_LOG_INFO, "Inserting scaler filter\n"); - if ((ret = avfilter_open(&scale, f, "Input equalizer")) < 0) - return ret; - - c->scale = scale; - - snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s", c->w, c->h, c->sws_param); - if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0) { - return ret; - } - - if ((ret = avfilter_insert_filter(buffer_filter->outputs[0], scale, 0, 0)) < 0) { - return ret; - } - scale->outputs[0]->time_base = scale->inputs[0]->time_base; - - scale->outputs[0]->format= c->pix_fmt; - } else if (!strcmp(scale->filter->name, "scale")) { - snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s", - scale->outputs[0]->w, scale->outputs[0]->h, c->sws_param); - scale->filter->init(scale, scale_param, NULL); - } - - c->pix_fmt = scale->inputs[0]->format = picref->format; - c->w = scale->inputs[0]->w = picref->video->w; - c->h = scale->inputs[0]->h = picref->video->h; - - link = scale->outputs[0]; - if ((ret = link->srcpad->config_props(link)) < 0) - return ret; - } - return 0; -} - -static int check_format_change_audio(AVFilterContext *ctx, - AVFilterBufferRef *samplesref) -{ - BufferSourceContext *abuffer = ctx->priv; - AVFilterLink *link; - int ret, logged = 0; - - link = ctx->outputs[0]; - if (samplesref->audio->sample_rate != link->sample_rate || - samplesref->format != link->format || - samplesref->audio->channel_layout != link->channel_layout) { - - log_input_change(ctx, link, samplesref); - logged = 1; - - abuffer->sample_rate = samplesref->audio->sample_rate; - abuffer->sample_format = samplesref->format; - abuffer->channel_layout = samplesref->audio->channel_layout; - - if (!abuffer->aresample) { - ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample"); - if (ret < 0) return ret; - } else { - link = abuffer->aresample->outputs[0]; - if (samplesref->audio->sample_rate == link->sample_rate && - samplesref->format == link->format && - samplesref->audio->channel_layout == link->channel_layout) - remove_filter(&abuffer->aresample); - else - if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0) - return ret; - } - } - - - return 0; -} - -static int check_format_change(AVFilterContext *buffer_filter, - AVFilterBufferRef *picref) -{ - switch (buffer_filter->outputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - return check_format_change_video(buffer_filter, picref); - case AVMEDIA_TYPE_AUDIO: - return check_format_change_audio(buffer_filter, picref); - default: - return AVERROR(ENOSYS); - } -} - -static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx, - AVFilterBufferRef *ref) -{ - AVFilterLink *outlink = ctx->outputs[0]; - AVFilterBufferRef *buf; - int channels, data_size, i; - - switch (outlink->type) { - - case AVMEDIA_TYPE_VIDEO: - buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, - ref->video->w, ref->video->h); - if(!buf) - return NULL; - av_image_copy(buf->data, buf->linesize, - (void*)ref->data, ref->linesize, - ref->format, ref->video->w, ref->video->h); - break; - - case AVMEDIA_TYPE_AUDIO: - buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, - ref->audio->nb_samples); - if(!buf) - return NULL; - channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout); - av_samples_copy(buf->extended_data, ref->buf->extended_data, - 0, 0, ref->audio->nb_samples, - channels, - ref->format); - break; - - default: - return NULL; - } - avfilter_copy_buffer_ref_props(buf, ref); - return buf; -} - -int av_buffersrc_add_ref(AVFilterContext *buffer_filter, - AVFilterBufferRef *picref, int flags) -{ - BufferSourceContext *c = buffer_filter->priv; - AVFilterBufferRef *buf; - int ret; - - if (!picref) { - c->eof = 1; - return 0; - } else if (c->eof) - return AVERROR(EINVAL); - - if (!av_fifo_space(c->fifo) && - (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) + - sizeof(buf))) < 0) - return ret; - - if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { - ret = check_format_change(buffer_filter, picref); - if (ret < 0) - return ret; - } - if (flags & AV_BUFFERSRC_FLAG_NO_COPY) - buf = picref; - else - buf = copy_buffer_ref(buffer_filter, picref); - if(!buf) - return -1; - - if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) { - if (buf != picref) - avfilter_unref_buffer(buf); - return ret; - } - c->nb_failed_requests = 0; - - return 0; -} - int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, AVFilterBufferRef *picref, int flags) { @@ -345,33 +76,6 @@ int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, #if CONFIG_AVCODEC #include "avcodec.h" -int av_buffersrc_add_frame(AVFilterContext *buffer_src, - const AVFrame *frame, int flags) -{ - AVFilterBufferRef *picref; - int ret; - - if (!frame) /* NULL for EOF */ - return av_buffersrc_add_ref(buffer_src, NULL, flags); - - switch (buffer_src->outputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - picref = avfilter_get_video_buffer_ref_from_frame(frame, AV_PERM_WRITE); - break; - case AVMEDIA_TYPE_AUDIO: - picref = avfilter_get_audio_buffer_ref_from_frame(frame, AV_PERM_WRITE); - break; - default: - return AVERROR(ENOSYS); - } - if (!picref) - return AVERROR(ENOMEM); - ret = av_buffersrc_add_ref(buffer_src, picref, flags); - picref->buf->data[0] = NULL; - avfilter_unref_buffer(picref); - return ret; -} - int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, const AVFrame *frame, int flags) { @@ -379,193 +83,11 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, } #endif -unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) -{ - return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests; -} - unsigned av_vsrc_buffer_get_nb_failed_requests(AVFilterContext *buffer_src) { return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests; } -static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaque) -{ - BufferSourceContext *c = ctx->priv; - char pix_fmt_str[128]; - int ret, n = 0; - *c->sws_param = 0; - - if (!args || - (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d:%255c", &c->w, &c->h, pix_fmt_str, - &c->time_base.num, &c->time_base.den, - &c->sample_aspect_ratio.num, &c->sample_aspect_ratio.den, c->sws_param)) < 7) { - av_log(ctx, AV_LOG_ERROR, "Expected at least 7 arguments, but only %d found in '%s'\n", n, args); - return AVERROR(EINVAL); - } - - if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0) - return ret; - - if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) - return AVERROR(ENOMEM); - - av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s tb:%d/%d sar:%d/%d sws_param:%s\n", - c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name, - c->time_base.num, c->time_base.den, - c->sample_aspect_ratio.num, c->sample_aspect_ratio.den, c->sws_param); - return 0; -} - -static av_cold int init_audio(AVFilterContext *ctx, const char *args0, void *opaque) -{ - BufferSourceContext *abuffer = ctx->priv; - char *arg = NULL, *ptr, chlayout_str[16]; - char *args = av_strdup(args0); - int ret; - - arg = av_strtok(args, ":", &ptr); - -#define ADD_FORMAT(fmt_name) \ - if (!arg) \ - goto arg_fail; \ - if ((ret = ff_parse_##fmt_name(&abuffer->fmt_name, arg, ctx)) < 0) { \ - av_freep(&args); \ - return ret; \ - } \ - if (*args) \ - arg = av_strtok(NULL, ":", &ptr) - - ADD_FORMAT(time_base); - ADD_FORMAT(sample_rate); - ADD_FORMAT(sample_format); - ADD_FORMAT(channel_layout); - - abuffer->fifo = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*)); - if (!abuffer->fifo) { - av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo, filter init failed.\n"); - return AVERROR(ENOMEM); - } - - av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), - -1, abuffer->channel_layout); - av_log(ctx, AV_LOG_INFO, "format:%s layout:%s rate:%d\n", - av_get_sample_fmt_name(abuffer->sample_format), chlayout_str, - abuffer->sample_rate); - av_freep(&args); - - return 0; - -arg_fail: - av_log(ctx, AV_LOG_ERROR, "Invalid arguments, must be of the form " - "sample_rate:sample_fmt:channel_layout\n"); - av_freep(&args); - return AVERROR(EINVAL); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - BufferSourceContext *s = ctx->priv; - while (s->fifo && av_fifo_size(s->fifo)) { - AVFilterBufferRef *buf; - av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL); - avfilter_unref_buffer(buf); - } - av_fifo_free(s->fifo); - s->fifo = NULL; - avfilter_free(s->scale); - s->scale = NULL; -} - -static int query_formats_video(AVFilterContext *ctx) -{ - BufferSourceContext *c = ctx->priv; - enum PixelFormat pix_fmts[] = { c->pix_fmt, PIX_FMT_NONE }; - - avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); - return 0; -} - -static int query_formats_audio(AVFilterContext *ctx) -{ - BufferSourceContext *abuffer = ctx->priv; - AVFilterFormats *formats; - AVFilterChannelLayouts *layouts; - - formats = NULL; - avfilter_add_format(&formats, abuffer->sample_format); - avfilter_set_common_sample_formats(ctx, formats); - - formats = NULL; - avfilter_add_format(&formats, abuffer->sample_rate); - ff_set_common_samplerates(ctx, formats); - - layouts = NULL; - ff_add_channel_layout(&layouts, abuffer->channel_layout); - ff_set_common_channel_layouts(ctx, layouts); - - return 0; -} - -static int config_output_video(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - - link->w = c->w; - link->h = c->h; - link->sample_aspect_ratio = c->sample_aspect_ratio; - link->time_base = c->time_base; - - return 0; -} - -static int config_output_audio(AVFilterLink *outlink) -{ - BufferSourceContext *abuffer = outlink->src->priv; - outlink->sample_rate = abuffer->sample_rate; - outlink->time_base = abuffer->time_base; - return 0; -} - -static int request_frame(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - AVFilterBufferRef *buf; - - 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, &buf, sizeof(buf), NULL); - - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - avfilter_start_frame(link, avfilter_ref_buffer(buf, ~0)); - avfilter_draw_slice(link, 0, link->h, 1); - avfilter_end_frame(link); - avfilter_unref_buffer(buf); - break; - case AVMEDIA_TYPE_AUDIO: - ff_filter_samples(link, avfilter_ref_buffer(buf, ~0)); - avfilter_unref_buffer(buf); - break; - default: - return AVERROR(ENOSYS); - } - return 0; -} - -static int poll_frame(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - int size = av_fifo_size(c->fifo); - if (!size && c->eof) - return AVERROR_EOF; - return size/sizeof(AVFilterBufferRef*); -} - int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx, AVFilterBufferRef *samplesref, int av_unused flags) @@ -619,40 +141,3 @@ int av_asrc_buffer_add_buffer(AVFilterContext *ctx, pts, flags); ) } - -AVFilter avfilter_vsrc_buffer = { - .name = "buffer", - .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."), - .priv_size = sizeof(BufferSourceContext), - .query_formats = query_formats_video, - - .init = init_video, - .uninit = uninit, - - .inputs = (const AVFilterPad[]) {{ .name = NULL }}, - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .poll_frame = poll_frame, - .config_props = config_output_video, }, - { .name = NULL}}, -}; - -AVFilter avfilter_asrc_abuffer = { - .name = "abuffer", - .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."), - .priv_size = sizeof(BufferSourceContext), - .query_formats = query_formats_audio, - - .init = init_audio, - .uninit = uninit, - - .inputs = (const AVFilterPad[]) {{ .name = NULL }}, - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .request_frame = request_frame, - .poll_frame = poll_frame, - .config_props = config_output_audio, }, - { .name = NULL}}, -}; - |