[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