]> granicus.if.org Git - libvpx/commitdiff
Allow large tx_size in lossless coding with transform skipping
authorpunksu <huisu@google.com>
Sat, 20 Dec 2014 06:49:44 +0000 (14:49 +0800)
committerpunksu <huisu@google.com>
Mon, 22 Dec 2014 14:56:52 +0000 (22:56 +0800)
In lossless coding, tx_size can be larger than 4x4 when transform
skipping is activated. Compared to regular vp9 lossless coding,
performance improvement for derf is about 5%; gain is larger
for screen content videos.

Change-Id: Ib20ece7e117f29fb91543612757302a2400110b4

vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_rdopt.c

index 057a622911bbbe984ce71de9c6f7829267de573b..5739cba3e8475c2edcd0600e53ef103d33f18a49 100644 (file)
@@ -2045,7 +2045,9 @@ static void read_supertx_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
 static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
                                   size_t partition_size) {
   VP9_COMMON *const cm = &pbi->common;
+#if !CONFIG_TX_SKIP
   MACROBLOCKD *const xd = &pbi->mb;
+#endif
   FRAME_CONTEXT *const fc = &cm->fc;
   vp9_reader r;
   int k;
@@ -2055,7 +2057,11 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder 0");
 
+#if CONFIG_TX_SKIP
+  cm->tx_mode = read_tx_mode(&r);
+#else
   cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r);
+#endif
   if (cm->tx_mode == TX_MODE_SELECT)
     read_tx_mode_probs(&fc->tx_probs, &r);
   read_coef_probs(fc, cm->tx_mode, &r);
index 9fae177239d6ad46726e06d79b64d3d0e9ecf891..a81894b5ead690c497791eaff7452adc9cafd9c0 100644 (file)
@@ -188,8 +188,22 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
     int q_idx = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex);
     int try_tx_skip = q_idx <= TX_SKIP_Q_THRESH_INTRA;
     if (try_tx_skip) {
-      mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[0]);
-      mbmi->tx_skip[1] = vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      if (xd->lossless) {
+        if (mbmi->tx_size == TX_4X4)
+          mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[0]);
+        else
+          mbmi->tx_skip[0] = 1;
+
+        if (get_uv_tx_size(mbmi, &xd->plane[1]) == TX_4X4)
+          mbmi->tx_skip[1] =
+            vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+        else
+          mbmi->tx_skip[1] = 1;
+        } else {
+          mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[0]);
+          mbmi->tx_skip[1] =
+            vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+        }
     } else {
       mbmi->tx_skip[0] = 0;
       mbmi->tx_skip[1] = 0;
@@ -730,12 +744,38 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
     int q_idx = cm->base_qindex;
 #else
     int q_idx = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex);
-#endif
+#endif  // CONFIG_SUPERTX
     int try_tx_skip = inter_block ? q_idx <= TX_SKIP_Q_THRESH_INTER :
                                     q_idx <= TX_SKIP_Q_THRESH_INTRA;
+#if CONFIG_SUPERTX
     if (try_tx_skip) {
-      mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[inter_block]);
-      mbmi->tx_skip[1] = vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+#else
+    if (try_tx_skip && !mbmi->skip) {
+#endif  // CONFIG_SUPERTX
+      if (xd->lossless) {
+#if CONFIG_SUPERTX
+        if (1)
+#else
+        if (mbmi->tx_size == TX_4X4)
+#endif  // CONFIG_SUPERTX
+          mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[inter_block]);
+        else
+          mbmi->tx_skip[0] = 1;
+
+#if CONFIG_SUPERTX
+        if (1)
+#else
+        if (get_uv_tx_size(mbmi, &xd->plane[1]) == TX_4X4)
+#endif  // CONFIG_SUPERTX
+          mbmi->tx_skip[1] =
+            vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+        else
+          mbmi->tx_skip[1] = 1;
+      } else {
+        mbmi->tx_skip[0] = vp9_read(r, cm->fc.y_tx_skip_prob[inter_block]);
+        mbmi->tx_skip[1] =
+          vp9_read(r, cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      }
 #if CONFIG_SUPERTX
       if (!cm->frame_parallel_decoding_mode && !supertx_enabled) {
 #else
index 919789ffede96852a4ead55d8c8e2907b5cb5f0b..75bde4011eb329206af332e90841b2c099720175 100644 (file)
@@ -401,12 +401,33 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
     int q_idx = cm->base_qindex;
 #else
     int q_idx = vp9_get_qindex(seg, segment_id, cm->base_qindex);
-#endif
+#endif  // CONFIG_SUPERTX
     int try_tx_skip = is_inter ? q_idx <= TX_SKIP_Q_THRESH_INTER :
                                  q_idx <= TX_SKIP_Q_THRESH_INTRA;
+#if CONFIG_SUPERTX
     if (try_tx_skip) {
-      vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[is_inter]);
-      vp9_write(w, mbmi->tx_skip[1], cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+#else
+    if (try_tx_skip && !skip) {
+#endif  // CONFIG_SUPERTX
+      if (xd->lossless) {
+#if CONFIG_SUPERTX
+        if (1)
+#else
+        if (mbmi->tx_size == TX_4X4)
+#endif  // CONFIG_SUPERTX
+          vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[is_inter]);
+#if CONFIG_SUPERTX
+        if (1)
+#else
+        if (get_uv_tx_size(mbmi, &xd->plane[1]) == TX_4X4)
+#endif  // CONFIG_SUPERTX
+          vp9_write(w, mbmi->tx_skip[1],
+                    cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      } else {
+        vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[is_inter]);
+        vp9_write(w, mbmi->tx_skip[1],
+                  cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      }
     }
   }
 #endif
@@ -520,8 +541,17 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
     int q_idx = vp9_get_qindex(seg, mbmi->segment_id, cm->base_qindex);
     int try_tx_skip = q_idx <= TX_SKIP_Q_THRESH_INTRA;
     if (try_tx_skip) {
-      vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[0]);
-      vp9_write(w, mbmi->tx_skip[1], cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      if (xd->lossless) {
+        if (mbmi->tx_size == TX_4X4)
+          vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[0]);
+        if (get_uv_tx_size(mbmi, &xd->plane[1]) == TX_4X4)
+          vp9_write(w, mbmi->tx_skip[1],
+                    cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      } else {
+        vp9_write(w, mbmi->tx_skip[0], cm->fc.y_tx_skip_prob[0]);
+        vp9_write(w, mbmi->tx_skip[1],
+                  cm->fc.uv_tx_skip_prob[mbmi->tx_skip[0]]);
+      }
     }
   }
 #endif
@@ -1453,16 +1483,22 @@ static void write_uncompressed_header(VP9_COMP *cpi,
 
 static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
   VP9_COMMON *const cm = &cpi->common;
+#if !CONFIG_TX_SKIP
   MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+#endif
   FRAME_CONTEXT *const fc = &cm->fc;
   vp9_writer header_bc;
 
   vp9_start_encode(&header_bc, data);
 
+#if CONFIG_TX_SKIP
+  encode_txfm_probs(cm, &header_bc);
+#else
   if (xd->lossless)
     cm->tx_mode = ONLY_4X4;
   else
     encode_txfm_probs(cm, &header_bc);
+#endif
 
   update_coef_probs(cpi, &header_bc);
   update_skip_probs(cm, &header_bc);
index 7b2bf698f3e7f91c2de5433a44fad845abb7c2ae..88bfa3118f3b6b857e698728d7d174ccb5209c12 100644 (file)
@@ -3439,8 +3439,10 @@ static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
 }
 
 static TX_MODE select_tx_mode(const VP9_COMP *cpi) {
+#if !CONFIG_TX_SKIP
   if (cpi->mb.e_mbd.lossless)
     return ONLY_4X4;
+#endif
   if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
 #if CONFIG_TX64X64
     return ALLOW_64X64;
@@ -4741,7 +4743,11 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
 #endif
       int try_tx_skip = is_inter_block(mbmi) ? q_idx <= TX_SKIP_Q_THRESH_INTER :
                                                q_idx <= TX_SKIP_Q_THRESH_INTRA;
+#if CONFIG_SUPERTX
       if (try_tx_skip) {
+#else
+      if (try_tx_skip && !(mbmi->skip || seg_skip)) {
+#endif
         ++cm->counts.y_tx_skip[is_inter_block(mbmi)][mbmi->tx_skip[0]];
         ++cm->counts.uv_tx_skip[mbmi->tx_skip[0]][mbmi->tx_skip[1]];
       }
index 6cfb06987647c73b8e12bb3d81c4341b84099c28..67ab66028edc059874f98e8625d302e414e2370c 100644 (file)
@@ -599,6 +599,17 @@ static void txfm_rd_in_plane(MACROBLOCK *x,
   args.best_rd = ref_best_rd;
   args.use_fast_coef_costing = use_fast_coef_casting;
 
+#if CONFIG_TX_SKIP
+  if (xd->lossless && tx_size != TX_4X4 &&
+      !xd->mi[0].src_mi->mbmi.tx_skip[plane != 0]) {
+    *rate       = INT_MAX;
+    *distortion = INT64_MAX;
+    *sse        = INT64_MAX;
+    *skippable  = 0;
+    return;
+  }
+#endif
+
   if (plane == 0)
     xd->mi[0].src_mi->mbmi.tx_size = tx_size;
 
@@ -802,13 +813,19 @@ static void super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
                             int64_t *psse, BLOCK_SIZE bs,
                             int64_t txfm_cache[TX_MODES],
                             int64_t ref_best_rd) {
+#if !CONFIG_TX_SKIP
   MACROBLOCKD *xd = &x->e_mbd;
+#endif
   int64_t sse;
   int64_t *ret_sse = psse ? psse : &sse;
 
   assert(bs == xd->mi[0].src_mi->mbmi.sb_type);
 
+#if CONFIG_TX_SKIP
+  if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
+#else
   if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) {
+#endif
     vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
     choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
                            bs);