[FFmpeg-devel] [RFC] libavfilter audio - af_resample channel conversion
S.N. Hemanth Meenakshisundaram
smeenaks
Wed Jul 7 13:31:04 CEST 2010
On 07/04/2010 07:57 AM, Stefano Sabatini wrote:
> On date Thursday 2010-07-01 01:42:51 -0700, S.N. Hemanth Meenakshisundaram encoded:
>
>> On 06/25/2010 05:10 PM, Stefano Sabatini wrote:
>>
>>> On date Friday 2010-06-25 03:52:45 -0700, S.N. Hemanth Meenakshisundaram encoded:
>>>
>>>> [...]
>>>>
>>>
>> Hi All,
>>
>> Here is the working af_resample.c and associated Makefile and
>> allfilters.c changes.
>>
> [...]
> All these are duplicated of existing code. I'm not against this if
> this will get us with a working/testable audio filtering framework,
> but put at least a FIXME somewhere.
>
> Also if someone can suggest a better solution to share this code it
> would be even better.
>
>
Hi All,
Here is an idea for a generalized channel conversion function for
af_resample:
We could have a table of gain tables corresponding to various channel
conversions as below:
+static const struct {
+ int64_t in_channel_layout;
+ int64_t out_channel_layout;
+ const float gain[8][8];
+} channel_mixing_table[] = {
+ {
+ .in_channel_layout = CH_LAYOUT_5POINT0,
+ .out_channel_layout = CH_LAYOUT_STEREO,
+ .gain = {
+ {1, 0, 0.5, 0.7, 0},
+ {0, 1, 0.5, 0, 0.7},
+ },
+ }
+};
The table above currently has a single gain table for 5.0 to stereo
downmixing.
We would need to look up an appropriate gain table only when input or
output channel layout changes. When these changes occur, we can also fix
the conversion function to be called to be one of ten function as below
(based on planar/non-planar and sample format).
+/* Generic channel conversion functions in case of short sample format */
+static void generic_planar_convert_short(short **outputs, short
**inputs, float **gains, short in_channels, short out_channels, int
samples_nb)
+{
+ int i, j, k;
+
+ for (j = 0; j < out_channels; j++)
+ for (k = 0; k < in_channels; k++)
+ for (i = 0; i < samples_nb; i++)
+ outputs[j][i] += gains[j][k] * inputs[k][i];
+}
+
+static void generic_packed_convert_short(short **outputs, short
**inputs, float **gains, short in_channels, short out_channels, int
samples_nb)
+{
+ int i, j, k;
+
+ for (i = 0; i < samples_nb; i++)
+ for (j = 0; j < out_channels; j++)
+ for (k = 0; k < in_channels; k++)
+ outputs[i][j] += gains[j][k] * inputs[i][k];
+}
+
And 4*2 other functions for the other 4 sample formats (planar and
non-planar versions for each)
The for loops and multiply-add statements could be factorized as a macro
if necessary for concise representation across the 10 functions. Only
the order of the loops and the pointer types of data would change
between the functions and we would cover all sample formats and any
channel conversion for which a gain table of conversions exists.
I am testing this out for a couple of conversions now.
One potential big drawback of this is the large size of the table of
gain tables. However, if we add these gain tables as and when necessary,
perhaps it is acceptable?
Once the input and output channel layouts are known and channel
conversion required is fixed, there are almost no branches in the data
path except for the predictable loop ones.
In addition to these, perhaps we can keep the stereo-to-mono and
mono-to-stereo functions for the common case.
Is this approach is worth pursuing? Are there any issues with this other
than the large table required?
Regards,
Hemanth
More information about the ffmpeg-devel
mailing list