]> granicus.if.org Git - libvpx/commitdiff
Adding a frame parallel decoding mode
authorDeb Mukherjee <debargha@google.com>
Fri, 25 Jan 2013 19:30:28 +0000 (11:30 -0800)
committerDeb Mukherjee <debargha@google.com>
Sat, 26 Jan 2013 01:16:19 +0000 (17:16 -0800)
Adds a flag to disable features that would inhibit frame parallel
decoding. This includes backward adaptation and MV sorting based
on search in ref frame buffer.

Also includes some minor clean-ups.

Change-Id: I434846717a47b7bcb244b37ea670c5cdf776f14d

vp8/vp8_cx_iface.c
vp9/common/vp9_onyx.h
vp9/common/vp9_onyxc_int.h
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_rdopt.c
vp9/vp9_cx_iface.c
vpx/vpx_encoder.h
vpxenc.c

index b985cb1b7fa88def67d7fdef3e1e658e809b6701..0b58b0eaae809272ec0dd99d3be2f12370aa80cc 100644 (file)
@@ -1238,6 +1238,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
         {1, 30},            /* g_timebase */
 
         0,                  /* g_error_resilient */
+        0,                  /* g_frame_parallel_decoding */
 
         VPX_RC_ONE_PASS,    /* g_pass */
 
index 46ae2f0f44f21690baffccd24c7a911aa764aa15..d757c398ebf781fd7d6145ddb04b1556cf08fadd 100644 (file)
@@ -165,6 +165,12 @@ extern "C"
      */
     unsigned int error_resilient_mode;
 
+    /* Bitfield defining the parallel decoding mode where the
+     * decoding in successive frames may be conducted in parallel
+     * just by decoding the frame headers.
+     */
+    unsigned int frame_parallel_decoding_mode;
+
     int arnr_max_frames;
     int arnr_strength;
     int arnr_type;
index 4e2fa379922d05b0d3fbe36f169be22fa7cb5d52..cbabfa3da6e967d2be969455b3214dc898d1c4ba 100644 (file)
@@ -277,6 +277,7 @@ typedef struct VP9Common {
 #endif
 
   int error_resilient_mode;
+  int frame_parallel_decoding_mode;
 } VP9_COMMON;
 
 static int get_free_fb(VP9_COMMON *cm) {
index 31ae257dc3a183def4b89eb1d5c3b98c55b7f899..76fb817dfd88c11e3c7cfc008a4e83f188482fa5 100644 (file)
@@ -791,7 +791,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 
       if (mbmi->mode != ZEROMV) {
         vp9_find_best_ref_mvs(xd,
-                              pbi->common.error_resilient_mode ?
+                              pbi->common.error_resilient_mode ||
+                              pbi->common.frame_parallel_decoding_mode ?
                               0 : xd->pre.y_buffer,
                               recon_y_stride,
                               mbmi->ref_mvs[ref_frame],
@@ -851,7 +852,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 
         if (mbmi->mode != ZEROMV) {
           vp9_find_best_ref_mvs(xd,
-                                pbi->common.error_resilient_mode ?
+                                pbi->common.error_resilient_mode ||
+                                pbi->common.frame_parallel_decoding_mode ?
                                 0 : xd->second_pre.y_buffer,
                                 recon_y_stride,
                                 mbmi->ref_mvs[mbmi->second_ref_frame],
index 10bcbf953002851db23276c06803bb6b59a3ce9b..936251a6adb3157fc7f344dd034a99b0b486036a 100644 (file)
@@ -1624,7 +1624,13 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
     vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
   }
 
-  pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
+  if (!pc->error_resilient_mode) {
+    pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
+    pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
+  } else {
+    pc->refresh_entropy_probs = 0;
+    pc->frame_parallel_decoding_mode = 1;
+  }
   pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
   vpx_memcpy(&pc->fc, &pc->frame_contexts[pc->frame_context_idx],
              sizeof(pc->fc));
@@ -1771,10 +1777,12 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
                          "A stream must start with a complete key frame");
   }
 
-  if (!pc->error_resilient_mode)
+  if (!pc->error_resilient_mode &&
+      !pc->frame_parallel_decoding_mode)
     vp9_adapt_coef_probs(pc);
   if (pc->frame_type != KEY_FRAME) {
-    if (!pc->error_resilient_mode) {
+    if (!pc->error_resilient_mode &&
+        !pc->frame_parallel_decoding_mode) {
       vp9_adapt_mode_probs(pc);
       vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
       vp9_adapt_mode_context(&pbi->common);
index 34d27d1beb2fe846078c04a4aa1f31a21bc86e30..23a5b93c57acc7c2811c8ea918a2a3791a3e8f7e 100644 (file)
@@ -1833,7 +1833,11 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
 #endif
   }
 
-  vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+  if (!pc->error_resilient_mode) {
+    vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
+    vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
+  }
+
   vp9_write_literal(&header_bc, pc->frame_context_idx,
                     NUM_FRAME_CONTEXTS_LG2);
 
@@ -2023,9 +2027,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
      * final packing pass */
     // if (!cpi->dummy_packing) vp9_zero(cpi->NMVcount);
     write_modes(cpi, &residual_bc);
-
-    if (!cpi->common.error_resilient_mode)
-      vp9_adapt_mode_context(&cpi->common);
   }
 
   vp9_stop_encode(&residual_bc);
index a14165752bb73b28ff7991c7e00a310666222ffe..d1c48e14cbc39d9289cfd23cfb2f08dbecad5fdf 100644 (file)
@@ -2824,6 +2824,12 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
     }
 
     cm->error_resilient_mode = (cpi->oxcf.error_resilient_mode != 0);
+    cm->frame_parallel_decoding_mode =
+      (cpi->oxcf.frame_parallel_decoding_mode != 0);
+    if (cm->error_resilient_mode) {
+      cm->frame_parallel_decoding_mode = 1;
+      cm->refresh_entropy_probs = 0;
+    }
   }
 
   // Test code for new segment features
@@ -3449,7 +3455,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   vp9_copy(cpi->common.fc.hybrid_coef_counts_16x16,
            cpi->hybrid_coef_counts_16x16);
   vp9_copy(cpi->common.fc.coef_counts_32x32, cpi->coef_counts_32x32);
-  if (!cpi->common.error_resilient_mode)
+  if (!cpi->common.error_resilient_mode &&
+      !cpi->common.frame_parallel_decoding_mode)
     vp9_adapt_coef_probs(&cpi->common);
   if (cpi->common.frame_type != KEY_FRAME) {
     vp9_copy(cpi->common.fc.sb_ymode_counts, cpi->sb_ymode_count);
@@ -3462,12 +3469,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
 #if CONFIG_COMP_INTERINTRA_PRED
     vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
 #endif
-    if (!cpi->common.error_resilient_mode)
-      vp9_adapt_mode_probs(&cpi->common);
-
     cpi->common.fc.NMVcount = cpi->NMVcount;
-    if (!cpi->common.error_resilient_mode)
+    if (!cpi->common.error_resilient_mode &&
+        !cpi->common.frame_parallel_decoding_mode) {
+      vp9_adapt_mode_probs(&cpi->common);
+      vp9_adapt_mode_context(&cpi->common);
       vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
+    }
   }
 #if CONFIG_COMP_INTERINTRA_PRED
   if (cm->frame_type != KEY_FRAME)
index 8710475bda53b9cb2b15c5cd243dde7de2d23c70..2f52f02972a1c119412078aa4e81b8f1d6840da1 100644 (file)
@@ -3179,7 +3179,8 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
 
   // Candidate refinement carried out at encoder and decoder
   vp9_find_best_ref_mvs(xd,
-                        cpi->common.error_resilient_mode ?
+                        cpi->common.error_resilient_mode ||
+                        cpi->common.frame_parallel_decoding_mode ?
                         0 : y_buffer[frame_type],
                         yv12->y_stride,
                         mbmi->ref_mvs[frame_type],
index 0c82d067cec3ac5e39a25df0bcd198acb68858dc..75df0e0372248e4239b54596479897306db7e2f0 100644 (file)
@@ -314,6 +314,7 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
 #endif
 
   oxcf->error_resilient_mode = cfg.g_error_resilient;
+  oxcf->frame_parallel_decoding_mode = cfg.g_frame_parallel_decoding;
   /*
   printf("Current VP9 Settings: \n");
   printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
@@ -342,6 +343,8 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
   printf("Version: %d\n", oxcf->Version);
   printf("encode_breakout: %d\n", oxcf->encode_breakout);
   printf("error resilient: %d\n", oxcf->error_resilient_mode);
+  printf("frame parallel detokenization: %d\n",
+         oxcf->frame_parallel_decoding_mode);
   */
   return VPX_CODEC_OK;
 }
@@ -1034,6 +1037,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = {
       {1, 30},            /* g_timebase */
 
       0,                  /* g_error_resilient */
+      0,                  /* g_frame_parallel_decoding */
 
       VPX_RC_ONE_PASS,    /* g_pass */
 
index ffdbc0644f794b157edf597715f8efc138e0f21a..2ec09bdd4b2b25a956c6b8231b14bff06e8849a0 100644 (file)
@@ -334,6 +334,12 @@ extern "C" {
      */
     vpx_codec_er_flags_t   g_error_resilient;
 
+    /*!\brief Enable frame parallel decoding mode
+     * This value should be 1 to encode in a way that enables frame parallel
+     * decoding. Otherwise make it 0.
+     */
+    unsigned int           g_frame_parallel_decoding;
+
 
     /*!\brief Multi-pass Encoding Mode
      *
index d53d9db57a32f7c63844f5df3a3152510c4d5654..e6f935174fccc0a13119f5923254530160c3b8a7 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -993,12 +993,20 @@ static const arg_def_t timebase         = ARG_DEF(NULL, "timebase", 1,
                                                   "Output timestamp precision (fractional seconds)");
 static const arg_def_t error_resilient  = ARG_DEF(NULL, "error-resilient", 1,
                                                   "Enable error resiliency features");
+#if CONFIG_VP9_ENCODER
+static const arg_def_t frame_parallel_decoding  = ARG_DEF(
+    NULL, "frame-parallel", 1, "Enable frame parallel decodability features");
+#endif
 static const arg_def_t lag_in_frames    = ARG_DEF(NULL, "lag-in-frames", 1,
                                                   "Max number of frames to lag");
 
 static const arg_def_t *global_args[] = {
   &use_yv12, &use_i420, &usage, &threads, &profile,
-  &width, &height, &stereo_mode, &timebase, &framerate, &error_resilient,
+  &width, &height, &stereo_mode, &timebase, &framerate,
+  &error_resilient,
+#if CONFIG_VP9_ENCODER
+  &frame_parallel_decoding,
+#endif
   &lag_in_frames, NULL
 };
 
@@ -1882,6 +1890,10 @@ static int parse_stream_params(struct global_config *global,
       validate_positive_rational(arg.name, &config->cfg.g_timebase);
     } else if (arg_match(&arg, &error_resilient, argi))
       config->cfg.g_error_resilient = arg_parse_uint(&arg);
+#if CONFIG_VP9_ENCODER
+    else if (arg_match(&arg, &frame_parallel_decoding, argi))
+      config->cfg.g_frame_parallel_decoding = arg_parse_uint(&arg);
+#endif
     else if (arg_match(&arg, &lag_in_frames, argi))
       config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
     else if (arg_match(&arg, &dropframe_thresh, argi))
@@ -2062,6 +2074,9 @@ static void show_stream_config(struct stream_state  *stream,
   SHOW(g_timebase.num);
   SHOW(g_timebase.den);
   SHOW(g_error_resilient);
+#if CONFIG_VP9_ENCODER
+  SHOW(g_frame_parallel_decoding);
+#endif
   SHOW(g_pass);
   SHOW(g_lag_in_frames);
   SHOW(rc_dropframe_thresh);