aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/avfiltergraph.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-05-23 21:41:13 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-05-23 21:48:31 +0200
commitd0ad91c258821708ce21b4ae53018922ef1f5614 (patch)
tree95332c7c22137cedd30a84bcc51cf6924ee2d631 /libavfilter/avfiltergraph.c
parentd0f78e77e1cde44532d613525a4f521e8effe3ed (diff)
parent3f9d6e423978f5e905def374e9c2e9166e3ebb2c (diff)
downloadffmpeg-d0ad91c258821708ce21b4ae53018922ef1f5614.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: os_support: Define SHUT_RD, SHUT_WR and SHUT_RDWR on OS/2 http: Add support for reading http POST reply headers http: Add http_shutdown() for ending writing of posts tcp: Allow signalling end of reading/writing avio: Add a function for signalling end of reading/writing lavfi: fix comment, audio is supported now. lavfi: fix incorrect comment. lavfi: remove avfilter_null_* from public API on next bump. lavfi: remove avfilter_default_* from public API on next bump. lavfi: deprecate default config_props() callback and refactor avfilter_config_links() avfiltergraph: smarter sample format selection. avconv: rename transcode_audio/video to decode_audio/video. asyncts: reset delta to 0 when it's not used. x86: lavc: use %if HAVE_AVX guards around AVX functions in yasm code. dwt: return errors from ff_slice_buffer_init() Conflicts: ffmpeg.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/formats.c libavfilter/version.h libavfilter/vf_blackframe.c libavfilter/vf_drawtext.c libavfilter/vf_fade.c libavfilter/vf_format.c libavfilter/vf_showinfo.c libavfilter/video.c libavfilter/video.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/avfiltergraph.c')
-rw-r--r--libavfilter/avfiltergraph.c73
1 files changed, 71 insertions, 2 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 9743009eb5..8d2312e05d 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -227,7 +227,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
if (graph->filters[i]->filter->query_formats)
graph->filters[i]->filter->query_formats(graph->filters[i]);
else
- avfilter_default_query_formats(graph->filters[i]);
+ ff_default_query_formats(graph->filters[i]);
}
/* go through and merge as many format lists as possible */
@@ -571,6 +571,74 @@ static void swap_channel_layouts(AVFilterGraph *graph)
swap_channel_layouts_on_filter(graph->filters[i]);
}
+static void swap_sample_fmts_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ int format, bps;
+ int i, j;
+
+ for (i = 0; i < filter->input_count; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_formats->format_count == 1)
+ break;
+ }
+ if (i == filter->input_count)
+ return;
+
+ format = link->out_formats->formats[0];
+ bps = av_get_bytes_per_sample(format);
+
+ for (i = 0; i < filter->output_count; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ int best_idx, best_score = INT_MIN;
+
+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
+ outlink->in_formats->format_count < 2)
+ continue;
+
+ for (j = 0; j < outlink->in_formats->format_count; j++) {
+ int out_format = outlink->in_formats->formats[j];
+ int out_bps = av_get_bytes_per_sample(out_format);
+ int score;
+
+ if (av_get_packed_sample_fmt(out_format) == format ||
+ av_get_planar_sample_fmt(out_format) == format) {
+ best_idx = j;
+ break;
+ }
+
+ /* for s32 and float prefer double to prevent loss of information */
+ if (bps == 4 && out_bps == 8) {
+ best_idx = j;
+ break;
+ }
+
+ /* prefer closest higher or equal bps */
+ score = -abs(out_bps - bps);
+ if (out_bps >= bps)
+ score += INT_MAX/2;
+
+ if (score > best_score) {
+ best_score = score;
+ best_idx = j;
+ }
+ }
+ FFSWAP(int, outlink->in_formats->formats[0],
+ outlink->in_formats->formats[best_idx]);
+ }
+}
+
+static void swap_sample_fmts(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->filter_count; i++)
+ swap_sample_fmts_on_filter(graph->filters[i]);
+
+}
+
static int pick_formats(AVFilterGraph *graph)
{
int i, j, ret;
@@ -633,8 +701,9 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
* of format conversion inside filters */
reduce_formats(graph);
- /* for audio filters, ensure the best sample rate and channel layout
+ /* for audio filters, ensure the best format, sample rate and channel layout
* is selected */
+ swap_sample_fmts(graph);
swap_samplerates(graph);
swap_channel_layouts(graph);