Fixes Ticket2758 Signed-off-by: Michael Niedermayer <michae...@gmx.at> --- libavcodec/pcm-dvd.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c index e729cb6..7aec415 100644 --- a/libavcodec/pcm-dvd.c +++ b/libavcodec/pcm-dvd.c @@ -231,6 +231,74 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src, } } +static int decode_aob(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *src = avpkt->data; + int buf_size = avpkt->size; + PCMDVDContext *s = avctx->priv_data; + int retval; + void *dst; + int ptr; + + if (buf_size < 8) + return AVERROR_INVALIDDATA; + + ptr = AV_RB16(src); + if (ptr < 8 || ptr > buf_size) + return AVERROR_INVALIDDATA; + + if (buf_size < 16) + return 0; + + switch (src[2]){ + case 0x10: + avctx->channels = 2; + break; + default: + avpriv_request_sample(avctx, "Unsupported channel layout\n"); + return AVERROR_INVALIDDATA; + } + + avctx->bits_per_coded_sample = 16 + (src[3] >> 4 & 3) * 4; + if (avctx->bits_per_coded_sample == 28) { + av_log(avctx, AV_LOG_ERROR, + "PCM DVD unsupported sample depth %i\n", + avctx->bits_per_coded_sample); + return AVERROR_INVALIDDATA; + } + switch(src[4] >> 4) { + case 0: avctx->sample_rate = 48000; break; + case 1: avctx->sample_rate = 96000; break; + case 2: avctx->sample_rate =192000; break; + case 8: avctx->sample_rate = 44100; break; + case 9: avctx->sample_rate = 88200; break; + case 10: avctx->sample_rate =176400; break; + default: + avpriv_request_sample(avctx, "Unsupported sample rate\n"); + return AVERROR_INVALIDDATA; + } + avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 + : AV_SAMPLE_FMT_S32; + + if (avctx->bits_per_coded_sample != 16) { + avpriv_request_sample(avctx, "Unsupported sample size\n"); + return AVERROR_INVALIDDATA; + } + + s->block_size = avctx->channels * 2; + frame->nb_samples = (buf_size - 16) / s->block_size; + if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) + return retval; + dst = frame->data[0]; + pcm_dvd_decode_samples(avctx, src + 16, + dst, frame->nb_samples); + + *got_frame_ptr = 1; + return buf_size; +} + static int pcm_dvd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -247,6 +315,8 @@ static int pcm_dvd_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } + if ((retval = decode_aob(avctx, data, got_frame_ptr, avpkt)) >= 0) + return retval; if ((retval = pcm_dvd_parse_header(avctx, src))) return retval; if (s->last_block_size && s->last_block_size != s->block_size) { -- 1.7.9.5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel