Signed-off-by: James Almer <jamr...@gmail.com> --- libavcodec/libopusenc.c | 55 +++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 13 deletions(-)
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 6b8b2cda0e..fcd0254be3 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -191,21 +191,25 @@ static int libopus_check_max_channels(AVCodecContext *avctx, } static int libopus_check_vorbis_layout(AVCodecContext *avctx, int mapping_family) { - av_assert2(avctx->ch_layout.nb_channels < FF_ARRAY_ELEMS(ff_vorbis_ch_layouts)); - if (avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) { av_log(avctx, AV_LOG_WARNING, "No channel layout specified. Opus encoder will use Vorbis " "channel layout for %d channels.\n", avctx->ch_layout.nb_channels); - } else if (av_channel_layout_compare(&avctx->ch_layout, &ff_vorbis_ch_layouts[avctx->ch_layout.nb_channels - 1])) { - char name[32]; - - av_channel_layout_describe(&avctx->ch_layout, name, sizeof(name)); - av_log(avctx, AV_LOG_ERROR, - "Invalid channel layout %s for specified mapping family %d.\n", - name, mapping_family); - - return AVERROR(EINVAL); + } else if (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) { + av_assert2(avctx->ch_layout.nb_channels < FF_ARRAY_ELEMS(ff_vorbis_ch_layouts)); + if (av_channel_layout_compare(&avctx->ch_layout, &ff_vorbis_ch_layouts[avctx->ch_layout.nb_channels - 1])) { + char name[32]; + av_channel_layout_describe(&avctx->ch_layout, name, sizeof(name)); + av_log(avctx, AV_LOG_ERROR, + "Invalid channel layout %s for specified mapping family %d.\n", + name, mapping_family); + + return AVERROR(EINVAL); + } + } else if (avctx->ch_layout.order != AV_CHANNEL_ORDER_AMBISONIC) { + av_log(avctx, AV_LOG_WARNING, + "Unsupported channel layout specified. Opus encoder will use Vorbis " + "channel layout for %d channels.\n", avctx->ch_layout.nb_channels); } return 0; @@ -221,7 +225,8 @@ static int libopus_validate_layout_and_get_channel_map( switch (mapping_family) { case -1: - ret = libopus_check_max_channels(avctx, 8); + ret = libopus_check_max_channels(avctx, avctx->ch_layout.order == AV_CHANNEL_ORDER_AMBISONIC + ? 227 : 8); if (ret == 0) { ret = libopus_check_vorbis_layout(avctx, mapping_family); /* Channels do not need to be reordered. */ @@ -242,6 +247,9 @@ static int libopus_validate_layout_and_get_channel_map( channel_map = ff_vorbis_channel_layout_offsets[avctx->ch_layout.nb_channels - 1]; } break; + case 2: + ret = libopus_check_max_channels(avctx, 227); + break; case 255: ret = libopus_check_max_channels(avctx, 254); break; @@ -345,7 +353,7 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) return av_ret; } - if (opus->opts.mapping_family == -1) { + if (opus->opts.mapping_family == -1 && avctx->ch_layout.order != AV_CHANNEL_ORDER_AMBISONIC) { /* By default, use mapping family 1 for the header but use the older * libopus multistream API to avoid surround masking. */ @@ -367,6 +375,27 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) * mapping and coupled stream counts to its internal defaults and will * use surround masking analysis to save bits. */ mapping_family = opus->opts.mapping_family; + if (mapping_family == -1) { + int ambisonic_order, non_diegetic_channels; + + mapping_family = 2; + av_assert2(avctx->ch_layout.order == AV_CHANNEL_ORDER_AMBISONIC); + ambisonic_order = av_channel_layout_ambisonic_order(&avctx->ch_layout); + if (ambisonic_order < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid ambisonic channel layout for mapping channel 2\n"); + ret = AVERROR(EINVAL); + goto fail; + } + + non_diegetic_channels = channels - (ambisonic_order + 1) * (ambisonic_order + 1); + if (non_diegetic_channels && + (non_diegetic_channels != 2 || + av_channel_layout_subset(&avctx->ch_layout, AV_CH_LAYOUT_STEREO) != AV_CH_LAYOUT_STEREO)) { + av_log(avctx, AV_LOG_ERROR, "Invalid amount of non-diegetic channels for mapping channel 2\n"); + ret = AVERROR(EINVAL); + goto fail; + } + } enc = opus_multistream_surround_encoder_create( avctx->sample_rate, channels, mapping_family, &opus->stream_count, &coupled_stream_count, libopus_channel_mapping, -- 2.46.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".