/*
* VC-1 and WMV3 decoder
- * Copyright (c) 2006 Konstantin Shishkov
+ * Copyright (c) 2006-2007 Konstantin Shishkov
* Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
*
* This file is part of FFmpeg.
uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- src_x = clip( src_x, -16, s->mb_width * 16);
- src_y = clip( src_y, -16, s->mb_height * 16);
- uvsrc_x = clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = clip(uvsrc_y, -8, s->mb_height * 8);
+ if(v->profile != PROFILE_ADVANCED){
+ src_x = av_clip( src_x, -16, s->mb_width * 16);
+ src_y = av_clip( src_y, -16, s->mb_height * 16);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ }else{
+ src_x = av_clip( src_x, -17, s->avctx->coded_width);
+ src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
srcY += src_y * s->linesize + src_x;
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2);
src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2);
- src_x = clip( src_x, -16, s->mb_width * 16);
- src_y = clip( src_y, -16, s->mb_height * 16);
+ if(v->profile != PROFILE_ADVANCED){
+ src_x = av_clip( src_x, -16, s->mb_width * 16);
+ src_y = av_clip( src_y, -16, s->mb_height * 16);
+ }else{
+ src_x = av_clip( src_x, -17, s->avctx->coded_width);
+ src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ }
srcY += src_y * s->linesize + src_x;
for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;}
tx = (mvx[t1] + mvx[t2]) / 2;
ty = (mvy[t1] + mvy[t2]) / 2;
- } else
+ } else {
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
return; //no need to do MC for inter blocks
+ }
s->current_picture.motion_val[1][s->block_index[0]][0] = tx;
s->current_picture.motion_val[1][s->block_index[0]][1] = ty;
uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- uvsrc_x = clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = clip(uvsrc_y, -8, s->mb_height * 8);
+ if(v->profile != PROFILE_ADVANCED){
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ }else{
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
+
srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
v->profile = get_bits(gb, 2);
- if (v->profile == 2)
+ if (v->profile == PROFILE_COMPLEX)
{
- av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden (and WMV3 Complex Profile is unsupported)\n");
- return -1;
+ av_log(avctx, AV_LOG_ERROR, "WMV3 Complex Profile is not fully supported\n");
}
if (v->profile == PROFILE_ADVANCED)
"Old WMV3 version detected, only I-frames will be decoded\n");
//return -1;
}
+ //TODO: figure out what they mean (always 0x402F)
+ if(!v->res_fasttx) skip_bits(gb, 16);
av_log(avctx, AV_LOG_DEBUG,
"Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n"
v->s.avctx->height = v->s.avctx->coded_height;
v->broadcast = get_bits1(gb);
v->interlace = get_bits1(gb);
- if(v->interlace){
- av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced mode not supported (yet)\n");
- return -1;
- }
v->tfcntrflag = get_bits1(gb);
v->finterpflag = get_bits1(gb);
get_bits1(gb); // reserved
+ v->s.h_edge_pos = v->s.avctx->coded_width;
+ v->s.v_edge_pos = v->s.avctx->coded_height;
+
av_log(v->s.avctx, AV_LOG_DEBUG,
"Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
"LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
return -1;
}
+ v->s.max_b_frames = v->s.avctx->max_b_frames = 7;
if(get_bits1(gb)) { //Display Info - decoding is not affected by it
int w, h, ar = 0;
av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
{
VC1Context *v = avctx->priv_data;
- int i, blink, refdist;
+ int i, blink, clentry, refdist;
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
blink = get_bits1(gb); // broken link
- avctx->max_b_frames = 1 - get_bits1(gb); // 'closed entry' also signalize possible B-frames
+ clentry = get_bits1(gb); // closed entry
v->panscanflag = get_bits1(gb);
refdist = get_bits1(gb); // refdist flag
v->s.loop_filter = get_bits1(gb);
"BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
"RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
"DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
- blink, 1 - avctx->max_b_frames, v->panscanflag, refdist, v->s.loop_filter,
+ blink, clentry, v->panscanflag, refdist, v->s.loop_filter,
v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
return 0;
else
if (v->multires && v->s.pict_type != B_TYPE) v->respic = get_bits(gb, 2);
+ if(v->res_x8 && (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)){
+ if(get_bits1(gb))return -1;
+ }
//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
// (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
shift = v->lumshift << 6;
}
for(i = 0; i < 256; i++) {
- v->luty[i] = clip_uint8((scale * i + shift + 32) >> 6);
- v->lutuv[i] = clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
+ v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
+ v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
}
}
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->p_frame_skipped = 0;
- if(v->interlace)
+ if(v->interlace){
v->fcm = decode012(gb);
+ if(v->fcm) return -1; // interlaced frames/fields are not implemented
+ }
switch(get_prefix(gb, 0, 4)) {
case 0:
v->s.pict_type = P_TYPE;
if(v->tfcntrflag)
get_bits(gb, 8);
if(v->broadcast) {
- if(!v->interlace || v->panscanflag) {
+ if(!v->interlace || v->psf) {
v->rptfrm = get_bits(gb, 2);
} else {
v->tff = get_bits1(gb);
if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
v->pquantizer = get_bits(gb, 1);
+ if(v->s.pict_type == I_TYPE || v->s.pict_type == P_TYPE) v->use_ic = 0;
+
switch(v->s.pict_type) {
case I_TYPE:
case BI_TYPE:
shift = v->lumshift << 6;
}
for(i = 0; i < 256; i++) {
- v->luty[i] = clip_uint8((scale * i + shift + 32) >> 6);
- v->lutuv[i] = clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
+ v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6);
+ v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
}
+ v->use_ic = 1;
}
if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
v->s.quarter_sample = 0;
if(s->mb_intra){
s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
+ s->current_picture.motion_val[1][xy][0] = 0;
+ s->current_picture.motion_val[1][xy][1] = 0;
if(mv1) { /* duplicate motion data for 1-MV block */
s->current_picture.motion_val[0][xy + 1][0] = 0;
s->current_picture.motion_val[0][xy + 1][1] = 0;
s->current_picture.motion_val[0][xy + wrap][1] = 0;
s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
+ s->current_picture.motion_val[1][xy + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + 1][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap][1] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
+ s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
}
return;
}
uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
- src_x = clip( src_x, -16, s->mb_width * 16);
- src_y = clip( src_y, -16, s->mb_height * 16);
- uvsrc_x = clip(uvsrc_x, -8, s->mb_width * 8);
- uvsrc_y = clip(uvsrc_y, -8, s->mb_height * 8);
+ if(v->profile != PROFILE_ADVANCED){
+ src_x = av_clip( src_x, -16, s->mb_width * 16);
+ src_y = av_clip( src_y, -16, s->mb_height * 16);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8);
+ }else{
+ src_x = av_clip( src_x, -17, s->avctx->coded_width);
+ src_y = av_clip( src_y, -18, s->avctx->coded_height + 1);
+ uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1);
+ uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
+ }
srcY += src_y * s->linesize + src_x;
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
B = s->current_picture.motion_val[0][xy - wrap*2 + off];
+ if(!s->mb_x) C[0] = C[1] = 0;
if(!s->first_slice_line) { // predictor A is not out of bounds
if(s->mb_width == 1) {
px = A[0];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
B = s->current_picture.motion_val[1][xy - wrap*2 + off];
+ if(!s->mb_x) C[0] = C[1] = 0;
if(!s->first_slice_line) { // predictor A is not out of bounds
if(s->mb_width == 1) {
px = A[0];
q1 = s->current_picture.qscale_table[mb_pos];
if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if(n && n<4) q2 = q1;
+ if(dc_pred_dir && n==1) q2 = q1;
+ if(!dc_pred_dir && n==2) q2 = q1;
+ if(n==3) q2 = q1;
if(coded) {
int last = 0, skip, value;
q1 = s->current_picture.qscale_table[mb_pos];
if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
- if(n && n<4) q2 = q1;
+ if(dc_pred_dir && n==1) q2 = q1;
+ if(!dc_pred_dir && n==2) q2 = q1;
+ if(n==3) q2 = q1;
if(coded) {
int last = 0, skip, value;
s->dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
for(j = 0; j < 64; j++) s->block[i][j] += 128;
+ if(!v->res_fasttx && v->res_x8) for(j = 0; j < 64; j++) s->block[i][j] += 16;
s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
if(v->pq >= 9 && v->overlap) {
if(v->c_avail)
s->dsp.vc1_inv_trans_8x8(s->block[i]);
if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;
for(j = 0; j < 64; j++) s->block[i][j] += 128;
+ if(!v->res_fasttx && v->res_x8) for(j = 0; j < 64; j++) s->block[i][j] += 16;
s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
if(v->pq >= 9 && v->overlap) {
if(v->c_avail)
vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
s->dsp.vc1_inv_trans_8x8(s->block[k]);
+ if(!v->res_fasttx && !v->res_x8) for(j = 0; j < 64; j++) s->block[k][j] -= 16;
if(v->pq >= 9 && v->overlap) {
for(j = 0; j < 64; j++) s->block[k][j] += 128;
}
return next;
}
-int vc1_split(AVCodecContext *avctx,
+static int vc1_split(AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
int i;