[FFmpeg-soc] [soc]: r1207 - in rv40: add_rv40.patch doc.patch rv30data.h rv40.c

kostya subversion at mplayerhq.hu
Mon Aug 27 19:54:36 CEST 2007


Author: kostya
Date: Mon Aug 27 19:54:36 2007
New Revision: 1207

Log:
Partial RV30 support

Added:
   rv40/rv30data.h
Modified:
   rv40/add_rv40.patch
   rv40/doc.patch
   rv40/rv40.c

Modified: rv40/add_rv40.patch
==============================================================================
--- rv40/add_rv40.patch	(original)
+++ rv40/add_rv40.patch	Mon Aug 27 19:54:36 2007
@@ -2,10 +2,11 @@ Index: libavcodec/Makefile
 ===================================================================
 --- libavcodec/Makefile
 +++ libavcodec/Makefile
-@@ -151,6 +151,7 @@
+@@ -151,6 +151,8 @@
  OBJS-$(CONFIG_RV10_ENCODER)            += rv10.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o
  OBJS-$(CONFIG_RV20_DECODER)            += rv10.o h263.o
  OBJS-$(CONFIG_RV20_ENCODER)            += rv10.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o
++OBJS-$(CONFIG_RV30_DECODER)            += rv40.o h264pred.o
 +OBJS-$(CONFIG_RV40_DECODER)            += rv40.o h264pred.o
  OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
  OBJS-$(CONFIG_SGI_ENCODER)             += sgienc.o rle.o
@@ -14,11 +15,25 @@ Index: libavcodec/allcodecs.c
 ===================================================================
 --- libavcodec/allcodecs.c
 +++ libavcodec/allcodecs.c
-@@ -128,6 +128,7 @@
+@@ -128,6 +128,8 @@
      REGISTER_DECODER(RPZA, rpza);
      REGISTER_ENCDEC (RV10, rv10);
      REGISTER_ENCDEC (RV20, rv20);
++    REGISTER_DECODER(RV30, rv30);
 +    REGISTER_DECODER(RV40, rv40);
      REGISTER_ENCDEC (SGI, sgi);
      REGISTER_DECODER(SMACKER, smacker);
      REGISTER_DECODER(SMC, smc);
+Index: libavformat/riff.c
+===================================================================
+--- libavformat/riff.c
++++ libavformat/riff.c
+@@ -172,6 +172,8 @@
+     { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') },
+     { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
+     { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
++    { CODEC_ID_RV30, MKTAG('R', 'V', '3', '0') },
++    { CODEC_ID_RV40, MKTAG('R', 'V', '4', '0') },
+     { CODEC_ID_NONE, 0 },
+ };
+ 

Modified: rv40/doc.patch
==============================================================================
--- rv40/doc.patch	(original)
+++ rv40/doc.patch	Mon Aug 27 19:54:36 2007
@@ -6,7 +6,7 @@ Index: Changelog
  - OS/2 support removed
  - AC-3 decoder
  - NUT muxer (since r10052)
-+- RealVideo 4 decoder
++- RealVideo 3 and 4 decoder
  
  version 0.4.9-pre1:
  
@@ -14,10 +14,11 @@ Index: doc/ffmpeg-doc.texi
 ===================================================================
 --- doc/ffmpeg-doc.texi
 +++ doc/ffmpeg-doc.texi
-@@ -1004,6 +1004,7 @@
+@@ -1004,6 +1004,8 @@
  @item H.264                  @tab     @tab  X
  @item RealVideo 1.0          @tab  X  @tab  X
  @item RealVideo 2.0          @tab  X  @tab  X
++ at item RealVideo 3.0          @tab     @tab  X @tab not completely working
 + at item RealVideo 4.0          @tab     @tab  X @tab not completely working
  @item MJPEG                  @tab  X  @tab  X
  @item lossless MJPEG         @tab  X  @tab  X

Added: rv40/rv30data.h
==============================================================================
--- (empty file)
+++ rv40/rv30data.h	Mon Aug 27 19:54:36 2007
@@ -0,0 +1,176 @@
+/*
+ * RealVideo 3 decoder
+ * copyright (c) 2007 Konstantin Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file rv30data.h
+ * Miscellaneous RV30 tables.
+ */
+
+#ifndef RV30DATA_H
+#define RV30DATA_H
+
+#include <stdint.h>
+
+/** DC quantizer mapping for RV30 */
+static const uint8_t rv30_luma_dc_quant[32] = {
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 22, 22, 23, 23, 23, 24, 24, 25, 25
+};
+
+/**
+ * This table is used for storing differences
+ * between predicted and real intra type.
+ */
+static const uint8_t rv30_itype_code[98*2] = {
+    0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 0, 3, 3, 0, 1, 2,
+    2, 1, 0, 4, 4, 0, 3, 1, 1, 3, 0, 5, 5, 0, 2, 2, 1, 4,
+    4, 1, 0, 6, 3, 2, 1, 5, 2, 3, 5, 1, 6, 0, 0, 7, 4, 2,
+    2, 4, 3, 3, 6, 1, 1, 6, 7, 0, 0, 8, 5, 2, 4, 3, 2, 5,
+    3, 4, 1, 7, 4, 4, 7, 1, 8, 0, 6, 2, 3, 5, 5, 3, 2, 6,
+    1, 8, 2, 7, 7, 2, 8, 1, 5, 4, 4, 5, 3, 6, 6, 3, 8, 2,
+    4, 6, 5, 5, 6, 7, 5, 5, 6, 4, 2, 8, 7, 3, 3, 7, 6, 5,
+    5, 6, 7, 4, 4, 7, 8, 3, 3, 8, 7, 5, 8, 4, 5, 7, 4, 8,
+    6, 6, 7, 6, 5, 8, 8, 5, 6, 7, 8, 6, 7, 7, 6, 8, 8, 7,
+    7, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/**
+ * This table is used for retrieving current intra type
+ * basing on its neighbours and adjustment provided by
+ * code read and decoded before.
+ *
+ * This is really three-dimensional matrix with dimensions
+ * [-1..9][-1..9][0..9], first and second coordinates
+ * are detemined by top and left neighbours (-1 if unavailable).
+ */
+static const uint8_t rv30_itype_from_context[900] = {
+    0, 9, 9, 9, 9, 9, 9, 9, 9,
+    0, 2, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    2, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+
+    0, 1, 9, 9, 9, 9, 9, 9, 9,
+    0, 2, 1, 6, 4, 8, 5, 7, 3,
+    1, 0, 2, 6, 5, 4, 3, 8, 7,
+    2, 8, 0, 1, 7, 4, 3, 6, 5,
+    2, 0, 1, 3, 8, 5, 4, 7, 6,
+    2, 0, 1, 4, 6, 7, 8, 3, 5,
+    0, 1, 5, 2, 6, 3, 8, 4, 7,
+    0, 1, 6, 2, 4, 7, 5, 8, 3,
+    2, 7, 0, 1, 4, 8, 6, 3, 5,
+    2, 8, 0, 1, 7, 3, 4, 5, 6,
+
+    1, 0, 9, 9, 9, 9, 9, 9, 9,
+    1, 2, 5, 6, 3, 0, 4, 8, 7,
+    1, 6, 2, 5, 3, 0, 4, 8, 7,
+    2, 1, 7, 6, 8, 3, 5, 0, 4,
+    1, 2, 5, 3, 6, 8, 4, 7, 0,
+    1, 6, 2, 0, 4, 5, 8, 7, 3,
+    1, 5, 2, 6, 3, 8, 4, 0, 7,
+    1, 6, 0, 2, 4, 5, 7, 3, 8,
+    2, 1, 7, 6, 0, 8, 5, 4, 3,
+    1, 2, 7, 8, 3, 4, 5, 6, 0,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    0, 2, 1, 8, 7, 6, 5, 4, 3,
+    1, 2, 0, 6, 5, 7, 4, 8, 3,
+    2, 8, 7, 1, 0, 6, 4, 3, 5,
+    2, 0, 8, 1, 3, 7, 5, 4, 6,
+    2, 0, 4, 1, 7, 8, 6, 3, 5,
+    2, 0, 1, 5, 8, 4, 6, 7, 3,
+    2, 0, 6, 1, 4, 7, 8, 5, 3,
+    2, 7, 8, 1, 0, 5, 4, 6, 3,
+    2, 8, 7, 1, 0, 4, 3, 6, 5,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    0, 2, 1, 3, 5, 8, 6, 4, 7,
+    1, 0, 2, 5, 3, 6, 4, 8, 7,
+    2, 8, 1, 0, 3, 5, 7, 6, 4,
+    3, 2, 5, 8, 1, 4, 6, 7, 0,
+    4, 2, 0, 6, 1, 5, 8, 3, 7,
+    5, 3, 1, 2, 8, 6, 4, 0, 7,
+    1, 6, 0, 2, 4, 5, 8, 3, 7,
+    2, 7, 0, 1, 5, 4, 8, 6, 3,
+    2, 8, 3, 5, 1, 0, 7, 6, 4,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    2, 0, 6, 1, 4, 7, 5, 8, 3,
+    1, 6, 2, 0, 4, 5, 3, 7, 8,
+    2, 8, 7, 6, 4, 0, 1, 5, 3,
+    4, 2, 1, 0, 6, 8, 3, 5, 7,
+    4, 2, 6, 0, 1, 5, 7, 8, 3,
+    1, 2, 5, 0, 6, 3, 4, 7, 8,
+    6, 4, 0, 1, 2, 7, 5, 3, 8,
+    2, 7, 4, 6, 0, 1, 8, 5, 3,
+    2, 8, 7, 4, 6, 1, 3, 5, 0,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    5, 1, 2, 3, 6, 8, 0, 4, 7,
+    1, 5, 6, 3, 2, 0, 4, 8, 7,
+    2, 1, 5, 3, 6, 8, 7, 4, 0,
+    5, 3, 1, 2, 6, 8, 4, 7, 0,
+    1, 6, 2, 4, 5, 8, 0, 3, 7,
+    5, 1, 3, 6, 2, 0, 8, 4, 7,
+    1, 6, 5, 2, 0, 4, 3, 7, 8,
+    2, 7, 1, 6, 5, 0, 8, 3, 4,
+    2, 5, 1, 3, 6, 8, 4, 0, 7,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    1, 6, 2, 0, 5, 4, 3, 7, 8,
+    1, 6, 5, 4, 2, 3, 0, 7, 8,
+    2, 1, 6, 7, 4, 8, 5, 3, 0,
+    2, 1, 6, 5, 8, 4, 3, 0, 7,
+    6, 4, 1, 2, 0, 5, 7, 8, 3,
+    1, 6, 5, 2, 3, 0, 4, 8, 7,
+    6, 1, 4, 0, 2, 7, 5, 3, 8,
+    2, 7, 4, 6, 1, 5, 0, 8, 3,
+    2, 1, 6, 8, 4, 7, 3, 5, 0,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    2, 0, 4, 7, 6, 1, 8, 5, 3,
+    6, 1, 2, 0, 4, 7, 5, 8, 3,
+    2, 7, 8, 0, 1, 6, 4, 3, 5,
+    2, 4, 0, 8, 3, 1, 7, 6, 5,
+    4, 2, 7, 0, 6, 1, 8, 5, 3,
+    2, 1, 0, 8, 5, 6, 7, 4, 3,
+    2, 6, 4, 1, 7, 0, 5, 8, 3,
+    2, 7, 4, 0, 8, 6, 1, 5, 3,
+    2, 8, 7, 4, 1, 0, 3, 6, 5,
+
+    9, 9, 9, 9, 9, 9, 9, 9, 9,
+    2, 0, 8, 1, 3, 4, 6, 5, 7,
+    1, 2, 0, 6, 8, 5, 7, 3, 4,
+    2, 8, 7, 1, 0, 3, 6, 5, 4,
+    8, 3, 2, 5, 1, 0, 4, 7, 6,
+    2, 0, 4, 8, 5, 1, 7, 6, 3,
+    2, 1, 0, 8, 5, 3, 6, 4, 7,
+    2, 1, 6, 0, 8, 4, 5, 7, 3,
+    2, 7, 8, 4, 0, 6, 1, 5, 3,
+    2, 8, 3, 0, 7, 4, 1, 6, 5,
+};
+#endif /* RV30DATA_H */

Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c	(original)
+++ rv40/rv40.c	Mon Aug 27 19:54:36 2007
@@ -21,7 +21,7 @@
 
 /**
  * @file rv40.c
- * RV40 decoder.
+ * RV30 and RV40 decoder.
  */
 
 #include "avcodec.h"
@@ -31,6 +31,7 @@
 #include "rv40vlc.h"
 #include "rv40vlc2.h"
 #include "rv40data.h"
+#include "rv30data.h"
 
 #include "h264pred.h"
 
@@ -124,6 +125,8 @@ typedef struct RV40DecContext{
 
     int truncated;           ///< flag signalling that slice ended prematurely
     SavedSliceInfo ssi;      ///< data for truncated slice
+
+    int rv30;                ///< indicates which RV variasnt is currently decoded
 }RV40DecContext;
 
 static RV40VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
@@ -549,6 +552,34 @@ static inline RV40VLC* choose_vlc_set(in
                 : &intra_vlcs[rv40_quant_to_vlc_set[0][av_clip(quant, 0, 30)]];
 }
 
+static int rv30_parse_slice_header(RV40DecContext *r, GetBitContext *gb, SliceInfo *si)
+{
+    int t, mb_bits;
+    int w = r->s.avctx->coded_width, h = r->s.avctx->coded_height;
+    int i, mb_size;
+
+    memset(si, 0, sizeof(SliceInfo));
+    si->type = -1;
+    get_bits(gb, 3);
+    si->type = get_bits(gb, 2);
+    if(get_bits1(gb))
+        return -1;
+    si->quant = get_bits(gb, 5);
+    get_bits1(gb);
+    t = get_bits(gb, 13);
+    get_bits(gb, 2);
+    si->vlc_set = 0;
+    mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
+    for(i = 0; i < 5; i++)
+        if(rv40_mb_max_sizes[i] > mb_size)
+            break;
+    mb_bits = rv40_mb_bits_sizes[i];
+    si->start = get_bits(gb, mb_bits);
+    get_bits1(gb);
+    si->header_size = get_bits_count(gb);
+    return 0;
+}
+
 static int rv40_parse_slice_header(RV40DecContext *r, GetBitContext *gb, SliceInfo *si)
 {
     int t, mb_bits;
@@ -583,6 +614,33 @@ static int rv40_parse_slice_header(RV40D
     return 0;
 }
 
+static inline int get_omega(GetBitContext *gb);
+
+/**
+ * Decode 4x4 intra types array
+ */
+static int rv30_decode_intra_types(RV40DecContext *r, GetBitContext *gb, int *dst)
+{
+    int i, j;
+    int A, B;
+    int *ptr;
+    int code;
+
+    for(i = 0; i < 4; i++, dst += r->intra_types_stride){
+        ptr = dst;
+        for(j = 0; j < 4; j+= 2){
+            code = (get_omega(gb) - 1) << 1;
+            A = ptr[-r->intra_types_stride] + 1;
+            B = ptr[-1] + 1;
+            *ptr++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + 0]];
+            A = ptr[-r->intra_types_stride] + 1;
+            B = ptr[-1] + 1;
+            *ptr++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + 1]];
+        }
+    }
+    return 0;
+}
+
 /**
  * Decode 4x4 intra types array
  */
@@ -698,6 +756,28 @@ static inline int get_omega_signed(GetBi
 /**
  * Decode macroblock information
  */
+static int rv30_decode_mb_info(RV40DecContext *r)
+{
+    static const int rv30_p_types[6] = { RV40_MB_SKIP, RV40_MB_P_16x16, RV40_MB_P_8x8, -1, RV40_MB_TYPE_INTRA, RV40_MB_TYPE_INTRA16x16 };
+    static const int rv30_b_types[6] = { RV40_MB_SKIP, RV40_MB_B_FORWARD, RV40_MB_B_BACKWARD, RV40_MB_TYPE_INTRA, RV40_MB_TYPE_INTRA16x16, -1 };
+    MpegEncContext *s = &r->s;
+    GetBitContext *gb = &s->gb;
+    int code;
+
+    code = get_omega(gb) - 1;
+    if(code > 5){
+        av_log(NULL,0, "dquant needed\n");
+        code -= 6;
+    }
+    if(s->pict_type != B_TYPE)
+        return rv30_p_types[code];
+    else
+        return rv30_b_types[code];
+}
+
+/**
+ * Decode macroblock information
+ */
 static int rv40_decode_mb_info(RV40DecContext *r)
 {
     MpegEncContext *s = &r->s;
@@ -1420,7 +1500,7 @@ static int rv40_decode_mb_header(RV40Dec
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int i, t;
 
-    if(!r->si.type){
+    if(!r->si.type && !r->rv30){
         r->is16 = 0;
         switch(decode210(gb)){
         case 0: // 16x16 block
@@ -1435,8 +1515,12 @@ static int rv40_decode_mb_header(RV40Dec
         }
         s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
         r->block_type = r->is16 ? RV40_MB_TYPE_INTRA16x16 : RV40_MB_TYPE_INTRA;
+    }else if(!r->si.type && r->rv30){
+        r->is16 = get_bits1(gb);
+        s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
+        r->block_type = r->is16 ? RV40_MB_TYPE_INTRA16x16 : RV40_MB_TYPE_INTRA;
     }else{
-        r->block_type = rv40_decode_mb_info(r);
+        r->block_type = r->rv30 ? rv30_decode_mb_info(r) : rv40_decode_mb_info(r);
         s->current_picture_ptr->mb_type[mb_pos] = rv40_mb_type_to_lavc[r->block_type];
         r->mb_type[mb_pos] = r->block_type;
         if(s->pict_type == P_TYPE && r->block_type == RV40_MB_SKIP)
@@ -1455,7 +1539,10 @@ static int rv40_decode_mb_header(RV40Dec
     }
     if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(!r->is16){
-            rv40_decode_intra_types(r, gb, intra_types);
+            if(r->rv30)
+                rv30_decode_intra_types(r, gb, intra_types);
+            else
+                rv40_decode_intra_types(r, gb, intra_types);
             r->chroma_vlc = 0;
             r->luma_vlc   = 1;
         }else{
@@ -1569,6 +1656,89 @@ static int check_slice_end(RV40DecContex
     return 0;
 }
 
+static int rv30_decode_slice(RV40DecContext *r, int size, int end, int *last)
+{
+    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) {
+        if(r->si.width) s->avctx->coded_width  = r->si.width;
+        if(r->si.height)s->avctx->coded_height = r->si.height;
+        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;
+    }
+if(s->pict_type == B_TYPE)return -1;
+    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;
+}
+
 static int rv40_decode_slice(RV40DecContext *r, int size, int end, int *last)
 {
     MpegEncContext *s = &r->s;
@@ -1881,6 +2051,7 @@ static int rv40_decode_init(AVCodecConte
 
     static int tables_done = 0;
 
+    r->rv30 = (avctx->codec_id == CODEC_ID_RV30);
     MPV_decode_defaults(s);
     s->avctx= avctx;
     s->out_format = FMT_H263;
@@ -1900,7 +2071,7 @@ static int rv40_decode_init(AVCodecConte
     if (MPV_common_init(s) < 0)
         return -1;
 
-    ff_h264_pred_init(&r->h, s->codec_id);
+    ff_h264_pred_init(&r->h, CODEC_ID_RV40);
 
     r->intra_types_stride = (s->mb_width + 1) * 4;
     r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(int));
@@ -1996,7 +2167,10 @@ static int rv40_decode_frame(AVCodecCont
                 r->si.end = si.start;
         }
         r->slice_data = buf + offset;
-        rv40_decode_slice(r, r->si.size, r->si.end, &last);
+        if(r->rv30)
+            rv30_decode_slice(r, r->si.size, r->si.end, &last);
+        else
+            rv40_decode_slice(r, r->si.size, r->si.end, &last);
         if(last)
             break;
         s->mb_num_left = r->si.end - r->si.start;
@@ -2036,6 +2210,17 @@ static int rv40_decode_end(AVCodecContex
     return 0;
 }
 
+AVCodec rv30_decoder = {
+    "rv30",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_RV30,
+    sizeof(RV40DecContext),
+    rv40_decode_init,
+    NULL,
+    rv40_decode_end,
+    rv40_decode_frame,
+};
+
 AVCodec rv40_decoder = {
     "rv40",
     CODEC_TYPE_VIDEO,



More information about the FFmpeg-soc mailing list