summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/audio_resample.c102
-rw-r--r--libhb/audio_resample.h45
-rw-r--r--libhb/deca52.c11
-rw-r--r--libhb/decavcodec.c12
-rw-r--r--libhb/declpcm.c8
-rw-r--r--libhb/encavcodecaudio.c5
6 files changed, 117 insertions, 66 deletions
diff --git a/libhb/audio_resample.c b/libhb/audio_resample.c
index ced6d69fd..1e5e10556 100644
--- a/libhb/audio_resample.c
+++ b/libhb/audio_resample.c
@@ -34,15 +34,52 @@ hb_audio_resample_t* hb_audio_resample_init(enum AVSampleFormat output_sample_fm
resample->resample_needed = 0;
resample->avresample = NULL;
+ // set default input characteristics
+ resample->in.sample_fmt = resample->out.sample_fmt;
+ resample->in.channel_layout = resample->out.channel_layout;
+ resample->in.center_mix_level = HB_MIXLEV_DEFAULT;
+ resample->in.surround_mix_level = HB_MIXLEV_DEFAULT;
+
return resample;
}
-int hb_audio_resample_update(hb_audio_resample_t *resample,
- enum AVSampleFormat new_sample_fmt,
- uint64_t new_channel_layout,
- double new_surroundmixlev,
- double new_centermixlev,
- int new_channels)
+void hb_audio_resample_set_channel_layout(hb_audio_resample_t *resample,
+ uint64_t channel_layout,
+ int channels)
+{
+ if (resample != NULL)
+ {
+ channel_layout = hb_ff_layout_xlat(channel_layout, channels);
+ if (channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX)
+ {
+ // Dolby Surround is Stereo when it comes to remixing
+ channel_layout = AV_CH_LAYOUT_STEREO;
+ }
+ resample->in.channel_layout = channel_layout;
+ }
+}
+
+void hb_audio_resample_set_mix_levels(hb_audio_resample_t *resample,
+ double surround_mix_level,
+ double center_mix_level)
+{
+ if (resample != NULL)
+ {
+ resample->in.center_mix_level = center_mix_level;
+ resample->in.surround_mix_level = surround_mix_level;
+ }
+}
+
+void hb_audio_resample_set_sample_fmt(hb_audio_resample_t *resample,
+ enum AVSampleFormat sample_fmt)
+{
+ if (resample != NULL)
+ {
+ resample->in.sample_fmt = sample_fmt;
+ }
+}
+
+int hb_audio_resample_update(hb_audio_resample_t *resample)
{
if (resample == NULL)
{
@@ -52,24 +89,17 @@ int hb_audio_resample_update(hb_audio_resample_t *resample,
int ret, resample_changed;
- new_channel_layout = hb_ff_layout_xlat(new_channel_layout, new_channels);
- if (new_channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX)
- {
- // Dolby Surround is Stereo when it comes to remixing
- new_channel_layout = AV_CH_LAYOUT_STEREO;
- }
-
resample->resample_needed =
(resample->resample_needed ||
- resample->out.sample_fmt != new_sample_fmt ||
- resample->out.channel_layout != new_channel_layout);
+ resample->out.sample_fmt != resample->in.sample_fmt ||
+ resample->out.channel_layout != resample->in.channel_layout);
resample_changed =
(resample->resample_needed &&
- (resample->in.sample_fmt != new_sample_fmt ||
- resample->in.channel_layout != new_channel_layout ||
- resample->in.center_mix_level != new_centermixlev ||
- resample->in.surround_mix_level != new_surroundmixlev));
+ (resample->resample.sample_fmt != resample->in.sample_fmt ||
+ resample->resample.channel_layout != resample->in.channel_layout ||
+ resample->resample.center_mix_level != resample->in.center_mix_level ||
+ resample->resample.surround_mix_level != resample->in.surround_mix_level));
if (resample_changed || (resample->resample_needed &&
resample->avresample == NULL))
@@ -98,13 +128,13 @@ int hb_audio_resample_update(hb_audio_resample_t *resample,
}
av_opt_set_int(resample->avresample, "in_sample_fmt",
- new_sample_fmt, 0);
+ resample->in.sample_fmt, 0);
av_opt_set_int(resample->avresample, "in_channel_layout",
- new_channel_layout, 0);
+ resample->in.channel_layout, 0);
av_opt_set_double(resample->avresample, "center_mix_level",
- new_centermixlev, 0);
+ resample->in.center_mix_level, 0);
av_opt_set_double(resample->avresample, "surround_mix_level",
- new_surroundmixlev, 0);
+ resample->in.surround_mix_level, 0);
if ((ret = avresample_open(resample->avresample)))
{
@@ -117,10 +147,12 @@ int hb_audio_resample_update(hb_audio_resample_t *resample,
return ret;
}
- resample->in.sample_fmt = new_sample_fmt;
- resample->in.channel_layout = new_channel_layout;
- resample->in.center_mix_level = new_centermixlev;
- resample->in.surround_mix_level = new_surroundmixlev;
+ resample->resample.sample_fmt = resample->in.sample_fmt;
+ resample->resample.channel_layout = resample->in.channel_layout;
+ resample->resample.channels =
+ av_get_channel_layout_nb_channels(resample->in.channel_layout);
+ resample->resample.center_mix_level = resample->in.center_mix_level;
+ resample->resample.surround_mix_level = resample->in.surround_mix_level;
}
return 0;
@@ -158,21 +190,19 @@ hb_buffer_t* hb_audio_resample(hb_audio_resample_t *resample,
if (resample->resample_needed)
{
- int out_samples;
+ int in_linesize, out_linesize, out_samples;
// set in/out linesize and out_size
- av_samples_get_buffer_size(&resample->in.linesize,
- resample->in.channels, nsamples,
- resample->in.sample_fmt, 0);
- out_size = av_samples_get_buffer_size(&resample->out.linesize,
+ av_samples_get_buffer_size(&in_linesize,
+ resample->resample.channels, nsamples,
+ resample->resample.sample_fmt, 0);
+ out_size = av_samples_get_buffer_size(&out_linesize,
resample->out.channels, nsamples,
resample->out.sample_fmt, 0);
out = hb_buffer_init(out_size);
out_samples = avresample_convert(resample->avresample,
- (void**)&out->data,
- resample->out.linesize, nsamples,
- (void**)&samples,
- resample->in.linesize, nsamples);
+ (void**)&out->data, out_linesize, nsamples,
+ (void**)&samples, in_linesize, nsamples);
if (out_samples <= 0)
{
diff --git a/libhb/audio_resample.h b/libhb/audio_resample.h
index 29a7f91d0..c853fc2e2 100644
--- a/libhb/audio_resample.h
+++ b/libhb/audio_resample.h
@@ -32,8 +32,6 @@ typedef struct
struct
{
- int channels;
- int linesize;
uint64_t channel_layout;
double center_mix_level;
double surround_mix_level;
@@ -43,7 +41,15 @@ typedef struct
struct
{
int channels;
- int linesize;
+ uint64_t channel_layout;
+ double center_mix_level;
+ double surround_mix_level;
+ enum AVSampleFormat sample_fmt;
+ } resample;
+
+ struct
+ {
+ int channels;
int sample_size;
int normalize_mix_level;
uint64_t channel_layout;
@@ -55,25 +61,38 @@ typedef struct
/* Initialize an hb_audio_resample_t for converting audio to the requested
* sample_fmt and channel_layout, using the specified matrix_encoding.
*
- * Input characteristics are set via hb_audio_resample_update().
+ * Also sets the default audio input characteristics, so that they are the same
+ * as the output characteristics (no conversion needed).
*/
hb_audio_resample_t* hb_audio_resample_init(enum AVSampleFormat output_sample_fmt,
uint64_t output_channel_layout,
enum AVMatrixEncoding matrix_encoding,
int normalize_mix_level);
-/* Update an hb_audio_resample_t, setting the input sample characteristics.
+/* The following functions set the audio input characteristics.
+ *
+ * They should be called whenever the relevant characteristic(s) differ from the
+ * requested output characteristics, or if they may have changed in the source.
*
- * Can be called whenever the input type may change.
+ * Note: channel_layout is automatically sanitized.
+ */
+
+void hb_audio_resample_set_channel_layout(hb_audio_resample_t *resample,
+ uint64_t channel_layout,
+ int channels);
+
+void hb_audio_resample_set_mix_levels(hb_audio_resample_t *resample,
+ double surround_mix_level,
+ double center_mix_level);
+
+void hb_audio_resample_set_sample_fmt(hb_audio_resample_t *resample,
+ enum AVSampleFormat sample_fmt);
+
+/* Update an hb_audio_resample_t.
*
- * new_channel_layout is sanitized automatically.
+ * Must be called after using any of the above functions.
*/
-int hb_audio_resample_update(hb_audio_resample_t *resample,
- enum AVSampleFormat new_sample_fmt,
- uint64_t new_channel_layout,
- double new_surroundmixlev,
- double new_centermixlev,
- int new_channels);
+int hb_audio_resample_update(hb_audio_resample_t *resample);
/* Free an hb_audio_remsample_t. */
void hb_audio_resample_free(hb_audio_resample_t *resample);
diff --git a/libhb/deca52.c b/libhb/deca52.c
index 0df250fe9..9ad603861 100644
--- a/libhb/deca52.c
+++ b/libhb/deca52.c
@@ -373,10 +373,13 @@ static hb_buffer_t* Decode(hb_work_object_t *w)
}
}
}
- if (hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT,
- pv->channel_layout,
- (double)pv->state->slev,
- (double)pv->state->clev, pv->nchannels))
+ hb_audio_resample_set_channel_layout(pv->resample,
+ pv->channel_layout,
+ pv->nchannels);
+ hb_audio_resample_set_mix_levels(pv->resample,
+ (double)pv->state->slev,
+ (double)pv->state->clev);
+ if (hb_audio_resample_update(pv->resample))
{
hb_log("deca52: hb_audio_resample_update() failed");
hb_buffer_close(&flt);
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index d0a64a2b0..4dc1e7388 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -1452,12 +1452,12 @@ static void decodeAudio(hb_audio_t *audio, hb_work_private_t *pv, uint8_t *data,
}
else
{
- if (hb_audio_resample_update(pv->resample,
- pv->context->sample_fmt,
- pv->context->channel_layout,
- HB_MIXLEV_DEFAULT,
- HB_MIXLEV_DEFAULT,
- pv->context->channels))
+ hb_audio_resample_set_channel_layout(pv->resample,
+ context->channel_layout,
+ context->channels);
+ hb_audio_resample_set_sample_fmt(pv->resample,
+ context->sample_fmt);
+ if (hb_audio_resample_update(pv->resample))
{
hb_log("decavcodec: hb_audio_resample_update() failed");
return;
diff --git a/libhb/declpcm.c b/libhb/declpcm.c
index 8cc5c61b3..85a47c313 100644
--- a/libhb/declpcm.c
+++ b/libhb/declpcm.c
@@ -330,10 +330,10 @@ static hb_buffer_t *Decode( hb_work_object_t *w )
} break;
}
- if (hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT,
- hdr2layout[pv->nchannels - 1],
- HB_MIXLEV_DEFAULT, HB_MIXLEV_DEFAULT,
- pv->nchannels))
+ hb_audio_resample_set_channel_layout(pv->resample,
+ hdr2layout[pv->nchannels - 1],
+ pv->nchannels);
+ if (hb_audio_resample_update(pv->resample))
{
hb_log("declpcm: hb_audio_resample_update() failed");
return NULL;
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 8435b022d..3a0af64d2 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -120,9 +120,8 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
pv->resample = hb_audio_resample_init(context->sample_fmt,
context->channel_layout,
AV_MATRIX_ENCODING_NONE, 0);
- if (hb_audio_resample_update(pv->resample, AV_SAMPLE_FMT_FLT,
- context->channel_layout, HB_MIXLEV_DEFAULT,
- HB_MIXLEV_DEFAULT, context->channels))
+ hb_audio_resample_set_sample_fmt(pv->resample, AV_SAMPLE_FMT_FLT);
+ if (hb_audio_resample_update(pv->resample))
{
hb_error("encavcodecaInit: hb_audio_resample_update() failed");
hb_audio_resample_free(pv->resample);