]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/rv10.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / rv10.c
index 2f822a8ac20f74d2629b5013ce9c8c5a0d6c902b..d53265b4187c6562b41ebe879e49ff4410ab068a 100644 (file)
 
 //#define DEBUG
 
+#define RV_GET_MAJOR_VER(x)  ((x) >> 28)
+#define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF)
+#define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
+
 #define DC_VLC_BITS 14 //FIXME find a better solution
 
 static const uint16_t rv_lum_code[256] =
@@ -292,6 +296,7 @@ static int rv10_decode_picture_header(MpegEncContext *s)
 static int rv20_decode_picture_header(MpegEncContext *s)
 {
     int seq, mb_pos, i;
+    int rpr_bits;
 
 #if 0
     GetBitContext gb= s->gb;
@@ -310,13 +315,6 @@ static int rv20_decode_picture_header(MpegEncContext *s)
     av_log(s->avctx, AV_LOG_DEBUG, "\n");
 #endif
 
-    if(s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){
-        if (get_bits(&s->gb, 3)){
-            av_log(s->avctx, AV_LOG_ERROR, "unknown triplet set\n");
-            return -1;
-        }
-    }
-
     i= get_bits(&s->gb, 2);
     switch(i){
     case 0: s->pict_type= AV_PICTURE_TYPE_I; break;
@@ -334,7 +332,7 @@ static int rv20_decode_picture_header(MpegEncContext *s)
     }
 
     if (get_bits1(&s->gb)){
-        av_log(s->avctx, AV_LOG_ERROR, "unknown bit set\n");
+        av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n");
         return -1;
     }
 
@@ -343,23 +341,21 @@ static int rv20_decode_picture_header(MpegEncContext *s)
         av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");
         return -1;
     }
-    if(s->avctx->sub_id == 0x30203002){
-        if (get_bits1(&s->gb)){
-            av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n");
-            return -1;
-        }
-    }
 
-    if(s->avctx->has_b_frames){
-        int f, new_w, new_h;
-        int v= s->avctx->extradata_size >= 4 ? 7&((uint8_t*)s->avctx->extradata)[1] : 0;
+    if(RV_GET_MINOR_VER(s->avctx->sub_id) >= 2)
+        s->loop_filter = get_bits1(&s->gb);
 
-        if (get_bits1(&s->gb)){
-            av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n");
-        }
-        seq= get_bits(&s->gb, 13)<<2;
+    if(RV_GET_MINOR_VER(s->avctx->sub_id) <= 1)
+        seq = get_bits(&s->gb, 8) << 7;
+    else
+        seq = get_bits(&s->gb, 13) << 2;
+
+    rpr_bits = s->avctx->extradata[1] & 7;
+    if(rpr_bits){
+        int f, new_w, new_h;
+        rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3);
 
-        f= get_bits(&s->gb, av_log2(v)+1);
+        f = get_bits(&s->gb, rpr_bits);
 
         if(f){
             new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f];
@@ -381,19 +377,12 @@ static int rv20_decode_picture_header(MpegEncContext *s)
         }
 
         if(s->avctx->debug & FF_DEBUG_PICT_INFO){
-            av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, v);
+            av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits);
         }
-    }else{
-        seq= get_bits(&s->gb, 8)*128;
     }
 
-//     if(s->avctx->sub_id <= 0x20201002){ //0x20201002 definitely needs this
-    mb_pos= ff_h263_decode_mba(s);
-/*    }else{
-        mb_pos= get_bits(&s->gb, av_log2(s->mb_num-1)+1);
-        s->mb_x= mb_pos % s->mb_width;
-        s->mb_y= mb_pos / s->mb_width;
-    }*/
+    mb_pos = ff_h263_decode_mba(s);
+
 //av_log(s->avctx, AV_LOG_DEBUG, "%d\n", seq);
     seq |= s->time &~0x7FFF;
     if(seq - s->time >  0x4000) seq -= 0x8000;
@@ -420,6 +409,9 @@ static int rv20_decode_picture_header(MpegEncContext *s)
 av_log(s->avctx, AV_LOG_DEBUG, "\n");*/
     s->no_rounding= get_bits1(&s->gb);
 
+    if(RV_GET_MINOR_VER(s->avctx->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B)
+        skip_bits(&s->gb, 5); // binary decoder reads 3+2 bits here but they don't seem to be used
+
     s->f_code = 1;
     s->unrestricted_mv = 1;
     s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I;
@@ -444,6 +436,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
     static int done=0;
+    int major_ver, minor_ver, micro_ver;
 
     if (avctx->extradata_size < 8) {
         av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
@@ -462,32 +455,27 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
     s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1;
     avctx->sub_id= AV_RB32((uint8_t*)avctx->extradata + 4);
 
-    if (avctx->sub_id == 0x10000000) {
-        s->rv10_version= 0;
-        s->low_delay=1;
-    } else if (avctx->sub_id == 0x10001000) {
-        s->rv10_version= 3;
-        s->low_delay=1;
-    } else if (avctx->sub_id == 0x10002000) {
-        s->rv10_version= 3;
-        s->low_delay=1;
-        s->obmc=1;
-    } else if (avctx->sub_id == 0x10003000) {
-        s->rv10_version= 3;
-        s->low_delay=1;
-    } else if (avctx->sub_id == 0x10003001) {
-        s->rv10_version= 3;
-        s->low_delay=1;
-    } else if (    avctx->sub_id == 0x20001000
-               || (avctx->sub_id >= 0x20100000 && avctx->sub_id < 0x201a0000)) {
-        s->low_delay=1;
-    } else if (    avctx->sub_id == 0x30202002
-               ||  avctx->sub_id == 0x30203002
-               || (avctx->sub_id >= 0x20200002 && avctx->sub_id < 0x20300000)) {
-        s->low_delay=0;
-        s->avctx->has_b_frames=1;
-    } else
+    major_ver = RV_GET_MAJOR_VER(avctx->sub_id);
+    minor_ver = RV_GET_MINOR_VER(avctx->sub_id);
+    micro_ver = RV_GET_MICRO_VER(avctx->sub_id);
+
+    s->low_delay = 1;
+    switch (major_ver) {
+    case 1:
+        s->rv10_version = micro_ver ? 3 : 1;
+        s->obmc = micro_ver == 2;
+        break;
+    case 2:
+        if (minor_ver >= 2) {
+            s->low_delay = 0;
+            s->avctx->has_b_frames = 1;
+        }
+        break;
+    default:
         av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id);
+        av_log_missing_feature(avctx, "RV1/2 version", 1);
+        return AVERROR_PATCHWELCOME;
+    }
 
     if(avctx->debug & FF_DEBUG_PICT_INFO){
         av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", avctx->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
@@ -710,30 +698,28 @@ static int rv10_decode_frame(AVCodecContext *avctx,
 }
 
 AVCodec ff_rv10_decoder = {
-    "rv10",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_RV10,
-    sizeof(MpegEncContext),
-    rv10_decode_init,
-    NULL,
-    rv10_decode_end,
-    rv10_decode_frame,
-    CODEC_CAP_DR1,
+    .name           = "rv10",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_RV10,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = rv10_decode_init,
+    .close          = rv10_decode_end,
+    .decode         = rv10_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .max_lowres = 3,
     .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .pix_fmts= ff_pixfmt_list_420,
 };
 
 AVCodec ff_rv20_decoder = {
-    "rv20",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_RV20,
-    sizeof(MpegEncContext),
-    rv10_decode_init,
-    NULL,
-    rv10_decode_end,
-    rv10_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .name           = "rv20",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_RV20,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = rv10_decode_init,
+    .close          = rv10_decode_end,
+    .decode         = rv10_decode_frame,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .flush= ff_mpeg_flush,
     .max_lowres = 3,
     .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),