diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 5e5e19fe33949be1e9ffd768afdcc6a60c9f5a22..0fc72d7eba79ec9b806a80c8ef98a542e0b4db7f 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -413,12 +413,11 @@ void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim, * such as 2, 4, 8. Will revisit it if needed. * Should also try using a look-up table to see if it helps * performance. */ - int round = cpi->oxcf.mr_down_sampling_factor.num/2; int parent_mb_row, parent_mb_col; - parent_mb_row = (mb_row*cpi->oxcf.mr_down_sampling_factor.den+round) + parent_mb_row = mb_row*cpi->oxcf.mr_down_sampling_factor.den /cpi->oxcf.mr_down_sampling_factor.num; - parent_mb_col = (mb_col*cpi->oxcf.mr_down_sampling_factor.den+round) + parent_mb_col = mb_col*cpi->oxcf.mr_down_sampling_factor.den /cpi->oxcf.mr_down_sampling_factor.num; parent_mb_index = parent_mb_row*cpi->mr_low_res_mb_cols + parent_mb_col; } diff --git a/vp8_multi_resolution_encoder.c b/vp8_multi_resolution_encoder.c index 11c33d618769bc8304c23780fd2644d26f3c8513..633c039ec59454cbcc12221672fd2cac60a179a1 100644 --- a/vp8_multi_resolution_encoder.c +++ b/vp8_multi_resolution_encoder.c @@ -212,7 +212,10 @@ int main(int argc, char **argv) double psnr_totals[NUM_ENCODERS][4] = {{0,0}}; int psnr_count[NUM_ENCODERS] = {0}; - /* Set the required target bitrates for each resolution level. */ + /* Set the required target bitrates for each resolution level. + * If target bitrate for highest-resolution level is set to 0, + * (i.e. target_bitrate[0]=0), we skip encoding at that level. + */ unsigned int target_bitrate[NUM_ENCODERS]={1400, 500, 100}; /* Enter the frame rate of the input video */ int framerate = 30; @@ -221,6 +224,9 @@ int main(int argc, char **argv) dsf[1] controls down sampling from level 1 to level 2; dsf[2] is not used. */ vpx_rational_t dsf[NUM_ENCODERS] = {{2, 1}, {2, 1}, {1, 1}}; + /* Encode starting from which resolution level. Normally it is 0 that + * means the original(highest) resolution. */ + int s_lvl = 0; if(argc!= (5+NUM_ENCODERS)) die("Usage: %s <width> <height> <infile> <outfile(s)> <output psnr?>\n", @@ -234,6 +240,21 @@ int main(int argc, char **argv) if(width < 16 || width%2 || height <16 || height%2) die("Invalid resolution: %ldx%ld", width, height); + /* Check to see if we need to encode all resolution levels */ + for (i=0; i<NUM_ENCODERS; i++) + { + if (target_bitrate[i]) + break; + else + s_lvl += 1; + } + + if (s_lvl >= NUM_ENCODERS) + { + printf("No encoding: total number of encoders is 0!"); + return 0; + } + /* Open input video file for encoding */ if(!(infile = fopen(argv[3], "rb"))) die("Failed to open %s for reading", argv[3]); @@ -321,17 +342,15 @@ int main(int argc, char **argv) else read_frame_p = read_frame_by_row; - for (i=0; i< NUM_ENCODERS; i++) - write_ivf_file_header(outfile[i], &cfg[i], 0); - /* Initialize multi-encoder */ - if(vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS, - (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0])) - die_codec(&codec[0], "Failed to initialize encoder"); + if(vpx_codec_enc_init_multi(&codec[s_lvl], interface, &cfg[s_lvl], s_lvl, + NUM_ENCODERS, + (show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[s_lvl])) + die_codec(&codec[s_lvl], "Failed to initialize encoder"); /* The extra encoding configuration parameters can be set as follows. */ /* Set encoding speed */ - for ( i=0; i<NUM_ENCODERS; i++) + for ( i=s_lvl; i<NUM_ENCODERS; i++) { int speed = -6; if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed)) @@ -341,20 +360,25 @@ int main(int argc, char **argv) * better performance. */ { unsigned int static_thresh = 1000; - if(vpx_codec_control(&codec[0], VP8E_SET_STATIC_THRESHOLD, static_thresh)) - die_codec(&codec[0], "Failed to set static threshold"); + if(vpx_codec_control(&codec[s_lvl], VP8E_SET_STATIC_THRESHOLD, + static_thresh)) + die_codec(&codec[s_lvl], "Failed to set static threshold"); } /* Set static thresh = 0 for other encoders for better quality */ - for ( i=1; i<NUM_ENCODERS; i++) + for ( i=s_lvl+1; i<NUM_ENCODERS; i++) { unsigned int static_thresh = 0; - if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, static_thresh)) + if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, + static_thresh)) die_codec(&codec[i], "Failed to set static threshold"); } frame_avail = 1; got_data = 0; + for (i=s_lvl ; i< NUM_ENCODERS; i++) + write_ivf_file_header(outfile[i], &cfg[i], 0); + while(frame_avail || got_data) { vpx_codec_iter_t iter[NUM_ENCODERS]={NULL}; @@ -381,11 +405,11 @@ int main(int argc, char **argv) } /* Encode each frame at multi-levels */ - if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL, + if(vpx_codec_encode(&codec[s_lvl], frame_avail? &raw[s_lvl] : NULL, frame_cnt, 1, flags, arg_deadline)) - die_codec(&codec[0], "Failed to encode frame"); + die_codec(&codec[s_lvl], "Failed to encode frame"); - for (i=NUM_ENCODERS-1; i>=0 ; i--) + for (i=NUM_ENCODERS-1; i>=s_lvl ; i--) { got_data = 0; @@ -428,7 +452,7 @@ int main(int argc, char **argv) fclose(infile); - for (i=0; i< NUM_ENCODERS; i++) + for (i=s_lvl; i< NUM_ENCODERS; i++) { printf("Processed %ld frames.\n",(long int)frame_cnt-1); @@ -454,8 +478,11 @@ int main(int argc, char **argv) /* Try to rewrite the file header with the actual frame count */ if(!fseek(outfile[i], 0, SEEK_SET)) write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1); - fclose(outfile[i]); + } + for (i=0; i< NUM_ENCODERS; i++) + { + fclose(outfile[i]); vpx_img_free(&raw[i]); } diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c index 03ddc62b289e65c908c3ac83ac89a7f98c6aec37..886cbb5fb01234967d87cd4aa5872ee6c194f0ad 100644 --- a/vpx/src/vpx_encoder.c +++ b/vpx/src/vpx_encoder.c @@ -69,6 +69,7 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t *ctx, vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, + int s_lvl, int num_enc, vpx_codec_flags_t flags, vpx_rational_t *dsf, @@ -99,7 +100,7 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, if(!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) { - for (i = 0; i < num_enc; i++) + for (i = s_lvl; i < num_enc; i++) { vpx_codec_priv_enc_mr_cfg_t mr_cfg; @@ -112,7 +113,7 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, } mr_cfg.mr_low_res_mode_info = mem_loc; - mr_cfg.mr_total_resolutions = num_enc; + mr_cfg.mr_total_resolutions = num_enc - s_lvl; mr_cfg.mr_encoder_id = num_enc-1-i; mr_cfg.mr_down_sampling_factor.num = dsf->num; mr_cfg.mr_down_sampling_factor.den = dsf->den; diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index 885ca229f96d9472f6a3e8a43a6bab064fc582dd..c5429c9bc837ee65a6f8118e01fd96afcf9d7f41 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -688,6 +688,7 @@ extern "C" { * \param[in] ctx Pointer to this instance's context. * \param[in] iface Pointer to the algorithm interface to use. * \param[in] cfg Configuration to use, if known. May be NULL. + * \param[in] s_lvl Starting encoder id. Normally it is 0. * \param[in] num_enc Total number of encoders. * \param[in] flags Bitfield of VPX_CODEC_USE_* flags * \param[in] dsf Pointer to down-sampling factors. @@ -701,6 +702,7 @@ extern "C" { vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx, vpx_codec_iface_t *iface, vpx_codec_enc_cfg_t *cfg, + int s_lvl, int num_enc, vpx_codec_flags_t flags, vpx_rational_t *dsf, @@ -711,8 +713,8 @@ extern "C" { * * Ensures the ABI version parameter is properly set. */ -#define vpx_codec_enc_init_multi(ctx, iface, cfg, num_enc, flags, dsf) \ - vpx_codec_enc_init_multi_ver(ctx, iface, cfg, num_enc, flags, dsf, \ +#define vpx_codec_enc_init_multi(ctx, iface, cfg, s_lvl, num_enc, flags, dsf) \ + vpx_codec_enc_init_multi_ver(ctx, iface, cfg, s_lvl, num_enc, flags, dsf, \ VPX_ENCODER_ABI_VERSION)