X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Frv10.c;h=d789eff787405d73115b7a0cfd955c6d95d424c0;hb=dad09ff93f5df1ec987493f404d43cd16991e992;hp=b6d87f4f09e49cedea3067fb1589b8211e28bd54;hpb=e16f217ceb95395669abe3cea18737e92fb78c82;p=ffmpeg diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index b6d87f4f09e..d789eff7874 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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, + * Libav 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 + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,7 +25,7 @@ * RV10/RV20 decoder */ -#include "libavcore/imgutils.h" +#include "libavutil/imgutils.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -34,6 +34,10 @@ //#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] = @@ -235,18 +239,18 @@ int rv_decode_dc(MpegEncContext *s, int n) /* read RV 1.0 compatible frame header */ static int rv10_decode_picture_header(MpegEncContext *s) { - int mb_count, pb_frame, marker, unk, mb_xy; + int mb_count, pb_frame, marker, mb_xy; marker = get_bits1(&s->gb); if (get_bits1(&s->gb)) - s->pict_type = FF_P_TYPE; + s->pict_type = AV_PICTURE_TYPE_P; else - s->pict_type = FF_I_TYPE; + s->pict_type = AV_PICTURE_TYPE_I; if(!marker) av_log(s->avctx, AV_LOG_ERROR, "marker missing\n"); pb_frame = get_bits1(&s->gb); - dprintf(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); + av_dlog(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); if (pb_frame){ av_log(s->avctx, AV_LOG_ERROR, "pb frame not supported\n"); @@ -259,13 +263,13 @@ static int rv10_decode_picture_header(MpegEncContext *s) return -1; } - if (s->pict_type == FF_I_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_I) { if (s->rv10_version == 3) { /* specific MPEG like DC coding not used */ s->last_dc[0] = get_bits(&s->gb, 8); s->last_dc[1] = get_bits(&s->gb, 8); s->last_dc[2] = get_bits(&s->gb, 8); - dprintf(s->avctx, "DC:%d %d %d\n", s->last_dc[0], + av_dlog(s->avctx, "DC:%d %d %d\n", s->last_dc[0], s->last_dc[1], s->last_dc[2]); } } @@ -282,7 +286,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) s->mb_y = 0; mb_count = s->mb_width * s->mb_height; } - unk= get_bits(&s->gb, 3); /* ignored */ + skip_bits(&s->gb, 3); /* ignored */ s->f_code = 1; s->unrestricted_mv = 1; @@ -292,49 +296,26 @@ static int rv10_decode_picture_header(MpegEncContext *s) static int rv20_decode_picture_header(MpegEncContext *s) { int seq, mb_pos, i; - -#if 0 - GetBitContext gb= s->gb; - for(i=0; i<64; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&gb)); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif -#if 0 - av_log(s->avctx, AV_LOG_DEBUG, "%3dx%03d/%02Xx%02X ", s->width, s->height, s->width/4, s->height/4); - for(i=0; iavctx->extradata_size; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%02X ", ((uint8_t*)s->avctx->extradata)[i]); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - 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; - } - } + int rpr_bits; i= get_bits(&s->gb, 2); switch(i){ - case 0: s->pict_type= FF_I_TYPE; break; - case 1: s->pict_type= FF_I_TYPE; break; //hmm ... - case 2: s->pict_type= FF_P_TYPE; break; - case 3: s->pict_type= FF_B_TYPE; break; + case 0: s->pict_type= AV_PICTURE_TYPE_I; break; + case 1: s->pict_type= AV_PICTURE_TYPE_I; break; //hmm ... + case 2: s->pict_type= AV_PICTURE_TYPE_P; break; + case 3: s->pict_type= AV_PICTURE_TYPE_B; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n"); return -1; } - if(s->last_picture_ptr==NULL && s->pict_type==FF_B_TYPE){ + if(s->last_picture_ptr==NULL && s->pict_type==AV_PICTURE_TYPE_B){ av_log(s->avctx, AV_LOG_ERROR, "early B pix\n"); return -1; } 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 +324,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; - f= get_bits(&s->gb, av_log2(v)+1); + 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, rpr_bits); if(f){ new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f]; @@ -381,25 +360,18 @@ 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; if(seq - s->time < -0x4000) seq += 0x8000; if(seq != s->time){ - if(s->pict_type!=FF_B_TYPE){ + if(s->pict_type!=AV_PICTURE_TYPE_B){ s->time= seq; s->pp_time= s->time - s->last_non_b_time; s->last_non_b_time= s->time; @@ -420,9 +392,12 @@ 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 == FF_I_TYPE; + s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I; // s->alt_inter_vlc=1; // s->obmc=1; // s->umvplus=1; @@ -435,7 +410,7 @@ av_log(s->avctx, AV_LOG_DEBUG, "\n");*/ seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding); } - assert(s->pict_type != FF_B_TYPE || !s->low_delay); + assert(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay); return s->mb_width*s->mb_height - mb_pos; } @@ -444,6 +419,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"); @@ -455,6 +431,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) s->avctx= avctx; s->out_format = FMT_H263; s->codec_id= avctx->codec_id; + avctx->flags |= CODEC_FLAG_EMU_EDGE; s->orig_width = s->width = avctx->coded_width; s->orig_height= s->height = avctx->coded_height; @@ -462,32 +439,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); @@ -561,7 +533,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, ff_er_frame_start(s); } - dprintf(avctx, "qscale=%d\n", s->qscale); + av_dlog(avctx, "qscale=%d\n", s->qscale); /* default quantization values */ if(s->codec_id== CODEC_ID_RV10){ @@ -600,7 +572,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, for(s->mb_num_left= mb_count; s->mb_num_left>0; s->mb_num_left--) { int ret; ff_update_block_index(s); - dprintf(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y); + av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y); s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; @@ -616,7 +588,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } - if(s->pict_type != FF_B_TYPE) + if(s->pict_type != AV_PICTURE_TYPE_B) ff_h263_update_motion_val(s); MPV_decode_mb(s, s->block); if(s->loop_filter) @@ -655,7 +627,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, int slice_count; const uint8_t *slices_hdr = NULL; - dprintf(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); + av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); /* no supplementary picture */ if (buf_size == 0) { @@ -691,7 +663,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, ff_er_frame_end(s); MPV_frame_end(s); - if (s->pict_type == FF_B_TYPE || s->low_delay) { + if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; @@ -707,31 +679,29 @@ static int rv10_decode_frame(AVCodecContext *avctx, return buf_size; } -AVCodec rv10_decoder = { - "rv10", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV10, - sizeof(MpegEncContext), - rv10_decode_init, - NULL, - rv10_decode_end, - rv10_decode_frame, - CODEC_CAP_DR1, +AVCodec ff_rv10_decoder = { + .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 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, +AVCodec ff_rv20_decoder = { + .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"),