Merge "Inter-frame non-RD mode decision"

This commit is contained in:
Jingning Han 2014-01-16 14:04:51 -08:00 коммит произвёл Gerrit Code Review
Родитель b0526522c1 2f52decd22
Коммит 013eba8ee8
7 изменённых файлов: 439 добавлений и 15 удалений

Просмотреть файл

@ -116,6 +116,7 @@ struct macroblock {
unsigned int source_variance; unsigned int source_variance;
unsigned int pred_sse[MAX_REF_FRAMES]; unsigned int pred_sse[MAX_REF_FRAMES];
int pred_mv_sad[MAX_REF_FRAMES]; int pred_mv_sad[MAX_REF_FRAMES];
int mode_sad[MAX_REF_FRAMES][INTER_MODES + 1];
int nmvjointcost[MV_JOINTS]; int nmvjointcost[MV_JOINTS];
int nmvcosts[2][MV_VALS]; int nmvcosts[2][MV_VALS];

Просмотреть файл

@ -34,6 +34,7 @@
#include "vp9/encoder/vp9_encodemv.h" #include "vp9/encoder/vp9_encodemv.h"
#include "vp9/encoder/vp9_extend.h" #include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_onyx_int.h" #include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/encoder/vp9_pickmode.h"
#include "vp9/encoder/vp9_rdopt.h" #include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h" #include "vp9/encoder/vp9_segmentation.h"
#include "vp9/encoder/vp9_tokenize.h" #include "vp9/encoder/vp9_tokenize.h"
@ -1038,6 +1039,132 @@ static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
return 0; return 0;
} }
// TODO(jingning) This currently serves as a test framework for non-RD mode
// decision. To be continued on optimizing the partition type decisions.
static void pick_partition_type(VP9_COMP *cpi,
const TileInfo *const tile,
MODE_INFO **mi_8x8, TOKENEXTRA **tp,
int mi_row, int mi_col,
BLOCK_SIZE bsize, int *rate, int64_t *dist,
int do_recon) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
const int mi_stride = cm->mode_info_stride;
const int num_8x8_subsize = (num_8x8_blocks_wide_lookup[bsize] >> 1);
int i;
PARTITION_TYPE partition = PARTITION_NONE;
BLOCK_SIZE subsize;
BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
int sub_rate[4] = {0};
int64_t sub_dist[4] = {0};
int mi_offset;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
partition = partition_lookup[b_width_log2(bsize)][bs_type];
subsize = get_subsize(bsize, partition);
if (bsize < BLOCK_8X8) {
// When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
// there is nothing to be done.
if (x->ab_index != 0) {
*rate = 0;
*dist = 0;
return;
}
} else {
*(get_sb_partitioning(x, bsize)) = subsize;
}
switch (partition) {
case PARTITION_NONE:
pick_sb_modes(cpi, tile, mi_row, mi_col, rate, dist,
bsize, get_block_context(x, bsize), INT64_MAX);
break;
case PARTITION_HORZ:
*get_sb_index(x, subsize) = 0;
pick_sb_modes(cpi, tile, mi_row, mi_col, &sub_rate[0], &sub_dist[0],
subsize, get_block_context(x, subsize), INT64_MAX);
if (bsize >= BLOCK_8X8 && mi_row + num_8x8_subsize < cm->mi_rows) {
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*get_sb_index(x, subsize) = 1;
pick_sb_modes(cpi, tile, mi_row + num_8x8_subsize, mi_col,
&sub_rate[1], &sub_dist[1], subsize,
get_block_context(x, subsize), INT64_MAX);
}
*rate = sub_rate[0] + sub_rate[1];
*dist = sub_dist[0] + sub_dist[1];
break;
case PARTITION_VERT:
*get_sb_index(x, subsize) = 0;
pick_sb_modes(cpi, tile, mi_row, mi_col, &sub_rate[0], &sub_dist[0],
subsize, get_block_context(x, subsize), INT64_MAX);
if (bsize >= BLOCK_8X8 && mi_col + num_8x8_subsize < cm->mi_cols) {
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*get_sb_index(x, subsize) = 1;
pick_sb_modes(cpi, tile, mi_row, mi_col + num_8x8_subsize,
&sub_rate[1], &sub_dist[1], subsize,
get_block_context(x, subsize), INT64_MAX);
}
*rate = sub_rate[0] + sub_rate[1];
*dist = sub_dist[1] + sub_dist[1];
break;
case PARTITION_SPLIT:
*get_sb_index(x, subsize) = 0;
pick_partition_type(cpi, tile, mi_8x8, tp, mi_row, mi_col, subsize,
&sub_rate[0], &sub_dist[0], 0);
if ((mi_col + num_8x8_subsize) < cm->mi_cols) {
*get_sb_index(x, subsize) = 1;
pick_partition_type(cpi, tile, mi_8x8 + num_8x8_subsize, tp,
mi_row, mi_col + num_8x8_subsize, subsize,
&sub_rate[1], &sub_dist[1], 0);
}
if ((mi_row + num_8x8_subsize) < cm->mi_rows) {
*get_sb_index(x, subsize) = 2;
pick_partition_type(cpi, tile, mi_8x8 + num_8x8_subsize * mi_stride, tp,
mi_row + num_8x8_subsize, mi_col, subsize,
&sub_rate[2], &sub_dist[2], 0);
}
if ((mi_col + num_8x8_subsize) < cm->mi_cols &&
(mi_row + num_8x8_subsize) < cm->mi_rows) {
*get_sb_index(x, subsize) = 3;
mi_offset = num_8x8_subsize * mi_stride + num_8x8_subsize;
pick_partition_type(cpi, tile, mi_8x8 + mi_offset, tp,
mi_row + num_8x8_subsize, mi_col + num_8x8_subsize,
subsize, &sub_rate[3], &sub_dist[3], 0);
}
for (i = 0; i < 4; ++i) {
*rate += sub_rate[i];
*dist += sub_dist[i];
}
break;
default:
assert(0);
}
if (do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
// Check the projected output rate for this SB against it's target
// and and if necessary apply a Q delta using segmentation to get
// closer to the target.
if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
select_in_frame_q_segment(cpi, mi_row, mi_col,
output_enabled, *rate);
}
encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
}
}
static void rd_use_partition(VP9_COMP *cpi, static void rd_use_partition(VP9_COMP *cpi,
const TileInfo *const tile, const TileInfo *const tile,
MODE_INFO **mi_8x8, MODE_INFO **mi_8x8,
@ -1875,6 +2002,34 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, const TileInfo *const tile,
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64);
} }
static void encode_sb_row_rt(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, TOKENEXTRA **tp) {
VP9_COMMON *const cm = &cpi->common;
int mi_col;
cpi->sf.always_this_block_size = BLOCK_8X8;
// Initialize the left context for the new SB row
vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context));
vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context));
// Code each SB in the row
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE) {
int dummy_rate;
int64_t dummy_dist;
const int idx_str = cm->mode_info_stride * mi_row + mi_col;
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
vp9_zero(cpi->mb.pred_mv);
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col);
pick_partition_type(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
&dummy_rate, &dummy_dist, 1);
}
}
static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, TOKENEXTRA **tp) { int mi_row, TOKENEXTRA **tp) {
VP9_COMMON *const cm = &cpi->common; VP9_COMMON *const cm = &cpi->common;
@ -2101,7 +2256,11 @@ static void encode_frame_internal(VP9_COMP *cpi) {
vp9_tile_init(&tile, cm, tile_row, tile_col); vp9_tile_init(&tile, cm, tile_row, tile_col);
for (mi_row = tile.mi_row_start; for (mi_row = tile.mi_row_start;
mi_row < tile.mi_row_end; mi_row += 8) mi_row < tile.mi_row_end; mi_row += 8)
#if 1
encode_sb_row(cpi, &tile, mi_row, &tp); encode_sb_row(cpi, &tile, mi_row, &tp);
#else
encode_sb_row_rt(cpi, &tile, mi_row, &tp);
#endif
cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old);
assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols));

230
vp9/encoder/vp9_pickmode.c Normal file
Просмотреть файл

@ -0,0 +1,230 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <assert.h>
#include "vp9/common/vp9_pragmas.h"
#include "vp9/encoder/vp9_tokenize.h"
#include "vp9/encoder/vp9_treewriter.h"
#include "vp9/encoder/vp9_onyx_int.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_variance.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vpx_mem/vpx_mem.h"
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_common.h"
static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
BLOCK_SIZE bsize, int mi_row, int mi_col,
int_mv *tmp_mv, int *rate_mv) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
int bestsme = INT_MAX;
int further_steps, step_param;
int sadpb = x->sadperbit16;
MV mvp_full;
int ref = mbmi->ref_frame[0];
int_mv ref_mv = mbmi->ref_mvs[ref][0];
int i;
int tmp_col_min = x->mv_col_min;
int tmp_col_max = x->mv_col_max;
int tmp_row_min = x->mv_row_min;
int tmp_row_max = x->mv_row_max;
int buf_offset;
int stride = xd->plane[0].pre[0].stride;
YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref);
if (scaled_ref_frame) {
int i;
// Swap out the reference frame for a version that's been scaled to
// match the resolution of the current frame, allowing the existing
// motion search code to be used without additional modifications.
for (i = 0; i < MAX_MB_PLANE; i++)
backup_yv12[i] = xd->plane[i].pre[0];
setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
vp9_set_mv_search_range(x, &ref_mv.as_mv);
// TODO(jingning) exploiting adaptive motion search control in non-RD
// mode decision too.
step_param = 6;
further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
for (i = LAST_FRAME; i <= ALTREF_FRAME && cpi->common.show_frame; ++i) {
if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
tmp_mv->as_int = INVALID_MV;
if (scaled_ref_frame) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[0] = backup_yv12[i];
}
return INT_MAX;
}
}
mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;
mvp_full.col >>= 3;
mvp_full.row >>= 3;
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 1,
&cpi->fn_ptr[bsize],
&ref_mv.as_mv, tmp_mv);
x->mv_col_min = tmp_col_min;
x->mv_col_max = tmp_col_max;
x->mv_row_min = tmp_row_min;
x->mv_row_max = tmp_row_max;
if (scaled_ref_frame) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[0] = backup_yv12[i];
}
// TODO(jingning) This step can be merged into full pixel search step in the
// re-designed log-diamond search
buf_offset = tmp_mv->as_mv.row * stride + tmp_mv->as_mv.col;
// Find sad for current vector.
bestsme = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, x->plane[0].src.stride,
xd->plane[0].pre[0].buf + buf_offset,
stride, 0x7fffffff);
// scale to 1/8 pixel resolution
tmp_mv->as_mv.row = tmp_mv->as_mv.row << 3;
tmp_mv->as_mv.col = tmp_mv->as_mv.col << 3;
// calculate the bit cost on motion vector
*rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
return bestsme;
}
// TODO(jingning) placeholder for inter-frame non-RD mode decision.
// this needs various further optimizations. to be continued..
int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
int mi_row, int mi_col,
int *returnrate,
int64_t *returndistortion,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
MB_PREDICTION_MODE this_mode;
MV_REFERENCE_FRAME ref_frame;
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
int64_t best_rd = INT64_MAX;
int64_t this_rd;
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
x->skip = 0;
if (cpi->active_map_enabled && x->active_ptr[0] == 0)
x->skip = 1;
// initialize mode decisions
*returnrate = INT_MAX;
vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO));
mbmi->sb_type = bsize;
mbmi->ref_frame[0] = NONE;
mbmi->ref_frame[1] = NONE;
mbmi->tx_size = MIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
vp9_setup_buffer_inter(cpi, x, tile, get_ref_frame_idx(cpi, ref_frame),
ref_frame, block_size, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
}
frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
frame_mv[ZEROMV][ref_frame].as_int = 0;
}
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
int rate_mv = 0;
if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
continue;
// Select prediction reference frames.
xd->plane[0].pre[0] = yv12_mb[ref_frame][0];
x->mode_sad[ref_frame][INTER_OFFSET(NEWMV)] =
full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
&frame_mv[NEWMV][ref_frame], &rate_mv);
if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV)
continue;
clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
int rate = x->inter_mode_cost[mbmi->mode_context[ref_frame]]
[INTER_OFFSET(this_mode)];
int64_t dist = x->mode_sad[ref_frame][INTER_OFFSET(this_mode)] *
x->mode_sad[ref_frame][INTER_OFFSET(this_mode)];
this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
if (this_rd < best_rd) {
best_rd = this_rd;
mbmi->mode = this_mode;
mbmi->ref_frame[0] = ref_frame;
mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
}
}
}
// TODO(jingning) sub-pixel motion search, if NEWMV is chosen
// TODO(jingning) intra prediction search, if the best SAD is above a certain
// threshold.
// store mode decisions
ctx->mic = *xd->mi_8x8[0];
return INT64_MAX;
}

Просмотреть файл

@ -0,0 +1,19 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "vp9/encoder/vp9_onyx_int.h"
int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const struct TileInfo *const tile,
int mi_row, int mi_col,
int *returnrate,
int64_t *returndistortion,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx);

Просмотреть файл

@ -37,8 +37,6 @@
#include "vp9/common/vp9_mvref_common.h" #include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_common.h" #include "vp9/common/vp9_common.h"
#define INVALID_MV 0x80008000
/* Factor to weigh the rate for switchable interp filters */ /* Factor to weigh the rate for switchable interp filters */
#define SWITCHABLE_INTERP_RATE_FACTOR 1 #define SWITCHABLE_INTERP_RATE_FACTOR 1
@ -113,14 +111,6 @@ const REF_DEFINITION vp9_ref_order[MAX_REFS] = {
static int rd_thresh_block_size_factor[BLOCK_SIZES] = static int rd_thresh_block_size_factor[BLOCK_SIZES] =
{2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32}; {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32};
#define RD_THRESH_MAX_FACT 64
#define RD_THRESH_INC 1
#define RD_THRESH_POW 1.25
#define RD_MULT_EPB_RATIO 64
#define MV_COST_WEIGHT 108
#define MV_COST_WEIGHT_SUB 120
static int raster_block_offset(BLOCK_SIZE plane_bsize, static int raster_block_offset(BLOCK_SIZE plane_bsize,
int raster_block, int stride) { int raster_block, int stride) {
const int bw = b_width_log2(plane_bsize); const int bw = b_width_log2(plane_bsize);
@ -2133,8 +2123,10 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
max_mv = MAX(max_mv, max_mv = MAX(max_mv,
MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3); MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
// only need to check zero mv once // only need to check zero mv once
if (!this_mv.as_int && zero_seen) if (!this_mv.as_int && zero_seen) {
x->mode_sad[ref_frame][i] = x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)];
continue; continue;
}
zero_seen = zero_seen || !this_mv.as_int; zero_seen = zero_seen || !this_mv.as_int;
row_offset = this_mv.as_mv.row >> 3; row_offset = this_mv.as_mv.row >> 3;
@ -2145,6 +2137,9 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
ref_y_ptr, ref_y_stride, ref_y_ptr, ref_y_stride,
0x7fffffff); 0x7fffffff);
x->mode_sad[ref_frame][i] = this_sad;
if (this_mv.as_int == 0)
x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = this_sad;
// Note if it is the best so far. // Note if it is the best so far.
if (this_sad < best_sad) { if (this_sad < best_sad) {
@ -2153,6 +2148,12 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
} }
} }
if (!zero_seen)
x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] =
cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
ref_y_buffer, ref_y_stride,
0x7fffffff);
// Note the index of the mv that worked best in the reference list. // Note the index of the mv that worked best in the reference list.
x->mv_best_ref_index[ref_frame] = best_index; x->mv_best_ref_index[ref_frame] = best_index;
x->max_mv_context[ref_frame] = max_mv; x->max_mv_context[ref_frame] = max_mv;
@ -2312,7 +2313,7 @@ void vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
frame_type, block_size); frame_type, block_size);
} }
static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) { YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) {
YV12_BUFFER_CONFIG *scaled_ref_frame = NULL; YV12_BUFFER_CONFIG *scaled_ref_frame = NULL;
int fb = get_ref_frame_idx(cpi, ref_frame); int fb = get_ref_frame_idx(cpi, ref_frame);
int fb_scale = get_scale_ref_frame_idx(cpi, ref_frame); int fb_scale = get_scale_ref_frame_idx(cpi, ref_frame);
@ -2350,7 +2351,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int tmp_row_min = x->mv_row_min; int tmp_row_min = x->mv_row_min;
int tmp_row_max = x->mv_row_max; int tmp_row_max = x->mv_row_max;
YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref); YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref);
int_mv pred_mv[3]; int_mv pred_mv[3];
pred_mv[0] = mbmi->ref_mvs[ref][0]; pred_mv[0] = mbmi->ref_mvs[ref][0];
@ -2498,8 +2499,8 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0]; struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
int last_besterr[2] = {INT_MAX, INT_MAX}; int last_besterr[2] = {INT_MAX, INT_MAX};
YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = { YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
get_scaled_ref_frame(cpi, mbmi->ref_frame[0]), vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
get_scaled_ref_frame(cpi, mbmi->ref_frame[1]) vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
}; };
for (ref = 0; ref < 2; ++ref) { for (ref = 0; ref < 2; ++ref) {

Просмотреть файл

@ -19,6 +19,16 @@
(((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM)) (((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM))
#define QIDX_SKIP_THRESH 115 #define QIDX_SKIP_THRESH 115
#define RD_THRESH_MAX_FACT 64
#define RD_THRESH_INC 1
#define RD_THRESH_POW 1.25
#define RD_MULT_EPB_RATIO 64
#define MV_COST_WEIGHT 108
#define MV_COST_WEIGHT_SUB 120
#define INVALID_MV 0x80008000
struct TileInfo; struct TileInfo;
int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex); int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex);
@ -36,6 +46,8 @@ void vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
int_mv frame_near_mv[MAX_REF_FRAMES], int_mv frame_near_mv[MAX_REF_FRAMES],
struct buf_2d yv12_mb[4][MAX_MB_PLANE]); struct buf_2d yv12_mb[4][MAX_MB_PLANE]);
YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame);
void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int *r, int64_t *d, BLOCK_SIZE bsize, int *r, int64_t *d, BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx, int64_t best_rd); PICK_MODE_CONTEXT *ctx, int64_t best_rd);

Просмотреть файл

@ -43,6 +43,7 @@ VP9_CX_SRCS-yes += encoder/vp9_psnr.h
VP9_CX_SRCS-yes += encoder/vp9_quantize.h VP9_CX_SRCS-yes += encoder/vp9_quantize.h
VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h
VP9_CX_SRCS-yes += encoder/vp9_rdopt.h VP9_CX_SRCS-yes += encoder/vp9_rdopt.h
VP9_CX_SRCS-yes += encoder/vp9_pickmode.h
VP9_CX_SRCS-yes += encoder/vp9_sadmxn.h VP9_CX_SRCS-yes += encoder/vp9_sadmxn.h
VP9_CX_SRCS-yes += encoder/vp9_tokenize.h VP9_CX_SRCS-yes += encoder/vp9_tokenize.h
VP9_CX_SRCS-yes += encoder/vp9_treewriter.h VP9_CX_SRCS-yes += encoder/vp9_treewriter.h
@ -55,6 +56,7 @@ VP9_CX_SRCS-yes += encoder/vp9_psnr.c
VP9_CX_SRCS-yes += encoder/vp9_quantize.c VP9_CX_SRCS-yes += encoder/vp9_quantize.c
VP9_CX_SRCS-yes += encoder/vp9_ratectrl.c VP9_CX_SRCS-yes += encoder/vp9_ratectrl.c
VP9_CX_SRCS-yes += encoder/vp9_rdopt.c VP9_CX_SRCS-yes += encoder/vp9_rdopt.c
VP9_CX_SRCS-yes += encoder/vp9_pickmode.c
VP9_CX_SRCS-yes += encoder/vp9_sad_c.c VP9_CX_SRCS-yes += encoder/vp9_sad_c.c
VP9_CX_SRCS-yes += encoder/vp9_segmentation.c VP9_CX_SRCS-yes += encoder/vp9_segmentation.c
VP9_CX_SRCS-yes += encoder/vp9_segmentation.h VP9_CX_SRCS-yes += encoder/vp9_segmentation.h