History

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.

Nicolas George committed 14 years ago

Commit aa1246e1 parent 7997fc44 files · +97 −570Browse files

Showing the changes to libavfilter/src_buffer.c (1 of 4 files). Show all

Unified · Split

libavfilter/src_buffer.c+0−515
@@ -61,281 +61,12 @@ typedef struct { · 60 unmodified lines
6161 AVFilterContext *aresample;
6262 } BufferSourceContext;
6363
64−#define FIFO_SIZE 8
65−
66−#define CHECK_PARAM_CHANGE(s, c, width, height, format)\
67− if (c->w != width || c->h != height || c->pix_fmt != format) {\
68− av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\
69− return AVERROR(EINVAL);\
70− }
71−
7264 static void buf_free(AVFilterBuffer *ptr)
7365 {
7466 av_free(ptr);
7567 return;
7668 }
7769
78−static void set_link_source(AVFilterContext *src, AVFilterLink *link)
79−{
80− link->src = src;
81− link->srcpad = &(src->output_pads[0]);
82− src->outputs[0] = link;
83−}
84−
85−static int reconfigure_filter(BufferSourceContext *abuffer, AVFilterContext *filt_ctx)
86−{
87− int ret;
88− AVFilterLink * const inlink = filt_ctx->inputs[0];
89− AVFilterLink * const outlink = filt_ctx->outputs[0];
90−
91− inlink->format = abuffer->sample_format;
92− inlink->channel_layout = abuffer->channel_layout;
93− inlink->sample_rate = abuffer->sample_rate;
94−
95− filt_ctx->filter->uninit(filt_ctx);
96− memset(filt_ctx->priv, 0, filt_ctx->filter->priv_size);
97− if ((ret = filt_ctx->filter->init(filt_ctx, NULL , NULL)) < 0)
98− return ret;
99− if ((ret = inlink->srcpad->config_props(inlink)) < 0)
100− return ret;
101− return outlink->srcpad->config_props(outlink);
102−}
103−
104−static int insert_filter(BufferSourceContext *abuffer,
105− AVFilterLink *link, AVFilterContext **filt_ctx,
106− const char *filt_name)
107−{
108− int ret;
109−
110− if ((ret = avfilter_open(filt_ctx, avfilter_get_by_name(filt_name), NULL)) < 0)
111− return ret;
112−
113− link->src->outputs[0] = NULL;
114− if ((ret = avfilter_link(link->src, 0, *filt_ctx, 0)) < 0) {
115− link->src->outputs[0] = link;
116− return ret;
117− }
118−
119− set_link_source(*filt_ctx, link);
120−
121− if ((ret = reconfigure_filter(abuffer, *filt_ctx)) < 0) {
122− avfilter_free(*filt_ctx);
123− return ret;
124− }
125−
126− return 0;
127−}
128−
129−static void remove_filter(AVFilterContext **filt_ctx)
130−{
131− AVFilterLink *outlink = (*filt_ctx)->outputs[0];
132− AVFilterContext *src = (*filt_ctx)->inputs[0]->src;
133−
134− (*filt_ctx)->outputs[0] = NULL;
135− avfilter_free(*filt_ctx);
136− *filt_ctx = NULL;
137−
138− set_link_source(src, outlink);
139−}
140−
141−static inline void log_input_change(void *ctx, AVFilterLink *link, AVFilterBufferRef *ref)
142−{
143− char old_layout_str[16], new_layout_str[16];
144− av_get_channel_layout_string(old_layout_str, sizeof(old_layout_str),
145− -1, link->channel_layout);
146− av_get_channel_layout_string(new_layout_str, sizeof(new_layout_str),
147− -1, ref->audio->channel_layout);
148− av_log(ctx, AV_LOG_INFO,
149− "Audio input format changed: "
150− "%s:%s:%d -> %s:%s:%d, normalizing\n",
151− av_get_sample_fmt_name(link->format),
152− old_layout_str, (int)link->sample_rate,
153− av_get_sample_fmt_name(ref->format),
154− new_layout_str, ref->audio->sample_rate);
155−}
156−
157−static int check_format_change_video(AVFilterContext *buffer_filter,
158− AVFilterBufferRef *picref)
159−{
160− BufferSourceContext *c = buffer_filter->priv;
161− int ret;
162−
163− if (picref->video->w != c->w || picref->video->h != c->h || picref->format != c->pix_fmt) {
164− AVFilterContext *scale = buffer_filter->outputs[0]->dst;
165− AVFilterLink *link;
166− char scale_param[1024];
167−
168− av_log(buffer_filter, AV_LOG_INFO,
169− "Buffer video input changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
170− c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,
171− picref->video->w, picref->video->h, av_pix_fmt_descriptors[picref->format].name);
172−
173− if (!scale || strcmp(scale->filter->name, "scale")) {
174− AVFilter *f = avfilter_get_by_name("scale");
175−
176− av_log(buffer_filter, AV_LOG_INFO, "Inserting scaler filter\n");
177− if ((ret = avfilter_open(&scale, f, "Input equalizer")) < 0)
178− return ret;
179−
180− c->scale = scale;
181−
182− snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s", c->w, c->h, c->sws_param);
183− if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0) {
184− return ret;
185− }
186−
187− if ((ret = avfilter_insert_filter(buffer_filter->outputs[0], scale, 0, 0)) < 0) {
188− return ret;
189− }
190− scale->outputs[0]->time_base = scale->inputs[0]->time_base;
191−
192− scale->outputs[0]->format= c->pix_fmt;
193− } else if (!strcmp(scale->filter->name, "scale")) {
194− snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s",
195− scale->outputs[0]->w, scale->outputs[0]->h, c->sws_param);
196− scale->filter->init(scale, scale_param, NULL);
197− }
198−
199− c->pix_fmt = scale->inputs[0]->format = picref->format;
200− c->w = scale->inputs[0]->w = picref->video->w;
201− c->h = scale->inputs[0]->h = picref->video->h;
202−
203− link = scale->outputs[0];
204− if ((ret = link->srcpad->config_props(link)) < 0)
205− return ret;
206− }
207− return 0;
208−}
209−
210−static int check_format_change_audio(AVFilterContext *ctx,
211− AVFilterBufferRef *samplesref)
212−{
213− BufferSourceContext *abuffer = ctx->priv;
214− AVFilterLink *link;
215− int ret, logged = 0;
216−
217− link = ctx->outputs[0];
218− if (samplesref->audio->sample_rate != link->sample_rate ||
219− samplesref->format != link->format ||
220− samplesref->audio->channel_layout != link->channel_layout) {
221−
222− log_input_change(ctx, link, samplesref);
223− logged = 1;
224−
225− abuffer->sample_rate = samplesref->audio->sample_rate;
226− abuffer->sample_format = samplesref->format;
227− abuffer->channel_layout = samplesref->audio->channel_layout;
228−
229− if (!abuffer->aresample) {
230− ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample");
231− if (ret < 0) return ret;
232− } else {
233− link = abuffer->aresample->outputs[0];
234− if (samplesref->audio->sample_rate == link->sample_rate &&
235− samplesref->format == link->format &&
236− samplesref->audio->channel_layout == link->channel_layout)
237− remove_filter(&abuffer->aresample);
238− else
239− if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0)
240− return ret;
241− }
242− }
243−
244−
245− return 0;
246−}
247−
248−static int check_format_change(AVFilterContext *buffer_filter,
249− AVFilterBufferRef *picref)
250−{
251− switch (buffer_filter->outputs[0]->type) {
252− case AVMEDIA_TYPE_VIDEO:
253− return check_format_change_video(buffer_filter, picref);
254− case AVMEDIA_TYPE_AUDIO:
255− return check_format_change_audio(buffer_filter, picref);
256− default:
257− return AVERROR(ENOSYS);
258− }
259−}
260−
261−static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx,
262− AVFilterBufferRef *ref)
263−{
264− AVFilterLink *outlink = ctx->outputs[0];
265− AVFilterBufferRef *buf;
266− int channels, data_size, i;
267−
268− switch (outlink->type) {
269−
270− case AVMEDIA_TYPE_VIDEO:
271− buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,
272− ref->video->w, ref->video->h);
273− if(!buf)
274− return NULL;
275− av_image_copy(buf->data, buf->linesize,
276− (void*)ref->data, ref->linesize,
277− ref->format, ref->video->w, ref->video->h);
278− break;
279−
280− case AVMEDIA_TYPE_AUDIO:
281− buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
282− ref->audio->nb_samples);
283− if(!buf)
284− return NULL;
285− channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
286− av_samples_copy(buf->extended_data, ref->buf->extended_data,
287− 0, 0, ref->audio->nb_samples,
288− channels,
289− ref->format);
290− break;
291−
292− default:
293− return NULL;
294− }
295− avfilter_copy_buffer_ref_props(buf, ref);
296− return buf;
297−}
298−
299−int av_buffersrc_add_ref(AVFilterContext *buffer_filter,
300− AVFilterBufferRef *picref, int flags)
301−{
302− BufferSourceContext *c = buffer_filter->priv;
303− AVFilterBufferRef *buf;
304− int ret;
305−
306− if (!picref) {
307− c->eof = 1;
308− return 0;
309− } else if (c->eof)
310− return AVERROR(EINVAL);
311−
312− if (!av_fifo_space(c->fifo) &&
313− (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
314− sizeof(buf))) < 0)
315− return ret;
316−
317− if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {
318− ret = check_format_change(buffer_filter, picref);
319− if (ret < 0)
320− return ret;
321− }
322− if (flags & AV_BUFFERSRC_FLAG_NO_COPY)
323− buf = picref;
324− else
325− buf = copy_buffer_ref(buffer_filter, picref);
326− if(!buf)
327− return -1;
328−
329− if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
330− if (buf != picref)
331− avfilter_unref_buffer(buf);
332− return ret;
333− }
334− c->nb_failed_requests = 0;
335−
336− return 0;
337−}
338−
33970 int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter,
34071 AVFilterBufferRef *picref, int flags)
34172 {
@@ -345,33 +76,6 @@ int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, · 3 unmodified lines
34576 #if CONFIG_AVCODEC
34677 #include "avcodec.h"
34778
348−int av_buffersrc_add_frame(AVFilterContext *buffer_src,
349− const AVFrame *frame, int flags)
350−{
351− AVFilterBufferRef *picref;
352− int ret;
353−
354− if (!frame) /* NULL for EOF */
355− return av_buffersrc_add_ref(buffer_src, NULL, flags);
356−
357− switch (buffer_src->outputs[0]->type) {
358− case AVMEDIA_TYPE_VIDEO:
359− picref = avfilter_get_video_buffer_ref_from_frame(frame, AV_PERM_WRITE);
360− break;
361− case AVMEDIA_TYPE_AUDIO:
362− picref = avfilter_get_audio_buffer_ref_from_frame(frame, AV_PERM_WRITE);
363− break;
364− default:
365− return AVERROR(ENOSYS);
366− }
367− if (!picref)
368− return AVERROR(ENOMEM);
369− ret = av_buffersrc_add_ref(buffer_src, picref, flags);
370− picref->buf->data[0] = NULL;
371− avfilter_unref_buffer(picref);
372− return ret;
373−}
374−
37579 int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src,
37680 const AVFrame *frame, int flags)
37781 {
@@ -379,193 +83,11 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_src, · 1 unmodified line
37983 }
38084 #endif
38185
382−unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
383−{
384− return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
385−}
386−
38786 unsigned av_vsrc_buffer_get_nb_failed_requests(AVFilterContext *buffer_src)
38887 {
38988 return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
39089 }
39190
392−static av_cold int init_video(AVFilterContext *ctx, const char *args, void *opaque)
393−{
394− BufferSourceContext *c = ctx->priv;
395− char pix_fmt_str[128];
396− int ret, n = 0;
397− *c->sws_param = 0;
398−
399− if (!args ||
400− (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d:%255c", &c->w, &c->h, pix_fmt_str,
401− &c->time_base.num, &c->time_base.den,
402− &c->sample_aspect_ratio.num, &c->sample_aspect_ratio.den, c->sws_param)) < 7) {
403− av_log(ctx, AV_LOG_ERROR, "Expected at least 7 arguments, but only %d found in '%s'\n", n, args);
404− return AVERROR(EINVAL);
405− }
406−
407− if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0)
408− return ret;
409−
410− if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
411− return AVERROR(ENOMEM);
412−
413− av_log(ctx, AV_LOG_INFO, "w:%d h:%d pixfmt:%s tb:%d/%d sar:%d/%d sws_param:%s\n",
414− c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,
415− c->time_base.num, c->time_base.den,
416− c->sample_aspect_ratio.num, c->sample_aspect_ratio.den, c->sws_param);
417− return 0;
418−}
419−
420−static av_cold int init_audio(AVFilterContext *ctx, const char *args0, void *opaque)
421−{
422− BufferSourceContext *abuffer = ctx->priv;
423− char *arg = NULL, *ptr, chlayout_str[16];
424− char *args = av_strdup(args0);
425− int ret;
426−
427− arg = av_strtok(args, ":", &ptr);
428−
429−#define ADD_FORMAT(fmt_name) \
430− if (!arg) \
431− goto arg_fail; \
432− if ((ret = ff_parse_##fmt_name(&abuffer->fmt_name, arg, ctx)) < 0) { \
433− av_freep(&args); \
434− return ret; \
435− } \
436− if (*args) \
437− arg = av_strtok(NULL, ":", &ptr)
438−
439− ADD_FORMAT(time_base);
440− ADD_FORMAT(sample_rate);
441− ADD_FORMAT(sample_format);
442− ADD_FORMAT(channel_layout);
443−
444− abuffer->fifo = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*));
445− if (!abuffer->fifo) {
446− av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo, filter init failed.\n");
447− return AVERROR(ENOMEM);
448− }
449−
450− av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str),
451− -1, abuffer->channel_layout);
452− av_log(ctx, AV_LOG_INFO, "format:%s layout:%s rate:%d\n",
453− av_get_sample_fmt_name(abuffer->sample_format), chlayout_str,
454− abuffer->sample_rate);
455− av_freep(&args);
456−
457− return 0;
458−
459−arg_fail:
460− av_log(ctx, AV_LOG_ERROR, "Invalid arguments, must be of the form "
461− "sample_rate:sample_fmt:channel_layout\n");
462− av_freep(&args);
463− return AVERROR(EINVAL);
464−}
465−
466−static av_cold void uninit(AVFilterContext *ctx)
467−{
468− BufferSourceContext *s = ctx->priv;
469− while (s->fifo && av_fifo_size(s->fifo)) {
470− AVFilterBufferRef *buf;
471− av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
472− avfilter_unref_buffer(buf);
473− }
474− av_fifo_free(s->fifo);
475− s->fifo = NULL;
476− avfilter_free(s->scale);
477− s->scale = NULL;
478−}
479−
480−static int query_formats_video(AVFilterContext *ctx)
481−{
482− BufferSourceContext *c = ctx->priv;
483− enum PixelFormat pix_fmts[] = { c->pix_fmt, PIX_FMT_NONE };
484−
485− avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
486− return 0;
487−}
488−
489−static int query_formats_audio(AVFilterContext *ctx)
490−{
491− BufferSourceContext *abuffer = ctx->priv;
492− AVFilterFormats *formats;
493− AVFilterChannelLayouts *layouts;
494−
495− formats = NULL;
496− avfilter_add_format(&formats, abuffer->sample_format);
497− avfilter_set_common_sample_formats(ctx, formats);
498−
499− formats = NULL;
500− avfilter_add_format(&formats, abuffer->sample_rate);
501− ff_set_common_samplerates(ctx, formats);
502−
503− layouts = NULL;
504− ff_add_channel_layout(&layouts, abuffer->channel_layout);
505− ff_set_common_channel_layouts(ctx, layouts);
506−
507− return 0;
508−}
509−
510−static int config_output_video(AVFilterLink *link)
511−{
512− BufferSourceContext *c = link->src->priv;
513−
514− link->w = c->w;
515− link->h = c->h;
516− link->sample_aspect_ratio = c->sample_aspect_ratio;
517− link->time_base = c->time_base;
518−
519− return 0;
520−}
521−
522−static int config_output_audio(AVFilterLink *outlink)
523−{
524− BufferSourceContext *abuffer = outlink->src->priv;
525− outlink->sample_rate = abuffer->sample_rate;
526− outlink->time_base = abuffer->time_base;
527− return 0;
528−}
529−
530−static int request_frame(AVFilterLink *link)
531−{
532− BufferSourceContext *c = link->src->priv;
533− AVFilterBufferRef *buf;
534−
535− if (!av_fifo_size(c->fifo)) {
536− if (c->eof)
537− return AVERROR_EOF;
538− c->nb_failed_requests++;
539− return AVERROR(EAGAIN);
540− }
541− av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
542−
543− switch (link->type) {
544− case AVMEDIA_TYPE_VIDEO:
545− avfilter_start_frame(link, avfilter_ref_buffer(buf, ~0));
546− avfilter_draw_slice(link, 0, link->h, 1);
547− avfilter_end_frame(link);
548− avfilter_unref_buffer(buf);
549− break;
550− case AVMEDIA_TYPE_AUDIO:
551− ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
552− avfilter_unref_buffer(buf);
553− break;
554− default:
555− return AVERROR(ENOSYS);
556− }
557− return 0;
558−}
559−
560−static int poll_frame(AVFilterLink *link)
561−{
562− BufferSourceContext *c = link->src->priv;
563− int size = av_fifo_size(c->fifo);
564− if (!size && c->eof)
565− return AVERROR_EOF;
566− return size/sizeof(AVFilterBufferRef*);
567−}
568−
56991 int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx,
57092 AVFilterBufferRef *samplesref,
57193 int av_unused flags)
@@ -619,40 +141,3 @@ int av_asrc_buffer_add_buffer(AVFilterContext *ctx, · 47 unmodified lines
619141 pts, flags);
620142 )
621143 }
622−
623−AVFilter avfilter_vsrc_buffer = {
624− .name = "buffer",
625− .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
626− .priv_size = sizeof(BufferSourceContext),
627− .query_formats = query_formats_video,
628−
629− .init = init_video,
630− .uninit = uninit,
631−
632− .inputs = (const AVFilterPad[]) {{ .name = NULL }},
633− .outputs = (const AVFilterPad[]) {{ .name = "default",
634− .type = AVMEDIA_TYPE_VIDEO,
635− .request_frame = request_frame,
636− .poll_frame = poll_frame,
637− .config_props = config_output_video, },
638− { .name = NULL}},
639−};
640−
641−AVFilter avfilter_asrc_abuffer = {
642− .name = "abuffer",
643− .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
644− .priv_size = sizeof(BufferSourceContext),
645− .query_formats = query_formats_audio,
646−
647− .init = init_audio,
648− .uninit = uninit,
649−
650− .inputs = (const AVFilterPad[]) {{ .name = NULL }},
651− .outputs = (const AVFilterPad[]) {{ .name = "default",
652− .type = AVMEDIA_TYPE_AUDIO,
653− .request_frame = request_frame,
654− .poll_frame = poll_frame,
655− .config_props = config_output_audio, },
656− { .name = NULL}},
657−};
658−

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t