multi-res: restore v1.0.0 API

Move the notion of 0 bitrate implying skip deeper into the codec,
rather than doing it at the multi-encoder API level. This preserves
v1.0.0 ABI compatibility, rather than forcing a bump to v2.0.0 over a
minor change. Also, this allows the case where the application can
selectively enable and disable the larger resolution(s) without having
to reinitialize the codec instace (for instance, if no target is
receiving the full resolution stream).

It's not clear how deep to push this check. It may be valuable to
allow the framerate adaptation code to run, for example. Currently put
the check as early as possible for simplicity, should reevaluate this
as this feature gains real use.

Change-Id: I371709b8c6b52185a1c71a166a131ecc244582f0
This commit is contained in:
John Koleszar 2012-04-19 10:00:33 -07:00
parent c311b3b3a9
commit d72c536ede
4 changed files with 36 additions and 50 deletions

View File

@ -757,6 +757,9 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx,
{
vpx_codec_err_t res = VPX_CODEC_OK;
if (!ctx->cfg.rc_target_bitrate)
return res;
if (img)
res = validate_img(ctx, img);

View File

@ -224,9 +224,6 @@ 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",
@ -240,21 +237,6 @@ 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]);
@ -262,6 +244,12 @@ int main(int argc, char **argv)
/* Open output file for each encoder to output bitstreams */
for (i=0; i< NUM_ENCODERS; i++)
{
if(!target_bitrate[i])
{
outfile[i] = NULL;
continue;
}
if(!(outfile[i] = fopen(argv[i+4], "wb")))
die("Failed to open %s for writing", argv[i+4]);
}
@ -342,15 +330,18 @@ int main(int argc, char **argv)
else
read_frame_p = read_frame_by_row;
for (i=0; i< NUM_ENCODERS; i++)
if(outfile[i])
write_ivf_file_header(outfile[i], &cfg[i], 0);
/* Initialize multi-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");
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");
/* The extra encoding configuration parameters can be set as follows. */
/* Set encoding speed */
for ( i=s_lvl; i<NUM_ENCODERS; i++)
for ( i=0; i<NUM_ENCODERS; i++)
{
int speed = -6;
if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed))
@ -360,25 +351,20 @@ int main(int argc, char **argv)
* better performance. */
{
unsigned int static_thresh = 1000;
if(vpx_codec_control(&codec[s_lvl], VP8E_SET_STATIC_THRESHOLD,
static_thresh))
die_codec(&codec[s_lvl], "Failed to set static threshold");
if(vpx_codec_control(&codec[0], VP8E_SET_STATIC_THRESHOLD, static_thresh))
die_codec(&codec[0], "Failed to set static threshold");
}
/* Set static thresh = 0 for other encoders for better quality */
for ( i=s_lvl+1; i<NUM_ENCODERS; i++)
for ( i=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};
@ -405,11 +391,11 @@ int main(int argc, char **argv)
}
/* Encode each frame at multi-levels */
if(vpx_codec_encode(&codec[s_lvl], frame_avail? &raw[s_lvl] : NULL,
if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
frame_cnt, 1, flags, arg_deadline))
die_codec(&codec[s_lvl], "Failed to encode frame");
die_codec(&codec[0], "Failed to encode frame");
for (i=NUM_ENCODERS-1; i>=s_lvl ; i--)
for (i=NUM_ENCODERS-1; i>=0 ; i--)
{
got_data = 0;
@ -452,10 +438,9 @@ int main(int argc, char **argv)
fclose(infile);
for (i=s_lvl; i< NUM_ENCODERS; i++)
printf("Processed %ld frames.\n",(long int)frame_cnt-1);
for (i=0; i< NUM_ENCODERS; i++)
{
printf("Processed %ld frames.\n",(long int)frame_cnt-1);
/* Calculate PSNR and print it out */
if ( (show_psnr) && (psnr_count[i]>0) )
{
@ -475,16 +460,17 @@ int main(int argc, char **argv)
if(vpx_codec_destroy(&codec[i]))
die_codec(&codec[i], "Failed to destroy codec");
vpx_img_free(&raw[i]);
if(!outfile[i])
continue;
/* 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);
}
for (i=0; i< NUM_ENCODERS; i++)
{
fclose(outfile[i]);
vpx_img_free(&raw[i]);
}
printf("\n");
return EXIT_SUCCESS;
}

View File

@ -69,7 +69,6 @@ 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,
@ -100,7 +99,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 = s_lvl; i < num_enc; i++)
for (i = 0; i < num_enc; i++)
{
vpx_codec_priv_enc_mr_cfg_t mr_cfg;
@ -113,7 +112,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 - s_lvl;
mr_cfg.mr_total_resolutions = num_enc;
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;

View File

@ -688,7 +688,6 @@ 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.
@ -702,7 +701,6 @@ 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,
@ -713,8 +711,8 @@ extern "C" {
*
* Ensures the ABI version parameter is properly set.
*/
#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, \
#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, \
VPX_ENCODER_ABI_VERSION)