mirror of https://git.ffmpeg.org/ffmpeg.git
libopus: Remap channels using libopus' internal remapping.
This way we can directly remap channels from Opus' channel order to libav's internal channel order, instead of mapping channels from Opus' order to Vorbis' order then to libav's order. Signed-off-by: Diego Biurrun <diego@biurrun.de>
This commit is contained in:
parent
44617d6ec9
commit
d16860a237
|
@ -56,28 +56,13 @@ static int opus_error_to_averror(int err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void reorder(uint8_t *data, unsigned channels, unsigned bps,
|
|
||||||
unsigned samples, const uint8_t *map)
|
|
||||||
{
|
|
||||||
uint8_t tmp[8 * 4];
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
av_assert1(channels * bps <= sizeof(tmp));
|
|
||||||
for (; samples > 0; samples--) {
|
|
||||||
for (i = 0; i < channels; i++)
|
|
||||||
memcpy(tmp + bps * i, data + bps * map[i], bps);
|
|
||||||
memcpy(data, tmp, bps * channels);
|
|
||||||
data += bps * channels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OPUS_HEAD_SIZE 19
|
#define OPUS_HEAD_SIZE 19
|
||||||
|
|
||||||
static av_cold int libopus_decode_init(AVCodecContext *avc)
|
static av_cold int libopus_decode_init(AVCodecContext *avc)
|
||||||
{
|
{
|
||||||
struct libopus_context *opus = avc->priv_data;
|
struct libopus_context *opus = avc->priv_data;
|
||||||
int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled;
|
int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled;
|
||||||
uint8_t mapping_stereo[] = { 0, 1 }, *mapping;
|
uint8_t mapping_arr[8] = { 0, 1 }, *mapping;
|
||||||
|
|
||||||
avc->sample_rate = 48000;
|
avc->sample_rate = 48000;
|
||||||
avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ?
|
avc->sample_fmt = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ?
|
||||||
|
@ -103,7 +88,17 @@ static av_cold int libopus_decode_init(AVCodecContext *avc)
|
||||||
}
|
}
|
||||||
nb_streams = 1;
|
nb_streams = 1;
|
||||||
nb_coupled = avc->channels > 1;
|
nb_coupled = avc->channels > 1;
|
||||||
mapping = mapping_stereo;
|
mapping = mapping_arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avc->channels > 2 && avc->channels <= 8) {
|
||||||
|
const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1];
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
/* Remap channels from vorbis order to libav order */
|
||||||
|
for (ch = 0; ch < avc->channels; ch++)
|
||||||
|
mapping_arr[ch] = mapping[vorbis_offset[ch]];
|
||||||
|
mapping = mapping_arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels,
|
opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels,
|
||||||
|
@ -164,14 +159,6 @@ static int libopus_decode(AVCodecContext *avc, void *frame,
|
||||||
return opus_error_to_averror(nb_samples);
|
return opus_error_to_averror(nb_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avc->channels > 3 && avc->channels <= 8) {
|
|
||||||
const uint8_t *m = ff_vorbis_channel_layout_offsets[avc->channels - 1];
|
|
||||||
if (avc->sample_fmt == AV_SAMPLE_FMT_S16)
|
|
||||||
reorder(opus->frame.data[0], avc->channels, 2, nb_samples, m);
|
|
||||||
else
|
|
||||||
reorder(opus->frame.data[0], avc->channels, 4, nb_samples, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
opus->frame.nb_samples = nb_samples;
|
opus->frame.nb_samples = nb_samples;
|
||||||
*(AVFrame *)frame = opus->frame;
|
*(AVFrame *)frame = opus->frame;
|
||||||
*got_frame_ptr = 1;
|
*got_frame_ptr = 1;
|
||||||
|
|
Loading…
Reference in New Issue