Source code
Revision control
Copy as Markdown
Other Tools
diff --git a/media/ffvpx/libavcodec/libvorbisdec.c b/media/ffvpx/libavcodec/libvorbisdec.c
index b38f423b9f9c..0c73c334895a 100644
--- a/media/ffvpx/libavcodec/libvorbisdec.c
+++ b/media/ffvpx/libavcodec/libvorbisdec.c
@@ -25,6 +25,7 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
+#include "vorbis_data.h"
typedef struct OggVorbisDecContext {
vorbis_info vi; /**< vorbis_info used during init */
@@ -121,9 +122,22 @@ static av_cold int oggvorbis_decode_init(AVCodecContext *avccontext)
goto error;
}
+ if (context->vi.channels <= 0) {
+ av_log(avccontext, AV_LOG_ERROR, "vorbis channel count is invalid\n");
+ ret = AVERROR_INVALIDDATA;
+ goto error;
+ }
+
av_channel_layout_uninit(&avccontext->ch_layout);
- avccontext->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- avccontext->ch_layout.nb_channels = context->vi.channels;
+ if (context->vi.channels <= 8) {
+ ret = av_channel_layout_copy(&avccontext->ch_layout,
+ &ff_vorbis_ch_layouts[context->vi.channels - 1]);
+ if (ret < 0)
+ goto error;
+ } else {
+ avccontext->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ avccontext->ch_layout.nb_channels = context->vi.channels;
+ }
avccontext->sample_rate = context->vi.rate;
avccontext->sample_fmt = AV_SAMPLE_FMT_FLTP;
avccontext->time_base= (AVRational){1, avccontext->sample_rate};
@@ -147,6 +161,11 @@ static int oggvorbis_decode_frame(AVCodecContext *avccontext, AVFrame *frame,
ogg_packet *op= &context->op;
int samples, total_samples;
int ret;
+ const int channels = context->vi.channels;
+ /* libvorbis emits the Vorbis I spec 4.3.9 channel order; map it to the
+ * layout declared in oggvorbis_decode_init(). */
+ const uint8_t *ch_map = channels <= 8 ?
+ ff_vorbis_channel_layout_offsets[channels - 1] : NULL;
if(!avpkt->size){
//FIXME flush
@@ -172,8 +191,9 @@ static int oggvorbis_decode_frame(AVCodecContext *avccontext, AVFrame *frame,
total_samples = 0 ;
while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) {
- for (int ch = 0; ch < context->vi.channels; ch++)
- memcpy((float *)frame->extended_data[ch] + total_samples, pcm[ch], samples * sizeof(float));
+ for (int ch = 0; ch < channels; ch++)
+ memcpy((float *)frame->extended_data[ch] + total_samples,
+ pcm[ch_map ? ch_map[ch] : ch], samples * sizeof(float));
total_samples += samples ;
vorbis_synthesis_read(&context->vd, samples) ;
}