| 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;
|
| }
|
|
|
|
|