[FFmpeg-cvslog] libopusenc: Add channel mapping family argument
ffmpeg | branch: master | Michael Graczyk | Tue Jun 14 18:33:15 2016 -0700| [37941878f193a2316c514bd5ba55bfe9d2dfdfcf] | committer: Michael Niedermayer libopusenc: Add channel mapping family argument The default value of -1 indicates that ffmpeg should determine the channel mapping automatically, which was the behavior before this commit. Unless the -mapping_family argument is provided, behavior is unchanged. Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=37941878f193a2316c514bd5ba55bfe9d2dfdfcf --- doc/encoders.texi | 11 libavcodec/libopusenc.c | 165 +++ 2 files changed, 150 insertions(+), 26 deletions(-) diff --git a/doc/encoders.texi b/doc/encoders.texi index f38cad3..d0caa77 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -1184,6 +1184,17 @@ following: 4000, 6000, 8000, 12000, or 2, corresponding to narrowband, mediumband, wideband, super wideband, and fullband respectively. The default is 0 (cutoff disabled). +@item mapping_family (@emph{mapping_family}) +Set channel mapping family to be used by the encoder. The default value of -1 +uses mapping family 0 for mono and stereo inputs, and mapping family 1 +otherwise. The default also disables the surround masking and LFE bandwidth +optimzations in libopus, and requires that the input contains 8 channels or +fewer. + +Other values include 0 for mono and stereo, 1 for surround sound with masking +and LFE bandwidth optimizations, and 255 for independent streams with an +unspecified channel layout. + @end table @section libvorbis diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index c9b96ce..c40fcde 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -38,6 +38,7 @@ typedef struct LibopusEncOpts { float frame_duration; int packet_size; int max_bandwidth; +int mapping_family; } LibopusEncOpts; typedef struct LibopusEncContext { @@ -47,6 +48,7 @@ typedef struct LibopusEncContext { uint8_t *samples; LibopusEncOpts opts; AudioFrameQueue afq; +const uint8_t *encoder_channel_map; } LibopusEncContext; static const uint8_t opus_coupled_streams[8] = { @@ -93,13 +95,11 @@ static void libopus_write_header(AVCodecContext *avctx, int stream_count, bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */ /* Channel mapping */ -if (channels > 2) { -bytestream_put_byte(&p, mapping_family); +bytestream_put_byte(&p, mapping_family); +if (mapping_family != 0) { bytestream_put_byte(&p, stream_count); bytestream_put_byte(&p, coupled_stream_count); bytestream_put_buffer(&p, channel_mapping, channels); -} else { -bytestream_put_byte(&p, 0); } } @@ -157,13 +157,92 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, return OPUS_OK; } +static int libopus_check_max_channels(AVCodecContext *avctx, + int max_channels) { +if (avctx->channels > max_channels) { +av_log(avctx, AV_LOG_ERROR, "Opus mapping family undefined for %d channels.\n", + avctx->channels); +return AVERROR(EINVAL); +} + +return 0; +} + +static int libopus_check_vorbis_layout(AVCodecContext *avctx, int mapping_family) { +av_assert2(avctx->channels < FF_ARRAY_ELEMS(ff_vorbis_channel_layouts)); + +if (!avctx->channel_layout) { +av_log(avctx, AV_LOG_WARNING, + "No channel layout specified. Opus encoder will use Vorbis " + "channel layout for %d channels.\n", avctx->channels); +} else if (avctx->channel_layout != ff_vorbis_channel_layouts[avctx->channels - 1]) { +char name[32]; +av_get_channel_layout_string(name, sizeof(name), avctx->channels, + avctx->channel_layout); +av_log(avctx, AV_LOG_ERROR, + "Invalid channel layout %s for specified mapping family %d.\n", + name, mapping_family); + +return AVERROR(EINVAL); +} + +return 0; +} + +static int libopus_validate_layout_and_get_channel_map( +AVCodecContext *avctx, +int mapping_family, +const uint8_t ** channel_map_result) +{ +const uint8_t * channel_map = NULL; +int ret; + +switch (mapping_family) { +case -1: +ret = libopus_check_max_channels(avctx, 8); +if (ret == 0) { +ret = libopus_check_vorbis_layout(avctx, mapping_family); +/* Channels do not need to be reordered. */ +} + +break; +case 0: +ret = libopus_check_max_channels(avctx, 2); +if (ret == 0) { +ret = libopus_check_vorbis_layout(avctx, mapping_family); +} +break; +case 1: +/* Opus expec
[FFmpeg-cvslog] libopusenc: Refactor to simplify forthcoming mapping_family parameter
ffmpeg | branch: master | Michael Graczyk | Tue Jun 14 18:30:36 2016 -0700| [a1e3c7cf0fd982d4d82146c4cbe78f6255ae9ca2] | committer: Michael Niedermayer libopusenc: Refactor to simplify forthcoming mapping_family parameter Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a1e3c7cf0fd982d4d82146c4cbe78f6255ae9ca2 --- libavcodec/libopusenc.c | 79 ++- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 3f3e80d..c9b96ce 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -79,6 +79,7 @@ static const uint8_t libavcodec_libopus_channel_map[8][8] = { static void libopus_write_header(AVCodecContext *avctx, int stream_count, int coupled_stream_count, + int mapping_family, const uint8_t *channel_mapping) { uint8_t *p = avctx->extradata; @@ -93,7 +94,7 @@ static void libopus_write_header(AVCodecContext *avctx, int stream_count, /* Channel mapping */ if (channels > 2) { -bytestream_put_byte(&p, channels <= 8 ? 1 : 255); +bytestream_put_byte(&p, mapping_family); bytestream_put_byte(&p, stream_count); bytestream_put_byte(&p, coupled_stream_count); bytestream_put_buffer(&p, channel_mapping, channels); @@ -159,37 +160,11 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, static av_cold int libopus_encode_init(AVCodecContext *avctx) { LibopusEncContext *opus = avctx->priv_data; -const uint8_t *channel_mapping; OpusMSEncoder *enc; +uint8_t libopus_channel_mapping[255]; int ret = OPUS_OK; int coupled_stream_count, header_size, frame_size; -coupled_stream_count = opus_coupled_streams[avctx->channels - 1]; -opus->stream_count = avctx->channels - coupled_stream_count; -channel_mapping = libavcodec_libopus_channel_map[avctx->channels - 1]; - -/* FIXME: Opus can handle up to 255 channels. However, the mapping for - * anything greater than 8 is undefined. */ -if (avctx->channels > 8) { -av_log(avctx, AV_LOG_ERROR, - "Channel layout undefined for %d channels.\n", avctx->channels); -return AVERROR_PATCHWELCOME; -} -if (!avctx->bit_rate) { -/* Sane default copied from opusenc */ -avctx->bit_rate = 64000 * opus->stream_count + - 32000 * coupled_stream_count; -av_log(avctx, AV_LOG_WARNING, - "No bit rate set. Defaulting to %"PRId64" bps.\n", (int64_t)avctx->bit_rate); -} - -if (avctx->bit_rate < 500 || avctx->bit_rate > 256000 * avctx->channels) { -av_log(avctx, AV_LOG_ERROR, "The bit rate %"PRId64" bps is unsupported. " - "Please choose a value between 500 and %d.\n", (int64_t)avctx->bit_rate, - 256000 * avctx->channels); -return AVERROR(EINVAL); -} - frame_size = opus->opts.frame_duration * 48000 / 1000; switch (frame_size) { case 120: @@ -251,17 +226,49 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) } } -enc = opus_multistream_encoder_create(avctx->sample_rate, avctx->channels, - opus->stream_count, - coupled_stream_count, - channel_mapping, - opus->opts.application, &ret); +/* FIXME: Opus can handle up to 255 channels. However, the mapping for + * anything greater than 8 is undefined. */ +if (avctx->channels > 8) { +av_log(avctx, AV_LOG_ERROR, + "Channel layout undefined for %d channels.\n", avctx->channels); +return AVERROR_PATCHWELCOME; +} + +coupled_stream_count = opus_coupled_streams[avctx->channels - 1]; +opus->stream_count = avctx->channels - coupled_stream_count; + +memcpy(libopus_channel_mapping, + opus_vorbis_channel_map[avctx->channels - 1], + avctx->channels * sizeof(*libopus_channel_mapping)); + +enc = opus_multistream_encoder_create( +avctx->sample_rate, avctx->channels, opus->stream_count, +coupled_stream_count, +libavcodec_libopus_channel_map[avctx->channels - 1], +opus->opts.application, &ret); + if (ret != OPUS_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to create encoder: %s\n", opus_strerror(ret)); return ff_opus_error_to_averror(ret); } +if (!avctx->bit_rate) { +/* Sane default copied from opusenc */
[FFmpeg-cvslog] libavcodec/opus: Fix spelling in error message
ffmpeg | branch: master | Michael Graczyk | Thu Sep 1 11:24:31 2016 -0700| [5d054a1ac45248db9fd9ba4ea192147ad35aa54c] | committer: Lou Logan libavcodec/opus: Fix spelling in error message > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5d054a1ac45248db9fd9ba4ea192147ad35aa54c --- libavcodec/opus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/opus.c b/libavcodec/opus.c index 703d2e8..29854fc 100644 --- a/libavcodec/opus.c +++ b/libavcodec/opus.c @@ -328,7 +328,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, channels = avctx->extradata ? extradata[9] : (avctx->channels == 1) ? 1 : 2; if (!channels) { -av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extadata\n"); +av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n"); return AVERROR_INVALIDDATA; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] libavcodec/opus: Add channel mapping 2 to extradata parser
ffmpeg | branch: master | Michael Graczyk | Thu Sep 1 11:17:30 2016 -0700| [be07c25896bb608ee84a902e6a470b87c741115b] | committer: Michael Niedermayer libavcodec/opus: Add channel mapping 2 to extradata parser This allows libavcodec/opus to demux ambisonics in an ogg/opus container. Channel mapping family 2 is being added in this standards track IETF draft: tools.ietf.org/html/draft-ietf-codec-ambisonics-00 Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=be07c25896bb608ee84a902e6a470b87c741115b --- libavcodec/opus.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/opus.c b/libavcodec/opus.c index 29854fc..08d94b6 100644 --- a/libavcodec/opus.c +++ b/libavcodec/opus.c @@ -347,7 +347,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, streams= 1; stereo_streams = channels - 1; channel_map= default_channel_map; -} else if (map_type == 1 || map_type == 255) { +} else if (map_type == 1 || map_type == 2 || map_type == 255) { if (extradata_size < 21 + channels) { av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extradata_size); @@ -371,6 +371,15 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, } layout = ff_vorbis_channel_layouts[channels - 1]; channel_reorder = channel_reorder_vorbis; +} else if (map_type == 2) { +int ambisonic_order = ff_sqrt(channels) - 1; +if (channels != (ambisonic_order + 1) * (ambisonic_order + 1)) { +av_log(avctx, AV_LOG_ERROR, + "Channel mapping 2 is only specified for channel counts" + " which can be written as (n + 1)^2 for nonnegative integer n\n"); +return AVERROR_INVALIDDATA; +} +layout = 0; } else layout = 0; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog