[FFmpeg-soc] [soc]: r1131 - rv40/rv40.c

kostya subversion at mplayerhq.hu
Tue Aug 21 13:34:14 CEST 2007


Author: kostya
Date: Tue Aug 21 13:34:14 2007
New Revision: 1131

Log:
Drop decoding by one slice
(find slice starts combined by parser instead)


Modified:
   rv40/rv40.c

Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c	(original)
+++ rv40/rv40.c	Tue Aug 21 13:34:14 2007
@@ -1846,6 +1846,30 @@ static int rv40_decode_init(AVCodecConte
     return 0;
 }
 
+/** These bits of slice header should be the same for all slices in one frame */
+#define KEY_MASK 0xE0CFFF80
+
+/**
+ * Find slice offsets and return them in array.
+ */
+static int* find_slice_offsets(uint8_t *buf, int buf_size, int *slices)
+{
+    int *offsets;
+    int i;
+    int hdr = AV_RB32(buf) & KEY_MASK;
+
+    offsets = av_malloc(sizeof(int)*12);//just to avoid unnecessary reallocs
+    offsets[0] = 0;
+    *slices = 1;
+    for(i = 4; i < buf_size; i += 4){
+        if((AV_RB32(buf + i) & KEY_MASK) == hdr){
+            (*slices)++;
+            offsets = av_realloc(offsets, *slices * sizeof(int));
+            offsets[*slices - 1] = i;
+        }
+    }
+    return offsets;
+}
 
 static int rv40_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_size,
@@ -1856,6 +1880,7 @@ static int rv40_decode_frame(AVCodecCont
     AVFrame *pict = data;
     SliceInfo si;
     int i;
+    int slice_count, *slice_offset;
 
     /* no supplementary picture */
     if (buf_size == 0) {
@@ -1869,22 +1894,28 @@ static int rv40_decode_frame(AVCodecCont
     }
 
     if(avctx->slice_count){
-        for(i=0; i<avctx->slice_count; i++){
-            int offset= avctx->slice_offset[i];
+        slice_count = avctx->slice_count;
+        slice_offset = avctx->slice_offset;
+    }else{
+        slice_offset = find_slice_offsets(buf, buf_size, &slice_count);
+    }
+
+    for(i=0; i<slice_count; i++){
+            int offset= slice_offset[i];
             int size;
 
-            if(i+1 == avctx->slice_count)
+            if(i+1 == slice_count)
                 size= buf_size - offset;
             else
-                size= avctx->slice_offset[i+1] - offset;
+                size= slice_offset[i+1] - offset;
 
             init_get_bits(&s->gb, buf + offset, size * 8);
             rv40_parse_slice_header(r, &r->s.gb, &r->prev_si);
             if(r->prev_si.type == -1) continue;
             r->prev_si.size = size * 8;
             r->prev_si.end = s->mb_width * s->mb_height;
-            if(i+1 < avctx->slice_count){
-                init_get_bits(&s->gb, buf+avctx->slice_offset[i+1], (buf_size-avctx->slice_offset[i+1])*8);
+            if(i+1 < slice_count){
+                init_get_bits(&s->gb, buf+slice_offset[i+1], (buf_size-slice_offset[i+1])*8);
                 rv40_parse_slice_header(r, &r->s.gb, &si);
                 if(si.type != -1)
                     r->prev_si.end = si.start;
@@ -1900,44 +1931,10 @@ static int rv40_decode_frame(AVCodecCont
             s->mb_num_left = r->prev_si.end - r->prev_si.start;
             //rv40_postprocess(r);
             r->slice_data = NULL;
-        }
-        ff_er_frame_end(s);
-        MPV_frame_end(s);
-        if (s->pict_type == B_TYPE || s->low_delay) {
-            *pict= *(AVFrame*)s->current_picture_ptr;
-        } else if (s->last_picture_ptr != NULL) {
-            *pict= *(AVFrame*)s->last_picture_ptr;
-        }
-
-        if(s->last_picture_ptr || s->low_delay){
-            *data_size = sizeof(AVFrame);
-            ff_print_debug_info(s, pict);
-        }
-        s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
-        s->mb_x = s->mb_y = 0;
-        return buf_size;
-    }
-
-    init_get_bits(&s->gb, buf, buf_size*8);
-    rv40_parse_slice_header(r, &r->s.gb, &si);
-    si.size = buf_size * 8;
-    si.end = s->mb_width * s->mb_height;
-
-    if(si.start > r->prev_si.start && si.type == r->prev_si.type) r->prev_si.end = si.start;
-    if(r->has_slice){
-        //XXX: Take it directly from slice info
-        r->cur_vlcs = choose_vlc_set(r->prev_si.quant, r->prev_si.vlc_set, r->prev_si.type);
-        r->quant = r->prev_si.quant;
-        r->bits = r->prev_si.size;
-        r->block_start = r->prev_si.start;
-        s->mb_num_left = r->prev_si.end - r->prev_si.start;
-        s->pict_type = r->prev_si.type ? r->prev_si.type : I_TYPE;
-        rv40_decode_slice(r);
-        s->mb_num_left = r->prev_si.end - r->prev_si.start;
-        //rv40_postprocess(r);
     }
+    if(!avctx->slice_count)
+        av_free(slice_offset);
 
-    if(r->has_slice && (si.start < r->prev_si.start || si.type != r->prev_si.type)){ // output complete frame
         ff_er_frame_end(s);
         MPV_frame_end(s);
         if (s->pict_type == B_TYPE || s->low_delay) {
@@ -1952,13 +1949,6 @@ static int rv40_decode_frame(AVCodecCont
         }
         s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
         s->mb_x = s->mb_y = 0;
-    }
-    //save slice for future decoding
-    r->slice_data = av_realloc(r->slice_data, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    memcpy(r->slice_data, buf, buf_size);
-    r->prev_si = si;
-    r->has_slice = si.type != -1;
-
     return buf_size;
 }
 



More information about the FFmpeg-soc mailing list