diff options
Diffstat (limited to 'libavcodec/cavsdec.c')
-rw-r--r-- | libavcodec/cavsdec.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 9f91d0b8ca..a464512773 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -115,7 +115,8 @@ static inline int get_ue_code(GetBitContext *gb, int order) { static int decode_residual_block(AVSContext *h, GetBitContext *gb, const struct dec_2dvlc *r, int esc_golomb_order, int qp, uint8_t *dst, int stride) { - int i, level_code, esc_code, level, run, mask; + int i, esc_code, level, mask; + unsigned int level_code, run; DCTELEM level_buf[65]; uint8_t run_buf[65]; DCTELEM *block = h->block; @@ -124,20 +125,20 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, level_code = get_ue_code(gb,r->golomb_order); if(level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; + if(run > 64) + return -1; esc_code = get_ue_code(gb,esc_golomb_order); level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while(level > r->inc_limit) r++; mask = -(level_code & 1); level = (level^mask) - mask; - } else if (level_code >= 0) { + } else { level = r->rltab[level_code][0]; if(!level) //end of block signal break; run = r->rltab[level_code][1]; r += r->rltab[level_code][2]; - } else { - break; } level_buf[i] = level; run_buf[i] = run; @@ -165,7 +166,7 @@ static inline int decode_residual_inter(AVSContext *h) { /* get coded block pattern */ int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63){ + if(cbp > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); return -1; } @@ -225,7 +226,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) { /* get coded block pattern */ if(h->pic_type == AV_PICTURE_TYPE_I) cbp_code = get_ue_golomb(gb); - if(cbp_code > 63){ + if(cbp_code > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return -1; } @@ -417,6 +418,10 @@ static void decode_mb_b(AVSContext *h, enum cavs_mb mb_type) { static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { if(h->stc > 0xAF) av_log(h->s.avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); + + if (h->stc >= h->mb_height) + return -1; + h->mby = h->stc; h->mbidx = h->mby*h->mb_width; @@ -608,12 +613,19 @@ static int decode_pic(AVSContext *h) { static int decode_seq_header(AVSContext *h) { MpegEncContext *s = &h->s; int frame_rate_code; + int width, height; h->profile = get_bits(&s->gb,8); h->level = get_bits(&s->gb,8); skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); + width = get_bits(&s->gb,14); + height = get_bits(&s->gb,14); + if ((s->width || s->height) && (s->width != width || s->height != height)) { + av_log_missing_feature(s, "Width/height changing in CAVS is", 0); + return -1; + } + s->width = width; + s->height = height; skip_bits(&s->gb,2); //chroma format skip_bits(&s->gb,3); //sample_precision h->aspect_ratio = get_bits(&s->gb,4); @@ -685,6 +697,8 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, *data_size = 0; if(!h->got_keyframe) break; + if(!h->top_qp) + break; init_get_bits(&s->gb, buf_ptr, input_size); h->stc = stc; if(decode_pic(h)) |