History

Merge remote-tracking branch 'qatar/master'

* qatar/master: (26 commits) fate: use diff -b in oneline comparison Add missing version bumps and APIchanges/Changelog entries. lavfi: move buffer management function to a separate file. lavfi: move formats-related functions from default.c to formats.c lavfi: move video-related functions to a separate file. fate: make smjpeg a demux test fate: separate sierra-vmd audio and video tests fate: separate smacker audio and video tests libmp3lame: set supported channel layouts. avconv: automatically insert asyncts when -async is used. avconv: add support for audio filters. lavfi: add asyncts filter. lavfi: add aformat filter lavfi: add an audio buffer sink. lavfi: add an audio buffer source. buffersrc: add av_buffersrc_write_frame(). buffersrc: fix invalid read in uninit if the fifo hasn't been allocated lavfi: rename vsrc_buffer.c to buffersrc.c avfiltergraph: reindent lavfi: add channel layout/sample rate negotiation. ... Conflicts: Changelog doc/APIchanges doc/filters.texi ffmpeg.c ffprobe.c libavcodec/libmp3lame.c libavfilter/Makefile libavfilter/af_aformat.c libavfilter/allfilters.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/avfiltergraph.c libavfilter/buffersrc.c libavfilter/defaults.c libavfilter/formats.c libavfilter/src_buffer.c libavfilter/version.h libavfilter/vf_yadif.c libavfilter/vsrc_buffer.c libavfilter/vsrc_buffer.h libavutil/avutil.h tests/fate/audio.mak tests/fate/demux.mak tests/fate/video.mak

Michael Niedermayer committed 14 years ago

Commit 1cbf7fb2 parents a48abf5 0ff0af752 files · +3304 −1706Browse files

Showing the changes to libavfilter/avfiltergraph.c (1 of 52 files). Show all

Unified · Split

libavfilter/avfiltergraph.c+286−50
@@ -28,8 +28,10 @@ · 27 unmodified lines
2828 #include "libavutil/pixdesc.h"
2929 #include "avfilter.h"
3030 #include "avfiltergraph.h"
31+#include "formats.h"
3132 #include "internal.h"
3233
34+#include "libavutil/audioconvert.h"
3335 #include "libavutil/log.h"
3436
3537 static const AVClass filtergraph_class = {
@@ -198,10 +200,10 @@ static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link, · 162 unmodified lines
198200
199201 if (link->type == AVMEDIA_TYPE_AUDIO &&
200202 (((link = filt_ctx-> inputs[0]) &&
201− (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
203+ (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) ||
202204 !avfilter_merge_formats(link->in_packing, link->out_packing))) ||
203205 ((link = filt_ctx->outputs[0]) &&
204− (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
206+ (!ff_merge_channel_layouts(link->in_channel_layouts, link->out_channel_layouts) ||
205207 !avfilter_merge_formats(link->in_packing, link->out_packing))))
206208 ) {
207209 av_log(NULL, AV_LOG_ERROR,
@@ -217,7 +219,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
217219 {
218220 int i, j, ret;
219221 char filt_args[128];
220− AVFilterFormats *formats, *chlayouts, *packing;
222+ AVFilterFormats *formats, *packing;
223+ AVFilterChannelLayouts *chlayouts;
224+ AVFilterFormats *samplerates;
225+ int scaler_count = 0, resampler_count = 0;
221226
222227 /* ask all the sub-filters for their supported media formats */
223228 for (i = 0; i < graph->filter_count; i++) {
@@ -233,6 +238,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
233238
234239 for (j = 0; j < filter->input_count; j++) {
235240 AVFilterLink *link = filter->inputs[j];
241+#if 0
236242 if (!link) continue;
237243
238244 if (!link->in_formats || !link->out_formats)
@@ -248,7 +254,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
248254 return ret;
249255 }
250256 else if (link->type == AVMEDIA_TYPE_AUDIO) {
251− if (!link->in_chlayouts || !link->out_chlayouts ||
257+ if (!link->in_channel_layouts || !link->out_channel_layouts ||
252258 !link->in_packing || !link->out_packing)
253259 return AVERROR(EINVAL);
254260
@@ -256,11 +262,100 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line
256262 * three categories, aconvert will use a common format
257263 * whenever possible. */
258264 formats = avfilter_merge_formats(link->in_formats, link->out_formats);
259− chlayouts = avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts);
265+ chlayouts = ff_merge_channel_layouts(link->in_channel_layouts , link->out_channel_layouts);
266+ samplerates = ff_merge_samplerates (link->in_samplerates, link->out_samplerates);
260267 packing = avfilter_merge_formats(link->in_packing, link->out_packing);
261− if (!formats || !chlayouts || !packing)
268+
269+ if (!formats || !chlayouts || !packing || !samplerates)
262270 if (ret = insert_conv_filter(graph, link, "aconvert", NULL))
263271 return ret;
272+#else
273+ int convert_needed = 0;
274+
275+ if (!link)
276+ continue;
277+
278+ if (link->in_formats != link->out_formats &&
279+ !avfilter_merge_formats(link->in_formats,
280+ link->out_formats))
281+ convert_needed = 1;
282+ if (link->type == AVMEDIA_TYPE_AUDIO) {
283+ if (link->in_channel_layouts != link->out_channel_layouts &&
284+ !ff_merge_channel_layouts(link->in_channel_layouts,
285+ link->out_channel_layouts))
286+ convert_needed = 1;
287+ if (link->in_samplerates != link->out_samplerates &&
288+ !ff_merge_samplerates(link->in_samplerates,
289+ link->out_samplerates))
290+ convert_needed = 1;
291+ }
292+
293+ if (convert_needed) {
294+ AVFilterContext *convert;
295+ AVFilter *filter;
296+ AVFilterLink *inlink, *outlink;
297+ char scale_args[256];
298+ char inst_name[30];
299+
300+ /* couldn't merge format lists. auto-insert conversion filter */
301+ switch (link->type) {
302+ case AVMEDIA_TYPE_VIDEO:
303+ snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
304+ scaler_count++);
305+ snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
306+ if ((ret = avfilter_graph_create_filter(&convert,
307+ avfilter_get_by_name("scale"),
308+ inst_name, scale_args, NULL,
309+ graph)) < 0)
310+ return ret;
311+ break;
312+ case AVMEDIA_TYPE_AUDIO:
313+ if (!(filter = avfilter_get_by_name("resample"))) {
314+ av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
315+ "not present, cannot convert audio formats.\n");
316+ return AVERROR(EINVAL);
317+ }
318+
319+ snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
320+ resampler_count++);
321+ if ((ret = avfilter_graph_create_filter(&convert,
322+ avfilter_get_by_name("resample"),
323+ inst_name, NULL, NULL, graph)) < 0)
324+ return ret;
325+ break;
326+ default:
327+ return AVERROR(EINVAL);
328+ }
329+
330+ if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
331+ return ret;
332+
333+ convert->filter->query_formats(convert);
334+ inlink = convert->inputs[0];
335+ outlink = convert->outputs[0];
336+ if (!avfilter_merge_formats( inlink->in_formats, inlink->out_formats) ||
337+ !avfilter_merge_formats(outlink->in_formats, outlink->out_formats))
338+ ret |= AVERROR(ENOSYS);
339+ if (inlink->type == AVMEDIA_TYPE_AUDIO &&
340+ (!ff_merge_samplerates(inlink->in_samplerates,
341+ inlink->out_samplerates) ||
342+ !ff_merge_channel_layouts(inlink->in_channel_layouts,
343+ inlink->out_channel_layouts)))
344+ ret |= AVERROR(ENOSYS);
345+ if (outlink->type == AVMEDIA_TYPE_AUDIO &&
346+ (!ff_merge_samplerates(outlink->in_samplerates,
347+ outlink->out_samplerates) ||
348+ !ff_merge_channel_layouts(outlink->in_channel_layouts,
349+ outlink->out_channel_layouts)))
350+ ret |= AVERROR(ENOSYS);
351+
352+ if (ret < 0) {
353+ av_log(log_ctx, AV_LOG_ERROR,
354+ "Impossible to convert between the formats supported by the filter "
355+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
356+ return ret;
357+ }
358+#endif
264359 }
265360 }
266361 }
@@ -268,10 +363,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line
268363 return 0;
269364 }
270365
271−static void pick_format(AVFilterLink *link, AVFilterLink *ref)
366+static int pick_format(AVFilterLink *link, AVFilterLink *ref)
272367 {
273368 if (!link || !link->in_formats)
274− return;
369+ return 0;
275370
276371 if (link->type == AVMEDIA_TYPE_VIDEO) {
277372 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
@@ -288,50 +383,83 @@ static void pick_format(AVFilterLink *link, AVFilterLink *ref) · 10 unmodified lines
288383
289384 link->in_formats->format_count = 1;
290385 link->format = link->in_formats->formats[0];
291− avfilter_formats_unref(&link->in_formats);
292− avfilter_formats_unref(&link->out_formats);
293386
294387 if (link->type == AVMEDIA_TYPE_AUDIO) {
295− link->in_chlayouts->format_count = 1;
296− link->channel_layout = link->in_chlayouts->formats[0];
297− avfilter_formats_unref(&link->in_chlayouts);
298− avfilter_formats_unref(&link->out_chlayouts);
299−
300− link->in_packing->format_count = 1;
301− link->planar = link->in_packing->formats[0] == AVFILTER_PLANAR;
302− avfilter_formats_unref(&link->in_packing);
303− avfilter_formats_unref(&link->out_packing);
388+ if (!link->in_samplerates->format_count) {
389+ av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
390+ " the link between filters %s and %s.\n", link->src->name,
391+ link->dst->name);
392+ return AVERROR(EINVAL);
393+ }
394+ link->in_samplerates->format_count = 1;
395+ link->sample_rate = link->in_samplerates->formats[0];
396+
397+ if (!link->in_channel_layouts->nb_channel_layouts) {
398+ av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
399+ "the link between filters %s and %s.\n", link->src->name,
400+ link->dst->name);
401+ return AVERROR(EINVAL);
402+ }
403+ link->in_channel_layouts->nb_channel_layouts = 1;
404+ link->channel_layout = link->in_channel_layouts->channel_layouts[0];
304405 }
406+
407+ avfilter_formats_unref(&link->in_formats);
408+ avfilter_formats_unref(&link->out_formats);
409+ avfilter_formats_unref(&link->in_samplerates);
410+ avfilter_formats_unref(&link->out_samplerates);
411+ ff_channel_layouts_unref(&link->in_channel_layouts);
412+ ff_channel_layouts_unref(&link->out_channel_layouts);
413+
414+ return 0;
305415 }
306416
417+#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
418+do { \
419+ for (i = 0; i < filter->input_count; i++) { \
420+ AVFilterLink *link = filter->inputs[i]; \
421+ fmt_type fmt; \
422+ \
423+ if (!link->out_ ## list || link->out_ ## list->nb != 1) \
424+ continue; \
425+ fmt = link->out_ ## list->var[0]; \
426+ \
427+ for (j = 0; j < filter->output_count; j++) { \
428+ AVFilterLink *out_link = filter->outputs[j]; \
429+ list_type *fmts; \
430+ \
431+ if (link->type != out_link->type || \
432+ out_link->in_ ## list->nb == 1) \
433+ continue; \
434+ fmts = out_link->in_ ## list; \
435+ \
436+ if (!out_link->in_ ## list->nb) { \
437+ add_format(&out_link->in_ ##list, fmt); \
438+ break; \
439+ } \
440+ \
441+ for (k = 0; k < out_link->in_ ## list->nb; k++) \
442+ if (fmts->var[k] == fmt) { \
443+ fmts->var[0] = fmt; \
444+ fmts->nb = 1; \
445+ ret = 1; \
446+ break; \
447+ } \
448+ } \
449+ } \
450+} while (0)
451+
307452 static int reduce_formats_on_filter(AVFilterContext *filter)
308453 {
309454 int i, j, k, ret = 0;
310455
311− for (i = 0; i < filter->input_count; i++) {
312− AVFilterLink *link = filter->inputs[i];
313− int format = link->out_formats->formats[0];
314−
315− if (link->out_formats->format_count != 1)
316− continue;
317−
318− for (j = 0; j < filter->output_count; j++) {
319− AVFilterLink *out_link = filter->outputs[j];
320− AVFilterFormats *fmts = out_link->in_formats;
321−
322− if (link->type != out_link->type ||
323− out_link->in_formats->format_count == 1)
324− continue;
456+ REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
457+ format_count, avfilter_add_format);
458+ REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
459+ format_count, avfilter_add_format);
460+ REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
461+ channel_layouts, nb_channel_layouts, ff_add_channel_layout);
325462
326− for (k = 0; k < out_link->in_formats->format_count; k++)
327− if (fmts->formats[k] == format) {
328− fmts->formats[0] = format;
329− fmts->format_count = 1;
330− ret = 1;
331− break;
332− }
333− }
334− }
335463 return ret;
336464 }
337465
@@ -347,9 +475,109 @@ static void reduce_formats(AVFilterGraph *graph) · 9 unmodified lines
347475 } while (reduced);
348476 }
349477
350−static void pick_formats(AVFilterGraph *graph)
478+static void swap_samplerates_on_filter(AVFilterContext *filter)
479+{
480+ AVFilterLink *link = NULL;
481+ int sample_rate;
482+ int i, j;
483+
484+ for (i = 0; i < filter->input_count; i++) {
485+ link = filter->inputs[i];
486+
487+ if (link->type == AVMEDIA_TYPE_AUDIO &&
488+ link->out_samplerates->format_count == 1)
489+ break;
490+ }
491+ if (i == filter->input_count)
492+ return;
493+
494+ sample_rate = link->out_samplerates->formats[0];
495+
496+ for (i = 0; i < filter->output_count; i++) {
497+ AVFilterLink *outlink = filter->outputs[i];
498+ int best_idx, best_diff = INT_MAX;
499+
500+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
501+ outlink->in_samplerates->format_count < 2)
502+ continue;
503+
504+ for (j = 0; j < outlink->in_samplerates->format_count; j++) {
505+ int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
506+
507+ if (diff < best_diff) {
508+ best_diff = diff;
509+ best_idx = j;
510+ }
511+ }
512+ FFSWAP(int, outlink->in_samplerates->formats[0],
513+ outlink->in_samplerates->formats[best_idx]);
514+ }
515+}
516+
517+static void swap_samplerates(AVFilterGraph *graph)
351518 {
519+ int i;
520+
521+ for (i = 0; i < graph->filter_count; i++)
522+ swap_samplerates_on_filter(graph->filters[i]);
523+}
524+
525+static void swap_channel_layouts_on_filter(AVFilterContext *filter)
526+{
527+ AVFilterLink *link = NULL;
528+ uint64_t chlayout;
352529 int i, j;
530+
531+ for (i = 0; i < filter->input_count; i++) {
532+ link = filter->inputs[i];
533+
534+ if (link->type == AVMEDIA_TYPE_AUDIO &&
535+ link->out_channel_layouts->nb_channel_layouts == 1)
536+ break;
537+ }
538+ if (i == filter->input_count)
539+ return;
540+
541+ chlayout = link->out_channel_layouts->channel_layouts[0];
542+
543+ for (i = 0; i < filter->output_count; i++) {
544+ AVFilterLink *outlink = filter->outputs[i];
545+ int best_idx, best_score = INT_MIN;
546+
547+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
548+ outlink->in_channel_layouts->nb_channel_layouts < 2)
549+ continue;
550+
551+ for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {
552+ uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];
553+ int matched_channels = av_get_channel_layout_nb_channels(chlayout &
554+ out_chlayout);
555+ int extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
556+ (~chlayout));
557+ int score = matched_channels - extra_channels;
558+
559+ if (score > best_score) {
560+ best_score = score;
561+ best_idx = j;
562+ }
563+ }
564+ FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
565+ outlink->in_channel_layouts->channel_layouts[best_idx]);
566+ }
567+
568+}
569+
570+static void swap_channel_layouts(AVFilterGraph *graph)
571+{
572+ int i;
573+
574+ for (i = 0; i < graph->filter_count; i++)
575+ swap_channel_layouts_on_filter(graph->filters[i]);
576+}
577+
578+static int pick_formats(AVFilterGraph *graph)
579+{
580+ int i, j, ret;
353581 int change;
354582
355583 do{
@@ -385,13 +613,15 @@ static void pick_formats(AVFilterGraph *graph) · 29 unmodified lines
385613
386614 for (i = 0; i < graph->filter_count; i++) {
387615 AVFilterContext *filter = graph->filters[i];
388− if (1) {
389− for (j = 0; j < filter->input_count; j++)
390− pick_format(filter->inputs[j], NULL);
391− for (j = 0; j < filter->output_count; j++)
392− pick_format(filter->outputs[j], NULL);
393− }
616+
617+ for (j = 0; j < filter->input_count; j++)
618+ if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
619+ return ret;
620+ for (j = 0; j < filter->output_count; j++)
621+ if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
622+ return ret;
394623 }
624+ return 0;
395625 }
396626
397627 int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
@@ -407,7 +637,13 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
407637 * of format conversion inside filters */
408638 reduce_formats(graph);
409639
410− pick_formats(graph);
640+ /* for audio filters, ensure the best sample rate and channel layout
641+ * is selected */
642+ swap_samplerates(graph);
643+ swap_channel_layouts(graph);
644+
645+ if ((ret = pick_formats(graph)) < 0)
646+ return ret;
411647
412648 return 0;
413649 }

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