| Index: source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 177019)
|
| +++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy)
|
| @@ -9,13 +9,14 @@
|
| */
|
|
|
|
|
| -#include "vpx_ports/config.h"
|
| +#include "./vpx_config.h"
|
| #include "vp9/encoder/vp9_encodeframe.h"
|
| #include "vp9/encoder/vp9_encodemb.h"
|
| #include "vp9/encoder/vp9_encodemv.h"
|
| #include "vp9/common/vp9_common.h"
|
| #include "vp9/encoder/vp9_onyx_int.h"
|
| #include "vp9/common/vp9_extend.h"
|
| +#include "vp9/common/vp9_entropy.h"
|
| #include "vp9/common/vp9_entropymode.h"
|
| #include "vp9/common/vp9_quant_common.h"
|
| #include "vp9/encoder/vp9_segmentation.h"
|
| @@ -44,15 +45,20 @@
|
| int enc_debug = 0;
|
| #endif
|
|
|
| -static void encode_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
|
| - TOKENEXTRA **t, int recon_yoffset,
|
| - int recon_uvoffset, int output_enabled,
|
| - int mb_col, int mb_row);
|
| +extern void select_interp_filter_type(VP9_COMP *cpi);
|
|
|
| -static void encode_superblock(VP9_COMP *cpi, MACROBLOCK *x,
|
| - TOKENEXTRA **t, int recon_yoffset,
|
| - int recon_uvoffset, int mb_col, int mb_row);
|
| +static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled, int mb_row, int mb_col);
|
|
|
| +static void encode_superblock32(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled, int mb_row, int mb_col);
|
| +
|
| +static void encode_superblock64(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled, int mb_row, int mb_col);
|
| +
|
| static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
|
|
|
| #ifdef MODE_STATS
|
| @@ -79,7 +85,7 @@
|
| * Eventually this should be replaced by custom no-reference routines,
|
| * which will be faster.
|
| */
|
| -static const unsigned char VP9_VAR_OFFS[16] = {
|
| +static const uint8_t VP9_VAR_OFFS[16] = {
|
| 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
|
| };
|
|
|
| @@ -279,10 +285,6 @@
|
| xd->left_available = (mb_col != 0);
|
| recon_yoffset += 16;
|
| #endif
|
| -#if !CONFIG_SUPERBLOCKS
|
| - // Copy current mb to a buffer
|
| - vp9_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
|
| -#endif
|
|
|
| // measure activity
|
| mb_activity = mb_activity_measure(cpi, x, mb_row, mb_col);
|
| @@ -391,12 +393,11 @@
|
| MACROBLOCKD *xd = &x->e_mbd;
|
| int max_mv = MV_MAX;
|
|
|
| - cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], 0) +
|
| + cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], 0) +
|
| vp9_mv_bit_cost(&target_mv, &mv_ref_list[0], x->nmvjointcost,
|
| x->mvcost, 96, xd->allow_high_precision_mv);
|
|
|
| - // Use 4 for now : for (i = 1; i < MAX_MV_REFS; ++i ) {
|
| - for (i = 1; i < 4; ++i) {
|
| + for (i = 1; i < MAX_MV_REF_CANDIDATES; ++i) {
|
| // If we see a 0,0 reference vector for a second time we have reached
|
| // the end of the list of valid candidate vectors.
|
| if (!mv_ref_list[i].as_int) {
|
| @@ -413,7 +414,7 @@
|
| continue;
|
| }
|
|
|
| - cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], i) +
|
| + cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], i) +
|
| vp9_mv_bit_cost(&target_mv, &mv_ref_list[i], x->nmvjointcost,
|
| x->mvcost, 96, xd->allow_high_precision_mv);
|
|
|
| @@ -422,43 +423,47 @@
|
| best_index = i;
|
| }
|
| }
|
| -
|
| best_ref->as_int = mv_ref_list[best_index].as_int;
|
|
|
| return best_index;
|
| }
|
| #endif
|
|
|
| -static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
|
| - PICK_MODE_CONTEXT *ctx) {
|
| - int i;
|
| - MACROBLOCKD *xd = &x->e_mbd;
|
| +static void update_state(VP9_COMP *cpi,
|
| + PICK_MODE_CONTEXT *ctx, int block_size,
|
| + int output_enabled) {
|
| + int i, x_idx, y;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| MODE_INFO *mi = &ctx->mic;
|
| - MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
|
| + MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
|
| int mb_mode = mi->mbmi.mode;
|
| int mb_mode_index = ctx->best_mode_index;
|
| + const int mis = cpi->common.mode_info_stride;
|
| + int mb_block_size = 1 << mi->mbmi.sb_type;
|
|
|
| #if CONFIG_DEBUG
|
| assert(mb_mode < MB_MODE_COUNT);
|
| assert(mb_mode_index < MAX_MODES);
|
| assert(mi->mbmi.ref_frame < MAX_REF_FRAMES);
|
| #endif
|
| + assert(mi->mbmi.sb_type == (block_size >> 5));
|
|
|
| // Restore the coding context of the MB to that that was in place
|
| // when the mode was picked for it
|
| - vpx_memcpy(xd->mode_info_context, mi, sizeof(MODE_INFO));
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (mi->mbmi.encoded_as_sb) {
|
| - const int mis = cpi->common.mode_info_stride;
|
| - if (xd->mb_to_right_edge >= 0)
|
| - vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
|
| - if (xd->mb_to_bottom_edge >= 0) {
|
| - vpx_memcpy(xd->mode_info_context + mis, mi, sizeof(MODE_INFO));
|
| - if (xd->mb_to_right_edge >= 0)
|
| - vpx_memcpy(xd->mode_info_context + mis + 1, mi, sizeof(MODE_INFO));
|
| + for (y = 0; y < mb_block_size; y++) {
|
| + for (x_idx = 0; x_idx < mb_block_size; x_idx++) {
|
| + if ((xd->mb_to_right_edge >> 7) + mb_block_size > x_idx &&
|
| + (xd->mb_to_bottom_edge >> 7) + mb_block_size > y) {
|
| + MODE_INFO *mi_addr = xd->mode_info_context + x_idx + y * mis;
|
| +
|
| + vpx_memcpy(mi_addr, mi, sizeof(MODE_INFO));
|
| + }
|
| }
|
| }
|
| -#endif
|
| + if (block_size == 16) {
|
| + ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
|
| + }
|
|
|
| if (mb_mode == B_PRED) {
|
| for (i = 0; i < 16; i++) {
|
| @@ -477,6 +482,10 @@
|
| mbmi->mv[1].as_int = x->partition_info->bmi[15].second_mv.as_int;
|
| }
|
|
|
| + x->skip = ctx->skip;
|
| + if (!output_enabled)
|
| + return;
|
| +
|
| {
|
| int segment_id = mbmi->segment_id;
|
| if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
|
| @@ -550,6 +559,7 @@
|
| best_index = pick_best_mv_ref(x, rf, mbmi->mv[0],
|
| mbmi->ref_mvs[rf], &best_mv);
|
| mbmi->best_index = best_index;
|
| + ++cpi->mb_mv_ref_count[rf][best_index];
|
|
|
| if (mbmi->second_ref_frame > 0) {
|
| unsigned int best_index;
|
| @@ -558,6 +568,7 @@
|
| mbmi->ref_mvs[sec_ref_frame],
|
| &best_second_mv);
|
| mbmi->best_second_index = best_index;
|
| + ++cpi->mb_mv_ref_count[sec_ref_frame][best_index];
|
| }
|
| #endif
|
| }
|
| @@ -578,6 +589,7 @@
|
| ++cpi->interintra_count[0];
|
| }
|
| }
|
| +#endif
|
| if (cpi->common.mcomp_filter_type == SWITCHABLE &&
|
| mbmi->mode >= NEARESTMV &&
|
| mbmi->mode <= SPLITMV) {
|
| @@ -585,7 +597,6 @@
|
| [vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
|
| [vp9_switchable_interp_map[mbmi->interp_filter]];
|
| }
|
| -#endif
|
|
|
| cpi->prediction_error += ctx->distortion;
|
| cpi->intra_error += ctx->intra_error;
|
| @@ -596,34 +607,154 @@
|
| }
|
| }
|
|
|
| +static unsigned find_seg_id(uint8_t *buf, int block_size,
|
| + int start_y, int height, int start_x, int width) {
|
| + const int end_x = MIN(start_x + block_size, width);
|
| + const int end_y = MIN(start_y + block_size, height);
|
| + int x, y;
|
| + unsigned seg_id = -1;
|
| +
|
| + buf += width * start_y;
|
| + for (y = start_y; y < end_y; y++, buf += width) {
|
| + for (x = start_x; x < end_x; x++) {
|
| + seg_id = MIN(seg_id, buf[x]);
|
| + }
|
| + }
|
| +
|
| + return seg_id;
|
| +}
|
| +
|
| +static void set_offsets(VP9_COMP *cpi,
|
| + int mb_row, int mb_col, int block_size,
|
| + int *ref_yoffset, int *ref_uvoffset) {
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + MB_MODE_INFO *mbmi;
|
| + const int dst_fb_idx = cm->new_fb_idx;
|
| + const int recon_y_stride = cm->yv12_fb[dst_fb_idx].y_stride;
|
| + const int recon_uv_stride = cm->yv12_fb[dst_fb_idx].uv_stride;
|
| + const int recon_yoffset = 16 * mb_row * recon_y_stride + 16 * mb_col;
|
| + const int recon_uvoffset = 8 * mb_row * recon_uv_stride + 8 * mb_col;
|
| + const int src_y_stride = x->src.y_stride;
|
| + const int src_uv_stride = x->src.uv_stride;
|
| + const int src_yoffset = 16 * mb_row * src_y_stride + 16 * mb_col;
|
| + const int src_uvoffset = 8 * mb_row * src_uv_stride + 8 * mb_col;
|
| + const int ref_fb_idx = cm->lst_fb_idx;
|
| + const int ref_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
|
| + const int ref_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
|
| + const int idx_map = mb_row * cm->mb_cols + mb_col;
|
| + const int idx_str = xd->mode_info_stride * mb_row + mb_col;
|
| +
|
| + // entropy context structures
|
| + xd->above_context = cm->above_context + mb_col;
|
| + xd->left_context = cm->left_context + (mb_row & 3);
|
| +
|
| + // GF active flags data structure
|
| + x->gf_active_ptr = (signed char *)&cpi->gf_active_flags[idx_map];
|
| +
|
| + // Activity map pointer
|
| + x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
|
| + x->active_ptr = cpi->active_map + idx_map;
|
| +
|
| + /* pointers to mode info contexts */
|
| + x->partition_info = x->pi + idx_str;
|
| + xd->mode_info_context = cm->mi + idx_str;
|
| + mbmi = &xd->mode_info_context->mbmi;
|
| + xd->prev_mode_info_context = cm->prev_mi + idx_str;
|
| +
|
| + // Set up destination pointers
|
| + xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
|
| + xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
|
| + xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
|
| +
|
| + /* Set up limit values for MV components to prevent them from
|
| + * extending beyond the UMV borders assuming 16x16 block size */
|
| + x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| + x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| + x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
|
| + (VP9BORDERINPIXELS - block_size - VP9_INTERP_EXTEND));
|
| + x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
|
| + (VP9BORDERINPIXELS - block_size - VP9_INTERP_EXTEND));
|
| +
|
| + // Set up distance of MB to edge of frame in 1/8th pel units
|
| + block_size >>= 4; // in macroblock units
|
| + assert(!(mb_col & (block_size - 1)) && !(mb_row & (block_size - 1)));
|
| + xd->mb_to_top_edge = -((mb_row * 16) << 3);
|
| + xd->mb_to_left_edge = -((mb_col * 16) << 3);
|
| + xd->mb_to_bottom_edge = ((cm->mb_rows - block_size - mb_row) * 16) << 3;
|
| + xd->mb_to_right_edge = ((cm->mb_cols - block_size - mb_col) * 16) << 3;
|
| +
|
| + // Are edges available for intra prediction?
|
| + xd->up_available = (mb_row != 0);
|
| + xd->left_available = (mb_col != 0);
|
| +
|
| + /* Reference buffer offsets */
|
| + *ref_yoffset = (mb_row * ref_y_stride * 16) + (mb_col * 16);
|
| + *ref_uvoffset = (mb_row * ref_uv_stride * 8) + (mb_col * 8);
|
| +
|
| + /* set up source buffers */
|
| + x->src.y_buffer = cpi->Source->y_buffer + src_yoffset;
|
| + x->src.u_buffer = cpi->Source->u_buffer + src_uvoffset;
|
| + x->src.v_buffer = cpi->Source->v_buffer + src_uvoffset;
|
| +
|
| + /* R/D setup */
|
| + x->rddiv = cpi->RDDIV;
|
| + x->rdmult = cpi->RDMULT;
|
| +
|
| + /* segment ID */
|
| + if (xd->segmentation_enabled) {
|
| + if (xd->update_mb_segmentation_map) {
|
| + mbmi->segment_id = find_seg_id(cpi->segmentation_map, block_size,
|
| + mb_row, cm->mb_rows, mb_col, cm->mb_cols);
|
| + } else {
|
| + mbmi->segment_id = find_seg_id(cm->last_frame_seg_map, block_size,
|
| + mb_row, cm->mb_rows, mb_col, cm->mb_cols);
|
| + }
|
| + assert(mbmi->segment_id <= 3);
|
| + vp9_mb_init_quantizer(cpi, x);
|
| +
|
| + if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
|
| + !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME) &&
|
| + vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME) &&
|
| + vp9_check_segref(xd, 1, INTRA_FRAME) +
|
| + vp9_check_segref(xd, 1, LAST_FRAME) +
|
| + vp9_check_segref(xd, 1, GOLDEN_FRAME) +
|
| + vp9_check_segref(xd, 1, ALTREF_FRAME) == 1) {
|
| + cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
|
| + } else {
|
| + const int y = mb_row & ~3;
|
| + const int x = mb_col & ~3;
|
| + const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
|
| + const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
|
| +
|
| + cpi->seg0_progress =
|
| + ((y * cm->mb_cols + x * 4 + p32 + p16) << 16) / cm->MBs;
|
| + }
|
| + } else {
|
| + mbmi->segment_id = 0;
|
| + }
|
| +}
|
| +
|
| static void pick_mb_modes(VP9_COMP *cpi,
|
| - VP9_COMMON *cm,
|
| int mb_row,
|
| int mb_col,
|
| - MACROBLOCK *x,
|
| - MACROBLOCKD *xd,
|
| TOKENEXTRA **tp,
|
| int *totalrate,
|
| int *totaldist) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| int i;
|
| - int map_index;
|
| int recon_yoffset, recon_uvoffset;
|
| - int ref_fb_idx = cm->lst_fb_idx;
|
| - int dst_fb_idx = cm->new_fb_idx;
|
| - int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
|
| - int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
|
| ENTROPY_CONTEXT_PLANES left_context[2];
|
| ENTROPY_CONTEXT_PLANES above_context[2];
|
| ENTROPY_CONTEXT_PLANES *initial_above_context_ptr = cm->above_context
|
| + mb_col;
|
|
|
| - // Offsets to move pointers from MB to MB within a SB in raster order
|
| - int row_delta[4] = { 0, +1, 0, -1};
|
| - int col_delta[4] = { +1, -1, +1, +1};
|
| -
|
| /* Function should not modify L & A contexts; save and restore on exit */
|
| vpx_memcpy(left_context,
|
| - cm->left_context,
|
| + cm->left_context + (mb_row & 2),
|
| sizeof(left_context));
|
| vpx_memcpy(above_context,
|
| initial_above_context_ptr,
|
| @@ -631,113 +762,29 @@
|
|
|
| /* Encode MBs in raster order within the SB */
|
| for (i = 0; i < 4; i++) {
|
| - int dy = row_delta[i];
|
| - int dx = col_delta[i];
|
| - int offset_unextended = dy * cm->mb_cols + dx;
|
| - int offset_extended = dy * xd->mode_info_stride + dx;
|
| - MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
|
| + const int x_idx = i & 1, y_idx = i >> 1;
|
| + MB_MODE_INFO *mbmi;
|
|
|
| - // TODO Many of the index items here can be computed more efficiently!
|
| -
|
| - if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols)) {
|
| + if ((mb_row + y_idx >= cm->mb_rows) || (mb_col + x_idx >= cm->mb_cols)) {
|
| // MB lies outside frame, move on
|
| - mb_row += dy;
|
| - mb_col += dx;
|
| -
|
| - // Update pointers
|
| - x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
|
| - x->src.u_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| - x->src.v_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| -
|
| - x->gf_active_ptr += offset_unextended;
|
| - x->partition_info += offset_extended;
|
| - xd->mode_info_context += offset_extended;
|
| - xd->prev_mode_info_context += offset_extended;
|
| -#if CONFIG_DEBUG
|
| - assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
|
| - (xd->mode_info_context - cpi->common.mip));
|
| -#endif
|
| continue;
|
| }
|
|
|
| // Index of the MB in the SB 0..3
|
| xd->mb_index = i;
|
| + set_offsets(cpi, mb_row + y_idx, mb_col + x_idx, 16,
|
| + &recon_yoffset, &recon_uvoffset);
|
|
|
| - map_index = (mb_row * cpi->common.mb_cols) + mb_col;
|
| - x->mb_activity_ptr = &cpi->mb_activity_map[map_index];
|
| -
|
| - // set above context pointer
|
| - xd->above_context = cm->above_context + mb_col;
|
| -
|
| - // Restore the appropriate left context depending on which
|
| - // row in the SB the MB is situated
|
| - xd->left_context = cm->left_context + (i >> 1);
|
| -
|
| - // Set up distance of MB to edge of frame in 1/8th pel units
|
| - xd->mb_to_top_edge = -((mb_row * 16) << 3);
|
| - xd->mb_to_left_edge = -((mb_col * 16) << 3);
|
| - xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
|
| - xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
|
| -
|
| - // Set up limit values for MV components to prevent them from
|
| - // extending beyond the UMV borders assuming 16x16 block size
|
| - x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| - x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| - x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
|
| - (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
|
| - x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
|
| - (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
|
| -
|
| - xd->up_available = (mb_row != 0);
|
| - xd->left_available = (mb_col != 0);
|
| -
|
| - recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
|
| - recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
|
| -
|
| - xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
|
| - xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
|
| - xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
|
| -
|
| -#if !CONFIG_SUPERBLOCKS
|
| - // Copy current MB to a work buffer
|
| - vp9_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
|
| -#endif
|
| -
|
| - x->rddiv = cpi->RDDIV;
|
| - x->rdmult = cpi->RDMULT;
|
| -
|
| if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| vp9_activity_masking(cpi, x);
|
|
|
| - // Is segmentation enabled
|
| - if (xd->segmentation_enabled) {
|
| - // Code to set segment id in xd->mbmi.segment_id
|
| - if (xd->update_mb_segmentation_map)
|
| - mbmi->segment_id = cpi->segmentation_map[map_index];
|
| - else
|
| - mbmi->segment_id = cm->last_frame_seg_map[map_index];
|
| - if (mbmi->segment_id > 3)
|
| - mbmi->segment_id = 0;
|
| + mbmi = &xd->mode_info_context->mbmi;
|
| + mbmi->sb_type = BLOCK_SIZE_MB16X16;
|
|
|
| - vp9_mb_init_quantizer(cpi, x);
|
| - } else
|
| - // Set to Segment 0 by default
|
| - mbmi->segment_id = 0;
|
| -
|
| - x->active_ptr = cpi->active_map + map_index;
|
| -
|
| -#if CONFIG_SUPERBLOCKS
|
| - xd->mode_info_context->mbmi.encoded_as_sb = 0;
|
| -#endif
|
| -
|
| cpi->update_context = 0; // TODO Do we need this now??
|
|
|
| vp9_intra_prediction_down_copy(xd);
|
|
|
| -#ifdef ENC_DEBUG
|
| - enc_debug = (cpi->common.current_video_frame == 46 &&
|
| - mb_row == 5 && mb_col == 2);
|
| -#endif
|
| // Find best coding mode & reconstruct the MB so it is available
|
| // as a predictor for MBs that follow in the SB
|
| if (cm->frame_type == KEY_FRAME) {
|
| @@ -751,28 +798,16 @@
|
| *totaldist += d;
|
|
|
| // Dummy encode, do not do the tokenization
|
| - encode_macroblock(cpi, x, tp,
|
| - recon_yoffset, recon_uvoffset, 0, mb_col, mb_row);
|
| + encode_macroblock(cpi, tp, recon_yoffset, recon_uvoffset, 0,
|
| + mb_row + y_idx, mb_col + x_idx);
|
| // Note the encoder may have changed the segment_id
|
|
|
| // Save the coding context
|
| - vpx_memcpy(&x->mb_context[i].mic, xd->mode_info_context,
|
| + vpx_memcpy(&x->mb_context[xd->sb_index][i].mic, xd->mode_info_context,
|
| sizeof(MODE_INFO));
|
| } else {
|
| int seg_id, r, d;
|
|
|
| - if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
|
| - !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME) &&
|
| - vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME) &&
|
| - vp9_check_segref(xd, 1, INTRA_FRAME) +
|
| - vp9_check_segref(xd, 1, LAST_FRAME) +
|
| - vp9_check_segref(xd, 1, GOLDEN_FRAME) +
|
| - vp9_check_segref(xd, 1, ALTREF_FRAME) == 1) {
|
| - cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
|
| - } else {
|
| - cpi->seg0_progress = (((mb_col & ~1) * 2 + (mb_row & ~1) * cm->mb_cols + i) << 16) / cm->MBs;
|
| - }
|
| -
|
| #ifdef ENC_DEBUG
|
| if (enc_debug)
|
| printf("inter pick_mb_modes %d %d\n", mb_row, mb_col);
|
| @@ -783,8 +818,8 @@
|
| *totaldist += d;
|
|
|
| // Dummy encode, do not do the tokenization
|
| - encode_macroblock(cpi, x, tp,
|
| - recon_yoffset, recon_uvoffset, 0, mb_col, mb_row);
|
| + encode_macroblock(cpi, tp, recon_yoffset, recon_uvoffset, 0,
|
| + mb_row + y_idx, mb_col + x_idx);
|
|
|
| seg_id = mbmi->segment_id;
|
| if (cpi->mb.e_mbd.segmentation_enabled && seg_id == 0) {
|
| @@ -804,28 +839,10 @@
|
| cpi->ref_pred_count[pred_context][pred_flag]++;
|
| }
|
| }
|
| -
|
| - // Next MB
|
| - mb_row += dy;
|
| - mb_col += dx;
|
| -
|
| - x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
|
| - x->src.u_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| - x->src.v_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| -
|
| - x->gf_active_ptr += offset_unextended;
|
| - x->partition_info += offset_extended;
|
| - xd->mode_info_context += offset_extended;
|
| - xd->prev_mode_info_context += offset_extended;
|
| -
|
| -#if CONFIG_DEBUG
|
| - assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
|
| - (xd->mode_info_context - cpi->common.mip));
|
| -#endif
|
| }
|
|
|
| /* Restore L & A coding context to those in place on entry */
|
| - vpx_memcpy(cm->left_context,
|
| + vpx_memcpy(cm->left_context + (mb_row & 2),
|
| left_context,
|
| sizeof(left_context));
|
| vpx_memcpy(initial_above_context_ptr,
|
| @@ -833,393 +850,193 @@
|
| sizeof(above_context));
|
| }
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| -static void pick_sb_modes (VP9_COMP *cpi,
|
| - VP9_COMMON *cm,
|
| - int mb_row,
|
| - int mb_col,
|
| - MACROBLOCK *x,
|
| - MACROBLOCKD *xd,
|
| - TOKENEXTRA **tp,
|
| - int *totalrate,
|
| - int *totaldist)
|
| -{
|
| - int map_index;
|
| +static void pick_sb_modes(VP9_COMP *cpi,
|
| + int mb_row,
|
| + int mb_col,
|
| + TOKENEXTRA **tp,
|
| + int *totalrate,
|
| + int *totaldist) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| int recon_yoffset, recon_uvoffset;
|
| - int ref_fb_idx = cm->lst_fb_idx;
|
| - int dst_fb_idx = cm->new_fb_idx;
|
| - int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
|
| - int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
|
| - ENTROPY_CONTEXT_PLANES left_context[2];
|
| - ENTROPY_CONTEXT_PLANES above_context[2];
|
| - ENTROPY_CONTEXT_PLANES *initial_above_context_ptr = cm->above_context
|
| - + mb_col;
|
|
|
| - /* Function should not modify L & A contexts; save and restore on exit */
|
| - vpx_memcpy (left_context,
|
| - cm->left_context,
|
| - sizeof(left_context));
|
| - vpx_memcpy (above_context,
|
| - initial_above_context_ptr,
|
| - sizeof(above_context));
|
| -
|
| - map_index = (mb_row * cpi->common.mb_cols) + mb_col;
|
| - x->mb_activity_ptr = &cpi->mb_activity_map[map_index];
|
| -
|
| - /* set above context pointer */
|
| - xd->above_context = cm->above_context + mb_col;
|
| -
|
| - /* Restore the appropriate left context depending on which
|
| - * row in the SB the MB is situated */
|
| - xd->left_context = cm->left_context;
|
| -
|
| - // Set up distance of MB to edge of frame in 1/8th pel units
|
| - xd->mb_to_top_edge = -((mb_row * 16) << 3);
|
| - xd->mb_to_left_edge = -((mb_col * 16) << 3);
|
| - xd->mb_to_bottom_edge = ((cm->mb_rows - 2 - mb_row) * 16) << 3;
|
| - xd->mb_to_right_edge = ((cm->mb_cols - 2 - mb_col) * 16) << 3;
|
| -
|
| - /* Set up limit values for MV components to prevent them from
|
| - * extending beyond the UMV borders assuming 16x16 block size */
|
| - x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| - x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| - x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
|
| - (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
|
| - x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
|
| - (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
|
| -
|
| - xd->up_available = (mb_row != 0);
|
| - xd->left_available = (mb_col != 0);
|
| -
|
| - recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
|
| - recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
|
| -
|
| - xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
|
| - xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
|
| - xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
|
| -#if 0 // FIXME
|
| - /* Copy current MB to a work buffer */
|
| - vp9_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
|
| -#endif
|
| - x->rddiv = cpi->RDDIV;
|
| - x->rdmult = cpi->RDMULT;
|
| - if(cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| + set_offsets(cpi, mb_row, mb_col, 32, &recon_yoffset, &recon_uvoffset);
|
| + xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_SB32X32;
|
| + if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| vp9_activity_masking(cpi, x);
|
| - /* Is segmentation enabled */
|
| - if (xd->segmentation_enabled)
|
| - {
|
| - /* Code to set segment id in xd->mbmi.segment_id */
|
| - if (xd->update_mb_segmentation_map)
|
| - xd->mode_info_context->mbmi.segment_id =
|
| - cpi->segmentation_map[map_index] &&
|
| - cpi->segmentation_map[map_index + 1] &&
|
| - cpi->segmentation_map[map_index + cm->mb_cols] &&
|
| - cpi->segmentation_map[map_index + cm->mb_cols + 1];
|
| - else
|
| - xd->mode_info_context->mbmi.segment_id =
|
| - cm->last_frame_seg_map[map_index] &&
|
| - cm->last_frame_seg_map[map_index + 1] &&
|
| - cm->last_frame_seg_map[map_index + cm->mb_cols] &&
|
| - cm->last_frame_seg_map[map_index + cm->mb_cols + 1];
|
| - if (xd->mode_info_context->mbmi.segment_id > 3)
|
| - xd->mode_info_context->mbmi.segment_id = 0;
|
| -
|
| - vp9_mb_init_quantizer(cpi, x);
|
| - }
|
| - else
|
| - /* Set to Segment 0 by default */
|
| - xd->mode_info_context->mbmi.segment_id = 0;
|
| -
|
| - x->active_ptr = cpi->active_map + map_index;
|
| -
|
| cpi->update_context = 0; // TODO Do we need this now??
|
|
|
| /* Find best coding mode & reconstruct the MB so it is available
|
| * as a predictor for MBs that follow in the SB */
|
| - if (cm->frame_type == KEY_FRAME)
|
| - {
|
| - vp9_rd_pick_intra_mode_sb(cpi, x,
|
| - totalrate,
|
| - totaldist);
|
| + if (cm->frame_type == KEY_FRAME) {
|
| + vp9_rd_pick_intra_mode_sb32(cpi, x,
|
| + totalrate,
|
| + totaldist);
|
|
|
| /* Save the coding context */
|
| - vpx_memcpy(&x->sb_context[0].mic, xd->mode_info_context,
|
| + vpx_memcpy(&x->sb32_context[xd->sb_index].mic, xd->mode_info_context,
|
| sizeof(MODE_INFO));
|
| } else {
|
| - if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
|
| - !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME) &&
|
| - vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME) &&
|
| - vp9_check_segref(xd, 1, INTRA_FRAME) +
|
| - vp9_check_segref(xd, 1, LAST_FRAME) +
|
| - vp9_check_segref(xd, 1, GOLDEN_FRAME) +
|
| - vp9_check_segref(xd, 1, ALTREF_FRAME) == 1) {
|
| - cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
|
| - } else {
|
| - cpi->seg0_progress =
|
| - (((mb_col & ~1) * 2 + (mb_row & ~1) * cm->mb_cols) << 16) / cm->MBs;
|
| - }
|
| -
|
| - vp9_rd_pick_inter_mode_sb(cpi, x,
|
| - recon_yoffset,
|
| - recon_uvoffset,
|
| - totalrate,
|
| - totaldist);
|
| + vp9_rd_pick_inter_mode_sb32(cpi, x,
|
| + recon_yoffset,
|
| + recon_uvoffset,
|
| + totalrate,
|
| + totaldist);
|
| }
|
| -
|
| - /* Restore L & A coding context to those in place on entry */
|
| - vpx_memcpy (cm->left_context,
|
| - left_context,
|
| - sizeof(left_context));
|
| - vpx_memcpy (initial_above_context_ptr,
|
| - above_context,
|
| - sizeof(above_context));
|
| }
|
| -#endif
|
|
|
| -static void encode_sb(VP9_COMP *cpi,
|
| - VP9_COMMON *cm,
|
| - int mbrow,
|
| - int mbcol,
|
| - MACROBLOCK *x,
|
| - MACROBLOCKD *xd,
|
| - TOKENEXTRA **tp) {
|
| - int i;
|
| - int map_index;
|
| - int mb_row, mb_col;
|
| +static void pick_sb64_modes(VP9_COMP *cpi,
|
| + int mb_row,
|
| + int mb_col,
|
| + TOKENEXTRA **tp,
|
| + int *totalrate,
|
| + int *totaldist) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| int recon_yoffset, recon_uvoffset;
|
| - int ref_fb_idx = cm->lst_fb_idx;
|
| - int dst_fb_idx = cm->new_fb_idx;
|
| - int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
|
| - int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
|
| - int row_delta[4] = { 0, +1, 0, -1};
|
| - int col_delta[4] = { +1, -1, +1, +1};
|
|
|
| - mb_row = mbrow;
|
| - mb_col = mbcol;
|
| + set_offsets(cpi, mb_row, mb_col, 64, &recon_yoffset, &recon_uvoffset);
|
| + xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_SB64X64;
|
| + if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| + vp9_activity_masking(cpi, x);
|
| + cpi->update_context = 0; // TODO(rbultje) Do we need this now??
|
|
|
| - /* Encode MBs in raster order within the SB */
|
| - for (i = 0; i < 4; i++) {
|
| - int dy = row_delta[i];
|
| - int dx = col_delta[i];
|
| - int offset_extended = dy * xd->mode_info_stride + dx;
|
| - int offset_unextended = dy * cm->mb_cols + dx;
|
| - MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
|
| + /* Find best coding mode & reconstruct the MB so it is available
|
| + * as a predictor for MBs that follow in the SB */
|
| + if (cm->frame_type == KEY_FRAME) {
|
| + vp9_rd_pick_intra_mode_sb64(cpi, x,
|
| + totalrate,
|
| + totaldist);
|
|
|
| - if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols)) {
|
| - // MB lies outside frame, move on
|
| - mb_row += dy;
|
| - mb_col += dx;
|
| + /* Save the coding context */
|
| + vpx_memcpy(&x->sb64_context.mic, xd->mode_info_context,
|
| + sizeof(MODE_INFO));
|
| + } else {
|
| + vp9_rd_pick_inter_mode_sb64(cpi, x,
|
| + recon_yoffset,
|
| + recon_uvoffset,
|
| + totalrate,
|
| + totaldist);
|
| + }
|
| +}
|
|
|
| - x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
|
| - x->src.u_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| - x->src.v_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| +static void update_stats(VP9_COMP *cpi) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + MODE_INFO *mi = xd->mode_info_context;
|
| + MB_MODE_INFO *const mbmi = &mi->mbmi;
|
|
|
| - x->gf_active_ptr += offset_unextended;
|
| - x->partition_info += offset_extended;
|
| - xd->mode_info_context += offset_extended;
|
| - xd->prev_mode_info_context += offset_extended;
|
| -
|
| -#if CONFIG_DEBUG
|
| - assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
|
| - (xd->mode_info_context - cpi->common.mip));
|
| + if (cm->frame_type == KEY_FRAME) {
|
| +#ifdef MODE_STATS
|
| + y_modes[mbmi->mode]++;
|
| #endif
|
| - continue;
|
| - }
|
| + } else {
|
| + int segment_id, seg_ref_active;
|
|
|
| - xd->mb_index = i;
|
| + if (mbmi->ref_frame) {
|
| + int pred_context = vp9_get_pred_context(cm, xd, PRED_COMP);
|
|
|
| - // Restore MB state to that when it was picked
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb) {
|
| - update_state(cpi, x, &x->sb_context[i]);
|
| - cpi->sb_count++;
|
| - } else
|
| -#endif
|
| - update_state(cpi, x, &x->mb_context[i]);
|
| + if (mbmi->second_ref_frame <= INTRA_FRAME)
|
| + cpi->single_pred_count[pred_context]++;
|
| + else
|
| + cpi->comp_pred_count[pred_context]++;
|
| + }
|
|
|
| - map_index = (mb_row * cpi->common.mb_cols) + mb_col;
|
| - x->mb_activity_ptr = &cpi->mb_activity_map[map_index];
|
| +#ifdef MODE_STATS
|
| + inter_y_modes[mbmi->mode]++;
|
|
|
| - // reset above block coeffs
|
| - xd->above_context = cm->above_context + mb_col;
|
| - xd->left_context = cm->left_context + (i >> 1);
|
| + if (mbmi->mode == SPLITMV) {
|
| + int b;
|
|
|
| - // Set up distance of MB to edge of the frame in 1/8th pel units
|
| - // Set up limit values for MV components to prevent them from
|
| - // extending beyond the UMV borders assuming 32x32 block size
|
| - x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| - x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
|
| -
|
| - xd->mb_to_top_edge = -((mb_row * 16) << 3);
|
| - xd->mb_to_left_edge = -((mb_col * 16) << 3);
|
| -
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb) {
|
| - x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
|
| - (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
|
| - x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
|
| - (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
|
| -
|
| - xd->mb_to_bottom_edge = ((cm->mb_rows - 2 - mb_row) * 16) << 3;
|
| - xd->mb_to_right_edge = ((cm->mb_cols - 2 - mb_col) * 16) << 3;
|
| - } else {
|
| + for (b = 0; b < x->partition_info->count; b++) {
|
| + inter_b_modes[x->partition_info->bmi[b].mode]++;
|
| + }
|
| + }
|
| #endif
|
| - x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
|
| - (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
|
| - x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
|
| - (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
|
|
|
| - xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
|
| - xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
|
| -#if CONFIG_SUPERBLOCKS
|
| + // If we have just a single reference frame coded for a segment then
|
| + // exclude from the reference frame counts used to work out
|
| + // probabilities. NOTE: At the moment we dont support custom trees
|
| + // for the reference frame coding for each segment but this is a
|
| + // possible future action.
|
| + segment_id = mbmi->segment_id;
|
| + seg_ref_active = vp9_segfeature_active(xd, segment_id,
|
| + SEG_LVL_REF_FRAME);
|
| + if (!seg_ref_active ||
|
| + ((vp9_check_segref(xd, segment_id, INTRA_FRAME) +
|
| + vp9_check_segref(xd, segment_id, LAST_FRAME) +
|
| + vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
|
| + vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1)) {
|
| + cpi->count_mb_ref_frame_usage[mbmi->ref_frame]++;
|
| }
|
| -#endif
|
| + // Count of last ref frame 0,0 usage
|
| + if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
|
| + cpi->inter_zz_count++;
|
| + }
|
| +}
|
|
|
| - xd->up_available = (mb_row != 0);
|
| - xd->left_available = (mb_col != 0);
|
| +static void encode_sb(VP9_COMP *cpi,
|
| + int mb_row,
|
| + int mb_col,
|
| + int output_enabled,
|
| + TOKENEXTRA **tp, int is_sb) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + int recon_yoffset, recon_uvoffset;
|
|
|
| - recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
|
| - recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);
|
| + cpi->sb32_count[is_sb]++;
|
| + if (is_sb) {
|
| + set_offsets(cpi, mb_row, mb_col, 32, &recon_yoffset, &recon_uvoffset);
|
| + update_state(cpi, &x->sb32_context[xd->sb_index], 32, output_enabled);
|
|
|
| - xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
|
| - xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
|
| - xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
|
| + encode_superblock32(cpi, tp, recon_yoffset, recon_uvoffset,
|
| + output_enabled, mb_row, mb_col);
|
| + if (output_enabled)
|
| + update_stats(cpi);
|
|
|
| -#if !CONFIG_SUPERBLOCKS
|
| - // Copy current MB to a work buffer
|
| - vp9_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
|
| -#endif
|
| -
|
| - if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| - vp9_activity_masking(cpi, x);
|
| -
|
| - // Is segmentation enabled
|
| - if (xd->segmentation_enabled) {
|
| - vp9_mb_init_quantizer(cpi, x);
|
| + if (output_enabled) {
|
| + (*tp)->Token = EOSB_TOKEN;
|
| + (*tp)++;
|
| + if (mb_row < cm->mb_rows)
|
| + cpi->tplist[mb_row].stop = *tp;
|
| }
|
| + } else {
|
| + int i;
|
|
|
| - x->active_ptr = cpi->active_map + map_index;
|
| + for (i = 0; i < 4; i++) {
|
| + const int x_idx = i & 1, y_idx = i >> 1;
|
|
|
| - cpi->update_context = 0;
|
| -
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (!xd->mode_info_context->mbmi.encoded_as_sb)
|
| -#endif
|
| - vp9_intra_prediction_down_copy(xd);
|
| -
|
| - if (cm->frame_type == KEY_FRAME) {
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb)
|
| - encode_superblock(cpi, x, tp, recon_yoffset, recon_uvoffset,
|
| - mb_col, mb_row);
|
| - else
|
| -#endif
|
| - encode_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset, 1,
|
| - mb_col, mb_row);
|
| - // Note the encoder may have changed the segment_id
|
| -
|
| -#ifdef MODE_STATS
|
| - y_modes[mbmi->mode]++;
|
| -#endif
|
| - } else {
|
| - unsigned char *segment_id;
|
| - int seg_ref_active;
|
| -
|
| - if (xd->mode_info_context->mbmi.ref_frame) {
|
| - unsigned char pred_context;
|
| -
|
| - pred_context = vp9_get_pred_context(cm, xd, PRED_COMP);
|
| -
|
| - if (xd->mode_info_context->mbmi.second_ref_frame <= INTRA_FRAME)
|
| - cpi->single_pred_count[pred_context]++;
|
| - else
|
| - cpi->comp_pred_count[pred_context]++;
|
| + if ((mb_row + y_idx >= cm->mb_rows) || (mb_col + x_idx >= cm->mb_cols)) {
|
| + // MB lies outside frame, move on
|
| + continue;
|
| }
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb)
|
| - encode_superblock(cpi, x, tp, recon_yoffset, recon_uvoffset,
|
| - mb_col, mb_row);
|
| - else
|
| -#endif
|
| - encode_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset, 1,
|
| - mb_col, mb_row);
|
| - // Note the encoder may have changed the segment_id
|
| + set_offsets(cpi, mb_row + y_idx, mb_col + x_idx, 16,
|
| + &recon_yoffset, &recon_uvoffset);
|
| + xd->mb_index = i;
|
| + update_state(cpi, &x->mb_context[xd->sb_index][i], 16, output_enabled);
|
|
|
| -#ifdef MODE_STATS
|
| - inter_y_modes[mbmi->mode]++;
|
| + if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
|
| + vp9_activity_masking(cpi, x);
|
|
|
| - if (mbmi->mode == SPLITMV) {
|
| - int b;
|
| + vp9_intra_prediction_down_copy(xd);
|
|
|
| - for (b = 0; b < x->partition_info->count; b++) {
|
| - inter_b_modes[x->partition_info->bmi[b].mode]++;
|
| - }
|
| - }
|
| + encode_macroblock(cpi, tp, recon_yoffset, recon_uvoffset,
|
| + output_enabled, mb_row + y_idx, mb_col + x_idx);
|
| + if (output_enabled)
|
| + update_stats(cpi);
|
|
|
| -#endif
|
| -
|
| - // If we have just a single reference frame coded for a segment then
|
| - // exclude from the reference frame counts used to work out
|
| - // probabilities. NOTE: At the moment we dont support custom trees
|
| - // for the reference frame coding for each segment but this is a
|
| - // possible future action.
|
| - segment_id = &mbmi->segment_id;
|
| - seg_ref_active = vp9_segfeature_active(xd, *segment_id,
|
| - SEG_LVL_REF_FRAME);
|
| - if (!seg_ref_active ||
|
| - ((vp9_check_segref(xd, *segment_id, INTRA_FRAME) +
|
| - vp9_check_segref(xd, *segment_id, LAST_FRAME) +
|
| - vp9_check_segref(xd, *segment_id, GOLDEN_FRAME) +
|
| - vp9_check_segref(xd, *segment_id, ALTREF_FRAME)) > 1)) {
|
| - {
|
| - cpi->count_mb_ref_frame_usage[mbmi->ref_frame]++;
|
| - }
|
| + if (output_enabled) {
|
| + (*tp)->Token = EOSB_TOKEN;
|
| + (*tp)++;
|
| + if (mb_row + y_idx < cm->mb_rows)
|
| + cpi->tplist[mb_row + y_idx].stop = *tp;
|
| }
|
| -
|
| - // Count of last ref frame 0,0 usage
|
| - if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
|
| - cpi->inter_zz_count++;
|
| }
|
| -
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb) {
|
| - x->src.y_buffer += 32;
|
| - x->src.u_buffer += 16;
|
| - x->src.v_buffer += 16;
|
| -
|
| - x->gf_active_ptr += 2;
|
| - x->partition_info += 2;
|
| - xd->mode_info_context += 2;
|
| - xd->prev_mode_info_context += 2;
|
| -
|
| - (*tp)->Token = EOSB_TOKEN;
|
| - (*tp)++;
|
| - if (mb_row < cm->mb_rows) cpi->tplist[mb_row].stop = *tp;
|
| - break;
|
| - }
|
| -#endif
|
| -
|
| - // Next MB
|
| - mb_row += dy;
|
| - mb_col += dx;
|
| -
|
| - x->src.y_buffer += 16 * (dx + dy * x->src.y_stride);
|
| - x->src.u_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| - x->src.v_buffer += 8 * (dx + dy * x->src.uv_stride);
|
| -
|
| - x->gf_active_ptr += offset_unextended;
|
| - x->partition_info += offset_extended;
|
| - xd->mode_info_context += offset_extended;
|
| - xd->prev_mode_info_context += offset_extended;
|
| -
|
| -#if CONFIG_DEBUG
|
| - assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
|
| - (xd->mode_info_context - cpi->common.mip));
|
| -#endif
|
| - (*tp)->Token = EOSB_TOKEN;
|
| - (*tp)++;
|
| - if (mb_row < cm->mb_rows) cpi->tplist[mb_row].stop = *tp;
|
| }
|
|
|
| // debug output
|
| @@ -1233,14 +1050,53 @@
|
| #endif
|
| }
|
|
|
| -static
|
| -void encode_sb_row(VP9_COMP *cpi,
|
| - VP9_COMMON *cm,
|
| - int mb_row,
|
| - MACROBLOCK *x,
|
| - MACROBLOCKD *xd,
|
| - TOKENEXTRA **tp,
|
| - int *totalrate) {
|
| +static void encode_sb64(VP9_COMP *cpi,
|
| + int mb_row,
|
| + int mb_col,
|
| + TOKENEXTRA **tp, int is_sb[4]) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| +
|
| + cpi->sb64_count[is_sb[0] == 2]++;
|
| + if (is_sb[0] == 2) {
|
| + int recon_yoffset, recon_uvoffset;
|
| +
|
| + set_offsets(cpi, mb_row, mb_col, 64, &recon_yoffset, &recon_uvoffset);
|
| + update_state(cpi, &x->sb64_context, 64, 1);
|
| + encode_superblock64(cpi, tp, recon_yoffset, recon_uvoffset,
|
| + 1, mb_row, mb_col);
|
| + update_stats(cpi);
|
| +
|
| + (*tp)->Token = EOSB_TOKEN;
|
| + (*tp)++;
|
| + if (mb_row < cm->mb_rows)
|
| + cpi->tplist[mb_row].stop = *tp;
|
| + } else {
|
| + int i;
|
| +
|
| + for (i = 0; i < 4; i++) {
|
| + const int x_idx = i & 1, y_idx = i >> 1;
|
| +
|
| + if (mb_row + y_idx * 2 >= cm->mb_rows ||
|
| + mb_col + x_idx * 2 >= cm->mb_cols) {
|
| + // MB lies outside frame, move on
|
| + continue;
|
| + }
|
| + xd->sb_index = i;
|
| + encode_sb(cpi, mb_row + 2 * y_idx, mb_col + 2 * x_idx, 1, tp,
|
| + is_sb[i]);
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void encode_sb_row(VP9_COMP *cpi,
|
| + int mb_row,
|
| + TOKENEXTRA **tp,
|
| + int *totalrate) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| int mb_col;
|
| int mb_cols = cm->mb_cols;
|
|
|
| @@ -1248,105 +1104,84 @@
|
| vpx_memset(cm->left_context, 0, sizeof(cm->left_context));
|
|
|
| // Code each SB in the row
|
| - for (mb_col = 0; mb_col < mb_cols; mb_col += 2) {
|
| - int mb_rate = 0, mb_dist = 0;
|
| -#if CONFIG_SUPERBLOCKS
|
| - int sb_rate = INT_MAX, sb_dist;
|
| -#endif
|
| + for (mb_col = 0; mb_col < mb_cols; mb_col += 4) {
|
| + int i;
|
| + int sb32_rate = 0, sb32_dist = 0;
|
| + int is_sb[4];
|
| + int sb64_rate = INT_MAX, sb64_dist;
|
| + ENTROPY_CONTEXT_PLANES l[4], a[4];
|
| + TOKENEXTRA *tp_orig = *tp;
|
|
|
| -#if CONFIG_DEBUG
|
| - MODE_INFO *mic = xd->mode_info_context;
|
| - PARTITION_INFO *pi = x->partition_info;
|
| - signed char *gfa = x->gf_active_ptr;
|
| - unsigned char *yb = x->src.y_buffer;
|
| - unsigned char *ub = x->src.u_buffer;
|
| - unsigned char *vb = x->src.v_buffer;
|
| -#endif
|
| + memcpy(&a, cm->above_context + mb_col, sizeof(a));
|
| + memcpy(&l, cm->left_context, sizeof(l));
|
| + for (i = 0; i < 4; i++) {
|
| + const int x_idx = (i & 1) << 1, y_idx = i & 2;
|
| + int mb_rate = 0, mb_dist = 0;
|
| + int sb_rate = INT_MAX, sb_dist;
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| - // Pick modes assuming the SB is coded as 4 independent MBs
|
| - xd->mode_info_context->mbmi.encoded_as_sb = 0;
|
| -#endif
|
| - pick_mb_modes(cpi, cm, mb_row, mb_col, x, xd, tp, &mb_rate, &mb_dist);
|
| -#if CONFIG_SUPERBLOCKS
|
| - mb_rate += vp9_cost_bit(cm->sb_coded, 0);
|
| -#endif
|
| + if (mb_row + y_idx >= cm->mb_rows || mb_col + x_idx >= cm->mb_cols)
|
| + continue;
|
|
|
| - x->src.y_buffer -= 32;
|
| - x->src.u_buffer -= 16;
|
| - x->src.v_buffer -= 16;
|
| + xd->sb_index = i;
|
|
|
| - x->gf_active_ptr -= 2;
|
| - x->partition_info -= 2;
|
| - xd->mode_info_context -= 2;
|
| - xd->prev_mode_info_context -= 2;
|
| + pick_mb_modes(cpi, mb_row + y_idx, mb_col + x_idx,
|
| + tp, &mb_rate, &mb_dist);
|
| + mb_rate += vp9_cost_bit(cm->sb32_coded, 0);
|
|
|
| -#if CONFIG_DEBUG
|
| - assert(x->gf_active_ptr == gfa);
|
| - assert(x->partition_info == pi);
|
| - assert(xd->mode_info_context == mic);
|
| - assert(x->src.y_buffer == yb);
|
| - assert(x->src.u_buffer == ub);
|
| - assert(x->src.v_buffer == vb);
|
| -#endif
|
| + if (!((( mb_cols & 1) && mb_col + x_idx == mb_cols - 1) ||
|
| + ((cm->mb_rows & 1) && mb_row + y_idx == cm->mb_rows - 1))) {
|
| + /* Pick a mode assuming that it applies to all 4 of the MBs in the SB */
|
| + pick_sb_modes(cpi, mb_row + y_idx, mb_col + x_idx,
|
| + tp, &sb_rate, &sb_dist);
|
| + sb_rate += vp9_cost_bit(cm->sb32_coded, 1);
|
| + }
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (!((( mb_cols & 1) && mb_col == mb_cols - 1) ||
|
| - ((cm->mb_rows & 1) && mb_row == cm->mb_rows - 1))) {
|
| - /* Pick a mode assuming that it applies to all 4 of the MBs in the SB */
|
| - xd->mode_info_context->mbmi.encoded_as_sb = 1;
|
| - pick_sb_modes(cpi, cm, mb_row, mb_col, x, xd, tp, &sb_rate, &sb_dist);
|
| - sb_rate += vp9_cost_bit(cm->sb_coded, 1);
|
| + /* Decide whether to encode as a SB or 4xMBs */
|
| + if (sb_rate < INT_MAX &&
|
| + RDCOST(x->rdmult, x->rddiv, sb_rate, sb_dist) <
|
| + RDCOST(x->rdmult, x->rddiv, mb_rate, mb_dist)) {
|
| + is_sb[i] = 1;
|
| + sb32_rate += sb_rate;
|
| + sb32_dist += sb_dist;
|
| + } else {
|
| + is_sb[i] = 0;
|
| + sb32_rate += mb_rate;
|
| + sb32_dist += mb_dist;
|
| + }
|
| +
|
| + /* Encode SB using best computed mode(s) */
|
| + // FIXME(rbultje): there really shouldn't be any need to encode_mb/sb
|
| + // for each level that we go up, we can just keep tokens and recon
|
| + // pixels of the lower level; also, inverting SB/MB order (big->small
|
| + // instead of small->big) means we can use as threshold for small, which
|
| + // may enable breakouts if RD is not good enough (i.e. faster)
|
| + encode_sb(cpi, mb_row + y_idx, mb_col + x_idx, 0, tp, is_sb[i]);
|
| }
|
|
|
| + memcpy(cm->above_context + mb_col, &a, sizeof(a));
|
| + memcpy(cm->left_context, &l, sizeof(l));
|
| + sb32_rate += vp9_cost_bit(cm->sb64_coded, 0);
|
| +
|
| + if (!((( mb_cols & 3) && mb_col + 3 >= mb_cols) ||
|
| + ((cm->mb_rows & 3) && mb_row + 3 >= cm->mb_rows))) {
|
| + pick_sb64_modes(cpi, mb_row, mb_col, tp, &sb64_rate, &sb64_dist);
|
| + sb64_rate += vp9_cost_bit(cm->sb64_coded, 1);
|
| + }
|
| +
|
| /* Decide whether to encode as a SB or 4xMBs */
|
| - if (sb_rate < INT_MAX &&
|
| - RDCOST(x->rdmult, x->rddiv, sb_rate, sb_dist) <
|
| - RDCOST(x->rdmult, x->rddiv, mb_rate, mb_dist)) {
|
| - xd->mode_info_context->mbmi.encoded_as_sb = 1;
|
| - xd->mode_info_context[1].mbmi.encoded_as_sb = 1;
|
| - xd->mode_info_context[cm->mode_info_stride].mbmi.encoded_as_sb = 1;
|
| - xd->mode_info_context[1 + cm->mode_info_stride].mbmi.encoded_as_sb = 1;
|
| - *totalrate += sb_rate;
|
| - } else
|
| -#endif
|
| - {
|
| -#if CONFIG_SUPERBLOCKS
|
| - xd->mode_info_context->mbmi.encoded_as_sb = 0;
|
| - if (cm->mb_cols - 1 > mb_col)
|
| - xd->mode_info_context[1].mbmi.encoded_as_sb = 0;
|
| - if (cm->mb_rows - 1 > mb_row) {
|
| - xd->mode_info_context[cm->mode_info_stride].mbmi.encoded_as_sb = 0;
|
| - if (cm->mb_cols - 1 > mb_col)
|
| - xd->mode_info_context[1 + cm->mode_info_stride].mbmi.encoded_as_sb = 0;
|
| - }
|
| -#endif
|
| - *totalrate += mb_rate;
|
| + if (sb64_rate < INT_MAX &&
|
| + RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist) <
|
| + RDCOST(x->rdmult, x->rddiv, sb32_rate, sb32_dist)) {
|
| + is_sb[0] = 2;
|
| + *totalrate += sb64_rate;
|
| + } else {
|
| + *totalrate += sb32_rate;
|
| }
|
|
|
| - /* Encode SB using best computed mode(s) */
|
| - encode_sb(cpi, cm, mb_row, mb_col, x, xd, tp);
|
| -
|
| -#if CONFIG_DEBUG
|
| - assert(x->gf_active_ptr == gfa + 2);
|
| - assert(x->partition_info == pi + 2);
|
| - assert(xd->mode_info_context == mic + 2);
|
| - assert(x->src.y_buffer == yb + 32);
|
| - assert(x->src.u_buffer == ub + 16);
|
| - assert(x->src.v_buffer == vb + 16);
|
| -#endif
|
| + assert(tp_orig == *tp);
|
| + encode_sb64(cpi, mb_row, mb_col, tp, is_sb);
|
| + assert(tp_orig < *tp);
|
| }
|
| -
|
| - // this is to account for the border
|
| - x->gf_active_ptr += mb_cols - (mb_cols & 0x1);
|
| - x->partition_info += xd->mode_info_stride + 1 - (mb_cols & 0x1);
|
| - xd->mode_info_context += xd->mode_info_stride + 1 - (mb_cols & 0x1);
|
| - xd->prev_mode_info_context += xd->mode_info_stride + 1 - (mb_cols & 0x1);
|
| -
|
| -#if CONFIG_DEBUG
|
| - assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
|
| - (xd->mode_info_context - cpi->common.mip));
|
| -#endif
|
| }
|
|
|
| static void init_encode_frame_mb_context(VP9_COMP *cpi) {
|
| @@ -1354,22 +1189,11 @@
|
| VP9_COMMON *const cm = &cpi->common;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
|
|
| - // GF active flags data structure
|
| - x->gf_active_ptr = (signed char *)cpi->gf_active_flags;
|
| -
|
| - // Activity map pointer
|
| - x->mb_activity_ptr = cpi->mb_activity_map;
|
| -
|
| x->act_zbin_adj = 0;
|
| cpi->seg0_idx = 0;
|
| vpx_memset(cpi->ref_pred_count, 0, sizeof(cpi->ref_pred_count));
|
|
|
| - x->partition_info = x->pi;
|
| -
|
| - xd->mode_info_context = cm->mi;
|
| xd->mode_info_stride = cm->mode_info_stride;
|
| - xd->prev_mode_info_context = cm->prev_mi;
|
| -
|
| xd->frame_type = cm->frame_type;
|
|
|
| xd->frames_since_golden = cm->frames_since_golden;
|
| @@ -1380,7 +1204,7 @@
|
| vp9_init_mbmode_probs(cm);
|
|
|
| // Copy data over into macro block data structures.
|
| - x->src = * cpi->Source;
|
| + x->src = *cpi->Source;
|
| xd->pre = cm->yv12_fb[cm->lst_fb_idx];
|
| xd->dst = cm->yv12_fb[cm->new_fb_idx];
|
|
|
| @@ -1404,10 +1228,9 @@
|
| vp9_zero(cpi->sub_mv_ref_count)
|
| vp9_zero(cpi->mbsplit_count)
|
| vp9_zero(cpi->common.fc.mv_ref_ct)
|
| -#if CONFIG_SUPERBLOCKS
|
| vp9_zero(cpi->sb_ymode_count)
|
| - cpi->sb_count = 0;
|
| -#endif
|
| + vp9_zero(cpi->sb32_count);
|
| + vp9_zero(cpi->sb64_count);
|
| #if CONFIG_COMP_INTERINTRA_PRED
|
| vp9_zero(cpi->interintra_count);
|
| vp9_zero(cpi->interintra_select_count);
|
| @@ -1438,11 +1261,6 @@
|
| // this frame which may be updated with each iteration of the recode loop.
|
| vp9_compute_mod_refprobs(cm);
|
|
|
| -#if CONFIG_NEW_MVREF
|
| - // temp stats reset
|
| - vp9_zero( cpi->best_ref_index_counts );
|
| -#endif
|
| -
|
| // debug output
|
| #if DBG_PRNT_SEGMAP
|
| {
|
| @@ -1466,28 +1284,23 @@
|
| cpi->skip_true_count[0] = cpi->skip_true_count[1] = cpi->skip_true_count[2] = 0;
|
| cpi->skip_false_count[0] = cpi->skip_false_count[1] = cpi->skip_false_count[2] = 0;
|
|
|
| -#if CONFIG_PRED_FILTER
|
| - if (cm->current_video_frame == 0) {
|
| - // Initially assume that we'll signal the prediction filter
|
| - // state at the frame level and that it is off.
|
| - cpi->common.pred_filter_mode = 0;
|
| - cpi->common.prob_pred_filter_off = 128;
|
| - }
|
| - cpi->pred_filter_on_count = 0;
|
| - cpi->pred_filter_off_count = 0;
|
| -#endif
|
| vp9_zero(cpi->switchable_interp_count);
|
| + vp9_zero(cpi->best_switchable_interp_count);
|
|
|
| xd->mode_info_context = cm->mi;
|
| xd->prev_mode_info_context = cm->prev_mi;
|
|
|
| vp9_zero(cpi->NMVcount);
|
| - vp9_zero(cpi->coef_counts);
|
| - vp9_zero(cpi->hybrid_coef_counts);
|
| + vp9_zero(cpi->coef_counts_4x4);
|
| + vp9_zero(cpi->hybrid_coef_counts_4x4);
|
| vp9_zero(cpi->coef_counts_8x8);
|
| vp9_zero(cpi->hybrid_coef_counts_8x8);
|
| vp9_zero(cpi->coef_counts_16x16);
|
| vp9_zero(cpi->hybrid_coef_counts_16x16);
|
| + vp9_zero(cpi->coef_counts_32x32);
|
| +#if CONFIG_NEW_MVREF
|
| + vp9_zero(cpi->mb_mv_ref_count);
|
| +#endif
|
|
|
| vp9_frame_init_quantizer(cpi);
|
|
|
| @@ -1508,7 +1321,8 @@
|
| vpx_memset(cpi->rd_comp_pred_diff, 0, sizeof(cpi->rd_comp_pred_diff));
|
| vpx_memset(cpi->single_pred_count, 0, sizeof(cpi->single_pred_count));
|
| vpx_memset(cpi->comp_pred_count, 0, sizeof(cpi->comp_pred_count));
|
| - vpx_memset(cpi->txfm_count, 0, sizeof(cpi->txfm_count));
|
| + vpx_memset(cpi->txfm_count_32x32p, 0, sizeof(cpi->txfm_count_32x32p));
|
| + vpx_memset(cpi->txfm_count_16x16p, 0, sizeof(cpi->txfm_count_16x16p));
|
| vpx_memset(cpi->txfm_count_8x8p, 0, sizeof(cpi->txfm_count_8x8p));
|
| vpx_memset(cpi->rd_tx_select_diff, 0, sizeof(cpi->rd_tx_select_diff));
|
| {
|
| @@ -1517,15 +1331,8 @@
|
|
|
| {
|
| // For each row of SBs in the frame
|
| - for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 2) {
|
| - int offset = (cm->mb_cols + 1) & ~0x1;
|
| -
|
| - encode_sb_row(cpi, cm, mb_row, x, xd, &tp, &totalrate);
|
| -
|
| - // adjust to the next row of SBs
|
| - x->src.y_buffer += 32 * x->src.y_stride - 16 * offset;
|
| - x->src.u_buffer += 16 * x->src.uv_stride - 8 * offset;
|
| - x->src.v_buffer += 16 * x->src.uv_stride - 8 * offset;
|
| + for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4) {
|
| + encode_sb_row(cpi, mb_row, &tp, &totalrate);
|
| }
|
|
|
| cpi->tok_count = (unsigned int)(tp - cpi->tok);
|
| @@ -1570,78 +1377,136 @@
|
| }
|
| }
|
|
|
| +static void reset_skip_txfm_size_mb(VP9_COMP *cpi,
|
| + MODE_INFO *mi, TX_SIZE txfm_max) {
|
| + MB_MODE_INFO *const mbmi = &mi->mbmi;
|
| +
|
| + if (mbmi->txfm_size > txfm_max) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + const int segment_id = mbmi->segment_id;
|
| +
|
| + xd->mode_info_context = mi;
|
| + assert((vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| + vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
|
| + (cm->mb_no_coeff_skip && mbmi->mb_skip_coeff));
|
| + mbmi->txfm_size = txfm_max;
|
| + }
|
| +}
|
| +
|
| +static int get_skip_flag(MODE_INFO *mi, int mis, int ymbs, int xmbs) {
|
| + int x, y;
|
| +
|
| + for (y = 0; y < ymbs; y++) {
|
| + for (x = 0; x < xmbs; x++) {
|
| + if (!mi[y * mis + x].mbmi.mb_skip_coeff)
|
| + return 0;
|
| + }
|
| + }
|
| +
|
| + return 1;
|
| +}
|
| +
|
| +static void set_txfm_flag(MODE_INFO *mi, int mis, int ymbs, int xmbs,
|
| + TX_SIZE txfm_size) {
|
| + int x, y;
|
| +
|
| + for (y = 0; y < ymbs; y++) {
|
| + for (x = 0; x < xmbs; x++) {
|
| + mi[y * mis + x].mbmi.txfm_size = txfm_size;
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void reset_skip_txfm_size_sb32(VP9_COMP *cpi, MODE_INFO *mi,
|
| + int mis, TX_SIZE txfm_max,
|
| + int mb_rows_left, int mb_cols_left) {
|
| + MB_MODE_INFO *const mbmi = &mi->mbmi;
|
| +
|
| + if (mbmi->txfm_size > txfm_max) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + const int segment_id = mbmi->segment_id;
|
| + const int ymbs = MIN(2, mb_rows_left);
|
| + const int xmbs = MIN(2, mb_cols_left);
|
| +
|
| + xd->mode_info_context = mi;
|
| + assert((vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| + vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
|
| + (cm->mb_no_coeff_skip && get_skip_flag(mi, mis, ymbs, xmbs)));
|
| + set_txfm_flag(mi, mis, ymbs, xmbs, txfm_max);
|
| + }
|
| +}
|
| +
|
| +static void reset_skip_txfm_size_sb64(VP9_COMP *cpi, MODE_INFO *mi,
|
| + int mis, TX_SIZE txfm_max,
|
| + int mb_rows_left, int mb_cols_left) {
|
| + MB_MODE_INFO *const mbmi = &mi->mbmi;
|
| +
|
| + if (mbmi->txfm_size > txfm_max) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + const int segment_id = mbmi->segment_id;
|
| + const int ymbs = MIN(4, mb_rows_left);
|
| + const int xmbs = MIN(4, mb_cols_left);
|
| +
|
| + xd->mode_info_context = mi;
|
| + assert((vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| + vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
|
| + (cm->mb_no_coeff_skip && get_skip_flag(mi, mis, ymbs, xmbs)));
|
| + set_txfm_flag(mi, mis, ymbs, xmbs, txfm_max);
|
| + }
|
| +}
|
| +
|
| static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) {
|
| - VP9_COMMON *cm = &cpi->common;
|
| - int mb_row, mb_col, mis = cm->mode_info_stride, segment_id;
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + int mb_row, mb_col;
|
| + const int mis = cm->mode_info_stride;
|
| MODE_INFO *mi, *mi_ptr = cm->mi;
|
| -#if CONFIG_SUPERBLOCKS
|
| - int skip;
|
| - MODE_INFO *sb_mi_ptr = cm->mi, *sb_mi;
|
| - MB_MODE_INFO *sb_mbmi;
|
| -#endif
|
| - MB_MODE_INFO *mbmi;
|
| - MACROBLOCK *x = &cpi->mb;
|
| - MACROBLOCKD *xd = &x->e_mbd;
|
|
|
| - for (mb_row = 0; mb_row < cm->mb_rows; mb_row++, mi_ptr += mis) {
|
| + for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4, mi_ptr += 4 * mis) {
|
| mi = mi_ptr;
|
| -#if CONFIG_SUPERBLOCKS
|
| - sb_mi = sb_mi_ptr;
|
| -#endif
|
| - for (mb_col = 0; mb_col < cm->mb_cols; mb_col++, mi++) {
|
| - mbmi = &mi->mbmi;
|
| -#if CONFIG_SUPERBLOCKS
|
| - sb_mbmi = &sb_mi->mbmi;
|
| -#endif
|
| - if (mbmi->txfm_size > txfm_max) {
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (sb_mbmi->encoded_as_sb) {
|
| - if (!((mb_col & 1) || (mb_row & 1))) {
|
| - segment_id = mbmi->segment_id;
|
| - skip = mbmi->mb_skip_coeff;
|
| - if (mb_col < cm->mb_cols - 1) {
|
| - segment_id = segment_id && mi[1].mbmi.segment_id;
|
| - skip = skip && mi[1].mbmi.mb_skip_coeff;
|
| + for (mb_col = 0; mb_col < cm->mb_cols; mb_col += 4, mi += 4) {
|
| + if (mi->mbmi.sb_type == BLOCK_SIZE_SB64X64) {
|
| + reset_skip_txfm_size_sb64(cpi, mi, mis, txfm_max,
|
| + cm->mb_rows - mb_row, cm->mb_cols - mb_col);
|
| + } else {
|
| + int i;
|
| +
|
| + for (i = 0; i < 4; i++) {
|
| + const int x_idx_sb = (i & 1) << 1, y_idx_sb = i & 2;
|
| + MODE_INFO *sb_mi = mi + y_idx_sb * mis + x_idx_sb;
|
| +
|
| + if (mb_row + y_idx_sb >= cm->mb_rows ||
|
| + mb_col + x_idx_sb >= cm->mb_cols)
|
| + continue;
|
| +
|
| + if (sb_mi->mbmi.sb_type) {
|
| + reset_skip_txfm_size_sb32(cpi, sb_mi, mis, txfm_max,
|
| + cm->mb_rows - mb_row - y_idx_sb,
|
| + cm->mb_cols - mb_col - x_idx_sb);
|
| + } else {
|
| + int m;
|
| +
|
| + for (m = 0; m < 4; m++) {
|
| + const int x_idx = x_idx_sb + (m & 1), y_idx = y_idx_sb + (m >> 1);
|
| + MODE_INFO *mb_mi;
|
| +
|
| + if (mb_col + x_idx >= cm->mb_cols ||
|
| + mb_row + y_idx >= cm->mb_rows)
|
| + continue;
|
| +
|
| + mb_mi = mi + y_idx * mis + x_idx;
|
| + assert(mb_mi->mbmi.sb_type == BLOCK_SIZE_MB16X16);
|
| + reset_skip_txfm_size_mb(cpi, mb_mi, txfm_max);
|
| }
|
| - if (mb_row < cm->mb_rows - 1) {
|
| - segment_id = segment_id &&
|
| - mi[cm->mode_info_stride].mbmi.segment_id;
|
| - skip = skip && mi[cm->mode_info_stride].mbmi.mb_skip_coeff;
|
| - if (mb_col < cm->mb_cols - 1) {
|
| - segment_id = segment_id &&
|
| - mi[cm->mode_info_stride + 1].mbmi.segment_id;
|
| - skip = skip && mi[cm->mode_info_stride + 1].mbmi.mb_skip_coeff;
|
| - }
|
| - }
|
| - xd->mode_info_context = mi;
|
| - assert((vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| - vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
|
| - (cm->mb_no_coeff_skip && skip));
|
| - mbmi->txfm_size = txfm_max;
|
| - } else {
|
| - mbmi->txfm_size = sb_mbmi->txfm_size;
|
| }
|
| - } else {
|
| -#endif
|
| - segment_id = mbmi->segment_id;
|
| - xd->mode_info_context = mi;
|
| - assert((vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| - vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
|
| - (cm->mb_no_coeff_skip && mbmi->mb_skip_coeff));
|
| - mbmi->txfm_size = txfm_max;
|
| -#if CONFIG_SUPERBLOCKS
|
| }
|
| -#endif
|
| }
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (mb_col & 1)
|
| - sb_mi += 2;
|
| -#endif
|
| }
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (mb_row & 1)
|
| - sb_mi_ptr += 2 * mis;
|
| -#endif
|
| }
|
| }
|
|
|
| @@ -1701,7 +1566,7 @@
|
| * keyframe's probabilities as an estimate of what the current keyframe's
|
| * coefficient cost distributions may look like. */
|
| if (frame_type == 0) {
|
| - txfm_type = ALLOW_16X16;
|
| + txfm_type = ALLOW_32X32;
|
| } else
|
| #if 0
|
| /* FIXME (rbultje)
|
| @@ -1732,9 +1597,9 @@
|
| } else
|
| txfm_type = ALLOW_8X8;
|
| #else
|
| - txfm_type = cpi->rd_tx_select_threshes[frame_type][ALLOW_16X16] >=
|
| - cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ?
|
| - ALLOW_16X16 : TX_MODE_SELECT;
|
| + txfm_type = cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] >=
|
| + cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ?
|
| + ALLOW_32X32 : TX_MODE_SELECT;
|
| #endif
|
| cpi->common.txfm_mode = txfm_type;
|
| if (txfm_type != TX_MODE_SELECT) {
|
| @@ -1754,7 +1619,8 @@
|
| int64_t pd = cpi->rd_tx_select_diff[i];
|
| int diff;
|
| if (i == TX_MODE_SELECT)
|
| - pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZE_MAX - 1), 0);
|
| + pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv,
|
| + 2048 * (TX_SIZE_MAX_SB - 1), 0);
|
| diff = (int)(pd / cpi->common.MBs);
|
| cpi->rd_tx_select_threshes[frame_type][i] += diff;
|
| cpi->rd_tx_select_threshes[frame_type][i] /= 2;
|
| @@ -1777,21 +1643,35 @@
|
| }
|
|
|
| if (cpi->common.txfm_mode == TX_MODE_SELECT) {
|
| - const int count4x4 = cpi->txfm_count[TX_4X4] + cpi->txfm_count_8x8p[TX_4X4];
|
| - const int count8x8 = cpi->txfm_count[TX_8X8];
|
| + const int count4x4 = cpi->txfm_count_16x16p[TX_4X4] +
|
| + cpi->txfm_count_32x32p[TX_4X4] +
|
| + cpi->txfm_count_8x8p[TX_4X4];
|
| + const int count8x8_lp = cpi->txfm_count_32x32p[TX_8X8] +
|
| + cpi->txfm_count_16x16p[TX_8X8];
|
| const int count8x8_8x8p = cpi->txfm_count_8x8p[TX_8X8];
|
| - const int count16x16 = cpi->txfm_count[TX_16X16];
|
| + const int count16x16_16x16p = cpi->txfm_count_16x16p[TX_16X16];
|
| + const int count16x16_lp = cpi->txfm_count_32x32p[TX_16X16];
|
| + const int count32x32 = cpi->txfm_count_32x32p[TX_32X32];
|
|
|
| - if (count4x4 == 0 && count16x16 == 0) {
|
| + if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
|
| + count32x32 == 0) {
|
| cpi->common.txfm_mode = ALLOW_8X8;
|
| reset_skip_txfm_size(cpi, TX_8X8);
|
| - } else if (count8x8 == 0 && count16x16 == 0 && count8x8_8x8p == 0) {
|
| + } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
|
| + count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
|
| cpi->common.txfm_mode = ONLY_4X4;
|
| reset_skip_txfm_size(cpi, TX_4X4);
|
| - } else if (count8x8 == 0 && count4x4 == 0) {
|
| + } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
|
| + cpi->common.txfm_mode = ALLOW_32X32;
|
| + } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
|
| cpi->common.txfm_mode = ALLOW_16X16;
|
| + reset_skip_txfm_size(cpi, TX_16X16);
|
| }
|
| }
|
| +
|
| + // Update interpolation filter strategy for next frame.
|
| + if ((cpi->common.frame_type != KEY_FRAME) && (cpi->sf.search_best_filter))
|
| + select_interp_filter_type(cpi);
|
| } else {
|
| encode_frame_internal(cpi);
|
| }
|
| @@ -1835,35 +1715,18 @@
|
|
|
| vp9_build_block_doffsets(&x->e_mbd);
|
|
|
| -#if !CONFIG_SUPERBLOCKS
|
| - // y blocks
|
| - x->thismb_ptr = &x->thismb[0];
|
| for (br = 0; br < 4; br++) {
|
| for (bc = 0; bc < 4; bc++) {
|
| BLOCK *this_block = &x->block[block];
|
| // this_block->base_src = &x->src.y_buffer;
|
| // this_block->src_stride = x->src.y_stride;
|
| // this_block->src = 4 * br * this_block->src_stride + 4 * bc;
|
| - this_block->base_src = &x->thismb_ptr;
|
| - this_block->src_stride = 16;
|
| - this_block->src = 4 * br * 16 + 4 * bc;
|
| - ++block;
|
| - }
|
| - }
|
| -#else
|
| - for (br = 0; br < 4; br++) {
|
| - for (bc = 0; bc < 4; bc++) {
|
| - BLOCK *this_block = &x->block[block];
|
| - // this_block->base_src = &x->src.y_buffer;
|
| - // this_block->src_stride = x->src.y_stride;
|
| - // this_block->src = 4 * br * this_block->src_stride + 4 * bc;
|
| this_block->base_src = &x->src.y_buffer;
|
| this_block->src_stride = x->src.y_stride;
|
| this_block->src = 4 * br * this_block->src_stride + 4 * bc;
|
| ++block;
|
| }
|
| }
|
| -#endif
|
|
|
| // u blocks
|
| for (br = 0; br < 2; br++) {
|
| @@ -1917,12 +1780,11 @@
|
| }
|
| #endif
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| - if (xd->mode_info_context->mbmi.encoded_as_sb) {
|
| + if (xd->mode_info_context->mbmi.sb_type) {
|
| ++cpi->sb_ymode_count[m];
|
| - } else
|
| -#endif
|
| + } else {
|
| ++cpi->ymode_count[m];
|
| + }
|
| if (m != I8X8_PRED)
|
| ++cpi->y_uv_mode_count[m][uvm];
|
| else {
|
| @@ -1964,16 +1826,14 @@
|
| #endif
|
| }
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| static void update_sb_skip_coeff_state(VP9_COMP *cpi,
|
| - MACROBLOCK *x,
|
| ENTROPY_CONTEXT_PLANES ta[4],
|
| ENTROPY_CONTEXT_PLANES tl[4],
|
| TOKENEXTRA *t[4],
|
| TOKENEXTRA **tp,
|
| - int skip[4])
|
| -{
|
| - TOKENEXTRA tokens[4][16 * 24];
|
| + int skip[4], int output_enabled) {
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + TOKENEXTRA tokens[4][16 * 25];
|
| int n_tokens[4], n;
|
|
|
| // if there were no skips, we don't need to do anything
|
| @@ -2013,7 +1873,7 @@
|
| if (skip[n]) {
|
| x->e_mbd.above_context = &ta[n];
|
| x->e_mbd.left_context = &tl[n];
|
| - vp9_stuff_mb(cpi, &x->e_mbd, tp, 0);
|
| + vp9_stuff_mb(cpi, &x->e_mbd, tp, !output_enabled);
|
| } else {
|
| if (n_tokens[n]) {
|
| memcpy(*tp, tokens[n], sizeof(*t[0]) * n_tokens[n]);
|
| @@ -2022,23 +1882,129 @@
|
| }
|
| }
|
| }
|
| -#endif /* CONFIG_SUPERBLOCKS */
|
|
|
| -static void encode_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
|
| - TOKENEXTRA **t, int recon_yoffset,
|
| - int recon_uvoffset, int output_enabled,
|
| - int mb_col, int mb_row) {
|
| - VP9_COMMON *cm = &cpi->common;
|
| +static void update_sb64_skip_coeff_state(VP9_COMP *cpi,
|
| + ENTROPY_CONTEXT_PLANES ta[16],
|
| + ENTROPY_CONTEXT_PLANES tl[16],
|
| + TOKENEXTRA *t[16],
|
| + TOKENEXTRA **tp,
|
| + int skip[16], int output_enabled) {
|
| + MACROBLOCK *const x = &cpi->mb;
|
| +
|
| + if (x->e_mbd.mode_info_context->mbmi.txfm_size == TX_32X32) {
|
| + TOKENEXTRA tokens[4][1024+512];
|
| + int n_tokens[4], n;
|
| +
|
| + // if there were no skips, we don't need to do anything
|
| + if (!skip[0] && !skip[1] && !skip[2] && !skip[3])
|
| + return;
|
| +
|
| + // if we don't do coeff skipping for this frame, we don't
|
| + // need to do anything here
|
| + if (!cpi->common.mb_no_coeff_skip)
|
| + return;
|
| +
|
| + // if all 4 MBs skipped coeff coding, nothing to be done
|
| + if (skip[0] && skip[1] && skip[2] && skip[3])
|
| + return;
|
| +
|
| + // so the situation now is that we want to skip coeffs
|
| + // for some MBs, but not all, and we didn't code EOB
|
| + // coefficients for them. However, the skip flag for this
|
| + // SB will be 0 overall, so we need to insert EOBs in the
|
| + // middle of the token tree. Do so here.
|
| + for (n = 0; n < 4; n++) {
|
| + if (n < 3) {
|
| + n_tokens[n] = t[n + 1] - t[n];
|
| + } else {
|
| + n_tokens[n] = *tp - t[3];
|
| + }
|
| + if (n_tokens[n]) {
|
| + memcpy(tokens[n], t[n], n_tokens[n] * sizeof(*t[0]));
|
| + }
|
| + }
|
| +
|
| + // reset pointer, stuff EOBs where necessary
|
| + *tp = t[0];
|
| + for (n = 0; n < 4; n++) {
|
| + if (skip[n]) {
|
| + x->e_mbd.above_context = &ta[n * 2];
|
| + x->e_mbd.left_context = &tl[n * 2];
|
| + vp9_stuff_sb(cpi, &x->e_mbd, tp, !output_enabled);
|
| + } else {
|
| + if (n_tokens[n]) {
|
| + memcpy(*tp, tokens[n], sizeof(*t[0]) * n_tokens[n]);
|
| + }
|
| + (*tp) += n_tokens[n];
|
| + }
|
| + }
|
| + } else {
|
| + TOKENEXTRA tokens[16][16 * 25];
|
| + int n_tokens[16], n;
|
| +
|
| + // if there were no skips, we don't need to do anything
|
| + if (!skip[ 0] && !skip[ 1] && !skip[ 2] && !skip[ 3] &&
|
| + !skip[ 4] && !skip[ 5] && !skip[ 6] && !skip[ 7] &&
|
| + !skip[ 8] && !skip[ 9] && !skip[10] && !skip[11] &&
|
| + !skip[12] && !skip[13] && !skip[14] && !skip[15])
|
| + return;
|
| +
|
| + // if we don't do coeff skipping for this frame, we don't
|
| + // need to do anything here
|
| + if (!cpi->common.mb_no_coeff_skip)
|
| + return;
|
| +
|
| + // if all 4 MBs skipped coeff coding, nothing to be done
|
| + if (skip[ 0] && skip[ 1] && skip[ 2] && skip[ 3] &&
|
| + skip[ 4] && skip[ 5] && skip[ 6] && skip[ 7] &&
|
| + skip[ 8] && skip[ 9] && skip[10] && skip[11] &&
|
| + skip[12] && skip[13] && skip[14] && skip[15])
|
| + return;
|
| +
|
| + // so the situation now is that we want to skip coeffs
|
| + // for some MBs, but not all, and we didn't code EOB
|
| + // coefficients for them. However, the skip flag for this
|
| + // SB will be 0 overall, so we need to insert EOBs in the
|
| + // middle of the token tree. Do so here.
|
| + for (n = 0; n < 16; n++) {
|
| + if (n < 15) {
|
| + n_tokens[n] = t[n + 1] - t[n];
|
| + } else {
|
| + n_tokens[n] = *tp - t[15];
|
| + }
|
| + if (n_tokens[n]) {
|
| + memcpy(tokens[n], t[n], n_tokens[n] * sizeof(*t[0]));
|
| + }
|
| + }
|
| +
|
| + // reset pointer, stuff EOBs where necessary
|
| + *tp = t[0];
|
| + for (n = 0; n < 16; n++) {
|
| + if (skip[n]) {
|
| + x->e_mbd.above_context = &ta[n];
|
| + x->e_mbd.left_context = &tl[n];
|
| + vp9_stuff_mb(cpi, &x->e_mbd, tp, !output_enabled);
|
| + } else {
|
| + if (n_tokens[n]) {
|
| + memcpy(*tp, tokens[n], sizeof(*t[0]) * n_tokens[n]);
|
| + }
|
| + (*tp) += n_tokens[n];
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled,
|
| + int mb_row, int mb_col) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| - MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
|
| - unsigned char *segment_id = &mbmi->segment_id;
|
| - int seg_ref_active;
|
| + MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
|
| unsigned char ref_pred_flag;
|
|
|
| - x->skip = 0;
|
| -#if CONFIG_SUPERBLOCKS
|
| - assert(!xd->mode_info_context->mbmi.encoded_as_sb);
|
| -#endif
|
| + assert(!xd->mode_info_context->mbmi.sb_type);
|
|
|
| #ifdef ENC_DEBUG
|
| enc_debug = (cpi->common.current_video_frame == 46 &&
|
| @@ -2079,8 +2045,6 @@
|
|
|
| vp9_update_zbin_extra(cpi, x);
|
|
|
| - seg_ref_active = vp9_segfeature_active(xd, *segment_id, SEG_LVL_REF_FRAME);
|
| -
|
| // SET VARIOUS PREDICTION FLAGS
|
|
|
| // Did the chosen reference frame match its predicted value.
|
| @@ -2250,7 +2214,7 @@
|
| mbmi->mb_skip_coeff = 1;
|
| if (output_enabled)
|
| cpi->skip_true_count[mb_skip_context]++;
|
| - vp9_fix_contexts(xd);
|
| + vp9_reset_mb_tokens_context(xd);
|
| } else {
|
| vp9_stuff_mb(cpi, xd, t, !output_enabled);
|
| mbmi->mb_skip_coeff = 0;
|
| @@ -2265,9 +2229,10 @@
|
| !((cpi->common.mb_no_coeff_skip && mbmi->mb_skip_coeff) ||
|
| (vp9_segfeature_active(&x->e_mbd, segment_id, SEG_LVL_EOB) &&
|
| vp9_get_segdata(&x->e_mbd, segment_id, SEG_LVL_EOB) == 0))) {
|
| + assert(mbmi->txfm_size <= TX_16X16);
|
| if (mbmi->mode != B_PRED && mbmi->mode != I8X8_PRED &&
|
| mbmi->mode != SPLITMV) {
|
| - cpi->txfm_count[mbmi->txfm_size]++;
|
| + cpi->txfm_count_16x16p[mbmi->txfm_size]++;
|
| } else if (mbmi->mode == I8X8_PRED ||
|
| (mbmi->mode == SPLITMV &&
|
| mbmi->partitioning != PARTITIONING_4X4)) {
|
| @@ -2287,11 +2252,11 @@
|
| }
|
| }
|
|
|
| -#if CONFIG_SUPERBLOCKS
|
| -static void encode_superblock(VP9_COMP *cpi, MACROBLOCK *x,
|
| - TOKENEXTRA **t, int recon_yoffset,
|
| - int recon_uvoffset, int mb_col, int mb_row) {
|
| +static void encode_superblock32(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled, int mb_row, int mb_col) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| const uint8_t *src = x->src.y_buffer;
|
| uint8_t *dst = xd->dst.y_buffer;
|
| @@ -2301,7 +2266,6 @@
|
| uint8_t *vdst = xd->dst.v_buffer;
|
| int src_y_stride = x->src.y_stride, dst_y_stride = xd->dst.y_stride;
|
| int src_uv_stride = x->src.uv_stride, dst_uv_stride = xd->dst.uv_stride;
|
| - int seg_ref_active;
|
| unsigned char ref_pred_flag;
|
| int n;
|
| TOKENEXTRA *tp[4];
|
| @@ -2309,9 +2273,8 @@
|
| MODE_INFO *mi = x->e_mbd.mode_info_context;
|
| unsigned int segment_id = mi->mbmi.segment_id;
|
| ENTROPY_CONTEXT_PLANES ta[4], tl[4];
|
| + const int mis = cm->mode_info_stride;
|
|
|
| - x->skip = 0;
|
| -
|
| if (cm->frame_type == KEY_FRAME) {
|
| if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
|
| adjust_act_zbin(cpi, x);
|
| @@ -2344,10 +2307,7 @@
|
|
|
| vp9_update_zbin_extra(cpi, x);
|
|
|
| - seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);
|
| -
|
| // SET VARIOUS PREDICTION FLAGS
|
| -
|
| // Did the chosen reference frame match its predicted value.
|
| ref_pred_flag = ((xd->mode_info_context->mbmi.ref_frame ==
|
| vp9_get_pred_ref(cm, xd)));
|
| @@ -2358,7 +2318,8 @@
|
| if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
|
| vp9_build_intra_predictors_sby_s(&x->e_mbd);
|
| vp9_build_intra_predictors_sbuv_s(&x->e_mbd);
|
| - sum_intra_stats(cpi, x);
|
| + if (output_enabled)
|
| + sum_intra_stats(cpi, x);
|
| } else {
|
| int ref_fb_idx;
|
|
|
| @@ -2398,74 +2359,391 @@
|
| xd->dst.y_stride, xd->dst.uv_stride);
|
| }
|
|
|
| - for (n = 0; n < 4; n++) {
|
| - int x_idx = n & 1, y_idx = n >> 1;
|
| + if (xd->mode_info_context->mbmi.txfm_size == TX_32X32) {
|
| + if (!x->skip) {
|
| + vp9_subtract_sby_s_c(x->sb_coeff_data.src_diff, src, src_y_stride,
|
| + dst, dst_y_stride);
|
| + vp9_subtract_sbuv_s_c(x->sb_coeff_data.src_diff,
|
| + usrc, vsrc, src_uv_stride,
|
| + udst, vdst, dst_uv_stride);
|
| + vp9_transform_sby_32x32(x);
|
| + vp9_transform_sbuv_16x16(x);
|
| + vp9_quantize_sby_32x32(x);
|
| + vp9_quantize_sbuv_16x16(x);
|
| + // TODO(rbultje): trellis optimize
|
| + vp9_inverse_transform_sbuv_16x16(&x->e_mbd.sb_coeff_data);
|
| + vp9_inverse_transform_sby_32x32(&x->e_mbd.sb_coeff_data);
|
| + vp9_recon_sby_s_c(&x->e_mbd, dst);
|
| + vp9_recon_sbuv_s_c(&x->e_mbd, udst, vdst);
|
|
|
| - xd->left_context = cm->left_context + y_idx;
|
| - xd->above_context = cm->above_context + mb_col + x_idx;
|
| - memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
|
| - memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
|
| - tp[n] = *t;
|
| - xd->mode_info_context = mi + x_idx + y_idx * cm->mode_info_stride;
|
| -
|
| - vp9_subtract_mby_s_c(x->src_diff,
|
| - src + x_idx * 16 + y_idx * 16 * src_y_stride,
|
| - src_y_stride,
|
| - dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
|
| - dst_y_stride);
|
| - vp9_subtract_mbuv_s_c(x->src_diff,
|
| - usrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| - vsrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| - src_uv_stride,
|
| - udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| - vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| - dst_uv_stride);
|
| - vp9_fidct_mb(x);
|
| - vp9_recon_mby_s_c(&x->e_mbd,
|
| - dst + x_idx * 16 + y_idx * 16 * dst_y_stride);
|
| - vp9_recon_mbuv_s_c(&x->e_mbd,
|
| - udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| - vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride);
|
| -
|
| - if (!x->skip) {
|
| - vp9_tokenize_mb(cpi, &x->e_mbd, t, 0);
|
| - skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff;
|
| + vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled);
|
| } else {
|
| int mb_skip_context =
|
| - cpi->common.mb_no_coeff_skip ?
|
| - (x->e_mbd.mode_info_context - 1)->mbmi.mb_skip_coeff +
|
| - (x->e_mbd.mode_info_context - cpi->common.mode_info_stride)->mbmi.mb_skip_coeff :
|
| + cpi->common.mb_no_coeff_skip ?
|
| + (mi - 1)->mbmi.mb_skip_coeff +
|
| + (mi - mis)->mbmi.mb_skip_coeff :
|
| 0;
|
| - xd->mode_info_context->mbmi.mb_skip_coeff = skip[n] = 1;
|
| - if (cpi->common.mb_no_coeff_skip) {
|
| - // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| - cpi->skip_true_count[mb_skip_context]++;
|
| - vp9_fix_contexts(xd);
|
| + mi->mbmi.mb_skip_coeff = 1;
|
| + if (cm->mb_no_coeff_skip) {
|
| + if (output_enabled)
|
| + cpi->skip_true_count[mb_skip_context]++;
|
| + vp9_fix_contexts_sb(xd);
|
| } else {
|
| - vp9_stuff_mb(cpi, xd, t, 0);
|
| - // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| - cpi->skip_false_count[mb_skip_context]++;
|
| + vp9_stuff_sb(cpi, xd, t, !output_enabled);
|
| + if (output_enabled)
|
| + cpi->skip_false_count[mb_skip_context]++;
|
| }
|
| }
|
| - }
|
|
|
| - xd->mode_info_context = mi;
|
| - update_sb_skip_coeff_state(cpi, x, ta, tl, tp, t, skip);
|
| - if (cm->txfm_mode == TX_MODE_SELECT &&
|
| - !((cm->mb_no_coeff_skip && skip[0] && skip[1] && skip[2] && skip[3]) ||
|
| - (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| - vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
|
| - cpi->txfm_count[mi->mbmi.txfm_size]++;
|
| - } else {
|
| - TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ? TX_16X16 : cm->txfm_mode;
|
| - mi->mbmi.txfm_size = sz;
|
| + // copy skip flag on all mb_mode_info contexts in this SB
|
| + // if this was a skip at this txfm size
|
| if (mb_col < cm->mb_cols - 1)
|
| - mi[1].mbmi.txfm_size = sz;
|
| + mi[1].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
|
| if (mb_row < cm->mb_rows - 1) {
|
| - mi[cm->mode_info_stride].mbmi.txfm_size = sz;
|
| + mi[mis].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
|
| if (mb_col < cm->mb_cols - 1)
|
| - mi[cm->mode_info_stride + 1].mbmi.txfm_size = sz;
|
| + mi[mis + 1].mbmi.mb_skip_coeff = mi->mbmi.mb_skip_coeff;
|
| }
|
| + skip[0] = skip[2] = skip[1] = skip[3] = mi->mbmi.mb_skip_coeff;
|
| + } else {
|
| + for (n = 0; n < 4; n++) {
|
| + int x_idx = n & 1, y_idx = n >> 1;
|
| +
|
| + xd->left_context = cm->left_context + y_idx + (mb_row & 2);
|
| + xd->above_context = cm->above_context + mb_col + x_idx;
|
| + memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
|
| + memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
|
| + tp[n] = *t;
|
| + xd->mode_info_context = mi + x_idx + y_idx * mis;
|
| +
|
| + if (!x->skip) {
|
| + vp9_subtract_mby_s_c(x->src_diff,
|
| + src + x_idx * 16 + y_idx * 16 * src_y_stride,
|
| + src_y_stride,
|
| + dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
|
| + dst_y_stride);
|
| + vp9_subtract_mbuv_s_c(x->src_diff,
|
| + usrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| + vsrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| + src_uv_stride,
|
| + udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + dst_uv_stride);
|
| + vp9_fidct_mb(x);
|
| + vp9_recon_mby_s_c(&x->e_mbd,
|
| + dst + x_idx * 16 + y_idx * 16 * dst_y_stride);
|
| + vp9_recon_mbuv_s_c(&x->e_mbd,
|
| + udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride);
|
| +
|
| + vp9_tokenize_mb(cpi, &x->e_mbd, t, !output_enabled);
|
| + skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff;
|
| + } else {
|
| + int mb_skip_context = cpi->common.mb_no_coeff_skip ?
|
| + (x->e_mbd.mode_info_context - 1)->mbmi.mb_skip_coeff +
|
| + (x->e_mbd.mode_info_context - mis)->mbmi.mb_skip_coeff :
|
| + 0;
|
| + xd->mode_info_context->mbmi.mb_skip_coeff = skip[n] = 1;
|
| + if (cpi->common.mb_no_coeff_skip) {
|
| + // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| + if (output_enabled)
|
| + cpi->skip_true_count[mb_skip_context]++;
|
| + vp9_reset_mb_tokens_context(xd);
|
| + } else {
|
| + vp9_stuff_mb(cpi, xd, t, !output_enabled);
|
| + // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| + if (output_enabled)
|
| + cpi->skip_false_count[mb_skip_context]++;
|
| + }
|
| + }
|
| + }
|
| +
|
| + xd->mode_info_context = mi;
|
| + update_sb_skip_coeff_state(cpi, ta, tl, tp, t, skip, output_enabled);
|
| }
|
| +
|
| + if (output_enabled) {
|
| + if (cm->txfm_mode == TX_MODE_SELECT &&
|
| + !((cm->mb_no_coeff_skip && skip[0] && skip[1] && skip[2] && skip[3]) ||
|
| + (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| + vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
|
| + cpi->txfm_count_32x32p[mi->mbmi.txfm_size]++;
|
| + } else {
|
| + TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ?
|
| + TX_32X32 :
|
| + cm->txfm_mode;
|
| + mi->mbmi.txfm_size = sz;
|
| + if (mb_col < cm->mb_cols - 1)
|
| + mi[1].mbmi.txfm_size = sz;
|
| + if (mb_row < cm->mb_rows - 1) {
|
| + mi[mis].mbmi.txfm_size = sz;
|
| + if (mb_col < cm->mb_cols - 1)
|
| + mi[mis + 1].mbmi.txfm_size = sz;
|
| + }
|
| + }
|
| + }
|
| }
|
| -#endif
|
| +
|
| +static void encode_superblock64(VP9_COMP *cpi, TOKENEXTRA **t,
|
| + int recon_yoffset, int recon_uvoffset,
|
| + int output_enabled, int mb_row, int mb_col) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + const uint8_t *src = x->src.y_buffer;
|
| + uint8_t *dst = xd->dst.y_buffer;
|
| + const uint8_t *usrc = x->src.u_buffer;
|
| + uint8_t *udst = xd->dst.u_buffer;
|
| + const uint8_t *vsrc = x->src.v_buffer;
|
| + uint8_t *vdst = xd->dst.v_buffer;
|
| + int src_y_stride = x->src.y_stride, dst_y_stride = xd->dst.y_stride;
|
| + int src_uv_stride = x->src.uv_stride, dst_uv_stride = xd->dst.uv_stride;
|
| + unsigned char ref_pred_flag;
|
| + int n;
|
| + TOKENEXTRA *tp[16];
|
| + int skip[16];
|
| + MODE_INFO *mi = x->e_mbd.mode_info_context;
|
| + unsigned int segment_id = mi->mbmi.segment_id;
|
| + ENTROPY_CONTEXT_PLANES ta[16], tl[16];
|
| + const int mis = cm->mode_info_stride;
|
| +
|
| + if (cm->frame_type == KEY_FRAME) {
|
| + if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
|
| + adjust_act_zbin(cpi, x);
|
| + vp9_update_zbin_extra(cpi, x);
|
| + }
|
| + } else {
|
| + vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, cm);
|
| +
|
| + if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
|
| + // Adjust the zbin based on this MB rate.
|
| + adjust_act_zbin(cpi, x);
|
| + }
|
| +
|
| + // Experimental code. Special case for gf and arf zeromv modes.
|
| + // Increase zbin size to suppress noise
|
| + cpi->zbin_mode_boost = 0;
|
| + if (cpi->zbin_mode_boost_enabled) {
|
| + if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
|
| + if (xd->mode_info_context->mbmi.mode == ZEROMV) {
|
| + if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
|
| + cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
|
| + else
|
| + cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
|
| + } else if (xd->mode_info_context->mbmi.mode == SPLITMV) {
|
| + cpi->zbin_mode_boost = 0;
|
| + } else {
|
| + cpi->zbin_mode_boost = MV_ZBIN_BOOST;
|
| + }
|
| + }
|
| + }
|
| +
|
| + vp9_update_zbin_extra(cpi, x);
|
| +
|
| + // Did the chosen reference frame match its predicted value.
|
| + ref_pred_flag = ((xd->mode_info_context->mbmi.ref_frame ==
|
| + vp9_get_pred_ref(cm, xd)));
|
| + vp9_set_pred_flag(xd, PRED_REF, ref_pred_flag);
|
| + }
|
| +
|
| + if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
|
| + vp9_build_intra_predictors_sb64y_s(&x->e_mbd);
|
| + vp9_build_intra_predictors_sb64uv_s(&x->e_mbd);
|
| + if (output_enabled)
|
| + sum_intra_stats(cpi, x);
|
| + } else {
|
| + int ref_fb_idx;
|
| +
|
| + assert(cm->frame_type != KEY_FRAME);
|
| +
|
| + if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
|
| + ref_fb_idx = cpi->common.lst_fb_idx;
|
| + else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
|
| + ref_fb_idx = cpi->common.gld_fb_idx;
|
| + else
|
| + ref_fb_idx = cpi->common.alt_fb_idx;
|
| +
|
| + xd->pre.y_buffer =
|
| + cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
|
| + xd->pre.u_buffer =
|
| + cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
|
| + xd->pre.v_buffer =
|
| + cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
|
| +
|
| + if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
|
| + int second_ref_fb_idx;
|
| +
|
| + if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
|
| + second_ref_fb_idx = cpi->common.lst_fb_idx;
|
| + else if (xd->mode_info_context->mbmi.second_ref_frame == GOLDEN_FRAME)
|
| + second_ref_fb_idx = cpi->common.gld_fb_idx;
|
| + else
|
| + second_ref_fb_idx = cpi->common.alt_fb_idx;
|
| +
|
| + xd->second_pre.y_buffer =
|
| + cpi->common.yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset;
|
| + xd->second_pre.u_buffer =
|
| + cpi->common.yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset;
|
| + xd->second_pre.v_buffer =
|
| + cpi->common.yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
|
| + }
|
| +
|
| + vp9_build_inter64x64_predictors_sb(xd, xd->dst.y_buffer,
|
| + xd->dst.u_buffer, xd->dst.v_buffer,
|
| + xd->dst.y_stride, xd->dst.uv_stride);
|
| + }
|
| +
|
| + if (xd->mode_info_context->mbmi.txfm_size == TX_32X32) {
|
| + int n;
|
| +
|
| + for (n = 0; n < 4; n++) {
|
| + int x_idx = n & 1, y_idx = n >> 1;
|
| +
|
| + xd->mode_info_context = mi + x_idx * 2 + mis * y_idx * 2;
|
| + xd->left_context = cm->left_context + (y_idx << 1);
|
| + xd->above_context = cm->above_context + mb_col + (x_idx << 1);
|
| + memcpy(&ta[n * 2], xd->above_context, sizeof(*ta) * 2);
|
| + memcpy(&tl[n * 2], xd->left_context, sizeof(*tl) * 2);
|
| + tp[n] = *t;
|
| + xd->mode_info_context = mi + x_idx * 2 + y_idx * mis * 2;
|
| + if (!x->skip) {
|
| + vp9_subtract_sby_s_c(x->sb_coeff_data.src_diff,
|
| + src + x_idx * 32 + y_idx * 32 * src_y_stride,
|
| + src_y_stride,
|
| + dst + x_idx * 32 + y_idx * 32 * dst_y_stride,
|
| + dst_y_stride);
|
| + vp9_subtract_sbuv_s_c(x->sb_coeff_data.src_diff,
|
| + usrc + x_idx * 16 + y_idx * 16 * src_uv_stride,
|
| + vsrc + x_idx * 16 + y_idx * 16 * src_uv_stride,
|
| + src_uv_stride,
|
| + udst + x_idx * 16 + y_idx * 16 * dst_uv_stride,
|
| + vdst + x_idx * 16 + y_idx * 16 * dst_uv_stride,
|
| + dst_uv_stride);
|
| + vp9_transform_sby_32x32(x);
|
| + vp9_transform_sbuv_16x16(x);
|
| + vp9_quantize_sby_32x32(x);
|
| + vp9_quantize_sbuv_16x16(x);
|
| + // TODO(rbultje): trellis optimize
|
| + vp9_inverse_transform_sbuv_16x16(&x->e_mbd.sb_coeff_data);
|
| + vp9_inverse_transform_sby_32x32(&x->e_mbd.sb_coeff_data);
|
| + vp9_recon_sby_s_c(&x->e_mbd,
|
| + dst + 32 * x_idx + 32 * y_idx * dst_y_stride);
|
| + vp9_recon_sbuv_s_c(&x->e_mbd,
|
| + udst + x_idx * 16 + y_idx * 16 * dst_uv_stride,
|
| + vdst + x_idx * 16 + y_idx * 16 * dst_uv_stride);
|
| +
|
| + vp9_tokenize_sb(cpi, &x->e_mbd, t, !output_enabled);
|
| + } else {
|
| + int mb_skip_context = cpi->common.mb_no_coeff_skip ?
|
| + (mi - 1)->mbmi.mb_skip_coeff +
|
| + (mi - mis)->mbmi.mb_skip_coeff : 0;
|
| + xd->mode_info_context->mbmi.mb_skip_coeff = 1;
|
| + if (cm->mb_no_coeff_skip) {
|
| + if (output_enabled)
|
| + cpi->skip_true_count[mb_skip_context]++;
|
| + vp9_fix_contexts_sb(xd);
|
| + } else {
|
| + vp9_stuff_sb(cpi, xd, t, !output_enabled);
|
| + if (output_enabled)
|
| + cpi->skip_false_count[mb_skip_context]++;
|
| + }
|
| + }
|
| +
|
| + // copy skip flag on all mb_mode_info contexts in this SB
|
| + // if this was a skip at this txfm size
|
| + if (mb_col + x_idx * 2 < cm->mb_cols - 1)
|
| + mi[mis * y_idx * 2 + x_idx * 2 + 1].mbmi.mb_skip_coeff =
|
| + mi[mis * y_idx * 2 + x_idx * 2].mbmi.mb_skip_coeff;
|
| + if (mb_row + y_idx * 2 < cm->mb_rows - 1) {
|
| + mi[mis * y_idx * 2 + x_idx * 2 + mis].mbmi.mb_skip_coeff =
|
| + mi[mis * y_idx * 2 + x_idx * 2].mbmi.mb_skip_coeff;
|
| + if (mb_col + x_idx * 2 < cm->mb_cols - 1)
|
| + mi[mis * y_idx * 2 + x_idx * 2 + mis + 1].mbmi.mb_skip_coeff =
|
| + mi[mis * y_idx * 2 + x_idx * 2].mbmi.mb_skip_coeff;
|
| + }
|
| + skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff;
|
| + }
|
| + } else {
|
| + for (n = 0; n < 16; n++) {
|
| + const int x_idx = n & 3, y_idx = n >> 2;
|
| +
|
| + xd->left_context = cm->left_context + y_idx;
|
| + xd->above_context = cm->above_context + mb_col + x_idx;
|
| + memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
|
| + memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
|
| + tp[n] = *t;
|
| + xd->mode_info_context = mi + x_idx + y_idx * mis;
|
| +
|
| + if (!x->skip) {
|
| + vp9_subtract_mby_s_c(x->src_diff,
|
| + src + x_idx * 16 + y_idx * 16 * src_y_stride,
|
| + src_y_stride,
|
| + dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
|
| + dst_y_stride);
|
| + vp9_subtract_mbuv_s_c(x->src_diff,
|
| + usrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| + vsrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
|
| + src_uv_stride,
|
| + udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + dst_uv_stride);
|
| + vp9_fidct_mb(x);
|
| + vp9_recon_mby_s_c(&x->e_mbd,
|
| + dst + x_idx * 16 + y_idx * 16 * dst_y_stride);
|
| + vp9_recon_mbuv_s_c(&x->e_mbd,
|
| + udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
|
| + vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride);
|
| +
|
| + vp9_tokenize_mb(cpi, &x->e_mbd, t, !output_enabled);
|
| + skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff;
|
| + } else {
|
| + int mb_skip_context = cpi->common.mb_no_coeff_skip ?
|
| + (x->e_mbd.mode_info_context - 1)->mbmi.mb_skip_coeff +
|
| + (x->e_mbd.mode_info_context - mis)->mbmi.mb_skip_coeff : 0;
|
| + xd->mode_info_context->mbmi.mb_skip_coeff = skip[n] = 1;
|
| + if (cpi->common.mb_no_coeff_skip) {
|
| + // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| + if (output_enabled)
|
| + cpi->skip_true_count[mb_skip_context]++;
|
| + vp9_reset_mb_tokens_context(xd);
|
| + } else {
|
| + vp9_stuff_mb(cpi, xd, t, !output_enabled);
|
| + // TODO(rbultje) this should be done per-sb instead of per-mb?
|
| + if (output_enabled)
|
| + cpi->skip_false_count[mb_skip_context]++;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + xd->mode_info_context = mi;
|
| + update_sb64_skip_coeff_state(cpi, ta, tl, tp, t, skip, output_enabled);
|
| +
|
| + if (output_enabled) {
|
| + if (cm->txfm_mode == TX_MODE_SELECT &&
|
| + !((cm->mb_no_coeff_skip &&
|
| + ((mi->mbmi.txfm_size == TX_32X32 &&
|
| + skip[0] && skip[1] && skip[2] && skip[3]) ||
|
| + (mi->mbmi.txfm_size != TX_32X32 &&
|
| + skip[0] && skip[1] && skip[2] && skip[3] &&
|
| + skip[4] && skip[5] && skip[6] && skip[7] &&
|
| + skip[8] && skip[9] && skip[10] && skip[11] &&
|
| + skip[12] && skip[13] && skip[14] && skip[15]))) ||
|
| + (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
|
| + vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
|
| + cpi->txfm_count_32x32p[mi->mbmi.txfm_size]++;
|
| + } else {
|
| + int x, y;
|
| + TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ?
|
| + TX_32X32 :
|
| + cm->txfm_mode;
|
| + for (y = 0; y < 4; y++) {
|
| + for (x = 0; x < 4; x++) {
|
| + if (mb_col + x < cm->mb_cols && mb_row + y < cm->mb_rows) {
|
| + mi[mis * y + x].mbmi.txfm_size = sz;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|