truncated h263 decoding support / H263-ES "demuxer"
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 22 May 2003 14:12:22 +0000 (14:12 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 22 May 2003 14:12:22 +0000 (14:12 +0000)
Originally committed as revision 1898 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/h263.c
libavcodec/h263dec.c
libavformat/raw.c

index cfaec76..5b3119a 100644 (file)
@@ -3902,10 +3902,21 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
 /* most is hardcoded. should extend to handle all h263 streams */
 int h263_decode_picture_header(MpegEncContext *s)
 {
-    int format, width, height;
+    int format, width, height, i;
+    uint32_t startcode;
+    
+    align_get_bits(&s->gb);
 
-    /* picture start code */
-    if (get_bits_long(&s->gb, 22) != 0x20) {
+    startcode= get_bits(&s->gb, 22-8);
+
+    for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>0; i--) {
+        startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF;
+        
+        if(startcode == 0x20)
+            break;
+    }
+        
+    if (startcode != 0x20) {
         fprintf(stderr, "Bad picture start code\n");
         return -1;
     }
@@ -3988,15 +3999,26 @@ int h263_decode_picture_header(MpegEncContext *s)
                 s->h263_aic = 1;
             }
            
-            skip_bits(&s->gb, 7);
-            /* these are the 7 bits: (in order of appearence  */
-            /* Deblocking Filter */
-            /* Slice Structured */
-            /* Reference Picture Selection */
-            /* Independent Segment Decoding */
-            /* Alternative Inter VLC */
-            /* Modified Quantization */
-            /* Prevent start code emulation */
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Deblocking Filter not supported\n");
+            }
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Slice Structured not supported\n");
+            }
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Reference Picture Selection not supported\n");
+            }
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Independent Segment Decoding not supported\n");
+            }
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Alternative Inter VLC not supported\n");
+            }
+            if (get_bits1(&s->gb) != 0) {
+                fprintf(stderr, "Modified Quantization not supported\n");
+            }
+            
+            skip_bits(&s->gb, 1); /* Prevent start code emulation */
 
             skip_bits(&s->gb, 3); /* Reserved */
         } else if (ufep != 0) {
@@ -4072,6 +4094,18 @@ int h263_decode_picture_header(MpegEncContext *s)
         s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
     }
 
+     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
+         printf("qp:%d %c size:%d rnd:%d %s %s %s %s\n", 
+         s->qscale, av_get_pict_type_char(s->pict_type),
+         s->gb.size_in_bits, 1-s->no_rounding,
+         s->mv_type == MV_TYPE_8X8 ? "ADV" : "",
+         s->umvplus ? "UMV" : "",
+         s->h263_long_vectors ? "LONG" : "",
+         s->h263_plus ? "+" : ""
+         ); 
+     }
+
+    
     return 0;
 }
 
index 4f42489..5ba0e16 100644 (file)
@@ -341,6 +341,42 @@ static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
     return END_NOT_FOUND;
 }
 
+static int h263_find_frame_end(MpegEncContext *s, uint8_t *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>>(32-22) == 0x20){
+                i++;
+                vop_found=1;
+                break;
+            }
+        }
+    }
+
+    if(vop_found){    
+      for(; i<buf_size; i++){
+        state= (state<<8) | buf[i];
+        if(state>>(32-22) == 0x20){
+            pc->frame_start_found=0;
+            pc->state=-1; 
+            return i-3;
+        }
+      }
+    }
+    pc->frame_start_found= vop_found;
+    pc->state= state;
+    
+    return END_NOT_FOUND;
+}
+
 /**
  * draws an line from (ex, ey) -> (sx, sy).
  * @param w width of the image
@@ -440,6 +476,8 @@ uint64_t time= rdtsc();
         
         if(s->codec_id==CODEC_ID_MPEG4){
             next= mpeg4_find_frame_end(s, buf, buf_size);
+        }else if(s->codec_id==CODEC_ID_H263){
+            next= h263_find_frame_end(s, buf, buf_size);
         }else{
             fprintf(stderr, "this codec doesnt support truncated bitstreams\n");
             return -1;
@@ -753,6 +791,7 @@ retry:
 #ifdef PRINT_FRAME_TIME
 printf("%Ld\n", rdtsc()-time);
 #endif
+
     return get_consumed_bytes(s, buf_size);
 }
 
@@ -784,7 +823,7 @@ AVCodec h263_decoder = {
     NULL,
     ff_h263_decode_end,
     ff_h263_decode_frame,
-    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
 };
 
 AVCodec msmpeg4v1_decoder = {
index 1c528c1..2354ad1 100644 (file)
@@ -208,6 +208,22 @@ static int mpegvideo_probe(AVProbeData *p)
     return 0;
 }
 
+static int h263_probe(AVProbeData *p)
+{
+    int code;
+    const uint8_t *d;
+
+    if (p->buf_size < 6)
+        return 0;
+    d = p->buf;
+    code = (d[0] << 14) | (d[1] << 6) | (d[2] >> 2);
+    if (code == 0x20) {
+        return 50;
+    }
+    return 0;
+}
+
+
 AVInputFormat mp3_iformat = {
     "mp3",
     "MPEG audio",
@@ -275,6 +291,18 @@ AVOutputFormat ac3_oformat = {
     raw_write_trailer,
 };
 
+AVInputFormat h263_iformat = {
+    "h263",
+    "raw h263",
+    0,
+    h263_probe,
+    video_read_header,
+    raw_read_packet,
+    raw_read_close,
+//    .extensions = "h263", //FIXME remove after writing mpeg4_probe
+    .value = CODEC_ID_H263,
+};
+
 AVOutputFormat h263_oformat = {
     "h263",
     "raw h263",
@@ -538,6 +566,7 @@ int raw_init(void)
     av_register_input_format(&ac3_iformat);
     av_register_output_format(&ac3_oformat);
 
+    av_register_input_format(&h263_iformat);
     av_register_output_format(&h263_oformat);
     
     av_register_input_format(&m4v_iformat);