Moving bits from compressed header to uncompressed one.
Bits moved: refresh_frame_flags, active_ref_idx[], ref_frame_sign_bias[], allow_high_precision_mv, mcomp_filter_type, ref_pred_probs[]. Derf results: +0.040% Change-Id: I011f43c7eac0371d533b255fd99aee5ed75b85a5
This commit is contained in:
parent
30226a658f
commit
12345cb391
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user