avfiltergraph: smarter sample format selection.
This commit is contained in:
parent
0629f6128e
commit
ccefa89f39
@ -461,6 +461,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;
|
||||
@ -491,8 +559,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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user