[FFmpeg-devel] [PATCH] adpcm_thp: Allow the use of extradata for	the adpcm table
    James Almer 
    jamrial at gmail.com
       
    Sat May 11 00:12:04 CEST 2013
    
    
  
There are several containers that support adpcm_thp (Also known as Gamecube DSP)
streams, but only thp files contain the coeff table and previous sample inside
each frame.
Some don't even contain previous sample information at all.
This change will make allow us to implement demuxers for said containers
without having to create a new decoder.
Signed-off-by: James Almer <jamrial at gmail.com>
---
 libavcodec/adpcm.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 4edc46f..aa2a40f 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -592,6 +592,10 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
         break;
     }
     case AV_CODEC_ID_ADPCM_THP:
+        if (avctx->extradata) {
+            nb_samples = buf_size / (8 * ch) * 14;
+            break;
+        }
         has_coded_samples = 1;
         bytestream2_skip(gb, 4); // channel size
         *coded_samples  = bytestream2_get_be32(gb);
@@ -1325,6 +1329,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
         int table[6][16];
         int ch;
 
+        if (avctx->extradata) {
+            GetByteContext tb;
+            if (avctx->extradata_size < 32 * avctx->channels) {
+                av_log(avctx, AV_LOG_ERROR, "Missing coeff table\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            bytestream2_init(&tb, avctx->extradata, avctx->extradata_size);
+            for (i = 0; i < avctx->channels; i++)
+                for (n = 0; n < 16; n++)
+                    table[i][n] = sign_extend(bytestream2_get_be16u(&tb), 16);
+        } else {
         for (i = 0; i < avctx->channels; i++)
             for (n = 0; n < 16; n++)
                 table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16);
@@ -1334,6 +1350,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
             c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16);
             c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16);
         }
+        }
 
         for (ch = 0; ch < avctx->channels; ch++) {
             samples = samples_p[ch];
-- 
1.8.1.msysgit.1
    
    
More information about the ffmpeg-devel
mailing list