Merge branch 'master' into nextgenv2

This commit is contained in:
Yaowu Xu 2016-01-14 13:57:27 -08:00
Родитель c38fc52df4 dcc0c894c4
Коммит 44da65fb44
23 изменённых файлов: 400 добавлений и 121 удалений

14
configure поставляемый
Просмотреть файл

@ -263,9 +263,7 @@ ARCH_EXT_LIST="
HAVE_LIST="
${ARCH_EXT_LIST}
vpx_ports
stdint_h
pthread_h
sys_mman_h
unistd_h
"
EXPERIMENT_LIST="
@ -559,16 +557,12 @@ process_detect() {
# Specialize windows and POSIX environments.
case $toolchain in
*-win*-*)
case $header-$toolchain in
stdint*-gcc) true;;
*) false;;
esac && enable_feature $var
;;
# Don't check for any headers in Windows builds.
false
;;
*)
case $header in
stdint.h) true;;
pthread.h) true;;
sys/mman.h) true;;
unistd.h) true;;
*) false;;
esac && enable_feature $var
@ -584,9 +578,7 @@ process_detect() {
int main(void) {return 0;}
EOF
# check system headers
check_header stdint.h
check_header pthread.h
check_header sys/mman.h
check_header unistd.h # for sysconf(3) and friends.
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports

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

@ -29,13 +29,6 @@
#include <math.h>
#include <assert.h>
#include <sys/time.h>
#if USE_POSIX_MMAP
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include "vpx_ports/vpx_timer.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"

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

@ -51,7 +51,7 @@ void vp10_setup_in_frame_q_adj(VP10_COMP *cpi) {
// Make SURE use of floating point in this function is safe.
vpx_clear_system_state();
if (cm->frame_type == KEY_FRAME ||
if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
cpi->refresh_alt_ref_frame ||
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
int segment;

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

@ -47,7 +47,7 @@ void vp10_vaq_frame_setup(VP10_COMP *cpi) {
struct segmentation *seg = &cm->seg;
int i;
if (cm->frame_type == KEY_FRAME ||
if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
cpi->refresh_alt_ref_frame ||
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
vp10_enable_segmentation(seg);

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

@ -250,7 +250,7 @@ void vp10_choose_segmap_coding_method(VP10_COMMON *cm, MACROBLOCKD *xd) {
no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree);
// Key frames cannot use temporal prediction
if (!frame_is_intra_only(cm)) {
if (!frame_is_intra_only(cm) && !cm->error_resilient_mode) {
// Work out probability tree for coding those segments not
// predicted using the temporal method and the cost.
calc_segtree_probs(t_unpred_seg_counts, t_pred_tree, segp->tree_probs);
@ -273,6 +273,7 @@ void vp10_choose_segmap_coding_method(VP10_COMMON *cm, MACROBLOCKD *xd) {
// Now choose which coding method to use.
if (t_pred_cost < no_pred_cost) {
assert(!cm->error_resilient_mode);
seg->temporal_update = 1;
} else {
seg->temporal_update = 0;

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

@ -11,9 +11,6 @@
#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_entropymv.h"
// Integer pel reference mv threshold for use of high-precision 1/8 mv
#define COMPANDED_MVREF_THRESH 8
const vpx_tree_index vp9_mv_joint_tree[TREE_SIZE(MV_JOINTS)] = {
-MV_JOINT_ZERO, 2,
-MV_JOINT_HNZVZ, 4,
@ -127,11 +124,6 @@ MV_CLASS_TYPE vp9_get_mv_class(int z, int *offset) {
return c;
}
int vp9_use_mv_hp(const MV *ref) {
return (abs(ref->row) >> 3) < COMPANDED_MVREF_THRESH &&
(abs(ref->col) >> 3) < COMPANDED_MVREF_THRESH;
}
static void inc_mv_component(int v, nmv_component_counts *comp_counts,
int incr, int usehp) {
int s, z, c, o, d, e, f;

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

@ -27,7 +27,14 @@ struct VP9Common;
void vp9_init_mv_probs(struct VP9Common *cm);
void vp9_adapt_mv_probs(struct VP9Common *cm, int usehp);
int vp9_use_mv_hp(const MV *ref);
// Integer pel reference mv threshold for use of high-precision 1/8 mv
#define COMPANDED_MVREF_THRESH 8
static INLINE int use_mv_hp(const MV *ref) {
return (abs(ref->row) >> 3) < COMPANDED_MVREF_THRESH &&
(abs(ref->col) >> 3) < COMPANDED_MVREF_THRESH;
}
#define MV_UPDATE_PROB 252

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

@ -11,20 +11,19 @@
#include "vp9/common/vp9_mvref_common.h"
// This function searches the neighbourhood of a given MB/SB
// This function searches the neighborhood of a given MB/SB
// to try and find candidate reference vectors.
static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
int_mv *mv_ref_list,
int block, int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data,
uint8_t *mode_context) {
const int *ref_sign_bias = cm->ref_frame_sign_bias;
int i, refmv_count = 0;
const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type];
int different_ref_found = 0;
int context_counter = 0;
const MV_REF *const prev_frame_mvs = cm->use_prev_frame_mvs ?
const MV_REF *const prev_frame_mvs = cm->use_prev_frame_mvs ?
cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col : NULL;
const TileInfo *const tile = &xd->tile;
@ -59,8 +58,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
for (; i < MVREF_NEIGHBOURS; ++i) {
const POSITION *const mv_ref = &mv_ref_search[i];
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row *
xd->mi_stride]->mbmi;
const MB_MODE_INFO *const candidate =
&xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
different_ref_found = 1;
if (candidate->ref_frame[0] == ref_frame)
@ -70,23 +69,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
}
}
// TODO(hkuang): Remove this sync after fixing pthread_cond_broadcast
// on windows platform. The sync here is unncessary if use_perv_frame_mvs
// is 0. But after removing it, there will be hang in the unit test on windows
// due to several threads waiting for a thread's signal.
#if defined(_WIN32) && !HAVE_PTHREAD_H
if (cm->frame_parallel_decode && sync != NULL) {
sync(data, mi_row);
}
#endif
// Check the last frame's mode and mv info.
if (cm->use_prev_frame_mvs) {
// Synchronize here for frame parallel decode if sync function is provided.
if (cm->frame_parallel_decode && sync != NULL) {
sync(data, mi_row);
}
if (prev_frame_mvs->ref_frame[0] == ref_frame) {
ADD_MV_REF_LIST(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done);
} else if (prev_frame_mvs->ref_frame[1] == ref_frame) {
@ -101,8 +85,8 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
const POSITION *mv_ref = &mv_ref_search[i];
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row
* xd->mi_stride]->mbmi;
const MB_MODE_INFO *const candidate =
&xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
// If the candidate is INTRA we don't want to consider its mv.
IF_DIFF_REF_FRAME_ADD_MV(candidate, ref_frame, ref_sign_bias,
@ -150,20 +134,9 @@ void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
int_mv *mv_ref_list,
int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data,
uint8_t *mode_context) {
find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1,
mi_row, mi_col, sync, data, mode_context);
}
static void lower_mv_precision(MV *mv, int allow_hp) {
const int use_hp = allow_hp && vp9_use_mv_hp(mv);
if (!use_hp) {
if (mv->row & 1)
mv->row += (mv->row > 0 ? -1 : 1);
if (mv->col & 1)
mv->col += (mv->col > 0 ? -1 : 1);
}
mi_row, mi_col, mode_context);
}
void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp,
@ -191,7 +164,7 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
assert(MAX_MV_REF_CANDIDATES == 2);
find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block,
mi_row, mi_col, NULL, NULL, mode_context);
mi_row, mi_col, mode_context);
near_mv->as_int = 0;
switch (block) {

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

@ -157,7 +157,7 @@ static INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref,
// This macro is used to add a motion vector mv_ref list if it isn't
// already in the list. If it's the second motion vector it will also
// skip all additional processing and jump to done!
// skip all additional processing and jump to Done!
#define ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, Done) \
do { \
if (refmv_count) { \
@ -207,11 +207,20 @@ static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
}
static INLINE void lower_mv_precision(MV *mv, int allow_hp) {
const int use_hp = allow_hp && use_mv_hp(mv);
if (!use_hp) {
if (mv->row & 1)
mv->row += (mv->row > 0 ? -1 : 1);
if (mv->col & 1)
mv->col += (mv->col > 0 ? -1 : 1);
}
}
typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
int_mv *mv_ref_list, int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data,
uint8_t *mode_context);
// check a list of motion vectors by sad score using a number rows of pixels

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

@ -719,6 +719,18 @@ static void dec_build_inter_predictors_sb(VP9Decoder *const pbi,
const InterpKernel *kernel = vp9_filter_kernels[mi->mbmi.interp_filter];
const BLOCK_SIZE sb_type = mi->mbmi.sb_type;
const int is_compound = has_second_ref(&mi->mbmi);
int ref;
for (ref = 0; ref < 1 + is_compound; ++ref) {
const MV_REFERENCE_FRAME frame = mi->mbmi.ref_frame[ref];
RefBuffer *ref_buf = &pbi->common.frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
if (!vp9_is_valid_scale(&ref_buf->sf))
vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
"Reference frame has invalid dimensions");
vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, &ref_buf->sf);
}
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
struct macroblockd_plane *const pd = &xd->plane[plane];

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

@ -289,7 +289,7 @@ static INLINE void read_mv(vpx_reader *r, MV *mv, const MV *ref,
nmv_context_counts *counts, int allow_hp) {
const MV_JOINT_TYPE joint_type =
(MV_JOINT_TYPE)vpx_read_tree(r, vp9_mv_joint_tree, ctx->joints);
const int use_hp = allow_hp && vp9_use_mv_hp(ref);
const int use_hp = allow_hp && use_mv_hp(ref);
MV diff = {0, 0};
if (mv_joint_vertical(joint_type))
@ -476,12 +476,203 @@ static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
}
}
static void dec_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp, int_mv *mvlist,
int_mv *nearest_mv, int_mv *near_mv,
int refmv_count) {
int i;
// Make sure all the candidates are properly clamped etc
for (i = 0; i < refmv_count; ++i) {
lower_mv_precision(&mvlist[i].as_mv, allow_hp);
clamp_mv2(&mvlist[i].as_mv, xd);
}
*nearest_mv = mvlist[0];
*near_mv = mvlist[1];
}
static void fpm_sync(void *const data, int mi_row) {
VP9Decoder *const pbi = (VP9Decoder *)data;
vp9_frameworker_wait(pbi->frame_worker_owner, pbi->common.prev_frame,
mi_row << MI_BLOCK_SIZE_LOG2);
}
// This macro is used to add a motion vector mv_ref list if it isn't
// already in the list. If it's the second motion vector or early_break
// it will also skip all additional processing and jump to Done!
#define ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done) \
do { \
if (refmv_count) { \
if ((mv).as_int != (mv_ref_list)[0].as_int) { \
(mv_ref_list)[(refmv_count)] = (mv); \
refmv_count++; \
goto Done; \
} \
} else { \
(mv_ref_list)[(refmv_count)++] = (mv); \
if (early_break) \
goto Done; \
} \
} while (0)
// If either reference frame is different, not INTRA, and they
// are different from each other scale and add the mv to our list.
#define IF_DIFF_REF_FRAME_ADD_MV_EB(mbmi, ref_frame, ref_sign_bias, \
refmv_count, mv_ref_list, Done) \
do { \
if (is_inter_block(mbmi)) { \
if ((mbmi)->ref_frame[0] != ref_frame) \
ADD_MV_REF_LIST_EB(scale_mv((mbmi), 0, ref_frame, ref_sign_bias), \
refmv_count, mv_ref_list, Done); \
if (has_second_ref(mbmi) && \
(mbmi)->ref_frame[1] != ref_frame && \
(mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \
ADD_MV_REF_LIST_EB(scale_mv((mbmi), 1, ref_frame, ref_sign_bias), \
refmv_count, mv_ref_list, Done); \
} \
} while (0)
// This function searches the neighborhood of a given MB/SB
// to try and find candidate reference vectors.
static int dec_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
const POSITION *const mv_ref_search,
int_mv *mv_ref_list,
int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data) {
const int *ref_sign_bias = cm->ref_frame_sign_bias;
int i, refmv_count = 0;
int different_ref_found = 0;
const MV_REF *const prev_frame_mvs = cm->use_prev_frame_mvs ?
cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col : NULL;
const TileInfo *const tile = &xd->tile;
// If mode is nearestmv or newmv (uses nearestmv as a reference) then stop
// searching after the first mv is found.
const int early_break = (mi->mbmi.mode == NEARESTMV) ||
(mi->mbmi.mode == NEWMV);
// Blank the reference vector list
memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
// Check the rest of the neighbors in much the same way
// as before except we don't need to keep track of sub blocks or
// mode counts.
for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
const POSITION *const mv_ref = &mv_ref_search[i];
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
const MB_MODE_INFO *const candidate =
&xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
different_ref_found = 1;
if (candidate->ref_frame[0] == ref_frame)
ADD_MV_REF_LIST_EB(candidate->mv[0], refmv_count, mv_ref_list, Done);
else if (candidate->ref_frame[1] == ref_frame)
ADD_MV_REF_LIST_EB(candidate->mv[1], refmv_count, mv_ref_list, Done);
}
}
// TODO(hkuang): Remove this sync after fixing pthread_cond_broadcast
// on windows platform. The sync here is unnecessary if use_prev_frame_mvs
// is 0. But after removing it, there will be hang in the unit test on windows
// due to several threads waiting for a thread's signal.
#if defined(_WIN32) && !HAVE_PTHREAD_H
if (cm->frame_parallel_decode && sync != NULL) {
sync(data, mi_row);
}
#endif
// Check the last frame's mode and mv info.
if (prev_frame_mvs) {
// Synchronize here for frame parallel decode if sync function is provided.
if (cm->frame_parallel_decode && sync != NULL) {
sync(data, mi_row);
}
if (prev_frame_mvs->ref_frame[0] == ref_frame) {
ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, Done);
} else if (prev_frame_mvs->ref_frame[1] == ref_frame) {
ADD_MV_REF_LIST_EB(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, Done);
}
}
// Since we couldn't find 2 mvs from the same reference frame
// go back through the neighbors and find motion vectors from
// different reference frames.
if (different_ref_found) {
for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
const POSITION *mv_ref = &mv_ref_search[i];
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
const MB_MODE_INFO *const candidate =
&xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
// If the candidate is INTRA we don't want to consider its mv.
IF_DIFF_REF_FRAME_ADD_MV_EB(candidate, ref_frame, ref_sign_bias,
refmv_count, mv_ref_list, Done);
}
}
}
// Since we still don't have a candidate we'll try the last frame.
if (prev_frame_mvs) {
if (prev_frame_mvs->ref_frame[0] != ref_frame &&
prev_frame_mvs->ref_frame[0] > INTRA_FRAME) {
int_mv mv = prev_frame_mvs->mv[0];
if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] !=
ref_sign_bias[ref_frame]) {
mv.as_mv.row *= -1;
mv.as_mv.col *= -1;
}
ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done);
}
if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME &&
prev_frame_mvs->ref_frame[1] != ref_frame &&
prev_frame_mvs->mv[1].as_int != prev_frame_mvs->mv[0].as_int) {
int_mv mv = prev_frame_mvs->mv[1];
if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] !=
ref_sign_bias[ref_frame]) {
mv.as_mv.row *= -1;
mv.as_mv.col *= -1;
}
ADD_MV_REF_LIST_EB(mv, refmv_count, mv_ref_list, Done);
}
}
if (mi->mbmi.mode == NEARMV)
refmv_count = MAX_MV_REF_CANDIDATES;
else
// we only care about the nearestmv for the remaining modes
refmv_count = 1;
Done:
// Clamp vectors
for (i = 0; i < refmv_count; ++i)
clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
return refmv_count;
}
static uint8_t get_mode_context(const VP9_COMMON *cm, const MACROBLOCKD *xd,
const POSITION *const mv_ref_search,
int mi_row, int mi_col) {
int i;
int context_counter = 0;
const TileInfo *const tile = &xd->tile;
// Get mode count from nearest 2 blocks
for (i = 0; i < 2; ++i) {
const POSITION *const mv_ref = &mv_ref_search[i];
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row *
xd->mi_stride];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
// Keep counts for entropy encoding.
context_counter += mode_2_counter[candidate->mode];
}
}
return counter_to_context[context_counter];
}
static void read_inter_block_mode_info(VP9Decoder *const pbi,
MACROBLOCKD *const xd,
MODE_INFO *const mi,
@ -491,26 +682,13 @@ static void read_inter_block_mode_info(VP9Decoder *const pbi,
const BLOCK_SIZE bsize = mbmi->sb_type;
const int allow_hp = cm->allow_high_precision_mv;
int_mv nearestmv[2], nearmv[2];
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
int ref, is_compound;
uint8_t inter_mode_ctx[MAX_REF_FRAMES];
uint8_t inter_mode_ctx;
const POSITION *const mv_ref_search = mv_ref_blocks[bsize];
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
is_compound = has_second_ref(mbmi);
for (ref = 0; ref < 1 + is_compound; ++ref) {
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
if ((!vp9_is_valid_scale(&ref_buf->sf)))
vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
"Reference frame has invalid dimensions");
vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
&ref_buf->sf);
vp9_find_mv_refs(cm, xd, mi, frame, ref_mvs[frame],
mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
}
inter_mode_ctx = get_mode_context(cm, xd, mv_ref_search, mi_row, mi_col);
if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
mbmi->mode = ZEROMV;
@ -521,14 +699,27 @@ static void read_inter_block_mode_info(VP9Decoder *const pbi,
}
} else {
if (bsize >= BLOCK_8X8)
mbmi->mode = read_inter_mode(cm, xd, r,
inter_mode_ctx[mbmi->ref_frame[0]]);
}
mbmi->mode = read_inter_mode(cm, xd, r, inter_mode_ctx);
else
// Sub 8x8 blocks use the nearestmv as a ref_mv if the b_mode is NEWMV.
// Setting mode to NEARESTMV forces the search to stop after the nearestmv
// has been found. After b_modes have been read, mode will be overwritten
// by the last b_mode.
mbmi->mode = NEARESTMV;
if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
for (ref = 0; ref < 1 + is_compound; ++ref) {
vp9_find_best_ref_mvs(xd, allow_hp, ref_mvs[mbmi->ref_frame[ref]],
&nearestmv[ref], &nearmv[ref]);
if (mbmi->mode != ZEROMV) {
for (ref = 0; ref < 1 + is_compound; ++ref) {
int_mv ref_mvs[MAX_MV_REF_CANDIDATES];
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
int refmv_count;
refmv_count = dec_find_mv_refs(cm, xd, mi, frame, mv_ref_search,
ref_mvs, mi_row, mi_col, fpm_sync,
(void *)pbi);
dec_find_best_ref_mvs(xd, allow_hp, ref_mvs, &nearestmv[ref],
&nearmv[ref], refmv_count);
}
}
}
@ -546,7 +737,7 @@ static void read_inter_block_mode_info(VP9Decoder *const pbi,
for (idx = 0; idx < 2; idx += num_4x4_w) {
int_mv block[2];
const int j = idy * 2 + idx;
b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx[mbmi->ref_frame[0]]);
b_mode = read_inter_mode(cm, xd, r, inter_mode_ctx);
if (b_mode == NEARESTMV || b_mode == NEARMV) {
uint8_t dummy_mode_ctx[MAX_REF_FRAMES];

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

@ -0,0 +1,79 @@
/*
* Copyright (c) 2013 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 <math.h>
#include "vpx_ports/mem.h"
#include "vpx_ports/system_state.h"
#include "vp9/encoder/vp9_aq_variance.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rd.h"
#include "vp9/encoder/vp9_segmentation.h"
#define ENERGY_MIN (-4)
#define ENERGY_MAX (1)
#define ENERGY_SPAN (ENERGY_MAX - ENERGY_MIN + 1)
#define ENERGY_IN_BOUNDS(energy)\
assert((energy) >= ENERGY_MIN && (energy) <= ENERGY_MAX)
static const double rate_ratio[MAX_SEGMENTS] =
{1.0, 0.75, 0.6, 0.5, 0.4, 0.3, 0.25};
// Sets segment id 0 for the equatorial region, 1 for temperate region
// and 2 for the polar regions
unsigned int vp9_360aq_segment_id(int mi_row, int mi_rows) {
if (mi_row < mi_rows / 8 || mi_row > mi_rows - mi_rows / 8)
return 2;
else if (mi_row < mi_rows / 4 || mi_row > mi_rows - mi_rows / 4)
return 1;
else
return 0;
}
void vp9_360aq_frame_setup(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
struct segmentation *seg = &cm->seg;
int i;
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
vp9_enable_segmentation(seg);
vp9_clearall_segfeatures(seg);
seg->abs_delta = SEGMENT_DELTADATA;
vpx_clear_system_state();
for (i = 0; i < MAX_SEGMENTS; ++i) {
int qindex_delta =
vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex,
rate_ratio[i], cm->bit_depth);
// We don't allow qindex 0 in a segment if the base value is not 0.
// Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment
// Q delta is sometimes applied without going back around the rd loop.
// This could lead to an illegal combination of partition size and q.
if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
qindex_delta = -cm->base_qindex + 1;
}
// No need to enable SEG_LVL_ALT_Q for this segment.
if (rate_ratio[i] == 1.0) {
continue;
}
vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta);
vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
}
}
}

28
vp9/encoder/vp9_aq_360.h Normal file
Просмотреть файл

@ -0,0 +1,28 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef VP9_ENCODER_VP9_AQ_360_H_
#define VP9_ENCODER_VP9_AQ_360_H_
#include "vp9/encoder/vp9_encoder.h"
#ifdef __cplusplus
extern "C" {
#endif
unsigned int vp9_360aq_segment_id(int mi_row, int mi_rows);
void vp9_360aq_frame_setup(VP9_COMP *cpi);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VP9_ENCODER_VP9_AQ_VARIANCE_H_

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

@ -33,6 +33,7 @@
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_tile_common.h"
#include "vp9/encoder/vp9_aq_360.h"
#include "vp9/encoder/vp9_aq_complexity.h"
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
#include "vp9/encoder/vp9_aq_variance.h"
@ -221,7 +222,8 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
// Setup segment ID.
if (seg->enabled) {
if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
if (cpi->oxcf.aq_mode != VARIANCE_AQ &&
cpi->oxcf.aq_mode != EQUATOR360_AQ) {
const uint8_t *const map = seg->update_map ? cpi->segmentation_map
: cm->last_frame_seg_map;
mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
@ -1263,6 +1265,15 @@ static void rd_pick_sb_modes(VP9_COMP *cpi,
mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
}
x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
} else if (aq_mode == EQUATOR360_AQ) {
if (cm->frame_type == KEY_FRAME) {
mbmi->segment_id = vp9_360aq_segment_id(mi_row, cm->mi_rows);
} else {
const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
: cm->last_frame_seg_map;
mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
}
x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
} else if (aq_mode == COMPLEXITY_AQ) {
x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
} else if (aq_mode == CYCLIC_REFRESH_AQ) {
@ -1719,7 +1730,8 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td,
// For in frame complexity AQ or variance AQ, copy segment_id from
// segmentation_map.
if (cpi->oxcf.aq_mode == COMPLEXITY_AQ ||
cpi->oxcf.aq_mode == VARIANCE_AQ ) {
cpi->oxcf.aq_mode == VARIANCE_AQ ||
cpi->oxcf.aq_mode == EQUATOR360_AQ) {
const uint8_t *const map = seg->update_map ? cpi->segmentation_map
: cm->last_frame_seg_map;
mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);

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

@ -206,7 +206,7 @@ void vp9_encode_mv(VP9_COMP* cpi, vpx_writer* w,
const MV diff = {mv->row - ref->row,
mv->col - ref->col};
const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
usehp = usehp && vp9_use_mv_hp(ref);
usehp = usehp && use_mv_hp(ref);
vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]);
if (mv_joint_vertical(j))

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

@ -36,6 +36,7 @@
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_tile_common.h"
#include "vp9/encoder/vp9_aq_360.h"
#include "vp9/encoder/vp9_aq_complexity.h"
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
#include "vp9/encoder/vp9_aq_variance.h"
@ -3334,6 +3335,8 @@ static void encode_without_recode_loop(VP9_COMP *cpi,
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_vaq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == EQUATOR360_AQ) {
vp9_360aq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
vp9_setup_in_frame_q_adj(cpi);
} else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
@ -3464,6 +3467,8 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_vaq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == EQUATOR360_AQ) {
vp9_360aq_frame_setup(cpi);
} else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
vp9_setup_in_frame_q_adj(cpi);
}

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

@ -112,6 +112,7 @@ typedef enum {
VARIANCE_AQ = 1,
COMPLEXITY_AQ = 2,
CYCLIC_REFRESH_AQ = 3,
EQUATOR360_AQ = 4,
AQ_MODE_COUNT // This should always be the last member of the enum
} AQ_MODE;

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

@ -439,7 +439,7 @@ int vp9_find_best_sub_pixel_tree_pruned_evenmore(
tr = br;
tc = bc;
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (eighthiters > 1) {
@ -507,7 +507,7 @@ int vp9_find_best_sub_pixel_tree_pruned_more(const MACROBLOCK *x,
}
}
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) {
tr = br;
tc = bc;
hstep >>= 1;
@ -602,7 +602,7 @@ int vp9_find_best_sub_pixel_tree_pruned(const MACROBLOCK *x,
tc = bc;
}
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
if (allow_hp && use_mv_hp(ref_mv) && forced_stop == 0) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (eighthiters > 1) {
@ -674,7 +674,7 @@ int vp9_find_best_sub_pixel_tree(const MACROBLOCK *x,
unsigned int cost_array[5];
int kr, kc;
if (!(allow_hp && vp9_use_mv_hp(ref_mv)))
if (!(allow_hp && use_mv_hp(ref_mv)))
if (round == 3)
round = 2;

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

@ -1225,8 +1225,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (cm->use_prev_frame_mvs)
vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame,
candidates, mi_row, mi_col, NULL, NULL,
x->mbmi_ext->mode_context);
candidates, mi_row, mi_col, x->mbmi_ext->mode_context);
else
const_motion[ref_frame] = mv_refs_rt(cm, x, xd, tile_info,
xd->mi[0],
@ -1833,8 +1832,7 @@ void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
vp9_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col,
sf, sf);
vp9_find_mv_refs(cm, xd, xd->mi[0], ref_frame,
candidates, mi_row, mi_col, NULL, NULL,
mbmi_ext->mode_context);
candidates, mi_row, mi_col, mbmi_ext->mode_context);
vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
&dummy_mv[0], &dummy_mv[1]);

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

@ -2202,7 +2202,7 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
// Gets an initial list of candidate vectors from neighbours and orders them
vp9_find_mv_refs(cm, xd, mi, ref_frame, candidates, mi_row, mi_col,
NULL, NULL, mbmi_ext->mode_context);
mbmi_ext->mode_context);
// Candidate refinement carried out at encoder and decoder
vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,

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

@ -75,6 +75,8 @@ VP9_CX_SRCS-yes += encoder/vp9_tokenize.c
VP9_CX_SRCS-yes += encoder/vp9_treewriter.c
VP9_CX_SRCS-yes += encoder/vp9_aq_variance.c
VP9_CX_SRCS-yes += encoder/vp9_aq_variance.h
VP9_CX_SRCS-yes += encoder/vp9_aq_360.c
VP9_CX_SRCS-yes += encoder/vp9_aq_360.h
VP9_CX_SRCS-yes += encoder/vp9_aq_cyclicrefresh.c
VP9_CX_SRCS-yes += encoder/vp9_aq_cyclicrefresh.h
VP9_CX_SRCS-yes += encoder/vp9_aq_complexity.c

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

@ -388,7 +388,7 @@ static const arg_def_t frame_parallel_decoding = ARG_DEF(
static const arg_def_t aq_mode = ARG_DEF(
NULL, "aq-mode", 1,
"Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
"3: cyclic refresh)");
"3: cyclic refresh, 4: equator360)");
static const arg_def_t frame_periodic_boost = ARG_DEF(
NULL, "frame-boost", 1,
"Enable frame periodic boost (0: off (default), 1: on)");

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

@ -26,17 +26,6 @@ int stats_open_file(stats_io_t *stats, const char *fpf, int pass) {
stats->buf.buf = NULL;
res = (stats->file != NULL);
} else {
#if USE_POSIX_MMAP
struct stat stat_buf;
int fd;
fd = open(fpf, O_RDONLY);
stats->file = fdopen(fd, "rb");
fstat(fd, &stat_buf);
stats->buf.sz = stat_buf.st_size;
stats->buf.buf = mmap(NULL, stats->buf.sz, PROT_READ, MAP_PRIVATE, fd, 0);
res = (stats->buf.buf != NULL);
#else
size_t nbytes;
stats->file = fopen(fpf, "rb");
@ -58,7 +47,6 @@ int stats_open_file(stats_io_t *stats, const char *fpf, int pass) {
nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file);
res = (nbytes == stats->buf.sz);
#endif /* USE_POSIX_MMAP */
}
return res;
@ -82,11 +70,7 @@ int stats_open_mem(stats_io_t *stats, int pass) {
void stats_close(stats_io_t *stats, int last_pass) {
if (stats->file) {
if (stats->pass == last_pass) {
#if USE_POSIX_MMAP
munmap(stats->buf.buf, stats->buf.sz);
#else
free(stats->buf.buf);
#endif /* USE_POSIX_MMAP */
}
fclose(stats->file);