- EPZS ME algo used by default. - HQ flag activated for ffmpeg. - Cosmetics ... Originally committed as revision 398 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -86,7 +86,7 @@ echo " --cpu=CPU force cpu to CPU [$cpu]" | |||||
| echo " --disable-mmx disable mmx usage" | echo " --disable-mmx disable mmx usage" | ||||
| echo " --enable-gprof enable profiling with gprof [$gprof]" | echo " --enable-gprof enable profiling with gprof [$gprof]" | ||||
| echo " --disable-grab disable audio/video grabbing code" | echo " --disable-grab disable audio/video grabbing code" | ||||
| echo " --enable-simple_idct use simple IDCT routines" | |||||
| echo " --enable-simple_idct use simple IDCT routines" | |||||
| echo " --enable-mp3lame enable mp3 encoding via libmp3lame" | echo " --enable-mp3lame enable mp3 encoding via libmp3lame" | ||||
| echo " --enable-win32 enable win32 cross compile" | echo " --enable-win32 enable win32 cross compile" | ||||
| echo " --enable-shared build shared libraries [default=no]" | echo " --enable-shared build shared libraries [default=no]" | ||||
| @@ -82,9 +82,11 @@ static int video_qmax = 15; | |||||
| static int video_qdiff = 3; | static int video_qdiff = 3; | ||||
| static float video_qblur = 0.5; | static float video_qblur = 0.5; | ||||
| static float video_qcomp = 0.5; | static float video_qcomp = 0.5; | ||||
| static int motion_estimation_method = 0; | |||||
| static int video_disable = 0; | static int video_disable = 0; | ||||
| static int video_codec_id = CODEC_ID_NONE; | static int video_codec_id = CODEC_ID_NONE; | ||||
| static int same_quality = 0; | static int same_quality = 0; | ||||
| static int use_hq = 0; | |||||
| static int use_4mv = 0; | static int use_4mv = 0; | ||||
| static int do_deinterlace = 0; | static int do_deinterlace = 0; | ||||
| @@ -1386,7 +1388,7 @@ void opt_motion_estimation(const char *arg) | |||||
| break; | break; | ||||
| p++; | p++; | ||||
| } | } | ||||
| motion_estimation_method = p - motion_str; | |||||
| motion_estimation_method = (p - motion_str) - 4; | |||||
| } | } | ||||
| void opt_video_codec(const char *arg) | void opt_video_codec(const char *arg) | ||||
| @@ -1763,6 +1765,10 @@ void opt_output_file(const char *filename) | |||||
| video_enc->quality = video_qscale; | video_enc->quality = video_qscale; | ||||
| } | } | ||||
| if (use_hq) { | |||||
| video_enc->flags |= CODEC_FLAG_HQ; | |||||
| } | |||||
| if (use_4mv) { | if (use_4mv) { | ||||
| video_enc->flags |= CODEC_FLAG_HQ; | video_enc->flags |= CODEC_FLAG_HQ; | ||||
| video_enc->flags |= CODEC_FLAG_4MV; | video_enc->flags |= CODEC_FLAG_4MV; | ||||
| @@ -1777,6 +1783,9 @@ void opt_output_file(const char *filename) | |||||
| video_enc->get_psnr = 1; | video_enc->get_psnr = 1; | ||||
| else | else | ||||
| video_enc->get_psnr = 0; | video_enc->get_psnr = 0; | ||||
| video_enc->me_method = motion_estimation_method; | |||||
| /* XXX: need to find a way to set codec parameters */ | /* XXX: need to find a way to set codec parameters */ | ||||
| if (oc->format == &ppm_format || | if (oc->format == &ppm_format || | ||||
| oc->format == &ppmpipe_format) { | oc->format == &ppmpipe_format) { | ||||
| @@ -2029,11 +2038,11 @@ void show_formats(void) | |||||
| pp = motion_str; | pp = motion_str; | ||||
| while (*pp) { | while (*pp) { | ||||
| printf(" %s", *pp); | printf(" %s", *pp); | ||||
| if ((pp - motion_str) == ME_ZERO) | |||||
| if ((pp - motion_str - 4) == ME_ZERO) | |||||
| printf("(fastest)"); | printf("(fastest)"); | ||||
| else if ((pp - motion_str) == ME_FULL) | |||||
| else if ((pp - motion_str - 4) == ME_FULL) | |||||
| printf("(slowest)"); | printf("(slowest)"); | ||||
| else if ((pp - motion_str) == ME_LOG) | |||||
| else if ((pp - motion_str - 4) == ME_EPZS) | |||||
| printf("(default)"); | printf("(default)"); | ||||
| pp++; | pp++; | ||||
| } | } | ||||
| @@ -2115,6 +2124,7 @@ const OptionDef options[] = { | |||||
| { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec", "codec" }, | { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec", "codec" }, | ||||
| { "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method", | { "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method", | ||||
| "method" }, | "method" }, | ||||
| { "hq", OPT_BOOL | OPT_EXPERT, {(void*)&use_hq}, "activate high quality settings" }, | |||||
| { "4mv", OPT_BOOL | OPT_EXPERT, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" }, | { "4mv", OPT_BOOL | OPT_EXPERT, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" }, | ||||
| { "sameq", OPT_BOOL, {(void*)&same_quality}, | { "sameq", OPT_BOOL, {(void*)&same_quality}, | ||||
| "use same video quality as source (implies VBR)" }, | "use same video quality as source (implies VBR)" }, | ||||
| @@ -56,14 +56,18 @@ enum SampleFormat { | |||||
| /* in bytes */ | /* in bytes */ | ||||
| #define AVCODEC_MAX_AUDIO_FRAME_SIZE 18432 | #define AVCODEC_MAX_AUDIO_FRAME_SIZE 18432 | ||||
| /* motion estimation type */ | |||||
| extern int motion_estimation_method; | |||||
| #define ME_ZERO 0 | |||||
| #define ME_FULL 1 | |||||
| #define ME_LOG 2 | |||||
| #define ME_PHODS 3 | |||||
| #define ME_EPZS 4 | |||||
| #define ME_X1 5 | |||||
| /* motion estimation type, EPZS by default */ | |||||
| enum Motion_Est_ID { | |||||
| ME_ZERO = -4, | |||||
| ME_FULL, | |||||
| ME_LOG, | |||||
| ME_PHODS, | |||||
| ME_EPZS, | |||||
| ME_X1 | |||||
| }; | |||||
| /* ME algos sorted by quality */ | |||||
| static const int Motion_Est_QTab[] = { -4, -1, -2, 1, 0, -3 }; | |||||
| /* encoding support */ | /* encoding support */ | ||||
| /* note not everything is supported yet */ | /* note not everything is supported yet */ | ||||
| @@ -89,6 +93,9 @@ typedef struct AVCodecContext { | |||||
| int flags; | int flags; | ||||
| int sub_id; /* some codecs needs additionnal format info. It is | int sub_id; /* some codecs needs additionnal format info. It is | ||||
| stored there */ | stored there */ | ||||
| int me_method; /* ME algorithm used for video coding */ | |||||
| /* 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; | ||||
| @@ -89,6 +89,8 @@ UINT8 ff_alternate_vertical_scan[64] = { | |||||
| 38, 46, 54, 62, 39, 47, 55, 63, | 38, 46, 54, 62, 39, 47, 55, 63, | ||||
| }; | }; | ||||
| #ifdef SIMPLE_IDCT | |||||
| /* Input permutation for the simple_idct_mmx */ | /* Input permutation for the simple_idct_mmx */ | ||||
| static UINT8 simple_mmx_permutation[64]={ | static UINT8 simple_mmx_permutation[64]={ | ||||
| 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, | 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, | ||||
| @@ -100,6 +102,7 @@ static UINT8 simple_mmx_permutation[64]={ | |||||
| 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, | 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, | ||||
| 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, | 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, | ||||
| }; | }; | ||||
| #endif | |||||
| /* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ | /* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ | ||||
| UINT32 inverse[256]={ | UINT32 inverse[256]={ | ||||
| @@ -594,7 +594,7 @@ 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) | ||||
| //check(best[0],best[1],0, b0) | //check(best[0],best[1],0, b0) | ||||
| if(s->full_search==ME_EPZS) | |||||
| if(s->me_method==ME_EPZS) | |||||
| dmin= small_diamond_search(s, best, dmin, new_pic, old_pic, pic_stride, | 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); | pred_x, pred_y, mv_penalty, quant, xmin, ymin, xmax, ymax, shift); | ||||
| else | else | ||||
| @@ -825,7 +825,7 @@ void estimate_motion(MpegEncContext * s, | |||||
| int P[6][2]; | int P[6][2]; | ||||
| const int shift= 1+s->quarter_sample; | const int shift= 1+s->quarter_sample; | ||||
| int mb_type=0; | int mb_type=0; | ||||
| //static int skip=0; | |||||
| range = 8 * (1 << (s->f_code - 1)); | range = 8 * (1 << (s->f_code - 1)); | ||||
| /* XXX: temporary kludge to avoid overflow for msmpeg4 */ | /* XXX: temporary kludge to avoid overflow for msmpeg4 */ | ||||
| if (s->out_format == FMT_H263 && !s->h263_msmpeg4) | if (s->out_format == FMT_H263 && !s->h263_msmpeg4) | ||||
| @@ -851,7 +851,7 @@ void estimate_motion(MpegEncContext * s, | |||||
| xmax = s->mb_width*16 - 16; | xmax = s->mb_width*16 - 16; | ||||
| ymax = s->mb_height*16 - 16; | ymax = s->mb_height*16 - 16; | ||||
| } | } | ||||
| switch(s->full_search) { | |||||
| switch(s->me_method) { | |||||
| case ME_ZERO: | case ME_ZERO: | ||||
| default: | default: | ||||
| no_motion_search(s, &mx, &my); | no_motion_search(s, &mx, &my); | ||||
| @@ -999,6 +999,7 @@ void estimate_motion(MpegEncContext * s, | |||||
| s->avg_mb_var+= varc; | s->avg_mb_var+= varc; | ||||
| s->mc_mb_var += vard; | s->mc_mb_var += vard; | ||||
| #if 0 | #if 0 | ||||
| printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", | printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", | ||||
| varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); | varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); | ||||
| @@ -1016,12 +1017,19 @@ void estimate_motion(MpegEncContext * s, | |||||
| }else{ | }else{ | ||||
| if (vard <= 64 || vard < varc) { | if (vard <= 64 || vard < varc) { | ||||
| mb_type|= MB_TYPE_INTER; | mb_type|= MB_TYPE_INTER; | ||||
| if (s->full_search != ME_ZERO) { | |||||
| if (s->me_method != ME_ZERO) { | |||||
| halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y); | halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y); | ||||
| } else { | } else { | ||||
| mx -= 16 * mb_x; | mx -= 16 * mb_x; | ||||
| my -= 16 * mb_y; | my -= 16 * mb_y; | ||||
| } | } | ||||
| #if 0 | |||||
| if (vard < 10) { | |||||
| skip++; | |||||
| fprintf(stderr,"\nEarly skip: %d vard: %2d varc: %5d dmin: %d", | |||||
| skip, vard, varc, dmin); | |||||
| } | |||||
| #endif | |||||
| }else{ | }else{ | ||||
| mb_type|= MB_TYPE_INTRA; | mb_type|= MB_TYPE_INTRA; | ||||
| mx = 0;//mx*2 - 32 * mb_x; | mx = 0;//mx*2 - 32 * mb_x; | ||||
| @@ -313,8 +313,10 @@ int MPV_encode_init(AVCodecContext *avctx) | |||||
| } else { | } else { | ||||
| s->intra_only = 0; | s->intra_only = 0; | ||||
| } | } | ||||
| s->full_search = motion_estimation_method; | |||||
| /* ME algorithm */ | |||||
| s->me_method = avctx->me_method; | |||||
| /* Fixed QSCALE */ | |||||
| s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE); | s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE); | ||||
| switch(avctx->codec->id) { | switch(avctx->codec->id) { | ||||
| @@ -413,7 +415,7 @@ int MPV_encode_init(AVCodecContext *avctx) | |||||
| mpeg1_encode_init(s); | mpeg1_encode_init(s); | ||||
| /* dont use mv_penalty table for crap MV as it would be confused */ | /* dont use mv_penalty table for crap MV as it would be confused */ | ||||
| if(s->full_search<4) s->mv_penalty= default_mv_penalty; | |||||
| if (s->me_method < 0) s->mv_penalty = default_mv_penalty; | |||||
| s->encoding = 1; | s->encoding = 1; | ||||
| @@ -1344,7 +1346,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||||
| } | } | ||||
| /* find best f_code for ME which do unlimited searches */ | /* find best f_code for ME which do unlimited searches */ | ||||
| if(s->pict_type==P_TYPE && s->full_search>3){ | |||||
| if(s->pict_type == P_TYPE && s->me_method >= 0){ | |||||
| int mv_num[8]; | int mv_num[8]; | ||||
| int i; | int i; | ||||
| int loose=0; | int loose=0; | ||||
| @@ -113,7 +113,7 @@ typedef struct MpegEncContext { | |||||
| int b_code; /* backward resolution for B Frames (mpeg4) */ | int b_code; /* backward resolution for B Frames (mpeg4) */ | ||||
| INT16 *mv_table[2]; /* MV table (1MV per MB)*/ | INT16 *mv_table[2]; /* MV table (1MV per MB)*/ | ||||
| INT16 (*motion_val)[2]; /* used for MV prediction (4MV per MB)*/ | INT16 (*motion_val)[2]; /* used for MV prediction (4MV per MB)*/ | ||||
| int full_search; | |||||
| int me_method; /* ME algorithm */ | |||||
| 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 | ||||