Merging robust and nodesync
authorLuc Trudeau <ltrudeau@mozilla.com>
Tue, 7 Mar 2017 02:56:53 +0000 (21:56 -0500)
committerLuc Trudeau <ltrudeau@mozilla.com>
Tue, 7 Mar 2017 15:46:10 +0000 (10:46 -0500)
The variables robust and nodesync appear to represent the same concept.
In order to simplify, they are merged into nodesync. This change does
not alter the bitstream.

src/decode.c
src/encode.c
src/pvq_decoder.c
src/pvq_encoder.c
src/pvq_encoder.h

index 8f69379..65661a2 100644 (file)
@@ -496,10 +496,12 @@ static void od_block_decode(daala_dec_ctx *dec, od_mb_dec_ctx *ctx, int bs,
   int quant;
   int dc_quant;
   int use_activity_masking;
+  int is_keyframe;
   OD_ASSERT(bs >= 0 && bs < OD_NBSIZES);
   n = 1 << (bs + 2);
   lossless = OD_LOSSLESS(dec);
   use_activity_masking = ctx->use_activity_masking;
+  is_keyframe = ctx->is_keyframe;
   bx <<= bs;
   by <<= bs;
   xdec = dec->state.info.plane_info[pli].xdec;
@@ -511,7 +513,7 @@ static void od_block_decode(daala_dec_ctx *dec, od_mb_dec_ctx *ctx, int bs,
   md = ctx->md;
   mc = ctx->mc;
   /*Apply forward transform to MC predictor.*/
-  if (!ctx->is_keyframe) {
+  if (!is_keyframe) {
     if (ctx->use_haar_wavelet) {
       od_haar(md + bo, w, mc + bo, w, bs + 2);
     }
@@ -531,7 +533,7 @@ static void od_block_decode(daala_dec_ctx *dec, od_mb_dec_ctx *ctx, int bs,
   }
   else {
     /*Safely initialize d since some coeffs are skipped by PVQ.*/
-    od_init_skipped_coeffs(d, pred, ctx->is_keyframe, bo, n, w);
+    od_init_skipped_coeffs(d, pred, is_keyframe, bo, n, w);
     od_raster_to_coding_order(predt,  n, &pred[0], n);
   }
   quant = OD_MAXI(1, dec->state.quantizer);
@@ -547,19 +549,22 @@ static void od_block_decode(daala_dec_ctx *dec, od_mb_dec_ctx *ctx, int bs,
   else {
     unsigned int flags;
     int off;
+    int nodesync;
+    /*We always use the robust bitstream for keyframes to avoid having
+      PVQ and entropy decoding depending on each other, hurting parallelism.*/
+    nodesync = OD_ROBUST_STREAM || is_keyframe;
     off = od_qm_offset(bs, xdec);
     od_pvq_decode(dec, predt, pred, quant, pli, bs,
-     OD_PVQ_BETA[use_activity_masking][pli][bs], OD_ROBUST_STREAM,
-     ctx->is_keyframe, &flags, skip, dec->state.qm + off,
-     dec->state.qm_inv + off);
+     OD_PVQ_BETA[use_activity_masking][pli][bs], nodesync, is_keyframe,
+     &flags, skip, dec->state.qm + off, dec->state.qm_inv + off);
 
     if (pli == 0 && dec->user_flags != NULL) {
       dec->user_flags[by*dec->user_fstride + bx] = flags;
     }
   }
-  if (!ctx->is_keyframe) {
+  if (!is_keyframe) {
     int has_dc_skip;
-    has_dc_skip = !ctx->is_keyframe && !ctx->use_haar_wavelet;
+    has_dc_skip = !is_keyframe && !ctx->use_haar_wavelet;
     if (!has_dc_skip || pred[0]) {
       pred[0] = has_dc_skip + generic_decode(&dec->ec,
        &dec->state.adapt.model_dc[pli], -1,
index 25f4c43..87cc2ab 100644 (file)
@@ -1233,6 +1233,7 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   int bo;
   int frame_width;
   int use_masking;
+  int is_keyframe;
   od_coeff *c;
   od_coeff *d;
   od_coeff *md;
@@ -1265,6 +1266,7 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   xdec = enc->state.info.plane_info[pli].xdec;
   frame_width = enc->state.frame_width;
   use_masking = enc->use_activity_masking;
+  is_keyframe = ctx->is_keyframe;
   w = frame_width >> xdec;
   bo = (by << 2)*w + (bx << 2);
   c = ctx->c;
@@ -1274,7 +1276,7 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   lossless = OD_LOSSLESS(enc);
   c_orig = enc->block_c_orig;
   mc_orig = enc->block_mc_orig;
-  has_late_skip_rdo = !ctx->is_keyframe && !ctx->use_haar_wavelet && bs > 0;
+  has_late_skip_rdo = !is_keyframe && !ctx->use_haar_wavelet && bs > 0;
   if (has_late_skip_rdo) {
     for (i = 0; i < n; i++) {
       for (j = 0; j < n; j++) c_orig[n*i + j] = c[bo + i*w + j];
@@ -1287,21 +1289,21 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   }
   /* Apply forward transform. */
   if (ctx->use_haar_wavelet) {
-    if (rdo_only || !ctx->is_keyframe) {
+    if (rdo_only || !is_keyframe) {
       od_haar(d + bo, w, c + bo, w, bs + 2);
     }
-    if (!ctx->is_keyframe) {
+    if (!is_keyframe) {
       od_haar(md + bo, w, mc + bo, w, bs + 2);
     }
   }
   else {
-    if (rdo_only || !ctx->is_keyframe) {
+    if (rdo_only || !is_keyframe) {
       int quantized_dc;
       quantized_dc = d[bo];
       (*enc->state.opt_vtbl.fdct_2d[bs])(d + bo, w, c + bo, w);
-      if (ctx->is_keyframe) d[bo] = quantized_dc;
+      if (is_keyframe) d[bo] = quantized_dc;
     }
-    if (!ctx->is_keyframe) {
+    if (!is_keyframe) {
       (*enc->state.opt_vtbl.fdct_2d[bs])(md + bo, w, mc + bo, w);
     }
   }
@@ -1331,7 +1333,7 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
      enc->state.pvq_qm_q4[pli][od_qm_get_index(bs, 0)] >> 4);
   }
   /* This quantization may be overridden in the PVQ code for full RDO. */
-  if (!ctx->is_keyframe) {
+  if (!is_keyframe) {
     if (abs(dblock[0] - predt[0]) < dc_quant*141/256) { /* 0.55 */
       scalar_out[0] = 0;
     }
@@ -1345,15 +1347,19 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   }
   else {
     int off;
+    int nodesync;
+    /*We always use the robust bitstream for keyframes to avoid having
+      PVQ and entropy decoding depending on each other, hurting parallelism.*/
+    nodesync = OD_ROBUST_STREAM || is_keyframe;
     off = od_qm_offset(bs, xdec);
     skip = od_pvq_encode(enc, predt, dblock, scalar_out, quant, pli, bs,
-     OD_PVQ_BETA[use_masking][pli][bs], OD_ROBUST_STREAM, ctx->is_keyframe,
-     ctx->q_scaling, bx, by, enc->state.qm + off, enc->state.qm_inv
-     + off, rdo_only && enc->complexity < 5 ? 1 : 0);
+     OD_PVQ_BETA[use_masking][pli][bs], nodesync, is_keyframe, ctx->q_scaling,
+     bx, by, enc->state.qm + off, enc->state.qm_inv + off,
+     rdo_only && enc->complexity < 5 ? 1 : 0);
   }
-  if (!ctx->is_keyframe) {
+  if (!is_keyframe) {
     int has_dc_skip;
-    has_dc_skip = !ctx->is_keyframe && !ctx->use_haar_wavelet;
+    has_dc_skip = !is_keyframe && !ctx->use_haar_wavelet;
     if (!has_dc_skip || scalar_out[0]) {
       generic_encode(&enc->ec, &enc->state.adapt.model_dc[pli],
        abs(scalar_out[0]) - has_dc_skip, -1,
@@ -1378,7 +1384,7 @@ static int od_block_encode(daala_enc_ctx *enc, od_mb_enc_ctx *ctx, int bs,
   }
   else {
     /*Safely initialize d since some coeffs are skipped by PVQ.*/
-    od_init_skipped_coeffs(d, pred, ctx->is_keyframe, bo, n, w);
+    od_init_skipped_coeffs(d, pred, is_keyframe, bo, n, w);
     od_coding_order_to_raster(&d[bo], w, scalar_out, n);
   }
   /*Apply the inverse transform.*/
index 6c1ecd9..9dfeb5d 100644 (file)
@@ -108,7 +108,7 @@ typedef struct {
  * @param [out]    out     decoded partition
  * @param [out]    noref   boolean indicating absence of reference
  * @param [in]     beta    per-band activity masking beta param
- * @param [in]     robust  stream is robust to error in the reference
+ * @param [in]     nodesync do not use info that depends on the reference
  * @param [in]     is_keyframe whether we're encoding a keyframe
  * @param [in]     pli     plane index
  * @param [in]     cdf_ctx selects which cdf context to use
@@ -130,7 +130,7 @@ static void pvq_decode_partition(od_ec_dec *ec,
                                  od_coeff *out,
                                  int *noref,
                                  od_val16 beta,
-                                 int robust,
+                                 int nodesync,
                                  int is_keyframe,
                                  int pli,
                                  int cdf_ctx,
@@ -150,7 +150,6 @@ static void pvq_decode_partition(od_ec_dec *ec,
   od_val32 gain_offset;
   od_coeff y[MAXN];
   int qg;
-  int nodesync;
   int id;
   int i;
   od_val16 ref16[MAXN];
@@ -158,9 +157,6 @@ static void pvq_decode_partition(od_ec_dec *ec,
   theta = 0;
   gr = 0;
   gain_offset = 0;
-  /* We always use the robust bitstream for keyframes to avoid having
-     PVQ and entropy decoding depending on each other, hurting parallelism. */
-  nodesync = robust || is_keyframe;
   /* Skip is per-direction. For band=0, we can use any of the flags. */
   if (skip_rest[(band + 2) % 3]) {
     qg = 0;
@@ -294,7 +290,7 @@ static void pvq_decode_partition(od_ec_dec *ec,
  * @param [in]     pli     plane index
  * @param [in]     bs      log of the block size minus two
  * @param [in]     beta    per-band activity masking beta param
- * @param [in]     robust  stream is robust to error in the reference
+ * @param [in]     nodesync do not use info that depends on the reference
  * @param [in]     is_keyframe whether we're encoding a keyframe
  * @param [out]    flags   bitmask of the per band skip and noref flags
  * @param [in]     block_skip skip flag for the block (range 0-3)
@@ -308,7 +304,7 @@ void od_pvq_decode(daala_dec_ctx *dec,
                    int pli,
                    int bs,
                    const od_val16 *beta,
-                   int robust,
+                   int nodesync,
                    int is_keyframe,
                    unsigned int *flags,
                    int block_skip,
@@ -354,12 +350,12 @@ void od_pvq_decode(daala_dec_ctx *dec,
     for (i = 0; i < nb_bands; i++) {
       int q;
       q = OD_MAXI(1, q0*pvq_qm[od_qm_get_index(bs, i + 1)] >> 4);
-      pvq_decode_partition(&dec->ec, q, size[i],
-       model, &dec->state.adapt, exg + i, ext + i, ref + off[i], out + off[i],
-       &noref[i], beta[i], robust, is_keyframe, pli,
+      pvq_decode_partition(&dec->ec, q, size[i], model, &dec->state.adapt,
+       exg + i, ext + i, ref + off[i], out + off[i], &noref[i], beta[i],
+       nodesync, is_keyframe, pli,
        (pli != 0)*OD_NBSIZES*PVQ_MAX_PARTITIONS + bs*PVQ_MAX_PARTITIONS + i,
-       &cfl, i == 0 && (i < nb_bands - 1), skip_rest, i, &skip[i],
-       qm + off[i], qm_inv + off[i]);
+       &cfl, i == 0 && (i < nb_bands - 1), skip_rest, i, &skip[i], qm + off[i],
+       qm_inv + off[i]);
       if (i == 0 && !skip_rest[0] && bs > 0) {
         int skip_dir;
         int j;
index 5b0b760..99af60e 100644 (file)
@@ -320,7 +320,7 @@ int items_compare(pvq_search_item *a, pvq_search_item *b) {
  * @param [in]     beta      per-band activity masking beta param
  * @param [out]    skip_diff distortion cost of skipping this block
  *                           (accumulated)
- * @param [in]     robust    make stream robust to error in the reference
+ * @param [in]     nodesync  do not use info that depends on the reference
  * @param [in]     is_keyframe whether we're encoding a keyframe
  * @param [in]     pli       plane index
  * @param [in]     adapt     probability adaptation context
@@ -332,7 +332,7 @@ int items_compare(pvq_search_item *a, pvq_search_item *b) {
 */
 static int pvq_theta(od_coeff *out, const od_coeff *x0, const od_coeff *r0,
  int n, int q0, od_coeff *y, int *itheta, int *max_theta, int *vk,
- od_val16 beta, double *skip_diff, int robust, int is_keyframe, int pli,
+ od_val16 beta, double *skip_diff, int nodesync, int is_keyframe, int pli,
  const od_adapt_ctx *adapt, const int16_t *qm,
  const int16_t *qm_inv, double pvq_norm_lambda, int speed) {
   od_val32 g;
@@ -486,7 +486,7 @@ static int pvq_theta(od_coeff *out, const od_coeff *x0, const od_coeff *r0,
       for (j = theta_lower; j <= theta_upper; j++) {
         od_val32 qtheta;
         qtheta = od_pvq_compute_theta(j, ts);
-        k = od_pvq_compute_k(qcg, j, qtheta, 0, n, beta, robust || is_keyframe);
+        k = od_pvq_compute_k(qcg, j, qtheta, 0, n, beta, nodesync);
         items[idx].gain = i;
         items[idx].theta = j;
         items[idx].k = k;
@@ -580,7 +580,7 @@ static int pvq_theta(od_coeff *out, const od_coeff *x0, const od_coeff *r0,
       double cost;
       od_val32 qcg;
       qcg = OD_SHL(i, OD_CGAIN_SHIFT);
-      k = od_pvq_compute_k(qcg, -1, -1, 1, n, beta, robust || is_keyframe);
+      k = od_pvq_compute_k(qcg, -1, -1, 1, n, beta, nodesync);
       /* Compute the minimal possible distortion by not taking the PVQ
          cos_dist into account. */
       dist = gain_weight*(qcg - cg)*(qcg - cg);
@@ -775,7 +775,7 @@ void od_encode_quantizer_scaling(daala_enc_ctx *enc, int q_scaling,
  * @param [in]     pli     plane index
  * @param [in]     bs      log of the block size minus two
  * @param [in]     beta    per-band activity masking beta param
- * @param [in]     robust  make stream robust to error in the reference
+ * @param [in]     nodesync do not use info that depends on the reference
  * @param [in]     is_keyframe whether we're encoding a keyframe
  * @param [in]     q_scaling scaling factor to apply to quantizer
  * @param [in]     bx      x-coordinate of this block
@@ -794,7 +794,7 @@ int od_pvq_encode(daala_enc_ctx *enc,
                    int pli,
                    int bs,
                    const od_val16 *beta,
-                   int robust,
+                   int nodesync,
                    int is_keyframe,
                    int q_scaling,
                    int bx,
@@ -874,7 +874,7 @@ int od_pvq_encode(daala_enc_ctx *enc,
     q = OD_MAXI(1, q0*pvq_qm[od_qm_get_index(bs, i + 1)] >> 4);
     qg[i] = pvq_theta(out + off[i], in + off[i], ref + off[i], size[i],
      q, y + off[i], &theta[i], &max_theta[i],
-     &k[i], beta[i], &skip_diff, robust, is_keyframe, pli,
+     &k[i], beta[i], &skip_diff, nodesync, is_keyframe, pli,
      &enc->state.adapt, qm + off[i], qm_inv + off[i], enc->pvq_norm_lambda,
      speed);
   }
@@ -922,7 +922,7 @@ int od_pvq_encode(daala_enc_ctx *enc,
     if (i == 0 || (!skip_rest && !(skip_dir & (1 << ((i - 1)%3))))) {
       pvq_encode_partition(&enc->ec, qg[i], theta[i], max_theta[i], y + off[i],
        size[i], k[i], model, &enc->state.adapt, exg + i, ext + i,
-       robust || is_keyframe, (pli != 0)*OD_NBSIZES*PVQ_MAX_PARTITIONS
+       nodesync, (pli != 0)*OD_NBSIZES*PVQ_MAX_PARTITIONS
        + bs*PVQ_MAX_PARTITIONS + i, is_keyframe, i == 0 && (i < nb_bands - 1),
        skip_rest, encode_flip, flip);
     }
index a1718d0..9a00770 100644 (file)
@@ -44,7 +44,7 @@ void od_encode_quantizer_scaling(daala_enc_ctx *enc, int q_scaling, int bx,
 #endif
 
 int od_pvq_encode(daala_enc_ctx *enc, od_coeff *ref, const od_coeff *in,
- od_coeff *out, int q0, int pli, int bs, const od_val16 *beta, int robust,
+ od_coeff *out, int q0, int pli, int bs, const od_val16 *beta, int nodesync,
  int is_keyframe, int q_scaling, int bx, int by, const int16_t *qm,
  const int16_t *qm_inv, int speed);