int dmb_is_raw; ///< direct mb plane is raw
int skip_is_raw; ///< skip mb plane is not coded
uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation
+ int use_ic; ///< use intensity compensation in B-frames
int rnd; ///< rounding control
/** Frame decoding info for S/M profiles only */
av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
get_bits1(gb); // broken link
- get_bits1(gb); // closed entry
+ avctx->max_b_frames = 1 - get_bits1(gb); // 'closed entry' also signalize possible B-frames
v->panscanflag = get_bits1(gb);
get_bits1(gb); // refdist flag
v->s.loop_filter = get_bits1(gb);
//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);
+ if(v->s.pict_type == I_TYPE || v->s.pict_type == P_TYPE) v->use_ic = 0;
+
switch(v->s.pict_type) {
case P_TYPE:
if (v->pq < 5) v->tt_index = 0;
v->mv_mode2 = mv_pmode_table2[lowquant][get_prefix(gb, 1, 3)];
v->lumscale = get_bits(gb, 6);
v->lumshift = get_bits(gb, 6);
+ v->use_ic = 1;
/* fill lookup tables for intensity compensation */
if(!v->lumscale) {
scale = -64;
break;
case 3:
v->s.pict_type = BI_TYPE;
- return -1;
-// break;
+ break;
case 4:
v->s.pict_type = P_TYPE; // skipped pic
v->p_frame_skipped = 1;
switch(v->s.pict_type) {
case I_TYPE:
+ case BI_TYPE:
status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v);
if (status < 0) return -1;
av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: "
vop_dquant_decoding(v);
}
+ v->bi_type = 0;
+ if(v->s.pict_type == BI_TYPE) {
+ v->s.pict_type = B_TYPE;
+ v->bi_type = 1;
+ }
return 0;
}
|| (unsigned)src_y > s->v_edge_pos - (my&3) - 16){
uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize;
- ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17, 17,
+ srcY -= s->mspel * (1 + s->linesize);
+ ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2,
src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos);
srcY = s->edge_emu_buffer;
ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1,
uint8_t *src, *src2;
src = srcY;
- for(j = 0; j < 17; j++) {
- for(i = 0; i < 17; i++) src[i] = ((src[i] - 128) >> 1) + 128;
+ for(j = 0; j < 17 + s->mspel*2; j++) {
+ for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128;
src += s->linesize;
}
src = srcU; src2 = srcV;
src2 += s->uvlinesize;
}
}
+ srcY += s->mspel * (1 + s->linesize);
}
if(v->fastuvmc) {
if(s->flags & CODEC_FLAG_GRAY) return;
/* Chroma MC always uses qpel blilinear */
uvdxy = ((uvmy & 3) << 2) | (uvmx & 3);
- dsp->avg_qpel_pixels_tab[1][uvdxy](s->dest[1], srcU, s->uvlinesize);
- dsp->avg_qpel_pixels_tab[1][uvdxy](s->dest[2], srcV, s->uvlinesize);
+ uvmx = (uvmx&3)<<1;
+ uvmy = (uvmy&3)<<1;
+ dsp->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+ dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
}
static always_inline int scale_mv(int value, int bfrac, int inv, int qs)
*/
static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode)
{
+ int t;
+
+ if(v->use_ic) {
+ v->mv_mode2 = v->mv_mode;
+ v->mv_mode = MV_PMODE_INTENSITY_COMP;
+ }
if(direct) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
+ if(v->use_ic) v->mv_mode = v->mv_mode2;
return;
}
if(mode == BMV_TYPE_INTERPOLATED) {
vc1_mc_1mv(v, 0);
vc1_interp_mc(v);
+ if(v->use_ic) v->mv_mode = v->mv_mode2;
return;
}
- vc1_mc_1mv(v, (mode == BMV_TYPE_FORWARD));
+ if(v->use_ic && (mode == BMV_TYPE_BACKWARD)) v->mv_mode = v->mv_mode2;
+ vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
+ if(v->use_ic) v->mv_mode = v->mv_mode2;
}
static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mvtype)
s->current_picture.motion_val[1][xy][1] = 0;
return;
}
- s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
- s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
- s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
- s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+ s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+ s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+ s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
if(direct) {
s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
return;
}
- if((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ if((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
C = s->current_picture.motion_val[0][xy - 2];
A = s->current_picture.motion_val[0][xy - wrap*2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x;
s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
}
- if((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
+ if((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
C = s->current_picture.motion_val[1][xy - 2];
A = s->current_picture.motion_val[1][xy - wrap*2];
off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
break;
case 2:
bmvtype = BMV_TYPE_INTERPOLATED;
- dmv_x[1] = dmv_y[1] = 0;
+ dmv_x[0] = dmv_y[0] = 0;
}
}
}
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
} else {
if(bmvtype == BMV_TYPE_INTERPOLATED) {
- GET_MVDATA(dmv_x[1], dmv_y[1]);
+ GET_MVDATA(dmv_x[0], dmv_y[0]);
if(!mb_has_coeffs) {
/* interpolated skipped block */
vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
mb_pos = s->mb_x + s->mb_y * s->mb_width;
s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
s->current_picture.qscale_table[mb_pos] = v->pq;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
// do actual MB decoding and displaying
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
s->dsp.clear_blocks(s->block[0]);
mb_pos = s->mb_x + s->mb_y * s->mb_stride;
s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+ s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+ s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
// do actual MB decoding and displaying
cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
return -1;
}
avctx->has_b_frames= !!(avctx->max_b_frames);
+ s->low_delay = !avctx->has_b_frames;
s->mb_width = (avctx->coded_width+15)>>4;
s->mb_height = (avctx->coded_height+15)>>4;
s->current_picture_ptr= &s->picture[i];
}
- avctx->has_b_frames= !s->low_delay;
-
//for advanced profile we need to unescape buffer
if (avctx->codec_id == CODEC_ID_VC1) {
int i, buf_size2;
// do parse frame header
if(v->profile < PROFILE_ADVANCED) {
if(vc1_parse_frame_header(v, &s->gb) == -1) {
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;
}
} else {
if(vc1_parse_frame_header_adv(v, &s->gb) == -1) {
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;
}
}
if(s->pict_type != I_TYPE && !v->res_rtm_flag){
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;
}
/* skip B-frames if we don't have reference frames */
if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)){
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;//buf_size;
}
/* skip b frames if we are in a hurry */
if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)
|| (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)
|| avctx->skip_frame >= AVDISCARD_ALL) {
- if(buf2)av_free(buf2);
+ av_free(buf2);
return buf_size;
}
/* skip everything if we are in a hurry>=5 */
if(avctx->hurry_up>=5) {
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;//buf_size;
}
}
if(MPV_frame_start(s, avctx) < 0) {
- if(buf2)av_free(buf2);
+ av_free(buf2);
return -1;
}
/* we substract 1 because it is added on utils.c */
avctx->frame_number = s->picture_number - 1;
- if(buf2)av_free(buf2);
+ av_free(buf2);
return buf_size;
}