mpeg4 aspect_ratio_info in AVCodecContext (requested by alex)
experimental (& faster) motion estimation squished a dirty uninitialized var bug mpeg1 fcode>1 support Originally committed as revision 349 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
c5b1c10a0e
commit
11ce88346b
@ -81,6 +81,7 @@ typedef struct AVCodecContext {
|
|||||||
/* video only */
|
/* video only */
|
||||||
int frame_rate; /* frames per sec multiplied by FRAME_RATE_BASE */
|
int frame_rate; /* frames per sec multiplied by FRAME_RATE_BASE */
|
||||||
int width, height;
|
int width, height;
|
||||||
|
int aspect_ratio_info;
|
||||||
int gop_size; /* 0 = intra only */
|
int gop_size; /* 0 = intra only */
|
||||||
int pix_fmt; /* pixel format, see PIX_FMT_xxx */
|
int pix_fmt; /* pixel format, see PIX_FMT_xxx */
|
||||||
|
|
||||||
|
@ -781,7 +781,10 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
|
|||||||
put_bits(&s->pb, 1, 1); /* is obj layer id= yes */
|
put_bits(&s->pb, 1, 1); /* is obj layer id= yes */
|
||||||
put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */
|
put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */
|
||||||
put_bits(&s->pb, 3, 1); /* is obj layer priority */
|
put_bits(&s->pb, 3, 1); /* is obj layer priority */
|
||||||
put_bits(&s->pb, 4, 1); /* aspect ratio info= sqare pixel */ //FIXME real aspect
|
if(s->aspect_ratio_info)
|
||||||
|
put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */
|
||||||
|
else
|
||||||
|
put_bits(&s->pb, 4, 1); /* aspect ratio info= sqare pixel */
|
||||||
put_bits(&s->pb, 1, 0); /* vol control parameters= no */
|
put_bits(&s->pb, 1, 0); /* vol control parameters= no */
|
||||||
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 */
|
||||||
@ -2149,6 +2152,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
|
|||||||
skip_bits(&s->gb, 8); //par_width
|
skip_bits(&s->gb, 8); //par_width
|
||||||
skip_bits(&s->gb, 8); // par_height
|
skip_bits(&s->gb, 8); // par_height
|
||||||
}
|
}
|
||||||
|
|
||||||
if(get_bits1(&s->gb)){ /* vol control parameter */
|
if(get_bits1(&s->gb)){ /* vol control parameter */
|
||||||
printf("vol control parameter not supported\n");
|
printf("vol control parameter not supported\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -2388,7 +2392,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
|
|||||||
//printf("b-code %d\n", s->b_code);
|
//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){
|
||||||
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
|
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
|
||||||
skip_bits1(&s->gb); // vop shape coding type
|
skip_bits1(&s->gb); // vop shape coding type
|
||||||
|
@ -123,6 +123,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
|
|||||||
if (!s->context_initialized) {
|
if (!s->context_initialized) {
|
||||||
avctx->width = s->width;
|
avctx->width = s->width;
|
||||||
avctx->height = s->height;
|
avctx->height = s->height;
|
||||||
|
avctx->aspect_ratio_info= s->aspect_ratio_info;
|
||||||
if (MPV_common_init(s) < 0)
|
if (MPV_common_init(s) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if (s->width != avctx->width || s->height != avctx->height) {
|
} else if (s->width != avctx->width || s->height != avctx->height) {
|
||||||
|
@ -335,13 +335,15 @@ static int phods_motion_search(MpegEncContext * s,
|
|||||||
#define Z_THRESHOLD 256
|
#define Z_THRESHOLD 256
|
||||||
|
|
||||||
#define CHECK_MV(x,y)\
|
#define CHECK_MV(x,y)\
|
||||||
|
{\
|
||||||
d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\
|
d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);\
|
||||||
d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
|
d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;\
|
||||||
if(d<dmin){\
|
if(d<dmin){\
|
||||||
best[0]=x;\
|
best[0]=x;\
|
||||||
best[1]=y;\
|
best[1]=y;\
|
||||||
dmin=d;\
|
dmin=d;\
|
||||||
}
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECK_MV_DIR(x,y,new_dir)\
|
#define CHECK_MV_DIR(x,y,new_dir)\
|
||||||
{\
|
{\
|
||||||
@ -355,6 +357,13 @@ static int phods_motion_search(MpegEncContext * s,
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define check(x,y,S,v)\
|
||||||
|
if( (x)<(xmin<<(S)) ) printf("%d %d %d %d xmin" #v, (x), (y), s->mb_x, s->mb_y);\
|
||||||
|
if( (x)>(xmax<<(S)) ) printf("%d %d %d %d xmax" #v, (x), (y), s->mb_x, s->mb_y);\
|
||||||
|
if( (y)<(ymin<<(S)) ) printf("%d %d %d %d ymin" #v, (x), (y), s->mb_x, s->mb_y);\
|
||||||
|
if( (y)>(ymax<<(S)) ) printf("%d %d %d %d ymax" #v, (x), (y), s->mb_x, s->mb_y);\
|
||||||
|
|
||||||
|
|
||||||
static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
|
static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
|
||||||
UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
|
UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
|
||||||
int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
|
int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
|
||||||
@ -379,6 +388,91 @@ static inline int small_diamond_search(MpegEncContext * s, int *best, int dmin,
|
|||||||
return dmin;
|
return dmin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for(;;){
|
||||||
|
int d;
|
||||||
|
const int x= best[0];
|
||||||
|
const int y= best[1];
|
||||||
|
const int last_min=dmin;
|
||||||
|
if(x>xmin) CHECK_MV(x-1, y )
|
||||||
|
if(y>xmin) CHECK_MV(x , y-1)
|
||||||
|
if(x<xmax) CHECK_MV(x+1, y )
|
||||||
|
if(y<xmax) CHECK_MV(x , y+1)
|
||||||
|
if(x>xmin && y>ymin) CHECK_MV(x-1, y-1)
|
||||||
|
if(x>xmin && y<ymax) CHECK_MV(x-1, y+1)
|
||||||
|
if(x<xmax && y>ymin) CHECK_MV(x+1, y-1)
|
||||||
|
if(x<xmax && y<ymax) CHECK_MV(x+1, y+1)
|
||||||
|
if(x-1>xmin) CHECK_MV(x-2, y )
|
||||||
|
if(y-1>xmin) CHECK_MV(x , y-2)
|
||||||
|
if(x+1<xmax) CHECK_MV(x+2, y )
|
||||||
|
if(y+1<xmax) CHECK_MV(x , y+2)
|
||||||
|
if(x-1>xmin && y-1>ymin) CHECK_MV(x-2, y-2)
|
||||||
|
if(x-1>xmin && y+1<ymax) CHECK_MV(x-2, y+2)
|
||||||
|
if(x+1<xmax && y-1>ymin) CHECK_MV(x+2, y-2)
|
||||||
|
if(x+1<xmax && y+1<ymax) CHECK_MV(x+2, y+2)
|
||||||
|
if(dmin==last_min) return dmin;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int snake_search(MpegEncContext * s, int *best, int dmin,
|
||||||
|
UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
|
||||||
|
int pred_x, int pred_y, UINT16 *mv_penalty, int quant,
|
||||||
|
int xmin, int ymin, int xmax, int ymax, int shift)
|
||||||
|
{
|
||||||
|
int dir=0;
|
||||||
|
int c=1;
|
||||||
|
static int x_dir[8]= {1,1,0,-1,-1,-1, 0, 1};
|
||||||
|
static int y_dir[8]= {0,1,1, 1, 0,-1,-1,-1};
|
||||||
|
int fails=0;
|
||||||
|
int last_d[2]={dmin, dmin};
|
||||||
|
|
||||||
|
/*static int good=0;
|
||||||
|
static int bad=0;
|
||||||
|
static int point=0;
|
||||||
|
|
||||||
|
point++;
|
||||||
|
if(256*256*256*64%point==0)
|
||||||
|
{
|
||||||
|
printf("%d %d %d\n", good, bad, point);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
int x= best[0];
|
||||||
|
int y= best[1];
|
||||||
|
int d;
|
||||||
|
x+=x_dir[dir];
|
||||||
|
y+=y_dir[dir];
|
||||||
|
if(x>=xmin && x<=xmax && y>=ymin && y<=ymax){
|
||||||
|
d = pix_abs16x16(new_pic, old_pic + (x) + (y)*pic_stride, pic_stride, 16);
|
||||||
|
d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*quant;
|
||||||
|
}else{
|
||||||
|
d = dmin + 10000; //FIXME smarter boundary handling
|
||||||
|
}
|
||||||
|
if(d<dmin){
|
||||||
|
best[0]=x;
|
||||||
|
best[1]=y;
|
||||||
|
dmin=d;
|
||||||
|
|
||||||
|
if(last_d[1] - last_d[0] > last_d[0] - d) c= -c;
|
||||||
|
dir+=c;
|
||||||
|
|
||||||
|
fails=0;
|
||||||
|
//good++;
|
||||||
|
last_d[1]=last_d[0];
|
||||||
|
last_d[0]=d;
|
||||||
|
}else{
|
||||||
|
//bad++;
|
||||||
|
if(fails){
|
||||||
|
if(fails>=3) return dmin;
|
||||||
|
}else{
|
||||||
|
c= -c;
|
||||||
|
}
|
||||||
|
dir+=c*2;
|
||||||
|
fails++;
|
||||||
|
}
|
||||||
|
dir&=7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int epzs_motion_search(MpegEncContext * s,
|
static int epzs_motion_search(MpegEncContext * s,
|
||||||
@ -397,8 +491,7 @@ static int epzs_motion_search(MpegEncContext * s,
|
|||||||
|
|
||||||
new_pic = s->new_picture[0] + pic_xy;
|
new_pic = s->new_picture[0] + pic_xy;
|
||||||
old_pic = s->last_picture[0] + pic_xy;
|
old_pic = s->last_picture[0] + pic_xy;
|
||||||
//printf("%d %d %d %d\n", xmin, ymin, xmax, ymax);
|
|
||||||
|
|
||||||
dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16);
|
dmin = pix_abs16x16(new_pic, old_pic, pic_stride, 16);
|
||||||
if(dmin<Z_THRESHOLD){
|
if(dmin<Z_THRESHOLD){
|
||||||
*mx_ptr= 0;
|
*mx_ptr= 0;
|
||||||
@ -424,13 +517,18 @@ static int epzs_motion_search(MpegEncContext * s,
|
|||||||
}
|
}
|
||||||
CHECK_MV(P[0][0]>>shift, P[0][1]>>shift)
|
CHECK_MV(P[0][0]>>shift, P[0][1]>>shift)
|
||||||
|
|
||||||
dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride,
|
//check(best[0],best[1],0, b0)
|
||||||
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
|
if(s->full_search==ME_EPZS)
|
||||||
|
dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride,
|
||||||
|
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
|
||||||
|
else
|
||||||
|
dmin= snake_search(s, best, dmin, new_pic, old_pic, pic_stride,
|
||||||
|
pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift);
|
||||||
|
//check(best[0],best[1],0, b1)
|
||||||
*mx_ptr= best[0];
|
*mx_ptr= best[0];
|
||||||
*my_ptr= best[1];
|
*my_ptr= best[1];
|
||||||
|
|
||||||
// printf("%d %d %d \n", best[0], best[1], dmin);
|
// printf("%d %d %d \n", best[0], best[1], dmin);
|
||||||
|
|
||||||
return dmin;
|
return dmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,8 +661,8 @@ int estimate_motion(MpegEncContext * s,
|
|||||||
rel_ymax= ymax - s->mb_y*16;
|
rel_ymax= ymax - s->mb_y*16;
|
||||||
if(s->out_format == FMT_H263){
|
if(s->out_format == FMT_H263){
|
||||||
static const int off[4]= {2, 1, 1, -1};
|
static const int off[4]= {2, 1, 1, -1};
|
||||||
const int mot_stride = s->block_wrap[0];
|
const int mot_stride = s->mb_width*2 + 2;
|
||||||
const int mot_xy = s->block_index[0];
|
const int mot_xy = (s->mb_y*2 + 1)*mot_stride + s->mb_x*2 + 1;
|
||||||
|
|
||||||
P[0][0] = s->motion_val[mot_xy ][0];
|
P[0][0] = s->motion_val[mot_xy ][0];
|
||||||
P[0][1] = s->motion_val[mot_xy ][1];
|
P[0][1] = s->motion_val[mot_xy ][1];
|
||||||
@ -618,7 +716,8 @@ int estimate_motion(MpegEncContext * s,
|
|||||||
P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);
|
P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax);
|
dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax);
|
||||||
|
|
||||||
mx+= s->mb_x*16;
|
mx+= s->mb_x*16;
|
||||||
my+= s->mb_y*16;
|
my+= s->mb_y*16;
|
||||||
break;
|
break;
|
||||||
@ -654,6 +753,8 @@ int estimate_motion(MpegEncContext * s,
|
|||||||
mx -= 16 * s->mb_x;
|
mx -= 16 * s->mb_x;
|
||||||
my -= 16 * s->mb_y;
|
my -= 16 * s->mb_y;
|
||||||
}
|
}
|
||||||
|
// check(mx + 32*s->mb_x, my + 32*s->mb_y, 1, end)
|
||||||
|
|
||||||
*mx_ptr = mx;
|
*mx_ptr = mx;
|
||||||
*my_ptr = my;
|
*my_ptr = my;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -51,6 +51,9 @@ static int mpeg2_decode_block_intra(MpegEncContext *s,
|
|||||||
int n);
|
int n);
|
||||||
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
|
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
|
||||||
|
|
||||||
|
static UINT16 mv_penalty[MAX_FCODE][MAX_MV*2+1];
|
||||||
|
static UINT8 fcode_tab[MAX_MV*2+1];
|
||||||
|
|
||||||
static void put_header(MpegEncContext *s, int header)
|
static void put_header(MpegEncContext *s, int header)
|
||||||
{
|
{
|
||||||
align_put_bits(&s->pb);
|
align_put_bits(&s->pb);
|
||||||
@ -353,6 +356,53 @@ static void mpeg1_encode_motion(MpegEncContext *s, int val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mpeg1_encode_init(MpegEncContext *s)
|
||||||
|
{
|
||||||
|
static int done=0;
|
||||||
|
if(!done){
|
||||||
|
int f_code;
|
||||||
|
int mv;
|
||||||
|
|
||||||
|
done=1;
|
||||||
|
for(f_code=1; f_code<=MAX_FCODE; f_code++){
|
||||||
|
for(mv=-MAX_MV; mv<=MAX_MV; mv++){
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(mv==0) len= mbMotionVectorTable[0][1];
|
||||||
|
else{
|
||||||
|
int val, bit_size, range, code;
|
||||||
|
|
||||||
|
bit_size = s->f_code - 1;
|
||||||
|
range = 1 << bit_size;
|
||||||
|
|
||||||
|
val=mv;
|
||||||
|
if (val < 0)
|
||||||
|
val = -val;
|
||||||
|
val--;
|
||||||
|
code = (val >> bit_size) + 1;
|
||||||
|
if(code<17){
|
||||||
|
len= mbMotionVectorTable[code][1] + 1 + bit_size;
|
||||||
|
}else{
|
||||||
|
len= mbMotionVectorTable[16][1] + 2 + bit_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mv_penalty[f_code][mv+MAX_MV]= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(f_code=MAX_FCODE; f_code>0; f_code--){
|
||||||
|
for(mv=-(8<<f_code); mv<(8<<f_code); mv++){
|
||||||
|
fcode_tab[mv+MAX_MV]= f_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s->mv_penalty= mv_penalty;
|
||||||
|
|
||||||
|
s->fcode_tab= fcode_tab;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void encode_dc(MpegEncContext *s, int diff, int component)
|
static inline void encode_dc(MpegEncContext *s, int diff, int component)
|
||||||
{
|
{
|
||||||
if (component == 0) {
|
if (component == 0) {
|
||||||
|
@ -294,6 +294,7 @@ int MPV_encode_init(AVCodecContext *avctx)
|
|||||||
s->qcompress= avctx->qcompress;
|
s->qcompress= avctx->qcompress;
|
||||||
s->qblur= avctx->qblur;
|
s->qblur= avctx->qblur;
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
|
s->aspect_ratio_info= avctx->aspect_ratio_info;
|
||||||
|
|
||||||
if (s->gop_size <= 1) {
|
if (s->gop_size <= 1) {
|
||||||
s->intra_only = 1;
|
s->intra_only = 1;
|
||||||
@ -377,6 +378,8 @@ int MPV_encode_init(AVCodecContext *avctx)
|
|||||||
|
|
||||||
if (s->out_format == FMT_H263)
|
if (s->out_format == FMT_H263)
|
||||||
h263_encode_init(s);
|
h263_encode_init(s);
|
||||||
|
else if (s->out_format == FMT_MPEG1)
|
||||||
|
mpeg1_encode_init(s);
|
||||||
|
|
||||||
s->encoding = 1;
|
s->encoding = 1;
|
||||||
|
|
||||||
@ -1075,7 +1078,6 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
|||||||
/* Reset the average MB variance */
|
/* Reset the average MB variance */
|
||||||
s->avg_mb_var = 0;
|
s->avg_mb_var = 0;
|
||||||
s->mc_mb_var = 0;
|
s->mc_mb_var = 0;
|
||||||
|
|
||||||
/* Estimate motion for every MB */
|
/* Estimate motion for every MB */
|
||||||
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
|
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
|
||||||
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
|
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
|
||||||
@ -1132,12 +1134,13 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
|||||||
|
|
||||||
for(i=MAX_FCODE; i>1; i--){
|
for(i=MAX_FCODE; i>1; i--){
|
||||||
loose+= mv_num[i];
|
loose+= mv_num[i];
|
||||||
if(loose > 4) break;
|
if(loose > 4) break; //FIXME this is pretty ineffective
|
||||||
}
|
}
|
||||||
s->f_code= i;
|
s->f_code= i;
|
||||||
}else{
|
}else{
|
||||||
s->f_code= 1;
|
s->f_code= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("f_code %d ///\n", s->f_code);
|
//printf("f_code %d ///\n", s->f_code);
|
||||||
/* convert MBs with too long MVs to I-Blocks */
|
/* convert MBs with too long MVs to I-Blocks */
|
||||||
if(s->pict_type==P_TYPE){
|
if(s->pict_type==P_TYPE){
|
||||||
|
@ -309,6 +309,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
|
|||||||
void mpeg1_encode_mb(MpegEncContext *s,
|
void mpeg1_encode_mb(MpegEncContext *s,
|
||||||
DCTELEM block[6][64],
|
DCTELEM block[6][64],
|
||||||
int motion_x, int motion_y);
|
int motion_x, int motion_y);
|
||||||
|
void mpeg1_encode_init(MpegEncContext *s);
|
||||||
|
|
||||||
/* h263enc.c */
|
/* h263enc.c */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user