[FFmpeg-devel] [PATCH] libopusenc: Add channel mapping family argument

Mark Harris mark.hsj at gmail.com
Wed Jun 15 09:27:53 CEST 2016

On Tue, Jun 14, 2016 at 6:49 PM, Michael Graczyk
<mgraczyk-at-google.com at ffmpeg.org> wrote:

> + at item mapping_family (@emph{mapping_family})
> +Set channel mapping family to be used by the encoder. The default is -1
> +(determine channel mapping and layout from channel count). Other values include
> +0 for stereo, 1 for surround sound, and 255 for independent streams with an
> +unspecified channel layout.

This implies that -mapping_family -1 (the default) is the same as some
other -mapping_family 0..255, determined by the input, but it is not.
For example even though 6 input channels will by default cause mapping
family 1 and a 5.1 surround layout to be written, it is required to
explicitly specify -mapping_family 1 to actually enable surround
masking and the special processing of the LFE channel.  It is not
clear why surround masking and LFE processing are not enabled when the
family is defaulted to 1 rather than set to 1 explicitly, but if there
is an intentional difference then this should be clarified in the
documentation.  -mapping_family -1 also imposes a limit on the number
of channels that is not present with -mapping_family 255.

> -    .channel_layouts = ff_vorbis_channel_layouts,

This removes the restrictions on input channel layouts, allowing any
channel layout to be accepted.  However, the code does not appear to
check the channel_layout, it only looks at the number of channels as
before.  That means, for example, that it will no longer produce any
error for a 6.0 layout or a hexagonal layout, but the code still
assumes that 6 channels have a 5.1 layout and will write it as such by
default, without even a warning.

If the layout is not supported it should not be silently reinterpreted
as a completely different layout.  See libvorbis_setup() for an
example of code that checks for a supported layout.

>      if (channels > 2) {
> -        bytestream_put_byte(&p, channels <= 8 ? 1 : 255);
> +        bytestream_put_byte(&p, mapping_family);

When channels <= 2, the mapping family will still be 0 even if
-mapping_family 255 was explicitly specified.

> +        /* Channels must be reordered to match opus mapping. */
> +        opus->encoder_channel_map = ff_vorbis_channel_layout_offsets[avctx->channels - 1];

It looks like this is only intended to be used for mapping family 1,
with a channel count between 1 and 8, when the input layout is the one
that is supported by mapping family 1 for that channel count.  However
there are no such checks.

If there are more than 8 channels it appears that it will read beyond
the end of the array.  If the input does not have a family 1 layout
and mapping family 255 was specified, it will still remap the channels
as if they had a family 1 layout.

 - Mark

More information about the ffmpeg-devel mailing list