Commit 204c7caf authored by Menno's avatar Menno Committed by Michael Niedermayer

avcodec/libopus: support disabling phase inversion.

Signed-off-by: 's avatarMenno <mrdegier@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 26d879c1
...@@ -981,6 +981,11 @@ Other values include 0 for mono and stereo, 1 for surround sound with masking ...@@ -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 and LFE bandwidth optimizations, and 255 for independent streams with an
unspecified channel layout. 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 @end table
@anchor{libshine} @anchor{libshine}
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "libavutil/internal.h" #include "libavutil/internal.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/ffmath.h" #include "libavutil/ffmath.h"
#include "libavutil/opt.h"
#include "avcodec.h" #include "avcodec.h"
#include "internal.h" #include "internal.h"
...@@ -33,11 +34,15 @@ ...@@ -33,11 +34,15 @@
#include "libopus.h" #include "libopus.h"
struct libopus_context { struct libopus_context {
AVClass *class;
OpusMSDecoder *dec; OpusMSDecoder *dec;
int pre_skip; int pre_skip;
#ifndef OPUS_SET_GAIN #ifndef OPUS_SET_GAIN
union { int i; double d; } gain; union { int i; double d; } gain;
#endif #endif
#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
int apply_phase_inv;
#endif
}; };
#define OPUS_HEAD_SIZE 19 #define OPUS_HEAD_SIZE 19
...@@ -136,6 +141,15 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) ...@@ -136,6 +141,15 @@ static av_cold int libopus_decode_init(AVCodecContext *avc)
} }
#endif #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 */ /* Decoder delay (in samples) at 48kHz */
avc->delay = avc->internal->skip_samples = opus->pre_skip; avc->delay = avc->internal->skip_samples = opus->pre_skip;
...@@ -209,6 +223,24 @@ static void libopus_flush(AVCodecContext *avc) ...@@ -209,6 +223,24 @@ static void libopus_flush(AVCodecContext *avc)
avc->internal->skip_samples = opus->pre_skip; 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 },
#endif
{ NULL },
};
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 = { AVCodec ff_libopus_decoder = {
.name = "libopus", .name = "libopus",
.long_name = NULL_IF_CONFIG_SMALL("libopus Opus"), .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"),
...@@ -223,5 +255,6 @@ AVCodec ff_libopus_decoder = { ...@@ -223,5 +255,6 @@ AVCodec ff_libopus_decoder = {
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE },
.priv_class = &libopusdec_class,
.wrapper_name = "libopus", .wrapper_name = "libopus",
}; };
...@@ -39,6 +39,9 @@ typedef struct LibopusEncOpts { ...@@ -39,6 +39,9 @@ typedef struct LibopusEncOpts {
int packet_size; int packet_size;
int max_bandwidth; int max_bandwidth;
int mapping_family; int mapping_family;
#ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
int apply_phase_inv;
#endif
} LibopusEncOpts; } LibopusEncOpts;
typedef struct LibopusEncContext { typedef struct LibopusEncContext {
...@@ -154,6 +157,14 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, ...@@ -154,6 +157,14 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc,
"Unable to set maximum bandwidth: %s\n", opus_strerror(ret)); "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; return OPUS_OK;
} }
...@@ -530,6 +541,9 @@ static const AVOption libopus_options[] = { ...@@ -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" }, { "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" }, { "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" }, { "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 }, { NULL },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment