staticvoid read_cdef(AV1_COMMON *cm, aom_reader *r, MACROBLOCKD *const xd) { const int skip_txfm = xd->mi[0]->skip_txfm;
if (cm->features.coded_lossless) return;
if (cm->features.allow_intrabc) {
assert(cm->cdef_info.cdef_bits == 0); return;
}
// At the start of a superblock, mark that we haven't yet read CDEF strengths // for any of the CDEF units contained in this superblock. const int sb_mask = (cm->seq_params->mib_size - 1); const int mi_row_in_sb = (xd->mi_row & sb_mask); const int mi_col_in_sb = (xd->mi_col & sb_mask);
if (mi_row_in_sb == 0 && mi_col_in_sb == 0) {
xd->cdef_transmitted[0] = xd->cdef_transmitted[1] =
xd->cdef_transmitted[2] = xd->cdef_transmitted[3] = false;
}
// CDEF unit size is 64x64 irrespective of the superblock size. const int cdef_size = 1 << (6 - MI_SIZE_LOG2);
// Find index of this CDEF unit in this superblock. const int index_mask = cdef_size; const int cdef_unit_row_in_sb = ((xd->mi_row & index_mask) != 0); const int cdef_unit_col_in_sb = ((xd->mi_col & index_mask) != 0); const int index = (cm->seq_params->sb_size == BLOCK_128X128)
? cdef_unit_col_in_sb + 2 * cdef_unit_row_in_sb
: 0;
// Read CDEF strength from the first non-skip coding block in this CDEF unit.
if (!xd->cdef_transmitted[index] && !skip_txfm) { // CDEF strength for this CDEF unit needs to be read into the MB_MODE_INFO // of the 1st block in this CDEF unit. const int first_block_mask = ~(cdef_size - 1);
CommonModeInfoParams *const mi_params = &cm->mi_params; const int grid_idx =
get_mi_grid_idx(mi_params, xd->mi_row & first_block_mask,
xd->mi_col & first_block_mask);
MB_MODE_INFO *const mbmi = mi_params->mi_grid_base[grid_idx];
mbmi->cdef_strength =
aom_read_literal(r, cm->cdef_info.cdef_bits, ACCT_STR);
xd->cdef_transmitted[index] = true;
}
}
int av1_neg_deinterleave(int diff, int ref, int max) {
if (!ref) return diff;
if (ref >= (max - 1)) return max - diff - 1;
if (2 * ref < max) {
if (diff <= 2 * ref) {
if (diff & 1) return ref + ((diff + 1) >> 1); else return ref - (diff >> 1);
} return diff;
} else {
if (diff <= 2 * (max - ref - 1)) {
if (diff & 1) return ref + ((diff + 1) >> 1); else return ref - (diff >> 1);
} return max - (diff + 1);
}
}
static int read_segment_id(AV1_COMMON *const cm, const MACROBLOCKD *const xd,
aom_reader *r, int skip) {
int cdf_num; const uint8_t pred = av1_get_spatial_seg_pred(cm, xd, &cdf_num, 0);
if (skip) return pred;
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
int mi_offset, int x_mis, int y_mis) {
int segment_id = INT_MAX;
for (int y = 0; y < y_mis; y++)
for (int x = 0; x < x_mis; x++)
segment_id = AOMMIN(
segment_id, segment_ids[mi_offset + y * cm->mi_params.mi_cols + x]);
static int read_intra_segment_id(AV1_COMMON *const cm, const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
aom_reader *r, int skip) { struct segmentation *const seg = &cm->seg;
if (!seg->enabled) return0; // Default for disabled segmentation
assert(seg->update_map && !seg->temporal_update);
const CommonModeInfoParams *const mi_params = &cm->mi_params; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; const int mi_stride = cm->mi_params.mi_cols; const int mi_offset = mi_row * mi_stride + mi_col; const int bw = mi_size_wide[bsize]; const int bh = mi_size_high[bsize]; const int x_mis = AOMMIN(mi_params->mi_cols - mi_col, bw); const int y_mis = AOMMIN(mi_params->mi_rows - mi_row, bh); const int segment_id = read_segment_id(cm, xd, r, skip);
set_segment_id(cm->cur_frame->seg_map, mi_offset, x_mis, y_mis, mi_stride,
segment_id); return segment_id;
}
staticvoid copy_segment_id(const CommonModeInfoParams *const mi_params, const uint8_t *last_segment_ids,
uint8_t *current_segment_ids, int mi_offset,
int x_mis, int y_mis) { const int stride = mi_params->mi_cols;
if (last_segment_ids) {
assert(last_segment_ids != current_segment_ids);
for (int y = 0; y < y_mis; y++) {
memcpy(¤t_segment_ids[mi_offset + y * stride],
&last_segment_ids[mi_offset + y * stride], sizeof(current_segment_ids[0]) * x_mis);
}
} else {
for (int y = 0; y < y_mis; y++) {
memset(¤t_segment_ids[mi_offset + y * stride], 0, sizeof(current_segment_ids[0]) * x_mis);
}
}
}
static int get_predicted_segment_id(AV1_COMMON *const cm, int mi_offset,
int x_mis, int y_mis) { return cm->last_frame_seg_map ? dec_get_segment_id(cm, cm->last_frame_seg_map,
mi_offset, x_mis, y_mis)
: 0;
}
static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int preskip, aom_reader *r) { struct segmentation *const seg = &cm->seg; const CommonModeInfoParams *const mi_params = &cm->mi_params;
MB_MODE_INFO *const mbmi = xd->mi[0]; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; const int mi_offset = mi_row * mi_params->mi_cols + mi_col; const int bw = mi_size_wide[mbmi->bsize]; const int bh = mi_size_high[mbmi->bsize];
// TODO(slavarnway): move x_mis, y_mis into xd ????? const int x_mis = AOMMIN(mi_params->mi_cols - mi_col, bw); const int y_mis = AOMMIN(mi_params->mi_rows - mi_row, bh);
if (!seg->enabled) return0; // Default for disabled segmentation
static int read_skip_mode(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
aom_reader *r) {
if (!cm->current_frame.skip_mode_info.skip_mode_flag) return0;
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { return0;
}
if (!is_comp_ref_allowed(xd->mi[0]->bsize)) return0;
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME) ||
segfeature_active(&cm->seg, segment_id, SEG_LVL_GLOBALMV)) { // These features imply single-reference mode, while skip mode implies // compound reference. Hence, the two are mutually exclusive. // In other words, skip_mode is implicitly 0 here. return0;
}
const int ctx = av1_get_skip_mode_context(xd);
FRAME_CONTEXT *ec_ctx = xd->tile_ctx; const int skip_mode =
aom_read_symbol(r, ec_ctx->skip_mode_cdfs[ctx], 2, ACCT_STR); return skip_mode;
}
static int read_skip_txfm(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
aom_reader *r) {
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) { return1;
} else { const int ctx = av1_get_skip_txfm_context(xd);
FRAME_CONTEXT *ec_ctx = xd->tile_ctx; const int skip_txfm =
aom_read_symbol(r, ec_ctx->skip_txfm_cdfs[ctx], 2, ACCT_STR); return skip_txfm;
}
}
// Merge the sorted list of cached colors(cached_colors[0...n_cached_colors-1]) // and the sorted list of transmitted colors(colors[n_cached_colors...n-1]) into // one single sorted list(colors[...]). staticvoid merge_colors(uint16_t *colors, uint16_t *cached_colors,
int n_colors, int n_cached_colors) {
if (n_cached_colors == 0) return;
int cache_idx = 0, trans_idx = n_cached_colors;
for (int i = 0; i < n_colors; ++i) {
if (cache_idx < n_cached_colors &&
(trans_idx >= n_colors ||
cached_colors[cache_idx] <= colors[trans_idx])) {
colors[i] = cached_colors[cache_idx++];
} else {
assert(trans_idx < n_colors);
colors[i] = colors[trans_idx++];
}
}
}
staticvoid read_palette_colors_y(MACROBLOCKD *const xd, int bit_depth,
PALETTE_MODE_INFO *const pmi, aom_reader *r) {
uint16_t color_cache[2 * PALETTE_MAX_SIZE];
uint16_t cached_colors[PALETTE_MAX_SIZE]; const int n_cache = av1_get_palette_cache(xd, 0, color_cache); const int n = pmi->palette_size[0];
int idx = 0;
for (int i = 0; i < n_cache && idx < n; ++i)
if (aom_read_bit(r, ACCT_STR)) cached_colors[idx++] = color_cache[i];
if (idx < n) { const int n_cached_colors = idx;
pmi->palette_colors[idx++] = aom_read_literal(r, bit_depth, ACCT_STR);
if (idx < n) { const int min_bits = bit_depth - 3;
int bits = min_bits + aom_read_literal(r, 2, ACCT_STR);
int range = (1 << bit_depth) - pmi->palette_colors[idx - 1] - 1;
for (; idx < n; ++idx) {
assert(range >= 0); const int delta = aom_read_literal(r, bits, ACCT_STR) + 1;
pmi->palette_colors[idx] = clamp(pmi->palette_colors[idx - 1] + delta, 0, (1 << bit_depth) - 1);
range -= (pmi->palette_colors[idx] - pmi->palette_colors[idx - 1]);
bits = AOMMIN(bits, aom_ceil_log2(range));
}
}
merge_colors(pmi->palette_colors, cached_colors, n, n_cached_colors);
} else {
memcpy(pmi->palette_colors, cached_colors, n * sizeof(cached_colors[0]));
}
}
staticvoid read_palette_colors_uv(MACROBLOCKD *const xd, int bit_depth,
PALETTE_MODE_INFO *const pmi,
aom_reader *r) { const int n = pmi->palette_size[1]; // U channel colors.
uint16_t color_cache[2 * PALETTE_MAX_SIZE];
uint16_t cached_colors[PALETTE_MAX_SIZE]; const int n_cache = av1_get_palette_cache(xd, 1, color_cache);
int idx = 0;
for (int i = 0; i < n_cache && idx < n; ++i)
if (aom_read_bit(r, ACCT_STR)) cached_colors[idx++] = color_cache[i];
if (idx < n) { const int n_cached_colors = idx;
idx += PALETTE_MAX_SIZE;
pmi->palette_colors[idx++] = aom_read_literal(r, bit_depth, ACCT_STR);
if (idx < PALETTE_MAX_SIZE + n) { const int min_bits = bit_depth - 3;
int bits = min_bits + aom_read_literal(r, 2, ACCT_STR);
int range = (1 << bit_depth) - pmi->palette_colors[idx - 1];
for (; idx < PALETTE_MAX_SIZE + n; ++idx) {
assert(range >= 0); const int delta = aom_read_literal(r, bits, ACCT_STR);
pmi->palette_colors[idx] = clamp(pmi->palette_colors[idx - 1] + delta, 0, (1 << bit_depth) - 1);
range -= (pmi->palette_colors[idx] - pmi->palette_colors[idx - 1]);
bits = AOMMIN(bits, aom_ceil_log2(range));
}
}
merge_colors(pmi->palette_colors + PALETTE_MAX_SIZE, cached_colors, n,
n_cached_colors);
} else {
memcpy(pmi->palette_colors + PALETTE_MAX_SIZE, cached_colors,
n * sizeof(cached_colors[0]));
}
// V channel colors.
if (aom_read_bit(r, ACCT_STR)) { // Delta encoding. const int min_bits_v = bit_depth - 4; const int max_val = 1 << bit_depth;
int bits = min_bits_v + aom_read_literal(r, 2, ACCT_STR);
pmi->palette_colors[2 * PALETTE_MAX_SIZE] =
aom_read_literal(r, bit_depth, ACCT_STR);
for (int i = 1; i < n; ++i) {
int delta = aom_read_literal(r, bits, ACCT_STR);
if (delta && aom_read_bit(r, ACCT_STR)) delta = -delta;
int val = (int)pmi->palette_colors[2 * PALETTE_MAX_SIZE + i - 1] + delta;
if (val < 0) val += max_val;
if (val >= max_val) val -= max_val;
pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] = val;
}
} else {
for (int i = 0; i < n; ++i) {
pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
aom_read_literal(r, bit_depth, ACCT_STR);
}
}
}
// No need to read transform type if block is skipped.
if (mbmi->skip_txfm ||
segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) return;
// No need to read transform type for lossless mode(qindex==0). const int qindex = xd->qindex[mbmi->segment_id];
if (qindex == 0) return;
const int inter_block = is_inter_block(mbmi);
if (get_ext_tx_types(tx_size, inter_block, cm->features.reduced_tx_set_used) > 1) { const TxSetType tx_set_type = av1_get_ext_tx_set_type(
tx_size, inter_block, cm->features.reduced_tx_set_used); const int eset =
get_ext_tx_set(tx_size, inter_block, cm->features.reduced_tx_set_used); // eset == 0 should correspond to a set with only DCT_DCT and // there is no need to read the tx_type
assert(eset != 0);
if (!cm->seq_params->monochrome && xd->is_chroma_ref) {
mbmi->uv_mode =
read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(xd), mbmi->mode);
if (mbmi->uv_mode == UV_CFL_PRED) {
mbmi->cfl_alpha_idx = read_cfl_alphas(ec_ctx, r, &mbmi->cfl_alpha_signs);
} const PREDICTION_MODE intra_mode = get_uv_mode(mbmi->uv_mode);
mbmi->angle_delta[PLANE_TYPE_UV] =
(use_angle_delta && av1_is_directional_mode(intra_mode))
? read_angle_delta(r, ec_ctx->angle_delta_cdf[intra_mode - V_PRED])
: 0;
} else { // Avoid decoding angle_info if there is no chroma prediction
mbmi->uv_mode = UV_DC_PRED;
}
xd->cfl.store_y = store_cfl_required(cm, xd);
if (av1_allow_palette(cm->features.allow_screen_content_tools, bsize))
read_palette_mode_info(cm, xd, r);
read_filter_intra_mode_info(cm, xd, r);
}
static int read_mv_component(aom_reader *r, nmv_component *mvcomp,
int use_subpel, int usehp) {
int mag, d, fr, hp; const int sign = aom_read_symbol(r, mvcomp->sign_cdf, 2, ACCT_STR); const int mv_class =
aom_read_symbol(r, mvcomp->classes_cdf, MV_CLASSES, ACCT_STR); const int class0 = mv_class == MV_CLASS_0;
// Integer part
if (class0) {
d = aom_read_symbol(r, mvcomp->class0_cdf, CLASS0_SIZE, ACCT_STR);
mag = 0;
} else { const int n = mv_class + CLASS0_BITS - 1; // number of bits
d = 0;
for (int i = 0; i < n; ++i)
d |= aom_read_symbol(r, mvcomp->bits_cdf[i], 2, ACCT_STR) << i;
mag = CLASS0_SIZE << (mv_class + 2);
}
if (use_subpel) { // Fractional part
fr = aom_read_symbol(r, class0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
MV_FP_SIZE, ACCT_STR);
// High precision part (if hp is not used, the default value of the hp is 1)
hp = usehp ? aom_read_symbol(
r, class0 ? mvcomp->class0_hp_cdf : mvcomp->hp_cdf, 2,
ACCT_STR)
: 1;
} else {
fr = 3;
hp = 1;
}
if (is_compound) {
int ref_mv_idx = mbmi->ref_mv_idx; // Special case: NEAR_NEWMV and NEW_NEARMV modes use // 1 + mbmi->ref_mv_idx (like NEARMV) instead of // mbmi->ref_mv_idx (like NEWMV)
if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
ref_mv_idx = 1 + mbmi->ref_mv_idx;
// TODO(jingning, yunqing): Do we need a lower_mv_precision() call here?
if (compound_ref0_mode(mbmi->mode) == NEWMV)
ref_mv[0] = xd->ref_mv_stack[ref_frame][ref_mv_idx].this_mv;
if (compound_ref1_mode(mbmi->mode) == NEWMV)
ref_mv[1] = xd->ref_mv_stack[ref_frame][ref_mv_idx].comp_mv;
} else {
if (mbmi->mode == NEWMV) {
if (dcb->ref_mv_count[ref_frame] > 1)
ref_mv[0] = xd->ref_mv_stack[ref_frame][mbmi->ref_mv_idx].this_mv;
}
}
if (mbmi->skip_mode) assert(mbmi->mode == NEAREST_NEARESTMV);
if (has_second_ref(mbmi) && !mbmi->skip_mode) { // Read idx to indicate current compound inter prediction mode group const int masked_compound_used = is_any_masked_compound_used(bsize) &&
cm->seq_params->enable_masked_compound;
if (masked_compound_used) { const int ctx_comp_group_idx = get_comp_group_idx_context(xd);
mbmi->comp_group_idx = (uint8_t)aom_read_symbol(
r, ec_ctx->comp_group_idx_cdf[ctx_comp_group_idx], 2, ACCT_STR);
}
if (mbmi->comp_group_idx == 0) {
if (cm->seq_params->order_hint_info.enable_dist_wtd_comp) { const int comp_index_ctx = get_comp_index_context(cm, xd);
mbmi->compound_idx = (uint8_t)aom_read_symbol(
r, ec_ctx->compound_index_cdf[comp_index_ctx], 2, ACCT_STR);
mbmi->interinter_comp.type =
mbmi->compound_idx ? COMPOUND_AVERAGE : COMPOUND_DISTWTD;
} else { // Distance-weighted compound is disabled, so always use average
mbmi->compound_idx = 1;
mbmi->interinter_comp.type = COMPOUND_AVERAGE;
}
} else {
assert(cm->current_frame.reference_mode != SINGLE_REFERENCE &&
is_inter_compound_mode(mbmi->mode) &&
mbmi->motion_mode == SIMPLE_TRANSLATION);
assert(masked_compound_used);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.