diff options
Diffstat (limited to 'libavcodec/vc1dec.c')
-rw-r--r-- | libavcodec/vc1dec.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 63c0949ccd..0362c1a04f 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * - * 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 */ @@ -38,6 +38,7 @@ #include "unary.h" #include "mathops.h" #include "vdpau_internal.h" +#include "libavutil/avassert.h" #undef NDEBUG #include <assert.h> @@ -368,7 +369,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } if (v->field_mode) { // interlaced field picture if (!dir) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { srcY = s->current_picture.f.data[0]; srcU = s->current_picture.f.data[1]; srcV = s->current_picture.f.data[2]; @@ -492,7 +493,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { + if (v->field_mode && v->second_field) { off = s->current_picture_ptr->f.linesize[0]; off_uv = s->current_picture_ptr->f.linesize[1]; } else { @@ -560,7 +561,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) if (!dir) { if (v->field_mode) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) + if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) srcY = s->current_picture.f.data[0]; else srcY = s->last_picture.f.data[0]; @@ -629,7 +630,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; else off = s->linesize * 4 * (n & 2) + (n & 1) * 8; - if (v->field_mode && v->cur_field_type) + if (v->field_mode && v->second_field) off += s->current_picture_ptr->f.linesize[0]; src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); @@ -860,7 +861,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcU += s->current_picture_ptr->f.linesize[1]; srcV += s->current_picture_ptr->f.linesize[2]; } - off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0; + off = v->second_field ? s->current_picture_ptr->f.linesize[1] : 0; } if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) @@ -1137,6 +1138,7 @@ static av_always_inline void get_mvdata_interlaced(VC1Context *v, int *dmv_x, } } else { + av_assert0(index < esc); if (extend_x) offs_tab = offset_table2; else @@ -1788,7 +1790,7 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y, } else if (c_valid) { px = C[0]; py = C[1]; - } + } else px = py = 0; } } else if (total_valid == 1) { px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]); @@ -1921,7 +1923,7 @@ static void vc1_interp_mc(VC1Context *v) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { + if (v->field_mode && v->second_field) { off = s->current_picture_ptr->f.linesize[0]; off_uv = s->current_picture_ptr->f.linesize[1]; } else { @@ -3688,7 +3690,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) int idx_mbmode = 0, mvbp; int stride_y, fieldtx; - mquant = v->pq; /* Loosy initialization */ + mquant = v->pq; /* Lossy initialization */ if (v->skip_is_raw) skipped = get_bits1(gb); @@ -3892,11 +3894,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) int val; /* temp values */ int first_block = 1; int dst_idx, off; - int pred_flag; + int pred_flag = 0; int block_cbp = 0, pat, block_tt = 0; int idx_mbmode = 0; - mquant = v->pq; /* Loosy initialization */ + mquant = v->pq; /* Lossy initialization */ idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); if (idx_mbmode <= 1) { // intra MB @@ -3931,7 +3933,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; + off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: loop filter } @@ -3978,7 +3980,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) + if (v->second_field) off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, @@ -4169,7 +4171,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) int bmvtype = BMV_TYPE_BACKWARD; int idx_mbmode, interpmvp; - mquant = v->pq; /* Loosy initialization */ + mquant = v->pq; /* Lossy initialization */ s->mb_intra = 0; idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2); @@ -4208,7 +4210,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) for (j = 0; j < 64; j++) s->block[i][j] <<= 1; off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; + off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: yet to perform loop filter } @@ -4290,7 +4292,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) + if (v->second_field) off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, @@ -4638,7 +4640,7 @@ static void vc1_decode_p_blocks(VC1Context *v) if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16); s->first_slice_line = 0; } - if (apply_loop_filter) { + if (apply_loop_filter && v->fcm == PROGRESSIVE) { s->mb_x = 0; ff_init_block_index(s); for (; s->mb_x < s->mb_width; s->mb_x++) { @@ -5311,13 +5313,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, AVFrame *pict = data; uint8_t *buf2 = NULL; const uint8_t *buf_start = buf; - int mb_height, n_slices1; + int mb_height, n_slices1=-1; struct { uint8_t *buf; GetBitContext gb; int mby_start; } *slices = NULL, *tmp; + if(s->flags & CODEC_FLAG_LOW_DELAY) + s->low_delay = 1; + /* no supplementary picture */ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { /* special case for last picture */ @@ -5328,7 +5333,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, *data_size = sizeof(AVFrame); } - return 0; + return buf_size; } if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { @@ -5480,15 +5485,18 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, // do parse frame header v->pic_header_flag = 0; if (v->profile < PROFILE_ADVANCED) { - if (ff_vc1_parse_frame_header(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header(v, &s->gb) < 0) { goto err; } } else { - if (ff_vc1_parse_frame_header_adv(v, &s->gb) == -1) { + if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) { goto err; } } + if (avctx->debug & FF_DEBUG_PICT_INFO) + av_log(v->s.avctx, AV_LOG_DEBUG, "pict_type: %c\n", av_get_picture_type_char(s->pict_type)); + if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) && s->pict_type != AV_PICTURE_TYPE_I) { av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n"); @@ -5532,6 +5540,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, goto err; } + v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE); + v->s.current_picture_ptr->f.top_field_first = v->tff; + s->me.qpel_put = s->dsp.put_qpel_pixels_tab; s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab; @@ -5602,6 +5613,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); else s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); + if (s->end_mb_y <= s->start_mb_y) { + av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y); + continue; + } ff_vc1_decode_blocks(v); if (i != n_slices) s->gb = slices[i].gb; @@ -5621,7 +5636,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); // if (get_bits_count(&s->gb) > buf_size * 8) // return -1; - ff_er_frame_end(s); + if(s->error_occurred && s->pict_type == AV_PICTURE_TYPE_B) + goto err; + if(!v->field_mode) + ff_er_frame_end(s); } ff_MPV_frame_end(s); |