summaryrefslogtreecommitdiffstats
path: root/libavcodec/vc1dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/vc1dec.c')
-rw-r--r--libavcodec/vc1dec.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 6b2662e..3f62201 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,
@@ -4641,7 +4643,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++) {
@@ -5314,13 +5316,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 */
@@ -5331,7 +5336,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) {
@@ -5483,15 +5488,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");
@@ -5535,6 +5543,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;
@@ -5606,6 +5617,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;
@@ -5625,7 +5640,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);
OpenPOWER on IntegriCloud