X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Frv30.c;h=7218fa36dce4f4ba9d6e13c82d00bf5ec5851693;hb=788544ff0ed6fe67fda80ad6d3a0796ace035584;hp=ae99a823bf1a08c10f0f108e7d5be98283cc15de;hpb=c242bbd8b6939507a1a6fb64101b0553d92d303f;p=ffmpeg diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index ae99a823bf1..7218fa36dce 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "mpegutils.h" #include "mpegvideo.h" #include "golomb.h" @@ -34,6 +35,7 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) { + AVCodecContext *avctx = r->s.avctx; int mb_bits; int w = r->s.width, h = r->s.height; int mb_size; @@ -51,6 +53,13 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn si->pts = get_bits(gb, 13); rpr = get_bits(gb, r->rpr); if(rpr){ + if (avctx->extradata_size < rpr * 2 + 8) { + av_log(avctx, AV_LOG_ERROR, + "Insufficient extradata - need at least %d bytes, got %d\n", + 8 + rpr * 2, avctx->extradata_size); + return AVERROR(EINVAL); + } + w = r->s.avctx->extradata[6 + rpr*2] << 2; h = r->s.avctx->extradata[7 + rpr*2] << 2; } @@ -72,7 +81,7 @@ static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ for(j = 0; j < 4; j+= 2){ - unsigned code = svq3_get_ue_golomb(gb) << 1; + unsigned code = get_interleaved_ue_golomb(gb) << 1; if(code >= 81*2){ av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); return -1; @@ -100,7 +109,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; - unsigned code = svq3_get_ue_golomb(gb); + unsigned code = get_interleaved_ue_golomb(gb); if (code > 11) { av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); @@ -119,7 +128,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) static inline void rv30_weak_loop_filter(uint8_t *src, const int step, const int stride, const int lim) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; int i, diff; for(i = 0; i < 4; i++){ @@ -141,7 +150,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int mbtype = s->current_picture_ptr->f.mb_type[mb_pos]; + int mbtype = s->current_picture_ptr->mb_type[mb_pos]; if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) r->deblock_coefs[mb_pos] = 0xFFFF; if(IS_INTRA(mbtype)) @@ -153,11 +162,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row) */ mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]]; + cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; if(mb_x) - left_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - 1]]; + left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]]; for(j = 0; j < 16; j += 4){ - Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; + Y = s->current_picture_ptr->f->data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; for(i = !mb_x; i < 4; i++, Y += 4){ int ij = i + j; loc_lim = 0; @@ -177,7 +186,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) if(mb_x) left_cbp = (r->cbp_chroma[mb_pos - 1] >> (k*4)) & 0xF; for(j = 0; j < 8; j += 4){ - C = s->current_picture_ptr->f.data[k + 1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x; + C = s->current_picture_ptr->f->data[k + 1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x; for(i = !mb_x; i < 2; i++, C += 4){ int ij = i + (j >> 1); loc_lim = 0; @@ -195,11 +204,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row) } mb_pos = row * s->mb_stride; for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]]; + cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; if(row) - top_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - s->mb_stride]]; + top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]]; for(j = 4*!row; j < 16; j += 4){ - Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize; + Y = s->current_picture_ptr->f->data[0] + mb_x*16 + (row*16 + j) * s->linesize; for(i = 0; i < 4; i++, Y += 4){ int ij = i + j; loc_lim = 0; @@ -219,7 +228,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row) if(row) top_cbp = (r->cbp_chroma[mb_pos - s->mb_stride] >> (k*4)) & 0xF; for(j = 4*!row; j < 8; j += 4){ - C = s->current_picture_ptr->f.data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize; + C = s->current_picture_ptr->f->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize; for(i = 0; i < 2; i++, C += 4){ int ij = i + (j >> 1); loc_lim = 0; @@ -243,20 +252,18 @@ static void rv30_loop_filter(RV34DecContext *r, int row) static av_cold int rv30_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; + int ret; r->rv30 = 1; - ff_rv34_decode_init(avctx); + if ((ret = ff_rv34_decode_init(avctx)) < 0) + return ret; if(avctx->extradata_size < 2){ av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; } r->rpr = (avctx->extradata[1] & 7) >> 1; r->rpr = FFMIN(r->rpr + 1, 3); - if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){ - av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n", - 6 + r->rpr * 2, avctx->extradata_size); - return AVERROR(EINVAL); - } + r->parse_slice_header = rv30_parse_slice_header; r->decode_intra_types = rv30_decode_intra_types; r->decode_mb_info = rv30_decode_mb_info; @@ -268,17 +275,20 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx) AVCodec ff_rv30_decoder = { .name = "rv30", + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_RV30, .priv_data_size = sizeof(RV34DecContext), .init = rv30_decode_init, .close = ff_rv34_decode_end, .decode = ff_rv34_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | - CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | + AV_CODEC_CAP_FRAME_THREADS, .flush = ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), - .pix_fmts = ff_pixfmt_list_420, + .pix_fmts = (const enum AVPixelFormat[]) { + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE + }, .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), };