changeset 842:e460775adb38 libavcodec

cleanup (breaks compatibility, requested by fabrice) remove CODEC_FLAG_NOT_TRUNCATED & add CODEC_FLAG_TRUNCATED add CODEC_CAP_TRUNCATED add alpha plane to AVPicture remove CODEC_ID_MSMPEG4 remove various unused stuff support "truncated" mpeg4 streams
author michaelni
date Fri, 08 Nov 2002 18:35:39 +0000
parents 4033915880d9
children 8c81f1ee9271
files avcodec.h h263dec.c mpeg12.c mpegvideo.c mpegvideo.h
diffstat 5 files changed, 111 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Wed Nov 06 11:59:17 2002 +0000
+++ b/avcodec.h	Fri Nov 08 18:35:39 2002 +0000
@@ -5,8 +5,8 @@
 
 #define LIBAVCODEC_VERSION_INT 0x000406
 #define LIBAVCODEC_VERSION     "0.4.6"
-#define LIBAVCODEC_BUILD       4634
-#define LIBAVCODEC_BUILD_STR   "4634"
+#define LIBAVCODEC_BUILD       4635
+#define LIBAVCODEC_BUILD_STR   "4635"
 
 enum CodecID {
     CODEC_ID_NONE, 
@@ -50,7 +50,6 @@
     CODEC_ID_ADPCM_IMA_WAV,
     CODEC_ID_ADPCM_MS,
 };
-#define CODEC_ID_MSMPEG4 CODEC_ID_MSMPEG4V3
 
 enum CodecType {
     CODEC_TYPE_UNKNOWN = -1,
@@ -80,6 +79,12 @@
 /* in bytes */
 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 131072
 
+/**
+ * Required number of zero bytes at the end of the input bitstream for decoding.
+ * to avoid overreading (and possibly segfaulting)
+ */
+#define FF_INPUT_BUFFER_PADDING_SIZE 8
+
 /* motion estimation type, EPZS by default */
 enum Motion_Est_ID {
     ME_ZERO = 1,
@@ -128,8 +133,8 @@
 #define CODEC_FLAG_GRAY  0x2000   /* only decode/encode grayscale */
 #define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */
 #define CODEC_FLAG_DR1    0x8000  /* direct renderig type 1 (store internal frames in external buffers) */
-#define CODEC_FLAG_NOT_TRUNCATED  0x00010000 /* input bitstream is not truncated, except before a startcode 
-                                                allows the last part of a frame to be decoded earlier */
+#define CODEC_FLAG_TRUNCATED  0x00010000 /* input bitstream might be truncated at a random location instead 
+                                            of only at frame boundaries */
 #define CODEC_FLAG_NORMALIZE_AQP  0x00020000 /* normalize adaptive quantization */
 #define CODEC_FLAG_INTERLACED_DCT 0x00040000 /* use interlaced dct */
 #define CODEC_FLAG_LOW_DELAY      0x00080000 /* force low delay / will fail on b frames */
@@ -141,6 +146,7 @@
 /* if 'parse_only' field is true, then avcodec_parse_frame() can be
    used */
 #define CODEC_CAP_PARSE_ONLY      0x0004
+#define CODEC_CAP_TRUNCATED       0x0008
 
 #define FRAME_RATE_BASE 10000
 
@@ -770,10 +776,13 @@
     struct AVCodec *next;
 } AVCodec;
 
-/* three components are given, that's all */
+/** 
+ * four components are given, that's all.
+ * the last component is alpha
+ */
 typedef struct AVPicture {
-    UINT8 *data[3];
-    int linesize[3];
+    UINT8 *data[4];
+    int linesize[4];
 } AVPicture;
 
 extern AVCodec ac3_encoder;
@@ -925,13 +934,6 @@
 
 void avcodec_flush_buffers(AVCodecContext *avctx);
 
-// deprecated / obsolete stuff, WILL be removed
-#ifndef MBC
-#define MBC 128
-#define MBR 96
-#endif
-#define QP_TYPE int
-
 /**
  * Interface for 0.5.0 version
  *
--- a/h263dec.c	Wed Nov 06 11:59:17 2002 +0000
+++ b/h263dec.c	Fri Nov 08 18:35:39 2002 +0000
@@ -125,9 +125,14 @@
  */
 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(s->flags&CODEC_FLAG_TRUNCATED){
+        pos -= s->parse_context.last_index;
+        if(pos<0) pos=0; // padding is not really read so this might be -1
+        return pos;
     }else{
         if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...)
         if(pos+10>buf_size) pos=buf_size; // oops ;)
@@ -299,6 +304,43 @@
     return -1;
 }
 
+/**
+ * finds the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or -1
+ */
+static int mpeg4_find_frame_end(MpegEncContext *s, UINT8 *buf, int buf_size){
+    ParseContext *pc= &s->parse_context;
+    int vop_found, i;
+    uint32_t state;
+    
+    vop_found= pc->frame_start_found;
+    state= pc->state;
+    
+    i=0;
+    if(!vop_found){
+        for(i=0; i<buf_size; i++){
+            state= (state<<8) | buf[i];
+            if(state == 0x1B6){
+                i++;
+                vop_found=1;
+                break;
+            }
+        }
+    }
+    
+    for(; i<buf_size; i++){
+        state= (state<<8) | buf[i];
+        if((state&0xFFFFFF00) == 0x100){
+            pc->frame_start_found=0;
+            pc->state=-1; 
+            return i-3;
+        }
+    }
+    pc->frame_start_found= vop_found;
+    pc->state= state;
+    return -1;
+}
+
 static int h263_decode_frame(AVCodecContext *avctx, 
                              void *data, int *data_size,
                              UINT8 *buf, int buf_size)
@@ -325,6 +367,42 @@
     if (buf_size == 0) {
         return 0;
     }
+    
+    if(s->flags&CODEC_FLAG_TRUNCATED){
+        int next;
+        ParseContext *pc= &s->parse_context;
+        
+        pc->last_index= pc->index;
+
+        if(s->codec_id==CODEC_ID_MPEG4){
+            next= mpeg4_find_frame_end(s, buf, buf_size);
+        }else{
+            fprintf(stderr, "this codec doesnt support truncated bitstreams\n");
+            return -1;
+        }
+        if(next==-1){
+            if(buf_size + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){
+                pc->buffer_size= buf_size + pc->index + 10*1024;
+                pc->buffer= realloc(pc->buffer, pc->buffer_size);
+            }
+
+            memcpy(&pc->buffer[pc->index], buf, buf_size);
+            pc->index += buf_size;
+            return buf_size;
+        }
+
+        if(pc->index){
+            if(next + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){
+                pc->buffer_size= next + pc->index + 10*1024;
+                pc->buffer= realloc(pc->buffer, pc->buffer_size);
+            }
+
+            memcpy(&pc->buffer[pc->index], buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
+            pc->index = 0;
+            buf= pc->buffer;
+            buf_size= pc->last_index + next;
+        }
+    }
 
 retry:
     
@@ -627,7 +705,7 @@
     NULL,
     h263_decode_end,
     h263_decode_frame,
-    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
 };
 
 AVCodec h263_decoder = {
--- a/mpeg12.c	Wed Nov 06 11:59:17 2002 +0000
+++ b/mpeg12.c	Fri Nov 08 18:35:39 2002 +0000
@@ -1876,7 +1876,7 @@
         } else {
             memcpy(s->buf_ptr, buf_start, len);
             s->buf_ptr += len;
-            if(   (s2->flags&CODEC_FLAG_NOT_TRUNCATED) && (!start_code_found) 
+            if(   (!(s2->flags&CODEC_FLAG_TRUNCATED)) && (!start_code_found) 
                && s->buf_ptr+4<s->buffer+s->buffer_size){
                 start_code_found= 1;
                 code= 0x1FF;
@@ -1971,5 +1971,5 @@
     NULL,
     mpeg_decode_end,
     mpeg_decode_frame,
-    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
 };
--- a/mpegvideo.c	Wed Nov 06 11:59:17 2002 +0000
+++ b/mpegvideo.c	Fri Nov 08 18:35:39 2002 +0000
@@ -445,6 +445,8 @@
     
     s->block= s->blocks[0];
 
+    s->parse_context.state= -1;
+
     s->context_initialized = 1;
     return 0;
  fail:
--- a/mpegvideo.h	Wed Nov 06 11:59:17 2002 +0000
+++ b/mpegvideo.h	Fri Nov 08 18:35:39 2002 +0000
@@ -109,6 +109,15 @@
 #endif
 } ScanTable;
 
+typedef struct ParseContext{
+    UINT8 *buffer;
+    int index;
+    int last_index;
+    int buffer_size;
+    int state;
+    int frame_start_found;
+} ParseContext;
+
 typedef struct MpegEncContext {
     struct AVCodecContext *avctx;
     /* the following parameters must be initialized before encoding */
@@ -351,6 +360,8 @@
     int mb_num_left;                 /* number of MBs left in this video packet (for partitioned Slices only)*/
     int next_p_frame_damaged;        /* set if the next p frame is damaged, to avoid showing trashed b frames */
     int error_resilience;
+    
+    ParseContext parse_context;
 
     /* H.263 specific */
     int gob_number;