Commit bd28dde2 authored by michaelni's avatar michaelni

much better ME for b frames (a bit slow though)

fixed MC rounding for b frames
fixed hq mode with b-frames


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@406 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 2ff6388d
...@@ -881,6 +881,16 @@ static inline int mid_pred(int a, int b, int c) ...@@ -881,6 +881,16 @@ static inline int mid_pred(int a, int b, int c)
return a + b + c - vmin - vmax; return a + b + c - vmin - vmax;
} }
static inline int clip(int a, int amin, int amax)
{
if (a < amin)
return amin;
else if (a > amax)
return amax;
else
return a;
}
/* memory */ /* memory */
void *av_mallocz(int size); void *av_mallocz(int size);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* ac prediction encoding by Michael Niedermayer <michaelni@gmx.at> * ac prediction encoding & b-frame support by Michael Niedermayer <michaelni@gmx.at>
*/ */
#include "common.h" #include "common.h"
#include "dsputil.h" #include "dsputil.h"
...@@ -282,7 +282,7 @@ void mpeg4_encode_mb(MpegEncContext * s, ...@@ -282,7 +282,7 @@ void mpeg4_encode_mb(MpegEncContext * s,
s->mv[0][0][1]= s->mv[0][0][1]=
s->mv[1][0][0]= s->mv[1][0][0]=
s->mv[1][0][1]= 0; s->mv[1][0][1]= 0;
// s->mv_dir= MV_DIR_FORWARD; //doesnt matter s->mv_dir= MV_DIR_FORWARD; //doesnt matter
return; return;
} }
...@@ -334,7 +334,8 @@ void mpeg4_encode_mb(MpegEncContext * s, ...@@ -334,7 +334,8 @@ void mpeg4_encode_mb(MpegEncContext * s,
s->last_mv[0][0][0]= motion_x; s->last_mv[0][0][0]= motion_x;
s->last_mv[0][0][1]= motion_y; s->last_mv[0][0][1]= motion_y;
break; break;
default: default:
printf("unknown mb type\n");
return; return;
} }
bits= get_bit_count(&s->pb); bits= get_bit_count(&s->pb);
...@@ -959,6 +960,31 @@ static void put_string(PutBitContext * pbc, char *s) ...@@ -959,6 +960,31 @@ static void put_string(PutBitContext * pbc, char *s)
put_bits(pbc, 8, 0); put_bits(pbc, 8, 0);
} }
/* must be called before writing the header */
void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){
int time_div, time_mod;
if(s->pict_type==I_TYPE){ //we will encode a vol header
s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE);
if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128;
s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
}
s->time= picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
time_div= s->time/s->time_increment_resolution;
time_mod= s->time%s->time_increment_resolution;
if(s->pict_type==B_TYPE){
s->bp_time= s->last_non_b_time - s->time;
}else{
s->last_time_base= s->time_base;
s->time_base= time_div;
s->pp_time= s->time - s->last_non_b_time;
s->last_non_b_time= s->time;
}
}
static void mpeg4_encode_vol_header(MpegEncContext * s) static void mpeg4_encode_vol_header(MpegEncContext * s)
{ {
int vo_ver_id=1; //must be 2 if we want GMC or q-pel int vo_ver_id=1; //must be 2 if we want GMC or q-pel
...@@ -983,11 +1009,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s) ...@@ -983,11 +1009,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */
put_bits(&s->pb, 1, 1); /* marker bit */ put_bits(&s->pb, 1, 1); /* marker bit */
s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE);
if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128;
put_bits(&s->pb, 16, s->time_increment_resolution); put_bits(&s->pb, 16, s->time_increment_resolution);
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;
put_bits(&s->pb, 1, 1); /* marker bit */ put_bits(&s->pb, 1, 1); /* marker bit */
...@@ -1034,9 +1056,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) ...@@ -1034,9 +1056,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
if(s->pict_type==I_TYPE) mpeg4_encode_vol_header(s); if(s->pict_type==I_TYPE) mpeg4_encode_vol_header(s);
s->time= s->picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate;
time_div= s->time/s->time_increment_resolution;
time_mod= s->time%s->time_increment_resolution;
//printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE); //printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE);
if(get_bit_count(&s->pb)!=0) mpeg4_stuffing(&s->pb); if(get_bit_count(&s->pb)!=0) mpeg4_stuffing(&s->pb);
...@@ -1044,15 +1063,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) ...@@ -1044,15 +1063,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
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 */
if(s->pict_type==B_TYPE){ time_div= s->time/s->time_increment_resolution;
s->bp_time= s->last_non_b_time - s->time; time_mod= s->time%s->time_increment_resolution;
}else{
s->last_time_base= s->time_base;
s->time_base= time_div;
s->pp_time= s->time - s->last_non_b_time;
s->last_non_b_time= s->time;
}
time_incr= time_div - s->last_time_base; time_incr= time_div - s->last_time_base;
while(time_incr--) while(time_incr--)
put_bits(&s->pb, 1, 1); put_bits(&s->pb, 1, 1);
...@@ -1770,6 +1782,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1770,6 +1782,7 @@ int h263_decode_mb(MpegEncContext *s,
s->last_mv[0][0][1]= s->last_mv[0][0][1]=
s->last_mv[1][0][0]= s->last_mv[1][0][0]=
s->last_mv[1][0][1]= 0; s->last_mv[1][0][1]= 0;
// printf("\n");
} }
/* if we skipped it in the future P Frame than skip it now too */ /* if we skipped it in the future P Frame than skip it now too */
...@@ -1789,6 +1802,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1789,6 +1802,7 @@ int h263_decode_mb(MpegEncContext *s,
//FIXME is this correct? //FIXME is this correct?
/* s->last_mv[0][0][0]= /* s->last_mv[0][0][0]=
s->last_mv[0][0][1]=0;*/ s->last_mv[0][0][1]=0;*/
// printf("S");
return 0; return 0;
} }
...@@ -1837,6 +1851,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1837,6 +1851,7 @@ int h263_decode_mb(MpegEncContext *s,
s->mv[0][0][1] = s->mv[0][0][1] =
s->mv[1][0][0] = s->mv[1][0][0] =
s->mv[1][0][1] = 1000;*/ s->mv[1][0][1] = 1000;*/
// printf("D");
break; break;
case 1: case 1:
s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
...@@ -1849,6 +1864,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1849,6 +1864,7 @@ int h263_decode_mb(MpegEncContext *s,
my = h263_decode_motion(s, s->last_mv[1][0][1], 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][0]= s->mv[1][0][0] = mx;
s->last_mv[1][0][1]= s->mv[1][0][1] = my; s->last_mv[1][0][1]= s->mv[1][0][1] = my;
// printf("I");
break; break;
case 2: case 2:
s->mv_dir = MV_DIR_BACKWARD; s->mv_dir = MV_DIR_BACKWARD;
...@@ -1856,6 +1872,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1856,6 +1872,7 @@ int h263_decode_mb(MpegEncContext *s,
my = h263_decode_motion(s, s->last_mv[1][0][1], 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][0]= s->mv[1][0][0] = mx;
s->last_mv[1][0][1]= s->mv[1][0][1] = my; s->last_mv[1][0][1]= s->mv[1][0][1] = my;
// printf("B");
break; break;
case 3: case 3:
s->mv_dir = MV_DIR_FORWARD; s->mv_dir = MV_DIR_FORWARD;
...@@ -1863,6 +1880,7 @@ int h263_decode_mb(MpegEncContext *s, ...@@ -1863,6 +1880,7 @@ int h263_decode_mb(MpegEncContext *s,
my = h263_decode_motion(s, s->last_mv[0][0][1], 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][0]= s->mv[0][0][0] = mx;
s->last_mv[0][0][1]= s->mv[0][0][1] = my; s->last_mv[0][0][1]= s->mv[0][0][1] = my;
// printf("F");
break; break;
default: return -1; default: return -1;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -141,7 +141,8 @@ typedef struct MpegEncContext { ...@@ -141,7 +141,8 @@ typedef struct MpegEncContext {
INT16 (*b_direct_forw_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */ INT16 (*b_direct_forw_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */
INT16 (*b_direct_back_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */ INT16 (*b_direct_back_mv_table)[2];/* MV table (1MV per MB) direct mode b-frame encoding */
INT16 (*b_direct_mv_table)[2]; /* MV table (1MV per MB) direct mode b-frame encoding */ INT16 (*b_direct_mv_table)[2]; /* MV table (1MV per MB) direct mode b-frame encoding */
int me_method; /* ME algorithm */ int me_method; /* ME algorithm */
uint8_t *me_scratchpad; /* data area for the me algo, so that the ME doesnt need to malloc/free */
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
...@@ -164,7 +165,8 @@ typedef struct MpegEncContext { ...@@ -164,7 +165,8 @@ typedef struct MpegEncContext {
UINT8 *fcode_tab; /* smallest fcode needed for each MV */ UINT8 *fcode_tab; /* smallest fcode needed for each MV */
int has_b_frames; int has_b_frames;
int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...) */ int no_rounding; /* apply no rounding to motion compensation (MPEG4, msmpeg4, ...)
for b-frames rounding mode is allways 0 */
/* macroblock layer */ /* macroblock layer */
int mb_x, mb_y; int mb_x, mb_y;
...@@ -335,9 +337,7 @@ typedef struct MpegEncContext { ...@@ -335,9 +337,7 @@ typedef struct MpegEncContext {
UINT32 mb_line_avgsize; UINT32 mb_line_avgsize;
DCTELEM (*block)[64]; /* points to one of the following blocks */ DCTELEM (*block)[64]; /* points to one of the following blocks */
DCTELEM intra_block[6][64] __align8; DCTELEM blocks[2][6][64] __align8; // for HQ mode we need to keep the best block
DCTELEM inter_block[6][64] __align8;
DCTELEM inter4v_block[6][64] __align8;
void (*dct_unquantize_mpeg1)(struct MpegEncContext *s, void (*dct_unquantize_mpeg1)(struct MpegEncContext *s,
DCTELEM *block, int n, int qscale); DCTELEM *block, int n, int qscale);
void (*dct_unquantize_mpeg2)(struct MpegEncContext *s, void (*dct_unquantize_mpeg2)(struct MpegEncContext *s,
...@@ -421,6 +421,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block, ...@@ -421,6 +421,7 @@ INT16 *h263_pred_motion(MpegEncContext * s, int block,
int *px, int *py); int *px, int *py);
void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n,
int dir); int dir);
void ff_set_mpeg4_time(MpegEncContext * s, int picture_number);
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_init(MpegEncContext *s); void h263_encode_init(MpegEncContext *s);
......
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