accept old extradata format
authorMåns Rullgård <mans@mansr.com>
Thu, 19 May 2005 11:45:10 +0000 (11:45 +0000)
committerMåns Rullgård <mans@mansr.com>
Thu, 19 May 2005 11:45:10 +0000 (11:45 +0000)
Originally committed as revision 4281 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/oggvorbis.c
libavcodec/vorbis.c

index 9a47aee..dc7a8c6 100644 (file)
@@ -180,13 +180,11 @@ AVCodec oggvorbis_encoder = {
     .capabilities= CODEC_CAP_DELAY,
 } ;
 
-
 static int oggvorbis_decode_init(AVCodecContext *avccontext) {
     OggVorbisContext *context = avccontext->priv_data ;
     uint8_t *p= avccontext->extradata;
     int i, hsizes[3];
     unsigned char *headers[3], *extradata = avccontext->extradata;
-    unsigned int offset;
 
     vorbis_info_init(&context->vi) ;
     vorbis_comment_init(&context->vc) ;
@@ -195,37 +193,47 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) {
         av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
         return -1;
     }
-    if(*p != 2) {
-        av_log(avccontext, AV_LOG_ERROR,
-               "vorbis initial header len is wrong: %d\n", *p);
-        return -1;
-    }
-    offset = 1;
-    p++;
-    for(i=0; i<2; i++) {
-        hsizes[i] = 0;
-        while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
-            hsizes[i] += 0xFF;
+
+    if(p[0] == 0 && p[1] == 30) {
+        for(i = 0; i < 3; i++){
+            hsizes[i] = *p++ << 8;
+            hsizes[i] += *p++;
+            headers[i] = p;
+            p += hsizes[i];
+        }
+    } else if(*p == 2) {
+        unsigned int offset = 1;
+        p++;
+        for(i=0; i<2; i++) {
+            hsizes[i] = 0;
+            while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
+                hsizes[i] += 0xFF;
+                offset++;
+                p++;
+            }
+            if(offset >= avccontext->extradata_size - 1) {
+                av_log(avccontext, AV_LOG_ERROR,
+                       "vorbis header sizes damaged\n");
+                return -1;
+            }
+            hsizes[i] += *p;
             offset++;
             p++;
         }
-        if(offset >= avccontext->extradata_size - 1) {
-            av_log(avccontext, AV_LOG_ERROR, "vorbis header sizes damaged\n");
-            return -1;
-        }
-        hsizes[i] += *p;
-        offset++;
-        p++;
-    }
-    hsizes[2] = avccontext->extradata_size - hsizes[0] - hsizes[1] - offset;
+        hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset;
 #if 0
-    av_log(avccontext, AV_LOG_DEBUG,
-           "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
-           hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
+        av_log(avccontext, AV_LOG_DEBUG,
+               "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
+               hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
 #endif
-    headers[0] = extradata + offset;
-    headers[1] = extradata + offset + hsizes[0];
-    headers[2] = extradata + offset + hsizes[0] + hsizes[1];
+        headers[0] = extradata + offset;
+        headers[1] = extradata + offset + hsizes[0];
+        headers[2] = extradata + offset + hsizes[0] + hsizes[1];
+    } else {
+        av_log(avccontext, AV_LOG_ERROR,
+               "vorbis initial header len is wrong: %d\n", *p);
+        return -1;
+    }
 
     for(i=0; i<3; i++){
         context->op.b_o_s= i==0;
@@ -236,6 +244,7 @@ static int oggvorbis_decode_init(AVCodecContext *avccontext) {
             return -1;
         }
     }
+
     avccontext->channels = context->vi.channels;
     avccontext->sample_rate = context->vi.rate;
     avccontext->time_base= (AVRational){1, avccontext->sample_rate};
index 9d6d55c..3505409 100644 (file)
@@ -759,33 +759,49 @@ static int vorbis_decode_init(AVCodecContext *avccontext) {
     vorbis_context *vc = avccontext->priv_data ;
     uint8_t *headers = avccontext->extradata;
     int headers_len=avccontext->extradata_size;
+    uint8_t *header_start[3];
     int header_len[3];
     GetBitContext *gb = &(vc->gb);
     int i, j, hdr_type;
 
     vc->avccontext = avccontext;
 
-    if (!headers_len || headers[0]!=2) {
+    if (!headers_len) {
         av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
         return -1;
     }
 
-    for(j=1,i=0;i<2;++i, ++j) {
-        header_len[i]=0;
-        while(j<headers_len && headers[j]==0xff) {
-            header_len[i]+=0xff;
-            ++j;
+    if(headers[0] == 0 && headers[1] == 30) {
+        for(i = 0; i < 3; i++){
+            header_len[i] = *headers++ << 8;
+            header_len[i] += *headers++;
+            header_start[i] = headers;
+            headers += header_len[i];
         }
-        if (j>=headers_len) {
-            av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
-            return -1;
+    } else if(headers[0] == 2) {
+        for(j=1,i=0;i<2;++i, ++j) {
+            header_len[i]=0;
+            while(j<headers_len && headers[j]==0xff) {
+                header_len[i]+=0xff;
+                ++j;
+            }
+            if (j>=headers_len) {
+                av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
+                return -1;
+            }
+            header_len[i]+=headers[j];
         }
-        header_len[i]+=headers[j];
+        header_len[2]=headers_len-header_len[0]-header_len[1]-j;
+        headers+=j;
+        header_start[0] = headers;
+        header_start[1] = header_start[0] + header_len[0];
+        header_start[2] = header_start[1] + header_len[1];
+    } else {
+        av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
+        return -1;
     }
-    header_len[2]=headers_len-header_len[0]-header_len[1]-j;
-    headers+=j;
 
-    init_get_bits(gb, headers, header_len[0]*8);
+    init_get_bits(gb, header_start[0], header_len[0]*8);
     hdr_type=get_bits(gb, 8);
     if (hdr_type!=1) {
         av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
@@ -797,7 +813,7 @@ static int vorbis_decode_init(AVCodecContext *avccontext) {
         return -1;
     }
 
-    init_get_bits(gb, headers+header_len[0]+header_len[1], header_len[2]*8);
+    init_get_bits(gb, header_start[2], header_len[2]*8);
     hdr_type=get_bits(gb, 8);
     if (hdr_type!=5) {
         av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");