Commit 6f91bcd1 authored by Michael Niedermayer's avatar Michael Niedermayer

mpeg4 b-frames :)

create slightly more correct headers & add "ffmpeg" user-data section

Originally committed as revision 328 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e2263827
...@@ -35,7 +35,7 @@ static void h263_encode_motion(MpegEncContext * s, int val); ...@@ -35,7 +35,7 @@ static void h263_encode_motion(MpegEncContext * s, int val);
static void h263p_encode_umotion(MpegEncContext * s, int val); static void h263p_encode_umotion(MpegEncContext * s, int val);
static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block,
int n); int n);
static int h263_decode_motion(MpegEncContext * s, int pred); static int h263_decode_motion(MpegEncContext * s, int pred, int fcode);
static int h263p_decode_umotion(MpegEncContext * s, int pred); static int h263p_decode_umotion(MpegEncContext * s, int pred);
static int h263_decode_block(MpegEncContext * s, DCTELEM * block, static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
int n, int coded); int n, int coded);
...@@ -421,7 +421,6 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block, ...@@ -421,7 +421,6 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block,
return mot_val; return mot_val;
} }
static void h263_encode_motion(MpegEncContext * s, int val) static void h263_encode_motion(MpegEncContext * s, int val)
{ {
int range, l, m, bit_size, sign, code, bits; int range, l, m, bit_size, sign, code, bits;
...@@ -571,11 +570,32 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) ...@@ -571,11 +570,32 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
/***************************************************/ /***************************************************/
static void mpeg4_stuffing(PutBitContext * pbc)
{
int length;
put_bits(pbc, 1, 0);
length= (-get_bit_count(pbc))&7;
put_bits(pbc, length, (1<<length)-1);
}
static void put_string(PutBitContext * pbc, char *s)
{
while(*s){
put_bits(pbc, 8, *s);
s++;
}
put_bits(pbc, 8, 0);
}
/* write mpeg4 VOP header */ /* write mpeg4 VOP header */
void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
{ {
align_put_bits(&s->pb); mpeg4_stuffing(&s->pb);
put_bits(&s->pb, 16, 0);
put_bits(&s->pb, 16, 0x1B2); /* user_data */
put_string(&s->pb, "ffmpeg"); //FIXME append some version ...
mpeg4_stuffing(&s->pb);
put_bits(&s->pb, 16, 0); /* vop header */ put_bits(&s->pb, 16, 0); /* vop header */
put_bits(&s->pb, 16, 0x1B6); /* vop header */ put_bits(&s->pb, 16, 0x1B6); /* vop header */
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
...@@ -839,6 +859,7 @@ static VLC cbpy_vlc; ...@@ -839,6 +859,7 @@ static VLC cbpy_vlc;
static VLC mv_vlc; static VLC mv_vlc;
static VLC dc_lum, dc_chrom; static VLC dc_lum, dc_chrom;
static VLC sprite_trajectory; static VLC sprite_trajectory;
static VLC mb_type_b_vlc;
void init_rl(RLTable *rl) void init_rl(RLTable *rl)
{ {
...@@ -922,6 +943,9 @@ void h263_decode_init_vlc(MpegEncContext *s) ...@@ -922,6 +943,9 @@ void h263_decode_init_vlc(MpegEncContext *s)
init_vlc(&sprite_trajectory, 9, 15, init_vlc(&sprite_trajectory, 9, 15,
&sprite_trajectory_tab[0][1], 4, 2, &sprite_trajectory_tab[0][1], 4, 2,
&sprite_trajectory_tab[0][0], 4, 2); &sprite_trajectory_tab[0][0], 4, 2);
init_vlc(&mb_type_b_vlc, 4, 4,
&mb_type_b_tab[0][1], 2, 1,
&mb_type_b_tab[0][0], 2, 1);
} }
} }
...@@ -997,15 +1021,8 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -997,15 +1021,8 @@ int h263_decode_mb(MpegEncContext *s,
dquant = cbpc & 8; dquant = cbpc & 8;
s->mb_intra = ((cbpc & 4) != 0); s->mb_intra = ((cbpc & 4) != 0);
} else { if (s->mb_intra) goto intra;
cbpc = get_vlc(&s->gb, &intra_MCBPC_vlc);
if (cbpc < 0)
return -1;
dquant = cbpc & 4;
s->mb_intra = 1;
}
if (!s->mb_intra) {
if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
s->mcsel= get_bits1(&s->gb); s->mcsel= get_bits1(&s->gb);
else s->mcsel= 0; else s->mcsel= 0;
...@@ -1026,7 +1043,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1026,7 +1043,7 @@ int h263_decode_mb(MpegEncContext *s,
if (s->umvplus_dec) if (s->umvplus_dec)
mx = h263p_decode_umotion(s, pred_x); mx = h263p_decode_umotion(s, pred_x);
else if(!s->mcsel) else if(!s->mcsel)
mx = h263_decode_motion(s, pred_x); mx = h263_decode_motion(s, pred_x, s->f_code);
else { else {
const int a= s->sprite_warping_accuracy; const int a= s->sprite_warping_accuracy;
// int l = (1 << (s->f_code - 1)) * 32; // int l = (1 << (s->f_code - 1)) * 32;
...@@ -1040,7 +1057,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1040,7 +1057,7 @@ int h263_decode_mb(MpegEncContext *s,
if (s->umvplus_dec) if (s->umvplus_dec)
my = h263p_decode_umotion(s, pred_y); my = h263p_decode_umotion(s, pred_y);
else if(!s->mcsel) else if(!s->mcsel)
my = h263_decode_motion(s, pred_y); my = h263_decode_motion(s, pred_y, s->f_code);
else{ else{
const int a= s->sprite_warping_accuracy; const int a= s->sprite_warping_accuracy;
// int l = (1 << (s->f_code - 1)) * 32; // int l = (1 << (s->f_code - 1)) * 32;
...@@ -1065,14 +1082,14 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1065,14 +1082,14 @@ int h263_decode_mb(MpegEncContext *s,
if (s->umvplus_dec) if (s->umvplus_dec)
mx = h263p_decode_umotion(s, pred_x); mx = h263p_decode_umotion(s, pred_x);
else else
mx = h263_decode_motion(s, pred_x); mx = h263_decode_motion(s, pred_x, s->f_code);
if (mx >= 0xffff) if (mx >= 0xffff)
return -1; return -1;
if (s->umvplus_dec) if (s->umvplus_dec)
my = h263p_decode_umotion(s, pred_y); my = h263p_decode_umotion(s, pred_y);
else else
my = h263_decode_motion(s, pred_y); my = h263_decode_motion(s, pred_y, s->f_code);
if (my >= 0xffff) if (my >= 0xffff)
return -1; return -1;
s->mv[0][i][0] = mx; s->mv[0][i][0] = mx;
...@@ -1083,7 +1100,126 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1083,7 +1100,126 @@ int h263_decode_mb(MpegEncContext *s,
mot_val[1] = my; mot_val[1] = my;
} }
} }
} else { } else if(s->pict_type==B_TYPE) {
int modb1; // first bit of modb
int modb2; // second bit of modb
int mb_type;
int time_pp;
int time_pb;
int xy;
s->mb_intra = 0; //B-frames never contain intra blocks
s->mcsel=0; // ... true gmc blocks
if(s->mb_x==0){
s->last_mv[0][0][0]=
s->last_mv[0][0][1]=
s->last_mv[1][0][0]=
s->last_mv[1][0][1]= 0;
}
/* if we skipped it in the future P Frame than skip it now too */
s->mb_skiped= s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC
if(s->mb_skiped){
/* skip mb */
for(i=0;i<6;i++)
s->block_last_index[i] = -1;
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
s->mv[0][0][0] = 0;
s->mv[0][0][1] = 0;
s->mv[1][0][0] = 0;
s->mv[1][0][1] = 0;
s->last_mv[0][0][0]=
s->last_mv[0][0][1]=
s->last_mv[1][0][0]=
s->last_mv[1][0][1]= 0;
s->mb_skiped = 1;
return 0;
}
modb1= get_bits1(&s->gb);
if(modb1==0){
modb2= get_bits1(&s->gb);
mb_type= get_vlc(&s->gb, &mb_type_b_vlc);
if(modb2==0) cbp= get_bits(&s->gb, 6);
else cbp=0;
if (mb_type && cbp) {
if(get_bits1(&s->gb)){
s->qscale +=get_bits1(&s->gb)*4 - 2;
if (s->qscale < 1)
s->qscale = 1;
else if (s->qscale > 31)
s->qscale = 31;
}
}
}else{
mb_type=4; //like 0 but no vectors coded
cbp=0;
}
s->mv_type = MV_TYPE_16X16; // we'll switch to 8x8 only if the last P frame had 8x8 for this MB and mb_type=0 here
mx=my=0; //for case 4, we could put this to the mb_type=4 but than gcc compains about uninitalized mx/my
switch(mb_type)
{
case 0:
mx = h263_decode_motion(s, 0, 1);
my = h263_decode_motion(s, 0, 1);
case 4:
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
xy= (2*s->mb_width + 2)*(2*s->mb_y + 1) + 2*s->mb_x + 1;
time_pp= s->last_non_b_time[0] - s->last_non_b_time[1];
time_pb= s->time - s->last_non_b_time[1];
//if(time_pp>3000 )printf("%d %d ", time_pp, time_pb);
//FIXME 4MV
//FIXME avoid divides
s->mv[0][0][0] = s->motion_val[xy][0]*time_pb/time_pp + mx;
s->mv[0][0][1] = s->motion_val[xy][1]*time_pb/time_pp + my;
s->mv[1][0][0] = mx ? s->mv[0][0][0] - s->motion_val[xy][0]
: s->motion_val[xy][0]*(time_pb - time_pp)/time_pp + mx;
s->mv[1][0][1] = my ? s->mv[0][0][1] - s->motion_val[xy][1]
: s->motion_val[xy][1]*(time_pb - time_pp)/time_pp + my;
/* s->mv[0][0][0] =
s->mv[0][0][1] =
s->mv[1][0][0] =
s->mv[1][0][1] = 1000;*/
break;
case 1:
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]= s->mv[0][0][0] = mx;
s->last_mv[0][0][1]= s->mv[0][0][1] = my;
mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
s->last_mv[1][0][1]= s->mv[1][0][1] = my;
break;
case 2:
s->mv_dir = MV_DIR_BACKWARD;
mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
s->last_mv[1][0][1]= s->mv[1][0][1] = my;
break;
case 3:
s->mv_dir = MV_DIR_FORWARD;
mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]= s->mv[0][0][0] = mx;
s->last_mv[0][0][1]= s->mv[0][0][1] = my;
break;
default: return -1;
}
} else { /* I-Frame */
cbpc = get_vlc(&s->gb, &intra_MCBPC_vlc);
if (cbpc < 0)
return -1;
dquant = cbpc & 4;
s->mb_intra = 1;
intra:
s->ac_pred = 0; s->ac_pred = 0;
if (s->h263_pred || s->h263_aic) { if (s->h263_pred || s->h263_aic) {
s->ac_pred = get_bits1(&s->gb); s->ac_pred = get_bits1(&s->gb);
...@@ -1120,7 +1256,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1120,7 +1256,7 @@ int h263_decode_mb(MpegEncContext *s,
return 0; return 0;
} }
static int h263_decode_motion(MpegEncContext * s, int pred) static int h263_decode_motion(MpegEncContext * s, int pred, int f_code)
{ {
int code, val, sign, shift, l, m; int code, val, sign, shift, l, m;
...@@ -1131,7 +1267,7 @@ static int h263_decode_motion(MpegEncContext * s, int pred) ...@@ -1131,7 +1267,7 @@ static int h263_decode_motion(MpegEncContext * s, int pred)
if (code == 0) if (code == 0)
return pred; return pred;
sign = get_bits1(&s->gb); sign = get_bits1(&s->gb);
shift = s->f_code - 1; shift = f_code - 1;
val = (code - 1) << shift; val = (code - 1) << shift;
if (shift > 0) if (shift > 0)
val |= get_bits(&s->gb, shift); val |= get_bits(&s->gb, shift);
...@@ -1142,7 +1278,7 @@ static int h263_decode_motion(MpegEncContext * s, int pred) ...@@ -1142,7 +1278,7 @@ static int h263_decode_motion(MpegEncContext * s, int pred)
/* modulo decoding */ /* modulo decoding */
if (!s->h263_long_vectors) { if (!s->h263_long_vectors) {
l = (1 << (s->f_code - 1)) * 32; l = (1 << (f_code - 1)) * 32;
m = 2 * l; m = 2 * l;
if (val < -l) { if (val < -l) {
val += m; val += m;
...@@ -1577,21 +1713,21 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s) ...@@ -1577,21 +1713,21 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s)
h2= 1<<beta; h2= 1<<beta;
// Note, the 4th point isnt used for GMC // Note, the 4th point isnt used for GMC
/* if(s->divx_version==500 && s->divx_build==413){
sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]); sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0];
sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]); sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1];
sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]); sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0];
sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]); sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1];
sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]); sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0];
sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]); sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1];
*/ } else {
//FIXME DIVX5 vs. mpeg4 ? sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]);
sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0]; sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]);
sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1]; sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]);
sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0]; sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]);
sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1]; sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]);
sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0]; sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]);
sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1]; }
/* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]); /* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */ sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
...@@ -1715,7 +1851,6 @@ printf("%d %d\n", s->sprite_delta[1][1][1], a<<s->sprite_shift[1][1]);*/ ...@@ -1715,7 +1851,6 @@ printf("%d %d\n", s->sprite_delta[1][1][1], a<<s->sprite_shift[1][1]);*/
else else
s->real_sprite_warping_points= s->num_sprite_warping_points; s->real_sprite_warping_points= s->num_sprite_warping_points;
//FIXME convert stuff if accurace != 3
} }
/* decode mpeg4 VOP header */ /* decode mpeg4 VOP header */
...@@ -1741,7 +1876,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -1741,7 +1876,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
//printf("startcode %X %d\n", startcode, get_bits_count(&s->gb)); //printf("startcode %X %d\n", startcode, get_bits_count(&s->gb));
if (startcode == 0x120) { // Video Object Layer if (startcode == 0x120) { // Video Object Layer
int time_increment_resolution, width, height, vo_ver_id; int width, height, vo_ver_id;
/* vol header */ /* vol header */
skip_bits(&s->gb, 1); /* random access */ skip_bits(&s->gb, 1); /* random access */
...@@ -1770,8 +1905,8 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -1770,8 +1905,8 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
time_increment_resolution = get_bits(&s->gb, 16); s->time_increment_resolution = get_bits(&s->gb, 16);
s->time_increment_bits = av_log2(time_increment_resolution - 1) + 1; s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
if (s->time_increment_bits < 1) if (s->time_increment_bits < 1)
s->time_increment_bits = 1; s->time_increment_bits = 1;
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
...@@ -1899,24 +2034,27 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -1899,24 +2034,27 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
s->pict_type = get_bits(&s->gb, 2) + 1; /* pict type: I = 0 , P = 1 */ s->pict_type = get_bits(&s->gb, 2) + 1; /* pict type: I = 0 , P = 1 */
if(s->pict_type == B_TYPE)
{
printf("B-VOP\n");
return -1;
}
/* XXX: parse time base */ time_incr=0;
time_incr = 0;
while (get_bits1(&s->gb) != 0) while (get_bits1(&s->gb) != 0)
time_incr++; time_incr++;
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
skip_bits(&s->gb, s->time_increment_bits); s->time_increment= get_bits(&s->gb, s->time_increment_bits);
if(s->pict_type!=B_TYPE){
s->time_base+= time_incr;
s->last_non_b_time[1]= s->last_non_b_time[0];
s->last_non_b_time[0]= s->time_base*s->time_increment_resolution + s->time_increment;
}else{
s->time= (s->last_non_b_time[1]/s->time_increment_resolution + time_incr)*s->time_increment_resolution;
s->time+= s->time_increment;
}
skip_bits1(&s->gb); /* marker */ skip_bits1(&s->gb); /* marker */
/* vop coded */ /* vop coded */
if (get_bits1(&s->gb) != 1) if (get_bits1(&s->gb) != 1)
goto redo; goto redo;
//printf("time %d %d %d || %d %d %d\n", s->time_increment_bits, s->time_increment, s->time_base,
//s->time, s->last_non_b_time[0], s->last_non_b_time[1]);
if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE
|| (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) {
/* rounding type for motion estimation */ /* rounding type for motion estimation */
...@@ -1967,9 +2105,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -1967,9 +2105,11 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
if (s->pict_type != I_TYPE) { if (s->pict_type != I_TYPE) {
s->f_code = get_bits(&s->gb, 3); /* fcode_for */ s->f_code = get_bits(&s->gb, 3); /* fcode_for */
//printf("f-code %d\n", s->f_code);
} }
if (s->pict_type == B_TYPE) { if (s->pict_type == B_TYPE) {
s->b_code = get_bits(&s->gb, 3); s->b_code = get_bits(&s->gb, 3);
//printf("b-code %d\n", s->b_code);
} }
//printf("quant:%d fcode:%d\n", s->qscale, s->f_code); //printf("quant:%d fcode:%d\n", s->qscale, s->f_code);
if(!s->scalability){ if(!s->scalability){
......
...@@ -45,6 +45,7 @@ static int h263_decode_init(AVCodecContext *avctx) ...@@ -45,6 +45,7 @@ static int h263_decode_init(AVCodecContext *avctx)
case CODEC_ID_MPEG4: case CODEC_ID_MPEG4:
s->time_increment_bits = 4; /* default value for broken headers */ s->time_increment_bits = 4; /* default value for broken headers */
s->h263_pred = 1; s->h263_pred = 1;
s->has_b_frames = 1;
break; break;
case CODEC_ID_MSMPEG4: case CODEC_ID_MSMPEG4:
s->h263_msmpeg4 = 1; s->h263_msmpeg4 = 1;
...@@ -219,9 +220,15 @@ static int h263_decode_frame(AVCodecContext *avctx, ...@@ -219,9 +220,15 @@ static int h263_decode_frame(AVCodecContext *avctx,
MPV_frame_end(s); MPV_frame_end(s);
pict->data[0] = s->current_picture[0]; if(s->pict_type==B_TYPE){
pict->data[1] = s->current_picture[1]; pict->data[0] = s->current_picture[0];
pict->data[2] = s->current_picture[2]; pict->data[1] = s->current_picture[1];
pict->data[2] = s->current_picture[2];
} else {
pict->data[0] = s->last_picture[0];
pict->data[1] = s->last_picture[1];
pict->data[2] = s->last_picture[2];
}
pict->linesize[0] = s->linesize; pict->linesize[0] = s->linesize;
pict->linesize[1] = s->linesize / 2; pict->linesize[1] = s->linesize / 2;
pict->linesize[2] = s->linesize / 2; pict->linesize[2] = s->linesize / 2;
......
...@@ -99,3 +99,7 @@ static const UINT16 sprite_trajectory_tab[15][2] = { ...@@ -99,3 +99,7 @@ static const UINT16 sprite_trajectory_tab[15][2] = {
{0x0E, 4}, {0x1E, 5}, {0x3E, 6}, {0x7E, 7}, {0xFE, 8}, {0x0E, 4}, {0x1E, 5}, {0x3E, 6}, {0x7E, 7}, {0xFE, 8},
{0x1FE, 9},{0x3FE, 10},{0x7FE, 11},{0xFFE, 12}, {0x1FE, 9},{0x3FE, 10},{0x7FE, 11},{0xFFE, 12},
}; };
static const UINT8 mb_type_b_tab[4][2] = {
{1, 1}, {1, 2}, {1, 3}, {1, 4},
};
...@@ -430,6 +430,7 @@ void MPV_frame_start(MpegEncContext *s) ...@@ -430,6 +430,7 @@ void MPV_frame_start(MpegEncContext *s)
s->current_picture[i] = s->aux_picture[i]; s->current_picture[i] = s->aux_picture[i];
} }
} else { } else {
s->last_non_b_pict_type= s->pict_type;
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
/* swap next and last */ /* swap next and last */
tmp = s->last_picture[i]; tmp = s->last_picture[i];
...@@ -745,7 +746,7 @@ static inline void MPV_motion(MpegEncContext *s, ...@@ -745,7 +746,7 @@ static inline void MPV_motion(MpegEncContext *s,
ref_picture, 0, ref_picture, 0,
16); 16);
#endif #endif
}else if(s->quarter_sample){ }else if(s->quarter_sample && dir==0){ //FIXME
qpel_motion(s, dest_y, dest_cb, dest_cr, 0, qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
ref_picture, 0, ref_picture, 0,
0, pix_op, qpix_op, 0, pix_op, qpix_op,
...@@ -930,8 +931,9 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) ...@@ -930,8 +931,9 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
else if (s->h263_pred || s->h263_aic) else if (s->h263_pred || s->h263_aic)
s->mbintra_table[mb_x + mb_y*s->mb_width]=1; s->mbintra_table[mb_x + mb_y*s->mb_width]=1;
/* update motion predictor */ /* update motion predictor, not for B-frames as they need the motion_val from the last P/S-Frame */
if (s->out_format == FMT_H263) { if (s->out_format == FMT_H263) {
if(s->pict_type!=B_TYPE){
int xy, wrap, motion_x, motion_y; int xy, wrap, motion_x, motion_y;
wrap = 2 * s->mb_width + 2; wrap = 2 * s->mb_width + 2;
...@@ -954,6 +956,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) ...@@ -954,6 +956,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
s->motion_val[xy + 1 + wrap][0] = motion_x; s->motion_val[xy + 1 + wrap][0] = motion_x;
s->motion_val[xy + 1 + wrap][1] = motion_y; s->motion_val[xy + 1 + wrap][1] = motion_y;
} }
}
} }
if (!s->intra_only) { if (!s->intra_only) {
......
...@@ -84,19 +84,21 @@ typedef struct MpegEncContext { ...@@ -84,19 +84,21 @@ typedef struct MpegEncContext {
int qscale; int qscale;
int pict_type; int pict_type;
int last_non_b_pict_type; /* used for mpeg4 gmc b-frames */
int frame_rate_index; int frame_rate_index;
/* motion compensation */ /* motion compensation */
int unrestricted_mv; int unrestricted_mv;
int h263_long_vectors; /* use horrible h263v1 long vector mode */ int h263_long_vectors; /* use horrible h263v1 long vector mode */
int f_code; /* resolution */ int f_code; /* resolution */
int b_code; /* resolution for B Frames*/ int b_code; /* backward resolution for B Frames (mpeg4) */
INT16 *mv_table[2]; /* MV table */ INT16 *mv_table[2]; /* MV table (1MV per MB)*/
INT16 (*motion_val)[2]; /* used for MV prediction */ INT16 (*motion_val)[2]; /* used for MV prediction (4MV per MB)*/
int full_search; int full_search;
int mv_dir; int mv_dir;
#define MV_DIR_BACKWARD 1 #define MV_DIR_BACKWARD 1
#define MV_DIR_FORWARD 2 #define MV_DIR_FORWARD 2
#define MV_DIRECT 4 // bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4)
int mv_type; int mv_type;
#define MV_TYPE_16X16 0 /* 1 vector for the whole mb */ #define MV_TYPE_16X16 0 /* 1 vector for the whole mb */
#define MV_TYPE_8X8 1 /* 4 vectors (h263) */ #define MV_TYPE_8X8 1 /* 4 vectors (h263) */
...@@ -156,7 +158,12 @@ typedef struct MpegEncContext { ...@@ -156,7 +158,12 @@ typedef struct MpegEncContext {
int h263_aic_dir; /* AIC direction: 0 = left, 1 = top */ int h263_aic_dir; /* AIC direction: 0 = left, 1 = top */
/* mpeg4 specific */ /* mpeg4 specific */
int time_increment_resolution;
int time_increment_bits; int time_increment_bits;
int time_increment;
int time_base;
int time;
int last_non_b_time[2];
int shape; int shape;
int vol_sprite_usage; int vol_sprite_usage;
int sprite_width; int sprite_width;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment