3 * Copyright (c) 2003-2015 HandBrake Team
4 * This file is part of the HandBrake source code
5 * Homepage: <http://handbrake.fr/>
6 * It may be used under the terms of the GNU General Public License v2.
7 * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
12 #include "audio_resample.h"
14 hb_audio_resample_t
* hb_audio_resample_init(enum AVSampleFormat sample_fmt
,
15 int hb_amixdown
, int normalize_mix
)
17 hb_audio_resample_t
*resample
= calloc(1, sizeof(hb_audio_resample_t
));
20 hb_error("hb_audio_resample_init: failed to allocate resample");
24 // avresample context, initialized in hb_audio_resample_update()
25 resample
->avresample
= NULL
;
27 // we don't support planar output yet
28 if (av_sample_fmt_is_planar(sample_fmt
))
30 hb_error("hb_audio_resample_init: planar output not supported ('%s')",
31 av_get_sample_fmt_name(sample_fmt
));
35 // convert mixdown to channel_layout/matrix_encoding combo
37 uint64_t channel_layout
= hb_ff_mixdown_xlat(hb_amixdown
, &matrix_encoding
);
40 * When downmixing, Dual Mono to Mono is a special case:
41 * the audio must remain 2-channel until all conversions are done.
43 if (hb_amixdown
== HB_AMIXDOWN_LEFT
|| hb_amixdown
== HB_AMIXDOWN_RIGHT
)
45 channel_layout
= AV_CH_LAYOUT_STEREO
;
46 resample
->dual_mono_downmix
= 1;
47 resample
->dual_mono_right_only
= (hb_amixdown
== HB_AMIXDOWN_RIGHT
);
51 resample
->dual_mono_downmix
= 0;
54 // requested output channel_layout, sample_fmt
55 resample
->out
.channels
= av_get_channel_layout_nb_channels(channel_layout
);
56 resample
->out
.channel_layout
= channel_layout
;
57 resample
->out
.matrix_encoding
= matrix_encoding
;
58 resample
->out
.normalize_mix_level
= normalize_mix
;
59 resample
->out
.sample_fmt
= sample_fmt
;
60 resample
->out
.sample_size
= av_get_bytes_per_sample(sample_fmt
);
62 // set default input characteristics
63 resample
->in
.sample_fmt
= resample
->out
.sample_fmt
;
64 resample
->in
.channel_layout
= resample
->out
.channel_layout
;
65 resample
->in
.lfe_mix_level
= HB_MIXLEV_ZERO
;
66 resample
->in
.center_mix_level
= HB_MIXLEV_DEFAULT
;
67 resample
->in
.surround_mix_level
= HB_MIXLEV_DEFAULT
;
69 // by default, no conversion needed
70 resample
->resample_needed
= 0;
74 hb_audio_resample_free(resample
);
78 void hb_audio_resample_set_channel_layout(hb_audio_resample_t
*resample
,
79 uint64_t channel_layout
)
83 if (channel_layout
== AV_CH_LAYOUT_STEREO_DOWNMIX
)
85 // Dolby Surround is Stereo when it comes to remixing
86 channel_layout
= AV_CH_LAYOUT_STEREO
;
88 resample
->in
.channel_layout
= channel_layout
;
92 void hb_audio_resample_set_mix_levels(hb_audio_resample_t
*resample
,
93 double surround_mix_level
,
94 double center_mix_level
,
99 resample
->in
.lfe_mix_level
= lfe_mix_level
;
100 resample
->in
.center_mix_level
= center_mix_level
;
101 resample
->in
.surround_mix_level
= surround_mix_level
;
105 void hb_audio_resample_set_sample_fmt(hb_audio_resample_t
*resample
,
106 enum AVSampleFormat sample_fmt
)
108 if (resample
!= NULL
)
110 resample
->in
.sample_fmt
= sample_fmt
;
114 int hb_audio_resample_update(hb_audio_resample_t
*resample
)
116 if (resample
== NULL
)
118 hb_error("hb_audio_resample_update: resample is NULL");
122 int ret
, resample_changed
;
124 resample
->resample_needed
=
125 (resample
->out
.sample_fmt
!= resample
->in
.sample_fmt
||
126 resample
->out
.channel_layout
!= resample
->in
.channel_layout
);
129 (resample
->resample_needed
&&
130 (resample
->resample
.sample_fmt
!= resample
->in
.sample_fmt
||
131 resample
->resample
.channel_layout
!= resample
->in
.channel_layout
||
132 resample
->resample
.lfe_mix_level
!= resample
->in
.lfe_mix_level
||
133 resample
->resample
.center_mix_level
!= resample
->in
.center_mix_level
||
134 resample
->resample
.surround_mix_level
!= resample
->in
.surround_mix_level
));
136 if (resample_changed
|| (resample
->resample_needed
&&
137 resample
->avresample
== NULL
))
139 if (resample
->avresample
== NULL
)
141 resample
->avresample
= avresample_alloc_context();
142 if (resample
->avresample
== NULL
)
144 hb_error("hb_audio_resample_update: avresample_alloc_context() failed");
148 av_opt_set_int(resample
->avresample
, "out_sample_fmt",
149 resample
->out
.sample_fmt
, 0);
150 av_opt_set_int(resample
->avresample
, "out_channel_layout",
151 resample
->out
.channel_layout
, 0);
152 av_opt_set_int(resample
->avresample
, "matrix_encoding",
153 resample
->out
.matrix_encoding
, 0);
154 av_opt_set_int(resample
->avresample
, "normalize_mix_level",
155 resample
->out
.normalize_mix_level
, 0);
157 else if (resample_changed
)
159 avresample_close(resample
->avresample
);
162 av_opt_set_int(resample
->avresample
, "in_sample_fmt",
163 resample
->in
.sample_fmt
, 0);
164 av_opt_set_int(resample
->avresample
, "in_channel_layout",
165 resample
->in
.channel_layout
, 0);
166 av_opt_set_double(resample
->avresample
, "lfe_mix_level",
167 resample
->in
.lfe_mix_level
, 0);
168 av_opt_set_double(resample
->avresample
, "center_mix_level",
169 resample
->in
.center_mix_level
, 0);
170 av_opt_set_double(resample
->avresample
, "surround_mix_level",
171 resample
->in
.surround_mix_level
, 0);
173 if ((ret
= avresample_open(resample
->avresample
)))
176 av_strerror(ret
, err_desc
, 63);
177 hb_error("hb_audio_resample_update: avresample_open() failed (%s)",
179 // avresample won't open, start over
180 avresample_free(&resample
->avresample
);
184 resample
->resample
.sample_fmt
= resample
->in
.sample_fmt
;
185 resample
->resample
.channel_layout
= resample
->in
.channel_layout
;
186 resample
->resample
.channels
=
187 av_get_channel_layout_nb_channels(resample
->in
.channel_layout
);
188 resample
->resample
.lfe_mix_level
= resample
->in
.lfe_mix_level
;
189 resample
->resample
.center_mix_level
= resample
->in
.center_mix_level
;
190 resample
->resample
.surround_mix_level
= resample
->in
.surround_mix_level
;
196 void hb_audio_resample_free(hb_audio_resample_t
*resample
)
198 if (resample
!= NULL
)
200 if (resample
->avresample
!= NULL
)
202 avresample_free(&resample
->avresample
);
208 hb_buffer_t
* hb_audio_resample(hb_audio_resample_t
*resample
,
209 uint8_t **samples
, int nsamples
)
211 if (resample
== NULL
)
213 hb_error("hb_audio_resample: resample is NULL");
216 if (resample
->resample_needed
&& resample
->avresample
== NULL
)
218 hb_error("hb_audio_resample: resample needed but libavresample context "
224 int out_size
, out_samples
;
226 if (resample
->resample_needed
)
228 int in_linesize
, out_linesize
;
229 // set in/out linesize and out_size
230 av_samples_get_buffer_size(&in_linesize
,
231 resample
->resample
.channels
, nsamples
,
232 resample
->resample
.sample_fmt
, 0);
233 out_size
= av_samples_get_buffer_size(&out_linesize
,
234 resample
->out
.channels
, nsamples
,
235 resample
->out
.sample_fmt
, 0);
236 out
= hb_buffer_init(out_size
);
238 out_samples
= avresample_convert(resample
->avresample
,
239 &out
->data
, out_linesize
, nsamples
,
240 samples
, in_linesize
, nsamples
);
242 if (out_samples
<= 0)
245 hb_log("hb_audio_resample: avresample_convert() failed");
246 // don't send empty buffers downstream (EOF)
247 hb_buffer_close(&out
);
250 out
->size
= (out_samples
*
251 resample
->out
.sample_size
* resample
->out
.channels
);
255 out_samples
= nsamples
;
256 out_size
= (out_samples
*
257 resample
->out
.sample_size
* resample
->out
.channels
);
258 out
= hb_buffer_init(out_size
);
259 memcpy(out
->data
, samples
[0], out_size
);
265 * Copy all left or right samples to the first half of the buffer and halve
268 if (resample
->dual_mono_downmix
)
270 int ii
, jj
= !!resample
->dual_mono_right_only
;
271 int sample_size
= resample
->out
.sample_size
;
272 uint8_t *audio_samples
= out
->data
;
273 for (ii
= 0; ii
< out_samples
; ii
++)
275 memcpy(audio_samples
+ (ii
* sample_size
),
276 audio_samples
+ (jj
* sample_size
), sample_size
);
279 out
->size
= out_samples
* sample_size
;