diff options
-rw-r--r-- | libhb/audio_resample.c | 102 | ||||
-rw-r--r-- | libhb/audio_resample.h | 45 | ||||
-rw-r--r-- | libhb/deca52.c | 11 | ||||
-rw-r--r-- | libhb/decavcodec.c | 12 | ||||
-rw-r--r-- | libhb/declpcm.c | 8 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 5 |
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); |