multi-res: restore v1.0.0 API
authorJohn Koleszar <jkoleszar@google.com>
Thu, 19 Apr 2012 17:00:33 +0000 (10:00 -0700)
committerJohn Koleszar <jkoleszar@google.com>
Fri, 20 Apr 2012 18:39:42 +0000 (11:39 -0700)
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

vp8/vp8_cx_iface.c
vp8_multi_resolution_encoder.c
vpx/src/vpx_encoder.c
vpx/vpx_encoder.h

index 683194a..d67d901 100644 (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);
 
index 633c039..78f50c2 100644 (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;
 }
index 886cbb5..03ddc62 100644 (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;
index c5429c9..885ca22 100644 (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)