[FFmpeg-cvslog] vqf/twinvq: pass vqf COMM chunk info in extradata

Justin Ruggles git at videolan.org
Sat Nov 12 03:02:02 CET 2011


ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Sun Oct 30 00:46:16 2011 -0400| [7b966566da24598a636a433a75a7842e272b18f6] | committer: Justin Ruggles

vqf/twinvq: pass vqf COMM chunk info in extradata

This is needed because the twinvq decoder cannot rely on bit_rate to be set.
The API documentation says that bit_rate is set by libavcodec, not by the
user.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7b966566da24598a636a433a75a7842e272b18f6
---

 libavcodec/twinvq.c |   18 ++++++++++++++++--
 libavformat/vqf.c   |   14 +++++++++++---
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index 174cee7..73eb7c1 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -1104,17 +1104,31 @@ static av_cold int twin_decode_init(AVCodecContext *avctx)
 {
     int ret;
     TwinContext *tctx = avctx->priv_data;
-    int isampf = avctx->sample_rate/1000;
-    int ibps = avctx->bit_rate/(1000 * avctx->channels);
+    int isampf, ibps;
 
     tctx->avctx       = avctx;
     avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
 
+    if (!avctx->extradata || avctx->extradata_size < 12) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+    avctx->channels = AV_RB32(avctx->extradata    ) + 1;
+    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
+    isampf          = AV_RB32(avctx->extradata + 8);
+    switch (isampf) {
+    case 44: avctx->sample_rate = 44100;         break;
+    case 22: avctx->sample_rate = 22050;         break;
+    case 11: avctx->sample_rate = 11025;         break;
+    default: avctx->sample_rate = isampf * 1000; break;
+    }
+
     if (avctx->channels > CHANNELS_MAX) {
         av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
                avctx->channels);
         return -1;
     }
+    ibps = avctx->bit_rate / (1000 * avctx->channels);
 
     switch ((isampf << 8) +  ibps) {
     case (8 <<8) +  8: tctx->mtab = &mode_08_08; break;
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 4650a0b..f2c1d8f 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -70,6 +70,7 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     int header_size;
     int read_bitrate = 0;
     int size;
+    uint8_t comm_chunk[12];
 
     if (!st)
         return AVERROR(ENOMEM);
@@ -100,9 +101,10 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
         switch(chunk_tag){
         case MKTAG('C','O','M','M'):
-            st->codec->channels = avio_rb32(s->pb) + 1;
-            read_bitrate        = avio_rb32(s->pb);
-            rate_flag           = avio_rb32(s->pb);
+            avio_read(s->pb, comm_chunk, 12);
+            st->codec->channels = AV_RB32(comm_chunk    ) + 1;
+            read_bitrate        = AV_RB32(comm_chunk + 4);
+            rate_flag           = AV_RB32(comm_chunk + 8);
             avio_skip(s->pb, len-12);
 
             st->codec->bit_rate              = read_bitrate*1000;
@@ -192,6 +194,12 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap)
     c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate;
     av_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
+    /* put first 12 bytes of COMM chunk in extradata */
+    if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE)))
+        return AVERROR(ENOMEM);
+    st->codec->extradata_size = 12;
+    memcpy(st->codec->extradata, comm_chunk, 12);
+
     return 0;
 }
 



More information about the ffmpeg-cvslog mailing list