func: static void hls_transform_tree(HEVCContext *s, int x0, int y0,
  
                                 int xBase, int yBase, int cb_xBase, int cb_yBase,
  
                                 int log2_cb_size, int log2_trafo_size,
  
                                 int trafo_depth, int blk_idx)
  
  {
  
      HEVCLocalContext *lc = &s->HEVClc;
  
      uint8_t split_transform_flag;
  
  
  
      if (trafo_depth > 0 && log2_trafo_size == 2) {
  
          SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
  
              SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase);
  
          SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
  
              SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase);
  
      } else {
  
          SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
  
          SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) = 0;
  
      }
  
  
  
      if (lc->cu.intra_split_flag) {
  
          if (trafo_depth == 1)
  
              lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[blk_idx];
  
      } else {
  
          lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[0];
  
      }
  
  
  
      lc->tt.cbf_luma = 1;
  
  
  
      lc->tt.inter_split_flag = s->sps->max_transform_hierarchy_depth_inter == 0 &&
  
                                lc->cu.pred_mode == MODE_INTER &&
  
                                lc->cu.part_mode != PART_2Nx2N &&
  
                                trafo_depth == 0;
  
  
  
      if (log2_trafo_size <= s->sps->log2_max_trafo_size &&
  
          log2_trafo_size >  s->sps->log2_min_tb_size    &&
  
          trafo_depth     < lc->cu.max_trafo_depth       &&
  
          !(lc->cu.intra_split_flag && trafo_depth == 0)) {
  
          split_transform_flag = ff_hevc_split_transform_flag_decode(s, log2_trafo_size);
  
      } else {
  
          split_transform_flag = log2_trafo_size > s->sps->log2_max_trafo_size ||
  
                                 (lc->cu.intra_split_flag && trafo_depth == 0) ||
  
                                 lc->tt.inter_split_flag;
  
      }
  
  
  
      if (log2_trafo_size > 2) {
  
          if (trafo_depth == 0 ||
  
              SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase)) {
  
              SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
  
                  ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
  
          }
  
  
  
          if (trafo_depth == 0 ||
  
              SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase)) {
  
              SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
  
                  ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
  
          }
  
      }
  
  
  
      if (split_transform_flag) {
  
          int x1 = x0 + ((1 << log2_trafo_size) >> 1);
  
          int y1 = y0 + ((1 << log2_trafo_size) >> 1);
  
  
  
          hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
  
                             log2_trafo_size - 1, trafo_depth + 1, 0);
  
          hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
  
                             log2_trafo_size - 1, trafo_depth + 1, 1);
  
          hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
  
                             log2_trafo_size - 1, trafo_depth + 1, 2);
  
          hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
  
                             log2_trafo_size - 1, trafo_depth + 1, 3);
  
      } else {
  
          int min_tu_size      = 1 << s->sps->log2_min_tb_size;
  
          int log2_min_tu_size = s->sps->log2_min_tb_size;
  
          int min_tu_width     = s->sps->min_tb_width;
  
  
  
          if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
  
              SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
  
              SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
  
              lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
  
          }
  
  
  
          hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
  
                             log2_cb_size, log2_trafo_size, trafo_depth, blk_idx);
  
  
  
          // TODO: store cbf_luma somewhere else
  
          if (lc->tt.cbf_luma) {
  
              int i, j;
  
              for (i = 0; i < (1 << log2_trafo_size); i += min_tu_size)
  
                  for (j = 0; j < (1 << log2_trafo_size); j += min_tu_size) {
  
                      int x_tu = (x0 + j) >> log2_min_tu_size;
  
                      int y_tu = (y0 + i) >> log2_min_tu_size;
  
                      s->cbf_luma[y_tu * min_tu_width + x_tu] = 1;
  
                  }
  
          }
  
          if (!s->sh.disable_deblocking_filter_flag) {
  
              ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_trafo_size,
  
                                                    lc->slice_or_tiles_up_boundary,
  
                                                    lc->slice_or_tiles_left_boundary);
  
              if (s->pps->transquant_bypass_enable_flag &&
  
                  lc->cu.cu_transquant_bypass_flag)
  
                  set_deblocking_bypass(s, x0, y0, log2_trafo_size);
  
          }
  
      }
  
  }
  