mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
user specified motion estimation range limit
h263 me range fixed (was smaller then needed) Originally committed as revision 1610 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
3a13f6bd48
commit
ebbcdc9ac0
@ -16,8 +16,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT 0x000406
|
#define LIBAVCODEC_VERSION_INT 0x000406
|
||||||
#define LIBAVCODEC_VERSION "0.4.6"
|
#define LIBAVCODEC_VERSION "0.4.6"
|
||||||
#define LIBAVCODEC_BUILD 4658
|
#define LIBAVCODEC_BUILD 4659
|
||||||
#define LIBAVCODEC_BUILD_STR "4658"
|
#define LIBAVCODEC_BUILD_STR "4659"
|
||||||
|
|
||||||
enum CodecID {
|
enum CodecID {
|
||||||
CODEC_ID_NONE,
|
CODEC_ID_NONE,
|
||||||
@ -971,6 +971,15 @@ typedef struct AVCodecContext {
|
|||||||
#define FF_DTG_AFD_16_9_SP_14_9 14
|
#define FF_DTG_AFD_16_9_SP_14_9 14
|
||||||
#define FF_DTG_AFD_SP_4_3 15
|
#define FF_DTG_AFD_SP_4_3 15
|
||||||
|
|
||||||
|
int me_range;
|
||||||
|
/**
|
||||||
|
* Maximum motion estimation search range in subpel units.
|
||||||
|
* if 0 then no limit
|
||||||
|
*
|
||||||
|
* encoding: set by user.
|
||||||
|
* decoding: unused.
|
||||||
|
*/
|
||||||
|
|
||||||
} AVCodecContext;
|
} AVCodecContext;
|
||||||
|
|
||||||
//void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
|
//void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
|
||||||
|
@ -791,18 +791,18 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax, int f_code)
|
/**
|
||||||
|
* get fullpel ME search limits.
|
||||||
|
* @param range the approximate search range for the old ME code, unused for EPZS and newer
|
||||||
|
*/
|
||||||
|
static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax)
|
||||||
{
|
{
|
||||||
*range = 8 * (1 << (f_code - 1));
|
if(s->avctx->me_range) *range= s->avctx->me_range >> 1;
|
||||||
/* XXX: temporary kludge to avoid overflow for msmpeg4 */
|
else *range= 16;
|
||||||
if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
|
|
||||||
*range *= 2;
|
|
||||||
|
|
||||||
if (s->unrestricted_mv) {
|
if (s->unrestricted_mv) {
|
||||||
*xmin = -16;
|
*xmin = -16;
|
||||||
*ymin = -16;
|
*ymin = -16;
|
||||||
if (s->h263_plus)
|
|
||||||
*range *= 2;
|
|
||||||
if(s->avctx->codec->id!=CODEC_ID_MPEG4){
|
if(s->avctx->codec->id!=CODEC_ID_MPEG4){
|
||||||
*xmax = s->mb_width*16;
|
*xmax = s->mb_width*16;
|
||||||
*ymax = s->mb_height*16;
|
*ymax = s->mb_height*16;
|
||||||
@ -816,6 +816,8 @@ static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymi
|
|||||||
*xmax = s->mb_width*16 - 16;
|
*xmax = s->mb_width*16 - 16;
|
||||||
*ymax = s->mb_height*16 - 16;
|
*ymax = s->mb_height*16 - 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME try to limit x/y min/max if me_range is set
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift)
|
static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift)
|
||||||
@ -982,7 +984,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
|
|||||||
s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
|
s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
|
||||||
s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
|
s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
|
||||||
|
|
||||||
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
|
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax);
|
||||||
rel_xmin= xmin - mb_x*16;
|
rel_xmin= xmin - mb_x*16;
|
||||||
rel_xmax= xmax - mb_x*16;
|
rel_xmax= xmax - mb_x*16;
|
||||||
rel_ymin= ymin - mb_y*16;
|
rel_ymin= ymin - mb_y*16;
|
||||||
@ -1151,7 +1153,7 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
|
|||||||
|
|
||||||
s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp);
|
s->me.pre_penalty_factor = get_penalty_factor(s, s->avctx->me_pre_cmp);
|
||||||
|
|
||||||
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code);
|
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax);
|
||||||
rel_xmin= xmin - mb_x*16;
|
rel_xmin= xmin - mb_x*16;
|
||||||
rel_xmax= xmax - mb_x*16;
|
rel_xmax= xmax - mb_x*16;
|
||||||
rel_ymin= ymin - mb_y*16;
|
rel_ymin= ymin - mb_y*16;
|
||||||
@ -1212,7 +1214,7 @@ static int ff_estimate_motion_b(MpegEncContext * s,
|
|||||||
s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
|
s->me.sub_penalty_factor= get_penalty_factor(s, s->avctx->me_sub_cmp);
|
||||||
s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
|
s->me.mb_penalty_factor = get_penalty_factor(s, s->avctx->mb_cmp);
|
||||||
|
|
||||||
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code);
|
get_limits(s, &range, &xmin, &ymin, &xmax, &ymax);
|
||||||
rel_xmin= xmin - mb_x*16;
|
rel_xmin= xmin - mb_x*16;
|
||||||
rel_xmax= xmax - mb_x*16;
|
rel_xmax= xmax - mb_x*16;
|
||||||
rel_ymin= ymin - mb_y*16;
|
rel_ymin= ymin - mb_y*16;
|
||||||
@ -1583,10 +1585,14 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
|
|||||||
void ff_fix_long_p_mvs(MpegEncContext * s)
|
void ff_fix_long_p_mvs(MpegEncContext * s)
|
||||||
{
|
{
|
||||||
const int f_code= s->f_code;
|
const int f_code= s->f_code;
|
||||||
int y;
|
int y, range;
|
||||||
uint8_t * fcode_tab= s->fcode_tab;
|
|
||||||
//int clip=0;
|
range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code);
|
||||||
//int noclip=0;
|
|
||||||
|
if(s->msmpeg4_version) range= 16;
|
||||||
|
|
||||||
|
if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;
|
||||||
|
|
||||||
/* clip / convert to intra 16x16 type MVs */
|
/* clip / convert to intra 16x16 type MVs */
|
||||||
for(y=0; y<s->mb_height; y++){
|
for(y=0; y<s->mb_height; y++){
|
||||||
int x;
|
int x;
|
||||||
@ -1594,10 +1600,8 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
|
|||||||
int i= y*s->mb_width;
|
int i= y*s->mb_width;
|
||||||
for(x=0; x<s->mb_width; x++){
|
for(x=0; x<s->mb_width; x++){
|
||||||
if(s->mb_type[i]&MB_TYPE_INTER){
|
if(s->mb_type[i]&MB_TYPE_INTER){
|
||||||
if( fcode_tab[s->p_mv_table[xy][0] + MAX_MV] > f_code
|
if( s->p_mv_table[xy][0] >=range || s->p_mv_table[xy][0] <-range
|
||||||
|| fcode_tab[s->p_mv_table[xy][0] + MAX_MV] == 0
|
|| s->p_mv_table[xy][1] >=range || s->p_mv_table[xy][1] <-range){
|
||||||
|| fcode_tab[s->p_mv_table[xy][1] + MAX_MV] > f_code
|
|
||||||
|| fcode_tab[s->p_mv_table[xy][1] + MAX_MV] == 0 ){
|
|
||||||
s->mb_type[i] &= ~MB_TYPE_INTER;
|
s->mb_type[i] &= ~MB_TYPE_INTER;
|
||||||
s->mb_type[i] |= MB_TYPE_INTRA;
|
s->mb_type[i] |= MB_TYPE_INTRA;
|
||||||
s->p_mv_table[xy][0] = 0;
|
s->p_mv_table[xy][0] = 0;
|
||||||
@ -1629,10 +1633,8 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
|
|||||||
int mx= s->motion_val[ xy + off ][0];
|
int mx= s->motion_val[ xy + off ][0];
|
||||||
int my= s->motion_val[ xy + off ][1];
|
int my= s->motion_val[ xy + off ][1];
|
||||||
|
|
||||||
if( fcode_tab[mx + MAX_MV] > f_code
|
if( mx >=range || mx <-range
|
||||||
|| fcode_tab[mx + MAX_MV] == 0
|
|| my >=range || my <-range){
|
||||||
|| fcode_tab[my + MAX_MV] > f_code
|
|
||||||
|| fcode_tab[my + MAX_MV] == 0 ){
|
|
||||||
s->mb_type[i] &= ~MB_TYPE_INTER4V;
|
s->mb_type[i] &= ~MB_TYPE_INTER4V;
|
||||||
s->mb_type[i] |= MB_TYPE_INTRA;
|
s->mb_type[i] |= MB_TYPE_INTRA;
|
||||||
}
|
}
|
||||||
@ -1648,33 +1650,29 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
|
|||||||
void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type)
|
void ff_fix_long_b_mvs(MpegEncContext * s, int16_t (*mv_table)[2], int f_code, int type)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
uint8_t * fcode_tab= s->fcode_tab;
|
|
||||||
|
|
||||||
// RAL: 8 in MPEG-1, 16 in MPEG-4
|
// RAL: 8 in MPEG-1, 16 in MPEG-4
|
||||||
int range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code);
|
int range = (((s->codec_id == CODEC_ID_MPEG1VIDEO) ? 8 : 16) << f_code);
|
||||||
|
|
||||||
|
if(s->avctx->me_range && range > s->avctx->me_range) range= s->avctx->me_range;
|
||||||
|
|
||||||
/* clip / convert to intra 16x16 type MVs */
|
/* clip / convert to intra 16x16 type MVs */
|
||||||
for(y=0; y<s->mb_height; y++){
|
for(y=0; y<s->mb_height; y++){
|
||||||
int x;
|
int x;
|
||||||
int xy= (y+1)* (s->mb_width+2)+1;
|
int xy= (y+1)* (s->mb_width+2)+1;
|
||||||
int i= y*s->mb_width;
|
int i= y*s->mb_width;
|
||||||
for(x=0; x<s->mb_width; x++)
|
for(x=0; x<s->mb_width; x++){
|
||||||
{
|
if (s->mb_type[i] & type){ // RAL: "type" test added...
|
||||||
if (s->mb_type[i] & type) // RAL: "type" test added...
|
if( mv_table[xy][0] >=range || mv_table[xy][0] <-range
|
||||||
{
|
|| mv_table[xy][1] >=range || mv_table[xy][1] <-range){
|
||||||
if (fcode_tab[mv_table[xy][0] + MAX_MV] > f_code || fcode_tab[mv_table[xy][0] + MAX_MV] == 0)
|
|
||||||
{
|
if(s->codec_id == CODEC_ID_MPEG1VIDEO && 0){
|
||||||
if(mv_table[xy][0]>0)
|
}else{
|
||||||
mv_table[xy][0]= range-1;
|
if (mv_table[xy][0] > range-1) mv_table[xy][0]= range-1;
|
||||||
else
|
else if(mv_table[xy][0] < -range ) mv_table[xy][0]= -range;
|
||||||
mv_table[xy][0]= -range;
|
if (mv_table[xy][1] > range-1) mv_table[xy][1]= range-1;
|
||||||
|
else if(mv_table[xy][1] < -range ) mv_table[xy][1]= -range;
|
||||||
}
|
}
|
||||||
if (fcode_tab[mv_table[xy][1] + MAX_MV] > f_code || fcode_tab[mv_table[xy][1] + MAX_MV] == 0)
|
|
||||||
{
|
|
||||||
if(mv_table[xy][1]>0)
|
|
||||||
mv_table[xy][1]= range-1;
|
|
||||||
else
|
|
||||||
mv_table[xy][1]= -range;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xy++;
|
xy++;
|
||||||
|
@ -2993,14 +2993,13 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
|||||||
//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
|
//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s->codec_id != CODEC_ID_H263P){ //FIXME use umvplus or something
|
||||||
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) {
|
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) {
|
||||||
s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER);
|
s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER);
|
||||||
|
|
||||||
// RAL: Next call moved into that bloc
|
|
||||||
ff_fix_long_p_mvs(s);
|
ff_fix_long_p_mvs(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAL: All this bloc changed
|
|
||||||
if(s->pict_type==B_TYPE){
|
if(s->pict_type==B_TYPE){
|
||||||
int a, b;
|
int a, b;
|
||||||
|
|
||||||
@ -3017,6 +3016,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
|
|||||||
ff_fix_long_b_mvs(s, s->b_bidir_forw_mv_table, s->f_code, MB_TYPE_BIDIR);
|
ff_fix_long_b_mvs(s, s->b_bidir_forw_mv_table, s->f_code, MB_TYPE_BIDIR);
|
||||||
ff_fix_long_b_mvs(s, s->b_bidir_back_mv_table, s->b_code, MB_TYPE_BIDIR);
|
ff_fix_long_b_mvs(s, s->b_bidir_back_mv_table, s->b_code, MB_TYPE_BIDIR);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (s->fixed_qscale)
|
if (s->fixed_qscale)
|
||||||
s->frame_qscale = s->current_picture.quality;
|
s->frame_qscale = s->current_picture.quality;
|
||||||
|
Loading…
Reference in New Issue
Block a user