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

kostya subversion at mplayerhq.hu
Sun Sep 16 17:13:02 CEST 2007


Author: kostya
Date: Sun Sep 16 17:13:02 2007
New Revision: 1352

Log:
New slice ends handling mechanism for both codecs

Modified:
   rv40/rv40.c

Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c	(original)
+++ rv40/rv40.c	Sun Sep 16 17:13:02 2007
@@ -1699,85 +1699,12 @@ static int check_slice_end(RV40DecContex
     return 0;
 }
 
-static int rv30_decode_slice(RV40DecContext *r, int size, int end, int *last)
+static inline int slice_compare(SliceInfo *si1, SliceInfo *si2)
 {
-    MpegEncContext *s = &r->s;
-    GetBitContext *gb = &s->gb;
-    int mb_pos;
-    *last = 1;
-
-    init_get_bits(&r->s.gb, r->slice_data, r->si.size);
-    if(rv30_parse_slice_header(r, gb, &r->si) < 0){
-        av_log(s->avctx, AV_LOG_ERROR, "Error parsing slice header\n");
-        *last = 0;
-        return -1;
-    }
-
-    if(r->prev_si.type != -1 && (r->si.type != r->prev_si.type || r->si.start <= r->prev_si.start || r->si.width != r->prev_si.width || r->si.height != r->prev_si.height)){
-        av_log(s->avctx, AV_LOG_ERROR, "Slice headers mismatch\n");
-    }
-    if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
-        s->pict_type = r->si.type ? r->si.type : I_TYPE;
-        if(MPV_frame_start(s, s->avctx) < 0)
-            return -1;
-        ff_er_frame_start(s);
-        s->current_picture_ptr = &s->current_picture;
-        s->mb_x = s->mb_y = 0;
-    }
-
-    r->si.size = size;
-    r->si.end = end;
-    r->quant = r->si.quant;
-    r->bits = r->si.size;
-    r->block_start = r->si.start;
-    s->mb_num_left = r->si.end - r->si.start;
-    r->skip_blocks = 0;
-
-    r->prev_si = r->si;
-    mb_pos = s->mb_x + s->mb_y * s->mb_width;
-    if(r->block_start != mb_pos){
-        av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->block_start, mb_pos);
-        s->mb_x = r->block_start % s->mb_width;
-        s->mb_y = r->block_start / s->mb_width;
-    }
-    memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(int));
-    s->first_slice_line = 1;
-    s->resync_mb_x= s->mb_x;
-    s->resync_mb_y= s->mb_y;
-
-    ff_init_block_index(s);
-    while(!check_slice_end(r, s) && s->mb_num_left-- && s->mb_y < s->mb_height) {
-        ff_update_block_index(s);
-        s->dsp.clear_blocks(s->block[0]);
-
-        /* save information about decoded position in case of truncated slice */
-        if(r->bits > get_bits_count(gb)){
-            r->ssi.bits_used = get_bits_count(gb);
-            r->ssi.mb_x = s->mb_x;
-            r->ssi.mb_y = s->mb_y;
-        }
-
-        if(rv40_decode_macroblock(r, r->intra_types + (s->mb_x + 1) * 4) < 0)
-            break;
-        if (++s->mb_x == s->mb_width) {
-            s->mb_x = 0;
-            s->mb_y++;
-            ff_init_block_index(s);
-
-            memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(int));
-            memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(int));
-        }
-        if(s->mb_x == s->resync_mb_x)
-            s->first_slice_line=0;
-    }
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
-    *last = 0;
-    if(s->mb_y >= s->mb_height || r->bits < get_bits_count(gb))
-        *last = 1;
-    if(r->bits > get_bits_count(gb) && show_bits(gb, r->bits-get_bits_count(gb)))
-        *last = 1;
-
-    return 0;
+    return si1->type   != si2->type ||
+           si1->start  >= si2->start ||
+           si1->width  != si2->width ||
+           si1->height != si2->height;
 }
 
 static int rv40_decode_slice(RV40DecContext *r, int size, int end, int *last)
@@ -1785,32 +1712,26 @@ static int rv40_decode_slice(RV40DecCont
     MpegEncContext *s = &r->s;
     GetBitContext *gb = &s->gb;
     int mb_pos;
+    int res;
+    int old_mb_x = r->ssi.mb_x, old_mb_y = r->ssi.mb_y;
     *last = 1;
 
     init_get_bits(&r->s.gb, r->slice_data, r->si.size);
-    if(rv40_parse_slice_header(r, gb, &r->si) < 0){
-        if(!r->truncated){
-            av_log(s->avctx, AV_LOG_ERROR, "Error parsing slice header\n");
-            *last = 0;
-            return -1;
-        }else{
-            r->ssi.data = av_realloc(r->ssi.data, r->ssi.data_size + (size>>3));
-            memcpy(r->ssi.data + r->ssi.data_size, r->slice_data, size >> 3);
-            r->ssi.data_size += size >> 3; // XXX: overflow check?
-            size = r->ssi.data_size * 8;
-            init_get_bits(&r->s.gb, r->ssi.data, r->ssi.data_size * 8);
-            r->si = r->prev_si;
-            skip_bits(gb, r->ssi.bits_used);
-            s->mb_x = r->ssi.mb_x;
-            s->mb_y = r->ssi.mb_y;
-            r->si.start = s->mb_x + s->mb_y * s->mb_width;
-        }
-    }else
-        r->truncated = 0;
-
-    if(!r->truncated && r->prev_si.type != -1 && (r->si.type != r->prev_si.type || r->si.start <= r->prev_si.start || r->si.width != r->prev_si.width || r->si.height != r->prev_si.height)){
-        av_log(s->avctx, AV_LOG_ERROR, "Slice headers mismatch\n");
+    res = r->rv30 ? rv30_parse_slice_header(r, gb, &r->si) : rv40_parse_slice_header(r, gb, &r->si);
+    if(res < 0 || (r->prev_si.type != -1 && slice_compare(&r->prev_si, &r->si))){
+        r->ssi.data = av_realloc(r->ssi.data, r->ssi.data_size + (size>>3));
+        memcpy(r->ssi.data + r->ssi.data_size, r->slice_data, size >> 3);
+        r->ssi.data_size += size >> 3; // XXX: overflow check?
+        size = r->ssi.data_size * 8;
+        init_get_bits(&r->s.gb, r->ssi.data, r->ssi.data_size * 8);
+        r->si = r->prev_si;
+        skip_bits(gb, r->ssi.bits_used);
+        s->mb_x = r->ssi.mb_x;
+        s->mb_y = r->ssi.mb_y;
+        r->si.start = s->mb_x + s->mb_y * s->mb_width;
+        r->truncated = 1;
     }
+
     if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
         if(s->width != r->si.width || s->height != r->si.height /*&& avcodec_check_dimensions(s->avctx, r->si.width, r->si.height) >= 0 */){
             av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height);
@@ -1876,20 +1797,20 @@ static int rv40_decode_slice(RV40DecCont
         if(s->mb_x == s->resync_mb_x)
             s->first_slice_line=0;
     }
+    if(!r->truncated)
+        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+    else // add only additionally decoded blocks
+        ff_er_add_slice(s, old_mb_x+1, old_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
     r->truncated = 0;
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
     *last = 0;
-    if(s->mb_y >= s->mb_height || r->bits < get_bits_count(gb))
+    if(s->mb_y >= s->mb_height)
         *last = 1;
     if(r->bits > get_bits_count(gb) && show_bits(gb, r->bits-get_bits_count(gb)))
         *last = 1;
 
-    if(r->bits < get_bits_count(gb)){
-        r->truncated = 1;
-        r->ssi.data = av_realloc(r->ssi.data, r->bits >> 3);
-        memcpy(r->ssi.data, r->slice_data, r->bits >> 3);
-        *last = 0;
-    }
+    r->ssi.data = av_realloc(r->ssi.data, r->bits >> 3);
+    r->ssi.data_size = r->bits >> 3;
+    memcpy(r->ssi.data, r->slice_data, r->bits >> 3);
     return 0;
 }
 
@@ -2224,7 +2145,7 @@ static int rv40_decode_frame(AVCodecCont
         }
         r->slice_data = buf + offset;
         if(r->rv30)
-            rv30_decode_slice(r, r->si.size, r->si.end, &last);
+            rv40_decode_slice(r, r->si.size, r->si.end, &last);
         else
             rv40_decode_slice(r, r->si.size, r->si.end, &last);
         if(last)



More information about the FFmpeg-soc mailing list