/* Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
for (y = 0; y < y_mis; y++) for (x = 0; x < x_mis; x++)
cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}
staticvoid copy_segment_id(const VP9_COMMON *cm, const uint8_t *last_segment_ids,
uint8_t *current_segment_ids, int mi_offset, int x_mis, int y_mis) { int x, y;
for (y = 0; y < y_mis; y++) for (x = 0; x < x_mis; x++)
current_segment_ids[mi_offset + y * cm->mi_cols + x] =
last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
: 0;
}
staticint read_intra_segment_id(VP9_COMMON *const cm, int mi_offset, int x_mis, int y_mis, vpx_reader *r) { struct segmentation *const seg = &cm->seg; int segment_id;
if (!seg->enabled) return 0; // Default for disabled segmentation
staticint read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd, int mi_row, int mi_col, vpx_reader *r, int x_mis, int y_mis) { struct segmentation *const seg = &cm->seg;
MODE_INFO *const mi = xd->mi[0]; int predicted_segment_id, segment_id; constint mi_offset = mi_row * cm->mi_cols + mi_col;
if (!seg->enabled) return 0; // Default for disabled segmentation
// Initialize interp_filter here so we do not have to check for inter block // modes in get_pred_context_switchable_interp()
mi->interp_filter = SWITCHABLE_FILTERS;
// This macro is used to add a motion vector mv_ref list if it isn't // already in the list. If it's the second motion vector or early_break // it will also skip all additional processing and jump to Done! #define ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done) \ do { \ if (refmv_count) { \ if ((mv).as_int != (mv_ref_list)[0].as_int) { \
(mv_ref_list)[(refmv_count)] = (mv); \
refmv_count++; \ goto Done; \
} \
} else { \
(mv_ref_list)[(refmv_count)++] = (mv); \ if (early_break) goto Done; \
} \
} while (0)
// If either reference frame is different, not INTRA, and they // are different from each other scale and add the mv to our list. #define IF_DIFF_REF_FRAME_ADD_MV_EB(mbmi, ref_frame, ref_sign_bias, \
refmv_count, mv_ref_list, Done) \ do { \ if (is_inter_block(mbmi)) { \ if ((mbmi)->ref_frame[0] != ref_frame) \
ADD_MV_REF_LIST_EB(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \
refmv_count, mv_ref_list, Done); \ if (has_second_ref(mbmi) && (mbmi)->ref_frame[1] != ref_frame && \
(mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \
ADD_MV_REF_LIST_EB(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \
refmv_count, mv_ref_list, Done); \
} \
} while (0)
// This function searches the neighborhood of a given MB/SB // to try and find candidate reference vectors. staticint dec_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
PREDICTION_MODE mode, MV_REFERENCE_FRAME ref_frame, const POSITION *const mv_ref_search,
int_mv *mv_ref_list, int mi_row, int mi_col, int block) { constint *ref_sign_bias = cm->ref_frame_sign_bias; int i, refmv_count = 0; int different_ref_found = 0; const MV_REF *const prev_frame_mvs =
cm->use_prev_frame_mvs
? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col
: NULL; const TileInfo *const tile = &xd->tile; // If mode is nearestmv or newmv (uses nearestmv as a reference) then stop // searching after the first mv is found. constint early_break = (mode != NEARMV);
// Blank the reference vector list
memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
i = 0; if (block >= 0) { // If the size < 8x8 we get the mv from the bmi substructure for the // nearest two blocks. for (i = 0; i < 2; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MODE_INFO *const candidate_mi =
xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
different_ref_found = 1;
// Check the rest of the neighbors in much the same way // as before except we don't need to keep track of sub blocks or // mode counts. for (; i < MVREF_NEIGHBOURS; ++i) { const POSITION *const mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MODE_INFO *const candidate =
xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
different_ref_found = 1;
// Check the last frame's mode and mv info. if (prev_frame_mvs) { if (prev_frame_mvs->ref_frame[0] == ref_frame) {
ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done);
} elseif (prev_frame_mvs->ref_frame[1] == ref_frame) {
ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done);
}
}
// Since we couldn't find 2 mvs from the same reference frame // go back through the neighbors and find motion vectors from // different reference frames. if (different_ref_found) { for (i = 0; i < MVREF_NEIGHBOURS; ++i) { const POSITION *mv_ref = &mv_ref_search[i]; if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { const MODE_INFO *const candidate =
xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
// If the candidate is INTRA we don't want to consider its mv.
IF_DIFF_REF_FRAME_ADD_MV_EB(candidate, ref_frame, ref_sign_bias,
refmv_count, mv_ref_list, Done);
}
}
}
// Since we still don't have a candidate we'll try the last frame. if (prev_frame_mvs) { if (prev_frame_mvs->ref_frame[0] != ref_frame &&
prev_frame_mvs->ref_frame[0] > INTRA_FRAME) {
int_mv mv = prev_frame_mvs->mv[0]; if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] !=
ref_sign_bias[ref_frame]) {
mv.as_mv.row *= -1;
mv.as_mv.col *= -1;
}
ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done);
}
if (mode == NEARMV)
refmv_count = MAX_MV_REF_CANDIDATES; else // we only care about the nearestmv for the remaining modes
refmv_count = 1;
Done: // Clamp vectors for (i = 0; i < refmv_count; ++i) clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
return refmv_count;
}
staticvoid append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, const POSITION *const mv_ref_search,
PREDICTION_MODE b_mode, int block, int ref, int mi_row, int mi_col,
int_mv *best_sub8x8) {
int_mv mv_list[MAX_MV_REF_CANDIDATES];
MODE_INFO *const mi = xd->mi[0];
b_mode_info *bmi = mi->bmi; int n; int refmv_count;
staticvoid read_inter_frame_mode_info(VP9Decoder *const pbi,
MACROBLOCKD *const xd, int mi_row, int mi_col, vpx_reader *r, int x_mis, int y_mis) {
VP9_COMMON *const cm = &pbi->common;
MODE_INFO *const mi = xd->mi[0]; int inter_block;
void vp9_read_mode_info(TileWorkerData *twd, VP9Decoder *const pbi, int mi_row, int mi_col, int x_mis, int y_mis) {
vpx_reader *r = &twd->bit_reader;
MACROBLOCKD *const xd = &twd->xd;
VP9_COMMON *const cm = &pbi->common;
MODE_INFO *const mi = xd->mi[0];
MV_REF *frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col; int w, h;
if (frame_is_intra_only(cm)) {
read_intra_frame_mode_info(cm, xd, mi_row, mi_col, r, x_mis, y_mis);
} else { // Cache mi->ref_frame and mi->mv so that the compiler can prove that they // are constant for the duration of the loop and avoids reloading them.
MV_REFERENCE_FRAME mi_ref_frame[2];
int_mv mi_mv[2];
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.