On Fri, Jan 26, 2018 at 11:30 AM, Menno de Gier <mrdeg...@gmail.com> wrote:
> From: Menno <mrdeg...@gmail.com> > > This supports disabling phase inversion in both the libopus encoder and the > decoder. > > Signed-off-by: Menno <mrdeg...@gmail.com> > --- > doc/encoders.texi | 5 +++++ > libavcodec/libopusdec.c | 33 +++++++++++++++++++++++++++++++++ > libavcodec/libopusenc.c | 14 ++++++++++++++ > 3 files changed, 52 insertions(+) > > diff --git a/doc/encoders.texi b/doc/encoders.texi > index 6a410a8cb6..c5dfc646d9 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -981,6 +981,11 @@ 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. > > +@item apply_phase_inv (N.A.) (requires libopus >= 1.2) > +If set to 0, disables the use of phase inversion for intensity stereo, > +improving the quality of mono downmixes, but slightly reducing normal > stereo > +quality. The default is 1 (phase inversion enabled). > + > @end table > > @anchor{libshine} > diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c > index 4f7f4755c2..f82ae57e54 100644 > --- a/libavcodec/libopusdec.c > +++ b/libavcodec/libopusdec.c > @@ -25,6 +25,7 @@ > #include "libavutil/internal.h" > #include "libavutil/intreadwrite.h" > #include "libavutil/ffmath.h" > +#include "libavutil/opt.h" > > #include "avcodec.h" > #include "internal.h" > @@ -33,11 +34,15 @@ > #include "libopus.h" > > struct libopus_context { > + AVClass *class; > OpusMSDecoder *dec; > int pre_skip; > #ifndef OPUS_SET_GAIN > union { int i; double d; } gain; > #endif > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + int apply_phase_inv; > +#endif > }; > > #define OPUS_HEAD_SIZE 19 > @@ -136,6 +141,15 @@ static av_cold int libopus_decode_init(AVCodecContext > *avc) > } > #endif > > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + ret = opus_multistream_decoder_ctl(opus->dec, > + OPUS_SET_PHASE_INVERSION_ > DISABLED(!opus->apply_phase_inv)); > + if (ret != OPUS_OK) > + av_log(avc, AV_LOG_WARNING, > + "Unable to set phase inversion: %s\n", > + opus_strerror(ret)); > +#endif > + > /* Decoder delay (in samples) at 48kHz */ > avc->delay = avc->internal->skip_samples = opus->pre_skip; > > @@ -209,6 +223,24 @@ static void libopus_flush(AVCodecContext *avc) > avc->internal->skip_samples = opus->pre_skip; > } > > + > +#define OFFSET(x) offsetof(struct libopus_context, x) > +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM > +static const AVOption libopusdec_options[] = { > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + { "apply_phase_inv", "Apply intensity stereo phase inversion", > OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, > + { NULL }, > +#endif > +}; > + > +static const AVClass libopusdec_class = { > + .class_name = "libopusdec", > + .item_name = av_default_item_name, > + .option = libopusdec_options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > + > AVCodec ff_libopus_decoder = { > .name = "libopus", > .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), > @@ -223,5 +255,6 @@ AVCodec ff_libopus_decoder = { > .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, > AV_SAMPLE_FMT_S16, > AV_SAMPLE_FMT_NONE }, > + .priv_class = &libopusdec_class, > .wrapper_name = "libopus", > }; > diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c > index b449497d15..4ae81b0bb2 100644 > --- a/libavcodec/libopusenc.c > +++ b/libavcodec/libopusenc.c > @@ -39,6 +39,9 @@ typedef struct LibopusEncOpts { > int packet_size; > int max_bandwidth; > int mapping_family; > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + int apply_phase_inv; > +#endif > } LibopusEncOpts; > > typedef struct LibopusEncContext { > @@ -154,6 +157,14 @@ static int libopus_configure_encoder(AVCodecContext > *avctx, OpusMSEncoder *enc, > "Unable to set maximum bandwidth: %s\n", > opus_strerror(ret)); > } > > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + ret = opus_multistream_encoder_ctl(enc, > + OPUS_SET_PHASE_INVERSION_ > DISABLED(!opts->apply_phase_inv)); > + if (ret != OPUS_OK) > + av_log(avctx, AV_LOG_WARNING, > + "Unable to set phase inversion: %s\n", > + opus_strerror(ret)); > +#endif > return OPUS_OK; > } > > @@ -530,6 +541,9 @@ static const AVOption libopus_options[] = { > { "on", "Use variable bit rate", 0, > AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" }, > { "constrained", "Use constrained VBR", 0, > AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "vbr" }, > { "mapping_family", "Channel Mapping Family", > OFFSET(mapping_family), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, > FLAGS, "mapping_family" }, > +#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST > + { "apply_phase_inv", "Apply intensity stereo phase inversion", > OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, > +#endif > { NULL }, > }; > > -- > 2.16.1 > > Did anyone get a chance to look at this? Happy to make changes if needed of course. -Menno _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel