]> granicus.if.org Git - libvpx/commitdiff
changes intra coding to be based on txfm block
authorYaowu Xu <yaowu@google.com>
Fri, 17 May 2013 19:50:40 +0000 (12:50 -0700)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 22 May 2013 10:53:19 +0000 (11:53 +0100)
This commit changed the encoding and decoding of intra blocks to be
based on transform block. In each prediction block, the intra coding
iterates thorough each transform block based on raster scan order.

This commit also fixed a bug in D135 prediction code.

TODO next:
The RD mode/txfm_size selection should take this into account when
computing RD values.

Change-Id: I6d1be2faa4c4948a52e830b6a9a84a6b2b6850f6

vp9/common/vp9_blockd.h
vp9/common/vp9_reconintra.c
vp9/common/vp9_reconintra.h
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodframe.c
vp9/decoder/vp9_onyxd_if.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodeintra.h
vp9/encoder/vp9_encodemb.c
vp9/encoder/vp9_onyx_if.c

index 71d1dd9343b3edccee7aee2e9324546bc4736ee8..f1722fd72315312f78970517a641fa602adf0e25 100644 (file)
@@ -192,6 +192,7 @@ static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) {
     case BLOCK_SIZE_SB64X32:
     case BLOCK_SIZE_SB64X64: return 4;
     default: assert(0);
+      return -1;
   }
 }
 
@@ -215,6 +216,7 @@ static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) {
     case BLOCK_SIZE_SB32X64:
     case BLOCK_SIZE_SB64X64: return 4;
     default: assert(0);
+      return -1;
   }
 }
 
index 1588f33cef17de052aba709c82bd0c4270ed05c0..dd60a76c7ac5cc358c87acd4835c12ffb2b7b3f6 100644 (file)
@@ -138,14 +138,10 @@ static void d135_predictor(uint8_t *ypred_ptr, int y_stride,
   ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] +
                                            yleft_col[0] * 2 +
                                            yleft_col[1], 2);
-  for (r = 2; r < bh - 1; ++r)
+  for (r = 2; r < bh; ++r)
     ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] +
                                                  yleft_col[r - 1] * 2 +
-                                                 yleft_col[r + 1], 2);
-
-  ypred_ptr[(bh - 1) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] +
-                                                      yleft_col[bh - 1] * 3,
-                                                      2);
+                                                 yleft_col[r], 2);
 
   ypred_ptr += y_stride;
   for (r = 1; r < bh; ++r) {
@@ -396,11 +392,11 @@ void vp9_build_intra_predictors_sbuv_s(MACROBLOCKD *xd,
 
 void vp9_predict_intra_block(MACROBLOCKD *xd,
                             int block_idx,
-                            BLOCK_SIZE_TYPE bsize,
+                            int bwl_in,
                             TX_SIZE tx_size,
                             int mode,
                             uint8_t *predictor, int pre_stride) {
-  const int bwl = b_width_log2(bsize) - tx_size;
+  const int bwl = bwl_in - tx_size;
   const int wmask = (1 << bwl) - 1;
   const int have_top =
       (block_idx >> bwl) || xd->up_available;
@@ -424,6 +420,6 @@ void vp9_intra4x4_predict(MACROBLOCKD *xd,
                           BLOCK_SIZE_TYPE bsize,
                           int mode,
                           uint8_t *predictor, int pre_stride) {
-  vp9_predict_intra_block(xd, block_idx, bsize, TX_4X4,
+  vp9_predict_intra_block(xd, block_idx, b_width_log2(bsize), TX_4X4,
                           mode, predictor, pre_stride);
 }
index faecd6be73565165603c61a3e55848bbdc51314b..b88761b023fd9387f6b3bd353a38eb1dd940bdab 100644 (file)
@@ -23,7 +23,7 @@ B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block,
 
 void vp9_predict_intra_block(MACROBLOCKD *xd,
                             int block_idx,
-                            BLOCK_SIZE_TYPE bsize,
+                            int bwl_in,
                             TX_SIZE tx_size,
                             int mode,
                             uint8_t *predictor, int pre_stride);
index ac66fb6442c4c88eb06104e2615afff199fb5fd3..1ddd21c120938a44238ca6de57f7427900aec3ea 100644 (file)
@@ -154,11 +154,11 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
   m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]);
 
   if (cm->txfm_mode == TX_MODE_SELECT &&
-      !m->mbmi.mb_skip_coeff &&
+    !(m->mbmi.mb_skip_coeff && m->mbmi.ref_frame != INTRA_FRAME)
 #if CONFIG_AB4X4
-      m->mbmi.sb_type >= BLOCK_SIZE_SB8X8
+      && m->mbmi.sb_type >= BLOCK_SIZE_SB8X8
 #else
-      m->mbmi.mode != I4X4_PRED
+      && m->mbmi.mode != I4X4_PRED
 #endif
       ) {
     const int allow_16x16 = m->mbmi.sb_type >= BLOCK_SIZE_MB16X16;
@@ -880,7 +880,8 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
   if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
       bsize >= BLOCK_SIZE_SB8X8) {
 #else
-  if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
+  if (cm->txfm_mode == TX_MODE_SELECT &&
+      (mbmi->mb_skip_coeff == 0 || mbmi->ref_frame == INTRA_FRAME) &&
       ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode != I4X4_PRED) ||
        (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) {
 #endif
index 449e4269ef81e1e583f770f6b9b1d707ea1b4151..eea7658a88005db1335e13b15746cc662ffaa5e6 100644 (file)
@@ -239,6 +239,59 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
   }
 }
 
+static void decode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
+                               int ss_txfrm_size, void *arg) {
+  MACROBLOCKD* const xd = arg;
+  int16_t* const qcoeff = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16);
+  const int stride = xd->plane[plane].dst.stride;
+  const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
+                                                       block, ss_txfrm_size);
+  uint8_t* const dst = raster_block_offset_uint8(xd, bsize, plane,
+                                                 raster_block,
+                                                 xd->plane[plane].dst.buf,
+                                                 stride);
+  const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2);
+  TX_TYPE tx_type;
+  int mode, b_mode;
+  int plane_b_size;
+  int tx_ib = raster_block >> tx_size;
+  mode = plane == 0? xd->mode_info_context->mbmi.mode:
+                     xd->mode_info_context->mbmi.uv_mode;
+
+  if (bsize <= BLOCK_SIZE_SB8X8 && mode == I4X4_PRED && plane == 0)
+    b_mode = xd->mode_info_context->bmi[raster_block].as_mode.first;
+  else
+    b_mode = mode;
+
+  plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x;
+  vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size,
+                          b_mode, dst, xd->plane[plane].dst.stride);
+
+  switch (ss_txfrm_size / 2) {
+    case TX_4X4:
+      tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT;
+      if (tx_type == DCT_DCT)
+        xd->itxm_add(qcoeff, dst, stride, xd->plane[plane].eobs[block]);
+      else
+        vp9_iht_add_c(tx_type, qcoeff, dst, stride,
+                      xd->plane[plane].eobs[block]);
+      break;
+    case TX_8X8:
+      tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT;
+      vp9_iht_add_8x8_c(tx_type, qcoeff, dst, stride,
+                        xd->plane[plane].eobs[block]);
+      break;
+    case TX_16X16:
+      tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT;
+      vp9_iht_add_16x16_c(tx_type, qcoeff, dst, stride,
+                          xd->plane[plane].eobs[block]);
+      break;
+    case TX_32X32:
+      vp9_idct_add_32x32(qcoeff, dst, stride, xd->plane[plane].eobs[block]);
+      break;
+  }
+}
+
 static void decode_atom_intra(VP9D_COMP *pbi, MACROBLOCKD *xd,
                               vp9_reader *r,
                               BLOCK_SIZE_TYPE bsize) {
@@ -295,6 +348,26 @@ static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd,
     foreach_transformed_block(xd, bsize, decode_block, xd);
 }
 
+static void decode_sb_intra(VP9D_COMP *pbi, MACROBLOCKD *xd,
+                          int mi_row, int mi_col,
+                          vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
+  MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
+  if (mbmi->mb_skip_coeff) {
+    vp9_reset_sb_tokens_context(xd, bsize);
+  } else {
+    // re-initialize macroblock dequantizer before detokenization
+    if (xd->segmentation_enabled)
+      mb_init_dequantizer(&pbi->common, xd);
+
+    if (!vp9_reader_has_error(r)) {
+      vp9_decode_tokens(pbi, xd, r, bsize);
+    }
+  }
+
+  foreach_transformed_block(xd, bsize, decode_block_intra, xd);
+}
+
+
 static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col,
                       vp9_reader *r, BLOCK_SIZE_TYPE bsize) {
   const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize);
@@ -422,12 +495,13 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
   vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r);
   set_refs(pbi, mi_row, mi_col);
 
+  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
+    decode_sb_intra(pbi, xd, mi_row, mi_col, r, bsize);
 #if CONFIG_AB4X4
-  if (bsize < BLOCK_SIZE_SB8X8)
+  else if (bsize < BLOCK_SIZE_SB8X8)
 #else
-  if (bsize == BLOCK_SIZE_SB8X8 &&
-      (xd->mode_info_context->mbmi.mode == SPLITMV ||
-       xd->mode_info_context->mbmi.mode == I4X4_PRED))
+  else if (bsize == BLOCK_SIZE_SB8X8 &&
+      xd->mode_info_context->mbmi.mode == SPLITMV)
 #endif
     decode_atom(pbi, xd, mi_row, mi_col, r, BLOCK_SIZE_SB8X8);
   else
index 9761bd6f8d2066d3003ae5185be53df0e7aaabf4..5d5a543a3c4f8d88d5428b33e1ed649c39a0e3d2 100644 (file)
@@ -352,6 +352,16 @@ int vp9_receive_compressed_data(VP9D_PTR ptr,
       vp9_loop_filter_frame(cm, &pbi->mb, cm->filter_level, 0,
                             cm->dering_enabled);
     }
+
+#if WRITE_RECON_BUFFER == 2
+    if (cm->show_frame)
+      write_dx_frame_to_file(cm->frame_to_show,
+                             cm->current_video_frame + 2000);
+    else
+      write_dx_frame_to_file(cm->frame_to_show,
+                             cm->current_video_frame + 3000);
+#endif
+
     vp9_extend_frame_borders(cm->frame_to_show,
                              cm->subsampling_x, cm->subsampling_y);
   }
index 88943330f390c88eb582a9386bdf6d0e675a1c5b..9f3268021fc3e3c6427ee237e6daccf19bacf8cf 100644 (file)
@@ -871,8 +871,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m,
   if (((rf == INTRA_FRAME && mode != I4X4_PRED) ||
        (rf != INTRA_FRAME && mode != SPLITMV)) &&
       pc->txfm_mode == TX_MODE_SELECT &&
-      !(skip_coeff || vp9_segfeature_active(xd, segment_id,
-                                            SEG_LVL_SKIP)))
+      !(rf != INTRA_FRAME &&
+        (skip_coeff || vp9_segfeature_active(xd, segment_id,
+                                            SEG_LVL_SKIP))))
 #endif
   {
     TX_SIZE sz = mi->txfm_size;
@@ -941,7 +942,8 @@ static void write_mb_modes_kf(const VP9_COMP *cpi,
       !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
 #else
   if (ym != I4X4_PRED && c->txfm_mode == TX_MODE_SELECT &&
-      !(skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
+    !(m->mbmi.ref_frame != INTRA_FRAME && (skip_coeff ||
+      vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
 #endif
     TX_SIZE sz = m->mbmi.txfm_size;
     // FIXME(rbultje) code ternary symbol once all experiments are merged
index 277f92ce7770996c0aa47882936023257ba71187..73eec565690e3299c900a53bb70f2b1a4ba4caaa 100644 (file)
@@ -1703,19 +1703,14 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
 #if CONFIG_AB4X4
   if (mbmi->ref_frame == INTRA_FRAME &&
       bsize < BLOCK_SIZE_SB8X8) {
-#else
-  if (mbmi->mode == I4X4_PRED) {
-    assert(bsize == BLOCK_SIZE_SB8X8 && mbmi->txfm_size == TX_4X4);
-#endif
-    vp9_encode_intra4x4mby(cm, x, BLOCK_SIZE_SB8X8);
+    vp9_encode_intra_block_y(cm, x, BLOCK_SIZE_SB8X8);
     vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_SB8X8);
     vp9_encode_sbuv(cm, x, BLOCK_SIZE_SB8X8);
-
-    if (output_enabled)
-      sum_intra_stats(cpi, x);
-  } else if (mbmi->ref_frame == INTRA_FRAME) {
-    vp9_build_intra_predictors_sby_s(xd, bsize);
-    vp9_build_intra_predictors_sbuv_s(xd, bsize);
+#else
+  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
+    vp9_encode_intra_block_y(cm, x, bsize);
+    vp9_encode_intra_block_uv(cm, x, bsize);
+#endif
     if (output_enabled)
       sum_intra_stats(cpi, x);
   } else {
@@ -1741,10 +1736,10 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
   if (mbmi->ref_frame == INTRA_FRAME &&
       bsize < BLOCK_SIZE_SB8X8) {
 #else
-  if (mbmi->mode == I4X4_PRED) {
-    assert(bsize == BLOCK_SIZE_SB8X8);
+  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
 #endif
-    vp9_tokenize_sb(cpi, xd, t, !output_enabled, BLOCK_SIZE_SB8X8);
+    vp9_tokenize_sb(cpi, xd, t, !output_enabled,
+                    (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
   } else if (!x->skip) {
     vp9_encode_sb(cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize);
     vp9_tokenize_sb(cpi, xd, t, !output_enabled,
@@ -1771,8 +1766,9 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
 
   if (output_enabled) {
     if (cm->txfm_mode == TX_MODE_SELECT &&
+        (mbmi->ref_frame == INTRA_FRAME ||
         !(mbmi->mb_skip_coeff ||
-          vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP))) {
+          vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) {
       if (bsize >= BLOCK_SIZE_SB32X32) {
         cpi->txfm_count_32x32p[mbmi->txfm_size]++;
       } else if (bsize >= BLOCK_SIZE_MB16X16) {
@@ -1783,18 +1779,23 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
     } else {
       int x, y;
       TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ? TX_32X32 : cm->txfm_mode;
-
-      if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
-        sz = TX_16X16;
-      if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
-        sz = TX_8X8;
+       // The new intra coding scheme requires no change of transform size
+      if (mi->mbmi.ref_frame != INTRA_FRAME) {
+        if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
+          sz = TX_16X16;
+        if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
+          sz = TX_8X8;
 #if CONFIG_AB4X4
-      if (sz == TX_8X8 && bsize < BLOCK_SIZE_SB8X8)
+        if (sz == TX_8X8 && bsize < BLOCK_SIZE_SB8X8)
 #else
-      if (sz == TX_8X8 && (mbmi->mode == SPLITMV ||
-                           mbmi->mode == I4X4_PRED))
+        if (sz == TX_8X8 && mbmi->mode == SPLITMV)
 #endif
+          sz = TX_4X4;
+      } else if (mbmi->mode != I4X4_PRED) {
+        sz = mbmi->txfm_size;
+      } else {
         sz = TX_4X4;
+      }
 
       for (y = 0; y < bh; y++) {
         for (x = 0; x < bw; x++) {
index 22a046e355a21679dc8021f5d13c5e588d9c1059..7da164c6a3da60cc73d8c4e789a0c00189d32d53 100644 (file)
@@ -16,6 +16,9 @@
 int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred);
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x);
 void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x);
-void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *mb,
-                            BLOCK_SIZE_TYPE bs);
+void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *mb,
+                              BLOCK_SIZE_TYPE bs);
+void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *mb,
+                               BLOCK_SIZE_TYPE bs);
+
 #endif  // VP9_ENCODER_VP9_ENCODEINTRA_H_
index d9cd091632fa001857b895c62e2a2fd5b6060476..a4991f21a9b6906c39d2f76577351e4d9d56e37b 100644 (file)
@@ -628,16 +628,23 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
 
   const int txfm_b_size = 4 << tx_size;
   int ib = raster_block;
+  int tx_ib = ib >> tx_size;
+  int plane_b_size;
 
   TX_TYPE tx_type;
+  int mode, b_mode;
 
-  if (tx_size <= TX_16X16)
-    tx_type = txfm_map(xd->mode_info_context->bmi[ib].as_mode.first);
+  mode = plane == 0? xd->mode_info_context->mbmi.mode:
+                     xd->mode_info_context->mbmi.uv_mode;
+  if (bsize <= BLOCK_SIZE_SB8X8 && mode == I4X4_PRED && plane == 0)
+    b_mode = xd->mode_info_context->bmi[ib].as_mode.first;
   else
-    tx_type = DCT_DCT;
+    b_mode = mode;
 
-  vp9_predict_intra_block(&x->e_mbd, ib, bsize, tx_size,
-                          xd->mode_info_context->bmi[ib].as_mode.first,
+  assert(b_mode >= B_DC_PRED && b_mode <= B_TM_PRED);
+
+  plane_b_size = b_width_log2(bsize) - xd->plane[plane].subsampling_x;
+  vp9_predict_intra_block(xd, tx_ib, plane_b_size, tx_size, b_mode,
                           dst, xd->plane[plane].dst.stride);
   vp9_subtract_block(txfm_b_size, txfm_b_size,
                      src_diff, bw,
@@ -650,7 +657,6 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
   if (x->optimize)
     vp9_optimize_b(plane, block, bsize, ss_txfrm_size, args->cm, x, args->ctx);
     */
-
   switch (ss_txfrm_size / 2) {
     case TX_32X32:
         vp9_short_idct32x32_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
@@ -695,8 +701,8 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
   }
 }
 
-void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x,
-                            BLOCK_SIZE_TYPE bsize) {
+void vp9_encode_intra_block_y(VP9_COMMON *const cm, MACROBLOCK *x,
+                              BLOCK_SIZE_TYPE bsize) {
   MACROBLOCKD* const xd = &x->e_mbd;
   struct optimize_ctx ctx;
   struct encode_b_args arg = {cm, x, &ctx};
@@ -704,4 +710,12 @@ void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x,
   foreach_transformed_block_in_plane(xd, bsize, 0,
                                      encode_block_intra, &arg);
 }
+void vp9_encode_intra_block_uv(VP9_COMMON *const cm, MACROBLOCK *x,
+                              BLOCK_SIZE_TYPE bsize) {
+  MACROBLOCKD* const xd = &x->e_mbd;
+  struct optimize_ctx ctx;
+  struct encode_b_args arg = {cm, x, &ctx};
+
+  foreach_transformed_block_uv(xd, bsize, encode_block_intra, &arg);
+}
 
index a8e1a1727783ff89a9308544a5147e5567834b6d..e3c7930ab25c5bfae9cb9fd1858cbd282f062c0a 100644 (file)
@@ -3170,6 +3170,15 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   // Pick the loop filter level for the frame.
   loopfilter_frame(cpi, cm);
 
+#if WRITE_RECON_BUFFER
+  if (cm->show_frame)
+    write_cx_frame_to_file(cm->frame_to_show,
+                           cm->current_video_frame + 2000);
+  else
+    write_cx_frame_to_file(cm->frame_to_show,
+                           cm->current_video_frame + 3000);
+#endif
+
   // build the bitstream
   cpi->dummy_packing = 0;
   vp9_pack_bitstream(cpi, dest, size);