Commit 7c7e4d4e authored by Yunqing Wang's avatar Yunqing Wang

vp9_ethread: allocate frame contexts outside VP9_COMMON struct

This patch allocated frame contexts outside VP9_COMMON. This allows
multiple threads to share the same copy of frame contexts, and
reduces the overhead. It also guarantees the correct update of
these contexts during bitstream packing. This patch doesn't change
encoding result.

Change-Id: Ic181a2460b891d1d587278a6d02d8057b9dbd353
parent 7c4992c4
...@@ -748,10 +748,10 @@ void vp9_model_to_full_probs(const vp9_prob *model, vp9_prob *full) { ...@@ -748,10 +748,10 @@ void vp9_model_to_full_probs(const vp9_prob *model, vp9_prob *full) {
} }
void vp9_default_coef_probs(VP9_COMMON *cm) { void vp9_default_coef_probs(VP9_COMMON *cm) {
vp9_copy(cm->fc.coef_probs[TX_4X4], default_coef_probs_4x4); vp9_copy(cm->fc->coef_probs[TX_4X4], default_coef_probs_4x4);
vp9_copy(cm->fc.coef_probs[TX_8X8], default_coef_probs_8x8); vp9_copy(cm->fc->coef_probs[TX_8X8], default_coef_probs_8x8);
vp9_copy(cm->fc.coef_probs[TX_16X16], default_coef_probs_16x16); vp9_copy(cm->fc->coef_probs[TX_16X16], default_coef_probs_16x16);
vp9_copy(cm->fc.coef_probs[TX_32X32], default_coef_probs_32x32); vp9_copy(cm->fc->coef_probs[TX_32X32], default_coef_probs_32x32);
} }
#define COEF_COUNT_SAT 24 #define COEF_COUNT_SAT 24
...@@ -765,7 +765,7 @@ static void adapt_coef_probs(VP9_COMMON *cm, TX_SIZE tx_size, ...@@ -765,7 +765,7 @@ static void adapt_coef_probs(VP9_COMMON *cm, TX_SIZE tx_size,
unsigned int count_sat, unsigned int count_sat,
unsigned int update_factor) { unsigned int update_factor) {
const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx];
vp9_coeff_probs_model *const probs = cm->fc.coef_probs[tx_size]; vp9_coeff_probs_model *const probs = cm->fc->coef_probs[tx_size];
const vp9_coeff_probs_model *const pre_probs = pre_fc->coef_probs[tx_size]; const vp9_coeff_probs_model *const pre_probs = pre_fc->coef_probs[tx_size];
vp9_coeff_count_model *counts = cm->counts.coef[tx_size]; vp9_coeff_count_model *counts = cm->counts.coef[tx_size];
unsigned int (*eob_counts)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] = unsigned int (*eob_counts)[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS] =
......
...@@ -350,7 +350,7 @@ static void adapt_probs(const vp9_tree_index *tree, ...@@ -350,7 +350,7 @@ static void adapt_probs(const vp9_tree_index *tree,
void vp9_adapt_mode_probs(VP9_COMMON *cm) { void vp9_adapt_mode_probs(VP9_COMMON *cm) {
int i, j; int i, j;
FRAME_CONTEXT *fc = &cm->fc; FRAME_CONTEXT *fc = cm->fc;
const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx]; const FRAME_CONTEXT *pre_fc = &cm->frame_contexts[cm->frame_context_idx];
const FRAME_COUNTS *counts = &cm->counts; const FRAME_COUNTS *counts = &cm->counts;
...@@ -451,17 +451,17 @@ void vp9_setup_past_independence(VP9_COMMON *cm) { ...@@ -451,17 +451,17 @@ void vp9_setup_past_independence(VP9_COMMON *cm) {
lf->last_sharpness_level = -1; lf->last_sharpness_level = -1;
vp9_default_coef_probs(cm); vp9_default_coef_probs(cm);
vp9_init_mode_probs(&cm->fc); vp9_init_mode_probs(cm->fc);
vp9_init_mv_probs(cm); vp9_init_mv_probs(cm);
if (cm->frame_type == KEY_FRAME || if (cm->frame_type == KEY_FRAME ||
cm->error_resilient_mode || cm->reset_frame_context == 3) { cm->error_resilient_mode || cm->reset_frame_context == 3) {
// Reset all frame contexts. // Reset all frame contexts.
for (i = 0; i < FRAME_CONTEXTS; ++i) for (i = 0; i < FRAME_CONTEXTS; ++i)
cm->frame_contexts[i] = cm->fc; cm->frame_contexts[i] = *cm->fc;
} else if (cm->reset_frame_context == 2) { } else if (cm->reset_frame_context == 2) {
// Reset only the frame context specified in the frame header. // Reset only the frame context specified in the frame header.
cm->frame_contexts[cm->frame_context_idx] = cm->fc; cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
} }
if (frame_is_intra_only(cm)) if (frame_is_intra_only(cm))
......
...@@ -196,7 +196,7 @@ static void adapt_probs(const vp9_tree_index *tree, const vp9_prob *pre_probs, ...@@ -196,7 +196,7 @@ static void adapt_probs(const vp9_tree_index *tree, const vp9_prob *pre_probs,
void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) { void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) {
int i, j; int i, j;
nmv_context *fc = &cm->fc.nmvc; nmv_context *fc = &cm->fc->nmvc;
const nmv_context *pre_fc = &cm->frame_contexts[cm->frame_context_idx].nmvc; const nmv_context *pre_fc = &cm->frame_contexts[cm->frame_context_idx].nmvc;
const nmv_context_counts *counts = &cm->counts.mv; const nmv_context_counts *counts = &cm->counts.mv;
...@@ -229,5 +229,5 @@ void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) { ...@@ -229,5 +229,5 @@ void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) {
} }
void vp9_init_mv_probs(VP9_COMMON *cm) { void vp9_init_mv_probs(VP9_COMMON *cm) {
cm->fc.nmvc = default_nmv_context; cm->fc->nmvc = default_nmv_context;
} }
...@@ -169,8 +169,8 @@ typedef struct VP9Common { ...@@ -169,8 +169,8 @@ typedef struct VP9Common {
MV_REFERENCE_FRAME comp_var_ref[2]; MV_REFERENCE_FRAME comp_var_ref[2];
REFERENCE_MODE reference_mode; REFERENCE_MODE reference_mode;
FRAME_CONTEXT fc; /* this frame entropy */ FRAME_CONTEXT *fc; /* this frame entropy */
FRAME_CONTEXT frame_contexts[FRAME_CONTEXTS]; FRAME_CONTEXT *frame_contexts; // FRAME_CONTEXTS
unsigned int frame_context_idx; /* Context to use/update */ unsigned int frame_context_idx; /* Context to use/update */
FRAME_COUNTS counts; FRAME_COUNTS counts;
...@@ -261,7 +261,7 @@ static INLINE int frame_is_intra_only(const VP9_COMMON *const cm) { ...@@ -261,7 +261,7 @@ static INLINE int frame_is_intra_only(const VP9_COMMON *const cm) {
static INLINE const vp9_prob* get_partition_probs(const VP9_COMMON *cm, static INLINE const vp9_prob* get_partition_probs(const VP9_COMMON *cm,
int ctx) { int ctx) {
return frame_is_intra_only(cm) ? vp9_kf_partition_probs[ctx] return frame_is_intra_only(cm) ? vp9_kf_partition_probs[ctx]
: cm->fc.partition_prob[ctx]; : cm->fc->partition_prob[ctx];
} }
static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) { static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) {
......
...@@ -54,7 +54,7 @@ static INLINE int vp9_get_skip_context(const MACROBLOCKD *xd) { ...@@ -54,7 +54,7 @@ static INLINE int vp9_get_skip_context(const MACROBLOCKD *xd) {
static INLINE vp9_prob vp9_get_skip_prob(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_skip_prob(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc.skip_probs[vp9_get_skip_context(xd)]; return cm->fc->skip_probs[vp9_get_skip_context(xd)];
} }
int vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd); int vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd);
...@@ -63,14 +63,14 @@ int vp9_get_intra_inter_context(const MACROBLOCKD *xd); ...@@ -63,14 +63,14 @@ int vp9_get_intra_inter_context(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_intra_inter_prob(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_intra_inter_prob(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc.intra_inter_prob[vp9_get_intra_inter_context(xd)]; return cm->fc->intra_inter_prob[vp9_get_intra_inter_context(xd)];
} }
int vp9_get_reference_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd); int vp9_get_reference_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_reference_mode_prob(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_reference_mode_prob(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc.comp_inter_prob[vp9_get_reference_mode_context(cm, xd)]; return cm->fc->comp_inter_prob[vp9_get_reference_mode_context(cm, xd)];
} }
int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
...@@ -79,21 +79,21 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, ...@@ -79,21 +79,21 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd); const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd);
return cm->fc.comp_ref_prob[pred_context]; return cm->fc->comp_ref_prob[pred_context];
} }
int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd); int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p1(xd)][0]; return cm->fc->single_ref_prob[vp9_get_pred_context_single_ref_p1(xd)][0];
} }
int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd); int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm, static INLINE vp9_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm,
const MACROBLOCKD *xd) { const MACROBLOCKD *xd) {
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1]; return cm->fc->single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1];
} }
int vp9_get_tx_size_context(const MACROBLOCKD *xd); int vp9_get_tx_size_context(const MACROBLOCKD *xd);
......
...@@ -127,7 +127,7 @@ static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm, ...@@ -127,7 +127,7 @@ static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm,
} }
static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) { static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
FRAME_CONTEXT *const fc = &cm->fc; FRAME_CONTEXT *const fc = cm->fc;
int i; int i;
if (cm->reference_mode == REFERENCE_MODE_SELECT) if (cm->reference_mode == REFERENCE_MODE_SELECT)
...@@ -1386,7 +1386,7 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data, ...@@ -1386,7 +1386,7 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
size_t partition_size) { size_t partition_size) {
VP9_COMMON *const cm = &pbi->common; VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb; MACROBLOCKD *const xd = &pbi->mb;
FRAME_CONTEXT *const fc = &cm->fc; FRAME_CONTEXT *const fc = cm->fc;
vp9_reader r; vp9_reader r;
int k; int k;
...@@ -1540,7 +1540,7 @@ void vp9_decode_frame(VP9Decoder *pbi, ...@@ -1540,7 +1540,7 @@ void vp9_decode_frame(VP9Decoder *pbi,
setup_plane_dequants(cm, xd, cm->base_qindex); setup_plane_dequants(cm, xd, cm->base_qindex);
vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y); vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
cm->fc = cm->frame_contexts[cm->frame_context_idx]; *cm->fc = cm->frame_contexts[cm->frame_context_idx];
vp9_zero(cm->counts); vp9_zero(cm->counts);
vp9_zero(xd->dqcoeff); vp9_zero(xd->dqcoeff);
...@@ -1580,5 +1580,5 @@ void vp9_decode_frame(VP9Decoder *pbi, ...@@ -1580,5 +1580,5 @@ void vp9_decode_frame(VP9Decoder *pbi,
} }
if (cm->refresh_frame_context) if (cm->refresh_frame_context)
cm->frame_contexts[cm->frame_context_idx] = cm->fc; cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
} }
...@@ -30,7 +30,7 @@ static PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) { ...@@ -30,7 +30,7 @@ static PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r, static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r,
int size_group) { int size_group) {
const PREDICTION_MODE y_mode = const PREDICTION_MODE y_mode =
read_intra_mode(r, cm->fc.y_mode_prob[size_group]); read_intra_mode(r, cm->fc->y_mode_prob[size_group]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.y_mode[size_group][y_mode]; ++cm->counts.y_mode[size_group][y_mode];
return y_mode; return y_mode;
...@@ -39,7 +39,7 @@ static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r, ...@@ -39,7 +39,7 @@ static PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r,
static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r, static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r,
PREDICTION_MODE y_mode) { PREDICTION_MODE y_mode) {
const PREDICTION_MODE uv_mode = read_intra_mode(r, const PREDICTION_MODE uv_mode = read_intra_mode(r,
cm->fc.uv_mode_prob[y_mode]); cm->fc->uv_mode_prob[y_mode]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.uv_mode[y_mode][uv_mode]; ++cm->counts.uv_mode[y_mode][uv_mode];
return uv_mode; return uv_mode;
...@@ -47,7 +47,7 @@ static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r, ...@@ -47,7 +47,7 @@ static PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r,
static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r, int ctx) { static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r, int ctx) {
const int mode = vp9_read_tree(r, vp9_inter_mode_tree, const int mode = vp9_read_tree(r, vp9_inter_mode_tree,
cm->fc.inter_mode_probs[ctx]); cm->fc->inter_mode_probs[ctx]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.inter_mode[ctx][mode]; ++cm->counts.inter_mode[ctx][mode];
...@@ -61,7 +61,7 @@ static int read_segment_id(vp9_reader *r, const struct segmentation *seg) { ...@@ -61,7 +61,7 @@ static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
TX_SIZE max_tx_size, vp9_reader *r) { TX_SIZE max_tx_size, vp9_reader *r) {
const int ctx = vp9_get_tx_size_context(xd); const int ctx = vp9_get_tx_size_context(xd);
const vp9_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc.tx_probs); const vp9_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs);
int tx_size = vp9_read(r, tx_probs[0]); int tx_size = vp9_read(r, tx_probs[0]);
if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
tx_size += vp9_read(r, tx_probs[1]); tx_size += vp9_read(r, tx_probs[1]);
...@@ -150,7 +150,7 @@ static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd, ...@@ -150,7 +150,7 @@ static int read_skip(VP9_COMMON *cm, const MACROBLOCKD *xd,
return 1; return 1;
} else { } else {
const int ctx = vp9_get_skip_context(xd); const int ctx = vp9_get_skip_context(xd);
const int skip = vp9_read(r, cm->fc.skip_probs[ctx]); const int skip = vp9_read(r, cm->fc->skip_probs[ctx]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.skip[ctx][skip]; ++cm->counts.skip[ctx][skip];
return skip; return skip;
...@@ -258,7 +258,7 @@ static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm, ...@@ -258,7 +258,7 @@ static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm,
if (cm->reference_mode == REFERENCE_MODE_SELECT) { if (cm->reference_mode == REFERENCE_MODE_SELECT) {
const int ctx = vp9_get_reference_mode_context(cm, xd); const int ctx = vp9_get_reference_mode_context(cm, xd);
const REFERENCE_MODE mode = const REFERENCE_MODE mode =
(REFERENCE_MODE)vp9_read(r, cm->fc.comp_inter_prob[ctx]); (REFERENCE_MODE)vp9_read(r, cm->fc->comp_inter_prob[ctx]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.comp_inter[ctx][mode]; ++cm->counts.comp_inter[ctx][mode];
return mode; // SINGLE_REFERENCE or COMPOUND_REFERENCE return mode; // SINGLE_REFERENCE or COMPOUND_REFERENCE
...@@ -271,7 +271,7 @@ static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm, ...@@ -271,7 +271,7 @@ static REFERENCE_MODE read_block_reference_mode(VP9_COMMON *cm,
static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd, static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
vp9_reader *r, vp9_reader *r,
int segment_id, MV_REFERENCE_FRAME ref_frame[2]) { int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
FRAME_CONTEXT *const fc = &cm->fc; FRAME_CONTEXT *const fc = cm->fc;
FRAME_COUNTS *const counts = &cm->counts; FRAME_COUNTS *const counts = &cm->counts;
if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) { if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
...@@ -317,7 +317,7 @@ static INLINE INTERP_FILTER read_switchable_interp_filter( ...@@ -317,7 +317,7 @@ static INLINE INTERP_FILTER read_switchable_interp_filter(
const int ctx = vp9_get_pred_context_switchable_interp(xd); const int ctx = vp9_get_pred_context_switchable_interp(xd);
const INTERP_FILTER type = const INTERP_FILTER type =
(INTERP_FILTER)vp9_read_tree(r, vp9_switchable_interp_tree, (INTERP_FILTER)vp9_read_tree(r, vp9_switchable_interp_tree,
cm->fc.switchable_interp_prob[ctx]); cm->fc->switchable_interp_prob[ctx]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.switchable_interp[ctx][type]; ++cm->counts.switchable_interp[ctx][type];
return type; return type;
...@@ -372,7 +372,7 @@ static INLINE int assign_mv(VP9_COMMON *cm, PREDICTION_MODE mode, ...@@ -372,7 +372,7 @@ static INLINE int assign_mv(VP9_COMMON *cm, PREDICTION_MODE mode,
nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ? nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ?
NULL : &cm->counts.mv; NULL : &cm->counts.mv;
for (i = 0; i < 1 + is_compound; ++i) { for (i = 0; i < 1 + is_compound; ++i) {
read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc.nmvc, mv_counts, read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp); allow_hp);
ret = ret && is_mv_valid(&mv[i].as_mv); ret = ret && is_mv_valid(&mv[i].as_mv);
} }
...@@ -410,7 +410,7 @@ static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd, ...@@ -410,7 +410,7 @@ static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
INTRA_FRAME; INTRA_FRAME;
} else { } else {
const int ctx = vp9_get_intra_inter_context(xd); const int ctx = vp9_get_intra_inter_context(xd);
const int is_inter = vp9_read(r, cm->fc.intra_inter_prob[ctx]); const int is_inter = vp9_read(r, cm->fc->intra_inter_prob[ctx]);
if (!cm->frame_parallel_decoding_mode) if (!cm->frame_parallel_decoding_mode)
++cm->counts.intra_inter[ctx][is_inter]; ++cm->counts.intra_inter[ctx][is_inter];
return is_inter; return is_inter;
......
...@@ -59,6 +59,13 @@ VP9Decoder *vp9_decoder_create() { ...@@ -59,6 +59,13 @@ VP9Decoder *vp9_decoder_create() {
} }
cm->error.setjmp = 1; cm->error.setjmp = 1;
CHECK_MEM_ERROR(cm, cm->fc,
(FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc)));
CHECK_MEM_ERROR(cm, cm->frame_contexts,
(FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS,
sizeof(*cm->frame_contexts)));
pbi->need_resync = 1; pbi->need_resync = 1;
initialize_dec(); initialize_dec();
...@@ -88,6 +95,11 @@ void vp9_decoder_remove(VP9Decoder *pbi) { ...@@ -88,6 +95,11 @@ void vp9_decoder_remove(VP9Decoder *pbi) {
VP9_COMMON *const cm = &pbi->common; VP9_COMMON *const cm = &pbi->common;
int i; int i;
vpx_free(cm->fc);
cm->fc = NULL;
vpx_free(cm->frame_contexts);
cm->frame_contexts = NULL;
vp9_get_worker_interface()->end(&pbi->lf_worker); vp9_get_worker_interface()->end(&pbi->lf_worker);
vpx_free(pbi->lf_worker.data1); vpx_free(pbi->lf_worker.data1);
vpx_free(pbi->tile_data); vpx_free(pbi->tile_data);
......
...@@ -58,7 +58,7 @@ static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd, PLANE_TYPE type, ...@@ -58,7 +58,7 @@ static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd, PLANE_TYPE type,
int ctx, const int16_t *scan, const int16_t *nb, int ctx, const int16_t *scan, const int16_t *nb,
vp9_reader *r) { vp9_reader *r) {
const int max_eob = 16 << (tx_size << 1); const int max_eob = 16 << (tx_size << 1);
const FRAME_CONTEXT *const fc = &cm->fc; const FRAME_CONTEXT *const fc = cm->fc;
FRAME_COUNTS *const counts = &cm->counts; FRAME_COUNTS *const counts = &cm->counts;
const int ref = is_inter_block(&xd->mi[0].src_mi->mbmi); const int ref = is_inter_block(&xd->mi[0].src_mi->mbmi);
int band, c = 0; int band, c = 0;
......
...@@ -84,7 +84,7 @@ static void write_selected_tx_size(const VP9_COMMON *cm, ...@@ -84,7 +84,7 @@ static void write_selected_tx_size(const VP9_COMMON *cm,
vp9_writer *w) { vp9_writer *w) {
const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
const vp9_prob *const tx_probs = get_tx_probs2(max_tx_size, xd, const vp9_prob *const tx_probs = get_tx_probs2(max_tx_size, xd,
&cm->fc.tx_probs); &cm->fc->tx_probs);
vp9_write(w, tx_size != TX_4X4, tx_probs[0]); vp9_write(w, tx_size != TX_4X4, tx_probs[0]);
if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) { if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
vp9_write(w, tx_size != TX_8X8, tx_probs[1]); vp9_write(w, tx_size != TX_8X8, tx_probs[1]);
...@@ -108,14 +108,14 @@ static void update_skip_probs(VP9_COMMON *cm, vp9_writer *w) { ...@@ -108,14 +108,14 @@ static void update_skip_probs(VP9_COMMON *cm, vp9_writer *w) {
int k; int k;
for (k = 0; k < SKIP_CONTEXTS; ++k) for (k = 0; k < SKIP_CONTEXTS; ++k)
vp9_cond_prob_diff_update(w, &cm->fc.skip_probs[k], cm->counts.skip[k]); vp9_cond_prob_diff_update(w, &cm->fc->skip_probs[k], cm->counts.skip[k]);
} }
static void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) { static void update_switchable_interp_probs(VP9_COMMON *cm, vp9_writer *w) {
int j; int j;
for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
prob_diff_update(vp9_switchable_interp_tree, prob_diff_update(vp9_switchable_interp_tree,
cm->fc.switchable_interp_prob[j], cm->fc->switchable_interp_prob[j],
cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w); cm->counts.switchable_interp[j], SWITCHABLE_FILTERS, w);
} }
...@@ -237,7 +237,7 @@ static void write_ref_frames(const VP9_COMMON *cm, const MACROBLOCKD *xd, ...@@ -237,7 +237,7 @@ static void write_ref_frames(const VP9_COMMON *cm, const MACROBLOCKD *xd,
static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi, static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
vp9_writer *w) { vp9_writer *w) {
VP9_COMMON *const cm = &cpi->common; VP9_COMMON *const cm = &cpi->common;
const nmv_context *nmvc = &cm->fc.nmvc; const nmv_context *nmvc = &cm->fc->nmvc;
const MACROBLOCK *const x = &cpi->mb; const MACROBLOCK *const x = &cpi->mb;
const MACROBLOCKD *const xd = &x->e_mbd; const MACROBLOCKD *const xd = &x->e_mbd;
const struct segmentation *const seg = &cm->seg; const struct segmentation *const seg = &cm->seg;
...@@ -275,7 +275,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi, ...@@ -275,7 +275,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (!is_inter) { if (!is_inter) {
if (bsize >= BLOCK_8X8) { if (bsize >= BLOCK_8X8) {
write_intra_mode(w, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]); write_intra_mode(w, mode, cm->fc->y_mode_prob[size_group_lookup[bsize]]);
} else { } else {
int idx, idy; int idx, idy;
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
...@@ -283,14 +283,14 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi, ...@@ -283,14 +283,14 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
for (idy = 0; idy < 2; idy += num_4x4_h) { for (idy = 0; idy < 2; idy += num_4x4_h) {
for (idx = 0; idx < 2; idx += num_4x4_w) { for (idx = 0; idx < 2; idx += num_4x4_w) {
const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode; const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode;
write_intra_mode(w, b_mode, cm->fc.y_mode_prob[0]); write_intra_mode(w, b_mode, cm->fc->y_mode_prob[0]);
} }
} }
} }
write_intra_mode(w, mbmi->uv_mode, cm->fc.uv_mode_prob[mode]); write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mode]);
} else { } else {
const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]]; const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx]; const vp9_prob *const inter_probs = cm->fc->inter_mode_probs[mode_ctx];
write_ref_frames(cm, xd, w); write_ref_frames(cm, xd, w);
// If segment skip is not enabled code the mode. // If segment skip is not enabled code the mode.
...@@ -304,7 +304,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi, ...@@ -304,7 +304,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (cm->interp_filter == SWITCHABLE) { if (cm->interp_filter == SWITCHABLE) {
const int ctx = vp9_get_pred_context_switchable_interp(xd); const int ctx = vp9_get_pred_context_switchable_interp(xd);
vp9_write_token(w, vp9_switchable_interp_tree, vp9_write_token(w, vp9_switchable_interp_tree,
cm->fc.switchable_interp_prob[ctx], cm->fc->switchable_interp_prob[ctx],
&switchable_interp_encodings[mbmi->interp_filter]); &switchable_interp_encodings[mbmi->interp_filter]);
++cpi->interp_filter_selected[0][mbmi->interp_filter]; ++cpi->interp_filter_selected[0][mbmi->interp_filter];
} else { } else {
...@@ -528,7 +528,7 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, ...@@ -528,7 +528,7 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi,
TX_SIZE tx_size, TX_SIZE tx_size,
vp9_coeff_stats *frame_branch_ct, vp9_coeff_stats *frame_branch_ct,
vp9_coeff_probs_model *new_coef_probs) { vp9_coeff_probs_model *new_coef_probs) {
vp9_coeff_probs_model *old_coef_probs = cpi->common.fc.coef_probs[tx_size]; vp9_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size];
const vp9_prob upd = DIFF_UPDATE_PROB; const vp9_prob upd = DIFF_UPDATE_PROB;
const int entropy_nodes_update = UNCONSTRAINED_NODES; const int entropy_nodes_update = UNCONSTRAINED_NODES;
int i, j, k, l, t; int i, j, k, l, t;
...@@ -830,20 +830,20 @@ static void encode_txfm_probs(VP9_COMMON *cm, vp9_writer *w) { ...@@ -830,20 +830,20 @@ static void encode_txfm_probs(VP9_COMMON *cm, vp9_writer *w) {
for (i = 0; i < TX_SIZE_CONTEXTS; i++) { for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
tx_counts_to_branch_counts_8x8(cm->counts.tx.p8x8[i], ct_8x8p); tx_counts_to_branch_counts_8x8(cm->counts.tx.p8x8[i], ct_8x8p);
for (j = 0; j < TX_SIZES - 3; j++) for (j = 0; j < TX_SIZES - 3; j++)
vp9_cond_prob_diff_update(w, &cm->fc.tx_probs.p8x8[i][j], ct_8x8p[j]); vp9_cond_prob_diff_update(w, &cm->fc->tx_probs.p8x8[i][j], ct_8x8p[j]);
} }
for (i = 0; i < TX_SIZE_CONTEXTS; i++) { for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
tx_counts_to_branch_counts_16x16(cm->counts.tx.p16x16[i], ct_16x16p); tx_counts_to_branch_counts_16x16(cm->counts.tx.p16x16[i], ct_16x16p);
for (j = 0; j < TX_SIZES - 2; j++) for (j = 0; j < TX_SIZES - 2; j++)
vp9_cond_prob_diff_update(w, &cm->fc.tx_probs.p16x16[i][j], vp9_cond_prob_diff_update(w, &cm->fc->tx_probs.p16x16[i][j],
ct_16x16p[j]);