[FFmpeg-devel] [PATCH] libavcodec/pcm-dvd: support a subset of AOB
Michael Niedermayer
michaelni at gmx.at
Thu Jun 11 05:05:48 CEST 2015
Fixes Ticket2758
Signed-off-by: Michael Niedermayer <michaelni at 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
More information about the ffmpeg-devel
mailing list