[FFmpeg-cvslog] libopusenc: Add channel mapping family argument

2016-07-02 Thread Michael Graczyk
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

2016-07-02 Thread Michael Graczyk
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

2016-09-01 Thread Michael Graczyk
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

2016-09-01 Thread Michael Graczyk
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