diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index ef14e1ab6..b770d0505 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -10,41 +10,39 @@ #include "./vpx_config.h" -#include "vp9/common/vp9_blockd.h" #include "vpx_mem/vpx_mem.h" -#include "vp9/common/vp9_onyxc_int.h" -#include "vp9/common/vp9_findnearmv.h" +#include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_entropymv.h" +#include "vp9/common/vp9_findnearmv.h" +#include "vp9/common/vp9_onyxc_int.h" #include "vp9/common/vp9_systemdependent.h" - -void vp9_update_mode_info_border(VP9_COMMON *cpi, MODE_INFO *mi) { - const int stride = cpi->mode_info_stride; +void vp9_update_mode_info_border(VP9_COMMON *cm, MODE_INFO *mi) { + const int stride = cm->mode_info_stride; int i; // Clear down top border row vpx_memset(mi, 0, sizeof(MODE_INFO) * stride); // Clear left border column - for (i = 1; i < cpi->mi_rows + 1; i++) + for (i = 1; i < cm->mi_rows + 1; i++) vpx_memset(&mi[i * stride], 0, sizeof(MODE_INFO)); } -void vp9_update_mode_info_in_image(VP9_COMMON *cpi, MODE_INFO *mi) { +void vp9_update_mode_info_in_image(VP9_COMMON *cm, MODE_INFO *mi) { int i, j; - MODE_INFO *ptr; // For each in image mode_info element set the in image flag to 1 - for (i = 0; i < cpi->mi_rows; i++) { - ptr = mi; - for (j = 0; j < cpi->mi_cols; j++) { + for (i = 0; i < cm->mi_rows; i++) { + MODE_INFO *ptr = mi; + for (j = 0; j < cm->mi_cols; j++) { ptr->mbmi.mb_in_image = 1; ptr++; // Next element in the row } // Step over border element at start of next row - mi += cpi->mode_info_stride; + mi += cm->mode_info_stride; } } @@ -69,23 +67,46 @@ void vp9_free_frame_buffers(VP9_COMMON *oci) { oci->above_seg_context = 0; } +static void set_mb_mi(VP9_COMMON *cm, int aligned_width, int aligned_height) { + cm->mb_cols = aligned_width >> 4; + cm->mb_rows = aligned_height >> 4; + cm->MBs = cm->mb_rows * cm->mb_cols; + + cm->mi_cols = aligned_width >> LOG2_MI_SIZE; + cm->mi_rows = aligned_height >> LOG2_MI_SIZE; + cm->mode_info_stride = cm->mi_cols + 1; +} + +static void setup_mi(VP9_COMMON *cm) { + cm->mi = cm->mip + cm->mode_info_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; + + vpx_memset(cm->mip, 0, + cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); + + vp9_update_mode_info_border(cm, cm->mip); + vp9_update_mode_info_in_image(cm, cm->mi); + + vp9_update_mode_info_border(cm, cm->prev_mip); + vp9_update_mode_info_in_image(cm, cm->prev_mi); +} + int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { int i, mi_cols; // Our internal buffers are always multiples of 16 const int aligned_width = multiple16(width); const int aligned_height = multiple16(height); + const int ss_x = oci->subsampling_x; + const int ss_y = oci->subsampling_y; vp9_free_frame_buffers(oci); for (i = 0; i < NUM_YV12_BUFFERS; i++) { oci->fb_idx_ref_cnt[i] = 0; - if (vp9_alloc_frame_buffer(&oci->yv12_fb[i], width, height, - oci->subsampling_x, oci->subsampling_y, - VP9BORDERINPIXELS) < 0) { - vp9_free_frame_buffers(oci); - return 1; - } + if (vp9_alloc_frame_buffer(&oci->yv12_fb[i], width, height, ss_x, ss_y, + VP9BORDERINPIXELS) < 0) + goto fail; } oci->new_fb_idx = NUM_YV12_BUFFERS - 1; @@ -99,47 +120,28 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { oci->fb_idx_ref_cnt[i] = 1; } - if (vp9_alloc_frame_buffer(&oci->temp_scale_frame, width, 16, - oci->subsampling_x, oci->subsampling_y, - VP9BORDERINPIXELS) < 0) { - vp9_free_frame_buffers(oci); - return 1; - } + if (vp9_alloc_frame_buffer(&oci->temp_scale_frame, width, 16, ss_x, ss_y, + VP9BORDERINPIXELS) < 0) + goto fail; - if (vp9_alloc_frame_buffer(&oci->post_proc_buffer, width, height, - oci->subsampling_x, oci->subsampling_y, - VP9BORDERINPIXELS) < 0) { - vp9_free_frame_buffers(oci); - return 1; - } + if (vp9_alloc_frame_buffer(&oci->post_proc_buffer, width, height, ss_x, ss_y, + VP9BORDERINPIXELS) < 0) + goto fail; - oci->mb_rows = aligned_height >> 4; - oci->mi_rows = aligned_height >> LOG2_MI_SIZE; - oci->mb_cols = aligned_width >> 4; - oci->mi_cols = aligned_width >> LOG2_MI_SIZE; - oci->MBs = oci->mb_rows * oci->mb_cols; - oci->mode_info_stride = oci->mi_cols + 1; + set_mb_mi(oci, aligned_width, aligned_height); + + // Allocation oci->mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1), sizeof(MODE_INFO)); - - if (!oci->mip) { - vp9_free_frame_buffers(oci); - return 1; - } - - oci->mi = oci->mip + oci->mode_info_stride + 1; - - /* allocate memory for last frame MODE_INFO array */ + if (!oci->mip) + goto fail; oci->prev_mip = vpx_calloc(oci->mode_info_stride * (oci->mi_rows + 1), sizeof(MODE_INFO)); + if (!oci->prev_mip) + goto fail; - if (!oci->prev_mip) { - vp9_free_frame_buffers(oci); - return 1; - } - - oci->prev_mi = oci->prev_mip + oci->mode_info_stride + 1; + setup_mi(oci); // FIXME(jkoleszar): allocate subsampled arrays for U/V once subsampling // information is exposed at this level @@ -150,26 +152,22 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { #else oci->above_context[0] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * 6 * mi_cols, 1); #endif - if (!oci->above_context[0]) { - vp9_free_frame_buffers(oci); - return 1; - } + if (!oci->above_context[0]) + goto fail; + for (i = 1; i < MAX_MB_PLANE; i++) oci->above_context[i] = oci->above_context[0] + i * sizeof(ENTROPY_CONTEXT) * 2 * mi_cols; - oci->above_seg_context = - vpx_calloc(sizeof(PARTITION_CONTEXT) * mi_cols, 1); - - if (!oci->above_seg_context) { - vp9_free_frame_buffers(oci); - return 1; - } - - vp9_update_mode_info_border(oci, oci->mip); - vp9_update_mode_info_in_image(oci, oci->mi); + oci->above_seg_context = vpx_calloc(sizeof(PARTITION_CONTEXT) * mi_cols, 1); + if (!oci->above_seg_context) + goto fail; return 0; + + fail: + vp9_free_frame_buffers(oci); + return 1; } void vp9_setup_version(VP9_COMMON *cm) { @@ -222,27 +220,10 @@ void vp9_initialize_common() { vp9_entropy_mv_init(); } - void vp9_update_frame_size(VP9_COMMON *cm) { const int aligned_width = multiple16(cm->width); const int aligned_height = multiple16(cm->height); - cm->mb_rows = aligned_height >> 4; - cm->mb_cols = aligned_width >> 4; - - cm->mi_rows = aligned_height >> LOG2_MI_SIZE; - cm->mi_cols = aligned_width >> LOG2_MI_SIZE; - - cm->MBs = cm->mb_rows * cm->mb_cols; - cm->mode_info_stride = cm->mi_cols + 1; - cm->mi = cm->mip + cm->mode_info_stride + 1; - cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; - - memset(cm->mip, 0, - cm->mode_info_stride * (cm->mi_rows + 1) * sizeof(MODE_INFO)); - vp9_update_mode_info_border(cm, cm->mip); - vp9_update_mode_info_in_image(cm, cm->mi); - - vp9_update_mode_info_border(cm, cm->prev_mip); - vp9_update_mode_info_in_image(cm, cm->prev_mi); + set_mb_mi(cm, aligned_width, aligned_height); + setup_mi(cm); } diff --git a/vp9/common/vp9_alloccommon.h b/vp9/common/vp9_alloccommon.h index 814a7607a..fc79f6377 100644 --- a/vp9/common/vp9_alloccommon.h +++ b/vp9/common/vp9_alloccommon.h @@ -14,6 +14,8 @@ #include "vp9/common/vp9_onyxc_int.h" +void vp9_initialize_common(); + void vp9_update_mode_info_border(VP9_COMMON *cpi, MODE_INFO *mi); void vp9_update_mode_info_in_image(VP9_COMMON *cpi, MODE_INFO *mi); diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h index 7fb0d895d..e18d353d3 100644 --- a/vp9/common/vp9_enums.h +++ b/vp9/common/vp9_enums.h @@ -16,8 +16,6 @@ #define LOG2_MI_SIZE 3 #define MI_SIZE (1 << LOG2_MI_SIZE) -#define MI_UV_SIZE (1 << (LOG2_MI_SIZE - 1)) - #define MI_MASK ((64 >> LOG2_MI_SIZE) - 1) typedef enum BLOCK_SIZE_TYPE { diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 665f00e91..ddc0c39ab 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -26,8 +26,6 @@ /* Create/destroy static data structures. */ -void vp9_initialize_common(void); - // Define the number of candidate reference buffers. #define NUM_REF_FRAMES 8 #define NUM_REF_FRAMES_LG2 3 @@ -248,9 +246,6 @@ typedef struct VP9Common { int near_boffset[3]; int version; -#ifdef PACKET_TESTING - VP9_HEADER oh; -#endif double bitrate; double framerate; diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 45b0c63c1..a9717222a 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -530,25 +530,6 @@ static void setup_token_decoder(VP9D_COMP *pbi, "Failed to allocate bool decoder %d", 1); } -static void init_frame(VP9D_COMP *pbi) { - VP9_COMMON *const pc = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - - if (pc->frame_type == KEY_FRAME) { - vp9_setup_past_independence(pc, xd); - // All buffers are implicitly updated on key frames. - pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1; - } else if (pc->error_resilient_mode) { - vp9_setup_past_independence(pc, xd); - } - - xd->mode_info_context = pc->mi; - xd->prev_mode_info_context = pc->prev_mi; - xd->frame_type = pc->frame_type; - xd->mode_info_context->mbmi.mode = DC_PRED; - xd->mode_info_stride = pc->mode_info_stride; -} - static void read_coef_probs_common(FRAME_CONTEXT *fc, TX_SIZE tx_size, vp9_reader *r) { const int entropy_nodes_update = UNCONSTRAINED_NODES; @@ -646,22 +627,6 @@ static void setup_segmentation(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) { } } -static void setup_pred_probs(VP9_COMMON *pc, vp9_reader *r) { - // Read common prediction model status flag probability updates for the - // reference frame - if (pc->frame_type == KEY_FRAME) { - // Set the prediction probabilities to defaults - pc->ref_pred_probs[0] = DEFAULT_PRED_PROB_0; - pc->ref_pred_probs[1] = DEFAULT_PRED_PROB_1; - pc->ref_pred_probs[2] = DEFAULT_PRED_PROB_2; - } else { - int i; - for (i = 0; i < PREDICTION_PROBS; ++i) - if (vp9_read_bit(r)) - pc->ref_pred_probs[i] = vp9_read_prob(r); - } -} - static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; @@ -716,9 +681,10 @@ static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { vp9_init_dequantizer(cm); } -static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) { - return vp9_read_bit(r) ? SWITCHABLE - : vp9_read_literal(r, 2); +static INTERPOLATIONFILTERTYPE read_interp_filter_type( + struct vp9_read_bit_buffer *rb) { + return vp9_rb_read_bit(rb) ? SWITCHABLE + : vp9_rb_read_literal(rb, 2); } static void read_frame_size(VP9_COMMON *cm, @@ -757,8 +723,8 @@ static void setup_frame_size(VP9D_COMP *pbi, int scaling_active, if (vp9_alloc_frame_buffers(pc, width, height)) vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate frame buffers"); - pbi->initial_width = width; - pbi->initial_height = height; + pbi->initial_width = width; + pbi->initial_height = height; } else { if (width > pbi->initial_width) vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, @@ -776,6 +742,10 @@ static void setup_frame_size(VP9D_COMP *pbi, int scaling_active, vp9_update_frame_size(pc); } + + vp9_realloc_frame_buffer(&pc->yv12_fb[pc->new_fb_idx], pc->width, pc->height, + pc->subsampling_x, pc->subsampling_y, + VP9BORDERINPIXELS); } static void update_frame_context(FRAME_CONTEXT *fc) { @@ -784,10 +754,8 @@ static void update_frame_context(FRAME_CONTEXT *fc) { vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob); vp9_copy(fc->pre_partition_prob, fc->partition_prob); fc->pre_nmvc = fc->nmvc; - vp9_copy(fc->pre_switchable_interp_prob, - fc->switchable_interp_prob); - vp9_copy(fc->pre_inter_mode_probs, - fc->inter_mode_probs); + vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob); + vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs); vp9_zero(fc->coef_counts); vp9_zero(fc->eob_branch_counts); @@ -909,8 +877,9 @@ static void error_handler(void *data, int bit_offset) { size_t read_uncompressed_header(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { VP9_COMMON *const cm = &pbi->common; + MACROBLOCKD *const xd = &pbi->mb; - int scaling_active; + int scaling_active, i; cm->last_frame_type = cm->frame_type; cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb); cm->version = vp9_rb_read_literal(rb, 3); @@ -923,22 +892,13 @@ size_t read_uncompressed_header(VP9D_COMP *pbi, if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 || vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 || vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) { - vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame sync code"); + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, + "Invalid frame sync code"); } } setup_frame_size(pbi, scaling_active, rb); - if (!cm->show_frame) { - cm->intra_only = vp9_rb_read_bit(rb); - } else { - cm->intra_only = 0; - } - - cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2); - cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb); - cm->error_resilient_mode = vp9_rb_read_bit(rb); if (!cm->error_resilient_mode) { cm->reset_frame_context = vp9_rb_read_bit(rb); @@ -950,6 +910,44 @@ size_t read_uncompressed_header(VP9D_COMP *pbi, cm->frame_parallel_decoding_mode = 1; } + if (cm->frame_type == KEY_FRAME) { + vp9_setup_past_independence(cm, xd); + + pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1; + + for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) + cm->active_ref_idx[i] = cm->new_fb_idx; + + cm->ref_pred_probs[0] = DEFAULT_PRED_PROB_0; + cm->ref_pred_probs[1] = DEFAULT_PRED_PROB_1; + cm->ref_pred_probs[2] = DEFAULT_PRED_PROB_2; + } else { + if (cm->error_resilient_mode) + vp9_setup_past_independence(cm, xd); + + pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES); + + for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { + const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LG2); + cm->active_ref_idx[i] = cm->ref_frame_map[ref]; + vp9_setup_scale_factors(cm, i); + } + + for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) + cm->ref_frame_sign_bias[i + 1] = vp9_rb_read_bit(rb); + + for (i = 0; i < PREDICTION_PROBS; ++i) + if (vp9_rb_read_bit(rb)) + cm->ref_pred_probs[i] = vp9_rb_read_literal(rb, 8); + + xd->allow_high_precision_mv = vp9_rb_read_bit(rb); + cm->mcomp_filter_type = read_interp_filter_type(rb); + } + + cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb); + cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2); + cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb); + setup_loopfilter(pbi, rb); setup_quantization(pbi, rb); @@ -961,7 +959,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { vp9_reader header_bc, residual_bc; VP9_COMMON *const pc = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; - YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx]; + const uint8_t *data = pbi->source; const uint8_t *data_end = pbi->source + pbi->source_sz; @@ -969,6 +967,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { pc, error_handler }; const size_t first_partition_size = read_uncompressed_header(pbi, &rb); const int keyframe = pc->frame_type == KEY_FRAME; + YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx]; data += vp9_rb_bytes_read(&rb); xd->corrupted = 0; @@ -981,15 +980,13 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { vp9_setup_version(pc); if (!read_is_valid(data, first_partition_size, data_end)) - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition 0 length"); + vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, + "Truncated packet or corrupt partition 0 length"); - init_frame(pbi); - - // Reset the frame pointers to the current frame size - vp9_realloc_frame_buffer(new_fb, pc->width, pc->height, - pc->subsampling_x, pc->subsampling_y, - VP9BORDERINPIXELS); + xd->mode_info_context = pc->mi; + xd->prev_mode_info_context = pc->prev_mi; + xd->frame_type = pc->frame_type; + xd->mode_info_stride = pc->mode_info_stride; if (vp9_reader_init(&header_bc, data, first_partition_size)) vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, @@ -1011,44 +1008,15 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { xd->itxm_add_uv_block = vp9_idct_add_uv_block; } - // Determine if the golden frame or ARF buffer should be updated and how. - // For all non key frames the GF and ARF refresh flags and sign bias - // flags must be set explicitly. - if (keyframe) { - for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) - pc->active_ref_idx[i] = pc->new_fb_idx; - } else { - // Should the GF or ARF be updated from the current frame - pbi->refresh_frame_flags = vp9_read_literal(&header_bc, NUM_REF_FRAMES); - - // Select active reference frames and calculate scaling factors - for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { - const int ref = vp9_read_literal(&header_bc, NUM_REF_FRAMES_LG2); - pc->active_ref_idx[i] = pc->ref_frame_map[ref]; - vp9_setup_scale_factors(pc, i); - } - - // Read the sign bias for each reference frame buffer. - for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) - pc->ref_frame_sign_bias[i + 1] = vp9_read_bit(&header_bc); - - xd->allow_high_precision_mv = vp9_read_bit(&header_bc); - pc->mcomp_filter_type = read_mcomp_filter_type(&header_bc); - - // To enable choice of different interpolation filters + if (!keyframe) vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc); - } pc->fc = pc->frame_contexts[pc->frame_context_idx]; setup_segmentation(pc, xd, &header_bc); - setup_pred_probs(pc, &header_bc); - setup_txfm_mode(pc, xd->lossless, &header_bc); - // Read inter mode probability context updates - update_frame_context(&pc->fc); read_coef_probs(pbi, &header_bc); diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index ff709508f..c6c8dca93 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -53,11 +53,6 @@ extern unsigned int active_section; static int update_bits[255]; -static INLINE void write_le16(uint8_t *p, int value) { - p[0] = value; - p[1] = value >> 8; -} - static INLINE void write_le32(uint8_t *p, int value) { p[0] = value; p[1] = value >> 8; @@ -1169,6 +1164,8 @@ static void update_coef_probs_common(vp9_writer* const bc, VP9_COMP *cpi, } static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) { + const TXFM_MODE txfm_mode = cpi->common.txfm_mode; + vp9_clear_system_state(); // Build the cofficient contexts based on counts collected in encode loop @@ -1176,18 +1173,15 @@ static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) { update_coef_probs_common(bc, cpi, TX_4X4); - /* do not do this if not even allowed */ - if (cpi->common.txfm_mode != ONLY_4X4) { + // do not do this if not even allowed + if (txfm_mode > ONLY_4X4) update_coef_probs_common(bc, cpi, TX_8X8); - } - if (cpi->common.txfm_mode > ALLOW_8X8) { + if (txfm_mode > ALLOW_8X8) update_coef_probs_common(bc, cpi, TX_16X16); - } - if (cpi->common.txfm_mode > ALLOW_16X16) { + if (txfm_mode > ALLOW_16X16) update_coef_probs_common(bc, cpi, TX_32X32); - } } static void segment_reference_frames(VP9_COMP *cpi) { @@ -1395,6 +1389,38 @@ static void encode_txfm(VP9_COMP *cpi, vp9_writer *w) { } } +static void write_interp_filter_type(INTERPOLATIONFILTERTYPE type, + struct vp9_write_bit_buffer *wb) { + vp9_wb_write_bit(wb, type == SWITCHABLE); + if (type != SWITCHABLE) + vp9_wb_write_literal(wb, type, 2); +} + +static void fix_mcomp_filter_type(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + + if (cm->mcomp_filter_type == SWITCHABLE) { + // Check to see if only one of the filters is actually used + int count[VP9_SWITCHABLE_FILTERS]; + int i, j, c = 0; + for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) { + count[i] = 0; + for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) + count[i] += cm->fc.switchable_interp_count[j][i]; + c += (count[i] > 0); + } + if (c == 1) { + // Only one filter is used. So set the filter at frame level + for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) { + if (count[i]) { + cm->mcomp_filter_type = vp9_switchable_interp[i]; + break; + } + } + } + } +} + void write_uncompressed_header(VP9_COMP *cpi, struct vp9_write_bit_buffer *wb) { VP9_COMMON *const cm = &cpi->common; @@ -1424,13 +1450,6 @@ void write_uncompressed_header(VP9_COMP *cpi, vp9_wb_write_literal(wb, cm->width, 16); vp9_wb_write_literal(wb, cm->height, 16); - if (!cm->show_frame) { - vp9_wb_write_bit(wb, cm->intra_only); - } - - vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2); - vp9_wb_write_bit(wb, cm->clr_type); - vp9_wb_write_bit(wb, cm->error_resilient_mode); if (!cm->error_resilient_mode) { vp9_wb_write_bit(wb, cm->reset_frame_context); @@ -1438,6 +1457,76 @@ void write_uncompressed_header(VP9_COMP *cpi, vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode); } + // When there is a key frame all reference buffers are updated using the new key frame + if (cm->frame_type != KEY_FRAME) { + int refresh_mask, i; + + // Should the GF or ARF be updated using the transmitted frame or buffer +#if CONFIG_MULTIPLE_ARF + if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame && + !cpi->refresh_alt_ref_frame) { +#else + if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) { +#endif + // Preserve the previously existing golden frame and update the frame in + // the alt ref slot instead. This is highly specific to the use of + // alt-ref as a forward reference, and this needs to be generalized as + // other uses are implemented (like RTC/temporal scaling) + // + // gld_fb_idx and alt_fb_idx need to be swapped for future frames, but + // that happens in vp9_onyx_if.c:update_reference_frames() so that it can + // be done outside of the recode loop. + refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) | + (cpi->refresh_golden_frame << cpi->alt_fb_idx); + } else { + int arf_idx = cpi->alt_fb_idx; +#if CONFIG_MULTIPLE_ARF + // Determine which ARF buffer to use to encode this ARF frame. + if (cpi->multi_arf_enabled) { + int sn = cpi->sequence_number; + arf_idx = (cpi->frame_coding_order[sn] < 0) ? + cpi->arf_buffer_idx[sn + 1] : + cpi->arf_buffer_idx[sn]; + } +#endif + refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) | + (cpi->refresh_golden_frame << cpi->gld_fb_idx) | + (cpi->refresh_alt_ref_frame << arf_idx); + } + + vp9_wb_write_literal(wb, refresh_mask, NUM_REF_FRAMES); + vp9_wb_write_literal(wb, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2); + vp9_wb_write_literal(wb, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2); + vp9_wb_write_literal(wb, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2); + + // Indicate the sign bias for each reference frame buffer. + for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) + vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]); + + // Encode the common prediction model status flag probability updates for + // the reference frame + update_refpred_stats(cpi); + for (i = 0; i < PREDICTION_PROBS; i++) { + const int update = cpi->ref_pred_probs_update[i]; + vp9_wb_write_bit(wb, update); + if (update) + vp9_wb_write_literal(wb, cm->ref_pred_probs[i], 8); + } + + // Signal whether to allow high MV precision + vp9_wb_write_bit(wb, xd->allow_high_precision_mv); + + // Signal the type of subpel filter to use + fix_mcomp_filter_type(cpi); + write_interp_filter_type(cm->mcomp_filter_type, wb); + } + + if (!cm->show_frame) + vp9_wb_write_bit(wb, cm->intra_only); + + vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2); + vp9_wb_write_bit(wb, cm->clr_type); + encode_loopfilter(cm, xd, wb); encode_quantization(cm, wb); } @@ -1463,82 +1552,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { vp9_start_encode(&header_bc, cx_data); - // When there is a key frame all reference buffers are updated using the new key frame - if (pc->frame_type != KEY_FRAME) { - int refresh_mask; - - // Should the GF or ARF be updated using the transmitted frame or buffer -#if CONFIG_MULTIPLE_ARF - if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame && - !cpi->refresh_alt_ref_frame) { -#else - if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) { -#endif - /* Preserve the previously existing golden frame and update the frame in - * the alt ref slot instead. This is highly specific to the use of - * alt-ref as a forward reference, and this needs to be generalized as - * other uses are implemented (like RTC/temporal scaling) - * - * gld_fb_idx and alt_fb_idx need to be swapped for future frames, but - * that happens in vp9_onyx_if.c:update_reference_frames() so that it can - * be done outside of the recode loop. - */ - refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) | - (cpi->refresh_golden_frame << cpi->alt_fb_idx); - } else { - int arf_idx = cpi->alt_fb_idx; -#if CONFIG_MULTIPLE_ARF - // Determine which ARF buffer to use to encode this ARF frame. - if (cpi->multi_arf_enabled) { - int sn = cpi->sequence_number; - arf_idx = (cpi->frame_coding_order[sn] < 0) ? - cpi->arf_buffer_idx[sn + 1] : - cpi->arf_buffer_idx[sn]; - } -#endif - refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) | - (cpi->refresh_golden_frame << cpi->gld_fb_idx) | - (cpi->refresh_alt_ref_frame << arf_idx); - } - - vp9_write_literal(&header_bc, refresh_mask, NUM_REF_FRAMES); - vp9_write_literal(&header_bc, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2); - vp9_write_literal(&header_bc, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2); - vp9_write_literal(&header_bc, cpi->alt_fb_idx, NUM_REF_FRAMES_LG2); - - // Indicate the sign bias for each reference frame buffer. - for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { - vp9_write_bit(&header_bc, pc->ref_frame_sign_bias[LAST_FRAME + i]); - } - - // Signal whether to allow high MV precision - vp9_write_bit(&header_bc, (xd->allow_high_precision_mv) ? 1 : 0); - if (pc->mcomp_filter_type == SWITCHABLE) { - /* Check to see if only one of the filters is actually used */ - int count[VP9_SWITCHABLE_FILTERS]; - int i, j, c = 0; - for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) { - count[i] = 0; - for (j = 0; j <= VP9_SWITCHABLE_FILTERS; ++j) - count[i] += cpi->common.fc.switchable_interp_count[j][i]; - c += (count[i] > 0); - } - if (c == 1) { - /* Only one filter is used. So set the filter at frame level */ - for (i = 0; i < VP9_SWITCHABLE_FILTERS; ++i) { - if (count[i]) { - pc->mcomp_filter_type = vp9_switchable_interp[i]; - break; - } - } - } - } - // Signal the type of subpel filter to use - vp9_write_bit(&header_bc, (pc->mcomp_filter_type == SWITCHABLE)); - if (pc->mcomp_filter_type != SWITCHABLE) - vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2); - } - #ifdef ENTROPY_STATS if (pc->frame_type == INTER_FRAME) active_section = 0; @@ -1548,20 +1561,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { encode_segmentation(cpi, &header_bc); - // Encode the common prediction model status flag probability updates for - // the reference frame - update_refpred_stats(cpi); - if (pc->frame_type != KEY_FRAME) { - for (i = 0; i < PREDICTION_PROBS; i++) { - if (cpi->ref_pred_probs_update[i]) { - vp9_write_bit(&header_bc, 1); - vp9_write_prob(&header_bc, pc->ref_pred_probs[i]); - } else { - vp9_write_bit(&header_bc, 0); - } - } - } - if (xd->lossless) pc->txfm_mode = ONLY_4X4; else @@ -1569,15 +1568,13 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { vp9_clear_system_state(); // __asm emms; - vp9_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs); - vp9_copy(cpi->common.fc.pre_y_mode_prob, cpi->common.fc.y_mode_prob); - vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob); - vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob); - cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc; - vp9_copy(cpi->common.fc.pre_switchable_interp_prob, - cpi->common.fc.switchable_interp_prob); - vp9_copy(cpi->common.fc.pre_inter_mode_probs, - cpi->common.fc.inter_mode_probs); + vp9_copy(pc->fc.pre_coef_probs, pc->fc.coef_probs); + vp9_copy(pc->fc.pre_y_mode_prob, pc->fc.y_mode_prob); + vp9_copy(pc->fc.pre_uv_mode_prob, pc->fc.uv_mode_prob); + vp9_copy(pc->fc.pre_partition_prob, pc->fc.partition_prob); + pc->fc.pre_nmvc = pc->fc.nmvc; + vp9_copy(pc->fc.pre_switchable_interp_prob, pc->fc.switchable_interp_prob); + vp9_copy(pc->fc.pre_inter_mode_probs, pc->fc.inter_mode_probs); update_coef_probs(cpi, &header_bc); @@ -1586,9 +1583,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { #endif vp9_update_skip_probs(cpi); - for (i = 0; i < MBSKIP_CONTEXTS; ++i) { + for (i = 0; i < MBSKIP_CONTEXTS; ++i) vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]); - } if (pc->frame_type != KEY_FRAME) {