GHB_CFLAGS="$HBINC $GHB_CFLAGS"
-HB_LIBS="-lhandbrake -lavresample -lavformat -lavfilter -lavcodec -lavutil -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lsamplerate -lx264 -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -llzma"
+HB_LIBS="-lhandbrake -lavformat -lavfilter -lavcodec -lavutil -lavresample -lswresample -lpostproc -ldvdnav -ldvdread -lmp3lame -lvorbis -lvorbisenc -logg -lsamplerate -lx264 -lswscale -ltheoraenc -ltheoradec -lvpx -lz -lbz2 -lbluray -lass -lfontconfig -lfreetype -lxml2 -ljansson -lopus -lspeex -llzma"
case $host in
*-*-mingw*)
goto fail;
}
- // avresample context, initialized in hb_audio_resample_update()
- resample->avresample = NULL;
+ // swresample context, initialized in hb_audio_resample_update()
+ resample->swresample = NULL;
// we don't support planar output yet
if (av_sample_fmt_is_planar(sample_fmt))
resample->out.channels = av_get_channel_layout_nb_channels(channel_layout);
resample->out.channel_layout = channel_layout;
resample->out.matrix_encoding = matrix_encoding;
- resample->out.normalize_mix_level = normalize_mix;
resample->out.sample_fmt = sample_fmt;
+ if (normalize_mix)
+ {
+ resample->out.maxval = 1.0;
+ }
+ else
+ {
+ resample->out.maxval = 1000;
+ }
resample->out.sample_size = av_get_bytes_per_sample(sample_fmt);
// set default input characteristics
// Dolby Surround is Stereo when it comes to remixing
channel_layout = AV_CH_LAYOUT_STEREO;
}
- // avresample can't remap a single-channel layout to
+ // swresample can't remap a single-channel layout to
// another single-channel layout
if (resample->out.channel_layout == AV_CH_LAYOUT_MONO &&
is_mono(channel_layout))
resample->resample.surround_mix_level != resample->in.surround_mix_level));
if (resample_changed || (resample->resample_needed &&
- resample->avresample == NULL))
+ resample->swresample == NULL))
{
- if (resample->avresample == NULL)
+ if (resample->swresample == NULL)
{
- resample->avresample = avresample_alloc_context();
- if (resample->avresample == NULL)
+ resample->swresample = swr_alloc();
+ if (resample->swresample == NULL)
{
- hb_error("hb_audio_resample_update: avresample_alloc_context() failed");
+ hb_error("hb_audio_resample_update: swr_alloc() failed");
return 1;
}
- av_opt_set_int(resample->avresample, "out_sample_fmt",
+ av_opt_set_int(resample->swresample, "out_sample_fmt",
resample->out.sample_fmt, 0);
- av_opt_set_int(resample->avresample, "out_channel_layout",
+ av_opt_set_int(resample->swresample, "out_channel_layout",
resample->out.channel_layout, 0);
- av_opt_set_int(resample->avresample, "matrix_encoding",
+ av_opt_set_int(resample->swresample, "matrix_encoding",
resample->out.matrix_encoding, 0);
- av_opt_set_int(resample->avresample, "normalize_mix_level",
- resample->out.normalize_mix_level, 0);
- }
- else if (resample_changed)
- {
- avresample_close(resample->avresample);
+ av_opt_set_double(resample->swresample, "rematrix_maxval",
+ resample->out.maxval, 0);
}
- av_opt_set_int(resample->avresample, "in_sample_fmt",
+ av_opt_set_int(resample->swresample, "in_sample_fmt",
resample->in.sample_fmt, 0);
- av_opt_set_int(resample->avresample, "in_channel_layout",
+ av_opt_set_int(resample->swresample, "in_channel_layout",
resample->in.channel_layout, 0);
- av_opt_set_double(resample->avresample, "lfe_mix_level",
+ av_opt_set_double(resample->swresample, "lfe_mix_level",
resample->in.lfe_mix_level, 0);
- av_opt_set_double(resample->avresample, "center_mix_level",
+ av_opt_set_double(resample->swresample, "center_mix_level",
resample->in.center_mix_level, 0);
- av_opt_set_double(resample->avresample, "surround_mix_level",
+ av_opt_set_double(resample->swresample, "surround_mix_level",
resample->in.surround_mix_level, 0);
- if ((ret = avresample_open(resample->avresample)))
+ if ((ret = swr_init(resample->swresample)))
{
char err_desc[64];
av_strerror(ret, err_desc, 63);
- hb_error("hb_audio_resample_update: avresample_open() failed (%s)",
+ hb_error("hb_audio_resample_update: swr_init() failed (%s)",
err_desc);
- // avresample won't open, start over
- avresample_free(&resample->avresample);
+ // swresample won't open, start over
+ swr_free(&resample->swresample);
return ret;
}
{
if (resample != NULL)
{
- if (resample->avresample != NULL)
+ if (resample->swresample != NULL)
{
- avresample_free(&resample->avresample);
+ swr_free(&resample->swresample);
}
free(resample);
}
}
hb_buffer_t* hb_audio_resample(hb_audio_resample_t *resample,
- uint8_t **samples, int nsamples)
+ const uint8_t **samples, int nsamples)
{
if (resample == NULL)
{
hb_error("hb_audio_resample: resample is NULL");
return NULL;
}
- if (resample->resample_needed && resample->avresample == NULL)
+ if (resample->resample_needed && resample->swresample == NULL)
{
- hb_error("hb_audio_resample: resample needed but libavresample context "
+ hb_error("hb_audio_resample: resample needed but libswresample context "
"is NULL");
return NULL;
}
if (resample->resample_needed)
{
- int in_linesize, out_linesize;
- // set in/out linesize and out_size
- 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,
+ out_size = av_samples_get_buffer_size(NULL,
resample->out.channels, nsamples,
resample->out.sample_fmt, 0);
out = hb_buffer_init(out_size);
-
- out_samples = avresample_convert(resample->avresample,
- &out->data, out_linesize, nsamples,
- samples, in_linesize, nsamples);
+ out_samples = swr_convert(resample->swresample, &out->data, nsamples,
+ samples, nsamples);
if (out_samples <= 0)
{
if (out_samples < 0)
- hb_log("hb_audio_resample: avresample_convert() failed");
+ hb_log("hb_audio_resample: swr_convert() failed");
// don't send empty buffers downstream (EOF)
hb_buffer_close(&out);
return NULL;
* For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
*/
-/* Implements a libavresample wrapper for convenience.
+/* Implements a libswresample wrapper for convenience.
*
* Supports sample_fmt and channel_layout conversion.
*
- * sample_rate conversion will come later (libavresample doesn't support
+ * sample_rate conversion will come later (libswresample doesn't support
* sample_rate conversion with float samples yet). */
#ifndef AUDIO_RESAMPLE_H
#include <math.h>
#include <stdint.h>
#include "libavutil/channel_layout.h"
-#include "libavresample/avresample.h"
+#include "libswresample/swresample.h"
/* Default mix level for center and surround channels */
#define HB_MIXLEV_DEFAULT ((double)M_SQRT1_2)
int dual_mono_right_only;
int resample_needed;
- AVAudioResampleContext *avresample;
+ SwrContext *swresample;
struct
{
{
int channels;
int sample_size;
- int normalize_mix_level;
uint64_t channel_layout;
enum AVSampleFormat sample_fmt;
enum AVMatrixEncoding matrix_encoding;
+ double maxval;
} out;
} hb_audio_resample_t;
* resampling is only done when necessary.
*/
hb_buffer_t* hb_audio_resample(hb_audio_resample_t *resample,
- uint8_t **samples, int nsamples);
+ const uint8_t **samples, int nsamples);
#endif /* AUDIO_RESAMPLE_H */
hb_dither_t *hb_audio_dithers_last_item = NULL;
hb_dither_internal_t hb_audio_dithers[] =
{
- { { "default", "auto", AV_RESAMPLE_DITHER_NONE - 1, }, NULL, 1, },
- { { "none", "none", AV_RESAMPLE_DITHER_NONE, }, NULL, 1, },
- { { "rectangular", "rectangular", AV_RESAMPLE_DITHER_RECTANGULAR, }, NULL, 1, },
- { { "triangular", "triangular", AV_RESAMPLE_DITHER_TRIANGULAR, }, NULL, 1, },
- { { "triangular with high pass", "triangular_hp", AV_RESAMPLE_DITHER_TRIANGULAR_HP, }, NULL, 1, },
- { { "triangular with noise shaping", "triangular_ns", AV_RESAMPLE_DITHER_TRIANGULAR_NS, }, NULL, 1, },
+ { { "default", "auto", SWR_DITHER_NONE - 1, }, NULL, 1, },
+ { { "none", "none", SWR_DITHER_NONE, }, NULL, 1, },
+ { { "rectangular", "rectangular", SWR_DITHER_RECTANGULAR, }, NULL, 1, },
+ { { "triangular", "triangular", SWR_DITHER_TRIANGULAR, }, NULL, 1, },
+ { { "triangular with high pass", "triangular_hp", SWR_DITHER_TRIANGULAR_HIGHPASS, }, NULL, 1, },
+ { { "lipshitz noise shaping", "lipshitz_ns", SWR_DITHER_NS_LIPSHITZ, }, NULL, 1, },
};
int hb_audio_dithers_count = sizeof(hb_audio_dithers) / sizeof(hb_audio_dithers[0]);
* input could be s16 (possibly already dithered) converted to flt, so
* let's use a "low-risk" dither algorithm (standard triangular).
*/
- return AV_RESAMPLE_DITHER_TRIANGULAR;
+ return SWR_DITHER_TRIANGULAR;
}
int hb_audio_dither_is_supported(uint32_t codec)
// regular stereo (not Dolby)
case HB_AMIXDOWN_LEFT:
case HB_AMIXDOWN_RIGHT:
- return (layout == AV_CH_LAYOUT_STEREO);
+ return (layout & AV_CH_LAYOUT_STEREO);
// mono remix always supported
// HB_AMIXDOWN_NONE always supported (for Passthru)
av_packet_unref(&avp);
return;
}
- out = hb_audio_resample(pv->resample, pv->frame->extended_data,
+ out = hb_audio_resample(pv->resample,
+ (const uint8_t **)pv->frame->extended_data,
pv->frame->nb_samples);
if (out != NULL && pv->drop_samples > 0)
{
hb_log("declpcm: hb_audio_resample_update() failed");
return NULL;
}
- out = hb_audio_resample(pv->resample, &pv->data, pv->nsamples);
+ out = hb_audio_resample(pv->resample, (const uint8_t **)&pv->data,
+ pv->nsamples);
if (out != NULL)
{
uint8_t * input_buf;
hb_list_t * list;
- AVAudioResampleContext *avresample;
+ SwrContext * swresample;
int64_t last_pts;
};
if (context->sample_fmt != AV_SAMPLE_FMT_FLT)
{
pv->output_buf = malloc(pv->max_output_bytes);
- pv->avresample = avresample_alloc_context();
- if (pv->avresample == NULL)
+ pv->swresample = swr_alloc();
+ if (pv->swresample == NULL)
{
- hb_error("encavcodecaInit: avresample_alloc_context() failed");
+ hb_error("encavcodecaInit: swr_alloc() failed");
return 1;
}
- av_opt_set_int(pv->avresample, "in_sample_fmt",
+ av_opt_set_int(pv->swresample, "in_sample_fmt",
AV_SAMPLE_FMT_FLT, 0);
- av_opt_set_int(pv->avresample, "out_sample_fmt",
+ av_opt_set_int(pv->swresample, "out_sample_fmt",
context->sample_fmt, 0);
- av_opt_set_int(pv->avresample, "in_channel_layout",
+ av_opt_set_int(pv->swresample, "in_channel_layout",
context->channel_layout, 0);
- av_opt_set_int(pv->avresample, "out_channel_layout",
+ av_opt_set_int(pv->swresample, "out_channel_layout",
context->channel_layout, 0);
if (hb_audio_dither_is_supported(audio->config.out.codec))
{
// dithering needs the sample rate
- av_opt_set_int(pv->avresample, "in_sample_rate",
+ av_opt_set_int(pv->swresample, "in_sample_rate",
context->sample_rate, 0);
- av_opt_set_int(pv->avresample, "out_sample_rate",
+ av_opt_set_int(pv->swresample, "out_sample_rate",
context->sample_rate, 0);
- av_opt_set_int(pv->avresample, "dither_method",
+ av_opt_set_int(pv->swresample, "dither_method",
audio->config.out.dither_method, 0);
}
- if (avresample_open(pv->avresample))
+ if (swr_init(pv->swresample))
{
- hb_error("encavcodecaInit: avresample_open() failed");
- avresample_free(&pv->avresample);
+ hb_error("encavcodecaInit: swr_init() failed");
+ swr_free(&pv->swresample);
return 1;
}
}
else
{
- pv->avresample = NULL;
+ pv->swresample = NULL;
pv->output_buf = pv->input_buf;
}
hb_list_empty(&pv->list);
}
- if (pv->avresample != NULL)
+ if (pv->swresample != NULL)
{
- avresample_free(&pv->avresample);
+ swr_free(&pv->swresample);
}
free(pv);
pv->input_samples * sizeof(float), &pts, &pos);
// Prepare input frame
- int out_linesize, out_size;
+ int out_size;
AVFrame frame = { .nb_samples = pv->samples_per_frame, };
- out_size = av_samples_get_buffer_size(&out_linesize,
+ out_size = av_samples_get_buffer_size(NULL,
pv->context->channels,
pv->samples_per_frame,
pv->context->sample_fmt, 1);
avcodec_fill_audio_frame(&frame,
pv->context->channels, pv->context->sample_fmt,
pv->output_buf, out_size, 1);
- if (pv->avresample != NULL)
+ if (pv->swresample != NULL)
{
- int in_linesize, out_samples;
-
- av_samples_get_buffer_size(&in_linesize, pv->context->channels,
- frame.nb_samples, AV_SAMPLE_FMT_FLT, 1);
- out_samples = avresample_convert(pv->avresample,
- frame.extended_data, out_linesize,
- frame.nb_samples, &pv->input_buf,
- in_linesize, frame.nb_samples);
+ int out_samples;
+
+ out_samples = swr_convert(pv->swresample,
+ frame.extended_data, frame.nb_samples,
+ (const uint8_t **)&pv->input_buf, frame.nb_samples);
if (out_samples != pv->samples_per_frame)
{
// we're not doing sample rate conversion,
// so this shouldn't happen
- hb_log("encavcodecaWork: avresample_convert() failed");
+ hb_log("encavcodecaWork: swr_convert() failed");
continue;
}
}
void hb_avcodec_init()
{
#ifdef _WIN64
+ // TODO: retest with swresample
// avresample's assembly optimizations can cause crashes under Win x86_64
// (see http://bugzilla.libav.org/show_bug.cgi?id=496)
// disable AVX and FMA4 as a workaround
#include "libavutil/downmix_info.h"
#include "libavutil/display.h"
#include "libswscale/swscale.h"
-#include "libavresample/avresample.h"
+#include "libswresample/swresample.h"
#include "common.h"
#define HB_FFMPEG_THREADS_AUTO (-1) // let hb_avcodec_open() decide thread_count