Index: source/libvpx/vp9/common/vp9_onyxc_int.h |
=================================================================== |
--- source/libvpx/vp9/common/vp9_onyxc_int.h (revision 240950) |
+++ source/libvpx/vp9/common/vp9_onyxc_int.h (working copy) |
@@ -25,24 +25,29 @@ |
#include "vp9/common/vp9_postproc.h" |
#endif |
-#define ALLOWED_REFS_PER_FRAME 3 |
+#define REFS_PER_FRAME 3 |
-#define NUM_REF_FRAMES_LOG2 3 |
-#define NUM_REF_FRAMES (1 << NUM_REF_FRAMES_LOG2) |
+#define REF_FRAMES_LOG2 3 |
+#define REF_FRAMES (1 << REF_FRAMES_LOG2) |
// 1 scratch frame for the new frame, 3 for scaled references on the encoder |
// TODO(jkoleszar): These 3 extra references could probably come from the |
// normal reference pool. |
-#define NUM_YV12_BUFFERS (NUM_REF_FRAMES + 4) |
+#define FRAME_BUFFERS (REF_FRAMES + 4) |
-#define NUM_FRAME_CONTEXTS_LOG2 2 |
-#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LOG2) |
+#define FRAME_CONTEXTS_LOG2 2 |
+#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2) |
+extern const struct { |
+ PARTITION_CONTEXT above; |
+ PARTITION_CONTEXT left; |
+} partition_context_lookup[BLOCK_SIZES]; |
+ |
typedef struct frame_contexts { |
vp9_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1]; |
vp9_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; |
- vp9_prob partition_prob[FRAME_TYPES][PARTITION_CONTEXTS][PARTITION_TYPES - 1]; |
- vp9_coeff_probs_model coef_probs[TX_SIZES][BLOCK_TYPES]; |
+ vp9_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; |
+ vp9_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES]; |
vp9_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] |
[SWITCHABLE_FILTERS - 1]; |
vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1]; |
@@ -59,9 +64,9 @@ |
unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES]; |
unsigned int uv_mode[INTRA_MODES][INTRA_MODES]; |
unsigned int partition[PARTITION_CONTEXTS][PARTITION_TYPES]; |
- vp9_coeff_count_model coef[TX_SIZES][BLOCK_TYPES]; |
- unsigned int eob_branch[TX_SIZES][BLOCK_TYPES][REF_TYPES] |
- [COEF_BANDS][PREV_COEF_CONTEXTS]; |
+ vp9_coeff_count_model coef[TX_SIZES][PLANE_TYPES]; |
+ unsigned int eob_branch[TX_SIZES][PLANE_TYPES][REF_TYPES] |
+ [COEF_BANDS][COEFF_CONTEXTS]; |
unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS] |
[SWITCHABLE_FILTERS]; |
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES]; |
@@ -76,11 +81,11 @@ |
typedef enum { |
- SINGLE_PREDICTION_ONLY = 0, |
- COMP_PREDICTION_ONLY = 1, |
- HYBRID_PREDICTION = 2, |
- NB_PREDICTION_TYPES = 3, |
-} COMPPREDMODE_TYPE; |
+ SINGLE_REFERENCE = 0, |
+ COMPOUND_REFERENCE = 1, |
+ REFERENCE_MODE_SELECT = 2, |
+ REFERENCE_MODES = 3, |
+} REFERENCE_MODE; |
typedef struct VP9Common { |
struct vpx_internal_error_info error; |
@@ -108,17 +113,17 @@ |
YV12_BUFFER_CONFIG *frame_to_show; |
- YV12_BUFFER_CONFIG yv12_fb[NUM_YV12_BUFFERS]; |
- int fb_idx_ref_cnt[NUM_YV12_BUFFERS]; /* reference counts */ |
- int ref_frame_map[NUM_REF_FRAMES]; /* maps fb_idx to reference slot */ |
+ YV12_BUFFER_CONFIG *yv12_fb; |
+ int *fb_idx_ref_cnt; /* reference counts */ |
+ int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */ |
// TODO(jkoleszar): could expand active_ref_idx to 4, with 0 as intra, and |
// roll new_fb_idx into it. |
- // Each frame can reference ALLOWED_REFS_PER_FRAME buffers |
- int active_ref_idx[ALLOWED_REFS_PER_FRAME]; |
- struct scale_factors active_ref_scale[ALLOWED_REFS_PER_FRAME]; |
- struct scale_factors_common active_ref_scale_comm[ALLOWED_REFS_PER_FRAME]; |
+ // Each frame can reference REFS_PER_FRAME buffers |
+ int active_ref_idx[REFS_PER_FRAME]; |
+ struct scale_factors active_ref_scale[REFS_PER_FRAME]; |
+ struct scale_factors_common active_ref_scale_comm[REFS_PER_FRAME]; |
int new_fb_idx; |
YV12_BUFFER_CONFIG post_proc_buffer; |
@@ -190,10 +195,10 @@ |
int allow_comp_inter_inter; |
MV_REFERENCE_FRAME comp_fixed_ref; |
MV_REFERENCE_FRAME comp_var_ref[2]; |
- COMPPREDMODE_TYPE comp_pred_mode; |
+ REFERENCE_MODE reference_mode; |
FRAME_CONTEXT fc; /* this frame entropy */ |
- FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS]; |
+ FRAME_CONTEXT frame_contexts[FRAME_CONTEXTS]; |
unsigned int frame_context_idx; /* Context to use/update */ |
FRAME_COUNTS counts; |
@@ -208,6 +213,15 @@ |
int frame_parallel_decoding_mode; |
int log2_tile_cols, log2_tile_rows; |
+ |
+ vpx_codec_frame_buffer_t *fb_list; // External frame buffers |
+ int fb_count; // Total number of frame buffers |
+ vpx_realloc_frame_buffer_cb_fn_t realloc_fb_cb; |
+ void *user_priv; // Private data associated with the external frame buffers. |
+ |
+ int fb_lru; // Flag telling if lru is on/off |
+ uint32_t *fb_idx_ref_lru; // Frame buffer lru cache |
+ uint32_t fb_idx_ref_lru_count; |
} VP9_COMMON; |
// ref == 0 => LAST_FRAME |
@@ -223,19 +237,35 @@ |
static int get_free_fb(VP9_COMMON *cm) { |
int i; |
- for (i = 0; i < NUM_YV12_BUFFERS; i++) |
- if (cm->fb_idx_ref_cnt[i] == 0) |
- break; |
+ uint32_t lru_count = cm->fb_idx_ref_lru_count + 1; |
+ int free_buffer_idx = cm->fb_count; |
+ for (i = 0; i < cm->fb_count; i++) { |
+ if (!cm->fb_lru) { |
+ if (cm->fb_idx_ref_cnt[i] == 0) { |
+ free_buffer_idx = i; |
+ break; |
+ } |
+ } else { |
+ if (cm->fb_idx_ref_cnt[i] == 0 && cm->fb_idx_ref_lru[i] < lru_count) { |
+ free_buffer_idx = i; |
+ lru_count = cm->fb_idx_ref_lru[i]; |
+ } |
+ } |
+ } |
- assert(i < NUM_YV12_BUFFERS); |
- cm->fb_idx_ref_cnt[i] = 1; |
- return i; |
+ assert(free_buffer_idx < cm->fb_count); |
+ cm->fb_idx_ref_cnt[free_buffer_idx] = 1; |
+ if (cm->fb_lru) |
+ cm->fb_idx_ref_lru[free_buffer_idx] = ++cm->fb_idx_ref_lru_count; |
+ return free_buffer_idx; |
} |
static void ref_cnt_fb(int *buf, int *idx, int new_idx) { |
- if (buf[*idx] > 0) |
- buf[*idx]--; |
+ const int ref_index = *idx; |
+ if (ref_index >= 0 && buf[ref_index] > 0) |
+ buf[ref_index]--; |
+ |
*idx = new_idx; |
buf[new_idx]++; |
@@ -245,6 +275,11 @@ |
return ALIGN_POWER_OF_TWO(n_mis, MI_BLOCK_SIZE_LOG2); |
} |
+static INLINE const vp9_prob* get_partition_probs(VP9_COMMON *cm, int ctx) { |
+ return cm->frame_type == KEY_FRAME ? vp9_kf_partition_probs[ctx] |
+ : cm->fc.partition_prob[ctx]; |
+} |
+ |
static INLINE void set_skip_context( |
MACROBLOCKD *xd, |
ENTROPY_CONTEXT *above_context[MAX_MB_PLANE], |
@@ -293,53 +328,41 @@ |
static INLINE void update_partition_context( |
PARTITION_CONTEXT *above_seg_context, |
PARTITION_CONTEXT left_seg_context[8], |
- int mi_row, int mi_col, |
- BLOCK_SIZE sb_type, |
- BLOCK_SIZE sb_size) { |
- PARTITION_CONTEXT *above_ctx = above_seg_context + mi_col; |
- PARTITION_CONTEXT *left_ctx = left_seg_context + (mi_row & MI_MASK); |
+ int mi_row, int mi_col, BLOCK_SIZE subsize, BLOCK_SIZE bsize) { |
+ PARTITION_CONTEXT *const above_ctx = above_seg_context + mi_col; |
+ PARTITION_CONTEXT *const left_ctx = left_seg_context + (mi_row & MI_MASK); |
- const int bsl = b_width_log2(sb_size), bs = (1 << bsl) / 2; |
- const int bwl = b_width_log2(sb_type); |
- const int bhl = b_height_log2(sb_type); |
- const int boffset = b_width_log2(BLOCK_64X64) - bsl; |
- const char pcval0 = ~(0xe << boffset); |
- const char pcval1 = ~(0xf << boffset); |
- const char pcvalue[2] = {pcval0, pcval1}; |
+ // num_4x4_blocks_wide_lookup[bsize] / 2 |
+ const int bs = num_8x8_blocks_wide_lookup[bsize]; |
- assert(MAX(bwl, bhl) <= bsl); |
- |
// update the partition context at the end notes. set partition bits |
// of block sizes larger than the current one to be one, and partition |
// bits of smaller block sizes to be zero. |
- vpx_memset(above_ctx, pcvalue[bwl == bsl], bs); |
- vpx_memset(left_ctx, pcvalue[bhl == bsl], bs); |
+ vpx_memset(above_ctx, partition_context_lookup[subsize].above, bs); |
+ vpx_memset(left_ctx, partition_context_lookup[subsize].left, bs); |
} |
static INLINE int partition_plane_context( |
const PARTITION_CONTEXT *above_seg_context, |
const PARTITION_CONTEXT left_seg_context[8], |
- int mi_row, int mi_col, |
- BLOCK_SIZE sb_type) { |
+ int mi_row, int mi_col, BLOCK_SIZE bsize) { |
const PARTITION_CONTEXT *above_ctx = above_seg_context + mi_col; |
const PARTITION_CONTEXT *left_ctx = left_seg_context + (mi_row & MI_MASK); |
- int bsl = mi_width_log2(sb_type), bs = 1 << bsl; |
+ const int bsl = mi_width_log2(bsize); |
+ const int bs = 1 << bsl; |
int above = 0, left = 0, i; |
- int boffset = mi_width_log2(BLOCK_64X64) - bsl; |
- assert(mi_width_log2(sb_type) == mi_height_log2(sb_type)); |
+ assert(mi_width_log2(bsize) == mi_height_log2(bsize)); |
assert(bsl >= 0); |
- assert(boffset >= 0); |
- for (i = 0; i < bs; i++) |
- above |= (above_ctx[i] & (1 << boffset)); |
- for (i = 0; i < bs; i++) |
- left |= (left_ctx[i] & (1 << boffset)); |
+ for (i = 0; i < bs; i++) { |
+ above |= above_ctx[i]; |
+ left |= left_ctx[i]; |
+ } |
+ above = (above & bs) > 0; |
+ left = (left & bs) > 0; |
- above = (above > 0); |
- left = (left > 0); |
- |
return (left * 2 + above) + bsl * PARTITION_PLOFFSET; |
} |