X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fcavsdec.c;h=9f91d0b8cac13bbf5b7e1b0b3fe119ac1a362955;hb=b6a6e90a7c79f9530637a1efb62e0af4049822c1;hp=7ff1a57eb5ae52f1d46f01050de6a46ad970efda;hpb=d36beb3f6902b1217beda576aa18abf7eb72b03c;p=ffmpeg diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 7ff1a57eb5a..9f91d0b8cac 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 * - * 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 */ @@ -130,12 +130,14 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, r++; mask = -(level_code & 1); level = (level^mask) - mask; - } else { + } else if (level_code >= 0) { 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; @@ -189,7 +191,8 @@ static inline int decode_residual_inter(AVSContext *h) { static int decode_mb_i(AVSContext *h, int cbp_code) { GetBitContext *gb = &h->s.gb; - int block, pred_mode_uv; + unsigned pred_mode_uv; + int block; uint8_t top[18]; uint8_t *left = NULL; uint8_t *d; @@ -220,7 +223,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) { ff_cavs_modify_mb_i(h, &pred_mode_uv); /* get coded block pattern */ - if(h->pic_type == FF_I_TYPE) + if(h->pic_type == AV_PICTURE_TYPE_I) cbp_code = get_ue_golomb(gb); if(cbp_code > 63){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); @@ -424,7 +427,7 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { h->qp = get_bits(gb,6); } /* inter frame or second slice can have weighting params */ - if((h->pic_type != FF_I_TYPE) || (!h->pic_structure && h->mby >= h->mb_width/2)) + if((h->pic_type != AV_PICTURE_TYPE_I) || (!h->pic_structure && h->mby >= h->mb_width/2)) if(get_bits1(gb)) { //slice_weighting_flag av_log(h->s.avctx, AV_LOG_ERROR, "weighted prediction not yet supported\n"); @@ -445,6 +448,8 @@ static inline int check_for_slice(AVSContext *h) { if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { skip_bits_long(gb,24+align); h->stc = get_bits(gb,8); + if (h->stc >= h->mb_height) + return 0; decode_slice_header(h,gb); return 1; } @@ -464,28 +469,28 @@ static int decode_pic(AVSContext *h) { if (!s->context_initialized) { s->avctx->idct_algo = FF_IDCT_CAVS; - if (MPV_common_init(s) < 0) + if (ff_MPV_common_init(s) < 0) return -1; ff_init_scantable(s->dsp.idct_permutation,&h->scantable,ff_zigzag_direct); } skip_bits(&s->gb,16);//bbv_dwlay if(h->stc == PIC_PB_START_CODE) { - h->pic_type = get_bits(&s->gb,2) + FF_I_TYPE; - if(h->pic_type > FF_B_TYPE) { + h->pic_type = get_bits(&s->gb,2) + AV_PICTURE_TYPE_I; + if(h->pic_type > AV_PICTURE_TYPE_B) { av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n"); return -1; } /* make sure we have the reference frames we need */ - if(!h->DPB[0].data[0] || - (!h->DPB[1].data[0] && h->pic_type == FF_B_TYPE)) + if(!h->DPB[0].f.data[0] || + (!h->DPB[1].f.data[0] && h->pic_type == AV_PICTURE_TYPE_B)) return -1; } else { - h->pic_type = FF_I_TYPE; + h->pic_type = AV_PICTURE_TYPE_I; if(get_bits1(&s->gb)) skip_bits(&s->gb,24);//time_code /* old sample clips were all progressive and no low_delay, bump stream revision if detected otherwise */ - if((s->low_delay) || !(show_bits(&s->gb,9) & 1)) + if (s->low_delay || !(show_bits(&s->gb,9) & 1)) h->stream_revision = 1; /* similarly test top_field_first and repeat_first_field */ else if(show_bits(&s->gb,11) & 3) @@ -494,15 +499,15 @@ static int decode_pic(AVSContext *h) { skip_bits(&s->gb,1); //marker_bit } /* release last B frame */ - if(h->picture.data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture); + if(h->picture.f.data[0]) + s->avctx->release_buffer(s->avctx, &h->picture.f); - s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture); + s->avctx->get_buffer(s->avctx, &h->picture.f); ff_cavs_init_pic(h); h->picture.poc = get_bits(&s->gb,8)*2; /* get temporal distances and MV scaling factors */ - if(h->pic_type != FF_B_TYPE) { + if(h->pic_type != AV_PICTURE_TYPE_B) { h->dist[0] = (h->picture.poc - h->DPB[0].poc + 512) % 512; } else { h->dist[0] = (h->DPB[0].poc - h->picture.poc + 512) % 512; @@ -510,7 +515,7 @@ static int decode_pic(AVSContext *h) { h->dist[1] = (h->picture.poc - h->DPB[1].poc + 512) % 512; h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0; h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0; - if(h->pic_type == FF_B_TYPE) { + if(h->pic_type == AV_PICTURE_TYPE_B) { h->sym_factor = h->dist[0]*h->scale_den[1]; } else { h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0; @@ -529,12 +534,12 @@ static int decode_pic(AVSContext *h) { skip_bits1(&s->gb); //repeat_first_field h->qp_fixed = get_bits1(&s->gb); h->qp = get_bits(&s->gb,6); - if(h->pic_type == FF_I_TYPE) { + if(h->pic_type == AV_PICTURE_TYPE_I) { if(!h->progressive && !h->pic_structure) skip_bits1(&s->gb);//what is this? skip_bits(&s->gb,4); //reserved bits } else { - if(!(h->pic_type == FF_B_TYPE && h->pic_structure == 1)) + if(!(h->pic_type == AV_PICTURE_TYPE_B && h->pic_structure == 1)) h->ref_flag = get_bits1(&s->gb); skip_bits(&s->gb,4); //reserved bits h->skip_mode_flag = get_bits1(&s->gb); @@ -546,12 +551,12 @@ static int decode_pic(AVSContext *h) { } else { h->alpha_offset = h->beta_offset = 0; } - if(h->pic_type == FF_I_TYPE) { + if(h->pic_type == AV_PICTURE_TYPE_I) { do { check_for_slice(h); decode_mb_i(h, 0); } while(ff_cavs_next_mb(h)); - } else if(h->pic_type == FF_P_TYPE) { + } else if(h->pic_type == AV_PICTURE_TYPE_P) { do { if(check_for_slice(h)) skip_count = -1; @@ -567,7 +572,7 @@ static int decode_pic(AVSContext *h) { decode_mb_p(h,mb_type); } } while(ff_cavs_next_mb(h)); - } else { /* FF_B_TYPE */ + } else { /* AV_PICTURE_TYPE_B */ do { if(check_for_slice(h)) skip_count = -1; @@ -584,9 +589,9 @@ static int decode_pic(AVSContext *h) { } } while(ff_cavs_next_mb(h)); } - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]); + if(h->pic_type != AV_PICTURE_TYPE_B) { + if(h->DPB[1].f.data[0]) + s->avctx->release_buffer(s->avctx, &h->DPB[1].f); h->DPB[1] = h->DPB[0]; h->DPB[0] = h->picture; memset(&h->picture,0,sizeof(Picture)); @@ -619,8 +624,8 @@ static int decode_seq_header(AVSContext *h) { s->low_delay = get_bits1(&s->gb); h->mb_width = (s->width + 15) >> 4; h->mb_height = (s->height + 15) >> 4; - h->s.avctx->time_base.den = ff_frame_rate_tab[frame_rate_code].num; - h->s.avctx->time_base.num = ff_frame_rate_tab[frame_rate_code].den; + h->s.avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_code].num; + h->s.avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_code].den; h->s.avctx->width = s->width; h->s.avctx->height = s->height; if(!h->top_qp) @@ -648,9 +653,10 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, s->avctx = avctx; if (buf_size == 0) { - if(!s->low_delay && h->DPB[0].data[0]) { + if (!s->low_delay && h->DPB[0].f.data[0]) { *data_size = sizeof(AVPicture); - *picture = *(AVFrame *) &h->DPB[0]; + *picture = h->DPB[0].f; + memset(&h->DPB[0], 0, sizeof(h->DPB[0])); } return 0; } @@ -658,8 +664,8 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, buf_ptr = buf; buf_end = buf + buf_size; for(;;) { - buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); - if(stc & 0xFFFFFE00) + buf_ptr = avpriv_mpv_find_start_code(buf_ptr,buf_end, &stc); + if((stc & 0xFFFFFE00) || buf_ptr == buf_end) return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); input_size = (buf_end - buf_ptr)*8; switch(stc) { @@ -669,10 +675,10 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, break; case PIC_I_START_CODE: if(!h->got_keyframe) { - if(h->DPB[0].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]); - if(h->DPB[1].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]); + if(h->DPB[0].f.data[0]) + avctx->release_buffer(avctx, &h->DPB[0].f); + if(h->DPB[1].f.data[0]) + avctx->release_buffer(avctx, &h->DPB[1].f); h->got_keyframe = 1; } case PIC_PB_START_CODE: @@ -684,14 +690,14 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, if(decode_pic(h)) break; *data_size = sizeof(AVPicture); - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) { - *picture = *(AVFrame *) &h->DPB[1]; + if(h->pic_type != AV_PICTURE_TYPE_B) { + if(h->DPB[1].f.data[0]) { + *picture = h->DPB[1].f; } else { *data_size = 0; } } else - *picture = *(AVFrame *) &h->picture; + *picture = h->picture.f; break; case EXT_START_CODE: //mpeg_decode_extension(avctx,buf_ptr, input_size); @@ -710,15 +716,14 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, } AVCodec ff_cavs_decoder = { - "cavs", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CAVS, - sizeof(AVSContext), - ff_cavs_init, - NULL, - ff_cavs_end, - cavs_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush= cavs_flush, - .long_name= NULL_IF_CONFIG_SMALL("Chinese AVS video (AVS1-P2, JiZhun profile)"), + .name = "cavs", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_CAVS, + .priv_data_size = sizeof(AVSContext), + .init = ff_cavs_init, + .close = ff_cavs_end, + .decode = cavs_decode_frame, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, + .flush = cavs_flush, + .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS video (AVS1-P2, JiZhun profile)"), };