ref: 25a36d6b3c6d206ad19d47f9999eb71109f87dea
parent: 0cc044f071bee19649ea13a2272f2d174de029f2
author: John Koleszar <jkoleszar@google.com>
date: Thu Apr 19 06:00:33 EDT 2012
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
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -755,6 +755,9 @@
{
vpx_codec_err_t res = VPX_CODEC_OK;
+ if (!ctx->cfg.rc_target_bitrate)
+ return res;
+
if (img)
res = validate_img(ctx, img);
--- a/vp8_multi_resolution_encoder.c
+++ b/vp8_multi_resolution_encoder.c
@@ -224,9 +224,6 @@
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 @@
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 @@
/* 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 @@
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,16 +351,14 @@
* 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");
}
@@ -376,9 +365,6 @@
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 @@
}
/* 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 @@
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 @@
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;
}
--- a/vpx/src/vpx_encoder.c
+++ b/vpx/src/vpx_encoder.c
@@ -69,7 +69,6 @@
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 @@
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 @@
}
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;
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -688,7 +688,6 @@
* \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 @@
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 @@
*
* 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)
--
⑨