changeset 655:0018e190cc4c libavcodec

m4v input support return the correct number of bytes consumed for decding h263 like formats (needed for reading raw streams) this could break some divx files with b frames, so please tell me ASAP if u notice any problems
author michaelni
date Thu, 12 Sep 2002 11:10:33 +0000
parents 850098147a3c
children e47fa3e3f2d5
files h263dec.c
diffstat 1 files changed, 24 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/h263dec.c	Thu Sep 12 10:54:53 2002 +0000
+++ b/h263dec.c	Thu Sep 12 11:10:33 2002 +0000
@@ -110,6 +110,23 @@
     return 0;
 }
 
+/**
+ * retunrs the number of bytes consumed for building the current frame
+ */
+static int get_consumed_bytes(MpegEncContext *s, int buf_size){
+    int pos= (get_bits_count(&s->gb)+7)>>3;
+
+    if(s->divx_version>=500){
+        //we would have to scan through the whole buf to handle the weird reordering ...
+        return buf_size; 
+    }else{
+        if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...)
+        if(pos>buf_size) pos=buf_size; // oops ;)
+
+        return pos;
+    }
+}
+
 static int h263_decode_frame(AVCodecContext *avctx, 
                              void *data, int *data_size,
                              UINT8 *buf, int buf_size)
@@ -179,20 +196,20 @@
             return -1;
     }
 
-    if(ret==FRAME_SKIPED) return buf_size;
+    if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size);
     /* skip if the header was thrashed */
     if (ret < 0){
         fprintf(stderr, "header damaged\n");
         return -1;
     }
     /* skip b frames if we dont have reference frames */
-    if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return buf_size;
+    if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
     /* skip b frames if we are in a hurry */
-    if(s->hurry_up && s->pict_type==B_TYPE) return buf_size;
+    if(s->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
     
     if(s->next_p_frame_damaged){
         if(s->pict_type==B_TYPE)
-            return buf_size;
+            return get_consumed_bytes(s, buf_size);
         else
             s->next_p_frame_damaged=0;
     }
@@ -354,14 +371,14 @@
         if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
     
     /* divx 5.01+ bistream reorder stuff */
-    if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0){
+    if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){
         int current_pos= get_bits_count(&s->gb)>>3;
 
         if(   buf_size - current_pos > 5 
            && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
             int i;
             int startcode_found=0;
-            for(i=current_pos; i<buf_size; i++){
+            for(i=current_pos; i<buf_size-3; i++){
                 if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
                     startcode_found=1;
                     break;
@@ -454,7 +471,7 @@
 #ifdef PRINT_FRAME_TIME
 printf("%Ld\n", rdtsc()-time);
 #endif
-    return buf_size;
+    return get_consumed_bytes(s, buf_size);
 }
 
 AVCodec mpeg4_decoder = {