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_remap.h"
14 // source: libavutil/channel_layout.h
15 hb_chan_map_t hb_libav_chan_map
=
24 AV_CH_FRONT_LEFT_OF_CENTER
,
25 AV_CH_FRONT_RIGHT_OF_CENTER
,
33 // source: liba52 documentation
34 hb_chan_map_t hb_liba52_chan_map
=
48 // source: http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9
49 hb_chan_map_t hb_vorbis_chan_map
=
65 // source: https://developer.apple.com/library/mac/#documentation/musicaudio/reference/CoreAudioDataTypesRef/Reference/reference.html
66 hb_chan_map_t hb_aac_chan_map
=
70 AV_CH_FRONT_LEFT_OF_CENTER
,
71 AV_CH_FRONT_RIGHT_OF_CENTER
,
84 static void remap_planar(uint8_t **samples
, int nsamples
,
85 int nchannels
, int *remap_table
)
88 uint8_t *tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
89 memcpy(tmp_buf
, samples
, nchannels
* sizeof(uint8_t*));
90 for (ii
= 0; ii
< nchannels
; ii
++)
92 samples
[ii
] = tmp_buf
[remap_table
[ii
]];
96 static void remap_u8_interleaved(uint8_t **samples
, int nsamples
,
97 int nchannels
, int *remap_table
)
100 uint8_t *samples_u8
= (*samples
);
101 uint8_t tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
102 for (ii
= 0; ii
< nsamples
; ii
++)
104 memcpy(tmp_buf
, samples_u8
, nchannels
* sizeof(uint8_t));
105 for (jj
= 0; jj
< nchannels
; jj
++)
107 samples_u8
[jj
] = tmp_buf
[remap_table
[jj
]];
109 samples_u8
+= nchannels
;
113 static void remap_s16_interleaved(uint8_t **samples
, int nsamples
,
114 int nchannels
, int *remap_table
)
117 int16_t *samples_s16
= (int16_t*)(*samples
);
118 int16_t tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
119 for (ii
= 0; ii
< nsamples
; ii
++)
121 memcpy(tmp_buf
, samples_s16
, nchannels
* sizeof(int16_t));
122 for (jj
= 0; jj
< nchannels
; jj
++)
124 samples_s16
[jj
] = tmp_buf
[remap_table
[jj
]];
126 samples_s16
+= nchannels
;
130 static void remap_s32_interleaved(uint8_t **samples
, int nsamples
,
131 int nchannels
, int *remap_table
)
134 int32_t *samples_s32
= (int32_t*)(*samples
);
135 int32_t tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
136 for (ii
= 0; ii
< nsamples
; ii
++)
138 memcpy(tmp_buf
, samples_s32
, nchannels
* sizeof(int32_t));
139 for (jj
= 0; jj
< nchannels
; jj
++)
141 samples_s32
[jj
] = tmp_buf
[remap_table
[jj
]];
143 samples_s32
+= nchannels
;
147 static void remap_flt_interleaved(uint8_t **samples
, int nsamples
,
148 int nchannels
, int *remap_table
)
151 float *samples_flt
= (float*)(*samples
);
152 float tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
153 for (ii
= 0; ii
< nsamples
; ii
++)
155 memcpy(tmp_buf
, samples_flt
, nchannels
* sizeof(float));
156 for (jj
= 0; jj
< nchannels
; jj
++)
158 samples_flt
[jj
] = tmp_buf
[remap_table
[jj
]];
160 samples_flt
+= nchannels
;
164 static void remap_dbl_interleaved(uint8_t **samples
, int nsamples
,
165 int nchannels
, int *remap_table
)
168 double *samples_dbl
= (double*)(*samples
);
169 double tmp_buf
[HB_AUDIO_REMAP_MAX_CHANNELS
];
170 for (ii
= 0; ii
< nsamples
; ii
++)
172 memcpy(tmp_buf
, samples_dbl
, nchannels
* sizeof(double));
173 for (jj
= 0; jj
< nchannels
; jj
++)
175 samples_dbl
[jj
] = tmp_buf
[remap_table
[jj
]];
177 samples_dbl
+= nchannels
;
181 hb_audio_remap_t
* hb_audio_remap_init(enum AVSampleFormat sample_fmt
,
182 hb_chan_map_t
*channel_map_out
,
183 hb_chan_map_t
*channel_map_in
)
185 hb_audio_remap_t
*remap
= calloc(1, sizeof(hb_audio_remap_t
));
188 hb_error("hb_audio_remap_init: failed to allocate remap");
195 case AV_SAMPLE_FMT_U8P
:
196 case AV_SAMPLE_FMT_S16P
:
197 case AV_SAMPLE_FMT_S32P
:
198 case AV_SAMPLE_FMT_FLTP
:
199 case AV_SAMPLE_FMT_DBLP
:
200 remap
->remap
= &remap_planar
;
203 case AV_SAMPLE_FMT_U8
:
204 remap
->remap
= &remap_u8_interleaved
;
207 case AV_SAMPLE_FMT_S16
:
208 remap
->remap
= &remap_s16_interleaved
;
211 case AV_SAMPLE_FMT_S32
:
212 remap
->remap
= &remap_s32_interleaved
;
215 case AV_SAMPLE_FMT_FLT
:
216 remap
->remap
= &remap_flt_interleaved
;
219 case AV_SAMPLE_FMT_DBL
:
220 remap
->remap
= &remap_dbl_interleaved
;
224 hb_error("hb_audio_remap_init: unsupported sample format '%s'",
225 av_get_sample_fmt_name(sample_fmt
));
229 // input/output channel order
230 if (channel_map_in
== NULL
|| channel_map_out
== NULL
)
232 hb_error("hb_audio_remap_init: invalid channel map(s)");
235 remap
->channel_map_in
= channel_map_in
;
236 remap
->channel_map_out
= channel_map_out
;
238 // remap can't be done until the channel layout has been set
239 remap
->remap_needed
= 0;
244 hb_audio_remap_free(remap
);
248 void hb_audio_remap_set_channel_layout(hb_audio_remap_t
*remap
,
249 uint64_t channel_layout
)
254 remap
->remap_needed
= 0;
256 // sanitize the layout
257 if (channel_layout
== AV_CH_LAYOUT_STEREO_DOWNMIX
)
259 channel_layout
= AV_CH_LAYOUT_STEREO
;
261 remap
->nchannels
= av_get_channel_layout_nb_channels(channel_layout
);
263 // in some cases, remapping is not necessary and/or supported
264 if (remap
->nchannels
> HB_AUDIO_REMAP_MAX_CHANNELS
)
266 hb_log("hb_audio_remap_set_channel_layout: too many channels (%d)",
270 if (remap
->channel_map_in
== remap
->channel_map_out
)
275 // build the table and check whether remapping is necessary
276 hb_audio_remap_build_table(remap
->channel_map_out
,
277 remap
->channel_map_in
, channel_layout
,
279 for (ii
= 0; ii
< remap
->nchannels
; ii
++)
281 if (remap
->table
[ii
] != ii
)
283 remap
->remap_needed
= 1;
291 void hb_audio_remap_free(hb_audio_remap_t
*remap
)
299 void hb_audio_remap(hb_audio_remap_t
*remap
, uint8_t **samples
, int nsamples
)
301 if (remap
!= NULL
&& remap
->remap_needed
)
303 remap
->remap(samples
, nsamples
, remap
->nchannels
, remap
->table
);
307 void hb_audio_remap_build_table(hb_chan_map_t
*channel_map_out
,
308 hb_chan_map_t
*channel_map_in
,
309 uint64_t channel_layout
,
312 int ii
, jj
, nchannels
, out_chan_idx
, remap_idx
;
313 uint64_t *channels_in
, *channels_out
;
315 if (channel_layout
== AV_CH_LAYOUT_STEREO_DOWNMIX
)
317 // Dolby Surround is Stereo when it comes to remapping
318 channel_layout
= AV_CH_LAYOUT_STEREO
;
320 nchannels
= av_get_channel_layout_nb_channels(channel_layout
);
322 // clear remap table before (re-)building it
323 memset(remap_table
, 0, nchannels
* sizeof(int));
326 channels_in
= channel_map_in
->channel_order_map
;
327 channels_out
= channel_map_out
->channel_order_map
;
328 for (ii
= 0; channels_out
[ii
] && out_chan_idx
< nchannels
; ii
++)
330 if (channel_layout
& channels_out
[ii
])
333 for (jj
= 0; channels_in
[jj
] && remap_idx
< nchannels
; jj
++)
335 if (channels_out
[ii
] == channels_in
[jj
])
337 remap_table
[out_chan_idx
++] = remap_idx
++;
340 else if (channel_layout
& channels_in
[jj
])