aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-03-22 23:22:08 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-03-22 23:22:08 +0000
commit11ce88346b1ae4da21b581baf1b4eb784d842547 (patch)
treebffaf9c06980445db1dc0cf44399526faee72316
parentc5b1c10a0e1ed783674b24d787797ffba9bdffc0 (diff)
downloadffmpeg-11ce88346b1ae4da21b581baf1b4eb784d842547.tar.gz
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
-rw-r--r--libavcodec/avcodec.h1
-rw-r--r--libavcodec/h263.c7
-rw-r--r--libavcodec/h263dec.c1
-rw-r--r--libavcodec/motion_est.c119
-rw-r--r--libavcodec/mpeg12.c50
-rw-r--r--libavcodec/mpegvideo.c7
-rw-r--r--libavcodec/mpegvideo.h1
7 files changed, 173 insertions, 13 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index d3ddf92a78..15b8f900cc 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -81,6 +81,7 @@ typedef struct AVCodecContext {
/* video only */
int frame_rate; /* frames per sec multiplied by FRAME_RATE_BASE */
int width, height;
+ int aspect_ratio_info;
int gop_size; /* 0 = intra only */
int pix_fmt; /* pixel format, see PIX_FMT_xxx */
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 60baedb47f..c4110726ad 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -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, 4, vo_ver_id); /* is obj layer ver id */
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, 2, RECT_SHAPE); /* vol shape= rectangle */
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_height
}
+
if(get_bits1(&s->gb)){ /* vol control parameter */
printf("vol control parameter not supported\n");
return -1;
@@ -2388,7 +2392,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
//printf("b-code %d\n", s->b_code);
}
//printf("quant:%d fcode:%d\n", s->qscale, s->f_code);
-
if(!s->scalability){
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
skip_bits1(&s->gb); // vop shape coding type
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 8a80af6bb0..aa822800bd 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -123,6 +123,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
if (!s->context_initialized) {
avctx->width = s->width;
avctx->height = s->height;
+ avctx->aspect_ratio_info= s->aspect_ratio_info;
if (MPV_common_init(s) < 0)
return -1;
} else if (s->width != avctx->width || s->height != avctx->height) {
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index f1dfc9f9e8..dc9b3066d0 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -335,13 +335,15 @@ static int phods_motion_search(MpegEncContext * s,
#define Z_THRESHOLD 256
#define CHECK_MV(x,y)\
+{\
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;\
if(d<dmin){\
best[0]=x;\
best[1]=y;\
dmin=d;\
- }
+ }\
+}
#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,
UINT8 *new_pic, UINT8 *old_pic, int pic_stride,
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;
}
}
+
+/* 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,
@@ -397,8 +491,7 @@ static int epzs_motion_search(MpegEncContext * s,
new_pic = s->new_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);
if(dmin<Z_THRESHOLD){
*mx_ptr= 0;
@@ -424,13 +517,18 @@ static int epzs_motion_search(MpegEncContext * s,
}
CHECK_MV(P[0][0]>>shift, P[0][1]>>shift)
- 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);
+//check(best[0],best[1],0, b0)
+ 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];
*my_ptr= best[1];
// printf("%d %d %d \n", best[0], best[1], dmin);
-
return dmin;
}
@@ -563,8 +661,8 @@ int estimate_motion(MpegEncContext * s,
rel_ymax= ymax - s->mb_y*16;
if(s->out_format == FMT_H263){
static const int off[4]= {2, 1, 1, -1};
- const int mot_stride = s->block_wrap[0];
- const int mot_xy = s->block_index[0];
+ const int mot_stride = s->mb_width*2 + 2;
+ 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][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]);
}
}
- 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;
my+= s->mb_y*16;
break;
@@ -654,6 +753,8 @@ int estimate_motion(MpegEncContext * s,
mx -= 16 * s->mb_x;
my -= 16 * s->mb_y;
}
+// check(mx + 32*s->mb_x, my + 32*s->mb_y, 1, end)
+
*mx_ptr = mx;
*my_ptr = my;
return 0;
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 417f595644..fba90e7144 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -51,6 +51,9 @@ static int mpeg2_decode_block_intra(MpegEncContext *s,
int n);
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)
{
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)
{
if (component == 0) {
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 180addb6f6..9510ca1847 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -294,6 +294,7 @@ int MPV_encode_init(AVCodecContext *avctx)
s->qcompress= avctx->qcompress;
s->qblur= avctx->qblur;
s->avctx = avctx;
+ s->aspect_ratio_info= avctx->aspect_ratio_info;
if (s->gop_size <= 1) {
s->intra_only = 1;
@@ -377,6 +378,8 @@ int MPV_encode_init(AVCodecContext *avctx)
if (s->out_format == FMT_H263)
h263_encode_init(s);
+ else if (s->out_format == FMT_MPEG1)
+ mpeg1_encode_init(s);
s->encoding = 1;
@@ -1075,7 +1078,6 @@ static void encode_picture(MpegEncContext *s, int picture_number)
/* Reset the average MB variance */
s->avg_mb_var = 0;
s->mc_mb_var = 0;
-
/* Estimate motion for every MB */
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
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--){
loose+= mv_num[i];
- if(loose > 4) break;
+ if(loose > 4) break; //FIXME this is pretty ineffective
}
s->f_code= i;
}else{
s->f_code= 1;
}
+
//printf("f_code %d ///\n", s->f_code);
/* convert MBs with too long MVs to I-Blocks */
if(s->pict_type==P_TYPE){
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 465b5ef3ab..1d0dd4f027 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -309,6 +309,7 @@ void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
void mpeg1_encode_mb(MpegEncContext *s,
DCTELEM block[6][64],
int motion_x, int motion_y);
+void mpeg1_encode_init(MpegEncContext *s);
/* h263enc.c */