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
28#include "libavutil/pixdesc.h"28#include "libavutil/pixdesc.h"
29#include "avfilter.h"29#include "avfilter.h"
30#include "avfiltergraph.h"30#include "avfiltergraph.h"
31#include "formats.h"
31#include "internal.h"32#include "internal.h"
32 33
34#include "libavutil/audioconvert.h"
33#include "libavutil/log.h"35#include "libavutil/log.h"
34 36
35static const AVClass filtergraph_class = {37static const AVClass filtergraph_class = {
@@ -198,10 +200,10 @@ static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link, · 162 unmodified lines
198 200
199 if (link->type == AVMEDIA_TYPE_AUDIO &&201 if (link->type == AVMEDIA_TYPE_AUDIO &&
200 (((link = filt_ctx-> inputs[0]) &&202 (((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) ||
202 !avfilter_merge_formats(link->in_packing, link->out_packing))) ||204 !avfilter_merge_formats(link->in_packing, link->out_packing))) ||
203 ((link = filt_ctx->outputs[0]) &&205 ((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) ||
205 !avfilter_merge_formats(link->in_packing, link->out_packing))))207 !avfilter_merge_formats(link->in_packing, link->out_packing))))
206 ) {208 ) {
207 av_log(NULL, AV_LOG_ERROR,209 av_log(NULL, AV_LOG_ERROR,
@@ -217,7 +219,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
217{219{
218 int i, j, ret;220 int i, j, ret;
219 char filt_args[128];221 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;
221 226
222 /* ask all the sub-filters for their supported media formats */227 /* ask all the sub-filters for their supported media formats */
223 for (i = 0; i < graph->filter_count; i++) {228 for (i = 0; i < graph->filter_count; i++) {
@@ -233,6 +238,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
233 238
234 for (j = 0; j < filter->input_count; j++) {239 for (j = 0; j < filter->input_count; j++) {
235 AVFilterLink *link = filter->inputs[j];240 AVFilterLink *link = filter->inputs[j];
241#if 0
236 if (!link) continue;242 if (!link) continue;
237 243
238 if (!link->in_formats || !link->out_formats)244 if (!link->in_formats || !link->out_formats)
@@ -248,7 +254,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
248 return ret;254 return ret;
249 }255 }
250 else if (link->type == AVMEDIA_TYPE_AUDIO) {256 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 ||
252 !link->in_packing || !link->out_packing)258 !link->in_packing || !link->out_packing)
253 return AVERROR(EINVAL);259 return AVERROR(EINVAL);
254 260
@@ -256,11 +262,100 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line
256 * three categories, aconvert will use a common format262 * three categories, aconvert will use a common format
257 * whenever possible. */263 * whenever possible. */
258 formats = avfilter_merge_formats(link->in_formats, link->out_formats);264 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);
260 packing = avfilter_merge_formats(link->in_packing, link->out_packing);267 packing = avfilter_merge_formats(link->in_packing, link->out_packing);
261 if (!formats || !chlayouts || !packing)268
269 if (!formats || !chlayouts || !packing || !samplerates)
262 if (ret = insert_conv_filter(graph, link, "aconvert", NULL))270 if (ret = insert_conv_filter(graph, link, "aconvert", NULL))
263 return ret;271 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
264 }359 }
265 }360 }
266 }361 }
@@ -268,10 +363,10 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 1 unmodified line
268 return 0;363 return 0;
269}364}
270 365
271static void pick_format(AVFilterLink *link, AVFilterLink *ref)366static int pick_format(AVFilterLink *link, AVFilterLink *ref)
272{367{
273 if (!link || !link->in_formats)368 if (!link || !link->in_formats)
274 return;369 return 0;
275 370
276 if (link->type == AVMEDIA_TYPE_VIDEO) {371 if (link->type == AVMEDIA_TYPE_VIDEO) {
277 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){372 if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
@@ -288,50 +383,83 @@ static void pick_format(AVFilterLink *link, AVFilterLink *ref) · 10 unmodified lines
288 383
289 link->in_formats->format_count = 1;384 link->in_formats->format_count = 1;
290 link->format = link->in_formats->formats[0];385 link->format = link->in_formats->formats[0];
291 avfilter_formats_unref(&link->in_formats);
292 avfilter_formats_unref(&link->out_formats);
293 386
294 if (link->type == AVMEDIA_TYPE_AUDIO) {387 if (link->type == AVMEDIA_TYPE_AUDIO) {
295 link->in_chlayouts->format_count = 1;388 if (!link->in_samplerates->format_count) {
296 link->channel_layout = link->in_chlayouts->formats[0];389 av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
297 avfilter_formats_unref(&link->in_chlayouts);390 " the link between filters %s and %s.\n", link->src->name,
298 avfilter_formats_unref(&link->out_chlayouts);391 link->dst->name);
299 392 return AVERROR(EINVAL);
300 link->in_packing->format_count = 1;393 }
301 link->planar = link->in_packing->formats[0] == AVFILTER_PLANAR;394 link->in_samplerates->format_count = 1;
302 avfilter_formats_unref(&link->in_packing);395 link->sample_rate = link->in_samplerates->formats[0];
303 avfilter_formats_unref(&link->out_packing);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];
304 }405 }
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;
305}415}
306 416
417#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \
418do { \
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
307static int reduce_formats_on_filter(AVFilterContext *filter)452static int reduce_formats_on_filter(AVFilterContext *filter)
308{453{
309 int i, j, k, ret = 0;454 int i, j, k, ret = 0;
310 455
311 for (i = 0; i < filter->input_count; i++) {456 REDUCE_FORMATS(int, AVFilterFormats, formats, formats,
312 AVFilterLink *link = filter->inputs[i];457 format_count, avfilter_add_format);
313 int format = link->out_formats->formats[0];458 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
314 459 format_count, avfilter_add_format);
315 if (link->out_formats->format_count != 1)460 REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
316 continue;461 channel_layouts, nb_channel_layouts, ff_add_channel_layout);
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;
325 462
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 }
335 return ret;463 return ret;
336}464}
337 465
@@ -347,9 +475,109 @@ static void reduce_formats(AVFilterGraph *graph) · 9 unmodified lines
347 } while (reduced);475 } while (reduced);
348}476}
349 477
350static void pick_formats(AVFilterGraph *graph)478static 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
517static void swap_samplerates(AVFilterGraph *graph)
351{518{
519 int i;
520
521 for (i = 0; i < graph->filter_count; i++)
522 swap_samplerates_on_filter(graph->filters[i]);
523}
524
525static void swap_channel_layouts_on_filter(AVFilterContext *filter)
526{
527 AVFilterLink *link = NULL;
528 uint64_t chlayout;
352 int i, j;529 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
570static 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
578static int pick_formats(AVFilterGraph *graph)
579{
580 int i, j, ret;
353 int change;581 int change;
354 582
355 do{583 do{
@@ -385,13 +613,15 @@ static void pick_formats(AVFilterGraph *graph) · 29 unmodified lines
385 613
386 for (i = 0; i < graph->filter_count; i++) {614 for (i = 0; i < graph->filter_count; i++) {
387 AVFilterContext *filter = graph->filters[i];615 AVFilterContext *filter = graph->filters[i];
388 if (1) {616
389 for (j = 0; j < filter->input_count; j++)617 for (j = 0; j < filter->input_count; j++)
390 pick_format(filter->inputs[j], NULL);618 if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
391 for (j = 0; j < filter->output_count; j++)619 return ret;
392 pick_format(filter->outputs[j], NULL);620 for (j = 0; j < filter->output_count; j++)
393 }621 if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
622 return ret;
394 }623 }
624 return 0;
395}625}
396 626
397int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)627int 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
407 * of format conversion inside filters */637 * of format conversion inside filters */
408 reduce_formats(graph);638 reduce_formats(graph);
409 639
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;
411 647
412 return 0;648 return 0;
413}649}

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