mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-13 02:37:32 +09:00
Update aom to v1.0.0
Update aom to commit id d14c5bb4f336ef1842046089849dee4a301fbbf0.
This commit is contained in:
parent
bb61121b44
commit
48f6d2e034
1087 changed files with 154333 additions and 265310 deletions
1318
third_party/aom/av1/encoder/ab_partition_model_weights.h
vendored
Normal file
1318
third_party/aom/av1/encoder/ab_partition_model_weights.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
28
third_party/aom/av1/encoder/aq_complexity.c
vendored
28
third_party/aom/av1/encoder/aq_complexity.c
vendored
|
|
@ -39,21 +39,29 @@ static const double aq_c_var_thresholds[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = {
|
|||
{ -3.0, -2.0, -1.0, 100.00, 100.0 }
|
||||
};
|
||||
|
||||
#define DEFAULT_COMPLEXITY 64
|
||||
|
||||
static int get_aq_c_strength(int q_index, aom_bit_depth_t bit_depth) {
|
||||
// Approximate base quatizer (truncated to int)
|
||||
const int base_quant = av1_ac_quant(q_index, 0, bit_depth) / 4;
|
||||
const int base_quant = av1_ac_quant_Q3(q_index, 0, bit_depth) / 4;
|
||||
return (base_quant > 10) + (base_quant > 25);
|
||||
}
|
||||
|
||||
void av1_setup_in_frame_q_adj(AV1_COMP *cpi) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
struct segmentation *const seg = &cm->seg;
|
||||
int resolution_change =
|
||||
cm->prev_frame && (cm->width != cm->prev_frame->width ||
|
||||
cm->height != cm->prev_frame->height);
|
||||
|
||||
// Make SURE use of floating point in this function is safe.
|
||||
aom_clear_system_state();
|
||||
|
||||
if (resolution_change) {
|
||||
memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
|
||||
av1_clearall_segfeatures(seg);
|
||||
av1_disable_segmentation(seg);
|
||||
return;
|
||||
}
|
||||
|
||||
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)) {
|
||||
|
|
@ -74,9 +82,6 @@ void av1_setup_in_frame_q_adj(AV1_COMP *cpi) {
|
|||
|
||||
av1_enable_segmentation(seg);
|
||||
|
||||
// Select delta coding method.
|
||||
seg->abs_delta = SEGMENT_DELTADATA;
|
||||
|
||||
// Default segment "Q" feature is disabled so it defaults to the baseline Q.
|
||||
av1_disable_segfeature(seg, DEFAULT_AQ2_SEG, SEG_LVL_ALT_Q);
|
||||
|
||||
|
|
@ -107,13 +112,13 @@ void av1_setup_in_frame_q_adj(AV1_COMP *cpi) {
|
|||
|
||||
#define DEFAULT_LV_THRESH 10.0
|
||||
#define MIN_DEFAULT_LV_THRESH 8.0
|
||||
#define VAR_STRENGTH_STEP 0.25
|
||||
// Select a segment for the current block.
|
||||
// The choice of segment for a block depends on the ratio of the projected
|
||||
// bits for the block vs a target average and its spatial complexity.
|
||||
void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs,
|
||||
int mi_row, int mi_col, int projected_rate) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
|
||||
const int mi_offset = mi_row * cm->mi_cols + mi_col;
|
||||
const int xmis = AOMMIN(cm->mi_cols - mi_col, mi_size_wide[bs]);
|
||||
|
|
@ -126,9 +131,10 @@ void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs,
|
|||
segment = DEFAULT_AQ2_SEG;
|
||||
} else {
|
||||
// Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
|
||||
// It is converted to bits * 256 units.
|
||||
const int64_t num = (int64_t)cpi->rc.sb64_target_rate * xmis * ymis * 256;
|
||||
const int denom = cm->mib_size * cm->mib_size;
|
||||
// It is converted to bits << AV1_PROB_COST_SHIFT units.
|
||||
const int64_t num = (int64_t)(cpi->rc.sb64_target_rate * xmis * ymis)
|
||||
<< AV1_PROB_COST_SHIFT;
|
||||
const int denom = cm->seq_params.mib_size * cm->seq_params.mib_size;
|
||||
const int target_rate = (int)(num / denom);
|
||||
double logvar;
|
||||
double low_var_thresh;
|
||||
|
|
@ -139,7 +145,7 @@ void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs,
|
|||
MIN_DEFAULT_LV_THRESH)
|
||||
: DEFAULT_LV_THRESH;
|
||||
|
||||
av1_setup_src_planes(mb, cpi->source, mi_row, mi_col);
|
||||
av1_setup_src_planes(mb, cpi->source, mi_row, mi_col, num_planes);
|
||||
logvar = av1_log_block_var(cpi, mb, bs);
|
||||
|
||||
segment = AQ_C_SEGMENTS - 1; // Just in case no break out below.
|
||||
|
|
|
|||
42
third_party/aom/av1/encoder/aq_cyclicrefresh.c
vendored
42
third_party/aom/av1/encoder/aq_cyclicrefresh.c
vendored
|
|
@ -320,7 +320,7 @@ void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) {
|
|||
double fraction_low = 0.0;
|
||||
int low_content_frame = 0;
|
||||
|
||||
MODE_INFO **mi;
|
||||
MB_MODE_INFO **mi;
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
const int rows = cm->mi_rows, cols = cm->mi_cols;
|
||||
int cnt1 = 0, cnt2 = 0;
|
||||
|
|
@ -330,12 +330,12 @@ void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) {
|
|||
mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
|
||||
|
||||
for (mi_col = 0; mi_col < cols; mi_col++) {
|
||||
int16_t abs_mvr = mi[0]->mbmi.mv[0].as_mv.row >= 0
|
||||
? mi[0]->mbmi.mv[0].as_mv.row
|
||||
: -1 * mi[0]->mbmi.mv[0].as_mv.row;
|
||||
int16_t abs_mvc = mi[0]->mbmi.mv[0].as_mv.col >= 0
|
||||
? mi[0]->mbmi.mv[0].as_mv.col
|
||||
: -1 * mi[0]->mbmi.mv[0].as_mv.col;
|
||||
int16_t abs_mvr = mi[0]->mv[0].as_mv.row >= 0
|
||||
? mi[0]->mv[0].as_mv.row
|
||||
: -1 * mi[0]->mv[0].as_mv.row;
|
||||
int16_t abs_mvc = mi[0]->mv[0].as_mv.col >= 0
|
||||
? mi[0]->mv[0].as_mv.col
|
||||
: -1 * mi[0]->mv[0].as_mv.col;
|
||||
|
||||
// Calculate the motion of the background.
|
||||
if (abs_mvr <= 16 && abs_mvc <= 16) {
|
||||
|
|
@ -389,8 +389,10 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
|
|||
int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame;
|
||||
int xmis, ymis, x, y;
|
||||
memset(seg_map, CR_SEGMENT_ID_BASE, cm->mi_rows * cm->mi_cols);
|
||||
sb_cols = (cm->mi_cols + cm->mib_size - 1) / cm->mib_size;
|
||||
sb_rows = (cm->mi_rows + cm->mib_size - 1) / cm->mib_size;
|
||||
sb_cols =
|
||||
(cm->mi_cols + cm->seq_params.mib_size - 1) / cm->seq_params.mib_size;
|
||||
sb_rows =
|
||||
(cm->mi_rows + cm->seq_params.mib_size - 1) / cm->seq_params.mib_size;
|
||||
sbs_in_frame = sb_cols * sb_rows;
|
||||
// Number of target blocks to get the q delta (segment 1).
|
||||
block_count = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
|
||||
|
|
@ -406,8 +408,8 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
|
|||
// Get the mi_row/mi_col corresponding to superblock index i.
|
||||
int sb_row_index = (i / sb_cols);
|
||||
int sb_col_index = i - sb_row_index * sb_cols;
|
||||
int mi_row = sb_row_index * cm->mib_size;
|
||||
int mi_col = sb_col_index * cm->mib_size;
|
||||
int mi_row = sb_row_index * cm->seq_params.mib_size;
|
||||
int mi_col = sb_col_index * cm->seq_params.mib_size;
|
||||
int qindex_thresh =
|
||||
cpi->oxcf.content == AOM_CONTENT_SCREEN
|
||||
? av1_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex)
|
||||
|
|
@ -416,14 +418,14 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
|
|||
assert(mi_col >= 0 && mi_col < cm->mi_cols);
|
||||
bl_index = mi_row * cm->mi_cols + mi_col;
|
||||
// Loop through all MI blocks in superblock and update map.
|
||||
xmis = AOMMIN(cm->mi_cols - mi_col, cm->mib_size);
|
||||
ymis = AOMMIN(cm->mi_rows - mi_row, cm->mib_size);
|
||||
xmis = AOMMIN(cm->mi_cols - mi_col, cm->seq_params.mib_size);
|
||||
ymis = AOMMIN(cm->mi_rows - mi_row, cm->seq_params.mib_size);
|
||||
for (y = 0; y < ymis; y++) {
|
||||
for (x = 0; x < xmis; x++) {
|
||||
const int bl_index2 = bl_index + y * cm->mi_cols + x;
|
||||
// If the block is as a candidate for clean up then mark it
|
||||
// for possible boost/refresh (segment 1). The segment id may get
|
||||
// reset to 0 later if block gets coded anything other than ZEROMV.
|
||||
// reset to 0 later if block gets coded anything other than GLOBALMV.
|
||||
if (cr->map[bl_index2] == 0) {
|
||||
if (cr->last_coded_q_map[bl_index2] > qindex_thresh) sum_map++;
|
||||
} else if (cr->map[bl_index2] < 0) {
|
||||
|
|
@ -479,6 +481,16 @@ void av1_cyclic_refresh_setup(AV1_COMP *const cpi) {
|
|||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
struct segmentation *const seg = &cm->seg;
|
||||
const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
|
||||
int resolution_change =
|
||||
cm->prev_frame && (cm->width != cm->prev_frame->width ||
|
||||
cm->height != cm->prev_frame->height);
|
||||
if (resolution_change) {
|
||||
memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
|
||||
av1_clearall_segfeatures(seg);
|
||||
aom_clear_system_state();
|
||||
av1_disable_segmentation(seg);
|
||||
return;
|
||||
}
|
||||
if (cm->current_video_frame == 0) cr->low_content_avg = 0.0;
|
||||
// Don't apply refresh on key frame or enhancement layer frames.
|
||||
if (!apply_cyclic_refresh || cm->frame_type == KEY_FRAME) {
|
||||
|
|
@ -509,8 +521,6 @@ void av1_cyclic_refresh_setup(AV1_COMP *const cpi) {
|
|||
// Clear down the segment map.
|
||||
av1_enable_segmentation(&cm->seg);
|
||||
av1_clearall_segfeatures(seg);
|
||||
// Select delta coding method.
|
||||
seg->abs_delta = SEGMENT_DELTADATA;
|
||||
|
||||
// Note: setting temporal_update has no effect, as the seg-map coding method
|
||||
// (temporal or spatial) is determined in
|
||||
|
|
|
|||
82
third_party/aom/av1/encoder/aq_variance.c
vendored
82
third_party/aom/av1/encoder/aq_variance.c
vendored
|
|
@ -19,6 +19,7 @@
|
|||
#include "av1/encoder/ratectrl.h"
|
||||
#include "av1/encoder/rd.h"
|
||||
#include "av1/encoder/segmentation.h"
|
||||
#include "av1/encoder/dwt.h"
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
#define ENERGY_MIN (-4)
|
||||
|
|
@ -34,10 +35,8 @@ static const int segment_id[ENERGY_SPAN] = { 0, 1, 1, 2, 3, 4 };
|
|||
#define SEGMENT_ID(i) segment_id[(i)-ENERGY_MIN]
|
||||
|
||||
DECLARE_ALIGNED(16, static const uint8_t, av1_all_zeros[MAX_SB_SIZE]) = { 0 };
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, static const uint16_t,
|
||||
av1_highbd_all_zeros[MAX_SB_SIZE]) = { 0 };
|
||||
#endif
|
||||
|
||||
unsigned int av1_vaq_segment_id(int energy) {
|
||||
ENERGY_IN_BOUNDS(energy);
|
||||
|
|
@ -49,6 +48,16 @@ void av1_vaq_frame_setup(AV1_COMP *cpi) {
|
|||
struct segmentation *seg = &cm->seg;
|
||||
int i;
|
||||
|
||||
int resolution_change =
|
||||
cm->prev_frame && (cm->width != cm->prev_frame->width ||
|
||||
cm->height != cm->prev_frame->height);
|
||||
if (resolution_change) {
|
||||
memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
|
||||
av1_clearall_segfeatures(seg);
|
||||
aom_clear_system_state();
|
||||
av1_disable_segmentation(seg);
|
||||
return;
|
||||
}
|
||||
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)) {
|
||||
|
|
@ -57,8 +66,6 @@ void av1_vaq_frame_setup(AV1_COMP *cpi) {
|
|||
av1_enable_segmentation(seg);
|
||||
av1_clearall_segfeatures(seg);
|
||||
|
||||
seg->abs_delta = SEGMENT_DELTADATA;
|
||||
|
||||
aom_clear_system_state();
|
||||
|
||||
for (i = 0; i < MAX_SEGMENTS; ++i) {
|
||||
|
|
@ -74,11 +81,6 @@ void av1_vaq_frame_setup(AV1_COMP *cpi) {
|
|||
qindex_delta = -cm->base_qindex + 1;
|
||||
}
|
||||
|
||||
// No need to enable SEG_LVL_ALT_Q for this segment.
|
||||
if (rate_ratio[i] == 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
av1_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta);
|
||||
av1_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
|
||||
}
|
||||
|
|
@ -108,7 +110,6 @@ static void aq_variance(const uint8_t *a, int a_stride, const uint8_t *b,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
static void aq_highbd_variance64(const uint8_t *a8, int a_stride,
|
||||
const uint8_t *b8, int b_stride, int w, int h,
|
||||
uint64_t *sse, uint64_t *sum) {
|
||||
|
|
@ -139,7 +140,6 @@ static void aq_highbd_8_variance(const uint8_t *a8, int a_stride,
|
|||
*sse = (unsigned int)sse_long;
|
||||
*sum = (int)sum_long;
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
static unsigned int block_variance(const AV1_COMP *const cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bs) {
|
||||
|
|
@ -154,7 +154,6 @@ static unsigned int block_variance(const AV1_COMP *const cpi, MACROBLOCK *x,
|
|||
const int bw = MI_SIZE * mi_size_wide[bs] - right_overflow;
|
||||
const int bh = MI_SIZE * mi_size_high[bs] - bottom_overflow;
|
||||
int avg;
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
aq_highbd_8_variance(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
CONVERT_TO_BYTEPTR(av1_highbd_all_zeros), 0, bw, bh,
|
||||
|
|
@ -165,14 +164,9 @@ static unsigned int block_variance(const AV1_COMP *const cpi, MACROBLOCK *x,
|
|||
aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, av1_all_zeros, 0,
|
||||
bw, bh, &sse, &avg);
|
||||
}
|
||||
#else
|
||||
aq_variance(x->plane[0].src.buf, x->plane[0].src.stride, av1_all_zeros, 0,
|
||||
bw, bh, &sse, &avg);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
var = sse - (unsigned int)(((int64_t)avg * avg) / (bw * bh));
|
||||
return (unsigned int)((uint64_t)var * 256) / (bw * bh);
|
||||
} else {
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
var =
|
||||
cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
|
|
@ -181,10 +175,6 @@ static unsigned int block_variance(const AV1_COMP *const cpi, MACROBLOCK *x,
|
|||
var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
av1_all_zeros, 0, &sse);
|
||||
}
|
||||
#else
|
||||
var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
av1_all_zeros, 0, &sse);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
return (unsigned int)((uint64_t)var * 256) >> num_pels_log2_lookup[bs];
|
||||
}
|
||||
}
|
||||
|
|
@ -205,3 +195,53 @@ int av1_block_energy(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs) {
|
|||
energy = av1_log_block_var(cpi, x, bs) - energy_midpoint;
|
||||
return clamp((int)round(energy), ENERGY_MIN, ENERGY_MAX);
|
||||
}
|
||||
|
||||
unsigned int haar_ac_energy(MACROBLOCK *x, BLOCK_SIZE bs) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
int stride = x->plane[0].src.stride;
|
||||
uint8_t *buf = x->plane[0].src.buf;
|
||||
const int bw = MI_SIZE * mi_size_wide[bs];
|
||||
const int bh = MI_SIZE * mi_size_high[bs];
|
||||
int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
|
||||
|
||||
int var = 0;
|
||||
for (int r = 0; r < bh; r += 8)
|
||||
for (int c = 0; c < bw; c += 8) {
|
||||
var += av1_haar_ac_sad_8x8_uint8_input(buf + c + r * stride, stride, hbd);
|
||||
}
|
||||
|
||||
return (unsigned int)((uint64_t)var * 256) >> num_pels_log2_lookup[bs];
|
||||
}
|
||||
|
||||
double av1_log_block_wavelet_energy(MACROBLOCK *x, BLOCK_SIZE bs) {
|
||||
unsigned int haar_sad = haar_ac_energy(x, bs);
|
||||
aom_clear_system_state();
|
||||
return log(haar_sad + 1.0);
|
||||
}
|
||||
|
||||
int av1_block_wavelet_energy_level(const AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bs) {
|
||||
double energy, energy_midpoint;
|
||||
aom_clear_system_state();
|
||||
energy_midpoint = (cpi->oxcf.pass == 2) ? cpi->twopass.frame_avg_haar_energy
|
||||
: DEFAULT_E_MIDPOINT;
|
||||
energy = av1_log_block_wavelet_energy(x, bs) - energy_midpoint;
|
||||
return clamp((int)round(energy), ENERGY_MIN, ENERGY_MAX);
|
||||
}
|
||||
|
||||
int av1_compute_deltaq_from_energy_level(const AV1_COMP *const cpi,
|
||||
int block_var_level) {
|
||||
ENERGY_IN_BOUNDS(block_var_level);
|
||||
|
||||
const int rate_level = SEGMENT_ID(block_var_level);
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
int qindex_delta =
|
||||
av1_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, cm->base_qindex,
|
||||
rate_ratio[rate_level], cm->bit_depth);
|
||||
|
||||
if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
|
||||
qindex_delta = -cm->base_qindex + 1;
|
||||
}
|
||||
|
||||
return qindex_delta;
|
||||
}
|
||||
|
|
|
|||
4
third_party/aom/av1/encoder/aq_variance.h
vendored
4
third_party/aom/av1/encoder/aq_variance.h
vendored
|
|
@ -23,6 +23,10 @@ void av1_vaq_frame_setup(AV1_COMP *cpi);
|
|||
|
||||
int av1_block_energy(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs);
|
||||
double av1_log_block_var(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs);
|
||||
int av1_compute_deltaq_from_energy_level(const AV1_COMP *const cpi,
|
||||
int block_var_level);
|
||||
int av1_block_wavelet_energy_level(const AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
|
||||
int64_t av1_block_error_fp_neon(const int16_t *coeff, const int16_t *dqcoeff,
|
||||
int block_size) {
|
||||
int64x2_t error = vdupq_n_s64(0);
|
||||
|
||||
assert(block_size >= 8);
|
||||
assert((block_size % 8) == 0);
|
||||
|
||||
do {
|
||||
const int16x8_t c = vld1q_s16(coeff);
|
||||
const int16x8_t d = vld1q_s16(dqcoeff);
|
||||
const int16x8_t diff = vsubq_s16(c, d);
|
||||
const int16x4_t diff_lo = vget_low_s16(diff);
|
||||
const int16x4_t diff_hi = vget_high_s16(diff);
|
||||
// diff is 15-bits, the squares 30, so we can store 2 in 31-bits before
|
||||
// accumulating them in 64-bits.
|
||||
const int32x4_t err0 = vmull_s16(diff_lo, diff_lo);
|
||||
const int32x4_t err1 = vmlal_s16(err0, diff_hi, diff_hi);
|
||||
const int64x2_t err2 = vaddl_s32(vget_low_s32(err1), vget_high_s32(err1));
|
||||
error = vaddq_s64(error, err2);
|
||||
coeff += 8;
|
||||
dqcoeff += 8;
|
||||
block_size -= 8;
|
||||
} while (block_size != 0);
|
||||
|
||||
return vgetq_lane_s64(error, 0) + vgetq_lane_s64(error, 1);
|
||||
}
|
||||
1902
third_party/aom/av1/encoder/av1_fwd_txfm1d.c
vendored
Normal file
1902
third_party/aom/av1/encoder/av1_fwd_txfm1d.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
49
third_party/aom/av1/encoder/av1_fwd_txfm1d.h
vendored
Normal file
49
third_party/aom/av1/encoder/av1_fwd_txfm1d.h
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_FWD_TXFM1D_H_
|
||||
#define AV1_FWD_TXFM1D_H_
|
||||
|
||||
#include "av1/common/av1_txfm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void av1_fdct4_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fdct8_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fdct16_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fdct32_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fdct64_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fadst4_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fadst8_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fadst16_new(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fidentity4_c(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fidentity8_c(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fidentity16_c(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
void av1_fidentity32_c(const int32_t *input, int32_t *output, int8_t cos_bit,
|
||||
const int8_t *stage_range);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AV1_FWD_TXFM1D_H_
|
||||
19
third_party/aom/av1/encoder/av1_fwd_txfm1d_cfg.h
vendored
Normal file
19
third_party/aom/av1/encoder/av1_fwd_txfm1d_cfg.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_FWD_TXFM2D_CFG_H_
|
||||
#define AV1_FWD_TXFM2D_CFG_H_
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/encoder/av1_fwd_txfm1d.h"
|
||||
extern const int8_t *fwd_txfm_shift_ls[TX_SIZES_ALL];
|
||||
extern const int8_t fwd_cos_bit_col[5][5];
|
||||
extern const int8_t fwd_cos_bit_row[5][5];
|
||||
#endif // AV1_FWD_TXFM2D_CFG_H_
|
||||
431
third_party/aom/av1/encoder/av1_fwd_txfm2d.c
vendored
Normal file
431
third_party/aom/av1/encoder/av1_fwd_txfm2d.c
vendored
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "config/aom_dsp_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
|
||||
#include "aom_dsp/txfm_common.h"
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/common/av1_txfm.h"
|
||||
#include "av1/encoder/av1_fwd_txfm1d.h"
|
||||
#include "av1/encoder/av1_fwd_txfm1d_cfg.h"
|
||||
|
||||
static INLINE TxfmFunc fwd_txfm_type_to_func(TXFM_TYPE txfm_type) {
|
||||
switch (txfm_type) {
|
||||
case TXFM_TYPE_DCT4: return av1_fdct4_new;
|
||||
case TXFM_TYPE_DCT8: return av1_fdct8_new;
|
||||
case TXFM_TYPE_DCT16: return av1_fdct16_new;
|
||||
case TXFM_TYPE_DCT32: return av1_fdct32_new;
|
||||
case TXFM_TYPE_DCT64: return av1_fdct64_new;
|
||||
case TXFM_TYPE_ADST4: return av1_fadst4_new;
|
||||
case TXFM_TYPE_ADST8: return av1_fadst8_new;
|
||||
case TXFM_TYPE_ADST16: return av1_fadst16_new;
|
||||
case TXFM_TYPE_IDENTITY4: return av1_fidentity4_c;
|
||||
case TXFM_TYPE_IDENTITY8: return av1_fidentity8_c;
|
||||
case TXFM_TYPE_IDENTITY16: return av1_fidentity16_c;
|
||||
case TXFM_TYPE_IDENTITY32: return av1_fidentity32_c;
|
||||
default: assert(0); return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_gen_fwd_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
|
||||
const TXFM_2D_FLIP_CFG *cfg, int bd) {
|
||||
// Take the shift from the larger dimension in the rectangular case.
|
||||
const int8_t *shift = cfg->shift;
|
||||
// i < MAX_TXFM_STAGE_NUM will mute above array bounds warning
|
||||
for (int i = 0; i < cfg->stage_num_col && i < MAX_TXFM_STAGE_NUM; ++i) {
|
||||
stage_range_col[i] = cfg->stage_range_col[i] + shift[0] + bd + 1;
|
||||
}
|
||||
|
||||
// i < MAX_TXFM_STAGE_NUM will mute above array bounds warning
|
||||
for (int i = 0; i < cfg->stage_num_row && i < MAX_TXFM_STAGE_NUM; ++i) {
|
||||
stage_range_row[i] = cfg->stage_range_row[i] + shift[0] + shift[1] + bd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void fwd_txfm2d_c(const int16_t *input, int32_t *output,
|
||||
const int stride, const TXFM_2D_FLIP_CFG *cfg,
|
||||
int32_t *buf, int bd) {
|
||||
int c, r;
|
||||
// Note when assigning txfm_size_col, we use the txfm_size from the
|
||||
// row configuration and vice versa. This is intentionally done to
|
||||
// accurately perform rectangular transforms. When the transform is
|
||||
// rectangular, the number of columns will be the same as the
|
||||
// txfm_size stored in the row cfg struct. It will make no difference
|
||||
// for square transforms.
|
||||
const int txfm_size_col = tx_size_wide[cfg->tx_size];
|
||||
const int txfm_size_row = tx_size_high[cfg->tx_size];
|
||||
// Take the shift from the larger dimension in the rectangular case.
|
||||
const int8_t *shift = cfg->shift;
|
||||
const int rect_type = get_rect_tx_log_ratio(txfm_size_col, txfm_size_row);
|
||||
int8_t stage_range_col[MAX_TXFM_STAGE_NUM];
|
||||
int8_t stage_range_row[MAX_TXFM_STAGE_NUM];
|
||||
assert(cfg->stage_num_col <= MAX_TXFM_STAGE_NUM);
|
||||
assert(cfg->stage_num_row <= MAX_TXFM_STAGE_NUM);
|
||||
av1_gen_fwd_stage_range(stage_range_col, stage_range_row, cfg, bd);
|
||||
|
||||
const int8_t cos_bit_col = cfg->cos_bit_col;
|
||||
const int8_t cos_bit_row = cfg->cos_bit_row;
|
||||
const TxfmFunc txfm_func_col = fwd_txfm_type_to_func(cfg->txfm_type_col);
|
||||
const TxfmFunc txfm_func_row = fwd_txfm_type_to_func(cfg->txfm_type_row);
|
||||
|
||||
// use output buffer as temp buffer
|
||||
int32_t *temp_in = output;
|
||||
int32_t *temp_out = output + txfm_size_row;
|
||||
|
||||
// Columns
|
||||
for (c = 0; c < txfm_size_col; ++c) {
|
||||
if (cfg->ud_flip == 0) {
|
||||
for (r = 0; r < txfm_size_row; ++r) temp_in[r] = input[r * stride + c];
|
||||
} else {
|
||||
for (r = 0; r < txfm_size_row; ++r)
|
||||
// flip upside down
|
||||
temp_in[r] = input[(txfm_size_row - r - 1) * stride + c];
|
||||
}
|
||||
av1_round_shift_array(temp_in, txfm_size_row, -shift[0]);
|
||||
txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
|
||||
av1_round_shift_array(temp_out, txfm_size_row, -shift[1]);
|
||||
if (cfg->lr_flip == 0) {
|
||||
for (r = 0; r < txfm_size_row; ++r)
|
||||
buf[r * txfm_size_col + c] = temp_out[r];
|
||||
} else {
|
||||
for (r = 0; r < txfm_size_row; ++r)
|
||||
// flip from left to right
|
||||
buf[r * txfm_size_col + (txfm_size_col - c - 1)] = temp_out[r];
|
||||
}
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (r = 0; r < txfm_size_row; ++r) {
|
||||
txfm_func_row(buf + r * txfm_size_col, output + r * txfm_size_col,
|
||||
cos_bit_row, stage_range_row);
|
||||
av1_round_shift_array(output + r * txfm_size_col, txfm_size_col, -shift[2]);
|
||||
if (abs(rect_type) == 1) {
|
||||
// Multiply everything by Sqrt2 if the transform is rectangular and the
|
||||
// size difference is a factor of 2.
|
||||
for (c = 0; c < txfm_size_col; ++c) {
|
||||
output[r * txfm_size_col + c] = round_shift(
|
||||
(int64_t)output[r * txfm_size_col + c] * NewSqrt2, NewSqrt2Bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_4x8_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[4 * 8]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_4X8, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_8x4_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[8 * 4];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_8X4, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_8x16_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[8 * 16]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_8X16, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_16x8_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[16 * 8];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_16X8, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_16x32_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[16 * 32]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_16X32, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_32x16_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[32 * 16];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_32X16, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_4x16_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[4 * 16]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_4X16, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_16x4_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[16 * 4];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_16X4, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_8x32_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[32 * 8]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_8X32, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_32x8_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[32 * 8];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_32X8, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_4x4_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[4 * 4];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_4X4, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_8x8_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[8 * 8];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_8X8, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_16x16_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[16 * 16];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_16X16, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_32x32_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[32 * 32];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_32X32, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_64x64_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[64 * 64];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_64X64, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
|
||||
// Zero out top-right 32x32 area.
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
memset(output + row * 64 + 32, 0, 32 * sizeof(*output));
|
||||
}
|
||||
// Zero out the bottom 64x32 area.
|
||||
memset(output + 32 * 64, 0, 32 * 64 * sizeof(*output));
|
||||
// Re-pack non-zero coeffs in the first 32x32 indices.
|
||||
for (int row = 1; row < 32; ++row) {
|
||||
memcpy(output + row * 32, output + row * 64, 32 * sizeof(*output));
|
||||
}
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_32x64_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[32 * 64]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_32X64, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
// Zero out the bottom 32x32 area.
|
||||
memset(output + 32 * 32, 0, 32 * 32 * sizeof(*output));
|
||||
// Note: no repacking needed here.
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_64x32_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[64 * 32];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_64X32, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
|
||||
// Zero out right 32x32 area.
|
||||
for (int row = 0; row < 32; ++row) {
|
||||
memset(output + row * 64 + 32, 0, 32 * sizeof(*output));
|
||||
}
|
||||
// Re-pack non-zero coeffs in the first 32x32 indices.
|
||||
for (int row = 1; row < 32; ++row) {
|
||||
memcpy(output + row * 32, output + row * 64, 32 * sizeof(*output));
|
||||
}
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_16x64_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
DECLARE_ALIGNED(32, int32_t, txfm_buf[64 * 16]);
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_16X64, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
// Zero out the bottom 16x32 area.
|
||||
memset(output + 16 * 32, 0, 16 * 32 * sizeof(*output));
|
||||
// Note: no repacking needed here.
|
||||
}
|
||||
|
||||
void av1_fwd_txfm2d_64x16_c(const int16_t *input, int32_t *output, int stride,
|
||||
TX_TYPE tx_type, int bd) {
|
||||
int32_t txfm_buf[64 * 16];
|
||||
TXFM_2D_FLIP_CFG cfg;
|
||||
av1_get_fwd_txfm_cfg(tx_type, TX_64X16, &cfg);
|
||||
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf, bd);
|
||||
// Zero out right 32x16 area.
|
||||
for (int row = 0; row < 16; ++row) {
|
||||
memset(output + row * 64 + 32, 0, 32 * sizeof(*output));
|
||||
}
|
||||
// Re-pack non-zero coeffs in the first 32x16 indices.
|
||||
for (int row = 1; row < 16; ++row) {
|
||||
memcpy(output + row * 32, output + row * 64, 32 * sizeof(*output));
|
||||
}
|
||||
}
|
||||
|
||||
static const int8_t fwd_shift_4x4[3] = { 2, 0, 0 };
|
||||
static const int8_t fwd_shift_8x8[3] = { 2, -1, 0 };
|
||||
static const int8_t fwd_shift_16x16[3] = { 2, -2, 0 };
|
||||
static const int8_t fwd_shift_32x32[3] = { 2, -4, 0 };
|
||||
static const int8_t fwd_shift_64x64[3] = { 0, -2, -2 };
|
||||
static const int8_t fwd_shift_4x8[3] = { 2, -1, 0 };
|
||||
static const int8_t fwd_shift_8x4[3] = { 2, -1, 0 };
|
||||
static const int8_t fwd_shift_8x16[3] = { 2, -2, 0 };
|
||||
static const int8_t fwd_shift_16x8[3] = { 2, -2, 0 };
|
||||
static const int8_t fwd_shift_16x32[3] = { 2, -4, 0 };
|
||||
static const int8_t fwd_shift_32x16[3] = { 2, -4, 0 };
|
||||
static const int8_t fwd_shift_32x64[3] = { 0, -2, -2 };
|
||||
static const int8_t fwd_shift_64x32[3] = { 2, -4, -2 };
|
||||
static const int8_t fwd_shift_4x16[3] = { 2, -1, 0 };
|
||||
static const int8_t fwd_shift_16x4[3] = { 2, -1, 0 };
|
||||
static const int8_t fwd_shift_8x32[3] = { 2, -2, 0 };
|
||||
static const int8_t fwd_shift_32x8[3] = { 2, -2, 0 };
|
||||
static const int8_t fwd_shift_16x64[3] = { 0, -2, 0 };
|
||||
static const int8_t fwd_shift_64x16[3] = { 2, -4, 0 };
|
||||
|
||||
const int8_t *fwd_txfm_shift_ls[TX_SIZES_ALL] = {
|
||||
fwd_shift_4x4, fwd_shift_8x8, fwd_shift_16x16, fwd_shift_32x32,
|
||||
fwd_shift_64x64, fwd_shift_4x8, fwd_shift_8x4, fwd_shift_8x16,
|
||||
fwd_shift_16x8, fwd_shift_16x32, fwd_shift_32x16, fwd_shift_32x64,
|
||||
fwd_shift_64x32, fwd_shift_4x16, fwd_shift_16x4, fwd_shift_8x32,
|
||||
fwd_shift_32x8, fwd_shift_16x64, fwd_shift_64x16,
|
||||
};
|
||||
|
||||
const int8_t fwd_cos_bit_col[MAX_TXWH_IDX /*txw_idx*/]
|
||||
[MAX_TXWH_IDX /*txh_idx*/] = {
|
||||
{ 13, 13, 13, 0, 0 },
|
||||
{ 13, 13, 13, 12, 0 },
|
||||
{ 13, 13, 13, 12, 13 },
|
||||
{ 0, 13, 13, 12, 13 },
|
||||
{ 0, 0, 13, 12, 13 }
|
||||
};
|
||||
|
||||
const int8_t fwd_cos_bit_row[MAX_TXWH_IDX /*txw_idx*/]
|
||||
[MAX_TXWH_IDX /*txh_idx*/] = {
|
||||
{ 13, 13, 12, 0, 0 },
|
||||
{ 13, 13, 13, 12, 0 },
|
||||
{ 13, 13, 12, 13, 12 },
|
||||
{ 0, 12, 13, 12, 11 },
|
||||
{ 0, 0, 12, 11, 10 }
|
||||
};
|
||||
|
||||
static const int8_t fdct4_range_mult2[4] = { 0, 2, 3, 3 };
|
||||
static const int8_t fdct8_range_mult2[6] = { 0, 2, 4, 5, 5, 5 };
|
||||
static const int8_t fdct16_range_mult2[8] = { 0, 2, 4, 6, 7, 7, 7, 7 };
|
||||
static const int8_t fdct32_range_mult2[10] = { 0, 2, 4, 6, 8, 9, 9, 9, 9, 9 };
|
||||
static const int8_t fdct64_range_mult2[12] = { 0, 2, 4, 6, 8, 10,
|
||||
11, 11, 11, 11, 11, 11 };
|
||||
|
||||
static const int8_t fadst4_range_mult2[7] = { 0, 2, 4, 3, 3, 3, 3 };
|
||||
static const int8_t fadst8_range_mult2[8] = { 0, 0, 1, 3, 3, 5, 5, 5 };
|
||||
static const int8_t fadst16_range_mult2[10] = { 0, 0, 1, 3, 3, 5, 5, 7, 7, 7 };
|
||||
|
||||
static const int8_t max_fwd_range_mult2_col[5] = { 3, 5, 7, 9, 11 };
|
||||
|
||||
static const int8_t fidtx4_range_mult2[1] = { 1 };
|
||||
static const int8_t fidtx8_range_mult2[1] = { 2 };
|
||||
static const int8_t fidtx16_range_mult2[1] = { 3 };
|
||||
static const int8_t fidtx32_range_mult2[1] = { 4 };
|
||||
|
||||
#if 0
|
||||
const int8_t fwd_idtx_range_row[MAX_TXWH_IDX /*txw_idx*/]
|
||||
[MAX_TXWH_IDX /*txh_idx*/] = { { 2, 4, 5, 0, 0 },
|
||||
{ 3, 4, 5, 6, 0 },
|
||||
{ 4, 5, 6, 7, 8 },
|
||||
{ 0, 5, 6, 7, 8 },
|
||||
{ 0, 0, 7, 8,
|
||||
9 } };
|
||||
#endif
|
||||
|
||||
const int8_t *fwd_txfm_range_mult2_list[TXFM_TYPES] = {
|
||||
fdct4_range_mult2, fdct8_range_mult2, fdct16_range_mult2,
|
||||
fdct32_range_mult2, fdct64_range_mult2, fadst4_range_mult2,
|
||||
fadst8_range_mult2, fadst16_range_mult2, fidtx4_range_mult2,
|
||||
fidtx8_range_mult2, fidtx16_range_mult2, fidtx32_range_mult2
|
||||
};
|
||||
|
||||
static INLINE void set_fwd_txfm_non_scale_range(TXFM_2D_FLIP_CFG *cfg) {
|
||||
const int txh_idx = get_txh_idx(cfg->tx_size);
|
||||
av1_zero(cfg->stage_range_col);
|
||||
av1_zero(cfg->stage_range_row);
|
||||
|
||||
if (cfg->txfm_type_col != TXFM_TYPE_INVALID) {
|
||||
int stage_num_col = cfg->stage_num_col;
|
||||
const int8_t *range_mult2_col =
|
||||
fwd_txfm_range_mult2_list[cfg->txfm_type_col];
|
||||
for (int i = 0; i < stage_num_col; ++i)
|
||||
cfg->stage_range_col[i] = (range_mult2_col[i] + 1) >> 1;
|
||||
}
|
||||
|
||||
if (cfg->txfm_type_row != TXFM_TYPE_INVALID) {
|
||||
int stage_num_row = cfg->stage_num_row;
|
||||
const int8_t *range_mult2_row =
|
||||
fwd_txfm_range_mult2_list[cfg->txfm_type_row];
|
||||
for (int i = 0; i < stage_num_row; ++i)
|
||||
cfg->stage_range_row[i] =
|
||||
(max_fwd_range_mult2_col[txh_idx] + range_mult2_row[i] + 1) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_get_fwd_txfm_cfg(TX_TYPE tx_type, TX_SIZE tx_size,
|
||||
TXFM_2D_FLIP_CFG *cfg) {
|
||||
assert(cfg != NULL);
|
||||
cfg->tx_size = tx_size;
|
||||
set_flip_cfg(tx_type, cfg);
|
||||
const TX_TYPE_1D tx_type_1d_col = vtx_tab[tx_type];
|
||||
const TX_TYPE_1D tx_type_1d_row = htx_tab[tx_type];
|
||||
const int txw_idx = tx_size_wide_log2[tx_size] - tx_size_wide_log2[0];
|
||||
const int txh_idx = tx_size_high_log2[tx_size] - tx_size_high_log2[0];
|
||||
cfg->shift = fwd_txfm_shift_ls[tx_size];
|
||||
cfg->cos_bit_col = fwd_cos_bit_col[txw_idx][txh_idx];
|
||||
cfg->cos_bit_row = fwd_cos_bit_row[txw_idx][txh_idx];
|
||||
cfg->txfm_type_col = av1_txfm_type_ls[txh_idx][tx_type_1d_col];
|
||||
cfg->txfm_type_row = av1_txfm_type_ls[txw_idx][tx_type_1d_row];
|
||||
cfg->stage_num_col = av1_txfm_stage_num_list[cfg->txfm_type_col];
|
||||
cfg->stage_num_row = av1_txfm_stage_num_list[cfg->txfm_type_row];
|
||||
set_fwd_txfm_non_scale_range(cfg);
|
||||
}
|
||||
1649
third_party/aom/av1/encoder/av1_quantize.c
vendored
1649
third_party/aom/av1/encoder/av1_quantize.c
vendored
File diff suppressed because it is too large
Load diff
119
third_party/aom/av1/encoder/av1_quantize.h
vendored
119
third_party/aom/av1/encoder/av1_quantize.h
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#ifndef AV1_ENCODER_QUANTIZE_H_
|
||||
#define AV1_ENCODER_QUANTIZE_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "av1/common/quant_common.h"
|
||||
#include "av1/common/scan.h"
|
||||
#include "av1/encoder/block.h"
|
||||
|
|
@ -23,33 +24,22 @@ extern "C" {
|
|||
|
||||
typedef struct QUANT_PARAM {
|
||||
int log_scale;
|
||||
#if CONFIG_NEW_QUANT
|
||||
TX_SIZE tx_size;
|
||||
int dq;
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
#if CONFIG_AOM_QM
|
||||
const qm_val_t *qmatrix;
|
||||
const qm_val_t *iqmatrix;
|
||||
#endif // CONFIG_AOM_QM
|
||||
} QUANT_PARAM;
|
||||
|
||||
typedef void (*AV1_QUANT_FACADE)(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
||||
// The QUANTS structure is used only for internal quantizer setup in
|
||||
// av1_quantize.c.
|
||||
// All of its fields use the same coefficient shift/scaling at TX.
|
||||
typedef struct {
|
||||
#if CONFIG_NEW_QUANT
|
||||
DECLARE_ALIGNED(
|
||||
16, tran_low_t,
|
||||
y_cuml_bins_nuq[QUANT_PROFILES][QINDEX_RANGE][COEF_BANDS][NUQ_KNOTS]);
|
||||
DECLARE_ALIGNED(
|
||||
16, tran_low_t,
|
||||
uv_cuml_bins_nuq[QUANT_PROFILES][QINDEX_RANGE][COEF_BANDS][NUQ_KNOTS]);
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
// 0: dc 1: ac 2-8: ac repeated to SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]);
|
||||
|
|
@ -59,25 +49,36 @@ typedef struct {
|
|||
// TODO(jingning): in progress of re-working the quantization. will decide
|
||||
// if we want to deprecate the current use of y_quant.
|
||||
DECLARE_ALIGNED(16, int16_t, y_quant_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, uv_quant_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_quant_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_quant_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, y_round_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, uv_round_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_round_fp[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_round_fp[QINDEX_RANGE][8]);
|
||||
|
||||
DECLARE_ALIGNED(16, int16_t, uv_quant[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, uv_quant_shift[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, uv_zbin[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, uv_round[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_quant[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_quant[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_quant_shift[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_quant_shift[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_zbin[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_zbin[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, u_round[QINDEX_RANGE][8]);
|
||||
DECLARE_ALIGNED(16, int16_t, v_round[QINDEX_RANGE][8]);
|
||||
} QUANTS;
|
||||
|
||||
// The Dequants structure is used only for internal quantizer setup in
|
||||
// av1_quantize.c.
|
||||
// Fields are sufffixed according to whether or not they're expressed in
|
||||
// the same coefficient shift/precision as TX or a fixed Q3 format.
|
||||
typedef struct {
|
||||
DECLARE_ALIGNED(16, int16_t, y_dequant[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t, uv_dequant[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
#if CONFIG_NEW_QUANT
|
||||
DECLARE_ALIGNED(16, dequant_val_type_nuq,
|
||||
y_dequant_val_nuq[QUANT_PROFILES][QINDEX_RANGE][COEF_BANDS]);
|
||||
DECLARE_ALIGNED(16, dequant_val_type_nuq,
|
||||
uv_dequant_val_nuq[QUANT_PROFILES][QINDEX_RANGE][COEF_BANDS]);
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
DECLARE_ALIGNED(16, int16_t,
|
||||
y_dequant_QTX[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t,
|
||||
u_dequant_QTX[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t,
|
||||
v_dequant_QTX[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t, y_dequant_Q3[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t, u_dequant_Q3[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
DECLARE_ALIGNED(16, int16_t, v_dequant_Q3[QINDEX_RANGE][8]); // 8: SIMD width
|
||||
} Dequants;
|
||||
|
||||
struct AV1_COMP;
|
||||
|
|
@ -89,8 +90,9 @@ void av1_init_plane_quantizers(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
|||
int segment_id);
|
||||
|
||||
void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
|
||||
int uv_dc_delta_q, int uv_ac_delta_q,
|
||||
QUANTS *const quants, Dequants *const deq);
|
||||
int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
|
||||
int v_ac_delta_q, QUANTS *const quants,
|
||||
Dequants *const deq);
|
||||
|
||||
void av1_init_quantizer(struct AV1_COMP *cpi);
|
||||
|
||||
|
|
@ -105,51 +107,22 @@ void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
|
|||
|
||||
void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd, tran_low_t *dqcoeff_ptr,
|
||||
uint16_t *eob_ptr, const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
|
||||
|
||||
#if CONFIG_NEW_QUANT
|
||||
void av1_quantize_fp_nuq_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_quantize_b_nuq_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_quantize_dc_nuq_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
|
||||
void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
|
||||
intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
|
@ -157,7 +130,6 @@ void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
|
|||
void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
|
||||
intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
|
@ -165,31 +137,10 @@ void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
|
|||
void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
|
||||
intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
|
||||
const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
||||
#if CONFIG_NEW_QUANT
|
||||
void av1_highbd_quantize_fp_nuq_facade(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr, const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_highbd_quantize_b_nuq_facade(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr, const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
|
||||
void av1_highbd_quantize_dc_nuq_facade(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
|
||||
tran_low_t *qcoeff_ptr, const MACROBLOCKD_PLANE *pd,
|
||||
tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, const SCAN_ORDER *sc,
|
||||
const QUANT_PARAM *qparam);
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
1257
third_party/aom/av1/encoder/bgsprite.c
vendored
1257
third_party/aom/av1/encoder/bgsprite.c
vendored
File diff suppressed because it is too large
Load diff
30
third_party/aom/av1/encoder/bgsprite.h
vendored
30
third_party/aom/av1/encoder/bgsprite.h
vendored
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_BGSPRITE_H_
|
||||
#define AV1_ENCODER_BGSPRITE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "av1/encoder/encoder.h"
|
||||
|
||||
// Creates alternate reference frame staring from source image + frames up to
|
||||
// 'distance' past source frame.
|
||||
// Returns 0 on success and 1 on failure.
|
||||
int av1_background_sprite(AV1_COMP *cpi, int distance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_BGSPRITE_H_
|
||||
6616
third_party/aom/av1/encoder/bitstream.c
vendored
6616
third_party/aom/av1/encoder/bitstream.c
vendored
File diff suppressed because it is too large
Load diff
26
third_party/aom/av1/encoder/bitstream.h
vendored
26
third_party/aom/av1/encoder/bitstream.h
vendored
|
|
@ -20,34 +20,24 @@ extern "C" {
|
|||
|
||||
struct aom_write_bit_buffer;
|
||||
|
||||
#if CONFIG_REFERENCE_BUFFER
|
||||
void write_sequence_header(AV1_COMMON *const cm,
|
||||
struct aom_write_bit_buffer *wb);
|
||||
#endif
|
||||
void write_sequence_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb);
|
||||
|
||||
void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dest, size_t *size);
|
||||
uint32_t write_obu_header(OBU_TYPE obu_type, int obu_extension,
|
||||
uint8_t *const dst);
|
||||
|
||||
void av1_encode_token_init(void);
|
||||
int write_uleb_obu_size(uint32_t obu_header_size, uint32_t obu_payload_size,
|
||||
uint8_t *dest);
|
||||
|
||||
int av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dest, size_t *size);
|
||||
|
||||
static INLINE int av1_preserve_existing_gf(AV1_COMP *cpi) {
|
||||
#if CONFIG_EXT_REFS
|
||||
// Do not swap gf and arf indices for internal overlay frames
|
||||
return !cpi->multi_arf_allowed && cpi->rc.is_src_frame_alt_ref &&
|
||||
!cpi->rc.is_src_frame_ext_arf;
|
||||
#else
|
||||
return !cpi->multi_arf_allowed && cpi->refresh_golden_frame &&
|
||||
cpi->rc.is_src_frame_alt_ref;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
}
|
||||
|
||||
void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd,
|
||||
#if CONFIG_SUPERTX
|
||||
const int supertx_enabled,
|
||||
#endif
|
||||
#if CONFIG_TXK_SEL
|
||||
int blk_row, int blk_col, int block, int plane,
|
||||
TX_SIZE tx_size,
|
||||
#endif
|
||||
int blk_row, int blk_col, int plane, TX_SIZE tx_size,
|
||||
aom_writer *w);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
384
third_party/aom/av1/encoder/block.h
vendored
384
third_party/aom/av1/encoder/block.h
vendored
|
|
@ -14,9 +14,6 @@
|
|||
|
||||
#include "av1/common/entropymv.h"
|
||||
#include "av1/common/entropy.h"
|
||||
#if CONFIG_PVQ
|
||||
#include "av1/encoder/encint.h"
|
||||
#endif
|
||||
#include "av1/common/mvref_common.h"
|
||||
#include "av1/encoder/hash.h"
|
||||
#if CONFIG_DIST_8X8
|
||||
|
|
@ -27,12 +24,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_PVQ
|
||||
// Maximum possible # of tx blocks in luma plane, which is currently 256,
|
||||
// since there can be 16x16 of 4x4 tx.
|
||||
#define MAX_PVQ_BLOCKS_IN_SB (MAX_SB_SQUARE >> 2 * OD_LOG_BSIZE0)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned int sse;
|
||||
int sum;
|
||||
|
|
@ -41,52 +32,38 @@ typedef struct {
|
|||
|
||||
typedef struct macroblock_plane {
|
||||
DECLARE_ALIGNED(16, int16_t, src_diff[MAX_SB_SQUARE]);
|
||||
#if CONFIG_PVQ
|
||||
DECLARE_ALIGNED(16, int16_t, src_int16[MAX_SB_SQUARE]);
|
||||
#endif
|
||||
tran_low_t *qcoeff;
|
||||
tran_low_t *coeff;
|
||||
uint16_t *eobs;
|
||||
#if CONFIG_LV_MAP
|
||||
uint8_t *txb_entropy_ctx;
|
||||
#endif
|
||||
struct buf_2d src;
|
||||
|
||||
// Quantizer setings
|
||||
const int16_t *quant_fp;
|
||||
const int16_t *round_fp;
|
||||
const int16_t *quant;
|
||||
const int16_t *quant_shift;
|
||||
const int16_t *zbin;
|
||||
const int16_t *round;
|
||||
#if CONFIG_NEW_QUANT
|
||||
const cuml_bins_type_nuq *cuml_bins_nuq[QUANT_PROFILES];
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
// These are used/accessed only in the quantization process
|
||||
// RDO does not / must not depend on any of these values
|
||||
// All values below share the coefficient scale/shift used in TX
|
||||
const int16_t *quant_fp_QTX;
|
||||
const int16_t *round_fp_QTX;
|
||||
const int16_t *quant_QTX;
|
||||
const int16_t *quant_shift_QTX;
|
||||
const int16_t *zbin_QTX;
|
||||
const int16_t *round_QTX;
|
||||
const int16_t *dequant_QTX;
|
||||
} MACROBLOCK_PLANE;
|
||||
|
||||
typedef int av1_coeff_cost[PLANE_TYPES][REF_TYPES][COEF_BANDS][COEFF_CONTEXTS]
|
||||
[TAIL_TOKENS];
|
||||
|
||||
#if CONFIG_LV_MAP
|
||||
typedef struct {
|
||||
int txb_skip_cost[TXB_SKIP_CONTEXTS][2];
|
||||
int nz_map_cost[SIG_COEF_CONTEXTS][2];
|
||||
int eob_cost[EOB_COEF_CONTEXTS][2];
|
||||
int base_eob_cost[SIG_COEF_CONTEXTS_EOB][3];
|
||||
int base_cost[SIG_COEF_CONTEXTS][4];
|
||||
int eob_extra_cost[EOB_COEF_CONTEXTS][2];
|
||||
int dc_sign_cost[DC_SIGN_CONTEXTS][2];
|
||||
int base_cost[NUM_BASE_LEVELS][COEFF_BASE_CONTEXTS][2];
|
||||
#if BR_NODE
|
||||
int lps_cost[LEVEL_CONTEXTS][COEFF_BASE_RANGE + 1];
|
||||
int br_cost[BASE_RANGE_SETS][LEVEL_CONTEXTS][2];
|
||||
#else // BR_NODE
|
||||
int lps_cost[LEVEL_CONTEXTS][2];
|
||||
#endif // BR_NODE
|
||||
#if CONFIG_CTX1D
|
||||
int eob_mode_cost[TX_CLASSES][2];
|
||||
int empty_line_cost[TX_CLASSES][EMPTY_LINE_CONTEXTS][2];
|
||||
int hv_eob_cost[TX_CLASSES][HV_EOB_CONTEXTS][2];
|
||||
#endif
|
||||
} LV_MAP_COEFF_COST;
|
||||
|
||||
typedef struct {
|
||||
int eob_cost[2][11];
|
||||
} LV_MAP_EOB_COST;
|
||||
|
||||
typedef struct {
|
||||
tran_low_t tcoeff[MAX_MB_PLANE][MAX_SB_SQUARE];
|
||||
uint16_t eobs[MAX_MB_PLANE][MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
|
||||
|
|
@ -95,20 +72,17 @@ typedef struct {
|
|||
int dc_sign_ctx[MAX_MB_PLANE]
|
||||
[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
|
||||
} CB_COEFF_BUFFER;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int_mv ref_mvs[MODE_CTX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
|
||||
int16_t mode_context[MODE_CTX_REF_FRAMES];
|
||||
#if CONFIG_LV_MAP
|
||||
// TODO(angiebird): Reduce the buffer size according to sb_type
|
||||
tran_low_t *tcoeff[MAX_MB_PLANE];
|
||||
uint16_t *eobs[MAX_MB_PLANE];
|
||||
uint8_t *txb_skip_ctx[MAX_MB_PLANE];
|
||||
int *dc_sign_ctx[MAX_MB_PLANE];
|
||||
#endif
|
||||
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
|
||||
CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
|
||||
int_mv global_mvs[REF_FRAMES];
|
||||
int16_t compound_mode_context[MODE_CTX_REF_FRAMES];
|
||||
} MB_MODE_INFO_EXT;
|
||||
|
||||
|
|
@ -120,39 +94,119 @@ typedef struct {
|
|||
} MvLimits;
|
||||
|
||||
typedef struct {
|
||||
uint8_t best_palette_color_map[MAX_SB_SQUARE];
|
||||
float kmeans_data_buf[2 * MAX_SB_SQUARE];
|
||||
uint8_t best_palette_color_map[MAX_PALETTE_SQUARE];
|
||||
int kmeans_data_buf[2 * MAX_PALETTE_SQUARE];
|
||||
} PALETTE_BUFFER;
|
||||
|
||||
typedef struct {
|
||||
TX_TYPE tx_type;
|
||||
TX_SIZE tx_size;
|
||||
#if CONFIG_VAR_TX
|
||||
TX_SIZE min_tx_size;
|
||||
TX_SIZE inter_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
|
||||
uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
|
||||
#endif // CONFIG_VAR_TX
|
||||
#if CONFIG_TXK_SEL
|
||||
TX_TYPE txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
|
||||
#endif // CONFIG_TXK_SEL
|
||||
TX_SIZE inter_tx_size[INTER_TX_SIZE_BUF_LEN];
|
||||
uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
|
||||
TX_TYPE txk_type[TXK_TYPE_BUF_LEN];
|
||||
RD_STATS rd_stats;
|
||||
uint32_t hash_value;
|
||||
} TX_RD_INFO;
|
||||
} MB_RD_INFO;
|
||||
|
||||
#define RD_RECORD_BUFFER_LEN 8
|
||||
typedef struct {
|
||||
TX_RD_INFO tx_rd_info[RD_RECORD_BUFFER_LEN]; // Circular buffer.
|
||||
MB_RD_INFO tx_rd_info[RD_RECORD_BUFFER_LEN]; // Circular buffer.
|
||||
int index_start;
|
||||
int num;
|
||||
CRC_CALCULATOR crc_calculator; // Hash function.
|
||||
} TX_RD_RECORD;
|
||||
CRC32C crc_calculator; // Hash function.
|
||||
} MB_RD_RECORD;
|
||||
|
||||
typedef struct {
|
||||
int64_t dist;
|
||||
int64_t sse;
|
||||
int rate;
|
||||
uint16_t eob;
|
||||
TX_TYPE tx_type;
|
||||
uint16_t entropy_context;
|
||||
uint8_t txb_entropy_ctx;
|
||||
uint8_t valid;
|
||||
uint8_t fast; // This is not being used now.
|
||||
} TXB_RD_INFO;
|
||||
|
||||
#define TX_SIZE_RD_RECORD_BUFFER_LEN 256
|
||||
typedef struct {
|
||||
uint32_t hash_vals[TX_SIZE_RD_RECORD_BUFFER_LEN];
|
||||
TXB_RD_INFO tx_rd_info[TX_SIZE_RD_RECORD_BUFFER_LEN];
|
||||
int index_start;
|
||||
int num;
|
||||
} TXB_RD_RECORD;
|
||||
|
||||
typedef struct tx_size_rd_info_node {
|
||||
TXB_RD_INFO *rd_info_array; // Points to array of size TX_TYPES.
|
||||
struct tx_size_rd_info_node *children[4];
|
||||
} TXB_RD_INFO_NODE;
|
||||
|
||||
// Region size for mode decision sampling in the first pass of partition
|
||||
// search(two_pass_partition_search speed feature), in units of mi size(4).
|
||||
// Used by the mode_pruning_based_on_two_pass_partition_search speed feature.
|
||||
#define FIRST_PARTITION_PASS_SAMPLE_REGION 8
|
||||
#define FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2 3
|
||||
#define FIRST_PARTITION_PASS_STATS_TABLES \
|
||||
(MAX_MIB_SIZE >> FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2) * \
|
||||
(MAX_MIB_SIZE >> FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2)
|
||||
#define FIRST_PARTITION_PASS_STATS_STRIDE \
|
||||
(MAX_MIB_SIZE_LOG2 - FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2)
|
||||
|
||||
static INLINE int av1_first_partition_pass_stats_index(int mi_row, int mi_col) {
|
||||
const int row =
|
||||
(mi_row & MAX_MIB_MASK) >> FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2;
|
||||
const int col =
|
||||
(mi_col & MAX_MIB_MASK) >> FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2;
|
||||
return (row << FIRST_PARTITION_PASS_STATS_STRIDE) + col;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t ref0_counts[REF_FRAMES]; // Counters for ref_frame[0].
|
||||
uint8_t ref1_counts[REF_FRAMES]; // Counters for ref_frame[1].
|
||||
int sample_counts; // Number of samples collected.
|
||||
} FIRST_PARTITION_PASS_STATS;
|
||||
|
||||
#define MAX_INTERP_FILTER_STATS 64
|
||||
typedef struct {
|
||||
InterpFilters filters;
|
||||
int_mv mv[2];
|
||||
int8_t ref_frames[2];
|
||||
} INTERPOLATION_FILTER_STATS;
|
||||
|
||||
typedef struct macroblock MACROBLOCK;
|
||||
struct macroblock {
|
||||
struct macroblock_plane plane[MAX_MB_PLANE];
|
||||
|
||||
// Save the transform RD search info.
|
||||
TX_RD_RECORD tx_rd_record;
|
||||
// Determine if one would go with reduced complexity transform block
|
||||
// search model to select prediction modes, or full complexity model
|
||||
// to select transform kernel.
|
||||
int rd_model;
|
||||
|
||||
// Indicate if the encoder is running in the first pass partition search.
|
||||
// In that case, apply certain speed features therein to reduce the overhead
|
||||
// cost in the first pass search.
|
||||
int cb_partition_scan;
|
||||
|
||||
FIRST_PARTITION_PASS_STATS
|
||||
first_partition_pass_stats[FIRST_PARTITION_PASS_STATS_TABLES];
|
||||
|
||||
// [comp_idx][saved stat_idx]
|
||||
INTERPOLATION_FILTER_STATS interp_filter_stats[2][MAX_INTERP_FILTER_STATS];
|
||||
int interp_filter_stats_idx[2];
|
||||
|
||||
// Activate constrained coding block partition search range.
|
||||
int use_cb_search_range;
|
||||
|
||||
// Inter macroblock RD search info.
|
||||
MB_RD_RECORD mb_rd_record;
|
||||
|
||||
// Inter transform block RD search info. for square TX sizes.
|
||||
TXB_RD_RECORD txb_rd_record_8X8[(MAX_MIB_SIZE >> 1) * (MAX_MIB_SIZE >> 1)];
|
||||
TXB_RD_RECORD txb_rd_record_16X16[(MAX_MIB_SIZE >> 2) * (MAX_MIB_SIZE >> 2)];
|
||||
TXB_RD_RECORD txb_rd_record_32X32[(MAX_MIB_SIZE >> 3) * (MAX_MIB_SIZE >> 3)];
|
||||
TXB_RD_RECORD txb_rd_record_64X64[(MAX_MIB_SIZE >> 4) * (MAX_MIB_SIZE >> 4)];
|
||||
|
||||
// Intra transform block RD search info. for square TX sizes.
|
||||
TXB_RD_RECORD txb_rd_record_intra;
|
||||
|
||||
MACROBLOCKD e_mbd;
|
||||
MB_MODE_INFO_EXT *mbmi_ext;
|
||||
|
|
@ -173,34 +227,29 @@ struct macroblock {
|
|||
int *m_search_count_ptr;
|
||||
int *ex_search_count_ptr;
|
||||
|
||||
#if CONFIG_VAR_TX
|
||||
unsigned int txb_split_count;
|
||||
#endif
|
||||
|
||||
// These are set to their default values at the beginning, and then adjusted
|
||||
// further in the encoding process.
|
||||
BLOCK_SIZE min_partition_size;
|
||||
BLOCK_SIZE max_partition_size;
|
||||
|
||||
int mv_best_ref_index[TOTAL_REFS_PER_FRAME];
|
||||
unsigned int max_mv_context[TOTAL_REFS_PER_FRAME];
|
||||
unsigned int max_mv_context[REF_FRAMES];
|
||||
unsigned int source_variance;
|
||||
unsigned int pred_sse[TOTAL_REFS_PER_FRAME];
|
||||
int pred_mv_sad[TOTAL_REFS_PER_FRAME];
|
||||
unsigned int pred_sse[REF_FRAMES];
|
||||
int pred_mv_sad[REF_FRAMES];
|
||||
|
||||
int *nmvjointcost;
|
||||
int nmv_vec_cost[NMV_CONTEXTS][MV_JOINTS];
|
||||
int *nmvcost[NMV_CONTEXTS][2];
|
||||
int *nmvcost_hp[NMV_CONTEXTS][2];
|
||||
int **mv_cost_stack[NMV_CONTEXTS];
|
||||
int nmv_vec_cost[MV_JOINTS];
|
||||
int *nmvcost[2];
|
||||
int *nmvcost_hp[2];
|
||||
int **mv_cost_stack;
|
||||
int **mvcost;
|
||||
|
||||
#if CONFIG_MOTION_VAR
|
||||
int32_t *wsrc_buf;
|
||||
int32_t *mask_buf;
|
||||
uint8_t *above_pred_buf;
|
||||
uint8_t *left_pred_buf;
|
||||
#endif // CONFIG_MOTION_VAR
|
||||
|
||||
PALETTE_BUFFER *palette_buffer;
|
||||
|
||||
|
|
@ -208,108 +257,80 @@ struct macroblock {
|
|||
// from extending outside the UMV borders
|
||||
MvLimits mv_limits;
|
||||
|
||||
#if CONFIG_VAR_TX
|
||||
uint8_t blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
|
||||
uint8_t blk_skip_drl[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
|
||||
#endif
|
||||
uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
|
||||
uint8_t blk_skip_drl[MAX_MIB_SIZE * MAX_MIB_SIZE];
|
||||
|
||||
int skip;
|
||||
|
||||
#if CONFIG_CB4X4
|
||||
int skip_chroma_rd;
|
||||
#endif
|
||||
int skip_cost[SKIP_CONTEXTS][2];
|
||||
|
||||
int skip_mode; // 0: off; 1: on
|
||||
int skip_mode_cost[SKIP_CONTEXTS][2];
|
||||
|
||||
int compound_idx;
|
||||
|
||||
#if CONFIG_LV_MAP
|
||||
LV_MAP_COEFF_COST coeff_costs[TX_SIZES][PLANE_TYPES];
|
||||
LV_MAP_EOB_COST eob_costs[7][2];
|
||||
uint16_t cb_offset;
|
||||
#endif
|
||||
|
||||
av1_coeff_cost token_head_costs[TX_SIZES];
|
||||
av1_coeff_cost token_tail_costs[TX_SIZES];
|
||||
|
||||
// mode costs
|
||||
int intra_inter_cost[INTRA_INTER_CONTEXTS][2];
|
||||
|
||||
int mbmode_cost[BLOCK_SIZE_GROUPS][INTRA_MODES];
|
||||
int newmv_mode_cost[NEWMV_MODE_CONTEXTS][2];
|
||||
int zeromv_mode_cost[ZEROMV_MODE_CONTEXTS][2];
|
||||
int zeromv_mode_cost[GLOBALMV_MODE_CONTEXTS][2];
|
||||
int refmv_mode_cost[REFMV_MODE_CONTEXTS][2];
|
||||
int drl_mode_cost0[DRL_MODE_CONTEXTS][2];
|
||||
|
||||
int comp_inter_cost[COMP_INTER_CONTEXTS][2];
|
||||
int single_ref_cost[REF_CONTEXTS][SINGLE_REFS - 1][2];
|
||||
int comp_ref_type_cost[COMP_REF_TYPE_CONTEXTS]
|
||||
[CDF_SIZE(COMP_REFERENCE_TYPES)];
|
||||
int uni_comp_ref_cost[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]
|
||||
[CDF_SIZE(2)];
|
||||
// Cost for signaling ref_frame[0] (LAST_FRAME, LAST2_FRAME, LAST3_FRAME or
|
||||
// GOLDEN_FRAME) in bidir-comp mode.
|
||||
int comp_ref_cost[REF_CONTEXTS][FWD_REFS - 1][2];
|
||||
// Cost for signaling ref_frame[1] (ALTREF_FRAME, ALTREF2_FRAME, or
|
||||
// BWDREF_FRAME) in bidir-comp mode.
|
||||
int comp_bwdref_cost[REF_CONTEXTS][BWD_REFS - 1][2];
|
||||
int inter_compound_mode_cost[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
|
||||
int compound_type_cost[BLOCK_SIZES_ALL][COMPOUND_TYPES];
|
||||
#if CONFIG_COMPOUND_SINGLEREF
|
||||
int inter_singleref_comp_mode_cost[INTER_MODE_CONTEXTS]
|
||||
[INTER_SINGLEREF_COMP_MODES];
|
||||
#endif // CONFIG_COMPOUND_SINGLEREF
|
||||
#if CONFIG_INTERINTRA
|
||||
int compound_type_cost[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
|
||||
int wedge_idx_cost[BLOCK_SIZES_ALL][16];
|
||||
int interintra_cost[BLOCK_SIZE_GROUPS][2];
|
||||
int wedge_interintra_cost[BLOCK_SIZES_ALL][2];
|
||||
int interintra_mode_cost[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
|
||||
#endif // CONFIG_INTERINTRA
|
||||
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
|
||||
int motion_mode_cost[BLOCK_SIZES_ALL][MOTION_MODES];
|
||||
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
|
||||
int motion_mode_cost1[BLOCK_SIZES_ALL][2];
|
||||
#if CONFIG_NCOBMC_ADAPT_WEIGHT
|
||||
int motion_mode_cost2[BLOCK_SIZES_ALL][OBMC_FAMILY_MODES];
|
||||
#endif
|
||||
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
|
||||
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC_ADAPT_WEIGHT
|
||||
int ncobmc_mode_cost[ADAPT_OVERLAP_BLOCKS][MAX_NCOBMC_MODES];
|
||||
#endif // CONFIG_MOTION_VAR && CONFIG_NCOBMC_ADAPT_WEIGHT
|
||||
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
|
||||
int intra_uv_mode_cost[INTRA_MODES][UV_INTRA_MODES];
|
||||
int intra_uv_mode_cost[CFL_ALLOWED_TYPES][INTRA_MODES][UV_INTRA_MODES];
|
||||
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
|
||||
int filter_intra_cost[BLOCK_SIZES_ALL][2];
|
||||
int filter_intra_mode_cost[FILTER_INTRA_MODES];
|
||||
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
int partition_cost[PARTITION_CONTEXTS + CONFIG_UNPOISON_PARTITION_CTX]
|
||||
[EXT_PARTITION_TYPES];
|
||||
#else
|
||||
int partition_cost[PARTITION_CONTEXTS + CONFIG_UNPOISON_PARTITION_CTX]
|
||||
[PARTITION_TYPES];
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
#if CONFIG_MRC_TX
|
||||
int mrc_mask_inter_cost[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
int mrc_mask_intra_cost[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
#endif // CONFIG_MRC_TX
|
||||
int palette_y_size_cost[PALETTE_BLOCK_SIZES][PALETTE_SIZES];
|
||||
int palette_uv_size_cost[PALETTE_BLOCK_SIZES][PALETTE_SIZES];
|
||||
int partition_cost[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
|
||||
int palette_y_size_cost[PALATTE_BSIZE_CTXS][PALETTE_SIZES];
|
||||
int palette_uv_size_cost[PALATTE_BSIZE_CTXS][PALETTE_SIZES];
|
||||
int palette_y_color_cost[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
int palette_uv_color_cost[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
#if CONFIG_CFL
|
||||
int palette_y_mode_cost[PALATTE_BSIZE_CTXS][PALETTE_Y_MODE_CONTEXTS][2];
|
||||
int palette_uv_mode_cost[PALETTE_UV_MODE_CONTEXTS][2];
|
||||
// The rate associated with each alpha codeword
|
||||
int cfl_cost[CFL_JOINT_SIGNS][CFL_PRED_PLANES][CFL_ALPHABET_SIZE];
|
||||
#endif // CONFIG_CFL
|
||||
int tx_size_cost[TX_SIZES - 1][TX_SIZE_CONTEXTS][TX_SIZES];
|
||||
#if CONFIG_EXT_TX
|
||||
#if CONFIG_LGT_FROM_PRED
|
||||
int intra_lgt_cost[LGT_SIZES][INTRA_MODES][2];
|
||||
int inter_lgt_cost[LGT_SIZES][2];
|
||||
#endif
|
||||
int txfm_partition_cost[TXFM_PARTITION_CONTEXTS][2];
|
||||
int inter_tx_type_costs[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES];
|
||||
int intra_tx_type_costs[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
|
||||
[TX_TYPES];
|
||||
#else
|
||||
int intra_tx_type_costs[EXT_TX_SIZES][TX_TYPES][TX_TYPES];
|
||||
int inter_tx_type_costs[EXT_TX_SIZES][TX_TYPES];
|
||||
#endif // CONFIG_EXT_TX
|
||||
#if CONFIG_EXT_INTRA
|
||||
#if CONFIG_INTRA_INTERP
|
||||
int intra_filter_cost[INTRA_FILTERS + 1][INTRA_FILTERS];
|
||||
#endif // CONFIG_INTRA_INTERP
|
||||
#endif // CONFIG_EXT_INTRA
|
||||
#if CONFIG_LOOP_RESTORATION
|
||||
int angle_delta_cost[DIRECTIONAL_MODES][2 * MAX_ANGLE_DELTA + 1];
|
||||
int switchable_restore_cost[RESTORE_SWITCHABLE_TYPES];
|
||||
#endif // CONFIG_LOOP_RESTORATION
|
||||
#if CONFIG_INTRABC
|
||||
int wiener_restore_cost[2];
|
||||
int sgrproj_restore_cost[2];
|
||||
int intrabc_cost[2];
|
||||
#endif // CONFIG_INTRABC
|
||||
|
||||
int optimize;
|
||||
|
||||
// Used to store sub partition's choices.
|
||||
MV pred_mv[TOTAL_REFS_PER_FRAME];
|
||||
MV pred_mv[REF_FRAMES];
|
||||
|
||||
// Store the best motion vector during motion search
|
||||
int_mv best_mv;
|
||||
|
|
@ -320,38 +341,65 @@ struct macroblock {
|
|||
int use_default_intra_tx_type;
|
||||
// use default transform and skip transform type search for inter modes
|
||||
int use_default_inter_tx_type;
|
||||
#if CONFIG_PVQ
|
||||
int rate;
|
||||
// 1 if neither AC nor DC is coded. Only used during RDO.
|
||||
int pvq_skip[MAX_MB_PLANE];
|
||||
PVQ_QUEUE *pvq_q;
|
||||
|
||||
// Storage for PVQ tx block encodings in a superblock.
|
||||
// There can be max 16x16 of 4x4 blocks (and YUV) encode by PVQ
|
||||
// 256 is the max # of 4x4 blocks in a SB (64x64), which comes from:
|
||||
// 1) Since PVQ is applied to each trasnform-ed block
|
||||
// 2) 4x4 is the smallest tx size in AV1
|
||||
// 3) AV1 allows using smaller tx size than block (i.e. partition) size
|
||||
// TODO(yushin) : The memory usage could be improved a lot, since this has
|
||||
// storage for 10 bands and 128 coefficients for every 4x4 block,
|
||||
PVQ_INFO pvq[MAX_PVQ_BLOCKS_IN_SB][MAX_MB_PLANE];
|
||||
daala_enc_ctx daala_enc;
|
||||
int pvq_speed;
|
||||
int pvq_coded; // Indicates whether pvq_info needs be stored to tokenize
|
||||
#endif
|
||||
#if CONFIG_DIST_8X8
|
||||
int using_dist_8x8;
|
||||
aom_tune_metric tune_metric;
|
||||
#if CONFIG_CB4X4
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, decoded_8x8[8 * 8]);
|
||||
#else
|
||||
DECLARE_ALIGNED(16, uint8_t, decoded_8x8[8 * 8]);
|
||||
#endif
|
||||
#endif // CONFIG_CB4X4
|
||||
DECLARE_ALIGNED(16, int16_t, pred_luma[MAX_SB_SQUARE]);
|
||||
#endif // CONFIG_DIST_8X8
|
||||
int comp_idx_cost[COMP_INDEX_CONTEXTS][2];
|
||||
int comp_group_idx_cost[COMP_GROUP_IDX_CONTEXTS][2];
|
||||
// Bit flags for pruning tx type search, tx split, etc.
|
||||
int tx_search_prune[EXT_TX_SET_TYPES];
|
||||
int must_find_valid_partition;
|
||||
int tx_split_prune_flag; // Flag to skip tx split RD search.
|
||||
};
|
||||
|
||||
static INLINE int is_rect_tx_allowed_bsize(BLOCK_SIZE bsize) {
|
||||
static const char LUT[BLOCK_SIZES_ALL] = {
|
||||
0, // BLOCK_4X4
|
||||
1, // BLOCK_4X8
|
||||
1, // BLOCK_8X4
|
||||
0, // BLOCK_8X8
|
||||
1, // BLOCK_8X16
|
||||
1, // BLOCK_16X8
|
||||
0, // BLOCK_16X16
|
||||
1, // BLOCK_16X32
|
||||
1, // BLOCK_32X16
|
||||
0, // BLOCK_32X32
|
||||
1, // BLOCK_32X64
|
||||
1, // BLOCK_64X32
|
||||
0, // BLOCK_64X64
|
||||
0, // BLOCK_64X128
|
||||
0, // BLOCK_128X64
|
||||
0, // BLOCK_128X128
|
||||
1, // BLOCK_4X16
|
||||
1, // BLOCK_16X4
|
||||
1, // BLOCK_8X32
|
||||
1, // BLOCK_32X8
|
||||
1, // BLOCK_16X64
|
||||
1, // BLOCK_64X16
|
||||
};
|
||||
|
||||
return LUT[bsize];
|
||||
}
|
||||
|
||||
static INLINE int is_rect_tx_allowed(const MACROBLOCKD *xd,
|
||||
const MB_MODE_INFO *mbmi) {
|
||||
return is_rect_tx_allowed_bsize(mbmi->sb_type) &&
|
||||
!xd->lossless[mbmi->segment_id];
|
||||
}
|
||||
|
||||
static INLINE int tx_size_to_depth(TX_SIZE tx_size, BLOCK_SIZE bsize) {
|
||||
TX_SIZE ctx_size = max_txsize_rect_lookup[bsize];
|
||||
int depth = 0;
|
||||
while (tx_size != ctx_size) {
|
||||
depth++;
|
||||
ctx_size = sub_tx_size_map[ctx_size];
|
||||
assert(depth <= MAX_TX_DEPTH);
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
7
third_party/aom/av1/encoder/blockiness.c
vendored
7
third_party/aom/av1/encoder/blockiness.c
vendored
|
|
@ -9,9 +9,10 @@
|
|||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
#include "config/aom_config.h"
|
||||
#include "config/aom_dsp_rtcd.h"
|
||||
|
||||
#include "av1/common/common.h"
|
||||
#include "av1/common/filter.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
|
|
|||
278
third_party/aom/av1/encoder/context_tree.c
vendored
278
third_party/aom/av1/encoder/context_tree.c
vendored
|
|
@ -13,32 +13,18 @@
|
|||
#include "av1/encoder/encoder.h"
|
||||
|
||||
static const BLOCK_SIZE square[MAX_SB_SIZE_LOG2 - 1] = {
|
||||
#if CONFIG_CB4X4
|
||||
BLOCK_4X4,
|
||||
#endif
|
||||
BLOCK_8X8, BLOCK_16X16, BLOCK_32X32, BLOCK_64X64,
|
||||
#if CONFIG_EXT_PARTITION
|
||||
BLOCK_128X128,
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
BLOCK_4X4, BLOCK_8X8, BLOCK_16X16, BLOCK_32X32, BLOCK_64X64, BLOCK_128X128,
|
||||
};
|
||||
|
||||
static void alloc_mode_context(AV1_COMMON *cm, int num_pix,
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
PARTITION_TYPE partition,
|
||||
#endif
|
||||
PICK_MODE_CONTEXT *ctx) {
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
int i;
|
||||
const int num_blk = num_pix / 16;
|
||||
ctx->num_4x4_blk = num_blk;
|
||||
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
ctx->partition = partition;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
#if CONFIG_VAR_TX
|
||||
CHECK_MEM_ERROR(cm, ctx->blk_skip[i], aom_calloc(num_blk, sizeof(uint8_t)));
|
||||
#endif
|
||||
CHECK_MEM_ERROR(cm, ctx->blk_skip, aom_calloc(num_blk, sizeof(uint8_t)));
|
||||
for (i = 0; i < num_planes; ++i) {
|
||||
CHECK_MEM_ERROR(cm, ctx->coeff[i],
|
||||
aom_memalign(32, num_pix * sizeof(*ctx->coeff[i])));
|
||||
CHECK_MEM_ERROR(cm, ctx->qcoeff[i],
|
||||
|
|
@ -47,148 +33,94 @@ static void alloc_mode_context(AV1_COMMON *cm, int num_pix,
|
|||
aom_memalign(32, num_pix * sizeof(*ctx->dqcoeff[i])));
|
||||
CHECK_MEM_ERROR(cm, ctx->eobs[i],
|
||||
aom_memalign(32, num_blk * sizeof(*ctx->eobs[i])));
|
||||
#if CONFIG_LV_MAP
|
||||
CHECK_MEM_ERROR(
|
||||
cm, ctx->txb_entropy_ctx[i],
|
||||
aom_memalign(32, num_blk * sizeof(*ctx->txb_entropy_ctx[i])));
|
||||
#endif
|
||||
|
||||
#if CONFIG_PVQ
|
||||
CHECK_MEM_ERROR(cm, ctx->pvq_ref_coeff[i],
|
||||
aom_memalign(32, num_pix * sizeof(*ctx->pvq_ref_coeff[i])));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
CHECK_MEM_ERROR(
|
||||
cm, ctx->color_index_map[i],
|
||||
aom_memalign(32, num_pix * sizeof(*ctx->color_index_map[i])));
|
||||
if (num_pix <= MAX_PALETTE_SQUARE) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
CHECK_MEM_ERROR(
|
||||
cm, ctx->color_index_map[i],
|
||||
aom_memalign(32, num_pix * sizeof(*ctx->color_index_map[i])));
|
||||
}
|
||||
}
|
||||
#if CONFIG_MRC_TX
|
||||
CHECK_MEM_ERROR(cm, ctx->mrc_mask,
|
||||
aom_memalign(32, num_pix * sizeof(*ctx->mrc_mask)));
|
||||
#endif // CONFIG_MRC_TX
|
||||
}
|
||||
|
||||
static void free_mode_context(PICK_MODE_CONTEXT *ctx) {
|
||||
static void free_mode_context(PICK_MODE_CONTEXT *ctx, const int num_planes) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_MB_PLANE; ++i) {
|
||||
#if CONFIG_VAR_TX
|
||||
aom_free(ctx->blk_skip[i]);
|
||||
ctx->blk_skip[i] = 0;
|
||||
#endif
|
||||
aom_free(ctx->blk_skip);
|
||||
ctx->blk_skip = 0;
|
||||
for (i = 0; i < num_planes; ++i) {
|
||||
aom_free(ctx->coeff[i]);
|
||||
ctx->coeff[i] = 0;
|
||||
aom_free(ctx->qcoeff[i]);
|
||||
ctx->qcoeff[i] = 0;
|
||||
aom_free(ctx->dqcoeff[i]);
|
||||
ctx->dqcoeff[i] = 0;
|
||||
#if CONFIG_PVQ
|
||||
aom_free(ctx->pvq_ref_coeff[i]);
|
||||
ctx->pvq_ref_coeff[i] = 0;
|
||||
#endif
|
||||
aom_free(ctx->eobs[i]);
|
||||
ctx->eobs[i] = 0;
|
||||
#if CONFIG_LV_MAP
|
||||
aom_free(ctx->txb_entropy_ctx[i]);
|
||||
ctx->txb_entropy_ctx[i] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
aom_free(ctx->color_index_map[i]);
|
||||
ctx->color_index_map[i] = 0;
|
||||
}
|
||||
#if CONFIG_MRC_TX
|
||||
aom_free(ctx->mrc_mask);
|
||||
ctx->mrc_mask = 0;
|
||||
#endif // CONFIG_MRC_TX
|
||||
}
|
||||
|
||||
static void alloc_tree_contexts(AV1_COMMON *cm, PC_TREE *tree, int num_pix) {
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
alloc_mode_context(cm, num_pix, PARTITION_NONE, &tree->none);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_HORZ, &tree->horizontal[0]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_VERT, &tree->vertical[0]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_VERT, &tree->horizontal[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_VERT, &tree->vertical[1]);
|
||||
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_A, &tree->horizontala[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_A, &tree->horizontala[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_HORZ_A, &tree->horizontala[2]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_HORZ_B, &tree->horizontalb[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_B, &tree->horizontalb[1]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_B, &tree->horizontalb[2]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_VERT_A, &tree->verticala[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_VERT_A, &tree->verticala[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_VERT_A, &tree->verticala[2]);
|
||||
alloc_mode_context(cm, num_pix / 2, PARTITION_VERT_B, &tree->verticalb[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_VERT_B, &tree->verticalb[1]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_VERT_B, &tree->verticalb[2]);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_4,
|
||||
&tree->horizontal4[i]);
|
||||
alloc_mode_context(cm, num_pix / 4, PARTITION_HORZ_4, &tree->vertical4[i]);
|
||||
}
|
||||
#if CONFIG_SUPERTX
|
||||
alloc_mode_context(cm, num_pix, PARTITION_HORZ, &tree->horizontal_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_VERT, &tree->vertical_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_SPLIT, &tree->split_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_HORZ_A, &tree->horizontala_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_HORZ_B, &tree->horizontalb_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_VERT_A, &tree->verticala_supertx);
|
||||
alloc_mode_context(cm, num_pix, PARTITION_VERT_B, &tree->verticalb_supertx);
|
||||
#endif // CONFIG_SUPERTX
|
||||
#else
|
||||
static void alloc_tree_contexts(AV1_COMMON *cm, PC_TREE *tree, int num_pix,
|
||||
int is_leaf) {
|
||||
alloc_mode_context(cm, num_pix, &tree->none);
|
||||
|
||||
if (is_leaf) return;
|
||||
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->horizontal[0]);
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->vertical[0]);
|
||||
#if CONFIG_SUPERTX
|
||||
alloc_mode_context(cm, num_pix, &tree->horizontal_supertx);
|
||||
alloc_mode_context(cm, num_pix, &tree->vertical_supertx);
|
||||
alloc_mode_context(cm, num_pix, &tree->split_supertx);
|
||||
#endif
|
||||
|
||||
if (num_pix > 16) {
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->horizontal[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->vertical[1]);
|
||||
} else {
|
||||
memset(&tree->horizontal[1], 0, sizeof(tree->horizontal[1]));
|
||||
memset(&tree->vertical[1], 0, sizeof(tree->vertical[1]));
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->horizontal[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->vertical[1]);
|
||||
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->horizontala[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->horizontala[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->horizontala[2]);
|
||||
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->horizontalb[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->horizontalb[1]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->horizontalb[2]);
|
||||
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->verticala[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->verticala[1]);
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->verticala[2]);
|
||||
|
||||
alloc_mode_context(cm, num_pix / 2, &tree->verticalb[0]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->verticalb[1]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->verticalb[2]);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->horizontal4[i]);
|
||||
alloc_mode_context(cm, num_pix / 4, &tree->vertical4[i]);
|
||||
}
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
}
|
||||
|
||||
static void free_tree_contexts(PC_TREE *tree) {
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
static void free_tree_contexts(PC_TREE *tree, const int num_planes) {
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
free_mode_context(&tree->horizontala[i]);
|
||||
free_mode_context(&tree->horizontalb[i]);
|
||||
free_mode_context(&tree->verticala[i]);
|
||||
free_mode_context(&tree->verticalb[i]);
|
||||
free_mode_context(&tree->horizontala[i], num_planes);
|
||||
free_mode_context(&tree->horizontalb[i], num_planes);
|
||||
free_mode_context(&tree->verticala[i], num_planes);
|
||||
free_mode_context(&tree->verticalb[i], num_planes);
|
||||
}
|
||||
for (i = 0; i < 4; ++i) {
|
||||
free_mode_context(&tree->horizontal4[i]);
|
||||
free_mode_context(&tree->vertical4[i]);
|
||||
free_mode_context(&tree->horizontal4[i], num_planes);
|
||||
free_mode_context(&tree->vertical4[i], num_planes);
|
||||
}
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
free_mode_context(&tree->none);
|
||||
free_mode_context(&tree->horizontal[0]);
|
||||
free_mode_context(&tree->horizontal[1]);
|
||||
free_mode_context(&tree->vertical[0]);
|
||||
free_mode_context(&tree->vertical[1]);
|
||||
#if CONFIG_SUPERTX
|
||||
free_mode_context(&tree->horizontal_supertx);
|
||||
free_mode_context(&tree->vertical_supertx);
|
||||
free_mode_context(&tree->split_supertx);
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
free_mode_context(&tree->horizontala_supertx);
|
||||
free_mode_context(&tree->horizontalb_supertx);
|
||||
free_mode_context(&tree->verticala_supertx);
|
||||
free_mode_context(&tree->verticalb_supertx);
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
#endif // CONFIG_SUPERTX
|
||||
free_mode_context(&tree->none, num_planes);
|
||||
free_mode_context(&tree->horizontal[0], num_planes);
|
||||
free_mode_context(&tree->horizontal[1], num_planes);
|
||||
free_mode_context(&tree->vertical[0], num_planes);
|
||||
free_mode_context(&tree->vertical[1], num_planes);
|
||||
}
|
||||
|
||||
// This function sets up a tree of contexts such that at each square
|
||||
|
|
@ -197,65 +129,25 @@ static void free_tree_contexts(PC_TREE *tree) {
|
|||
// represents the state of our search.
|
||||
void av1_setup_pc_tree(AV1_COMMON *cm, ThreadData *td) {
|
||||
int i, j;
|
||||
#if CONFIG_CB4X4
|
||||
#if CONFIG_EXT_PARTITION
|
||||
const int tree_nodes_inc = 1024;
|
||||
#else
|
||||
const int tree_nodes_inc = 256;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
const int leaf_factor = 4;
|
||||
#else
|
||||
const int tree_nodes_inc = 0;
|
||||
const int leaf_factor = 1;
|
||||
#endif
|
||||
#if CONFIG_EXT_PARTITION
|
||||
const int leaf_nodes = 256 * leaf_factor;
|
||||
const int tree_nodes = tree_nodes_inc + 256 + 64 + 16 + 4 + 1;
|
||||
#else
|
||||
const int leaf_nodes = 64 * leaf_factor;
|
||||
const int tree_nodes = tree_nodes_inc + 64 + 16 + 4 + 1;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
int pc_tree_index = 0;
|
||||
PC_TREE *this_pc;
|
||||
int square_index = 1;
|
||||
int nodes;
|
||||
|
||||
#if !CONFIG_CB4X4
|
||||
aom_free(td->leaf_tree);
|
||||
CHECK_MEM_ERROR(cm, td->leaf_tree,
|
||||
aom_calloc(leaf_nodes, sizeof(*td->leaf_tree)));
|
||||
PICK_MODE_CONTEXT *this_leaf = &td->leaf_tree[0];
|
||||
#endif
|
||||
aom_free(td->pc_tree);
|
||||
CHECK_MEM_ERROR(cm, td->pc_tree,
|
||||
aom_calloc(tree_nodes, sizeof(*td->pc_tree)));
|
||||
this_pc = &td->pc_tree[0];
|
||||
|
||||
#if !CONFIG_CB4X4
|
||||
// 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same
|
||||
// context so we only need to allocate 1 for each 8x8 block.
|
||||
for (i = 0; i < leaf_nodes; ++i) {
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
alloc_mode_context(cm, 4, PARTITION_NONE, &td->leaf_tree[i]);
|
||||
#else
|
||||
alloc_mode_context(cm, 16, &td->leaf_tree[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sets up all the leaf nodes in the tree.
|
||||
for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) {
|
||||
PC_TREE *const tree = &td->pc_tree[pc_tree_index];
|
||||
tree->block_size = square[0];
|
||||
#if CONFIG_CB4X4
|
||||
alloc_tree_contexts(cm, tree, 16);
|
||||
#else
|
||||
alloc_tree_contexts(cm, tree, 4);
|
||||
#endif
|
||||
#if !CONFIG_CB4X4
|
||||
tree->leaf_split[0] = this_leaf++;
|
||||
for (j = 1; j < 4; j++) tree->leaf_split[j] = tree->leaf_split[0];
|
||||
#endif
|
||||
alloc_tree_contexts(cm, tree, 16, 1);
|
||||
}
|
||||
|
||||
// Each node has 4 leaf nodes, fill each block_size level of the tree
|
||||
|
|
@ -263,11 +155,7 @@ void av1_setup_pc_tree(AV1_COMMON *cm, ThreadData *td) {
|
|||
for (nodes = leaf_nodes >> 2; nodes > 0; nodes >>= 2) {
|
||||
for (i = 0; i < nodes; ++i) {
|
||||
PC_TREE *const tree = &td->pc_tree[pc_tree_index];
|
||||
#if CONFIG_CB4X4
|
||||
alloc_tree_contexts(cm, tree, 16 << (2 * square_index));
|
||||
#else
|
||||
alloc_tree_contexts(cm, tree, 4 << (2 * square_index));
|
||||
#endif
|
||||
alloc_tree_contexts(cm, tree, 16 << (2 * square_index), 0);
|
||||
tree->block_size = square[square_index];
|
||||
for (j = 0; j < 4; j++) tree->split[j] = this_pc++;
|
||||
++pc_tree_index;
|
||||
|
|
@ -286,35 +174,41 @@ void av1_setup_pc_tree(AV1_COMMON *cm, ThreadData *td) {
|
|||
}
|
||||
}
|
||||
|
||||
void av1_free_pc_tree(ThreadData *td) {
|
||||
#if CONFIG_CB4X4
|
||||
#if CONFIG_EXT_PARTITION
|
||||
void av1_free_pc_tree(ThreadData *td, const int num_planes) {
|
||||
const int tree_nodes_inc = 1024;
|
||||
#else
|
||||
const int tree_nodes_inc = 256;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
#else
|
||||
const int tree_nodes_inc = 0;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_PARTITION
|
||||
const int tree_nodes = tree_nodes_inc + 256 + 64 + 16 + 4 + 1;
|
||||
#else
|
||||
const int tree_nodes = tree_nodes_inc + 64 + 16 + 4 + 1;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
int i;
|
||||
for (i = 0; i < tree_nodes; ++i) free_tree_contexts(&td->pc_tree[i]);
|
||||
for (i = 0; i < tree_nodes; ++i)
|
||||
free_tree_contexts(&td->pc_tree[i], num_planes);
|
||||
aom_free(td->pc_tree);
|
||||
td->pc_tree = NULL;
|
||||
#if !CONFIG_CB4X4
|
||||
const int leaf_factor = 1;
|
||||
#if CONFIG_EXT_PARTITION
|
||||
const int leaf_nodes = 256 * leaf_factor;
|
||||
#else
|
||||
const int leaf_nodes = 64 * leaf_factor;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
for (i = 0; i < leaf_nodes; ++i) free_mode_context(&td->leaf_tree[i]);
|
||||
aom_free(td->leaf_tree);
|
||||
td->leaf_tree = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
|
||||
PICK_MODE_CONTEXT *src_ctx) {
|
||||
dst_ctx->mic = src_ctx->mic;
|
||||
dst_ctx->mbmi_ext = src_ctx->mbmi_ext;
|
||||
|
||||
dst_ctx->num_4x4_blk = src_ctx->num_4x4_blk;
|
||||
dst_ctx->skip = src_ctx->skip;
|
||||
dst_ctx->skippable = src_ctx->skippable;
|
||||
dst_ctx->best_mode_index = src_ctx->best_mode_index;
|
||||
|
||||
memcpy(dst_ctx->blk_skip, src_ctx->blk_skip,
|
||||
sizeof(uint8_t) * src_ctx->num_4x4_blk);
|
||||
|
||||
dst_ctx->hybrid_pred_diff = src_ctx->hybrid_pred_diff;
|
||||
dst_ctx->comp_pred_diff = src_ctx->comp_pred_diff;
|
||||
dst_ctx->single_pred_diff = src_ctx->single_pred_diff;
|
||||
|
||||
dst_ctx->rate = src_ctx->rate;
|
||||
dst_ctx->dist = src_ctx->dist;
|
||||
dst_ctx->rdcost = src_ctx->rdcost;
|
||||
dst_ctx->rd_mode_is_ready = src_ctx->rd_mode_is_ready;
|
||||
|
||||
memcpy(dst_ctx->pred_mv, src_ctx->pred_mv, sizeof(MV) * REF_FRAMES);
|
||||
dst_ctx->pred_interp_filter = src_ctx->pred_interp_filter;
|
||||
|
||||
dst_ctx->partition = src_ctx->partition;
|
||||
}
|
||||
|
|
|
|||
67
third_party/aom/av1/encoder/context_tree.h
vendored
67
third_party/aom/av1/encoder/context_tree.h
vendored
|
|
@ -23,28 +23,29 @@ struct AV1_COMP;
|
|||
struct AV1Common;
|
||||
struct ThreadData;
|
||||
|
||||
typedef enum {
|
||||
// Search all the partition types in this plane.
|
||||
SEARCH_FULL_PLANE = 0,
|
||||
// Only search none_partition coding block.
|
||||
NONE_PARTITION_PLANE = 1,
|
||||
// Search all the partition types in this plane except split.
|
||||
SEARCH_SAME_PLANE = 2,
|
||||
// Skip search partition on this plane. Go split directly.
|
||||
SPLIT_PLANE = 3,
|
||||
} CB_TREE_SEARCH;
|
||||
|
||||
// Structure to hold snapshot of coding context during the mode picking process
|
||||
typedef struct {
|
||||
MODE_INFO mic;
|
||||
MB_MODE_INFO mic;
|
||||
MB_MODE_INFO_EXT mbmi_ext;
|
||||
uint8_t *color_index_map[2];
|
||||
#if CONFIG_MRC_TX
|
||||
uint8_t *mrc_mask;
|
||||
#endif // CONFIG_MRC_TX
|
||||
#if CONFIG_VAR_TX
|
||||
uint8_t *blk_skip[MAX_MB_PLANE];
|
||||
#endif
|
||||
uint8_t *blk_skip;
|
||||
|
||||
tran_low_t *coeff[MAX_MB_PLANE];
|
||||
tran_low_t *qcoeff[MAX_MB_PLANE];
|
||||
tran_low_t *dqcoeff[MAX_MB_PLANE];
|
||||
#if CONFIG_PVQ
|
||||
tran_low_t *pvq_ref_coeff[MAX_MB_PLANE];
|
||||
#endif
|
||||
uint16_t *eobs[MAX_MB_PLANE];
|
||||
#if CONFIG_LV_MAP
|
||||
uint8_t *txb_entropy_ctx[MAX_MB_PLANE];
|
||||
#endif
|
||||
|
||||
int num_4x4_blk;
|
||||
int skip;
|
||||
|
|
@ -60,16 +61,27 @@ typedef struct {
|
|||
// scope of refactoring.
|
||||
int rate;
|
||||
int64_t dist;
|
||||
int64_t rdcost;
|
||||
int rd_mode_is_ready; // Flag to indicate whether rd pick mode decision has
|
||||
// been made.
|
||||
|
||||
// motion vector cache for adaptive motion search control in partition
|
||||
// search loop
|
||||
MV pred_mv[TOTAL_REFS_PER_FRAME];
|
||||
MV pred_mv[REF_FRAMES];
|
||||
InterpFilter pred_interp_filter;
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
PARTITION_TYPE partition;
|
||||
#endif
|
||||
} PICK_MODE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
int valid;
|
||||
int split;
|
||||
int skip;
|
||||
int64_t rdcost;
|
||||
int sub_block_split[4];
|
||||
int sub_block_skip[4];
|
||||
int64_t sub_block_rdcost[4];
|
||||
} PC_TREE_STATS;
|
||||
|
||||
typedef struct PC_TREE {
|
||||
int index;
|
||||
PARTITION_TYPE partitioning;
|
||||
|
|
@ -77,34 +89,21 @@ typedef struct PC_TREE {
|
|||
PICK_MODE_CONTEXT none;
|
||||
PICK_MODE_CONTEXT horizontal[2];
|
||||
PICK_MODE_CONTEXT vertical[2];
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
PICK_MODE_CONTEXT horizontala[3];
|
||||
PICK_MODE_CONTEXT horizontalb[3];
|
||||
PICK_MODE_CONTEXT verticala[3];
|
||||
PICK_MODE_CONTEXT verticalb[3];
|
||||
PICK_MODE_CONTEXT horizontal4[4];
|
||||
PICK_MODE_CONTEXT vertical4[4];
|
||||
#endif
|
||||
// TODO(jingning): remove leaf_split[] when cb4x4 experiment flag is removed.
|
||||
union {
|
||||
struct PC_TREE *split[4];
|
||||
PICK_MODE_CONTEXT *leaf_split[4];
|
||||
};
|
||||
#if CONFIG_SUPERTX
|
||||
PICK_MODE_CONTEXT horizontal_supertx;
|
||||
PICK_MODE_CONTEXT vertical_supertx;
|
||||
PICK_MODE_CONTEXT split_supertx;
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
PICK_MODE_CONTEXT horizontala_supertx;
|
||||
PICK_MODE_CONTEXT horizontalb_supertx;
|
||||
PICK_MODE_CONTEXT verticala_supertx;
|
||||
PICK_MODE_CONTEXT verticalb_supertx;
|
||||
#endif
|
||||
#endif
|
||||
CB_TREE_SEARCH cb_search_range;
|
||||
struct PC_TREE *split[4];
|
||||
PC_TREE_STATS pc_tree_stats;
|
||||
} PC_TREE;
|
||||
|
||||
void av1_setup_pc_tree(struct AV1Common *cm, struct ThreadData *td);
|
||||
void av1_free_pc_tree(struct ThreadData *td);
|
||||
void av1_free_pc_tree(struct ThreadData *td, const int num_planes);
|
||||
void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
|
||||
PICK_MODE_CONTEXT *src_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
3
third_party/aom/av1/encoder/corner_match.c
vendored
3
third_party/aom/av1/encoder/corner_match.c
vendored
|
|
@ -13,7 +13,8 @@
|
|||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
|
||||
#include "av1/encoder/corner_match.h"
|
||||
|
||||
#define SEARCH_SZ 9
|
||||
|
|
|
|||
65
third_party/aom/av1/encoder/cost.c
vendored
65
third_party/aom/av1/encoder/cost.c
vendored
|
|
@ -13,65 +13,26 @@
|
|||
#include "av1/encoder/cost.h"
|
||||
#include "av1/common/entropy.h"
|
||||
|
||||
/* round(-log2(i/256.) * (1 << AV1_PROB_COST_SHIFT))
|
||||
Begins with a bogus entry for simpler addressing. */
|
||||
const uint16_t av1_prob_cost[256] = {
|
||||
4096, 4096, 3584, 3284, 3072, 2907, 2772, 2659, 2560, 2473, 2395, 2325, 2260,
|
||||
2201, 2147, 2096, 2048, 2003, 1961, 1921, 1883, 1847, 1813, 1780, 1748, 1718,
|
||||
1689, 1661, 1635, 1609, 1584, 1559, 1536, 1513, 1491, 1470, 1449, 1429, 1409,
|
||||
1390, 1371, 1353, 1335, 1318, 1301, 1284, 1268, 1252, 1236, 1221, 1206, 1192,
|
||||
1177, 1163, 1149, 1136, 1123, 1110, 1097, 1084, 1072, 1059, 1047, 1036, 1024,
|
||||
1013, 1001, 990, 979, 968, 958, 947, 937, 927, 917, 907, 897, 887,
|
||||
878, 868, 859, 850, 841, 832, 823, 814, 806, 797, 789, 780, 772,
|
||||
764, 756, 748, 740, 732, 724, 717, 709, 702, 694, 687, 680, 673,
|
||||
665, 658, 651, 644, 637, 631, 624, 617, 611, 604, 598, 591, 585,
|
||||
578, 572, 566, 560, 554, 547, 541, 535, 530, 524, 518, 512, 506,
|
||||
501, 495, 489, 484, 478, 473, 467, 462, 456, 451, 446, 441, 435,
|
||||
430, 425, 420, 415, 410, 405, 400, 395, 390, 385, 380, 375, 371,
|
||||
366, 361, 356, 352, 347, 343, 338, 333, 329, 324, 320, 316, 311,
|
||||
307, 302, 298, 294, 289, 285, 281, 277, 273, 268, 264, 260, 256,
|
||||
252, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 209, 205,
|
||||
201, 197, 194, 190, 186, 182, 179, 175, 171, 168, 164, 161, 157,
|
||||
153, 150, 146, 143, 139, 136, 132, 129, 125, 122, 119, 115, 112,
|
||||
109, 105, 102, 99, 95, 92, 89, 86, 82, 79, 76, 73, 70,
|
||||
66, 63, 60, 57, 54, 51, 48, 45, 42, 38, 35, 32, 29,
|
||||
26, 23, 20, 18, 15, 12, 9, 6, 3
|
||||
// round(-log2(i/256.) * (1 << AV1_PROB_COST_SHIFT)); i = 128~255.
|
||||
const uint16_t av1_prob_cost[128] = {
|
||||
512, 506, 501, 495, 489, 484, 478, 473, 467, 462, 456, 451, 446, 441, 435,
|
||||
430, 425, 420, 415, 410, 405, 400, 395, 390, 385, 380, 375, 371, 366, 361,
|
||||
356, 352, 347, 343, 338, 333, 329, 324, 320, 316, 311, 307, 302, 298, 294,
|
||||
289, 285, 281, 277, 273, 268, 264, 260, 256, 252, 248, 244, 240, 236, 232,
|
||||
228, 224, 220, 216, 212, 209, 205, 201, 197, 194, 190, 186, 182, 179, 175,
|
||||
171, 168, 164, 161, 157, 153, 150, 146, 143, 139, 136, 132, 129, 125, 122,
|
||||
119, 115, 112, 109, 105, 102, 99, 95, 92, 89, 86, 82, 79, 76, 73,
|
||||
70, 66, 63, 60, 57, 54, 51, 48, 45, 42, 38, 35, 32, 29, 26,
|
||||
23, 20, 18, 15, 12, 9, 6, 3,
|
||||
};
|
||||
|
||||
static void cost(int *costs, aom_tree tree, const aom_prob *probs, int i,
|
||||
int c) {
|
||||
const aom_prob prob = probs[i / 2];
|
||||
int b;
|
||||
|
||||
assert(prob != 0);
|
||||
for (b = 0; b <= 1; ++b) {
|
||||
const int cc = c + av1_cost_bit(prob, b);
|
||||
const aom_tree_index ii = tree[i + b];
|
||||
|
||||
if (ii <= 0)
|
||||
costs[-ii] = cc;
|
||||
else
|
||||
cost(costs, tree, probs, ii, cc);
|
||||
}
|
||||
}
|
||||
|
||||
void av1_cost_tokens(int *costs, const aom_prob *probs, aom_tree tree) {
|
||||
cost(costs, tree, probs, 0, 0);
|
||||
}
|
||||
|
||||
void av1_cost_tokens_skip(int *costs, const aom_prob *probs, aom_tree tree) {
|
||||
assert(tree[0] <= 0 && tree[1] > 0);
|
||||
|
||||
costs[-tree[0]] = av1_cost_bit(probs[0], 0);
|
||||
cost(costs, tree, probs, 2, 0);
|
||||
}
|
||||
|
||||
void av1_cost_tokens_from_cdf(int *costs, const aom_cdf_prob *cdf,
|
||||
const int *inv_map) {
|
||||
int i;
|
||||
aom_cdf_prob prev_cdf = 0;
|
||||
for (i = 0;; ++i) {
|
||||
const aom_cdf_prob p15 = AOM_ICDF(cdf[i]) - prev_cdf;
|
||||
aom_cdf_prob p15 = AOM_ICDF(cdf[i]) - prev_cdf;
|
||||
p15 = (p15 < EC_MIN_PROB) ? EC_MIN_PROB : p15;
|
||||
prev_cdf = AOM_ICDF(cdf[i]);
|
||||
|
||||
if (inv_map)
|
||||
|
|
|
|||
34
third_party/aom/av1/encoder/cost.h
vendored
34
third_party/aom/av1/encoder/cost.h
vendored
|
|
@ -19,17 +19,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const uint16_t av1_prob_cost[256];
|
||||
extern const uint16_t av1_prob_cost[128];
|
||||
|
||||
// The factor to scale from cost in bits to cost in av1_prob_cost units.
|
||||
#define AV1_PROB_COST_SHIFT 9
|
||||
|
||||
#define av1_cost_zero(prob) (av1_prob_cost[prob])
|
||||
|
||||
#define av1_cost_one(prob) av1_cost_zero(256 - (prob))
|
||||
|
||||
#define av1_cost_bit(prob, bit) av1_cost_zero((bit) ? 256 - (prob) : (prob))
|
||||
|
||||
// Cost of coding an n bit literal, using 128 (i.e. 50%) probability
|
||||
// for each bit.
|
||||
#define av1_cost_literal(n) ((n) * (1 << AV1_PROB_COST_SHIFT))
|
||||
|
|
@ -38,31 +32,11 @@ extern const uint16_t av1_prob_cost[256];
|
|||
static INLINE int av1_cost_symbol(aom_cdf_prob p15) {
|
||||
assert(0 < p15 && p15 < CDF_PROB_TOP);
|
||||
const int shift = CDF_PROB_BITS - 1 - get_msb(p15);
|
||||
return av1_cost_zero(get_prob(p15 << shift, CDF_PROB_TOP)) +
|
||||
av1_cost_literal(shift);
|
||||
const int prob = get_prob(p15 << shift, CDF_PROB_TOP);
|
||||
assert(prob >= 128);
|
||||
return av1_prob_cost[prob - 128] + av1_cost_literal(shift);
|
||||
}
|
||||
|
||||
static INLINE unsigned int cost_branch256(const unsigned int ct[2],
|
||||
aom_prob p) {
|
||||
return ct[0] * av1_cost_zero(p) + ct[1] * av1_cost_one(p);
|
||||
}
|
||||
|
||||
static INLINE int treed_cost(aom_tree tree, const aom_prob *probs, int bits,
|
||||
int len) {
|
||||
int cost = 0;
|
||||
aom_tree_index i = 0;
|
||||
|
||||
do {
|
||||
const int bit = (bits >> --len) & 1;
|
||||
cost += av1_cost_bit(probs[i >> 1], bit);
|
||||
i = tree[i + bit];
|
||||
} while (len);
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
void av1_cost_tokens(int *costs, const aom_prob *probs, aom_tree tree);
|
||||
void av1_cost_tokens_skip(int *costs, const aom_prob *probs, aom_tree tree);
|
||||
void av1_cost_tokens_from_cdf(int *costs, const aom_cdf_prob *cdf,
|
||||
const int *inv_map);
|
||||
|
||||
|
|
|
|||
30
third_party/aom/av1/encoder/daala_compat_enc.c
vendored
30
third_party/aom/av1/encoder/daala_compat_enc.c
vendored
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "encint.h"
|
||||
|
||||
void od_encode_checkpoint(const daala_enc_ctx *enc, od_rollback_buffer *rbuf) {
|
||||
#if !CONFIG_ANS
|
||||
od_ec_enc_checkpoint(&rbuf->ec, &enc->w.ec);
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
OD_COPY(&rbuf->adapt, enc->state.adapt, 1);
|
||||
}
|
||||
|
||||
void od_encode_rollback(daala_enc_ctx *enc, const od_rollback_buffer *rbuf) {
|
||||
#if !CONFIG_ANS
|
||||
od_ec_enc_rollback(&enc->w.ec, &rbuf->ec);
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
OD_COPY(enc->state.adapt, &rbuf->adapt, 1);
|
||||
}
|
||||
2797
third_party/aom/av1/encoder/dct.c
vendored
2797
third_party/aom/av1/encoder/dct.c
vendored
File diff suppressed because it is too large
Load diff
144
third_party/aom/av1/encoder/dwt.c
vendored
Normal file
144
third_party/aom/av1/encoder/dwt.c
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "config/av1_rtcd.h"
|
||||
#include "av1/encoder/dwt.h"
|
||||
|
||||
// Note: block length must be even for this implementation
|
||||
static void analysis_53_row(int length, tran_low_t *x, tran_low_t *lowpass,
|
||||
tran_low_t *highpass) {
|
||||
int n;
|
||||
tran_low_t r, *a, *b;
|
||||
|
||||
n = length >> 1;
|
||||
b = highpass;
|
||||
a = lowpass;
|
||||
while (--n) {
|
||||
*a++ = (r = *x++) * 2;
|
||||
*b++ = *x - ((r + x[1] + 1) >> 1);
|
||||
x++;
|
||||
}
|
||||
*a = (r = *x++) * 2;
|
||||
*b = *x - r;
|
||||
|
||||
n = length >> 1;
|
||||
b = highpass;
|
||||
a = lowpass;
|
||||
r = *highpass;
|
||||
while (n--) {
|
||||
*a++ += (r + (*b) + 1) >> 1;
|
||||
r = *b++;
|
||||
}
|
||||
}
|
||||
|
||||
static void analysis_53_col(int length, tran_low_t *x, tran_low_t *lowpass,
|
||||
tran_low_t *highpass) {
|
||||
int n;
|
||||
tran_low_t r, *a, *b;
|
||||
|
||||
n = length >> 1;
|
||||
b = highpass;
|
||||
a = lowpass;
|
||||
while (--n) {
|
||||
*a++ = (r = *x++);
|
||||
*b++ = (((*x) * 2) - (r + x[1]) + 2) >> 2;
|
||||
x++;
|
||||
}
|
||||
*a = (r = *x++);
|
||||
*b = (*x - r + 1) >> 1;
|
||||
|
||||
n = length >> 1;
|
||||
b = highpass;
|
||||
a = lowpass;
|
||||
r = *highpass;
|
||||
while (n--) {
|
||||
*a++ += (r + (*b) + 1) >> 1;
|
||||
r = *b++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dyadic_analyze_53_uint8_input(int levels, int width, int height,
|
||||
uint8_t *x, int pitch_x,
|
||||
tran_low_t *c, int pitch_c,
|
||||
int dwt_scale_bits, int hbd) {
|
||||
int lv, i, j, nh, nw, hh = height, hw = width;
|
||||
tran_low_t buffer[2 * DWT_MAX_LENGTH];
|
||||
|
||||
if (hbd) {
|
||||
uint16_t *x16 = CONVERT_TO_SHORTPTR(x);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
c[i * pitch_c + j] = x16[i * pitch_x + j] << dwt_scale_bits;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
c[i * pitch_c + j] = x[i * pitch_x + j] << dwt_scale_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (lv = 0; lv < levels; lv++) {
|
||||
nh = hh;
|
||||
hh = (hh + 1) >> 1;
|
||||
nw = hw;
|
||||
hw = (hw + 1) >> 1;
|
||||
if ((nh < 2) || (nw < 2)) return;
|
||||
for (i = 0; i < nh; i++) {
|
||||
memcpy(buffer, &c[i * pitch_c], nw * sizeof(tran_low_t));
|
||||
analysis_53_row(nw, buffer, &c[i * pitch_c], &c[i * pitch_c] + hw);
|
||||
}
|
||||
for (j = 0; j < nw; j++) {
|
||||
for (i = 0; i < nh; i++) buffer[i + nh] = c[i * pitch_c + j];
|
||||
analysis_53_col(nh, buffer + nh, buffer, buffer + hh);
|
||||
for (i = 0; i < nh; i++) c[i * pitch_c + j] = buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void av1_fdwt8x8_uint8_input_c(uint8_t *input, tran_low_t *output, int stride,
|
||||
int hbd) {
|
||||
dyadic_analyze_53_uint8_input(4, 8, 8, input, stride, output, 8, 2, hbd);
|
||||
}
|
||||
|
||||
int av1_haar_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
|
||||
int acsad = 0;
|
||||
|
||||
for (int r = 0; r < bh; ++r)
|
||||
for (int c = 0; c < bw; ++c) {
|
||||
if (r >= bh / 2 || c >= bw / 2) acsad += abs(output[r * stride + c]);
|
||||
}
|
||||
return acsad;
|
||||
}
|
||||
|
||||
uint64_t av1_dct_ac_sad(tran_low_t *output, int bw, int bh, int stride) {
|
||||
uint64_t acsad = 0;
|
||||
|
||||
for (int r = 0; r < bh; ++r)
|
||||
for (int c = 0; c < bw; ++c) {
|
||||
if (r > 0 || c > 0) acsad += abs(output[r * stride + c]);
|
||||
}
|
||||
|
||||
return acsad;
|
||||
}
|
||||
|
||||
uint32_t av1_variance(uint8_t *input, int bw, int bh, int stride) {
|
||||
int sum = 0;
|
||||
uint32_t sse = 0;
|
||||
|
||||
for (int r = 0; r < bh; ++r)
|
||||
for (int c = 0; c < bw; ++c) {
|
||||
sum += input[r * stride + c];
|
||||
sse += input[r * stride + c] * input[r * stride + c];
|
||||
}
|
||||
return sse - (uint32_t)(((int64_t)sum * sum) / (bw * bh));
|
||||
}
|
||||
|
||||
int av1_haar_ac_sad_8x8_uint8_input(uint8_t *input, int stride, int hbd) {
|
||||
tran_low_t output[64];
|
||||
|
||||
av1_fdwt8x8_uint8_input_c(input, output, stride, hbd);
|
||||
return av1_haar_ac_sad(output, 8, 8, 8);
|
||||
}
|
||||
9
third_party/aom/av1/encoder/dwt.h
vendored
Normal file
9
third_party/aom/av1/encoder/dwt.h
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "av1/common/common.h"
|
||||
#include "av1/common/enums.h"
|
||||
|
||||
#define DWT_MAX_LENGTH 64
|
||||
|
||||
void av1_fdwt8x8(tran_low_t *input, tran_low_t *output, int stride);
|
||||
void av1_fdwt8x8_uint8_input_c(uint8_t *input, tran_low_t *output, int stride,
|
||||
int hbd);
|
||||
int av1_haar_ac_sad_8x8_uint8_input(uint8_t *input, int stride, int hbd);
|
||||
51
third_party/aom/av1/encoder/encint.h
vendored
51
third_party/aom/av1/encoder/encint.h
vendored
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
/* clang-format off */
|
||||
|
||||
#if !defined(_encint_H)
|
||||
# define _encint_H (1)
|
||||
|
||||
typedef struct daala_enc_ctx od_enc_ctx;
|
||||
typedef struct od_params_ctx od_params_ctx;
|
||||
typedef struct od_rollback_buffer od_rollback_buffer;
|
||||
|
||||
# include "aom_dsp/entenc.h"
|
||||
# include "av1/common/odintrin.h"
|
||||
# include "av1/common/pvq_state.h"
|
||||
|
||||
struct daala_enc_ctx{
|
||||
/* Stores context-adaptive CDFs for PVQ. */
|
||||
od_state state;
|
||||
/* AOM entropy encoder. */
|
||||
aom_writer w;
|
||||
int use_activity_masking;
|
||||
/* Mode of quantization matrice : FLAT (0) or HVS (1) */
|
||||
int qm;
|
||||
/*Normalized PVQ lambda for use where we've already performed
|
||||
quantization.*/
|
||||
double pvq_norm_lambda;
|
||||
double pvq_norm_lambda_dc;
|
||||
};
|
||||
|
||||
// from daalaenc.h
|
||||
/**The encoder context.*/
|
||||
typedef struct daala_enc_ctx daala_enc_ctx;
|
||||
|
||||
/** Holds important encoder information so we can roll back decisions */
|
||||
struct od_rollback_buffer {
|
||||
od_ec_enc ec;
|
||||
od_adapt_ctx adapt;
|
||||
};
|
||||
|
||||
void od_encode_checkpoint(const daala_enc_ctx *enc, od_rollback_buffer *rbuf);
|
||||
void od_encode_rollback(daala_enc_ctx *enc, const od_rollback_buffer *rbuf);
|
||||
|
||||
#endif
|
||||
7670
third_party/aom/av1/encoder/encodeframe.c
vendored
7670
third_party/aom/av1/encoder/encodeframe.c
vendored
File diff suppressed because it is too large
Load diff
10
third_party/aom/av1/encoder/encodeframe.h
vendored
10
third_party/aom/av1/encoder/encodeframe.h
vendored
|
|
@ -20,6 +20,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DELTAQ_MODULATION 0 // 0: variance based, 1: wavelet AC energy based
|
||||
|
||||
struct macroblock;
|
||||
struct yv12_buffer_config;
|
||||
struct AV1_COMP;
|
||||
|
|
@ -27,7 +29,7 @@ struct ThreadData;
|
|||
|
||||
void av1_setup_src_planes(struct macroblock *x,
|
||||
const struct yv12_buffer_config *src, int mi_row,
|
||||
int mi_col);
|
||||
int mi_col, const int num_planes);
|
||||
|
||||
void av1_encode_frame(struct AV1_COMP *cpi);
|
||||
|
||||
|
|
@ -35,12 +37,6 @@ void av1_init_tile_data(struct AV1_COMP *cpi);
|
|||
void av1_encode_tile(struct AV1_COMP *cpi, struct ThreadData *td, int tile_row,
|
||||
int tile_col);
|
||||
|
||||
void av1_update_tx_type_count(const struct AV1Common *cm, MACROBLOCKD *xd,
|
||||
#if CONFIG_TXK_SEL
|
||||
int blk_row, int blk_col, int block, int plane,
|
||||
#endif
|
||||
BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
FRAME_COUNTS *counts);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
1209
third_party/aom/av1/encoder/encodemb.c
vendored
1209
third_party/aom/av1/encoder/encodemb.c
vendored
File diff suppressed because it is too large
Load diff
57
third_party/aom/av1/encoder/encodemb.h
vendored
57
third_party/aom/av1/encoder/encodemb.h
vendored
|
|
@ -12,21 +12,23 @@
|
|||
#ifndef AV1_ENCODER_ENCODEMB_H_
|
||||
#define AV1_ENCODER_ENCODEMB_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/encoder/block.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/common/txb_common.h"
|
||||
#include "av1/encoder/block.h"
|
||||
#include "av1/encoder/tokenize.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct optimize_ctx {
|
||||
ENTROPY_CONTEXT ta[MAX_MB_PLANE][2 * MAX_MIB_SIZE];
|
||||
ENTROPY_CONTEXT tl[MAX_MB_PLANE][2 * MAX_MIB_SIZE];
|
||||
ENTROPY_CONTEXT ta[MAX_MB_PLANE][MAX_MIB_SIZE];
|
||||
ENTROPY_CONTEXT tl[MAX_MB_PLANE][MAX_MIB_SIZE];
|
||||
};
|
||||
|
||||
struct encode_b_args {
|
||||
AV1_COMMON *cm;
|
||||
const struct AV1_COMP *cpi;
|
||||
MACROBLOCK *x;
|
||||
struct optimize_ctx *ctx;
|
||||
int8_t *skip;
|
||||
|
|
@ -43,52 +45,39 @@ typedef enum AV1_XFORM_QUANT {
|
|||
AV1_XFORM_QUANT_TYPES,
|
||||
} AV1_XFORM_QUANT;
|
||||
|
||||
void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row,
|
||||
int mi_col);
|
||||
#if CONFIG_SUPERTX
|
||||
void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize);
|
||||
#endif // CONFIG_SUPERTX
|
||||
void av1_encode_sb(const struct AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, RUN_TYPE dry_run);
|
||||
void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize);
|
||||
void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
|
||||
int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, int ctx, AV1_XFORM_QUANT xform_quant_idx);
|
||||
TX_SIZE tx_size, TX_TYPE tx_type,
|
||||
AV1_XFORM_QUANT xform_quant_idx);
|
||||
|
||||
int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int blk_row,
|
||||
int blk_col, int block, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
|
||||
const ENTROPY_CONTEXT *l, int fast_mode);
|
||||
int av1_optimize_b(const struct AV1_COMP *cpi, MACROBLOCK *mb, int plane,
|
||||
int block, TX_SIZE tx_size, TX_TYPE tx_type,
|
||||
const TXB_CTX *const txb_ctx, int fast_mode, int *rate_cost);
|
||||
|
||||
void av1_subtract_txb(MACROBLOCK *x, int plane, BLOCK_SIZE plane_bsize,
|
||||
int blk_col, int blk_row, TX_SIZE tx_size);
|
||||
|
||||
void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
|
||||
|
||||
#if !CONFIG_PVQ
|
||||
void av1_set_txb_context(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size,
|
||||
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l);
|
||||
#endif
|
||||
static INLINE void av1_set_txb_context(MACROBLOCK *x, int plane, int block,
|
||||
TX_SIZE tx_size, ENTROPY_CONTEXT *a,
|
||||
ENTROPY_CONTEXT *l) {
|
||||
const uint8_t ctx = x->plane[plane].txb_entropy_ctx[block];
|
||||
memset(a, ctx, tx_size_wide_unit[tx_size] * sizeof(*a));
|
||||
memset(l, ctx, tx_size_high_unit[tx_size] * sizeof(*l));
|
||||
}
|
||||
|
||||
void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg);
|
||||
|
||||
void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
|
||||
void av1_encode_intra_block_plane(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bsize, int plane,
|
||||
int enable_optimize_b, int mi_row,
|
||||
int mi_col);
|
||||
|
||||
#if CONFIG_PVQ
|
||||
PVQ_SKIP_TYPE av1_pvq_encode_helper(MACROBLOCK *x, tran_low_t *const coeff,
|
||||
tran_low_t *ref_coeff,
|
||||
tran_low_t *const dqcoeff, uint16_t *eob,
|
||||
const int16_t *quant, int plane,
|
||||
TX_SIZE tx_size, TX_TYPE tx_type, int *rate,
|
||||
int speed, PVQ_INFO *pvq_info);
|
||||
|
||||
void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta, int *k,
|
||||
od_coeff *y, int nb_bands, const int *off,
|
||||
int *size, int skip_rest, int skip_dir, int bs);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
346
third_party/aom/av1/encoder/encodemv.c
vendored
346
third_party/aom/av1/encoder/encodemv.c
vendored
|
|
@ -16,20 +16,9 @@
|
|||
|
||||
#include "av1/encoder/cost.h"
|
||||
#include "av1/encoder/encodemv.h"
|
||||
#include "av1/encoder/subexp.h"
|
||||
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
|
||||
static struct av1_token mv_joint_encodings[MV_JOINTS];
|
||||
static struct av1_token mv_class_encodings[MV_CLASSES];
|
||||
static struct av1_token mv_fp_encodings[MV_FP_SIZE];
|
||||
|
||||
void av1_entropy_mv_init(void) {
|
||||
av1_tokens_from_tree(mv_joint_encodings, av1_mv_joint_tree);
|
||||
av1_tokens_from_tree(mv_class_encodings, av1_mv_class_tree);
|
||||
av1_tokens_from_tree(mv_fp_encodings, av1_mv_fp_tree);
|
||||
}
|
||||
|
||||
static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
|
||||
MvSubpelPrecision precision) {
|
||||
int offset;
|
||||
|
|
@ -42,38 +31,23 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
|
|||
|
||||
assert(comp != 0);
|
||||
|
||||
// Sign
|
||||
#if CONFIG_NEW_MULTISYMBOL
|
||||
aom_write_bit(w, sign);
|
||||
#else
|
||||
aom_write(w, sign, mvcomp->sign);
|
||||
#endif
|
||||
// Sign
|
||||
aom_write_symbol(w, sign, mvcomp->sign_cdf, 2);
|
||||
|
||||
// Class
|
||||
aom_write_symbol(w, mv_class, mvcomp->class_cdf, MV_CLASSES);
|
||||
aom_write_symbol(w, mv_class, mvcomp->classes_cdf, MV_CLASSES);
|
||||
|
||||
// Integer bits
|
||||
if (mv_class == MV_CLASS_0) {
|
||||
#if CONFIG_NEW_MULTISYMBOL
|
||||
aom_write_symbol(w, d, mvcomp->class0_cdf, CLASS0_SIZE);
|
||||
#else
|
||||
aom_write(w, d, mvcomp->class0[0]);
|
||||
#endif
|
||||
} else {
|
||||
int i;
|
||||
const int n = mv_class + CLASS0_BITS - 1; // number of bits
|
||||
#if CONFIG_NEW_MULTISYMBOL
|
||||
for (i = 0; i < n; ++i)
|
||||
aom_write_symbol(w, (d >> i) & 1, mvcomp->bits_cdf[(i + 1) / 2], 2);
|
||||
#else
|
||||
for (i = 0; i < n; ++i) aom_write(w, (d >> i) & 1, mvcomp->bits[i]);
|
||||
#endif
|
||||
aom_write_symbol(w, (d >> i) & 1, mvcomp->bits_cdf[i], 2);
|
||||
}
|
||||
// Fractional bits
|
||||
#if CONFIG_INTRABC || CONFIG_AMVR
|
||||
if (precision > MV_SUBPEL_NONE)
|
||||
#endif // CONFIG_INTRABC || CONFIG_AMVR
|
||||
{
|
||||
// Fractional bits
|
||||
if (precision > MV_SUBPEL_NONE) {
|
||||
aom_write_symbol(
|
||||
w, fr,
|
||||
mv_class == MV_CLASS_0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
|
||||
|
|
@ -82,13 +56,9 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
|
|||
|
||||
// High precision bit
|
||||
if (precision > MV_SUBPEL_LOW_PRECISION)
|
||||
#if CONFIG_NEW_MULTISYMBOL
|
||||
aom_write_symbol(
|
||||
w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp_cdf : mvcomp->hp_cdf,
|
||||
2);
|
||||
#else
|
||||
aom_write(w, hp, mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void build_nmv_component_cost_table(int *mvcost,
|
||||
|
|
@ -100,24 +70,20 @@ static void build_nmv_component_cost_table(int *mvcost,
|
|||
int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
|
||||
int class0_hp_cost[2], hp_cost[2];
|
||||
|
||||
sign_cost[0] = av1_cost_zero(mvcomp->sign);
|
||||
sign_cost[1] = av1_cost_one(mvcomp->sign);
|
||||
av1_cost_tokens(class_cost, mvcomp->classes, av1_mv_class_tree);
|
||||
av1_cost_tokens(class0_cost, mvcomp->class0, av1_mv_class0_tree);
|
||||
av1_cost_tokens_from_cdf(sign_cost, mvcomp->sign_cdf, NULL);
|
||||
av1_cost_tokens_from_cdf(class_cost, mvcomp->classes_cdf, NULL);
|
||||
av1_cost_tokens_from_cdf(class0_cost, mvcomp->class0_cdf, NULL);
|
||||
for (i = 0; i < MV_OFFSET_BITS; ++i) {
|
||||
bits_cost[i][0] = av1_cost_zero(mvcomp->bits[i]);
|
||||
bits_cost[i][1] = av1_cost_one(mvcomp->bits[i]);
|
||||
av1_cost_tokens_from_cdf(bits_cost[i], mvcomp->bits_cdf[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < CLASS0_SIZE; ++i)
|
||||
av1_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], av1_mv_fp_tree);
|
||||
av1_cost_tokens(fp_cost, mvcomp->fp, av1_mv_fp_tree);
|
||||
av1_cost_tokens_from_cdf(class0_fp_cost[i], mvcomp->class0_fp_cdf[i], NULL);
|
||||
av1_cost_tokens_from_cdf(fp_cost, mvcomp->fp_cdf, NULL);
|
||||
|
||||
if (precision > MV_SUBPEL_LOW_PRECISION) {
|
||||
class0_hp_cost[0] = av1_cost_zero(mvcomp->class0_hp);
|
||||
class0_hp_cost[1] = av1_cost_one(mvcomp->class0_hp);
|
||||
hp_cost[0] = av1_cost_zero(mvcomp->hp);
|
||||
hp_cost[1] = av1_cost_one(mvcomp->hp);
|
||||
av1_cost_tokens_from_cdf(class0_hp_cost, mvcomp->class0_hp_cdf, NULL);
|
||||
av1_cost_tokens_from_cdf(hp_cost, mvcomp->hp_cdf, NULL);
|
||||
}
|
||||
mvcost[0] = 0;
|
||||
for (v = 1; v <= MV_MAX; ++v) {
|
||||
|
|
@ -134,10 +100,7 @@ static void build_nmv_component_cost_table(int *mvcost,
|
|||
const int b = c + CLASS0_BITS - 1; /* number of bits */
|
||||
for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)];
|
||||
}
|
||||
#if CONFIG_INTRABC || CONFIG_AMVR
|
||||
if (precision > MV_SUBPEL_NONE)
|
||||
#endif // CONFIG_INTRABC || CONFIG_AMVR
|
||||
{
|
||||
if (precision > MV_SUBPEL_NONE) {
|
||||
if (c == MV_CLASS_0) {
|
||||
cost += class0_fp_cost[d][f];
|
||||
} else {
|
||||
|
|
@ -156,50 +119,14 @@ static void build_nmv_component_cost_table(int *mvcost,
|
|||
}
|
||||
}
|
||||
|
||||
#if !CONFIG_NEW_MULTISYMBOL
|
||||
static void update_mv(aom_writer *w, const unsigned int ct[2], aom_prob *cur_p,
|
||||
aom_prob upd_p) {
|
||||
(void)upd_p;
|
||||
// Just use the default maximum number of tile groups to avoid passing in the
|
||||
// actual
|
||||
// number
|
||||
av1_cond_prob_diff_update(w, cur_p, ct, DEFAULT_MAX_NUM_TG);
|
||||
}
|
||||
|
||||
void av1_write_nmv_probs(AV1_COMMON *cm, int usehp, aom_writer *w,
|
||||
nmv_context_counts *const nmv_counts) {
|
||||
int i;
|
||||
int nmv_ctx = 0;
|
||||
#if CONFIG_AMVR
|
||||
if (cm->cur_frame_mv_precision_level) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
for (nmv_ctx = 0; nmv_ctx < NMV_CONTEXTS; ++nmv_ctx) {
|
||||
nmv_context *const mvc = &cm->fc->nmvc[nmv_ctx];
|
||||
nmv_context_counts *const counts = &nmv_counts[nmv_ctx];
|
||||
|
||||
if (usehp) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp,
|
||||
MV_UPDATE_PROB);
|
||||
update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, MV_UPDATE_PROB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref,
|
||||
nmv_context *mvctx, int usehp) {
|
||||
const MV diff = { mv->row - ref->row, mv->col - ref->col };
|
||||
const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
|
||||
#if CONFIG_AMVR
|
||||
if (cpi->common.cur_frame_mv_precision_level) {
|
||||
if (cpi->common.cur_frame_force_integer_mv) {
|
||||
usehp = MV_SUBPEL_NONE;
|
||||
}
|
||||
#endif
|
||||
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
|
||||
aom_write_symbol(w, j, mvctx->joints_cdf, MV_JOINTS);
|
||||
if (mv_joint_vertical(j))
|
||||
encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
|
||||
|
||||
|
|
@ -214,212 +141,81 @@ void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_INTRABC
|
||||
void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref,
|
||||
nmv_context *mvctx) {
|
||||
// DV and ref DV should not have sub-pel.
|
||||
assert((mv->col & 7) == 0);
|
||||
assert((mv->row & 7) == 0);
|
||||
assert((ref->col & 7) == 0);
|
||||
assert((ref->row & 7) == 0);
|
||||
const MV diff = { mv->row - ref->row, mv->col - ref->col };
|
||||
const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
|
||||
|
||||
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
|
||||
aom_write_symbol(w, j, mvctx->joints_cdf, MV_JOINTS);
|
||||
if (mv_joint_vertical(j))
|
||||
encode_mv_component(w, diff.row, &mvctx->comps[0], MV_SUBPEL_NONE);
|
||||
|
||||
if (mv_joint_horizontal(j))
|
||||
encode_mv_component(w, diff.col, &mvctx->comps[1], MV_SUBPEL_NONE);
|
||||
}
|
||||
#endif // CONFIG_INTRABC
|
||||
|
||||
void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
|
||||
const nmv_context *ctx,
|
||||
MvSubpelPrecision precision) {
|
||||
av1_cost_tokens(mvjoint, ctx->joints, av1_mv_joint_tree);
|
||||
av1_cost_tokens_from_cdf(mvjoint, ctx->joints_cdf, NULL);
|
||||
build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], precision);
|
||||
build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], precision);
|
||||
}
|
||||
|
||||
static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
|
||||
const int_mv mvs[2], const int_mv pred_mvs[2],
|
||||
nmv_context_counts *nmv_counts
|
||||
#if CONFIG_AMVR
|
||||
,
|
||||
MvSubpelPrecision precision
|
||||
#endif
|
||||
) {
|
||||
int i;
|
||||
PREDICTION_MODE mode = mbmi->mode;
|
||||
int_mv av1_get_ref_mv_from_stack(int ref_idx,
|
||||
const MV_REFERENCE_FRAME *ref_frame,
|
||||
int ref_mv_idx,
|
||||
const MB_MODE_INFO_EXT *mbmi_ext) {
|
||||
const int8_t ref_frame_type = av1_ref_frame_type(ref_frame);
|
||||
const CANDIDATE_MV *curr_ref_mv_stack =
|
||||
mbmi_ext->ref_mv_stack[ref_frame_type];
|
||||
int_mv ref_mv;
|
||||
ref_mv.as_int = INVALID_MV;
|
||||
|
||||
if (mode == NEWMV || mode == NEW_NEWMV) {
|
||||
for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
|
||||
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
|
||||
const MV diff = { mvs[i].as_mv.row - ref->row,
|
||||
mvs[i].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
(void)pred_mvs;
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
}
|
||||
} else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
|
||||
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv;
|
||||
const MV diff = { mvs[1].as_mv.row - ref->row,
|
||||
mvs[1].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
} else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
|
||||
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv;
|
||||
const MV diff = { mvs[0].as_mv.row - ref->row,
|
||||
mvs[0].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
#if CONFIG_COMPOUND_SINGLEREF
|
||||
} else {
|
||||
assert( // mode == SR_NEAREST_NEWMV ||
|
||||
mode == SR_NEAR_NEWMV || mode == SR_ZERO_NEWMV || mode == SR_NEW_NEWMV);
|
||||
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv;
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
(void)pred_mvs;
|
||||
MV diff;
|
||||
if (mode == SR_NEW_NEWMV) {
|
||||
diff.row = mvs[0].as_mv.row - ref->row;
|
||||
diff.col = mvs[0].as_mv.col - ref->col;
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
}
|
||||
diff.row = mvs[1].as_mv.row - ref->row;
|
||||
diff.col = mvs[1].as_mv.col - ref->col;
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif // CONFIG_COMPOUND_SINGLEREF
|
||||
}
|
||||
}
|
||||
|
||||
static void inc_mvs_sub8x8(const MODE_INFO *mi, int block, const int_mv mvs[2],
|
||||
const MB_MODE_INFO_EXT *mbmi_ext,
|
||||
nmv_context_counts *nmv_counts
|
||||
#if CONFIG_AMVR
|
||||
,
|
||||
MvSubpelPrecision precision
|
||||
#endif
|
||||
) {
|
||||
int i;
|
||||
PREDICTION_MODE mode = mi->bmi[block].as_mode;
|
||||
const MB_MODE_INFO *mbmi = &mi->mbmi;
|
||||
|
||||
if (mode == NEWMV || mode == NEW_NEWMV) {
|
||||
for (i = 0; i < 1 + has_second_ref(&mi->mbmi); ++i) {
|
||||
const MV *ref = &mi->bmi[block].ref_mv[i].as_mv;
|
||||
const MV diff = { mvs[i].as_mv.row - ref->row,
|
||||
mvs[i].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
}
|
||||
} else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
|
||||
const MV *ref = &mi->bmi[block].ref_mv[1].as_mv;
|
||||
const MV diff = { mvs[1].as_mv.row - ref->row,
|
||||
mvs[1].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
} else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
|
||||
const MV *ref = &mi->bmi[block].ref_mv[0].as_mv;
|
||||
const MV diff = { mvs[0].as_mv.row - ref->row,
|
||||
mvs[0].as_mv.col - ref->col };
|
||||
int8_t rf_type = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int nmv_ctx =
|
||||
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
|
||||
mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx);
|
||||
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
|
||||
#if CONFIG_AMVR
|
||||
av1_inc_mv(&diff, counts, precision);
|
||||
#else
|
||||
av1_inc_mv(&diff, counts, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void av1_update_mv_count(ThreadData *td) {
|
||||
const MACROBLOCKD *xd = &td->mb.e_mbd;
|
||||
const MODE_INFO *mi = xd->mi[0];
|
||||
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
const MB_MODE_INFO_EXT *mbmi_ext = td->mb.mbmi_ext;
|
||||
#if CONFIG_CB4X4
|
||||
const int unify_bsize = 1;
|
||||
#else
|
||||
const int unify_bsize = 0;
|
||||
#endif
|
||||
#if CONFIG_AMVR
|
||||
MvSubpelPrecision precision = 1;
|
||||
if (xd->cur_frame_mv_precision_level) {
|
||||
precision = MV_SUBPEL_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbmi->sb_type < BLOCK_8X8 && !unify_bsize) {
|
||||
const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type];
|
||||
const int num_4x4_h = num_4x4_blocks_high_lookup[mbmi->sb_type];
|
||||
int idx, idy;
|
||||
|
||||
for (idy = 0; idy < 2; idy += num_4x4_h) {
|
||||
for (idx = 0; idx < 2; idx += num_4x4_w) {
|
||||
const int i = idy * 2 + idx;
|
||||
|
||||
if (have_newmv_in_inter_mode(mi->bmi[i].as_mode))
|
||||
|
||||
#if CONFIG_AMVR
|
||||
inc_mvs_sub8x8(mi, i, mi->bmi[i].as_mv, mbmi_ext, td->counts->mv,
|
||||
precision);
|
||||
#else
|
||||
inc_mvs_sub8x8(mi, i, mi->bmi[i].as_mv, mbmi_ext, td->counts->mv);
|
||||
#endif
|
||||
}
|
||||
if (ref_frame[1] > INTRA_FRAME) {
|
||||
if (ref_idx == 0) {
|
||||
ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
|
||||
} else {
|
||||
assert(ref_idx == 1);
|
||||
ref_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
|
||||
}
|
||||
} else {
|
||||
if (have_newmv_in_inter_mode(mbmi->mode))
|
||||
|
||||
#if CONFIG_AMVR
|
||||
inc_mvs(mbmi, mbmi_ext, mbmi->mv, mbmi->pred_mv, td->counts->mv,
|
||||
precision);
|
||||
#else
|
||||
inc_mvs(mbmi, mbmi_ext, mbmi->mv, mbmi->pred_mv, td->counts->mv);
|
||||
#endif
|
||||
assert(ref_idx == 0);
|
||||
if (ref_mv_idx < mbmi_ext->ref_mv_count[ref_frame_type]) {
|
||||
ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
|
||||
} else {
|
||||
ref_mv = mbmi_ext->global_mvs[ref_frame_type];
|
||||
}
|
||||
}
|
||||
return ref_mv;
|
||||
}
|
||||
|
||||
int_mv av1_get_ref_mv(const MACROBLOCK *x, int ref_idx) {
|
||||
const MACROBLOCKD *xd = &x->e_mbd;
|
||||
const MB_MODE_INFO *mbmi = xd->mi[0];
|
||||
int ref_mv_idx = mbmi->ref_mv_idx;
|
||||
if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV) {
|
||||
assert(has_second_ref(mbmi));
|
||||
ref_mv_idx += 1;
|
||||
}
|
||||
return av1_get_ref_mv_from_stack(ref_idx, mbmi->ref_frame, ref_mv_idx,
|
||||
x->mbmi_ext);
|
||||
}
|
||||
|
||||
void av1_find_best_ref_mvs_from_stack(int allow_hp,
|
||||
const MB_MODE_INFO_EXT *mbmi_ext,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
int_mv *nearest_mv, int_mv *near_mv,
|
||||
int is_integer) {
|
||||
const int ref_idx = 0;
|
||||
MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, NONE_FRAME };
|
||||
*nearest_mv = av1_get_ref_mv_from_stack(ref_idx, ref_frames, 0, mbmi_ext);
|
||||
lower_mv_precision(&nearest_mv->as_mv, allow_hp, is_integer);
|
||||
*near_mv = av1_get_ref_mv_from_stack(ref_idx, ref_frames, 1, mbmi_ext);
|
||||
lower_mv_precision(&near_mv->as_mv, allow_hp, is_integer);
|
||||
}
|
||||
|
|
|
|||
19
third_party/aom/av1/encoder/encodemv.h
vendored
19
third_party/aom/av1/encoder/encodemv.h
vendored
|
|
@ -18,13 +18,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void av1_entropy_mv_init(void);
|
||||
|
||||
#if !CONFIG_NEW_MULTISYMBOL
|
||||
void av1_write_nmv_probs(AV1_COMMON *cm, int usehp, aom_writer *w,
|
||||
nmv_context_counts *const counts);
|
||||
#endif
|
||||
|
||||
void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref,
|
||||
nmv_context *mvctx, int usehp);
|
||||
|
||||
|
|
@ -34,10 +27,18 @@ void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
|
|||
|
||||
void av1_update_mv_count(ThreadData *td);
|
||||
|
||||
#if CONFIG_INTRABC
|
||||
void av1_encode_dv(aom_writer *w, const MV *mv, const MV *ref,
|
||||
nmv_context *mvctx);
|
||||
#endif // CONFIG_INTRABC
|
||||
int_mv av1_get_ref_mv(const MACROBLOCK *x, int ref_idx);
|
||||
int_mv av1_get_ref_mv_from_stack(int ref_idx,
|
||||
const MV_REFERENCE_FRAME *ref_frame,
|
||||
int ref_mv_idx,
|
||||
const MB_MODE_INFO_EXT *mbmi_ext);
|
||||
void av1_find_best_ref_mvs_from_stack(int allow_hp,
|
||||
const MB_MODE_INFO_EXT *mbmi_ext,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
int_mv *nearest_mv, int_mv *near_mv,
|
||||
int is_integer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
3978
third_party/aom/av1/encoder/encoder.c
vendored
3978
third_party/aom/av1/encoder/encoder.c
vendored
File diff suppressed because it is too large
Load diff
438
third_party/aom/av1/encoder/encoder.h
vendored
438
third_party/aom/av1/encoder/encoder.h
vendored
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "aom/aomcx.h"
|
||||
|
||||
#include "av1/common/alloccommon.h"
|
||||
|
|
@ -22,11 +23,8 @@
|
|||
#include "av1/common/thread_common.h"
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/common/resize.h"
|
||||
#include "av1/common/timing.h"
|
||||
#include "av1/encoder/aq_cyclicrefresh.h"
|
||||
#if CONFIG_ANS
|
||||
#include "aom_dsp/ans.h"
|
||||
#include "aom_dsp/buf_ans.h"
|
||||
#endif
|
||||
#include "av1/encoder/av1_quantize.h"
|
||||
#include "av1/encoder/context_tree.h"
|
||||
#include "av1/encoder/encodemb.h"
|
||||
|
|
@ -38,9 +36,6 @@
|
|||
#include "av1/encoder/rd.h"
|
||||
#include "av1/encoder/speed_features.h"
|
||||
#include "av1/encoder/tokenize.h"
|
||||
#if CONFIG_XIPHRC
|
||||
#include "av1/encoder/ratectrl_xiph.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
#include "aom_dsp/ssim.h"
|
||||
|
|
@ -54,19 +49,13 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct {
|
||||
int nmv_vec_cost[NMV_CONTEXTS][MV_JOINTS];
|
||||
int nmv_costs[NMV_CONTEXTS][2][MV_VALS];
|
||||
int nmv_costs_hp[NMV_CONTEXTS][2][MV_VALS];
|
||||
|
||||
// 0 = Intra, Last, GF, ARF
|
||||
int8_t last_ref_lf_deltas[TOTAL_REFS_PER_FRAME];
|
||||
// 0 = ZERO_MV, MV
|
||||
int8_t last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
|
||||
int nmv_vec_cost[MV_JOINTS];
|
||||
int nmv_costs[2][MV_VALS];
|
||||
int nmv_costs_hp[2][MV_VALS];
|
||||
|
||||
FRAME_CONTEXT fc;
|
||||
} CODING_CONTEXT;
|
||||
|
||||
#if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
|
||||
typedef enum {
|
||||
// regular inter frame
|
||||
REGULAR_FRAME = 0,
|
||||
|
|
@ -76,14 +65,12 @@ typedef enum {
|
|||
OVERLAY_FRAME = 2,
|
||||
// golden frame
|
||||
GLD_FRAME = 3,
|
||||
#if CONFIG_EXT_REFS
|
||||
// backward reference frame
|
||||
BRF_FRAME = 4,
|
||||
// extra alternate reference frame
|
||||
EXT_ARF_FRAME = 5
|
||||
#endif
|
||||
EXT_ARF_FRAME = 5,
|
||||
FRAME_CONTEXT_INDEXES
|
||||
} FRAME_CONTEXT_INDEX;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
NORMAL = 0,
|
||||
|
|
@ -101,13 +88,9 @@ typedef enum {
|
|||
typedef enum {
|
||||
FRAMEFLAGS_KEY = 1 << 0,
|
||||
FRAMEFLAGS_GOLDEN = 1 << 1,
|
||||
#if CONFIG_EXT_REFS
|
||||
FRAMEFLAGS_BWDREF = 1 << 2,
|
||||
// TODO(zoeliu): To determine whether a frame flag is needed for ALTREF2_FRAME
|
||||
FRAMEFLAGS_ALTREF = 1 << 3,
|
||||
#else // !CONFIG_EXT_REFS
|
||||
FRAMEFLAGS_ALTREF = 1 << 2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} FRAMETYPE_FLAGS;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -115,26 +98,22 @@ typedef enum {
|
|||
VARIANCE_AQ = 1,
|
||||
COMPLEXITY_AQ = 2,
|
||||
CYCLIC_REFRESH_AQ = 3,
|
||||
#if !CONFIG_EXT_DELTA_Q
|
||||
DELTA_AQ = 4,
|
||||
#endif
|
||||
AQ_MODE_COUNT // This should always be the last member of the enum
|
||||
} AQ_MODE;
|
||||
#if CONFIG_EXT_DELTA_Q
|
||||
typedef enum {
|
||||
NO_DELTA_Q = 0,
|
||||
DELTA_Q_ONLY = 1,
|
||||
DELTA_Q_LF = 2,
|
||||
DELTAQ_MODE_COUNT // This should always be the last member of the enum
|
||||
} DELTAQ_MODE;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
RESIZE_NONE = 0, // No frame resizing allowed.
|
||||
RESIZE_FIXED = 1, // All frames are coded at the specified scale.
|
||||
RESIZE_RANDOM = 2, // All frames are coded at a random scale.
|
||||
RESIZE_MODES
|
||||
} RESIZE_MODE;
|
||||
#if CONFIG_FRAME_SUPERRES
|
||||
|
||||
typedef enum {
|
||||
SUPERRES_NONE = 0, // No frame superres allowed
|
||||
SUPERRES_FIXED = 1, // All frames are coded at the specified scale,
|
||||
|
|
@ -145,13 +124,14 @@ typedef enum {
|
|||
// q_index
|
||||
SUPERRES_MODES
|
||||
} SUPERRES_MODE;
|
||||
#endif // CONFIG_FRAME_SUPERRES
|
||||
|
||||
typedef struct AV1EncoderConfig {
|
||||
BITSTREAM_PROFILE profile;
|
||||
aom_bit_depth_t bit_depth; // Codec bit-depth.
|
||||
int width; // width of data passed to the compressor
|
||||
int height; // height of data passed to the compressor
|
||||
int forced_max_frame_width; // forced maximum width of frame (if != 0)
|
||||
int forced_max_frame_height; // forced maximum height of frame (if != 0)
|
||||
unsigned int input_bit_depth; // Input bit depth.
|
||||
double init_framerate; // set to passed in framerate
|
||||
int64_t target_bandwidth; // bandwidth to be used in bits per second
|
||||
|
|
@ -159,6 +139,7 @@ typedef struct AV1EncoderConfig {
|
|||
int noise_sensitivity; // pre processing blur: recommendation 0
|
||||
int sharpness; // sharpening output: recommendation 0:
|
||||
int speed;
|
||||
int dev_sf;
|
||||
// maximum allowed bitrate for any intra frame in % of bitrate target.
|
||||
unsigned int rc_max_intra_bitrate_pct;
|
||||
// maximum allowed bitrate for any inter frame in % of bitrate target.
|
||||
|
|
@ -172,8 +153,11 @@ typedef struct AV1EncoderConfig {
|
|||
// Key Framing Operations
|
||||
int auto_key; // autodetect cut scenes and set the keyframes
|
||||
int key_freq; // maximum distance to key frame.
|
||||
|
||||
int sframe_dist;
|
||||
int sframe_mode;
|
||||
int sframe_enabled;
|
||||
int lag_in_frames; // how many frames lag before we start encoding
|
||||
int fwd_kf_enabled;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// DATARATE CONTROL OPTIONS
|
||||
|
|
@ -199,36 +183,33 @@ typedef struct AV1EncoderConfig {
|
|||
int best_allowed_q;
|
||||
int cq_level;
|
||||
AQ_MODE aq_mode; // Adaptive Quantization mode
|
||||
#if CONFIG_EXT_DELTA_Q
|
||||
DELTAQ_MODE deltaq_mode;
|
||||
#endif
|
||||
#if CONFIG_AOM_QM
|
||||
int enable_cdef;
|
||||
int enable_restoration;
|
||||
int disable_trellis_quant;
|
||||
int using_qm;
|
||||
int qm_y;
|
||||
int qm_u;
|
||||
int qm_v;
|
||||
int qm_minlevel;
|
||||
int qm_maxlevel;
|
||||
#endif
|
||||
#if CONFIG_DIST_8X8
|
||||
int using_dist_8x8;
|
||||
#endif
|
||||
unsigned int num_tile_groups;
|
||||
unsigned int mtu;
|
||||
|
||||
#if CONFIG_TEMPMV_SIGNALING
|
||||
unsigned int disable_tempmv;
|
||||
#endif
|
||||
// Internal frame size scaling.
|
||||
RESIZE_MODE resize_mode;
|
||||
uint8_t resize_scale_denominator;
|
||||
uint8_t resize_kf_scale_denominator;
|
||||
|
||||
#if CONFIG_FRAME_SUPERRES
|
||||
// Frame Super-Resolution size scaling.
|
||||
SUPERRES_MODE superres_mode;
|
||||
uint8_t superres_scale_denominator;
|
||||
uint8_t superres_kf_scale_denominator;
|
||||
int superres_qthresh;
|
||||
int superres_kf_qthresh;
|
||||
#endif // CONFIG_FRAME_SUPERRES
|
||||
|
||||
// Enable feature to reduce the frame quantization every x frames.
|
||||
int frame_periodic_boost;
|
||||
|
|
@ -241,9 +222,7 @@ typedef struct AV1EncoderConfig {
|
|||
// ----------------------------------------------------------------
|
||||
|
||||
int enable_auto_arf;
|
||||
#if CONFIG_EXT_REFS
|
||||
int enable_auto_brf; // (b)ackward (r)ef (f)rame
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
/* Bitfield defining the error resiliency features to enable.
|
||||
* Can provide decodable frames after losses in previous
|
||||
|
|
@ -251,12 +230,16 @@ typedef struct AV1EncoderConfig {
|
|||
*/
|
||||
unsigned int error_resilient_mode;
|
||||
|
||||
unsigned int s_frame_mode;
|
||||
|
||||
/* Bitfield defining the parallel decoding mode where the
|
||||
* decoding in successive frames may be conducted in parallel
|
||||
* just by decoding the frame headers.
|
||||
*/
|
||||
unsigned int frame_parallel_decoding_mode;
|
||||
|
||||
unsigned int limit;
|
||||
|
||||
int arnr_max_frames;
|
||||
int arnr_strength;
|
||||
|
||||
|
|
@ -265,18 +248,10 @@ typedef struct AV1EncoderConfig {
|
|||
|
||||
int tile_columns;
|
||||
int tile_rows;
|
||||
#if CONFIG_MAX_TILE
|
||||
int tile_width_count;
|
||||
int tile_height_count;
|
||||
int tile_widths[MAX_TILE_COLS];
|
||||
int tile_heights[MAX_TILE_ROWS];
|
||||
#endif
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
int dependent_horz_tiles;
|
||||
#endif
|
||||
#if CONFIG_LOOPFILTERING_ACROSS_TILES
|
||||
int loop_filter_across_tiles_enabled;
|
||||
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
|
||||
|
||||
int max_threads;
|
||||
|
||||
|
|
@ -289,34 +264,135 @@ typedef struct AV1EncoderConfig {
|
|||
|
||||
aom_tune_metric tuning;
|
||||
aom_tune_content content;
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_highbitdepth;
|
||||
#endif
|
||||
aom_color_space_t color_space;
|
||||
aom_transfer_function_t transfer_function;
|
||||
aom_color_primaries_t color_primaries;
|
||||
aom_transfer_characteristics_t transfer_characteristics;
|
||||
aom_matrix_coefficients_t matrix_coefficients;
|
||||
aom_chroma_sample_position_t chroma_sample_position;
|
||||
int color_range;
|
||||
int render_width;
|
||||
int render_height;
|
||||
aom_timing_info_type_t timing_info_type;
|
||||
int timing_info_present;
|
||||
aom_timing_info_t timing_info;
|
||||
int decoder_model_info_present_flag;
|
||||
int display_model_info_present_flag;
|
||||
int buffer_removal_delay_present;
|
||||
aom_dec_model_info_t buffer_model;
|
||||
aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1];
|
||||
aom_op_timing_info_t op_frame_timing[MAX_NUM_OPERATING_POINTS + 1];
|
||||
int film_grain_test_vector;
|
||||
const char *film_grain_table_filename;
|
||||
|
||||
#if CONFIG_EXT_PARTITION
|
||||
uint8_t cdf_update_mode;
|
||||
aom_superblock_size_t superblock_size;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
#if CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
int ans_window_size_log2;
|
||||
#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
|
||||
#if CONFIG_EXT_TILE
|
||||
unsigned int large_scale_tile;
|
||||
unsigned int single_tile_decoding;
|
||||
#endif // CONFIG_EXT_TILE
|
||||
|
||||
int monochrome;
|
||||
unsigned int full_still_picture_hdr;
|
||||
int enable_dual_filter;
|
||||
unsigned int motion_vector_unit_test;
|
||||
const cfg_options_t *cfg;
|
||||
int enable_order_hint;
|
||||
int enable_jnt_comp;
|
||||
int enable_ref_frame_mvs;
|
||||
unsigned int allow_ref_frame_mvs;
|
||||
int enable_warped_motion;
|
||||
int allow_warped_motion;
|
||||
int enable_superres;
|
||||
unsigned int save_as_annexb;
|
||||
} AV1EncoderConfig;
|
||||
|
||||
static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {
|
||||
return cfg->best_allowed_q == 0 && cfg->worst_allowed_q == 0;
|
||||
}
|
||||
|
||||
typedef struct FRAME_COUNTS {
|
||||
// Note: This structure should only contain 'unsigned int' fields, or
|
||||
// aggregates built solely from 'unsigned int' fields/elements
|
||||
#if CONFIG_ENTROPY_STATS
|
||||
unsigned int kf_y_mode[KF_MODE_CONTEXTS][KF_MODE_CONTEXTS][INTRA_MODES];
|
||||
unsigned int angle_delta[DIRECTIONAL_MODES][2 * MAX_ANGLE_DELTA + 1];
|
||||
unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
|
||||
unsigned int uv_mode[CFL_ALLOWED_TYPES][INTRA_MODES][UV_INTRA_MODES];
|
||||
unsigned int cfl_sign[CFL_JOINT_SIGNS];
|
||||
unsigned int cfl_alpha[CFL_ALPHA_CONTEXTS][CFL_ALPHABET_SIZE];
|
||||
unsigned int palette_y_mode[PALATTE_BSIZE_CTXS][PALETTE_Y_MODE_CONTEXTS][2];
|
||||
unsigned int palette_uv_mode[PALETTE_UV_MODE_CONTEXTS][2];
|
||||
unsigned int palette_y_size[PALATTE_BSIZE_CTXS][PALETTE_SIZES];
|
||||
unsigned int palette_uv_size[PALATTE_BSIZE_CTXS][PALETTE_SIZES];
|
||||
unsigned int palette_y_color_index[PALETTE_SIZES]
|
||||
[PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
unsigned int palette_uv_color_index[PALETTE_SIZES]
|
||||
[PALETTE_COLOR_INDEX_CONTEXTS]
|
||||
[PALETTE_COLORS];
|
||||
unsigned int partition[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
|
||||
unsigned int txb_skip[TOKEN_CDF_Q_CTXS][TX_SIZES][TXB_SKIP_CONTEXTS][2];
|
||||
unsigned int eob_extra[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES]
|
||||
[EOB_COEF_CONTEXTS][2];
|
||||
unsigned int dc_sign[PLANE_TYPES][DC_SIGN_CONTEXTS][2];
|
||||
unsigned int coeff_lps[TX_SIZES][PLANE_TYPES][BR_CDF_SIZE - 1][LEVEL_CONTEXTS]
|
||||
[2];
|
||||
unsigned int eob_flag[TX_SIZES][PLANE_TYPES][EOB_COEF_CONTEXTS][2];
|
||||
unsigned int eob_multi16[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][5];
|
||||
unsigned int eob_multi32[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][6];
|
||||
unsigned int eob_multi64[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][7];
|
||||
unsigned int eob_multi128[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][8];
|
||||
unsigned int eob_multi256[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][9];
|
||||
unsigned int eob_multi512[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][10];
|
||||
unsigned int eob_multi1024[TOKEN_CDF_Q_CTXS][PLANE_TYPES][2][11];
|
||||
unsigned int coeff_lps_multi[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES]
|
||||
[LEVEL_CONTEXTS][BR_CDF_SIZE];
|
||||
unsigned int coeff_base_multi[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES]
|
||||
[SIG_COEF_CONTEXTS][NUM_BASE_LEVELS + 2];
|
||||
unsigned int coeff_base_eob_multi[TOKEN_CDF_Q_CTXS][TX_SIZES][PLANE_TYPES]
|
||||
[SIG_COEF_CONTEXTS_EOB][NUM_BASE_LEVELS + 1];
|
||||
unsigned int newmv_mode[NEWMV_MODE_CONTEXTS][2];
|
||||
unsigned int zeromv_mode[GLOBALMV_MODE_CONTEXTS][2];
|
||||
unsigned int refmv_mode[REFMV_MODE_CONTEXTS][2];
|
||||
unsigned int drl_mode[DRL_MODE_CONTEXTS][2];
|
||||
unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
|
||||
unsigned int wedge_idx[BLOCK_SIZES_ALL][16];
|
||||
unsigned int interintra[BLOCK_SIZE_GROUPS][2];
|
||||
unsigned int interintra_mode[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
|
||||
unsigned int wedge_interintra[BLOCK_SIZES_ALL][2];
|
||||
unsigned int compound_type[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
|
||||
unsigned int motion_mode[BLOCK_SIZES_ALL][MOTION_MODES];
|
||||
unsigned int obmc[BLOCK_SIZES_ALL][2];
|
||||
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
|
||||
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
|
||||
unsigned int comp_ref_type[COMP_REF_TYPE_CONTEXTS][2];
|
||||
unsigned int uni_comp_ref[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1][2];
|
||||
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS - 1][2];
|
||||
unsigned int comp_ref[REF_CONTEXTS][FWD_REFS - 1][2];
|
||||
unsigned int comp_bwdref[REF_CONTEXTS][BWD_REFS - 1][2];
|
||||
unsigned int intrabc[2];
|
||||
|
||||
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
|
||||
unsigned int intra_tx_size[MAX_TX_CATS][TX_SIZE_CONTEXTS][MAX_TX_DEPTH + 1];
|
||||
unsigned int skip_mode[SKIP_MODE_CONTEXTS][2];
|
||||
unsigned int skip[SKIP_CONTEXTS][2];
|
||||
unsigned int compound_index[COMP_INDEX_CONTEXTS][2];
|
||||
unsigned int comp_group_idx[COMP_GROUP_IDX_CONTEXTS][2];
|
||||
unsigned int delta_q[DELTA_Q_PROBS][2];
|
||||
unsigned int delta_lf_multi[FRAME_LF_COUNT][DELTA_LF_PROBS][2];
|
||||
unsigned int delta_lf[DELTA_LF_PROBS][2];
|
||||
|
||||
unsigned int inter_ext_tx[EXT_TX_SETS_INTER][EXT_TX_SIZES][TX_TYPES];
|
||||
unsigned int intra_ext_tx[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
|
||||
[TX_TYPES];
|
||||
unsigned int filter_intra_mode[FILTER_INTRA_MODES];
|
||||
unsigned int filter_intra[BLOCK_SIZES_ALL][2];
|
||||
unsigned int switchable_restore[RESTORE_SWITCHABLE_TYPES];
|
||||
unsigned int wiener_restore[2];
|
||||
unsigned int sgrproj_restore[2];
|
||||
#endif // CONFIG_ENTROPY_STATS
|
||||
|
||||
unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS]
|
||||
[SWITCHABLE_FILTERS];
|
||||
} FRAME_COUNTS;
|
||||
|
||||
// TODO(jingning) All spatially adaptive variables should go to TileDataEnc.
|
||||
typedef struct TileDataEnc {
|
||||
TileInfo tile_info;
|
||||
|
|
@ -324,42 +400,31 @@ typedef struct TileDataEnc {
|
|||
int mode_map[BLOCK_SIZES_ALL][MAX_MODES];
|
||||
int m_search_count;
|
||||
int ex_search_count;
|
||||
#if CONFIG_PVQ
|
||||
PVQ_QUEUE pvq_q;
|
||||
#endif
|
||||
#if CONFIG_CFL
|
||||
CFL_CTX cfl;
|
||||
#endif
|
||||
DECLARE_ALIGNED(16, FRAME_CONTEXT, tctx);
|
||||
uint8_t allow_update_cdf;
|
||||
} TileDataEnc;
|
||||
|
||||
typedef struct RD_COUNTS {
|
||||
int64_t comp_pred_diff[REFERENCE_MODES];
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
// Stores number of 4x4 blocks using global motion per reference frame.
|
||||
int global_motion_used[TOTAL_REFS_PER_FRAME];
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
int single_ref_used_flag;
|
||||
int global_motion_used[REF_FRAMES];
|
||||
int compound_ref_used_flag;
|
||||
int skip_mode_used_flag;
|
||||
} RD_COUNTS;
|
||||
|
||||
typedef struct ThreadData {
|
||||
MACROBLOCK mb;
|
||||
RD_COUNTS rd_counts;
|
||||
FRAME_COUNTS *counts;
|
||||
#if !CONFIG_CB4X4
|
||||
PICK_MODE_CONTEXT *leaf_tree;
|
||||
#endif
|
||||
PC_TREE *pc_tree;
|
||||
PC_TREE *pc_root[MAX_MIB_SIZE_LOG2 - MIN_MIB_SIZE_LOG2 + 1];
|
||||
#if CONFIG_MOTION_VAR
|
||||
int32_t *wsrc_buf;
|
||||
int32_t *mask_buf;
|
||||
uint8_t *above_pred_buf;
|
||||
uint8_t *left_pred_buf;
|
||||
#endif
|
||||
|
||||
PALETTE_BUFFER *palette_buffer;
|
||||
int intrabc_used_this_tile;
|
||||
} ThreadData;
|
||||
|
||||
struct EncWorkerData;
|
||||
|
|
@ -370,14 +435,21 @@ typedef struct ActiveMap {
|
|||
unsigned char *map;
|
||||
} ActiveMap;
|
||||
|
||||
#define NUM_STAT_TYPES 4 // types of stats: Y, U, V and ALL
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
// types of stats
|
||||
typedef enum {
|
||||
STAT_Y,
|
||||
STAT_U,
|
||||
STAT_V,
|
||||
STAT_ALL,
|
||||
NUM_STAT_TYPES // This should always be the last member of the enum
|
||||
} StatType;
|
||||
|
||||
typedef struct IMAGE_STAT {
|
||||
double stat[NUM_STAT_TYPES];
|
||||
double worst;
|
||||
} ImageStat;
|
||||
|
||||
#undef NUM_STAT_TYPES
|
||||
#endif // CONFIG_INTERNAL_STATS
|
||||
|
||||
typedef struct {
|
||||
int ref_count;
|
||||
|
|
@ -392,16 +464,18 @@ typedef struct TileBufferEnc {
|
|||
typedef struct AV1_COMP {
|
||||
QUANTS quants;
|
||||
ThreadData td;
|
||||
FRAME_COUNTS counts;
|
||||
MB_MODE_INFO_EXT *mbmi_ext_base;
|
||||
#if CONFIG_LV_MAP
|
||||
CB_COEFF_BUFFER *coeff_buffer_base;
|
||||
#endif
|
||||
Dequants dequants;
|
||||
AV1_COMMON common;
|
||||
AV1EncoderConfig oxcf;
|
||||
struct lookahead_ctx *lookahead;
|
||||
struct lookahead_entry *alt_ref_source;
|
||||
|
||||
int optimize_speed_feature;
|
||||
int optimize_seg_arr[MAX_SEGMENTS];
|
||||
|
||||
YV12_BUFFER_CONFIG *source;
|
||||
YV12_BUFFER_CONFIG *last_source; // NULL for first frame and alt_ref frames
|
||||
YV12_BUFFER_CONFIG *unscaled_source;
|
||||
|
|
@ -411,58 +485,42 @@ typedef struct AV1_COMP {
|
|||
|
||||
// For a still frame, this flag is set to 1 to skip partition search.
|
||||
int partition_search_skippable_frame;
|
||||
#if CONFIG_AMVR
|
||||
double csm_rate_array[32];
|
||||
double m_rate_array[32];
|
||||
int rate_size;
|
||||
int rate_index;
|
||||
hash_table *previsou_hash_table;
|
||||
int previsous_index;
|
||||
hash_table *previous_hash_table;
|
||||
int previous_index;
|
||||
int cur_poc; // DebugInfo
|
||||
#endif
|
||||
|
||||
int scaled_ref_idx[TOTAL_REFS_PER_FRAME];
|
||||
#if CONFIG_EXT_REFS
|
||||
int lst_fb_idxes[LAST_REF_FRAMES];
|
||||
#else
|
||||
int lst_fb_idx;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int gld_fb_idx;
|
||||
#if CONFIG_EXT_REFS
|
||||
int bwd_fb_idx; // BWDREF_FRAME
|
||||
int alt2_fb_idx; // ALTREF2_FRAME
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int alt_fb_idx;
|
||||
#if CONFIG_EXT_REFS
|
||||
int ext_fb_idx; // extra ref frame buffer index
|
||||
int scaled_ref_idx[REF_FRAMES];
|
||||
int ref_fb_idx[REF_FRAMES];
|
||||
int refresh_fb_idx; // ref frame buffer index to refresh
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
int last_show_frame_buf_idx; // last show frame buffer index
|
||||
|
||||
int refresh_last_frame;
|
||||
int refresh_golden_frame;
|
||||
#if CONFIG_EXT_REFS
|
||||
int refresh_bwd_ref_frame;
|
||||
int refresh_alt2_ref_frame;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int refresh_alt_ref_frame;
|
||||
|
||||
int ext_refresh_frame_flags_pending;
|
||||
int ext_refresh_last_frame;
|
||||
int ext_refresh_golden_frame;
|
||||
int ext_refresh_bwd_ref_frame;
|
||||
int ext_refresh_alt2_ref_frame;
|
||||
int ext_refresh_alt_ref_frame;
|
||||
|
||||
int ext_refresh_frame_context_pending;
|
||||
int ext_refresh_frame_context;
|
||||
int ext_use_ref_frame_mvs;
|
||||
int ext_use_error_resilient;
|
||||
int ext_use_s_frame;
|
||||
int ext_use_primary_ref_none;
|
||||
|
||||
YV12_BUFFER_CONFIG last_frame_uf;
|
||||
#if CONFIG_LOOP_RESTORATION
|
||||
YV12_BUFFER_CONFIG last_frame_db;
|
||||
YV12_BUFFER_CONFIG trial_frame_rst;
|
||||
uint8_t *extra_rstbuf; // Extra buffers used in restoration search
|
||||
RestorationInfo rst_search[MAX_MB_PLANE]; // Used for encoder side search
|
||||
#endif // CONFIG_LOOP_RESTORATION
|
||||
|
||||
// Ambient reconstruction err target for force key frames
|
||||
int64_t ambient_err;
|
||||
|
|
@ -471,22 +529,17 @@ typedef struct AV1_COMP {
|
|||
|
||||
CODING_CONTEXT coding_context;
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
int gmtype_cost[TRANS_TYPES];
|
||||
int gmparams_cost[TOTAL_REFS_PER_FRAME];
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
int gmparams_cost[REF_FRAMES];
|
||||
|
||||
int nmv_costs[NMV_CONTEXTS][2][MV_VALS];
|
||||
int nmv_costs_hp[NMV_CONTEXTS][2][MV_VALS];
|
||||
int nmv_costs[2][MV_VALS];
|
||||
int nmv_costs_hp[2][MV_VALS];
|
||||
|
||||
int64_t last_time_stamp_seen;
|
||||
int64_t last_end_time_stamp_seen;
|
||||
int64_t first_time_stamp_ever;
|
||||
|
||||
RATE_CONTROL rc;
|
||||
#if CONFIG_XIPHRC
|
||||
od_rc_state od_rc;
|
||||
#endif
|
||||
double framerate;
|
||||
|
||||
// NOTE(zoeliu): Any inter frame allows maximum of REF_FRAMES inter
|
||||
|
|
@ -500,6 +553,8 @@ typedef struct AV1_COMP {
|
|||
int mbgraph_n_frames; // number of frames filled in the above
|
||||
int static_mb_pct; // % forced skip mbs by segmentation
|
||||
int ref_frame_flags;
|
||||
int ext_ref_frame_flags;
|
||||
RATE_FACTOR_LEVEL frame_rf_level[FRAME_BUFFERS];
|
||||
|
||||
SPEED_FEATURES sf;
|
||||
|
||||
|
|
@ -507,6 +562,7 @@ typedef struct AV1_COMP {
|
|||
int mv_step_param;
|
||||
|
||||
int allow_comp_inter_inter;
|
||||
int all_one_sided_refs;
|
||||
|
||||
uint8_t *segmentation_map;
|
||||
|
||||
|
|
@ -514,7 +570,6 @@ typedef struct AV1_COMP {
|
|||
ActiveMap active_map;
|
||||
|
||||
fractional_mv_step_fp *find_fractional_mv_step;
|
||||
av1_full_search_fn_t full_search_sad; // It is currently unused.
|
||||
av1_diamond_search_fn_t diamond_search_sad;
|
||||
aom_variance_fn_ptr_t fn_ptr[BLOCK_SIZES_ALL];
|
||||
uint64_t time_receive_data;
|
||||
|
|
@ -581,8 +636,6 @@ typedef struct AV1_COMP {
|
|||
search_site_config ss_cfg;
|
||||
|
||||
int multi_arf_allowed;
|
||||
int multi_arf_enabled;
|
||||
int multi_arf_last_grp_enabled;
|
||||
|
||||
TileDataEnc *tile_data;
|
||||
int allocated_tiles; // Keep track of memory allocated for tiles.
|
||||
|
|
@ -597,6 +650,11 @@ typedef struct AV1_COMP {
|
|||
int resize_buffer_underflow;
|
||||
int resize_count;
|
||||
|
||||
// Sequence parameters have been transmitted already and locked
|
||||
// or not. Once locked av1_change_config cannot change the seq
|
||||
// parameters.
|
||||
int seq_params_locked;
|
||||
|
||||
// VARIANCE_AQ segment map refresh
|
||||
int vaq_refresh;
|
||||
|
||||
|
|
@ -604,11 +662,6 @@ typedef struct AV1_COMP {
|
|||
int num_workers;
|
||||
AVxWorker *workers;
|
||||
struct EncWorkerData *tile_thr_data;
|
||||
AV1LfSync lf_row_sync;
|
||||
#if CONFIG_ANS
|
||||
struct BufAnsCoder buf_ans;
|
||||
#endif
|
||||
#if CONFIG_EXT_REFS
|
||||
int refresh_frame_mask;
|
||||
int existing_fb_idx_to_show;
|
||||
int is_arf_filter_off[MAX_EXT_ARFS + 1];
|
||||
|
|
@ -616,22 +669,24 @@ typedef struct AV1_COMP {
|
|||
int arf_map[MAX_EXT_ARFS + 1];
|
||||
int arf_pos_in_gf[MAX_EXT_ARFS + 1];
|
||||
int arf_pos_for_ovrly[MAX_EXT_ARFS + 1];
|
||||
#endif // CONFIG_EXT_REFS
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
int global_motion_search_done;
|
||||
#endif
|
||||
#if CONFIG_LV_MAP
|
||||
tran_low_t *tcoeff_buf[MAX_MB_PLANE];
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
int extra_arf_allowed;
|
||||
int bwd_ref_allowed;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
// A flag to indicate if intrabc is ever used in current frame.
|
||||
int intrabc_used;
|
||||
int dv_cost[2][MV_VALS];
|
||||
// TODO(huisu@google.com): we can update dv_joint_cost per SB.
|
||||
int dv_joint_cost[MV_JOINTS];
|
||||
int has_lossless_segment;
|
||||
|
||||
#if CONFIG_BGSPRITE
|
||||
int bgsprite_allowed;
|
||||
#endif // CONFIG_BGSPRITE
|
||||
// For frame refs short signaling:
|
||||
// A mapping of each reference frame from its encoder side value to the
|
||||
// decoder side value obtained following the short signaling procedure.
|
||||
int ref_conv[REF_FRAMES];
|
||||
|
||||
AV1LfSync lf_row_sync;
|
||||
AV1LrSync lr_row_sync;
|
||||
AV1LrStruct lr_ctxt;
|
||||
} AV1_COMP;
|
||||
|
||||
void av1_initialize_enc(void);
|
||||
|
|
@ -650,12 +705,17 @@ int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
|
|||
|
||||
int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
|
||||
size_t *size, uint8_t *dest, int64_t *time_stamp,
|
||||
int64_t *time_end, int flush);
|
||||
int64_t *time_end, int flush,
|
||||
const aom_rational_t *timebase);
|
||||
|
||||
int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest);
|
||||
|
||||
int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame);
|
||||
|
||||
aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
|
||||
YV12_BUFFER_CONFIG *new_frame,
|
||||
YV12_BUFFER_CONFIG *sd);
|
||||
|
||||
int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
|
||||
|
||||
void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags);
|
||||
|
|
@ -675,6 +735,11 @@ int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
|
|||
|
||||
int av1_get_quantizer(struct AV1_COMP *cpi);
|
||||
|
||||
int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *input_size);
|
||||
|
||||
int64_t timebase_units_to_ticks(const aom_rational_t *timebase, int64_t n);
|
||||
int64_t ticks_to_timebase_units(const aom_rational_t *timebase, int64_t n);
|
||||
|
||||
static INLINE int frame_is_kf_gf_arf(const AV1_COMP *cpi) {
|
||||
return frame_is_intra_only(&cpi->common) || cpi->refresh_alt_ref_frame ||
|
||||
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref);
|
||||
|
|
@ -682,22 +747,7 @@ static INLINE int frame_is_kf_gf_arf(const AV1_COMP *cpi) {
|
|||
|
||||
static INLINE int get_ref_frame_map_idx(const AV1_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame) {
|
||||
#if CONFIG_EXT_REFS
|
||||
if (ref_frame >= LAST_FRAME && ref_frame <= LAST3_FRAME)
|
||||
return cpi->lst_fb_idxes[ref_frame - 1];
|
||||
#else
|
||||
if (ref_frame == LAST_FRAME) return cpi->lst_fb_idx;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
else if (ref_frame == GOLDEN_FRAME)
|
||||
return cpi->gld_fb_idx;
|
||||
#if CONFIG_EXT_REFS
|
||||
else if (ref_frame == BWDREF_FRAME)
|
||||
return cpi->bwd_fb_idx;
|
||||
else if (ref_frame == ALTREF2_FRAME)
|
||||
return cpi->alt2_fb_idx;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
else
|
||||
return cpi->alt_fb_idx;
|
||||
return (ref_frame >= 1) ? cpi->ref_fb_idx[ref_frame - 1] : INVALID_IDX;
|
||||
}
|
||||
|
||||
static INLINE int get_ref_frame_buf_idx(const AV1_COMP *cpi,
|
||||
|
|
@ -707,16 +757,19 @@ static INLINE int get_ref_frame_buf_idx(const AV1_COMP *cpi,
|
|||
return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : INVALID_IDX;
|
||||
}
|
||||
|
||||
#if CONFIG_HASH_ME
|
||||
static INLINE hash_table *get_ref_frame_hash_map(const AV1_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame) {
|
||||
// TODO(huisu@google.com, youzhou@microsoft.com): enable hash-me for HBD.
|
||||
static INLINE int av1_use_hash_me(const AV1_COMMON *const cm) {
|
||||
return cm->allow_screen_content_tools;
|
||||
}
|
||||
|
||||
static INLINE hash_table *av1_get_ref_frame_hash_map(
|
||||
const AV1_COMP *cpi, MV_REFERENCE_FRAME ref_frame) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
|
||||
return buf_idx != INVALID_IDX
|
||||
? &cm->buffer_pool->frame_bufs[buf_idx].hash_table
|
||||
: NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer(
|
||||
const AV1_COMP *cpi, MV_REFERENCE_FRAME ref_frame) {
|
||||
|
|
@ -726,7 +779,6 @@ static INLINE YV12_BUFFER_CONFIG *get_ref_frame_buffer(
|
|||
: NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
|
||||
static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) {
|
||||
MV_REFERENCE_FRAME ref_frame;
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
|
|
@ -737,48 +789,42 @@ static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) {
|
|||
}
|
||||
return (ref_frame <= ALTREF_FRAME);
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols) {
|
||||
// We assume 3 planes all at full resolution. We assume up to 1 token per
|
||||
// pixel, and then allow a head room of 1 EOSB token per 4x4 block per plane,
|
||||
// plus EOSB_TOKEN per plane.
|
||||
return mb_rows * mb_cols * (16 * 16 + 17) * 3;
|
||||
// Token buffer is only used for palette tokens.
|
||||
static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols,
|
||||
int sb_size_log2,
|
||||
const int num_planes) {
|
||||
// Calculate the maximum number of max superblocks in the image.
|
||||
const int shift = sb_size_log2 - 4;
|
||||
const int sb_size = 1 << sb_size_log2;
|
||||
const int sb_size_square = sb_size * sb_size;
|
||||
const int sb_rows = ALIGN_POWER_OF_TWO(mb_rows, shift) >> shift;
|
||||
const int sb_cols = ALIGN_POWER_OF_TWO(mb_cols, shift) >> shift;
|
||||
|
||||
// One palette token for each pixel. There can be palettes on two planes.
|
||||
const int sb_palette_toks = AOMMIN(2, num_planes) * sb_size_square;
|
||||
|
||||
return sb_rows * sb_cols * sb_palette_toks;
|
||||
}
|
||||
|
||||
// Get the allocated token size for a tile. It does the same calculation as in
|
||||
// the frame token allocation.
|
||||
static INLINE unsigned int allocated_tokens(TileInfo tile) {
|
||||
#if CONFIG_CB4X4
|
||||
static INLINE unsigned int allocated_tokens(TileInfo tile, int sb_size_log2,
|
||||
int num_planes) {
|
||||
int tile_mb_rows = (tile.mi_row_end - tile.mi_row_start + 2) >> 2;
|
||||
int tile_mb_cols = (tile.mi_col_end - tile.mi_col_start + 2) >> 2;
|
||||
#else
|
||||
int tile_mb_rows = (tile.mi_row_end - tile.mi_row_start + 1) >> 1;
|
||||
int tile_mb_cols = (tile.mi_col_end - tile.mi_col_start + 1) >> 1;
|
||||
#endif
|
||||
|
||||
return get_token_alloc(tile_mb_rows, tile_mb_cols);
|
||||
return get_token_alloc(tile_mb_rows, tile_mb_cols, sb_size_log2, num_planes);
|
||||
}
|
||||
|
||||
#if CONFIG_TEMPMV_SIGNALING
|
||||
void av1_set_temporal_mv_prediction(AV1_COMP *cpi, int allow_tempmv_prediction);
|
||||
#endif
|
||||
|
||||
void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags);
|
||||
|
||||
#define ALT_MIN_LAG 3
|
||||
static INLINE int is_altref_enabled(const AV1_COMP *const cpi) {
|
||||
return cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.enable_auto_arf;
|
||||
return cpi->oxcf.lag_in_frames >= ALT_MIN_LAG && cpi->oxcf.enable_auto_arf;
|
||||
}
|
||||
|
||||
// TODO(zoeliu): To set up cpi->oxcf.enable_auto_brf
|
||||
#if 0 && CONFIG_EXT_REFS
|
||||
static INLINE int is_bwdref_enabled(const AV1_COMP *const cpi) {
|
||||
// NOTE(zoeliu): The enabling of bi-predictive frames depends on the use of
|
||||
// alt_ref, and now will be off when the alt_ref interval is
|
||||
// not sufficiently large.
|
||||
return is_altref_enabled(cpi) && cpi->oxcf.enable_auto_brf;
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
static INLINE void set_ref_ptrs(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
||||
MV_REFERENCE_FRAME ref0,
|
||||
|
|
@ -813,22 +859,14 @@ static INLINE void uref_cnt_fb(EncRefCntBuffer *ubufs, int *uidx,
|
|||
ubufs[new_uidx].ref_count++;
|
||||
}
|
||||
|
||||
// Returns 1 if a frame is unscaled and 0 otherwise.
|
||||
static INLINE int av1_resize_unscaled(const AV1_COMMON *cm) {
|
||||
#if CONFIG_FRAME_SUPERRES
|
||||
return cm->superres_upscaled_width == cm->render_width &&
|
||||
cm->superres_upscaled_height == cm->render_height;
|
||||
#else
|
||||
return cm->width == cm->render_width && cm->height == cm->render_height;
|
||||
#endif // CONFIG_FRAME_SUPERRES
|
||||
// Returns 1 if a frame is scaled and 0 otherwise.
|
||||
static INLINE int av1_resize_scaled(const AV1_COMMON *cm) {
|
||||
return !(cm->superres_upscaled_width == cm->render_width &&
|
||||
cm->superres_upscaled_height == cm->render_height);
|
||||
}
|
||||
|
||||
static INLINE int av1_frame_unscaled(const AV1_COMMON *cm) {
|
||||
#if CONFIG_FRAME_SUPERRES
|
||||
return av1_superres_unscaled(cm) && av1_resize_unscaled(cm);
|
||||
#else
|
||||
return av1_resize_unscaled(cm);
|
||||
#endif // CONFIG_FRAME_SUPERRES
|
||||
static INLINE int av1_frame_scaled(const AV1_COMMON *cm) {
|
||||
return !av1_superres_scaled(cm) && av1_resize_scaled(cm);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
4192
third_party/aom/av1/encoder/encodetxb.c
vendored
4192
third_party/aom/av1/encoder/encodetxb.c
vendored
File diff suppressed because it is too large
Load diff
66
third_party/aom/av1/encoder/encodetxb.h
vendored
66
third_party/aom/av1/encoder/encodetxb.h
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#ifndef ENCODETXB_H_
|
||||
#define ENCODETXB_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "av1/common/blockd.h"
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/common/txb_common.h"
|
||||
|
|
@ -25,6 +26,7 @@ extern "C" {
|
|||
|
||||
typedef struct TxbInfo {
|
||||
tran_low_t *qcoeff;
|
||||
uint8_t *levels; // absolute values and clamped to 255.
|
||||
tran_low_t *dqcoeff;
|
||||
const tran_low_t *tcoeff;
|
||||
const int16_t *dequant;
|
||||
|
|
@ -33,7 +35,7 @@ typedef struct TxbInfo {
|
|||
TX_SIZE txs_ctx;
|
||||
TX_TYPE tx_type;
|
||||
int bwl;
|
||||
int stride;
|
||||
int width;
|
||||
int height;
|
||||
int eob;
|
||||
int seg_eob;
|
||||
|
|
@ -41,51 +43,27 @@ typedef struct TxbInfo {
|
|||
TXB_CTX *txb_ctx;
|
||||
int64_t rdmult;
|
||||
const LV_MAP_CTX_TABLE *coeff_ctx_table;
|
||||
const qm_val_t *iqmatrix;
|
||||
int tx_type_cost;
|
||||
} TxbInfo;
|
||||
|
||||
typedef struct TxbCache {
|
||||
int nz_count_arr[MAX_TX_SQUARE];
|
||||
int nz_ctx_arr[MAX_TX_SQUARE];
|
||||
int base_count_arr[NUM_BASE_LEVELS][MAX_TX_SQUARE];
|
||||
int base_mag_arr[MAX_TX_SQUARE]
|
||||
[2]; // [0]: max magnitude [1]: num of max magnitude
|
||||
int base_ctx_arr[NUM_BASE_LEVELS][MAX_TX_SQUARE];
|
||||
|
||||
int br_count_arr[MAX_TX_SQUARE];
|
||||
int br_mag_arr[MAX_TX_SQUARE]
|
||||
[2]; // [0]: max magnitude [1]: num of max magnitude
|
||||
int br_ctx_arr[MAX_TX_SQUARE];
|
||||
} TxbCache;
|
||||
|
||||
typedef struct TxbProbs {
|
||||
const aom_prob *dc_sign_prob;
|
||||
const aom_prob *nz_map;
|
||||
aom_prob (*coeff_base)[COEFF_BASE_CONTEXTS];
|
||||
const aom_prob *coeff_lps;
|
||||
const aom_prob *eob_flag;
|
||||
const aom_prob *txb_skip;
|
||||
#if BR_NODE
|
||||
const aom_prob *coeff_br;
|
||||
#endif
|
||||
} TxbProbs;
|
||||
|
||||
void av1_alloc_txb_buf(AV1_COMP *cpi);
|
||||
void av1_free_txb_buf(AV1_COMP *cpi);
|
||||
int av1_cost_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
|
||||
int blk_row, int blk_col, int block, TX_SIZE tx_size,
|
||||
TXB_CTX *txb_ctx);
|
||||
int av1_cost_coeffs_txb(const AV1_COMMON *const cm, const MACROBLOCK *x,
|
||||
const int plane, const int blk_row, const int blk_col,
|
||||
const int block, const TX_SIZE tx_size,
|
||||
const TXB_CTX *const txb_ctx);
|
||||
void av1_write_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
|
||||
aom_writer *w, int blk_row, int blk_col, int block,
|
||||
int plane, TX_SIZE tx_size, const tran_low_t *tcoeff,
|
||||
aom_writer *w, int blk_row, int blk_col, int plane,
|
||||
TX_SIZE tx_size, const tran_low_t *tcoeff,
|
||||
uint16_t eob, TXB_CTX *txb_ctx);
|
||||
void av1_write_coeffs_mb(const AV1_COMMON *const cm, MACROBLOCK *x,
|
||||
aom_writer *w, int plane);
|
||||
void av1_write_coeffs_mb(const AV1_COMMON *const cm, MACROBLOCK *x, int mi_row,
|
||||
int mi_col, aom_writer *w, BLOCK_SIZE bsize);
|
||||
int av1_get_txb_entropy_context(const tran_low_t *qcoeff,
|
||||
const SCAN_ORDER *scan_order, int eob);
|
||||
void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td,
|
||||
RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
|
||||
const int mi_row, const int mi_col);
|
||||
void av1_write_txb_probs(AV1_COMP *cpi, aom_writer *w);
|
||||
int mi_row, int mi_col, uint8_t allow_update_cdf);
|
||||
|
||||
void av1_update_txb_context_b(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
|
||||
|
|
@ -98,16 +76,10 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row,
|
|||
void av1_set_coeff_buffer(const AV1_COMP *const cpi, MACROBLOCK *const x,
|
||||
int mi_row, int mi_col);
|
||||
|
||||
#if CONFIG_TXK_SEL
|
||||
int64_t av1_search_txk_type(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
||||
int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
|
||||
const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
|
||||
int use_fast_coef_costing, RD_STATS *rd_stats);
|
||||
#endif
|
||||
int av1_optimize_txb(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
|
||||
int blk_row, int blk_col, int block, TX_SIZE tx_size,
|
||||
TXB_CTX *txb_ctx, int fast_mode);
|
||||
void hbt_destroy();
|
||||
int av1_optimize_txb_new(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
||||
int block, TX_SIZE tx_size, TX_TYPE tx_type,
|
||||
const TXB_CTX *txb_ctx, int *rate_cost, int sharpness);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
58
third_party/aom/av1/encoder/ethread.c
vendored
58
third_party/aom/av1/encoder/ethread.c
vendored
|
|
@ -18,15 +18,13 @@ static void accumulate_rd_opt(ThreadData *td, ThreadData *td_t) {
|
|||
for (int i = 0; i < REFERENCE_MODES; i++)
|
||||
td->rd_counts.comp_pred_diff[i] += td_t->rd_counts.comp_pred_diff[i];
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
for (int i = 0; i < TOTAL_REFS_PER_FRAME; i++)
|
||||
for (int i = 0; i < REF_FRAMES; i++)
|
||||
td->rd_counts.global_motion_used[i] +=
|
||||
td_t->rd_counts.global_motion_used[i];
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
|
||||
td->rd_counts.compound_ref_used_flag |=
|
||||
td_t->rd_counts.compound_ref_used_flag;
|
||||
td->rd_counts.single_ref_used_flag |= td_t->rd_counts.single_ref_used_flag;
|
||||
td->rd_counts.skip_mode_used_flag |= td_t->rd_counts.skip_mode_used_flag;
|
||||
}
|
||||
|
||||
static int enc_worker_hook(EncWorkerData *const thread_data, void *unused) {
|
||||
|
|
@ -53,7 +51,7 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
AV1_COMMON *const cm = &cpi->common;
|
||||
const int tile_cols = cm->tile_cols;
|
||||
const AVxWorkerInterface *const winterface = aom_get_worker_interface();
|
||||
const int num_workers = AOMMIN(cpi->oxcf.max_threads, tile_cols);
|
||||
int num_workers = AOMMIN(cpi->oxcf.max_threads, tile_cols);
|
||||
int i;
|
||||
|
||||
av1_init_tile_data(cpi);
|
||||
|
|
@ -81,29 +79,19 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
aom_memalign(32, sizeof(*thread_data->td)));
|
||||
av1_zero(*thread_data->td);
|
||||
|
||||
// Set up pc_tree.
|
||||
#if !CONFIG_CB4X4
|
||||
thread_data->td->leaf_tree = NULL;
|
||||
#endif
|
||||
// Set up pc_tree.
|
||||
thread_data->td->pc_tree = NULL;
|
||||
av1_setup_pc_tree(cm, thread_data->td);
|
||||
|
||||
#if CONFIG_MOTION_VAR
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int buf_scaler = 2;
|
||||
#else
|
||||
int buf_scaler = 1;
|
||||
#endif
|
||||
CHECK_MEM_ERROR(cm, thread_data->td->above_pred_buf,
|
||||
(uint8_t *)aom_memalign(
|
||||
16,
|
||||
buf_scaler * MAX_MB_PLANE * MAX_SB_SQUARE *
|
||||
sizeof(*thread_data->td->above_pred_buf)));
|
||||
16, MAX_MB_PLANE * MAX_SB_SQUARE *
|
||||
sizeof(*thread_data->td->above_pred_buf)));
|
||||
CHECK_MEM_ERROR(cm, thread_data->td->left_pred_buf,
|
||||
(uint8_t *)aom_memalign(
|
||||
16,
|
||||
buf_scaler * MAX_MB_PLANE * MAX_SB_SQUARE *
|
||||
sizeof(*thread_data->td->left_pred_buf)));
|
||||
16, MAX_MB_PLANE * MAX_SB_SQUARE *
|
||||
sizeof(*thread_data->td->left_pred_buf)));
|
||||
|
||||
CHECK_MEM_ERROR(
|
||||
cm, thread_data->td->wsrc_buf,
|
||||
(int32_t *)aom_memalign(
|
||||
|
|
@ -112,7 +100,6 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
cm, thread_data->td->mask_buf,
|
||||
(int32_t *)aom_memalign(
|
||||
16, MAX_SB_SQUARE * sizeof(*thread_data->td->mask_buf)));
|
||||
#endif
|
||||
// Allocate frame counters in thread data.
|
||||
CHECK_MEM_ERROR(cm, thread_data->td->counts,
|
||||
aom_calloc(1, sizeof(*thread_data->td->counts)));
|
||||
|
|
@ -133,6 +120,8 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
|
||||
winterface->sync(worker);
|
||||
}
|
||||
} else {
|
||||
num_workers = AOMMIN(num_workers, cpi->num_workers);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_workers; i++) {
|
||||
|
|
@ -148,16 +137,13 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
if (thread_data->td != &cpi->td) {
|
||||
thread_data->td->mb = cpi->td.mb;
|
||||
thread_data->td->rd_counts = cpi->td.rd_counts;
|
||||
#if CONFIG_MOTION_VAR
|
||||
thread_data->td->mb.above_pred_buf = thread_data->td->above_pred_buf;
|
||||
thread_data->td->mb.left_pred_buf = thread_data->td->left_pred_buf;
|
||||
thread_data->td->mb.wsrc_buf = thread_data->td->wsrc_buf;
|
||||
thread_data->td->mb.mask_buf = thread_data->td->mask_buf;
|
||||
#endif
|
||||
}
|
||||
if (thread_data->td->counts != &cpi->common.counts) {
|
||||
memcpy(thread_data->td->counts, &cpi->common.counts,
|
||||
sizeof(cpi->common.counts));
|
||||
if (thread_data->td->counts != &cpi->counts) {
|
||||
memcpy(thread_data->td->counts, &cpi->counts, sizeof(cpi->counts));
|
||||
}
|
||||
|
||||
if (i < num_workers - 1)
|
||||
|
|
@ -187,14 +173,24 @@ void av1_encode_tiles_mt(AV1_COMP *cpi) {
|
|||
for (i = 0; i < num_workers; i++) {
|
||||
AVxWorker *const worker = &cpi->workers[i];
|
||||
EncWorkerData *const thread_data = (EncWorkerData *)worker->data1;
|
||||
|
||||
cpi->intrabc_used |= thread_data->td->intrabc_used_this_tile;
|
||||
// Accumulate counters.
|
||||
if (i < cpi->num_workers - 1) {
|
||||
av1_accumulate_frame_counts(&cm->counts, thread_data->td->counts);
|
||||
av1_accumulate_frame_counts(&cpi->counts, thread_data->td->counts);
|
||||
accumulate_rd_opt(&cpi->td, thread_data->td);
|
||||
#if CONFIG_VAR_TX
|
||||
cpi->td.mb.txb_split_count += thread_data->td->mb.txb_split_count;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate frame counts. FRAME_COUNTS consist solely of 'unsigned int'
|
||||
// members, so we treat it as an array, and sum over the whole length.
|
||||
void av1_accumulate_frame_counts(FRAME_COUNTS *acc_counts,
|
||||
const FRAME_COUNTS *counts) {
|
||||
unsigned int *const acc = (unsigned int *)acc_counts;
|
||||
const unsigned int *const cnt = (const unsigned int *)counts;
|
||||
|
||||
const unsigned int n_counts = sizeof(FRAME_COUNTS) / sizeof(unsigned int);
|
||||
|
||||
for (unsigned int i = 0; i < n_counts; i++) acc[i] += cnt[i];
|
||||
}
|
||||
|
|
|
|||
3
third_party/aom/av1/encoder/ethread.h
vendored
3
third_party/aom/av1/encoder/ethread.h
vendored
|
|
@ -27,6 +27,9 @@ typedef struct EncWorkerData {
|
|||
|
||||
void av1_encode_tiles_mt(struct AV1_COMP *cpi);
|
||||
|
||||
void av1_accumulate_frame_counts(struct FRAME_COUNTS *acc_counts,
|
||||
const struct FRAME_COUNTS *counts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
4
third_party/aom/av1/encoder/extend.c
vendored
4
third_party/aom/av1/encoder/extend.c
vendored
|
|
@ -57,7 +57,6 @@ static void copy_and_extend_plane(const uint8_t *src, int src_pitch,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
static void highbd_copy_and_extend_plane(const uint8_t *src8, int src_pitch,
|
||||
uint8_t *dst8, int dst_pitch, int w,
|
||||
int h, int extend_top, int extend_left,
|
||||
|
|
@ -100,7 +99,6 @@ static void highbd_copy_and_extend_plane(const uint8_t *src8, int src_pitch,
|
|||
dst_ptr2 += dst_pitch;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
void av1_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src,
|
||||
YV12_BUFFER_CONFIG *dst) {
|
||||
|
|
@ -124,7 +122,6 @@ void av1_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src,
|
|||
const int eb_uv = eb_y >> uv_height_subsampling;
|
||||
const int er_uv = er_y >> uv_width_subsampling;
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
highbd_copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer,
|
||||
dst->y_stride, src->y_crop_width,
|
||||
|
|
@ -139,7 +136,6 @@ void av1_copy_and_extend_frame(const YV12_BUFFER_CONFIG *src,
|
|||
src->uv_crop_width, src->uv_crop_height, et_uv, el_uv, eb_uv, er_uv);
|
||||
return;
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
copy_and_extend_plane(src->y_buffer, src->y_stride, dst->y_buffer,
|
||||
dst->y_stride, src->y_crop_width, src->y_crop_height,
|
||||
|
|
|
|||
522
third_party/aom/av1/encoder/firstpass.c
vendored
522
third_party/aom/av1/encoder/firstpass.c
vendored
File diff suppressed because it is too large
Load diff
14
third_party/aom/av1/encoder/firstpass.h
vendored
14
third_party/aom/av1/encoder/firstpass.h
vendored
|
|
@ -42,7 +42,6 @@ typedef struct {
|
|||
} FIRSTPASS_MB_STATS;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
// Length of the bi-predictive frame group (BFG)
|
||||
// NOTE: Currently each BFG contains one backward ref (BWF) frame plus a certain
|
||||
// number of bi-predictive frames.
|
||||
|
|
@ -64,7 +63,6 @@ typedef struct {
|
|||
#define MAX_SR_CODED_ERROR 40
|
||||
#define MAX_RAW_ERR_VAR 2000
|
||||
#define MIN_MV_IN_OUT 0.4
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#define VLOW_MOTION_THRESHOLD 950
|
||||
|
||||
|
|
@ -72,6 +70,7 @@ typedef struct {
|
|||
double frame;
|
||||
double weight;
|
||||
double intra_error;
|
||||
double frame_avg_wavelet_energy;
|
||||
double coded_error;
|
||||
double sr_coded_error;
|
||||
double pcnt_inter;
|
||||
|
|
@ -91,10 +90,8 @@ typedef struct {
|
|||
double new_mv_count;
|
||||
double duration;
|
||||
double count;
|
||||
#if CONFIG_EXT_REFS || CONFIG_BGSPRITE
|
||||
// standard deviation for (0, 0) motion prediction error
|
||||
double raw_error_stdev;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} FIRSTPASS_STATS;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -103,16 +100,12 @@ typedef enum {
|
|||
GF_UPDATE = 2,
|
||||
ARF_UPDATE = 3,
|
||||
OVERLAY_UPDATE = 4,
|
||||
#if CONFIG_EXT_REFS
|
||||
BRF_UPDATE = 5, // Backward Reference Frame
|
||||
LAST_BIPRED_UPDATE = 6, // Last Bi-predictive Frame
|
||||
BIPRED_UPDATE = 7, // Bi-predictive Frame, but not the last one
|
||||
INTNL_OVERLAY_UPDATE = 8, // Internal Overlay Frame
|
||||
INTNL_ARF_UPDATE = 9, // Internal Altref Frame (candidate for ALTREF2)
|
||||
FRAME_UPDATE_TYPES = 10
|
||||
#else // !CONFIG_EXT_REFS
|
||||
FRAME_UPDATE_TYPES = 5
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} FRAME_UPDATE_TYPE;
|
||||
|
||||
#define FC_ANIMATION_THRESH 0.15
|
||||
|
|
@ -129,13 +122,11 @@ typedef struct {
|
|||
unsigned char arf_src_offset[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
unsigned char arf_update_idx[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
unsigned char arf_ref_idx[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
#if CONFIG_EXT_REFS
|
||||
unsigned char brf_src_offset[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
unsigned char bidir_pred_enabled[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
unsigned char ref_fb_idx_map[(MAX_LAG_BUFFERS * 2) + 1][REF_FRAMES];
|
||||
unsigned char refresh_idx[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
unsigned char refresh_flag[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int bit_allocation[(MAX_LAG_BUFFERS * 2) + 1];
|
||||
} GF_GROUP;
|
||||
|
||||
|
|
@ -153,6 +144,7 @@ typedef struct {
|
|||
double modified_error_max;
|
||||
double modified_error_left;
|
||||
double mb_av_energy;
|
||||
double frame_avg_haar_energy;
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
uint8_t *frame_mb_stats_buf;
|
||||
|
|
@ -198,7 +190,6 @@ void av1_rc_get_second_pass_params(struct AV1_COMP *cpi);
|
|||
// Post encode update of the rate control parameters for 2-pass
|
||||
void av1_twopass_postencode_update(struct AV1_COMP *cpi);
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
#if USE_GF16_MULTI_LAYER
|
||||
void av1_ref_frame_map_idx_updates(struct AV1_COMP *cpi, int gf_frame_index);
|
||||
#endif // USE_GF16_MULTI_LAYER
|
||||
|
|
@ -213,7 +204,6 @@ static INLINE int get_number_of_extra_arfs(int interval, int arf_pending) {
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
157
third_party/aom/av1/encoder/generic_encoder.c
vendored
157
third_party/aom/av1/encoder/generic_encoder.c
vendored
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
#include "av1/common/generic_code.h"
|
||||
#include "av1/common/odintrin.h"
|
||||
#include "pvq_encoder.h"
|
||||
|
||||
/** Encodes a value from 0 to N-1 (with N up to 16) based on a cdf and adapts
|
||||
* the cdf accordingly.
|
||||
*
|
||||
* @param [in,out] w multi-symbol entropy encoder
|
||||
* @param [in] val variable being encoded
|
||||
* @param [in,out] cdf CDF of the variable (Q15)
|
||||
* @param [in] n number of values possible
|
||||
* @param [in,out] count number of symbols encoded with that cdf so far
|
||||
* @param [in] rate adaptation rate shift (smaller is faster)
|
||||
*/
|
||||
void aom_encode_cdf_adapt_q15(aom_writer *w, int val, uint16_t *cdf, int n,
|
||||
int *count, int rate) {
|
||||
int i;
|
||||
if (*count == 0) {
|
||||
/* On the first call, we normalize the cdf to (32768 - n). This should
|
||||
eventually be moved to the state init, but for now it makes it much
|
||||
easier to experiment and convert symbols to the Q15 adaptation.*/
|
||||
int ft;
|
||||
ft = cdf[n - 1];
|
||||
for (i = 0; i < n; i++) {
|
||||
cdf[i] = AOM_ICDF(cdf[i]*32768/ft);
|
||||
}
|
||||
}
|
||||
aom_write_cdf(w, val, cdf, n);
|
||||
aom_cdf_adapt_q15(val, cdf, n, count, rate);
|
||||
}
|
||||
|
||||
/** Encodes a random variable using a "generic" model, assuming that the
|
||||
* distribution is one-sided (zero and up), has a single mode, and decays
|
||||
* exponentially past the model.
|
||||
*
|
||||
* @param [in,out] w multi-symbol entropy encoder
|
||||
* @param [in,out] model generic probability model
|
||||
* @param [in] x variable being encoded
|
||||
* @param [in,out] ExQ16 expectation of x (adapted)
|
||||
* @param [in] integration integration period of ExQ16 (leaky average over
|
||||
* 1<<integration samples)
|
||||
*/
|
||||
void generic_encode(aom_writer *w, generic_encoder *model, int x,
|
||||
int *ex_q16, int integration) {
|
||||
int lg_q1;
|
||||
int shift;
|
||||
int id;
|
||||
uint16_t *cdf;
|
||||
int xs;
|
||||
lg_q1 = log_ex(*ex_q16);
|
||||
OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG,
|
||||
"%d %d", *ex_q16, lg_q1));
|
||||
/* If expectation is too large, shift x to ensure that
|
||||
all we have past xs=15 is the exponentially decaying tail
|
||||
of the distribution */
|
||||
shift = OD_MAXI(0, (lg_q1 - 5) >> 1);
|
||||
/* Choose the cdf to use: we have two per "octave" of ExQ16 */
|
||||
id = OD_MINI(GENERIC_TABLES - 1, lg_q1);
|
||||
cdf = model->cdf[id];
|
||||
xs = (x + (1 << shift >> 1)) >> shift;
|
||||
aom_write_symbol_pvq(w, OD_MINI(15, xs), cdf, 16);
|
||||
if (xs >= 15) {
|
||||
int e;
|
||||
unsigned decay;
|
||||
/* Estimate decay based on the assumption that the distribution is close
|
||||
to Laplacian for large values. We should probably have an adaptive
|
||||
estimate instead. Note: The 2* is a kludge that's not fully understood
|
||||
yet. */
|
||||
OD_ASSERT(*ex_q16 < INT_MAX >> 1);
|
||||
e = ((2**ex_q16 >> 8) + (1 << shift >> 1)) >> shift;
|
||||
decay = OD_MAXI(2, OD_MINI(254, 256*e/(e + 256)));
|
||||
/* Encode the tail of the distribution assuming exponential decay. */
|
||||
aom_laplace_encode_special(w, xs - 15, decay);
|
||||
}
|
||||
if (shift != 0) {
|
||||
int special;
|
||||
/* Because of the rounding, there's only half the number of possibilities
|
||||
for xs=0. */
|
||||
special = xs == 0;
|
||||
if (shift - special > 0) {
|
||||
aom_write_literal(w, x - (xs << shift) + (!special << (shift - 1)),
|
||||
shift - special);
|
||||
}
|
||||
}
|
||||
generic_model_update(ex_q16, x, integration);
|
||||
OD_LOG((OD_LOG_ENTROPY_CODER, OD_LOG_DEBUG,
|
||||
"enc: %d %d %d %d %d %x", *ex_q16, x, shift, id, xs, enc->rng));
|
||||
}
|
||||
|
||||
/** Estimates the cost of encoding a value with generic_encode().
|
||||
*
|
||||
* @param [in,out] model generic probability model
|
||||
* @param [in] x variable being encoded
|
||||
* @param [in,out] ExQ16 expectation of x (adapted)
|
||||
* @return number of bits (approximation)
|
||||
*/
|
||||
double generic_encode_cost(generic_encoder *model, int x, int *ex_q16) {
|
||||
int lg_q1;
|
||||
int shift;
|
||||
int id;
|
||||
uint16_t *cdf;
|
||||
int xs;
|
||||
int extra;
|
||||
lg_q1 = log_ex(*ex_q16);
|
||||
/* If expectation is too large, shift x to ensure that
|
||||
all we have past xs=15 is the exponentially decaying tail
|
||||
of the distribution */
|
||||
shift = OD_MAXI(0, (lg_q1 - 5) >> 1);
|
||||
/* Choose the cdf to use: we have two per "octave" of ExQ16 */
|
||||
id = OD_MINI(GENERIC_TABLES - 1, lg_q1);
|
||||
cdf = model->cdf[id];
|
||||
xs = (x + (1 << shift >> 1)) >> shift;
|
||||
extra = 0;
|
||||
if (shift) extra = shift - (xs == 0);
|
||||
xs = OD_MINI(15, xs);
|
||||
/* Shortcut: assume it's going to cost 2 bits for the Laplace coder. */
|
||||
if (xs == 15) extra += 2;
|
||||
return
|
||||
extra - OD_LOG2((double)(cdf[xs] - (xs == 0 ? 0 : cdf[xs - 1]))/cdf[15]);
|
||||
}
|
||||
|
||||
/*Estimates the cost of encoding a value with a given CDF.*/
|
||||
double od_encode_cdf_cost(int val, uint16_t *cdf, int n) {
|
||||
int total_prob;
|
||||
int prev_prob;
|
||||
double val_prob;
|
||||
OD_ASSERT(n > 0);
|
||||
total_prob = cdf[n - 1];
|
||||
if (val == 0) {
|
||||
prev_prob = 0;
|
||||
}
|
||||
else {
|
||||
prev_prob = cdf[val - 1];
|
||||
}
|
||||
val_prob = (cdf[val] - prev_prob) / (double)total_prob;
|
||||
return -OD_LOG2(val_prob);
|
||||
}
|
||||
109
third_party/aom/av1/encoder/global_motion.c
vendored
109
third_party/aom/av1/encoder/global_motion.c
vendored
|
|
@ -32,12 +32,14 @@
|
|||
// Border over which to compute the global motion
|
||||
#define ERRORADV_BORDER 0
|
||||
|
||||
#define ERRORADV_MAX_THRESH 0.995
|
||||
#define ERRORADV_COST_PRODUCT_THRESH 26000
|
||||
static const double erroradv_tr[] = { 0.75, 0.70, 0.65 };
|
||||
static const double erroradv_prod_tr[] = { 22000, 20000, 18000 };
|
||||
|
||||
int is_enough_erroradvantage(double best_erroradvantage, int params_cost) {
|
||||
return best_erroradvantage < ERRORADV_MAX_THRESH &&
|
||||
best_erroradvantage * params_cost < ERRORADV_COST_PRODUCT_THRESH;
|
||||
int is_enough_erroradvantage(double best_erroradvantage, int params_cost,
|
||||
int erroradv_type) {
|
||||
assert(erroradv_type < GM_ERRORADV_TR_TYPES);
|
||||
return best_erroradvantage < erroradv_tr[erroradv_type] &&
|
||||
best_erroradvantage * params_cost < erroradv_prod_tr[erroradv_type];
|
||||
}
|
||||
|
||||
static void convert_to_params(const double *params, int32_t *model) {
|
||||
|
|
@ -76,6 +78,7 @@ static void convert_to_params(const double *params, int32_t *model) {
|
|||
void convert_model_to_params(const double *params, WarpedMotionParams *model) {
|
||||
convert_to_params(params, model->wmmat);
|
||||
model->wmtype = get_gmtype(model);
|
||||
model->invalid = 0;
|
||||
}
|
||||
|
||||
// Adds some offset to a global motion parameter and handles
|
||||
|
|
@ -110,32 +113,31 @@ static int32_t add_param_offset(int param_index, int32_t param_value,
|
|||
|
||||
static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
|
||||
switch (wmtype) {
|
||||
case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
|
||||
case IDENTITY:
|
||||
wm->wmmat[0] = 0;
|
||||
wm->wmmat[1] = 0;
|
||||
AOM_FALLTHROUGH_INTENDED;
|
||||
case TRANSLATION:
|
||||
wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
|
||||
wm->wmmat[3] = 0;
|
||||
case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
|
||||
AOM_FALLTHROUGH_INTENDED;
|
||||
case ROTZOOM:
|
||||
wm->wmmat[4] = -wm->wmmat[3];
|
||||
wm->wmmat[5] = wm->wmmat[2];
|
||||
AOM_FALLTHROUGH_INTENDED;
|
||||
case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0; break;
|
||||
case HORTRAPEZOID: wm->wmmat[6] = wm->wmmat[4] = 0; break;
|
||||
case VERTRAPEZOID: wm->wmmat[7] = wm->wmmat[3] = 0; break;
|
||||
case HOMOGRAPHY: break;
|
||||
default: assert(0);
|
||||
}
|
||||
wm->wmtype = wmtype;
|
||||
}
|
||||
|
||||
int64_t refine_integerized_param(WarpedMotionParams *wm,
|
||||
TransformationType wmtype,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_hbd, int bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
TransformationType wmtype, int use_hbd, int bd,
|
||||
uint8_t *ref, int r_width, int r_height,
|
||||
int r_stride, uint8_t *dst, int d_width,
|
||||
int d_height, int d_stride, int n_refinements,
|
||||
int64_t best_frame_error) {
|
||||
static const int max_trans_model_params[TRANS_TYPES] = {
|
||||
0, 2, 4, 6, 8, 8, 8
|
||||
};
|
||||
static const int max_trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6 };
|
||||
const int border = ERRORADV_BORDER;
|
||||
int i = 0, p;
|
||||
int n_params = max_trans_model_params[wmtype];
|
||||
|
|
@ -147,35 +149,26 @@ int64_t refine_integerized_param(WarpedMotionParams *wm,
|
|||
int32_t best_param;
|
||||
|
||||
force_wmtype(wm, wmtype);
|
||||
best_error = av1_warp_error(
|
||||
wm,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_hbd, bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
|
||||
border, border, d_width - 2 * border, d_height - 2 * border, d_stride, 0,
|
||||
0, SCALE_SUBPEL_SHIFTS, SCALE_SUBPEL_SHIFTS, best_frame_error);
|
||||
best_error = av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
|
||||
dst + border * d_stride + border, border, border,
|
||||
d_width - 2 * border, d_height - 2 * border,
|
||||
d_stride, 0, 0, best_frame_error);
|
||||
best_error = AOMMIN(best_error, best_frame_error);
|
||||
step = 1 << (n_refinements - 1);
|
||||
for (i = 0; i < n_refinements; i++, step >>= 1) {
|
||||
for (p = 0; p < n_params; ++p) {
|
||||
int step_dir = 0;
|
||||
// Skip searches for parameters that are forced to be 0
|
||||
if (wmtype == HORTRAPEZOID && (p == 4 || p == 6)) continue;
|
||||
if (wmtype == VERTRAPEZOID && (p == 3 || p == 7)) continue;
|
||||
param = param_mat + p;
|
||||
curr_param = *param;
|
||||
best_param = curr_param;
|
||||
// look to the left
|
||||
*param = add_param_offset(p, curr_param, -step);
|
||||
step_error = av1_warp_error(
|
||||
wm,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_hbd, bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
|
||||
border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
|
||||
0, 0, SCALE_SUBPEL_SHIFTS, SCALE_SUBPEL_SHIFTS, best_error);
|
||||
step_error =
|
||||
av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
|
||||
dst + border * d_stride + border, border, border,
|
||||
d_width - 2 * border, d_height - 2 * border, d_stride,
|
||||
0, 0, best_error);
|
||||
if (step_error < best_error) {
|
||||
best_error = step_error;
|
||||
best_param = *param;
|
||||
|
|
@ -184,14 +177,11 @@ int64_t refine_integerized_param(WarpedMotionParams *wm,
|
|||
|
||||
// look to the right
|
||||
*param = add_param_offset(p, curr_param, step);
|
||||
step_error = av1_warp_error(
|
||||
wm,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_hbd, bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
|
||||
border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
|
||||
0, 0, SCALE_SUBPEL_SHIFTS, SCALE_SUBPEL_SHIFTS, best_error);
|
||||
step_error =
|
||||
av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
|
||||
dst + border * d_stride + border, border, border,
|
||||
d_width - 2 * border, d_height - 2 * border, d_stride,
|
||||
0, 0, best_error);
|
||||
if (step_error < best_error) {
|
||||
best_error = step_error;
|
||||
best_param = *param;
|
||||
|
|
@ -203,15 +193,11 @@ int64_t refine_integerized_param(WarpedMotionParams *wm,
|
|||
// for the biggest step size
|
||||
while (step_dir) {
|
||||
*param = add_param_offset(p, best_param, step * step_dir);
|
||||
step_error = av1_warp_error(
|
||||
wm,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_hbd, bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
|
||||
border, border, d_width - 2 * border, d_height - 2 * border,
|
||||
d_stride, 0, 0, SCALE_SUBPEL_SHIFTS, SCALE_SUBPEL_SHIFTS,
|
||||
best_error);
|
||||
step_error =
|
||||
av1_warp_error(wm, use_hbd, bd, ref, r_width, r_height, r_stride,
|
||||
dst + border * d_stride + border, border, border,
|
||||
d_width - 2 * border, d_height - 2 * border,
|
||||
d_stride, 0, 0, best_error);
|
||||
if (step_error < best_error) {
|
||||
best_error = step_error;
|
||||
best_param = *param;
|
||||
|
|
@ -229,9 +215,6 @@ int64_t refine_integerized_param(WarpedMotionParams *wm,
|
|||
|
||||
static INLINE RansacFunc get_ransac_type(TransformationType type) {
|
||||
switch (type) {
|
||||
case HOMOGRAPHY: return ransac_homography;
|
||||
case HORTRAPEZOID: return ransac_hortrapezoid;
|
||||
case VERTRAPEZOID: return ransac_vertrapezoid;
|
||||
case AFFINE: return ransac_affine;
|
||||
case ROTZOOM: return ransac_rotzoom;
|
||||
case TRANSLATION: return ransac_translation;
|
||||
|
|
@ -239,7 +222,6 @@ static INLINE RansacFunc get_ransac_type(TransformationType type) {
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
static unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm,
|
||||
int bit_depth) {
|
||||
int i, j;
|
||||
|
|
@ -257,14 +239,13 @@ static unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm,
|
|||
}
|
||||
return buf_8bit;
|
||||
}
|
||||
#endif
|
||||
|
||||
int compute_global_motion_feature_based(
|
||||
TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int bit_depth,
|
||||
#endif
|
||||
int *num_inliers_by_motion, double *params_by_motion, int num_motions) {
|
||||
int compute_global_motion_feature_based(TransformationType type,
|
||||
YV12_BUFFER_CONFIG *frm,
|
||||
YV12_BUFFER_CONFIG *ref, int bit_depth,
|
||||
int *num_inliers_by_motion,
|
||||
double *params_by_motion,
|
||||
int num_motions) {
|
||||
int i;
|
||||
int num_frm_corners, num_ref_corners;
|
||||
int num_correspondences;
|
||||
|
|
@ -274,7 +255,6 @@ int compute_global_motion_feature_based(
|
|||
unsigned char *ref_buffer = ref->y_buffer;
|
||||
RansacFunc ransac = get_ransac_type(type);
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
// The frame buffer is 16-bit, so we need to convert to 8 bits for the
|
||||
// following code. We cache the result until the frame is released.
|
||||
|
|
@ -283,7 +263,6 @@ int compute_global_motion_feature_based(
|
|||
if (ref->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
ref_buffer = downconvert_frame(ref, bit_depth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// compute interest points in images using FAST features
|
||||
num_frm_corners = fast_corner_detect(frm_buffer, frm->y_width, frm->y_height,
|
||||
|
|
|
|||
20
third_party/aom/av1/encoder/global_motion.h
vendored
20
third_party/aom/av1/encoder/global_motion.h
vendored
|
|
@ -24,16 +24,14 @@ extern "C" {
|
|||
|
||||
void convert_model_to_params(const double *params, WarpedMotionParams *model);
|
||||
|
||||
int is_enough_erroradvantage(double erroradv, int params_cost);
|
||||
int is_enough_erroradvantage(double best_erroradvantage, int params_cost,
|
||||
int erroradv_type);
|
||||
|
||||
// Returns the av1_warp_error between "dst" and the result of applying the
|
||||
// motion params that result from fine-tuning "wm" to "ref". Note that "wm" is
|
||||
// modified in place.
|
||||
int64_t refine_integerized_param(WarpedMotionParams *wm,
|
||||
TransformationType wmtype,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_hbd, int bd,
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
TransformationType wmtype, int use_hbd, int bd,
|
||||
uint8_t *ref, int r_width, int r_height,
|
||||
int r_stride, uint8_t *dst, int d_width,
|
||||
int d_height, int d_stride, int n_refinements,
|
||||
|
|
@ -54,12 +52,12 @@ int64_t refine_integerized_param(WarpedMotionParams *wm,
|
|||
number of inlier feature points for each motion. Params for which the
|
||||
num_inliers entry is 0 should be ignored by the caller.
|
||||
*/
|
||||
int compute_global_motion_feature_based(
|
||||
TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int bit_depth,
|
||||
#endif
|
||||
int *num_inliers_by_motion, double *params_by_motion, int num_motions);
|
||||
int compute_global_motion_feature_based(TransformationType type,
|
||||
YV12_BUFFER_CONFIG *frm,
|
||||
YV12_BUFFER_CONFIG *ref, int bit_depth,
|
||||
int *num_inliers_by_motion,
|
||||
double *params_by_motion,
|
||||
int num_motions);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
781
third_party/aom/av1/encoder/grain_test_vectors.h
vendored
Normal file
781
third_party/aom/av1/encoder/grain_test_vectors.h
vendored
Normal file
|
|
@ -0,0 +1,781 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#ifndef AV1_GRAIN_TEST_VECTORS_H_
|
||||
#define AV1_GRAIN_TEST_VECTORS_H_
|
||||
|
||||
/* Test vectors for emulation of different film grain types.
|
||||
* Note that bit depth would be derived from the bitstream and
|
||||
* not signaled in film grain metadata. The parameters are valid
|
||||
* for any bit depth.
|
||||
*/
|
||||
static aom_film_grain_t film_grain_test_vectors[16] = {
|
||||
/* Test 1 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 16, 0 },
|
||||
{ 25, 136 },
|
||||
{ 33, 144 },
|
||||
{ 41, 160 },
|
||||
{ 48, 168 },
|
||||
{ 56, 136 },
|
||||
{ 67, 128 },
|
||||
{ 82, 144 },
|
||||
{ 97, 152 },
|
||||
{ 113, 144 },
|
||||
{ 128, 176 },
|
||||
{ 143, 168 },
|
||||
{ 158, 176 },
|
||||
{ 178, 184 } },
|
||||
14 /* num_points_y */,
|
||||
{ { 16, 0 },
|
||||
{ 20, 64 },
|
||||
{ 28, 88 },
|
||||
{ 60, 104 },
|
||||
{ 90, 136 },
|
||||
{ 105, 160 },
|
||||
{ 134, 168 },
|
||||
{ 168, 208 } },
|
||||
8 /* num_cb_points */,
|
||||
{ { 16, 0 },
|
||||
{ 28, 96 },
|
||||
{ 56, 80 },
|
||||
{ 66, 96 },
|
||||
{ 80, 104 },
|
||||
{ 108, 96 },
|
||||
{ 122, 112 },
|
||||
{ 137, 112 },
|
||||
{ 169, 176 } },
|
||||
9 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 0, 0, -58, 0, 0, 0, -76, 100, -43, 0, -51, 82 },
|
||||
{ 0, 0, -49, 0, 0, 0, -36, 22, -30, 0, -38, 7, 39 },
|
||||
{ 0, 0, -47, 0, 0, 0, -31, 31, -25, 0, -32, 13, -100 },
|
||||
8 /* ar_coeff_shift */,
|
||||
247 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
18 /* cb_offset */,
|
||||
229 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
54 /* cr_offset */,
|
||||
0 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /* chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 2 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 0, 96 }, { 255, 96 } },
|
||||
2 /* num_points_y */,
|
||||
{ { 0, 64 }, { 255, 64 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 64 }, { 255, 64 } },
|
||||
2 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 3 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 0, 192 }, { 255, 192 } },
|
||||
2 /* num_points_y */,
|
||||
{ { 0, 128 }, { 255, 128 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 128 }, { 255, 128 } },
|
||||
2 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
4, -7, 2, 4, 12, -12, 5, -8, 6, 8, -19, -16, 19,
|
||||
-10, -2, 17, -42, 58, -2, -13, 9, 14, -36, 67, 0,
|
||||
},
|
||||
{
|
||||
4, -7, 2, 4, 12, -12, 5, -8, 6, 8, -19, -16, 19,
|
||||
-10, -2, 17, -42, 58, -2, -13, 9, 14, -36, 67, 0,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
1 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 4 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 24, 137 },
|
||||
{ 53, 146 },
|
||||
{ 63, 155 },
|
||||
{ 78, 155 },
|
||||
{ 107, 150 },
|
||||
{ 122, 147 },
|
||||
{ 136, 147 },
|
||||
{ 166, 153 },
|
||||
},
|
||||
9 /* num_points_y */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 20, 72 },
|
||||
{ 27, 82 },
|
||||
{ 33, 91 },
|
||||
{ 69, 121 },
|
||||
{ 95, 143 },
|
||||
{ 108, 154 },
|
||||
{ 134, 169 },
|
||||
{ 147, 177 },
|
||||
},
|
||||
9 /* num_cb_points */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 24, 95 },
|
||||
{ 54, 93 },
|
||||
{ 65, 94 },
|
||||
{ 79, 98 },
|
||||
{ 109, 107 },
|
||||
{ 124, 119 },
|
||||
{ 139, 136 },
|
||||
{ 169, 170 },
|
||||
},
|
||||
9 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
7, -9, 2, 4, 7, -12, 7, -18, 18, -30, -27, -42,
|
||||
13, -20, 7, -18, 6, 107, 55, -2, -4, -9, -22, 113,
|
||||
},
|
||||
{
|
||||
-3, -1, -4, 3, -6, -2, 3, 1, -4, -10, -10, -5, -5,
|
||||
-3, -1, -13, -28, -25, -31, -6, -4, 14, -64, 66, 0,
|
||||
},
|
||||
{
|
||||
0, 4, -3, 13, 0, 1, -3, 0, -3, -10, -68, -4, -2,
|
||||
-5, 2, -3, -20, 62, -31, 0, -4, -1, -8, -29, 0,
|
||||
},
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 5 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
0 /* update_parameters */,
|
||||
{ { 0, 64 }, { 255, 64 } },
|
||||
2 /* num_points_y */,
|
||||
{
|
||||
{ 0, 96 },
|
||||
{ 32, 90 },
|
||||
{ 64, 83 },
|
||||
{ 96, 76 },
|
||||
{ 128, 68 },
|
||||
{ 159, 59 },
|
||||
{ 191, 48 },
|
||||
{ 223, 34 },
|
||||
{ 255, 0 },
|
||||
},
|
||||
9 /* num_cb_points */,
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 32, 34 },
|
||||
{ 64, 48 },
|
||||
{ 96, 59 },
|
||||
{ 128, 68 },
|
||||
{ 159, 76 },
|
||||
{ 191, 83 },
|
||||
{ 223, 90 },
|
||||
{ 255, 96 },
|
||||
},
|
||||
9 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
-2, 2, -5, 7, -6, 4, -2, -1, 1, -2, 0, -2, 2,
|
||||
-3, -5, 13, -13, 6, -14, 8, -1, 18, -36, 58, 0,
|
||||
},
|
||||
{
|
||||
-2, -1, -3, 14, -4, -1, -3, 0, -1, 7, -31, 7, 2,
|
||||
0, 1, 0, -7, 50, -8, -2, 2, 2, 2, -4, 0,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
1063 /* random_seed */
|
||||
},
|
||||
/* Test 6 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 0, 96 },
|
||||
{ 20, 92 },
|
||||
{ 39, 88 },
|
||||
{ 59, 84 },
|
||||
{ 78, 80 },
|
||||
{ 98, 75 },
|
||||
{ 118, 70 },
|
||||
{ 137, 65 },
|
||||
{ 157, 60 },
|
||||
{ 177, 53 },
|
||||
{ 196, 46 },
|
||||
{ 216, 38 },
|
||||
{ 235, 27 },
|
||||
{ 255, 0 },
|
||||
},
|
||||
14 /* num_points_y */,
|
||||
{ { 0, 0 } },
|
||||
0 /* num_cb_points */,
|
||||
{ { 0, 0 } },
|
||||
0 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
2754 /* random_seed */
|
||||
},
|
||||
/* Test 7 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 20, 27 },
|
||||
{ 39, 38 },
|
||||
{ 59, 46 },
|
||||
{ 78, 53 },
|
||||
{ 98, 60 },
|
||||
{ 118, 65 },
|
||||
{ 137, 70 },
|
||||
{ 157, 75 },
|
||||
{ 177, 80 },
|
||||
{ 196, 84 },
|
||||
{ 216, 88 },
|
||||
{ 235, 92 },
|
||||
{ 255, 96 },
|
||||
},
|
||||
14 /* num_points_y */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
2 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 8 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 0, 96 }, { 255, 96 } },
|
||||
2 /* num_points_y */,
|
||||
{ { 0, 62 }, { 255, 62 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 62 }, { 255, 62 } },
|
||||
2 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
0, -2, -2, 8, 5, -1, 1, -1, 5, 16, -33, -9, 6,
|
||||
-1, -3, 10, -47, 63, 0, -15, 3, 11, -42, 75, -69,
|
||||
},
|
||||
{
|
||||
1, -1, -1, 9, 5, 0, 1, -1, 5, 15, -32, -10, 8,
|
||||
-2, -4, 11, -46, 62, 1, -16, 3, 13, -43, 75, -55,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 9 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
0 /* update_parameters */,
|
||||
{ { 0, 48 }, { 255, 48 } },
|
||||
2 /* num_points_y */,
|
||||
{ { 0, 32 }, { 255, 32 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 32 }, { 255, 32 } },
|
||||
2 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 10, -30, -20, -39, 1, -24, 12, 103, 60, -9, -24, 113 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127 },
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 10 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 0, 48 }, { 255, 48 } },
|
||||
2 /* num_points_y */,
|
||||
{ { 0, 32 }, { 255, 32 } },
|
||||
2 /* num_cb_points */,
|
||||
{ { 0, 32 }, { 255, 32 } },
|
||||
2 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 10, -30, -20, -39, 1, -24, 12, 103, 60, -9, -24, 113 },
|
||||
{ -7, -6, -48, -22, 2, -3, -45, 73, -11, -26, -52, 76, 0 },
|
||||
{ -7, -6, -48, -22, 2, -3, -45, 73, -11, -26, -52, 76, 0 },
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 11 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
0 /* update_parameters */,
|
||||
{ { 0, 32 }, { 255, 32 } },
|
||||
2 /* num_points_y */,
|
||||
{
|
||||
{ 0, 48 },
|
||||
{ 32, 45 },
|
||||
{ 64, 42 },
|
||||
{ 96, 38 },
|
||||
{ 128, 34 },
|
||||
{ 159, 29 },
|
||||
{ 191, 24 },
|
||||
{ 223, 17 },
|
||||
{ 255, 0 },
|
||||
},
|
||||
9 /* num_cb_points */,
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 32, 17 },
|
||||
{ 64, 24 },
|
||||
{ 96, 29 },
|
||||
{ 128, 34 },
|
||||
{ 159, 38 },
|
||||
{ 191, 42 },
|
||||
{ 223, 45 },
|
||||
{ 255, 48 },
|
||||
},
|
||||
9 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
7, -9, 2, 4, 7, -12, 7, -18, 18, -30, -27, -42,
|
||||
13, -20, 7, -18, 6, 107, 55, -2, -4, -9, -22, 113,
|
||||
},
|
||||
{
|
||||
-3, -1, -4, 3, -6, -2, 3, 1, -4, -10, -10, -5, -5,
|
||||
-3, -1, -13, -28, -25, -31, -6, -4, 14, -64, 66, 0,
|
||||
},
|
||||
{
|
||||
0, 4, -3, 13, 0, 1, -3, 0, -3, -10, -68, -4, -2,
|
||||
-5, 2, -3, -20, 62, -31, 0, -4, -1, -8, -29, 0,
|
||||
},
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
1357 /* random_seed */
|
||||
},
|
||||
/* Test 12 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 24, 49 },
|
||||
{ 39, 69 },
|
||||
{ 46, 84 },
|
||||
{ 53, 91 },
|
||||
{ 63, 100 },
|
||||
{ 78, 114 },
|
||||
{ 92, 134 },
|
||||
{ 164, 139 },
|
||||
},
|
||||
9 /* num_points_y */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 20, 31 },
|
||||
{ 26, 42 },
|
||||
{ 33, 54 },
|
||||
{ 40, 65 },
|
||||
{ 47, 72 },
|
||||
{ 56, 85 },
|
||||
{ 84, 123 },
|
||||
{ 152, 157 },
|
||||
},
|
||||
9 /* num_cb_points */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 25, 14 },
|
||||
{ 39, 33 },
|
||||
{ 47, 40 },
|
||||
{ 54, 47 },
|
||||
{ 64, 62 },
|
||||
{ 79, 76 },
|
||||
{ 94, 83 },
|
||||
{ 167, 101 },
|
||||
},
|
||||
9 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 0, 0, -58, 0, 0, 0, -76, 100, -43, 0, -51, 82 },
|
||||
{ 0, 0, -49, 0, 0, 0, -36, 22, -30, 0, -38, 7, 39 },
|
||||
{ 0, 0, -47, 0, 0, 0, -31, 31, -25, 0, -32, 13, -100 },
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
0 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 13 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 0, 48 },
|
||||
{ 20, 46 },
|
||||
{ 39, 44 },
|
||||
{ 59, 42 },
|
||||
{ 78, 40 },
|
||||
{ 98, 38 },
|
||||
{ 118, 35 },
|
||||
{ 137, 33 },
|
||||
{ 157, 30 },
|
||||
{ 177, 27 },
|
||||
{ 196, 23 },
|
||||
{ 216, 19 },
|
||||
{ 235, 13 },
|
||||
{ 255, 0 },
|
||||
},
|
||||
14 /* num_points_y */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
0 /* num_cb_points */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
0 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 10, -30, -20, -39, 1, -24, 12, 103, 60, -9, -24, 113 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 14 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 20, 13 },
|
||||
{ 39, 19 },
|
||||
{ 59, 23 },
|
||||
{ 78, 27 },
|
||||
{ 98, 30 },
|
||||
{ 118, 33 },
|
||||
{ 137, 35 },
|
||||
{ 157, 38 },
|
||||
{ 177, 40 },
|
||||
{ 196, 42 },
|
||||
{ 216, 44 },
|
||||
{ 235, 46 },
|
||||
{ 255, 48 },
|
||||
},
|
||||
14 /* num_points_y */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
0 /* num_cb_points */,
|
||||
{ { 0, 0 }, { 255, 0 } },
|
||||
0 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 10, -30, -20, -39, 1, -24, 12, 103, 60, -9, -24, 113 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
8 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
1 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 15 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{ { 0, 96 }, { 255, 96 } },
|
||||
1 /* num_points_y */,
|
||||
{ { 0, 96 }, { 255, 96 } },
|
||||
0 /* num_cb_points */,
|
||||
{ { 0, 96 }, { 255, 96 } },
|
||||
0 /* num_cr_points */,
|
||||
11 /* scaling_shift */,
|
||||
2 /* ar_coeff_lag */,
|
||||
{ 5, -15, -10, -19, 0, -12, 6, 51, 30, -5, -12, 56 },
|
||||
{ 2, 2, -24, -5, 1, 1, -18, 37, -2, 0, -15, 39, -70 },
|
||||
{ 2, 3, -24, -5, -1, 0, -18, 38, -2, 0, -15, 39, -55 },
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
1 /*chroma_scaling_from_luma*/,
|
||||
0 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
/* Test 16 */
|
||||
{
|
||||
1 /* apply_grain */,
|
||||
1 /* update_parameters */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 58, 126 },
|
||||
{ 87, 120 },
|
||||
{ 97, 122 },
|
||||
{ 112, 125 },
|
||||
{ 126, 131 },
|
||||
{ 141, 139 },
|
||||
{ 199, 153 },
|
||||
},
|
||||
8 /* num_points_y */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 59, 68 },
|
||||
{ 66, 76 },
|
||||
{ 73, 82 },
|
||||
{ 79, 85 },
|
||||
{ 86, 86 },
|
||||
{ 151, 95 },
|
||||
{ 192, 101 },
|
||||
},
|
||||
8 /* num_cb_points */,
|
||||
{
|
||||
{ 16, 0 },
|
||||
{ 59, 64 },
|
||||
{ 89, 80 },
|
||||
{ 99, 86 },
|
||||
{ 114, 90 },
|
||||
{ 129, 93 },
|
||||
{ 144, 97 },
|
||||
{ 203, 85 },
|
||||
},
|
||||
8 /* num_cr_points */,
|
||||
10 /* scaling_shift */,
|
||||
3 /* ar_coeff_lag */,
|
||||
{
|
||||
4, 1, 3, 0, 1, -3, 8, -3, 7, -23, 1, -25,
|
||||
0, -10, 6, -17, -4, 53, 36, 5, -5, -17, 8, 66,
|
||||
},
|
||||
{
|
||||
0, -2, -2, 8, 5, -1, 1, -1, 5, 16, -33, -9, 6,
|
||||
-1, -3, 10, -47, 63, 0, -15, 3, 11, -42, 75, -69,
|
||||
},
|
||||
{
|
||||
1, -1, -1, 9, 5, 0, 1, -1, 5, 15, -32, -10, 8,
|
||||
-2, -4, 11, -46, 62, 1, -16, 3, 13, -43, 75, -55,
|
||||
},
|
||||
7 /* ar_coeff_shift */,
|
||||
128 /* cb_mult */,
|
||||
192 /* cb_luma_mult */,
|
||||
256 /* cb_offset */,
|
||||
128 /* cr_mult */,
|
||||
192 /* cr_luma_mult */,
|
||||
256 /* cr_offset */,
|
||||
1 /* overlap_flag */,
|
||||
0 /* clip_to_restricted_range */,
|
||||
8 /* bit_depth */,
|
||||
0 /*chroma_scaling_from_luma*/,
|
||||
2 /* grain_scale_shift*/,
|
||||
45231 /* random_seed */
|
||||
},
|
||||
};
|
||||
#endif // AV1_GRAIN_TEST_VECTORS_H_
|
||||
62
third_party/aom/av1/encoder/hash.c
vendored
62
third_party/aom/av1/encoder/hash.c
vendored
|
|
@ -22,7 +22,7 @@ static void crc_calculator_process_data(CRC_CALCULATOR *p_crc_calculator,
|
|||
}
|
||||
}
|
||||
|
||||
void crc_calculator_reset(CRC_CALCULATOR *p_crc_calculator) {
|
||||
static void crc_calculator_reset(CRC_CALCULATOR *p_crc_calculator) {
|
||||
p_crc_calculator->remainder = 0;
|
||||
}
|
||||
|
||||
|
|
@ -61,9 +61,65 @@ void av1_crc_calculator_init(CRC_CALCULATOR *p_crc_calculator, uint32_t bits,
|
|||
crc_calculator_init_table(p_crc_calculator);
|
||||
}
|
||||
|
||||
uint32_t av1_get_crc_value(CRC_CALCULATOR *p_crc_calculator, uint8_t *p,
|
||||
int length) {
|
||||
uint32_t av1_get_crc_value(void *crc_calculator, uint8_t *p, int length) {
|
||||
CRC_CALCULATOR *p_crc_calculator = (CRC_CALCULATOR *)crc_calculator;
|
||||
crc_calculator_reset(p_crc_calculator);
|
||||
crc_calculator_process_data(p_crc_calculator, p, length);
|
||||
return crc_calculator_get_crc(p_crc_calculator);
|
||||
}
|
||||
|
||||
/* CRC-32C (iSCSI) polynomial in reversed bit order. */
|
||||
#define POLY 0x82f63b78
|
||||
|
||||
/* Construct table for software CRC-32C calculation. */
|
||||
void av1_crc32c_calculator_init(CRC32C *p_crc32c) {
|
||||
uint32_t crc;
|
||||
|
||||
for (int n = 0; n < 256; n++) {
|
||||
crc = n;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
|
||||
p_crc32c->table[0][n] = crc;
|
||||
}
|
||||
for (int n = 0; n < 256; n++) {
|
||||
crc = p_crc32c->table[0][n];
|
||||
for (int k = 1; k < 8; k++) {
|
||||
crc = p_crc32c->table[0][crc & 0xff] ^ (crc >> 8);
|
||||
p_crc32c->table[k][n] = crc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Table-driven software version as a fall-back. This is about 15 times slower
|
||||
than using the hardware instructions. This assumes little-endian integers,
|
||||
as is the case on Intel processors that the assembler code here is for. */
|
||||
uint32_t av1_get_crc32c_value_c(CRC32C *p, uint8_t *buf, size_t len) {
|
||||
const uint8_t *next = (const uint8_t *)(buf);
|
||||
uint64_t crc;
|
||||
|
||||
crc = 0 ^ 0xffffffff;
|
||||
while (len && ((uintptr_t)next & 7) != 0) {
|
||||
crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
|
||||
len--;
|
||||
}
|
||||
while (len >= 8) {
|
||||
crc ^= *(uint64_t *)next;
|
||||
crc = p->table[7][crc & 0xff] ^ p->table[6][(crc >> 8) & 0xff] ^
|
||||
p->table[5][(crc >> 16) & 0xff] ^ p->table[4][(crc >> 24) & 0xff] ^
|
||||
p->table[3][(crc >> 32) & 0xff] ^ p->table[2][(crc >> 40) & 0xff] ^
|
||||
p->table[1][(crc >> 48) & 0xff] ^ p->table[0][crc >> 56];
|
||||
next += 8;
|
||||
len -= 8;
|
||||
}
|
||||
while (len) {
|
||||
crc = p->table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
|
||||
len--;
|
||||
}
|
||||
return (uint32_t)crc ^ 0xffffffff;
|
||||
}
|
||||
|
|
|
|||
14
third_party/aom/av1/encoder/hash.h
vendored
14
third_party/aom/av1/encoder/hash.h
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#ifndef AV1_ENCODER_HASH_H_
|
||||
#define AV1_ENCODER_HASH_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -31,9 +32,16 @@ typedef struct _crc_calculator {
|
|||
// calling av1_get_crc_value().
|
||||
void av1_crc_calculator_init(CRC_CALCULATOR *p_crc_calculator, uint32_t bits,
|
||||
uint32_t truncPoly);
|
||||
uint32_t av1_get_crc_value(void *crc_calculator, uint8_t *p, int length);
|
||||
|
||||
uint32_t av1_get_crc_value(CRC_CALCULATOR *p_crc_calculator, uint8_t *p,
|
||||
int length);
|
||||
// CRC32C: POLY = 0x82f63b78;
|
||||
typedef struct _CRC32C {
|
||||
/* Table for a quadword-at-a-time software crc. */
|
||||
uint32_t table[8][256];
|
||||
} CRC32C;
|
||||
|
||||
// init table for software version crc32c
|
||||
void av1_crc32c_calculator_init(CRC32C *p_crc32c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
205
third_party/aom/av1/encoder/hash_motion.c
vendored
205
third_party/aom/av1/encoder/hash_motion.c
vendored
|
|
@ -1,7 +1,9 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "config/av1_rtcd.h"
|
||||
|
||||
#include "av1/encoder/hash.h"
|
||||
#include "av1/encoder/hash_motion.h"
|
||||
#include "./av1_rtcd.h"
|
||||
|
||||
static const int crc_bits = 16;
|
||||
static const int block_size_bits = 3;
|
||||
|
|
@ -16,7 +18,7 @@ static void hash_table_clear_all(hash_table *p_hash_table) {
|
|||
int max_addr = 1 << (crc_bits + block_size_bits);
|
||||
for (int i = 0; i < max_addr; i++) {
|
||||
if (p_hash_table->p_lookup_table[i] != NULL) {
|
||||
vector_destroy(p_hash_table->p_lookup_table[i]);
|
||||
aom_vector_destroy(p_hash_table->p_lookup_table[i]);
|
||||
aom_free(p_hash_table->p_lookup_table[i]);
|
||||
p_hash_table->p_lookup_table[i] = NULL;
|
||||
}
|
||||
|
|
@ -37,11 +39,30 @@ static void get_pixels_in_1D_char_array_by_block_2x2(uint8_t *y_src, int stride,
|
|||
}
|
||||
}
|
||||
|
||||
static void get_pixels_in_1D_short_array_by_block_2x2(uint16_t *y_src,
|
||||
int stride,
|
||||
uint16_t *p_pixels_in1D) {
|
||||
uint16_t *p_pel = y_src;
|
||||
int index = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
p_pixels_in1D[index++] = p_pel[j];
|
||||
}
|
||||
p_pel += stride;
|
||||
}
|
||||
}
|
||||
|
||||
static int is_block_2x2_row_same_value(uint8_t *p) {
|
||||
if (p[0] != p[1] || p[2] != p[3]) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_block16_2x2_row_same_value(uint16_t *p) {
|
||||
if (p[0] != p[1] || p[2] != p[3]) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +70,13 @@ static int is_block_2x2_col_same_value(uint8_t *p) {
|
|||
if ((p[0] != p[2]) || (p[1] != p[3])) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_block16_2x2_col_same_value(uint16_t *p) {
|
||||
if ((p[0] != p[2]) || (p[1] != p[3])) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +90,7 @@ static int hash_block_size_to_index(int block_size) {
|
|||
case 16: return 2;
|
||||
case 32: return 3;
|
||||
case 64: return 4;
|
||||
case 128: return 5;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -100,11 +128,13 @@ static void hash_table_add_to_table(hash_table *p_hash_table,
|
|||
if (p_hash_table->p_lookup_table[hash_value] == NULL) {
|
||||
p_hash_table->p_lookup_table[hash_value] =
|
||||
aom_malloc(sizeof(p_hash_table->p_lookup_table[0][0]));
|
||||
vector_setup(p_hash_table->p_lookup_table[hash_value], 10,
|
||||
sizeof(curr_block_hash[0]));
|
||||
vector_push_back(p_hash_table->p_lookup_table[hash_value], curr_block_hash);
|
||||
aom_vector_setup(p_hash_table->p_lookup_table[hash_value], 10,
|
||||
sizeof(curr_block_hash[0]));
|
||||
aom_vector_push_back(p_hash_table->p_lookup_table[hash_value],
|
||||
curr_block_hash);
|
||||
} else {
|
||||
vector_push_back(p_hash_table->p_lookup_table[hash_value], curr_block_hash);
|
||||
aom_vector_push_back(p_hash_table->p_lookup_table[hash_value],
|
||||
curr_block_hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +149,7 @@ int32_t av1_hash_table_count(hash_table *p_hash_table, uint32_t hash_value) {
|
|||
Iterator av1_hash_get_first_iterator(hash_table *p_hash_table,
|
||||
uint32_t hash_value) {
|
||||
assert(av1_hash_table_count(p_hash_table, hash_value) > 0);
|
||||
return vector_begin(p_hash_table->p_lookup_table[hash_value]);
|
||||
return aom_vector_begin(p_hash_table->p_lookup_table[hash_value]);
|
||||
}
|
||||
|
||||
int32_t av1_has_exact_match(hash_table *p_hash_table, uint32_t hash_value1,
|
||||
|
|
@ -127,8 +157,9 @@ int32_t av1_has_exact_match(hash_table *p_hash_table, uint32_t hash_value1,
|
|||
if (p_hash_table->p_lookup_table[hash_value1] == NULL) {
|
||||
return 0;
|
||||
}
|
||||
Iterator iterator = vector_begin(p_hash_table->p_lookup_table[hash_value1]);
|
||||
Iterator last = vector_end(p_hash_table->p_lookup_table[hash_value1]);
|
||||
Iterator iterator =
|
||||
aom_vector_begin(p_hash_table->p_lookup_table[hash_value1]);
|
||||
Iterator last = aom_vector_end(p_hash_table->p_lookup_table[hash_value1]);
|
||||
for (; !iterator_equals(&iterator, &last); iterator_increment(&iterator)) {
|
||||
if ((*(block_hash *)iterator_get(&iterator)).hash_value2 == hash_value2) {
|
||||
return 1;
|
||||
|
|
@ -146,25 +177,45 @@ void av1_generate_block_2x2_hash_value(const YV12_BUFFER_CONFIG *picture,
|
|||
const int y_end = picture->y_crop_height - height + 1;
|
||||
|
||||
const int length = width * 2;
|
||||
uint8_t p[4];
|
||||
if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
uint16_t p[4];
|
||||
int pos = 0;
|
||||
for (int y_pos = 0; y_pos < y_end; y_pos++) {
|
||||
for (int x_pos = 0; x_pos < x_end; x_pos++) {
|
||||
get_pixels_in_1D_short_array_by_block_2x2(
|
||||
CONVERT_TO_SHORTPTR(picture->y_buffer) + y_pos * picture->y_stride +
|
||||
x_pos,
|
||||
picture->y_stride, p);
|
||||
pic_block_same_info[0][pos] = is_block16_2x2_row_same_value(p);
|
||||
pic_block_same_info[1][pos] = is_block16_2x2_col_same_value(p);
|
||||
|
||||
int pos = 0;
|
||||
for (int y_pos = 0; y_pos < y_end; y_pos++) {
|
||||
for (int x_pos = 0; x_pos < x_end; x_pos++) {
|
||||
get_pixels_in_1D_char_array_by_block_2x2(
|
||||
picture->y_buffer + y_pos * picture->y_stride + x_pos,
|
||||
picture->y_stride, p);
|
||||
pic_block_same_info[0][pos] = is_block_2x2_row_same_value(p);
|
||||
pic_block_same_info[1][pos] = is_block_2x2_col_same_value(p);
|
||||
|
||||
pic_block_hash[0][pos] =
|
||||
av1_get_crc_value(&crc_calculator1, p, length * sizeof(p[0]));
|
||||
pic_block_hash[1][pos] =
|
||||
av1_get_crc_value(&crc_calculator2, p, length * sizeof(p[0]));
|
||||
|
||||
pos++;
|
||||
pic_block_hash[0][pos] = av1_get_crc_value(
|
||||
&crc_calculator1, (uint8_t *)p, length * sizeof(p[0]));
|
||||
pic_block_hash[1][pos] = av1_get_crc_value(
|
||||
&crc_calculator2, (uint8_t *)p, length * sizeof(p[0]));
|
||||
pos++;
|
||||
}
|
||||
pos += width - 1;
|
||||
}
|
||||
} else {
|
||||
uint8_t p[4];
|
||||
int pos = 0;
|
||||
for (int y_pos = 0; y_pos < y_end; y_pos++) {
|
||||
for (int x_pos = 0; x_pos < x_end; x_pos++) {
|
||||
get_pixels_in_1D_char_array_by_block_2x2(
|
||||
picture->y_buffer + y_pos * picture->y_stride + x_pos,
|
||||
picture->y_stride, p);
|
||||
pic_block_same_info[0][pos] = is_block_2x2_row_same_value(p);
|
||||
pic_block_same_info[1][pos] = is_block_2x2_col_same_value(p);
|
||||
|
||||
pic_block_hash[0][pos] =
|
||||
av1_get_crc_value(&crc_calculator1, p, length * sizeof(p[0]));
|
||||
pic_block_hash[1][pos] =
|
||||
av1_get_crc_value(&crc_calculator2, p, length * sizeof(p[0]));
|
||||
pos++;
|
||||
}
|
||||
pos += width - 1;
|
||||
}
|
||||
pos += width - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,14 +273,14 @@ void av1_generate_block_hash_value(const YV12_BUFFER_CONFIG *picture,
|
|||
}
|
||||
|
||||
if (block_size >= 4) {
|
||||
const int size_minus1 = block_size - 1;
|
||||
const int size_minus_1 = block_size - 1;
|
||||
pos = 0;
|
||||
for (int y_pos = 0; y_pos < y_end; y_pos++) {
|
||||
for (int x_pos = 0; x_pos < x_end; x_pos++) {
|
||||
dst_pic_block_same_info[2][pos] =
|
||||
(!dst_pic_block_same_info[0][pos] &&
|
||||
!dst_pic_block_same_info[1][pos]) ||
|
||||
(((x_pos & size_minus1) == 0) && ((y_pos & size_minus1) == 0));
|
||||
(((x_pos & size_minus_1) == 0) && ((y_pos & size_minus_1) == 0));
|
||||
pos++;
|
||||
}
|
||||
pos += block_size - 1;
|
||||
|
|
@ -276,13 +327,25 @@ int av1_hash_is_horizontal_perfect(const YV12_BUFFER_CONFIG *picture,
|
|||
const int stride = picture->y_stride;
|
||||
const uint8_t *p = picture->y_buffer + y_start * stride + x_start;
|
||||
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p[j] != p[0]) {
|
||||
return 0;
|
||||
if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
const uint16_t *p16 = CONVERT_TO_SHORTPTR(p);
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p16[j] != p16[0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p16 += stride;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p[j] != p[0]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p += stride;
|
||||
}
|
||||
p += stride;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -293,26 +356,38 @@ int av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG *picture,
|
|||
const int stride = picture->y_stride;
|
||||
const uint8_t *p = picture->y_buffer + y_start * stride + x_start;
|
||||
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p[j * stride + i] != p[i]) {
|
||||
return 0;
|
||||
if (picture->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
const uint16_t *p16 = CONVERT_TO_SHORTPTR(p);
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p16[j * stride + i] != p16[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
for (int j = 1; j < block_size; j++) {
|
||||
if (p[j * stride + i] != p[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// global buffer for hash value calculation of a block
|
||||
// used only in av1_get_block_hash_value()
|
||||
static uint32_t hash_value_buffer[2][2][1024]; // [first hash/second hash]
|
||||
// [two buffers used ping-pong]
|
||||
// [num of 2x2 blocks in 64x64]
|
||||
#define AOM_BUFFER_SIZE_FOR_BLOCK_HASH (4096)
|
||||
// [first hash/second hash]
|
||||
// [two buffers used ping-pong]
|
||||
// [num of 2x2 blocks in 128x128]
|
||||
static uint32_t hash_value_buffer[2][2][AOM_BUFFER_SIZE_FOR_BLOCK_HASH];
|
||||
|
||||
void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
||||
uint32_t *hash_value1, uint32_t *hash_value2) {
|
||||
uint8_t pixel_to_hash[4];
|
||||
uint32_t *hash_value1, uint32_t *hash_value2,
|
||||
int use_highbitdepth) {
|
||||
uint32_t to_hash[4];
|
||||
const int add_value = hash_block_size_to_index(block_size) << crc_bits;
|
||||
assert(add_value >= 0);
|
||||
|
|
@ -320,16 +395,34 @@ void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
|||
|
||||
// 2x2 subblock hash values in current CU
|
||||
int sub_block_in_width = (block_size >> 1);
|
||||
for (int y_pos = 0; y_pos < block_size; y_pos += 2) {
|
||||
for (int x_pos = 0; x_pos < block_size; x_pos += 2) {
|
||||
int pos = (y_pos >> 1) * sub_block_in_width + (x_pos >> 1);
|
||||
get_pixels_in_1D_char_array_by_block_2x2(y_src + y_pos * stride + x_pos,
|
||||
stride, pixel_to_hash);
|
||||
|
||||
hash_value_buffer[0][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator1, pixel_to_hash, sizeof(pixel_to_hash));
|
||||
hash_value_buffer[1][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator2, pixel_to_hash, sizeof(pixel_to_hash));
|
||||
if (use_highbitdepth) {
|
||||
uint16_t pixel_to_hash[4];
|
||||
uint16_t *y16_src = CONVERT_TO_SHORTPTR(y_src);
|
||||
for (int y_pos = 0; y_pos < block_size; y_pos += 2) {
|
||||
for (int x_pos = 0; x_pos < block_size; x_pos += 2) {
|
||||
int pos = (y_pos >> 1) * sub_block_in_width + (x_pos >> 1);
|
||||
get_pixels_in_1D_short_array_by_block_2x2(
|
||||
y16_src + y_pos * stride + x_pos, stride, pixel_to_hash);
|
||||
assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
|
||||
hash_value_buffer[0][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator1, (uint8_t *)pixel_to_hash, sizeof(pixel_to_hash));
|
||||
hash_value_buffer[1][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator2, (uint8_t *)pixel_to_hash, sizeof(pixel_to_hash));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint8_t pixel_to_hash[4];
|
||||
for (int y_pos = 0; y_pos < block_size; y_pos += 2) {
|
||||
for (int x_pos = 0; x_pos < block_size; x_pos += 2) {
|
||||
int pos = (y_pos >> 1) * sub_block_in_width + (x_pos >> 1);
|
||||
get_pixels_in_1D_char_array_by_block_2x2(y_src + y_pos * stride + x_pos,
|
||||
stride, pixel_to_hash);
|
||||
assert(pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
|
||||
hash_value_buffer[0][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator1, pixel_to_hash, sizeof(pixel_to_hash));
|
||||
hash_value_buffer[1][0][pos] = av1_get_crc_value(
|
||||
&crc_calculator2, pixel_to_hash, sizeof(pixel_to_hash));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,6 +442,10 @@ void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
|||
for (int x_pos = 0; x_pos < sub_block_in_width; x_pos++) {
|
||||
int srcPos = (y_pos << 1) * src_sub_block_in_width + (x_pos << 1);
|
||||
|
||||
assert(srcPos + 1 < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
|
||||
assert(srcPos + src_sub_block_in_width + 1 <
|
||||
AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
|
||||
assert(dst_pos < AOM_BUFFER_SIZE_FOR_BLOCK_HASH);
|
||||
to_hash[0] = hash_value_buffer[0][src_idx][srcPos];
|
||||
to_hash[1] = hash_value_buffer[0][src_idx][srcPos + 1];
|
||||
to_hash[2] =
|
||||
|
|
@ -378,3 +475,5 @@ void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
|||
*hash_value1 = (hash_value_buffer[0][dst_idx][0] & crc_mask) + add_value;
|
||||
*hash_value2 = hash_value_buffer[1][dst_idx][0];
|
||||
}
|
||||
|
||||
#undef AOM_BUFFER_SIZE_FOR_BLOCK_HASH
|
||||
|
|
|
|||
10
third_party/aom/av1/encoder/hash_motion.h
vendored
10
third_party/aom/av1/encoder/hash_motion.h
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#ifndef AV1_ENCODER_HASH_MOTION_H_
|
||||
#define AV1_ENCODER_HASH_MOTION_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_scale/yv12config.h"
|
||||
#include "third_party/vector/vector.h"
|
||||
|
|
@ -29,7 +30,9 @@ typedef struct _block_hash {
|
|||
uint32_t hash_value2;
|
||||
} block_hash;
|
||||
|
||||
typedef struct _hash_table { Vector **p_lookup_table; } hash_table;
|
||||
typedef struct _hash_table {
|
||||
Vector **p_lookup_table;
|
||||
} hash_table;
|
||||
|
||||
void av1_hash_table_init(hash_table *p_hash_table);
|
||||
void av1_hash_table_destroy(hash_table *p_hash_table);
|
||||
|
|
@ -63,7 +66,8 @@ int av1_hash_is_horizontal_perfect(const YV12_BUFFER_CONFIG *picture,
|
|||
int av1_hash_is_vertical_perfect(const YV12_BUFFER_CONFIG *picture,
|
||||
int block_size, int x_start, int y_start);
|
||||
void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
||||
uint32_t *hash_value1, uint32_t *hash_value2);
|
||||
uint32_t *hash_value1, uint32_t *hash_value2,
|
||||
int use_highbitdepth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
597
third_party/aom/av1/encoder/hybrid_fwd_txfm.c
vendored
597
third_party/aom/av1/encoder/hybrid_fwd_txfm.c
vendored
|
|
@ -9,229 +9,74 @@
|
|||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "config/aom_config.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
#include "config/aom_dsp_rtcd.h"
|
||||
|
||||
#include "av1/common/idct.h"
|
||||
#include "av1/encoder/hybrid_fwd_txfm.h"
|
||||
|
||||
#if CONFIG_CHROMA_2X2
|
||||
static void fwd_txfm_2x2(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
tran_high_t a1 = src_diff[0];
|
||||
tran_high_t b1 = src_diff[1];
|
||||
tran_high_t c1 = src_diff[diff_stride];
|
||||
tran_high_t d1 = src_diff[1 + diff_stride];
|
||||
/* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per
|
||||
pixel. */
|
||||
void av1_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) {
|
||||
int i;
|
||||
tran_high_t a1, b1, c1, d1, e1;
|
||||
const int16_t *ip_pass0 = input;
|
||||
const tran_low_t *ip = NULL;
|
||||
tran_low_t *op = output;
|
||||
|
||||
tran_high_t a2 = a1 + c1;
|
||||
tran_high_t b2 = b1 + d1;
|
||||
tran_high_t c2 = a1 - c1;
|
||||
tran_high_t d2 = b1 - d1;
|
||||
for (i = 0; i < 4; i++) {
|
||||
a1 = ip_pass0[0 * stride];
|
||||
b1 = ip_pass0[1 * stride];
|
||||
c1 = ip_pass0[2 * stride];
|
||||
d1 = ip_pass0[3 * stride];
|
||||
|
||||
a1 = a2 + b2;
|
||||
b1 = a2 - b2;
|
||||
c1 = c2 + d2;
|
||||
d1 = c2 - d2;
|
||||
a1 += b1;
|
||||
d1 = d1 - c1;
|
||||
e1 = (a1 - d1) >> 1;
|
||||
b1 = e1 - b1;
|
||||
c1 = e1 - c1;
|
||||
a1 -= c1;
|
||||
d1 += b1;
|
||||
op[0] = (tran_low_t)a1;
|
||||
op[4] = (tran_low_t)c1;
|
||||
op[8] = (tran_low_t)d1;
|
||||
op[12] = (tran_low_t)b1;
|
||||
|
||||
coeff[0] = (tran_low_t)(4 * a1);
|
||||
coeff[1] = (tran_low_t)(4 * b1);
|
||||
coeff[2] = (tran_low_t)(4 * c1);
|
||||
coeff[3] = (tran_low_t)(4 * d1);
|
||||
|
||||
(void)txfm_param;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
if (txfm_param->lossless) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
av1_fwht4x4(src_diff, coeff, diff_stride);
|
||||
return;
|
||||
ip_pass0++;
|
||||
op++;
|
||||
}
|
||||
ip = output;
|
||||
op = output;
|
||||
|
||||
#if CONFIG_LGT || CONFIG_DAALA_DCT4
|
||||
// only C version has LGTs
|
||||
av1_fht4x4_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht4x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
a1 = ip[0];
|
||||
b1 = ip[1];
|
||||
c1 = ip[2];
|
||||
d1 = ip[3];
|
||||
|
||||
static void fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht4x8_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht4x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
a1 += b1;
|
||||
d1 -= c1;
|
||||
e1 = (a1 - d1) >> 1;
|
||||
b1 = e1 - b1;
|
||||
c1 = e1 - c1;
|
||||
a1 -= c1;
|
||||
d1 += b1;
|
||||
op[0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR);
|
||||
op[1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR);
|
||||
op[2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR);
|
||||
op[3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR);
|
||||
|
||||
static void fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht8x4_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht8x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht8x16_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht8x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht16x8_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht16x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
av1_fht16x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
static void fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
av1_fht32x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
static void fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT || CONFIG_DAALA_DCT8
|
||||
av1_fht8x8_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht8x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_DAALA_DCT16
|
||||
av1_fht16x16_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht16x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif // CONFIG_DAALA_DCT16
|
||||
}
|
||||
|
||||
static void fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_MRC_TX
|
||||
// MRC_DCT currently only has a C implementation
|
||||
if (txfm_param->tx_type == MRC_DCT) {
|
||||
av1_fht32x32_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
return;
|
||||
ip += 4;
|
||||
op += 4;
|
||||
}
|
||||
#endif // CONFIG_MRC_TX
|
||||
av1_fht32x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
#if CONFIG_TX64X64
|
||||
static void fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_EXT_TX
|
||||
if (txfm_param->tx_type == IDTX)
|
||||
av1_fwd_idtx_c(src_diff, coeff, diff_stride, 64, 64, txfm_param->tx_type);
|
||||
else
|
||||
#endif
|
||||
av1_fht64x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
void av1_highbd_fwht4x4_c(const int16_t *input, tran_low_t *output,
|
||||
int stride) {
|
||||
av1_fwht4x4_c(input, output, stride);
|
||||
}
|
||||
|
||||
static void fwd_txfm_32x64(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_EXT_TX
|
||||
if (txfm_param->tx_type == IDTX)
|
||||
av1_fwd_idtx_c(src_diff, coeff, diff_stride, 32, 64, txfm_param->tx_type);
|
||||
else
|
||||
#endif
|
||||
av1_fht32x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
static void fwd_txfm_64x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_EXT_TX
|
||||
if (txfm_param->tx_type == IDTX)
|
||||
av1_fwd_idtx_c(src_diff, coeff, diff_stride, 64, 32, txfm_param->tx_type);
|
||||
else
|
||||
#endif
|
||||
av1_fht64x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
#endif // CONFIG_TX64X64
|
||||
|
||||
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
|
||||
static void fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht16x4_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht16x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht4x16_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht4x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht32x8_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht32x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
#if CONFIG_LGT
|
||||
av1_fht8x32_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
#else
|
||||
av1_fht8x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_CHROMA_2X2
|
||||
static void highbd_fwd_txfm_2x2(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
tran_high_t a1 = src_diff[0];
|
||||
tran_high_t b1 = src_diff[1];
|
||||
tran_high_t c1 = src_diff[diff_stride];
|
||||
tran_high_t d1 = src_diff[1 + diff_stride];
|
||||
|
||||
tran_high_t a2 = a1 + c1;
|
||||
tran_high_t b2 = b1 + d1;
|
||||
tran_high_t c2 = a1 - c1;
|
||||
tran_high_t d2 = b1 - d1;
|
||||
|
||||
a1 = a2 + b2;
|
||||
b1 = a2 - b2;
|
||||
c1 = c2 + d2;
|
||||
d1 = c2 - d2;
|
||||
|
||||
coeff[0] = (tran_low_t)(4 * a1);
|
||||
coeff[1] = (tran_low_t)(4 * b1);
|
||||
coeff[2] = (tran_low_t)(4 * c1);
|
||||
coeff[3] = (tran_low_t)(4 * d1);
|
||||
|
||||
(void)txfm_param;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
|
|
@ -243,22 +88,6 @@ static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
|
|||
return;
|
||||
}
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
// use the c version for anything including identity for now
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
|
|
@ -267,11 +96,11 @@ static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
case IDTX:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_4x4_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0);
|
||||
default:
|
||||
av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,28 +146,40 @@ static void highbd_fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
|
|||
txfm_param->bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
av1_fwd_txfm2d_16x4_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
|
||||
txfm_param->bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
av1_fwd_txfm2d_4x16_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
|
||||
txfm_param->bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
av1_fwd_txfm2d_32x8_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
|
||||
txfm_param->bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
av1_fwd_txfm2d_8x32_c(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
|
||||
txfm_param->bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
// use the c version for anything including identity for now
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
|
|
@ -347,11 +188,11 @@ static void highbd_fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
case IDTX:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_8x8_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0);
|
||||
default:
|
||||
av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,22 +202,6 @@ static void highbd_fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
|
|||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
// use the c version for anything including identity for now
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
|
|
@ -385,11 +210,11 @@ static void highbd_fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
case IDTX:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_16x16_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0);
|
||||
default:
|
||||
av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -399,22 +224,6 @@ static void highbd_fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
|
|||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_32x32(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_32x32(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
// use the c version for anything including identity for now
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
|
|
@ -423,206 +232,72 @@ static void highbd_fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
case IDTX:
|
||||
// fallthrough intended
|
||||
av1_fwd_txfm2d_32x32_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0);
|
||||
default:
|
||||
av1_fwd_txfm2d_32x32(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_TX64X64
|
||||
static void highbd_fwd_txfm_32x64(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
av1_fwd_txfm2d_32x64_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
case V_ADST:
|
||||
case H_ADST:
|
||||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
// TODO(sarahparker)
|
||||
// I've deleted the 64x64 implementations that existed in lieu
|
||||
// of adst, flipadst and identity for simplicity but will bring back
|
||||
// in a later change. This shouldn't impact performance since
|
||||
// DCT_DCT is the only extended type currently allowed for 64x64,
|
||||
// as dictated by get_ext_tx_set_type in blockd.h.
|
||||
av1_fwd_txfm2d_32x64_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
break;
|
||||
case IDTX:
|
||||
av1_fwd_idtx_c(src_diff, dst_coeff, diff_stride, 32, 64, tx_type);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0); break;
|
||||
}
|
||||
av1_fwd_txfm2d_32x64_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_64x32(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
av1_fwd_txfm2d_64x32_c(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
case V_ADST:
|
||||
case H_ADST:
|
||||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
// TODO(sarahparker)
|
||||
// I've deleted the 64x64 implementations that existed in lieu
|
||||
// of adst, flipadst and identity for simplicity but will bring back
|
||||
// in a later change. This shouldn't impact performance since
|
||||
// DCT_DCT is the only extended type currently allowed for 64x64,
|
||||
// as dictated by get_ext_tx_set_type in blockd.h.
|
||||
av1_fwd_txfm2d_64x32_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
break;
|
||||
case IDTX:
|
||||
av1_fwd_idtx_c(src_diff, dst_coeff, diff_stride, 64, 32, tx_type);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0); break;
|
||||
}
|
||||
av1_fwd_txfm2d_64x32_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_16x64(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const int bd = txfm_param->bd;
|
||||
av1_fwd_txfm2d_16x64_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_64x16(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const int bd = txfm_param->bd;
|
||||
av1_fwd_txfm2d_64x16_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
}
|
||||
|
||||
static void highbd_fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(txfm_param->tx_type == DCT_DCT);
|
||||
int32_t *dst_coeff = (int32_t *)coeff;
|
||||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
const int bd = txfm_param->bd;
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
av1_fwd_txfm2d_64x64(src_diff, dst_coeff, diff_stride, tx_type, bd);
|
||||
break;
|
||||
#if CONFIG_EXT_TX
|
||||
case ADST_DCT:
|
||||
case DCT_ADST:
|
||||
case ADST_ADST:
|
||||
case FLIPADST_DCT:
|
||||
case DCT_FLIPADST:
|
||||
case FLIPADST_FLIPADST:
|
||||
case ADST_FLIPADST:
|
||||
case FLIPADST_ADST:
|
||||
case V_DCT:
|
||||
case H_DCT:
|
||||
case V_ADST:
|
||||
case H_ADST:
|
||||
case V_FLIPADST:
|
||||
case H_FLIPADST:
|
||||
// TODO(sarahparker)
|
||||
// I've deleted the 64x64 implementations that existed in lieu
|
||||
// of adst, flipadst and identity for simplicity but will bring back
|
||||
// in a later change. This shouldn't impact performance since
|
||||
// DCT_DCT is the only extended type currently allowed for 64x64,
|
||||
// as dictated by get_ext_tx_set_type in blockd.h.
|
||||
av1_fwd_txfm2d_64x64_c(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
break;
|
||||
case IDTX:
|
||||
av1_fwd_idtx_c(src_diff, dst_coeff, diff_stride, 64, 64, tx_type);
|
||||
break;
|
||||
#endif // CONFIG_EXT_TX
|
||||
default: assert(0); break;
|
||||
}
|
||||
av1_fwd_txfm2d_64x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
|
||||
}
|
||||
#endif // CONFIG_TX64X64
|
||||
|
||||
void av1_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff, int diff_stride,
|
||||
TxfmParam *txfm_param) {
|
||||
const TX_SIZE tx_size = txfm_param->tx_size;
|
||||
#if CONFIG_LGT_FROM_PRED
|
||||
if (txfm_param->use_lgt) {
|
||||
// if use_lgt is 1, it will override tx_type
|
||||
assert(is_lgt_allowed(txfm_param->mode, tx_size));
|
||||
flgt2d_from_pred_c(src_diff, coeff, diff_stride, txfm_param);
|
||||
return;
|
||||
}
|
||||
#endif // CONFIG_LGT_FROM_PRED
|
||||
switch (tx_size) {
|
||||
#if CONFIG_TX64X64
|
||||
case TX_64X64:
|
||||
fwd_txfm_64x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_32X64:
|
||||
fwd_txfm_32x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_64X32:
|
||||
fwd_txfm_64x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
#endif // CONFIG_TX64X64
|
||||
case TX_32X32:
|
||||
fwd_txfm_32x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_16X16:
|
||||
fwd_txfm_16x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_8X8: fwd_txfm_8x8(src_diff, coeff, diff_stride, txfm_param); break;
|
||||
case TX_4X8: fwd_txfm_4x8(src_diff, coeff, diff_stride, txfm_param); break;
|
||||
case TX_8X4: fwd_txfm_8x4(src_diff, coeff, diff_stride, txfm_param); break;
|
||||
case TX_8X16:
|
||||
fwd_txfm_8x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_16X8:
|
||||
fwd_txfm_16x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_16X32:
|
||||
fwd_txfm_16x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_32X16:
|
||||
fwd_txfm_32x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_4X4: fwd_txfm_4x4(src_diff, coeff, diff_stride, txfm_param); break;
|
||||
#if CONFIG_CHROMA_2X2
|
||||
case TX_2X2: fwd_txfm_2x2(src_diff, coeff, diff_stride, txfm_param); break;
|
||||
#endif
|
||||
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
|
||||
case TX_4X16:
|
||||
fwd_txfm_4x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_16X4:
|
||||
fwd_txfm_16x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_8X32:
|
||||
fwd_txfm_8x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_32X8:
|
||||
fwd_txfm_32x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
#endif
|
||||
default: assert(0); break;
|
||||
}
|
||||
if (txfm_param->bd == 8)
|
||||
av1_lowbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
|
||||
else
|
||||
av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
void av1_lowbd_fwd_txfm_c(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
|
||||
}
|
||||
|
||||
void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
|
||||
int diff_stride, TxfmParam *txfm_param) {
|
||||
assert(av1_ext_tx_used[txfm_param->tx_set_type][txfm_param->tx_type]);
|
||||
const TX_SIZE tx_size = txfm_param->tx_size;
|
||||
switch (tx_size) {
|
||||
#if CONFIG_TX64X64
|
||||
case TX_64X64:
|
||||
highbd_fwd_txfm_64x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
|
|
@ -632,7 +307,12 @@ void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case TX_64X32:
|
||||
highbd_fwd_txfm_64x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
#endif // CONFIG_TX64X64
|
||||
case TX_16X64:
|
||||
highbd_fwd_txfm_16x64(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_64X16:
|
||||
highbd_fwd_txfm_64x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_32X32:
|
||||
highbd_fwd_txfm_32x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
|
|
@ -663,11 +343,18 @@ void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
|
|||
case TX_4X4:
|
||||
highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
#if CONFIG_CHROMA_2X2
|
||||
case TX_2X2:
|
||||
highbd_fwd_txfm_2x2(src_diff, coeff, diff_stride, txfm_param);
|
||||
case TX_4X16:
|
||||
highbd_fwd_txfm_4x16(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_16X4:
|
||||
highbd_fwd_txfm_16x4(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_8X32:
|
||||
highbd_fwd_txfm_8x32(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
case TX_32X8:
|
||||
highbd_fwd_txfm_32x8(src_diff, coeff, diff_stride, txfm_param);
|
||||
break;
|
||||
#endif
|
||||
default: assert(0); break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef AV1_ENCODER_HYBRID_FWD_TXFM_H_
|
||||
#define AV1_ENCODER_HYBRID_FWD_TXFM_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
|||
70
third_party/aom/av1/encoder/k_means_template.h
vendored
70
third_party/aom/av1/encoder/k_means_template.h
vendored
|
|
@ -23,25 +23,23 @@
|
|||
#define RENAME_(x, y) AV1_K_MEANS_RENAME(x, y)
|
||||
#define RENAME(x) RENAME_(x, AV1_K_MEANS_DIM)
|
||||
|
||||
static float RENAME(calc_dist)(const float *p1, const float *p2) {
|
||||
float dist = 0;
|
||||
int i;
|
||||
for (i = 0; i < AV1_K_MEANS_DIM; ++i) {
|
||||
const float diff = p1[i] - p2[i];
|
||||
static int RENAME(calc_dist)(const int *p1, const int *p2) {
|
||||
int dist = 0;
|
||||
for (int i = 0; i < AV1_K_MEANS_DIM; ++i) {
|
||||
const int diff = p1[i] - p2[i];
|
||||
dist += diff * diff;
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
void RENAME(av1_calc_indices)(const float *data, const float *centroids,
|
||||
void RENAME(av1_calc_indices)(const int *data, const int *centroids,
|
||||
uint8_t *indices, int n, int k) {
|
||||
int i, j;
|
||||
for (i = 0; i < n; ++i) {
|
||||
float min_dist = RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM, centroids);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
int min_dist = RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM, centroids);
|
||||
indices[i] = 0;
|
||||
for (j = 1; j < k; ++j) {
|
||||
const float this_dist = RENAME(calc_dist)(
|
||||
data + i * AV1_K_MEANS_DIM, centroids + j * AV1_K_MEANS_DIM);
|
||||
for (int j = 1; j < k; ++j) {
|
||||
const int this_dist = RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM,
|
||||
centroids + j * AV1_K_MEANS_DIM);
|
||||
if (this_dist < min_dist) {
|
||||
min_dist = this_dist;
|
||||
indices[i] = j;
|
||||
|
|
@ -50,19 +48,16 @@ void RENAME(av1_calc_indices)(const float *data, const float *centroids,
|
|||
}
|
||||
}
|
||||
|
||||
static void RENAME(calc_centroids)(const float *data, float *centroids,
|
||||
static void RENAME(calc_centroids)(const int *data, int *centroids,
|
||||
const uint8_t *indices, int n, int k) {
|
||||
int i, j, index;
|
||||
int count[PALETTE_MAX_SIZE];
|
||||
int i, j;
|
||||
int count[PALETTE_MAX_SIZE] = { 0 };
|
||||
unsigned int rand_state = (unsigned int)data[0];
|
||||
|
||||
assert(n <= 32768);
|
||||
|
||||
memset(count, 0, sizeof(count[0]) * k);
|
||||
memset(centroids, 0, sizeof(centroids[0]) * k * AV1_K_MEANS_DIM);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
index = indices[i];
|
||||
const int index = indices[i];
|
||||
assert(index < k);
|
||||
++count[index];
|
||||
for (j = 0; j < AV1_K_MEANS_DIM; ++j) {
|
||||
|
|
@ -76,43 +71,35 @@ static void RENAME(calc_centroids)(const float *data, float *centroids,
|
|||
data + (lcg_rand16(&rand_state) % n) * AV1_K_MEANS_DIM,
|
||||
sizeof(centroids[0]) * AV1_K_MEANS_DIM);
|
||||
} else {
|
||||
const float norm = 1.0f / count[i];
|
||||
for (j = 0; j < AV1_K_MEANS_DIM; ++j)
|
||||
centroids[i * AV1_K_MEANS_DIM + j] *= norm;
|
||||
for (j = 0; j < AV1_K_MEANS_DIM; ++j) {
|
||||
centroids[i * AV1_K_MEANS_DIM + j] =
|
||||
DIVIDE_AND_ROUND(centroids[i * AV1_K_MEANS_DIM + j], count[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Round to nearest integers.
|
||||
for (i = 0; i < k * AV1_K_MEANS_DIM; ++i) {
|
||||
centroids[i] = roundf(centroids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static float RENAME(calc_total_dist)(const float *data, const float *centroids,
|
||||
const uint8_t *indices, int n, int k) {
|
||||
float dist = 0;
|
||||
int i;
|
||||
static int64_t RENAME(calc_total_dist)(const int *data, const int *centroids,
|
||||
const uint8_t *indices, int n, int k) {
|
||||
int64_t dist = 0;
|
||||
(void)k;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
for (int i = 0; i < n; ++i) {
|
||||
dist += RENAME(calc_dist)(data + i * AV1_K_MEANS_DIM,
|
||||
centroids + indices[i] * AV1_K_MEANS_DIM);
|
||||
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
void RENAME(av1_k_means)(const float *data, float *centroids, uint8_t *indices,
|
||||
void RENAME(av1_k_means)(const int *data, int *centroids, uint8_t *indices,
|
||||
int n, int k, int max_itr) {
|
||||
int i;
|
||||
float this_dist;
|
||||
float pre_centroids[2 * PALETTE_MAX_SIZE];
|
||||
int pre_centroids[2 * PALETTE_MAX_SIZE];
|
||||
uint8_t pre_indices[MAX_SB_SQUARE];
|
||||
|
||||
RENAME(av1_calc_indices)(data, centroids, indices, n, k);
|
||||
this_dist = RENAME(calc_total_dist)(data, centroids, indices, n, k);
|
||||
int64_t this_dist = RENAME(calc_total_dist)(data, centroids, indices, n, k);
|
||||
|
||||
for (i = 0; i < max_itr; ++i) {
|
||||
const float pre_dist = this_dist;
|
||||
for (int i = 0; i < max_itr; ++i) {
|
||||
const int64_t pre_dist = this_dist;
|
||||
memcpy(pre_centroids, centroids,
|
||||
sizeof(pre_centroids[0]) * k * AV1_K_MEANS_DIM);
|
||||
memcpy(pre_indices, indices, sizeof(pre_indices[0]) * n);
|
||||
|
|
@ -132,6 +119,5 @@ void RENAME(av1_k_means)(const float *data, float *centroids, uint8_t *indices,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef RENAME_
|
||||
#undef RENAME
|
||||
|
|
|
|||
107
third_party/aom/av1/encoder/laplace_encoder.c
vendored
107
third_party/aom/av1/encoder/laplace_encoder.c
vendored
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
#include "av1/common/odintrin.h"
|
||||
#include "av1/common/pvq.h"
|
||||
#include "pvq_encoder.h"
|
||||
|
||||
static void aom_encode_pvq_split(aom_writer *w, od_pvq_codeword_ctx *adapt,
|
||||
int count, int sum, int ctx) {
|
||||
int shift;
|
||||
int rest;
|
||||
int fctx;
|
||||
if (sum == 0) return;
|
||||
shift = OD_MAXI(0, OD_ILOG(sum) - 3);
|
||||
if (shift) {
|
||||
rest = count & ((1 << shift) - 1);
|
||||
count >>= shift;
|
||||
sum >>= shift;
|
||||
}
|
||||
fctx = 7*ctx + sum - 1;
|
||||
aom_write_symbol_pvq(w, count, adapt->pvq_split_cdf[fctx], sum + 1);
|
||||
if (shift) aom_write_literal(w, rest, shift);
|
||||
}
|
||||
|
||||
void aom_encode_band_pvq_splits(aom_writer *w, od_pvq_codeword_ctx *adapt,
|
||||
const int *y, int n, int k, int level) {
|
||||
int mid;
|
||||
int i;
|
||||
int count_right;
|
||||
if (n <= 1 || k == 0) return;
|
||||
if (k == 1 && n <= 16) {
|
||||
int cdf_id;
|
||||
int pos;
|
||||
cdf_id = od_pvq_k1_ctx(n, level == 0);
|
||||
for (pos = 0; !y[pos]; pos++);
|
||||
OD_ASSERT(pos < n);
|
||||
aom_write_symbol_pvq(w, pos, adapt->pvq_k1_cdf[cdf_id], n);
|
||||
}
|
||||
else {
|
||||
mid = n >> 1;
|
||||
count_right = k;
|
||||
for (i = 0; i < mid; i++) count_right -= abs(y[i]);
|
||||
aom_encode_pvq_split(w, adapt, count_right, k, od_pvq_size_ctx(n));
|
||||
aom_encode_band_pvq_splits(w, adapt, y, mid, k - count_right, level + 1);
|
||||
aom_encode_band_pvq_splits(w, adapt, y + mid, n - mid, count_right,
|
||||
level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Encodes the tail of a Laplace-distributed variable, i.e. it doesn't
|
||||
* do anything special for the zero case.
|
||||
*
|
||||
* @param [in,out] enc range encoder
|
||||
* @param [in] x variable to encode (has to be positive)
|
||||
* @param [in] decay decay factor of the distribution in Q8 format,
|
||||
* i.e. pdf ~= decay^x
|
||||
*/
|
||||
void aom_laplace_encode_special(aom_writer *w, int x, unsigned decay) {
|
||||
int shift;
|
||||
int xs;
|
||||
int sym;
|
||||
const uint16_t *cdf;
|
||||
shift = 0;
|
||||
/* We don't want a large decay value because that would require too many
|
||||
symbols. */
|
||||
while (decay > 235) {
|
||||
decay = (decay*decay + 128) >> 8;
|
||||
shift++;
|
||||
}
|
||||
decay = OD_MINI(decay, 254);
|
||||
decay = OD_MAXI(decay, 2);
|
||||
xs = x >> shift;
|
||||
cdf = EXP_CDF_TABLE[(decay + 1) >> 1];
|
||||
OD_LOG((OD_LOG_PVQ, OD_LOG_DEBUG, "decay = %d", decay));
|
||||
do {
|
||||
sym = OD_MINI(xs, 15);
|
||||
{
|
||||
int i;
|
||||
OD_LOG((OD_LOG_PVQ, OD_LOG_DEBUG, "%d %d %d %d %d\n", x, xs, shift,
|
||||
sym, max));
|
||||
for (i = 0; i < 16; i++) {
|
||||
OD_LOG_PARTIAL((OD_LOG_PVQ, OD_LOG_DEBUG, "%d ", cdf[i]));
|
||||
}
|
||||
OD_LOG_PARTIAL((OD_LOG_PVQ, OD_LOG_DEBUG, "\n"));
|
||||
}
|
||||
aom_write_cdf(w, sym, cdf, 16);
|
||||
xs -= 15;
|
||||
} while (sym >= 15);
|
||||
if (shift) aom_write_literal(w, x & ((1 << shift) - 1), shift);
|
||||
}
|
||||
29
third_party/aom/av1/encoder/lookahead.c
vendored
29
third_party/aom/av1/encoder/lookahead.c
vendored
|
|
@ -11,10 +11,9 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "av1/common/common.h"
|
||||
|
||||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/extend.h"
|
||||
#include "av1/encoder/lookahead.h"
|
||||
|
|
@ -42,14 +41,9 @@ void av1_lookahead_destroy(struct lookahead_ctx *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
struct lookahead_ctx *av1_lookahead_init(unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int subsampling_x,
|
||||
unsigned int subsampling_y,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_highbitdepth,
|
||||
#endif
|
||||
unsigned int depth) {
|
||||
struct lookahead_ctx *av1_lookahead_init(
|
||||
unsigned int width, unsigned int height, unsigned int subsampling_x,
|
||||
unsigned int subsampling_y, int use_highbitdepth, unsigned int depth) {
|
||||
struct lookahead_ctx *ctx = NULL;
|
||||
|
||||
// Clamp the lookahead queue depth
|
||||
|
|
@ -68,10 +62,7 @@ struct lookahead_ctx *av1_lookahead_init(unsigned int width,
|
|||
if (!ctx->buf) goto bail;
|
||||
for (i = 0; i < depth; i++)
|
||||
if (aom_alloc_frame_buffer(&ctx->buf[i].img, width, height, subsampling_x,
|
||||
subsampling_y,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_highbitdepth,
|
||||
#endif
|
||||
subsampling_y, use_highbitdepth,
|
||||
AOM_BORDER_IN_PIXELS, legacy_byte_alignment))
|
||||
goto bail;
|
||||
}
|
||||
|
|
@ -84,10 +75,7 @@ bail:
|
|||
#define USE_PARTIAL_COPY 0
|
||||
|
||||
int av1_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
|
||||
int64_t ts_start, int64_t ts_end,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_highbitdepth,
|
||||
#endif
|
||||
int64_t ts_start, int64_t ts_end, int use_highbitdepth,
|
||||
aom_enc_frame_flags_t flags) {
|
||||
struct lookahead_entry *buf;
|
||||
#if USE_PARTIAL_COPY
|
||||
|
|
@ -160,10 +148,7 @@ int av1_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
|
|||
YV12_BUFFER_CONFIG new_img;
|
||||
memset(&new_img, 0, sizeof(new_img));
|
||||
if (aom_alloc_frame_buffer(&new_img, width, height, subsampling_x,
|
||||
subsampling_y,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
use_highbitdepth,
|
||||
#endif
|
||||
subsampling_y, use_highbitdepth,
|
||||
AOM_BORDER_IN_PIXELS, 0))
|
||||
return 1;
|
||||
aom_free_frame_buffer(&buf->img);
|
||||
|
|
|
|||
16
third_party/aom/av1/encoder/lookahead.h
vendored
16
third_party/aom/av1/encoder/lookahead.h
vendored
|
|
@ -44,14 +44,9 @@ struct lookahead_ctx {
|
|||
* The lookahead stage is a queue of frame buffers on which some analysis
|
||||
* may be done when buffers are enqueued.
|
||||
*/
|
||||
struct lookahead_ctx *av1_lookahead_init(unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int subsampling_x,
|
||||
unsigned int subsampling_y,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_highbitdepth,
|
||||
#endif
|
||||
unsigned int depth);
|
||||
struct lookahead_ctx *av1_lookahead_init(
|
||||
unsigned int width, unsigned int height, unsigned int subsampling_x,
|
||||
unsigned int subsampling_y, int use_highbitdepth, unsigned int depth);
|
||||
|
||||
/**\brief Destroys the lookahead stage
|
||||
*/
|
||||
|
|
@ -73,10 +68,7 @@ void av1_lookahead_destroy(struct lookahead_ctx *ctx);
|
|||
* \param[in] active_map Map that specifies which macroblock is active
|
||||
*/
|
||||
int av1_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src,
|
||||
int64_t ts_start, int64_t ts_end,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int use_highbitdepth,
|
||||
#endif
|
||||
int64_t ts_start, int64_t ts_end, int use_highbitdepth,
|
||||
aom_enc_frame_flags_t flags);
|
||||
|
||||
/**\brief Get the next source buffer to encode
|
||||
|
|
|
|||
58
third_party/aom/av1/encoder/mbgraph.c
vendored
58
third_party/aom/av1/encoder/mbgraph.c
vendored
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
#include <limits.h>
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
#include "config/aom_dsp_rtcd.h"
|
||||
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
|
|
@ -47,32 +47,28 @@ static unsigned int do_16x16_motion_iteration(AV1_COMP *cpi, const MV *ref_mv,
|
|||
av1_hex_search(x, &ref_full, step_param, x->errorperbit, 0,
|
||||
cond_cost_list(cpi, cost_list), &v_fn_ptr, 0, ref_mv);
|
||||
|
||||
// Try sub-pixel MC
|
||||
// if (bestsme > error_thresh && bestsme < INT_MAX)
|
||||
#if CONFIG_AMVR
|
||||
if (cpi->common.cur_frame_mv_precision_level == 1) {
|
||||
// Try sub-pixel MC
|
||||
// if (bestsme > error_thresh && bestsme < INT_MAX)
|
||||
if (cpi->common.cur_frame_force_integer_mv == 1) {
|
||||
x->best_mv.as_mv.row *= 8;
|
||||
x->best_mv.as_mv.col *= 8;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
int distortion;
|
||||
unsigned int sse;
|
||||
cpi->find_fractional_mv_step(x, ref_mv, cpi->common.allow_high_precision_mv,
|
||||
x->errorperbit, &v_fn_ptr, 0,
|
||||
mv_sf->subpel_iters_per_step,
|
||||
cond_cost_list(cpi, cost_list), NULL, NULL,
|
||||
&distortion, &sse, NULL, NULL, 0, 0, 0, 0, 0);
|
||||
cpi->find_fractional_mv_step(
|
||||
x, &cpi->common, mb_row, mb_col, ref_mv,
|
||||
cpi->common.allow_high_precision_mv, x->errorperbit, &v_fn_ptr, 0,
|
||||
mv_sf->subpel_iters_per_step, cond_cost_list(cpi, cost_list), NULL,
|
||||
NULL, &distortion, &sse, NULL, NULL, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (has_second_ref(&xd->mi[0]->mbmi))
|
||||
xd->mi[0]->mbmi.mode = NEW_NEWMV;
|
||||
if (has_second_ref(xd->mi[0]))
|
||||
xd->mi[0]->mode = NEW_NEWMV;
|
||||
else
|
||||
xd->mi[0]->mbmi.mode = NEWMV;
|
||||
xd->mi[0]->mode = NEWMV;
|
||||
|
||||
xd->mi[0]->mbmi.mv[0] = x->best_mv;
|
||||
xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
|
||||
xd->mi[0]->mv[0] = x->best_mv;
|
||||
xd->mi[0]->ref_frame[1] = NONE_FRAME;
|
||||
|
||||
av1_build_inter_predictors_sby(&cpi->common, xd, mb_row, mb_col, NULL,
|
||||
BLOCK_16X16);
|
||||
|
|
@ -108,7 +104,7 @@ static int do_16x16_motion_search(AV1_COMP *cpi, const MV *ref_mv, int mb_row,
|
|||
// If the current best reference mv is not centered on 0,0 then do a 0,0
|
||||
// based search as well.
|
||||
if (ref_mv->row != 0 || ref_mv->col != 0) {
|
||||
MV zero_ref_mv = { 0, 0 };
|
||||
MV zero_ref_mv = kZeroMv;
|
||||
|
||||
tmp_err = do_16x16_motion_iteration(cpi, &zero_ref_mv, mb_row, mb_col);
|
||||
if (tmp_err < err) {
|
||||
|
|
@ -144,14 +140,14 @@ static int find_best_16x16_intra(AV1_COMP *cpi, PREDICTION_MODE *pbest_mode) {
|
|||
|
||||
// calculate SATD for each intra prediction mode;
|
||||
// we're intentionally not doing 4x4, we just want a rough estimate
|
||||
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
|
||||
for (mode = DC_PRED; mode <= PAETH_PRED; mode++) {
|
||||
unsigned int err;
|
||||
|
||||
xd->mi[0]->mbmi.mode = mode;
|
||||
av1_predict_intra_block(cm, xd, 16, 16, BLOCK_16X16, mode,
|
||||
x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
xd->plane[0].dst.buf, xd->plane[0].dst.stride, 0, 0,
|
||||
0);
|
||||
xd->mi[0]->mode = mode;
|
||||
av1_predict_intra_block(cm, xd, 16, 16, TX_16X16, mode, 0, 0,
|
||||
FILTER_INTRA_MODES, x->plane[0].src.buf,
|
||||
x->plane[0].src.stride, xd->plane[0].dst.buf,
|
||||
xd->plane[0].dst.stride, 0, 0, 0);
|
||||
err = aom_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
|
||||
|
||||
|
|
@ -231,8 +227,8 @@ static void update_mbgraph_frame_stats(AV1_COMP *cpi,
|
|||
|
||||
int mb_col, mb_row, offset = 0;
|
||||
int mb_y_offset = 0, arf_y_offset = 0, gld_y_offset = 0;
|
||||
MV gld_top_mv = { 0, 0 };
|
||||
MODE_INFO mi_local;
|
||||
MV gld_top_mv = kZeroMv;
|
||||
MB_MODE_INFO mi_local;
|
||||
|
||||
av1_zero(mi_local);
|
||||
// Set up limit values for motion vectors to prevent them extending outside
|
||||
|
|
@ -244,9 +240,9 @@ static void update_mbgraph_frame_stats(AV1_COMP *cpi,
|
|||
xd->plane[0].pre[0].stride = buf->y_stride;
|
||||
xd->plane[1].dst.stride = buf->uv_stride;
|
||||
xd->mi[0] = &mi_local;
|
||||
mi_local.mbmi.sb_type = BLOCK_16X16;
|
||||
mi_local.mbmi.ref_frame[0] = LAST_FRAME;
|
||||
mi_local.mbmi.ref_frame[1] = NONE_FRAME;
|
||||
mi_local.sb_type = BLOCK_16X16;
|
||||
mi_local.ref_frame[0] = LAST_FRAME;
|
||||
mi_local.ref_frame[1] = NONE_FRAME;
|
||||
|
||||
for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
|
||||
MV gld_left_mv = gld_top_mv;
|
||||
|
|
|
|||
6
third_party/aom/av1/encoder/mbgraph.h
vendored
6
third_party/aom/av1/encoder/mbgraph.h
vendored
|
|
@ -23,10 +23,12 @@ typedef struct {
|
|||
int_mv mv;
|
||||
PREDICTION_MODE mode;
|
||||
} m;
|
||||
} ref[TOTAL_REFS_PER_FRAME];
|
||||
} ref[REF_FRAMES];
|
||||
} MBGRAPH_MB_STATS;
|
||||
|
||||
typedef struct { MBGRAPH_MB_STATS *mb_stats; } MBGRAPH_FRAME_STATS;
|
||||
typedef struct {
|
||||
MBGRAPH_MB_STATS *mb_stats;
|
||||
} MBGRAPH_FRAME_STATS;
|
||||
|
||||
struct AV1_COMP;
|
||||
|
||||
|
|
|
|||
1235
third_party/aom/av1/encoder/mcomp.c
vendored
1235
third_party/aom/av1/encoder/mcomp.c
vendored
File diff suppressed because it is too large
Load diff
64
third_party/aom/av1/encoder/mcomp.h
vendored
64
third_party/aom/av1/encoder/mcomp.h
vendored
|
|
@ -69,10 +69,9 @@ struct SPEED_FEATURES;
|
|||
|
||||
int av1_init_search_range(int size);
|
||||
|
||||
int av1_refining_search_sad(struct macroblock *x, struct mv *ref_mv,
|
||||
int sad_per_bit, int distance,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const struct mv *center_mv);
|
||||
int av1_refining_search_sad(struct macroblock *x, MV *ref_mv, int sad_per_bit,
|
||||
int distance, const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *center_mv);
|
||||
|
||||
// Runs sequence of diamond searches in smaller steps for RD.
|
||||
int av1_full_pixel_diamond(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
|
|
@ -81,24 +80,20 @@ int av1_full_pixel_diamond(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
|||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv, MV *dst_mv);
|
||||
|
||||
// Perform integral projection based motion estimation.
|
||||
unsigned int av1_int_pro_motion_estimation(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col);
|
||||
|
||||
int av1_hex_search(MACROBLOCK *x, MV *start_mv, int search_param,
|
||||
int sad_per_bit, int do_init_search, int *cost_list,
|
||||
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
|
||||
const MV *center_mv);
|
||||
|
||||
typedef int(fractional_mv_step_fp)(
|
||||
MACROBLOCK *x, const MV *ref_mv, int allow_hp, int error_per_bit,
|
||||
MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col,
|
||||
const MV *ref_mv, int allow_hp, int error_per_bit,
|
||||
const aom_variance_fn_ptr_t *vfp,
|
||||
int forced_stop, // 0 - full, 1 - qtr only, 2 - half only
|
||||
int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2],
|
||||
int *distortion, unsigned int *sse1, const uint8_t *second_pred,
|
||||
const uint8_t *mask, int mask_stride, int invert_mask, int w, int h,
|
||||
int use_upsampled_ref);
|
||||
int use_accurate_subpel_search);
|
||||
|
||||
extern fractional_mv_step_fp av1_find_best_sub_pixel_tree;
|
||||
extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned;
|
||||
|
|
@ -123,52 +118,33 @@ int av1_refining_search_8p_c(MACROBLOCK *x, int error_per_bit, int search_range,
|
|||
int invert_mask, const MV *center_mv,
|
||||
const uint8_t *second_pred);
|
||||
|
||||
struct AV1_COMP;
|
||||
|
||||
#if CONFIG_HASH_ME
|
||||
int av1_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bsize, MV *mvp_full, int step_param,
|
||||
int error_per_bit, int *cost_list, const MV *ref_mv,
|
||||
int var_max, int rd, int x_pos, int y_pos, int intra);
|
||||
#else
|
||||
int av1_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bsize, MV *mvp_full, int step_param,
|
||||
int error_per_bit, int *cost_list, const MV *ref_mv,
|
||||
int var_max, int rd);
|
||||
#endif
|
||||
|
||||
#if CONFIG_MOTION_VAR
|
||||
int av1_obmc_full_pixel_diamond(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
MV *mvp_full, int step_param, int sadpb,
|
||||
int further_steps, int do_refine,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv, MV *dst_mv, int is_second);
|
||||
int av1_find_best_obmc_sub_pixel_tree_up(
|
||||
MACROBLOCK *x, MV *bestmv, const MV *ref_mv, int allow_hp,
|
||||
int error_per_bit, const aom_variance_fn_ptr_t *vfp, int forced_stop,
|
||||
int iters_per_step, int *mvjcost, int *mvcost[2], int *distortion,
|
||||
unsigned int *sse1, int is_second, int use_upsampled_ref);
|
||||
#endif // CONFIG_MOTION_VAR
|
||||
MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col,
|
||||
MV *bestmv, const MV *ref_mv, int allow_hp, int error_per_bit,
|
||||
const aom_variance_fn_ptr_t *vfp, int forced_stop, int iters_per_step,
|
||||
int *mvjcost, int *mvcost[2], int *distortion, unsigned int *sse1,
|
||||
int is_second, int use_accurate_subpel_search);
|
||||
|
||||
unsigned int av1_compute_motion_cost(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *const x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, const MV *this_mv);
|
||||
unsigned int av1_refine_warped_mv(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *const x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, int *pts0,
|
||||
int *pts_inref0, int total_samples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#if CONFIG_WARPED_MOTION
|
||||
unsigned int av1_compute_motion_cost(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *const x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, const MV *this_mv);
|
||||
#if WARPED_MOTION_SORT_SAMPLES
|
||||
unsigned int av1_refine_warped_mv(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *const x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, int *pts0,
|
||||
int *pts_inref0, int *pts_mv0,
|
||||
int total_samples);
|
||||
#else
|
||||
unsigned int av1_refine_warped_mv(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *const x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col, int *pts,
|
||||
int *pts_inref);
|
||||
#endif // WARPED_MOTION_SORT_SAMPLES
|
||||
#endif // CONFIG_WARPED_MOTION
|
||||
|
||||
#endif // AV1_ENCODER_MCOMP_H_
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
|
||||
#include "aom_dsp/mips/macros_msa.h"
|
||||
|
||||
#define BLOCK_ERROR_BLOCKSIZE_MSA(BSize) \
|
||||
|
|
|
|||
436
third_party/aom/av1/encoder/mips/msa/fdct16x16_msa.c
vendored
436
third_party/aom/av1/encoder/mips/msa/fdct16x16_msa.c
vendored
|
|
@ -1,436 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/encoder/mips/msa/fdct_msa.h"
|
||||
#include "aom_dsp/mips/fwd_txfm_msa.h"
|
||||
|
||||
static void fadst16_cols_step1_msa(const int16_t *input, int32_t stride,
|
||||
const int32_t *const0, int16_t *int_buf) {
|
||||
v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
v8i16 tp0, tp1, tp2, tp3, g0, g1, g2, g3, g8, g9, g10, g11, h0, h1, h2, h3;
|
||||
v4i32 k0, k1, k2, k3;
|
||||
|
||||
/* load input data */
|
||||
r0 = LD_SH(input);
|
||||
r15 = LD_SH(input + 15 * stride);
|
||||
r7 = LD_SH(input + 7 * stride);
|
||||
r8 = LD_SH(input + 8 * stride);
|
||||
SLLI_4V(r0, r15, r7, r8, 2);
|
||||
|
||||
/* stage 1 */
|
||||
LD_SW2(const0, 4, k0, k1);
|
||||
LD_SW2(const0 + 8, 4, k2, k3);
|
||||
MADD_BF(r15, r0, r7, r8, k0, k1, k2, k3, g0, g1, g2, g3);
|
||||
|
||||
r3 = LD_SH(input + 3 * stride);
|
||||
r4 = LD_SH(input + 4 * stride);
|
||||
r11 = LD_SH(input + 11 * stride);
|
||||
r12 = LD_SH(input + 12 * stride);
|
||||
SLLI_4V(r3, r4, r11, r12, 2);
|
||||
|
||||
LD_SW2(const0 + 4 * 4, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 6, 4, k2, k3);
|
||||
MADD_BF(r11, r4, r3, r12, k0, k1, k2, k3, g8, g9, g10, g11);
|
||||
|
||||
/* stage 2 */
|
||||
BUTTERFLY_4(g0, g2, g10, g8, tp0, tp2, tp3, tp1);
|
||||
ST_SH2(tp0, tp2, int_buf, 8);
|
||||
ST_SH2(tp1, tp3, int_buf + 4 * 8, 8);
|
||||
|
||||
LD_SW2(const0 + 4 * 8, 4, k0, k1);
|
||||
k2 = LD_SW(const0 + 4 * 10);
|
||||
MADD_BF(g1, g3, g9, g11, k0, k1, k2, k0, h0, h1, h2, h3);
|
||||
|
||||
ST_SH2(h0, h1, int_buf + 8 * 8, 8);
|
||||
ST_SH2(h3, h2, int_buf + 12 * 8, 8);
|
||||
|
||||
r9 = LD_SH(input + 9 * stride);
|
||||
r6 = LD_SH(input + 6 * stride);
|
||||
r1 = LD_SH(input + stride);
|
||||
r14 = LD_SH(input + 14 * stride);
|
||||
SLLI_4V(r9, r6, r1, r14, 2);
|
||||
|
||||
LD_SW2(const0 + 4 * 11, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 13, 4, k2, k3);
|
||||
MADD_BF(r9, r6, r1, r14, k0, k1, k2, k3, g0, g1, g2, g3);
|
||||
|
||||
ST_SH2(g1, g3, int_buf + 3 * 8, 4 * 8);
|
||||
|
||||
r13 = LD_SH(input + 13 * stride);
|
||||
r2 = LD_SH(input + 2 * stride);
|
||||
r5 = LD_SH(input + 5 * stride);
|
||||
r10 = LD_SH(input + 10 * stride);
|
||||
SLLI_4V(r13, r2, r5, r10, 2);
|
||||
|
||||
LD_SW2(const0 + 4 * 15, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 17, 4, k2, k3);
|
||||
MADD_BF(r13, r2, r5, r10, k0, k1, k2, k3, h0, h1, h2, h3);
|
||||
|
||||
ST_SH2(h1, h3, int_buf + 11 * 8, 4 * 8);
|
||||
|
||||
BUTTERFLY_4(h0, h2, g2, g0, tp0, tp1, tp2, tp3);
|
||||
ST_SH4(tp0, tp1, tp2, tp3, int_buf + 2 * 8, 4 * 8);
|
||||
}
|
||||
|
||||
static void fadst16_step2_msa_helper(int16_t *int_buf, const int32_t *const0,
|
||||
int16_t *out, int16_t *out_ptr) {
|
||||
v8i16 tp0, tp1, tp2, tp3, g5, g7, g13, g15;
|
||||
v8i16 h0, h1, h2, h3, h4, h5, h6, h7, h10, h11;
|
||||
v8i16 out0, out1, out2, out3, out4, out5, out6, out7;
|
||||
v8i16 out8, out9, out10, out11, out12, out13, out14, out15;
|
||||
v4i32 k0, k1, k2, k3;
|
||||
|
||||
LD_SH2(int_buf + 3 * 8, 4 * 8, g13, g15);
|
||||
LD_SH2(int_buf + 11 * 8, 4 * 8, g5, g7);
|
||||
LD_SW2(const0 + 4 * 19, 4, k0, k1);
|
||||
k2 = LD_SW(const0 + 4 * 21);
|
||||
MADD_BF(g7, g5, g15, g13, k0, k1, k2, k0, h4, h5, h6, h7);
|
||||
|
||||
tp0 = LD_SH(int_buf + 4 * 8);
|
||||
tp1 = LD_SH(int_buf + 5 * 8);
|
||||
tp3 = LD_SH(int_buf + 10 * 8);
|
||||
tp2 = LD_SH(int_buf + 14 * 8);
|
||||
LD_SW2(const0 + 4 * 22, 4, k0, k1);
|
||||
k2 = LD_SW(const0 + 4 * 24);
|
||||
MADD_BF(tp0, tp1, tp2, tp3, k0, k1, k2, k0, out4, out6, out5, out7);
|
||||
out4 = -out4;
|
||||
ST_SH(out4, (out + 3 * 16));
|
||||
ST_SH(out5, (out_ptr + 4 * 16));
|
||||
|
||||
h1 = LD_SH(int_buf + 9 * 8);
|
||||
h3 = LD_SH(int_buf + 12 * 8);
|
||||
MADD_BF(h1, h3, h5, h7, k0, k1, k2, k0, out12, out14, out13, out15);
|
||||
out13 = -out13;
|
||||
ST_SH(out12, (out + 2 * 16));
|
||||
ST_SH(out13, (out_ptr + 5 * 16));
|
||||
|
||||
tp0 = LD_SH(int_buf);
|
||||
tp1 = LD_SH(int_buf + 8);
|
||||
tp2 = LD_SH(int_buf + 2 * 8);
|
||||
tp3 = LD_SH(int_buf + 6 * 8);
|
||||
|
||||
BUTTERFLY_4(tp0, tp1, tp3, tp2, out0, out1, h11, h10);
|
||||
out1 = -out1;
|
||||
ST_SH(out0, (out));
|
||||
ST_SH(out1, (out_ptr + 7 * 16));
|
||||
|
||||
h0 = LD_SH(int_buf + 8 * 8);
|
||||
h2 = LD_SH(int_buf + 13 * 8);
|
||||
|
||||
BUTTERFLY_4(h0, h2, h6, h4, out8, out9, out11, out10);
|
||||
out8 = -out8;
|
||||
ST_SH(out8, (out + 16));
|
||||
ST_SH(out9, (out_ptr + 6 * 16));
|
||||
|
||||
/* stage 4 */
|
||||
LD_SW2(const0 + 4 * 25, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 27, 4, k2, k3);
|
||||
MADD_SHORT(h10, h11, k1, k2, out2, out3);
|
||||
ST_SH(out2, (out + 7 * 16));
|
||||
ST_SH(out3, (out_ptr));
|
||||
|
||||
MADD_SHORT(out6, out7, k0, k3, out6, out7);
|
||||
ST_SH(out6, (out + 4 * 16));
|
||||
ST_SH(out7, (out_ptr + 3 * 16));
|
||||
|
||||
MADD_SHORT(out10, out11, k0, k3, out10, out11);
|
||||
ST_SH(out10, (out + 6 * 16));
|
||||
ST_SH(out11, (out_ptr + 16));
|
||||
|
||||
MADD_SHORT(out14, out15, k1, k2, out14, out15);
|
||||
ST_SH(out14, (out + 5 * 16));
|
||||
ST_SH(out15, (out_ptr + 2 * 16));
|
||||
}
|
||||
|
||||
static void fadst16_cols_step2_msa(int16_t *int_buf, const int32_t *const0,
|
||||
int16_t *out) {
|
||||
fadst16_step2_msa_helper(int_buf, const0, out, out + 128);
|
||||
}
|
||||
|
||||
static void fadst16_transpose_postproc_msa(int16_t *input, int16_t *out) {
|
||||
v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15;
|
||||
|
||||
/* load input data */
|
||||
LD_SH8(input, 16, l0, l1, l2, l3, l4, l5, l6, l7);
|
||||
TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6,
|
||||
r7);
|
||||
FDCT_POSTPROC_2V_NEG_H(r0, r1);
|
||||
FDCT_POSTPROC_2V_NEG_H(r2, r3);
|
||||
FDCT_POSTPROC_2V_NEG_H(r4, r5);
|
||||
FDCT_POSTPROC_2V_NEG_H(r6, r7);
|
||||
ST_SH8(r0, r1, r2, r3, r4, r5, r6, r7, out, 8);
|
||||
out += 64;
|
||||
|
||||
LD_SH8(input + 8, 16, l8, l9, l10, l11, l12, l13, l14, l15);
|
||||
TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11,
|
||||
r12, r13, r14, r15);
|
||||
FDCT_POSTPROC_2V_NEG_H(r8, r9);
|
||||
FDCT_POSTPROC_2V_NEG_H(r10, r11);
|
||||
FDCT_POSTPROC_2V_NEG_H(r12, r13);
|
||||
FDCT_POSTPROC_2V_NEG_H(r14, r15);
|
||||
ST_SH8(r8, r9, r10, r11, r12, r13, r14, r15, out, 8);
|
||||
out += 64;
|
||||
|
||||
/* load input data */
|
||||
input += 128;
|
||||
LD_SH8(input, 16, l0, l1, l2, l3, l4, l5, l6, l7);
|
||||
TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6,
|
||||
r7);
|
||||
FDCT_POSTPROC_2V_NEG_H(r0, r1);
|
||||
FDCT_POSTPROC_2V_NEG_H(r2, r3);
|
||||
FDCT_POSTPROC_2V_NEG_H(r4, r5);
|
||||
FDCT_POSTPROC_2V_NEG_H(r6, r7);
|
||||
ST_SH8(r0, r1, r2, r3, r4, r5, r6, r7, out, 8);
|
||||
out += 64;
|
||||
|
||||
LD_SH8(input + 8, 16, l8, l9, l10, l11, l12, l13, l14, l15);
|
||||
TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11,
|
||||
r12, r13, r14, r15);
|
||||
FDCT_POSTPROC_2V_NEG_H(r8, r9);
|
||||
FDCT_POSTPROC_2V_NEG_H(r10, r11);
|
||||
FDCT_POSTPROC_2V_NEG_H(r12, r13);
|
||||
FDCT_POSTPROC_2V_NEG_H(r14, r15);
|
||||
ST_SH8(r8, r9, r10, r11, r12, r13, r14, r15, out, 8);
|
||||
}
|
||||
|
||||
static void fadst16_rows_step1_msa(int16_t *input, const int32_t *const0,
|
||||
int16_t *int_buf) {
|
||||
v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
v8i16 tp0, tp1, tp2, tp3, g0, g1, g2, g3, g8, g9, g10, g11, h0, h1, h2, h3;
|
||||
v4i32 k0, k1, k2, k3;
|
||||
|
||||
/* load input data */
|
||||
r0 = LD_SH(input);
|
||||
r7 = LD_SH(input + 7 * 8);
|
||||
r8 = LD_SH(input + 8 * 8);
|
||||
r15 = LD_SH(input + 15 * 8);
|
||||
|
||||
/* stage 1 */
|
||||
LD_SW2(const0, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 2, 4, k2, k3);
|
||||
MADD_BF(r15, r0, r7, r8, k0, k1, k2, k3, g0, g1, g2, g3);
|
||||
|
||||
r3 = LD_SH(input + 3 * 8);
|
||||
r4 = LD_SH(input + 4 * 8);
|
||||
r11 = LD_SH(input + 11 * 8);
|
||||
r12 = LD_SH(input + 12 * 8);
|
||||
|
||||
LD_SW2(const0 + 4 * 4, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 6, 4, k2, k3);
|
||||
MADD_BF(r11, r4, r3, r12, k0, k1, k2, k3, g8, g9, g10, g11);
|
||||
|
||||
/* stage 2 */
|
||||
BUTTERFLY_4(g0, g2, g10, g8, tp0, tp2, tp3, tp1);
|
||||
ST_SH2(tp0, tp1, int_buf, 4 * 8);
|
||||
ST_SH2(tp2, tp3, int_buf + 8, 4 * 8);
|
||||
|
||||
LD_SW2(const0 + 4 * 8, 4, k0, k1);
|
||||
k2 = LD_SW(const0 + 4 * 10);
|
||||
MADD_BF(g1, g3, g9, g11, k0, k1, k2, k0, h0, h1, h2, h3);
|
||||
ST_SH2(h0, h3, int_buf + 8 * 8, 4 * 8);
|
||||
ST_SH2(h1, h2, int_buf + 9 * 8, 4 * 8);
|
||||
|
||||
r1 = LD_SH(input + 8);
|
||||
r6 = LD_SH(input + 6 * 8);
|
||||
r9 = LD_SH(input + 9 * 8);
|
||||
r14 = LD_SH(input + 14 * 8);
|
||||
|
||||
LD_SW2(const0 + 4 * 11, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 13, 4, k2, k3);
|
||||
MADD_BF(r9, r6, r1, r14, k0, k1, k2, k3, g0, g1, g2, g3);
|
||||
ST_SH2(g1, g3, int_buf + 3 * 8, 4 * 8);
|
||||
|
||||
r2 = LD_SH(input + 2 * 8);
|
||||
r5 = LD_SH(input + 5 * 8);
|
||||
r10 = LD_SH(input + 10 * 8);
|
||||
r13 = LD_SH(input + 13 * 8);
|
||||
|
||||
LD_SW2(const0 + 4 * 15, 4, k0, k1);
|
||||
LD_SW2(const0 + 4 * 17, 4, k2, k3);
|
||||
MADD_BF(r13, r2, r5, r10, k0, k1, k2, k3, h0, h1, h2, h3);
|
||||
ST_SH2(h1, h3, int_buf + 11 * 8, 4 * 8);
|
||||
BUTTERFLY_4(h0, h2, g2, g0, tp0, tp1, tp2, tp3);
|
||||
ST_SH4(tp0, tp1, tp2, tp3, int_buf + 2 * 8, 4 * 8);
|
||||
}
|
||||
|
||||
static void fadst16_rows_step2_msa(int16_t *int_buf, const int32_t *const0,
|
||||
int16_t *out) {
|
||||
fadst16_step2_msa_helper(int_buf, const0, out, out + 8);
|
||||
}
|
||||
|
||||
static void fadst16_transpose_msa(int16_t *input, int16_t *out) {
|
||||
v8i16 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
v8i16 l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15;
|
||||
|
||||
/* load input data */
|
||||
LD_SH16(input, 8, l0, l8, l1, l9, l2, l10, l3, l11, l4, l12, l5, l13, l6, l14,
|
||||
l7, l15);
|
||||
TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6,
|
||||
r7);
|
||||
TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11,
|
||||
r12, r13, r14, r15);
|
||||
ST_SH8(r0, r8, r1, r9, r2, r10, r3, r11, out, 8);
|
||||
ST_SH8(r4, r12, r5, r13, r6, r14, r7, r15, (out + 64), 8);
|
||||
out += 16 * 8;
|
||||
|
||||
/* load input data */
|
||||
input += 128;
|
||||
LD_SH16(input, 8, l0, l8, l1, l9, l2, l10, l3, l11, l4, l12, l5, l13, l6, l14,
|
||||
l7, l15);
|
||||
TRANSPOSE8x8_SH_SH(l0, l1, l2, l3, l4, l5, l6, l7, r0, r1, r2, r3, r4, r5, r6,
|
||||
r7);
|
||||
TRANSPOSE8x8_SH_SH(l8, l9, l10, l11, l12, l13, l14, l15, r8, r9, r10, r11,
|
||||
r12, r13, r14, r15);
|
||||
ST_SH8(r0, r8, r1, r9, r2, r10, r3, r11, out, 8);
|
||||
ST_SH8(r4, r12, r5, r13, r6, r14, r7, r15, (out + 64), 8);
|
||||
}
|
||||
|
||||
static void postproc_fdct16x8_1d_row(int16_t *intermediate, int16_t *output) {
|
||||
int16_t *temp = intermediate;
|
||||
int16_t *out = output;
|
||||
v8i16 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
v8i16 in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11;
|
||||
v8i16 in12, in13, in14, in15;
|
||||
|
||||
LD_SH8(temp, 16, in0, in1, in2, in3, in4, in5, in6, in7);
|
||||
temp = intermediate + 8;
|
||||
LD_SH8(temp, 16, in8, in9, in10, in11, in12, in13, in14, in15);
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3,
|
||||
in4, in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(in8, in9, in10, in11, in12, in13, in14, in15, in8, in9,
|
||||
in10, in11, in12, in13, in14, in15);
|
||||
FDCT_POSTPROC_2V_NEG_H(in0, in1);
|
||||
FDCT_POSTPROC_2V_NEG_H(in2, in3);
|
||||
FDCT_POSTPROC_2V_NEG_H(in4, in5);
|
||||
FDCT_POSTPROC_2V_NEG_H(in6, in7);
|
||||
FDCT_POSTPROC_2V_NEG_H(in8, in9);
|
||||
FDCT_POSTPROC_2V_NEG_H(in10, in11);
|
||||
FDCT_POSTPROC_2V_NEG_H(in12, in13);
|
||||
FDCT_POSTPROC_2V_NEG_H(in14, in15);
|
||||
BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11,
|
||||
in12, in13, in14, in15, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6,
|
||||
tmp7, in8, in9, in10, in11, in12, in13, in14, in15);
|
||||
temp = intermediate;
|
||||
ST_SH8(in8, in9, in10, in11, in12, in13, in14, in15, temp, 16);
|
||||
FDCT8x16_EVEN(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp0, tmp1,
|
||||
tmp2, tmp3, tmp4, tmp5, tmp6, tmp7);
|
||||
temp = intermediate;
|
||||
LD_SH8(temp, 16, in8, in9, in10, in11, in12, in13, in14, in15);
|
||||
FDCT8x16_ODD(in8, in9, in10, in11, in12, in13, in14, in15, in0, in1, in2, in3,
|
||||
in4, in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, tmp0, in0,
|
||||
tmp1, in1, tmp2, in2, tmp3, in3);
|
||||
ST_SH8(tmp0, in0, tmp1, in1, tmp2, in2, tmp3, in3, out, 16);
|
||||
TRANSPOSE8x8_SH_SH(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, tmp4, in4,
|
||||
tmp5, in5, tmp6, in6, tmp7, in7);
|
||||
out = output + 8;
|
||||
ST_SH8(tmp4, in4, tmp5, in5, tmp6, in6, tmp7, in7, out, 16);
|
||||
}
|
||||
|
||||
void av1_fht16x16_msa(const int16_t *input, int16_t *output, int32_t stride,
|
||||
int32_t tx_type) {
|
||||
DECLARE_ALIGNED(32, int16_t, tmp[256]);
|
||||
DECLARE_ALIGNED(32, int16_t, trans_buf[256]);
|
||||
DECLARE_ALIGNED(32, int16_t, tmp_buf[128]);
|
||||
int32_t i;
|
||||
int16_t *ptmpbuf = &tmp_buf[0];
|
||||
int16_t *trans = &trans_buf[0];
|
||||
const int32_t const_arr[29 * 4] = {
|
||||
52707308, 52707308, 52707308, 52707308, -1072430300,
|
||||
-1072430300, -1072430300, -1072430300, 795618043, 795618043,
|
||||
795618043, 795618043, -721080468, -721080468, -721080468,
|
||||
-721080468, 459094491, 459094491, 459094491, 459094491,
|
||||
-970646691, -970646691, -970646691, -970646691, 1010963856,
|
||||
1010963856, 1010963856, 1010963856, -361743294, -361743294,
|
||||
-361743294, -361743294, 209469125, 209469125, 209469125,
|
||||
209469125, -1053094788, -1053094788, -1053094788, -1053094788,
|
||||
1053160324, 1053160324, 1053160324, 1053160324, 639644520,
|
||||
639644520, 639644520, 639644520, -862444000, -862444000,
|
||||
-862444000, -862444000, 1062144356, 1062144356, 1062144356,
|
||||
1062144356, -157532337, -157532337, -157532337, -157532337,
|
||||
260914709, 260914709, 260914709, 260914709, -1041559667,
|
||||
-1041559667, -1041559667, -1041559667, 920985831, 920985831,
|
||||
920985831, 920985831, -551995675, -551995675, -551995675,
|
||||
-551995675, 596522295, 596522295, 596522295, 596522295,
|
||||
892853362, 892853362, 892853362, 892853362, -892787826,
|
||||
-892787826, -892787826, -892787826, 410925857, 410925857,
|
||||
410925857, 410925857, -992012162, -992012162, -992012162,
|
||||
-992012162, 992077698, 992077698, 992077698, 992077698,
|
||||
759246145, 759246145, 759246145, 759246145, -759180609,
|
||||
-759180609, -759180609, -759180609, -759222975, -759222975,
|
||||
-759222975, -759222975, 759288511, 759288511, 759288511,
|
||||
759288511
|
||||
};
|
||||
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
/* column transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fdct8x16_1d_column(input + 8 * i, tmp + 8 * i, stride);
|
||||
}
|
||||
|
||||
/* row transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fdct16x8_1d_row(tmp + (128 * i), output + (128 * i));
|
||||
}
|
||||
break;
|
||||
case ADST_DCT:
|
||||
/* column transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fadst16_cols_step1_msa(input + (i << 3), stride, const_arr, ptmpbuf);
|
||||
fadst16_cols_step2_msa(ptmpbuf, const_arr, tmp + (i << 3));
|
||||
}
|
||||
|
||||
/* row transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
postproc_fdct16x8_1d_row(tmp + (128 * i), output + (128 * i));
|
||||
}
|
||||
break;
|
||||
case DCT_ADST:
|
||||
/* column transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fdct8x16_1d_column(input + 8 * i, tmp + 8 * i, stride);
|
||||
}
|
||||
|
||||
fadst16_transpose_postproc_msa(tmp, trans);
|
||||
|
||||
/* row transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fadst16_rows_step1_msa(trans + (i << 7), const_arr, ptmpbuf);
|
||||
fadst16_rows_step2_msa(ptmpbuf, const_arr, tmp + (i << 7));
|
||||
}
|
||||
|
||||
fadst16_transpose_msa(tmp, output);
|
||||
break;
|
||||
case ADST_ADST:
|
||||
/* column transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fadst16_cols_step1_msa(input + (i << 3), stride, const_arr, ptmpbuf);
|
||||
fadst16_cols_step2_msa(ptmpbuf, const_arr, tmp + (i << 3));
|
||||
}
|
||||
|
||||
fadst16_transpose_postproc_msa(tmp, trans);
|
||||
|
||||
/* row transform */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
fadst16_rows_step1_msa(trans + (i << 7), const_arr, ptmpbuf);
|
||||
fadst16_rows_step2_msa(ptmpbuf, const_arr, tmp + (i << 7));
|
||||
}
|
||||
|
||||
fadst16_transpose_msa(tmp, output);
|
||||
break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/encoder/mips/msa/fdct_msa.h"
|
||||
|
||||
void av1_fwht4x4_msa(const int16_t *input, int16_t *output,
|
||||
int32_t src_stride) {
|
||||
|
|
@ -45,54 +44,3 @@ void av1_fwht4x4_msa(const int16_t *input, int16_t *output,
|
|||
ST4x2_UB(in1, output + 8, 4);
|
||||
ST4x2_UB(in2, output + 12, 4);
|
||||
}
|
||||
|
||||
void av1_fht4x4_msa(const int16_t *input, int16_t *output, int32_t stride,
|
||||
int32_t tx_type) {
|
||||
v8i16 in0, in1, in2, in3;
|
||||
|
||||
LD_SH4(input, stride, in0, in1, in2, in3);
|
||||
|
||||
/* fdct4 pre-process */
|
||||
{
|
||||
v8i16 temp, mask;
|
||||
v16i8 zero = { 0 };
|
||||
v16i8 one = __msa_ldi_b(1);
|
||||
|
||||
mask = (v8i16)__msa_sldi_b(zero, one, 15);
|
||||
SLLI_4V(in0, in1, in2, in3, 4);
|
||||
temp = __msa_ceqi_h(in0, 0);
|
||||
temp = (v8i16)__msa_xori_b((v16u8)temp, 255);
|
||||
temp = mask & temp;
|
||||
in0 += temp;
|
||||
}
|
||||
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
AOM_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
AOM_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
break;
|
||||
case ADST_DCT:
|
||||
AOM_FADST4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
AOM_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
break;
|
||||
case DCT_ADST:
|
||||
AOM_FDCT4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
AOM_FADST4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
break;
|
||||
case ADST_ADST:
|
||||
AOM_FADST4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
AOM_FADST4(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
|
||||
TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, in0, in1, in2, in3);
|
||||
ADD4(in0, 1, in1, 1, in2, 1, in3, 1, in0, in1, in2, in3);
|
||||
SRA_4V(in0, in1, in2, in3, 2);
|
||||
PCKEV_D2_SH(in1, in0, in3, in2, in0, in2);
|
||||
ST_SH2(in0, in2, output, 8);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/encoder/mips/msa/fdct_msa.h"
|
||||
|
||||
void av1_fht8x8_msa(const int16_t *input, int16_t *output, int32_t stride,
|
||||
int32_t tx_type) {
|
||||
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
|
||||
|
||||
LD_SH8(input, stride, in0, in1, in2, in3, in4, in5, in6, in7);
|
||||
SLLI_4V(in0, in1, in2, in3, 2);
|
||||
SLLI_4V(in4, in5, in6, in7, 2);
|
||||
|
||||
switch (tx_type) {
|
||||
case DCT_DCT:
|
||||
AOM_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2,
|
||||
in3, in4, in5, in6, in7);
|
||||
AOM_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
break;
|
||||
case ADST_DCT:
|
||||
AOM_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2,
|
||||
in3, in4, in5, in6, in7);
|
||||
AOM_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
break;
|
||||
case DCT_ADST:
|
||||
AOM_FDCT8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2,
|
||||
in3, in4, in5, in6, in7);
|
||||
AOM_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
break;
|
||||
case ADST_ADST:
|
||||
AOM_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2,
|
||||
in3, in4, in5, in6, in7);
|
||||
AOM_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3, in4,
|
||||
in5, in6, in7);
|
||||
break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
|
||||
TRANSPOSE8x8_SH_SH(in0, in1, in2, in3, in4, in5, in6, in7, in0, in1, in2, in3,
|
||||
in4, in5, in6, in7);
|
||||
SRLI_AVE_S_4V_H(in0, in1, in2, in3, in4, in5, in6, in7);
|
||||
ST_SH8(in0, in1, in2, in3, in4, in5, in6, in7, output, 8);
|
||||
}
|
||||
117
third_party/aom/av1/encoder/mips/msa/fdct_msa.h
vendored
117
third_party/aom/av1/encoder/mips/msa/fdct_msa.h
vendored
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_MIPS_MSA_AV1_FDCT_MSA_H_
|
||||
#define AV1_ENCODER_MIPS_MSA_AV1_FDCT_MSA_H_
|
||||
|
||||
#include "aom_dsp/mips/fwd_txfm_msa.h"
|
||||
#include "aom_dsp/mips/txfm_macros_msa.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
#define AOM_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \
|
||||
out3, out4, out5, out6, out7) \
|
||||
{ \
|
||||
v8i16 cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst4_m; \
|
||||
v8i16 vec0_m, vec1_m, vec2_m, vec3_m, s0_m, s1_m; \
|
||||
v8i16 coeff0_m = { cospi_2_64, cospi_6_64, cospi_10_64, cospi_14_64, \
|
||||
cospi_18_64, cospi_22_64, cospi_26_64, cospi_30_64 }; \
|
||||
v8i16 coeff1_m = { cospi_8_64, -cospi_8_64, cospi_16_64, -cospi_16_64, \
|
||||
cospi_24_64, -cospi_24_64, 0, 0 }; \
|
||||
\
|
||||
SPLATI_H2_SH(coeff0_m, 0, 7, cnst0_m, cnst1_m); \
|
||||
cnst2_m = -cnst0_m; \
|
||||
ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \
|
||||
SPLATI_H2_SH(coeff0_m, 4, 3, cnst2_m, cnst3_m); \
|
||||
cnst4_m = -cnst2_m; \
|
||||
ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \
|
||||
\
|
||||
ILVRL_H2_SH(in0, in7, vec1_m, vec0_m); \
|
||||
ILVRL_H2_SH(in4, in3, vec3_m, vec2_m); \
|
||||
DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \
|
||||
cnst2_m, cnst3_m, in7, in0, in4, in3); \
|
||||
\
|
||||
SPLATI_H2_SH(coeff0_m, 2, 5, cnst0_m, cnst1_m); \
|
||||
cnst2_m = -cnst0_m; \
|
||||
ILVEV_H2_SH(cnst0_m, cnst1_m, cnst1_m, cnst2_m, cnst0_m, cnst1_m); \
|
||||
SPLATI_H2_SH(coeff0_m, 6, 1, cnst2_m, cnst3_m); \
|
||||
cnst4_m = -cnst2_m; \
|
||||
ILVEV_H2_SH(cnst2_m, cnst3_m, cnst3_m, cnst4_m, cnst2_m, cnst3_m); \
|
||||
\
|
||||
ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \
|
||||
ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \
|
||||
\
|
||||
DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst1_m, \
|
||||
cnst2_m, cnst3_m, in5, in2, in6, in1); \
|
||||
BUTTERFLY_4(in7, in0, in2, in5, s1_m, s0_m, in2, in5); \
|
||||
out7 = -s0_m; \
|
||||
out0 = s1_m; \
|
||||
\
|
||||
SPLATI_H4_SH(coeff1_m, 0, 4, 1, 5, cnst0_m, cnst1_m, cnst2_m, cnst3_m); \
|
||||
\
|
||||
ILVEV_H2_SH(cnst3_m, cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst2_m); \
|
||||
cnst0_m = __msa_ilvev_h(cnst1_m, cnst0_m); \
|
||||
cnst1_m = cnst0_m; \
|
||||
\
|
||||
ILVRL_H2_SH(in4, in3, vec1_m, vec0_m); \
|
||||
ILVRL_H2_SH(in6, in1, vec3_m, vec2_m); \
|
||||
DOT_ADD_SUB_SRARI_PCK(vec0_m, vec1_m, vec2_m, vec3_m, cnst0_m, cnst2_m, \
|
||||
cnst3_m, cnst1_m, out1, out6, s0_m, s1_m); \
|
||||
\
|
||||
SPLATI_H2_SH(coeff1_m, 2, 3, cnst0_m, cnst1_m); \
|
||||
cnst1_m = __msa_ilvev_h(cnst1_m, cnst0_m); \
|
||||
\
|
||||
ILVRL_H2_SH(in2, in5, vec1_m, vec0_m); \
|
||||
ILVRL_H2_SH(s0_m, s1_m, vec3_m, vec2_m); \
|
||||
out3 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst0_m); \
|
||||
out4 = DOT_SHIFT_RIGHT_PCK_H(vec0_m, vec1_m, cnst1_m); \
|
||||
out2 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst0_m); \
|
||||
out5 = DOT_SHIFT_RIGHT_PCK_H(vec2_m, vec3_m, cnst1_m); \
|
||||
\
|
||||
out1 = -out1; \
|
||||
out3 = -out3; \
|
||||
out5 = -out5; \
|
||||
}
|
||||
|
||||
#define AOM_FADST4(in0, in1, in2, in3, out0, out1, out2, out3) \
|
||||
{ \
|
||||
v4i32 s0_m, s1_m, s2_m, s3_m, constant_m; \
|
||||
v4i32 in0_r_m, in1_r_m, in2_r_m, in3_r_m; \
|
||||
\
|
||||
UNPCK_R_SH_SW(in0, in0_r_m); \
|
||||
UNPCK_R_SH_SW(in1, in1_r_m); \
|
||||
UNPCK_R_SH_SW(in2, in2_r_m); \
|
||||
UNPCK_R_SH_SW(in3, in3_r_m); \
|
||||
\
|
||||
constant_m = __msa_fill_w(sinpi_4_9); \
|
||||
MUL2(in0_r_m, constant_m, in3_r_m, constant_m, s1_m, s0_m); \
|
||||
\
|
||||
constant_m = __msa_fill_w(sinpi_1_9); \
|
||||
s0_m += in0_r_m * constant_m; \
|
||||
s1_m -= in1_r_m * constant_m; \
|
||||
\
|
||||
constant_m = __msa_fill_w(sinpi_2_9); \
|
||||
s0_m += in1_r_m * constant_m; \
|
||||
s1_m += in3_r_m * constant_m; \
|
||||
\
|
||||
s2_m = in0_r_m + in1_r_m - in3_r_m; \
|
||||
\
|
||||
constant_m = __msa_fill_w(sinpi_3_9); \
|
||||
MUL2(in2_r_m, constant_m, s2_m, constant_m, s3_m, in1_r_m); \
|
||||
\
|
||||
in0_r_m = s0_m + s3_m; \
|
||||
s2_m = s1_m - s3_m; \
|
||||
s3_m = s1_m - s0_m + s3_m; \
|
||||
\
|
||||
SRARI_W4_SW(in0_r_m, in1_r_m, s2_m, s3_m, DCT_CONST_BITS); \
|
||||
PCKEV_H4_SH(in0_r_m, in0_r_m, in1_r_m, in1_r_m, s2_m, s2_m, s3_m, s3_m, \
|
||||
out0, out1, out2, out3); \
|
||||
}
|
||||
#endif // AV1_ENCODER_MIPS_MSA_AV1_FDCT_MSA_H_
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./av1_rtcd.h"
|
||||
#include "config/av1_rtcd.h"
|
||||
|
||||
#include "aom_dsp/mips/macros_msa.h"
|
||||
|
||||
static void temporal_filter_apply_8size_msa(uint8_t *frm1_ptr, uint32_t stride,
|
||||
|
|
|
|||
57
third_party/aom/av1/encoder/ml.c
vendored
Normal file
57
third_party/aom/av1/encoder/ml.c
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "av1/encoder/ml.h"
|
||||
|
||||
void av1_nn_predict(const float *features, const NN_CONFIG *nn_config,
|
||||
float *output) {
|
||||
int num_input_nodes = nn_config->num_inputs;
|
||||
int buf_index = 0;
|
||||
float buf[2][NN_MAX_NODES_PER_LAYER];
|
||||
const float *input_nodes = features;
|
||||
|
||||
// Propagate hidden layers.
|
||||
const int num_layers = nn_config->num_hidden_layers;
|
||||
assert(num_layers <= NN_MAX_HIDDEN_LAYERS);
|
||||
for (int layer = 0; layer < num_layers; ++layer) {
|
||||
const float *weights = nn_config->weights[layer];
|
||||
const float *bias = nn_config->bias[layer];
|
||||
float *output_nodes = buf[buf_index];
|
||||
const int num_output_nodes = nn_config->num_hidden_nodes[layer];
|
||||
assert(num_output_nodes < NN_MAX_NODES_PER_LAYER);
|
||||
for (int node = 0; node < num_output_nodes; ++node) {
|
||||
float val = 0.0f;
|
||||
for (int i = 0; i < num_input_nodes; ++i)
|
||||
val += weights[i] * input_nodes[i];
|
||||
val += bias[node];
|
||||
// ReLU as activation function.
|
||||
val = val > 0.0f ? val : 0.0f; // Could use AOMMAX().
|
||||
output_nodes[node] = val;
|
||||
weights += num_input_nodes;
|
||||
}
|
||||
num_input_nodes = num_output_nodes;
|
||||
input_nodes = output_nodes;
|
||||
buf_index = 1 - buf_index;
|
||||
}
|
||||
|
||||
// Final output layer.
|
||||
const float *weights = nn_config->weights[num_layers];
|
||||
for (int node = 0; node < nn_config->num_outputs; ++node) {
|
||||
const float *bias = nn_config->bias[num_layers];
|
||||
float val = 0.0f;
|
||||
for (int i = 0; i < num_input_nodes; ++i)
|
||||
val += weights[i] * input_nodes[i];
|
||||
output[node] = val + bias[node];
|
||||
weights += num_input_nodes;
|
||||
}
|
||||
}
|
||||
44
third_party/aom/av1/encoder/ml.h
vendored
Normal file
44
third_party/aom/av1/encoder/ml.h
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_ML_H_
|
||||
#define AV1_ENCODER_ML_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NN_MAX_HIDDEN_LAYERS 10
|
||||
#define NN_MAX_NODES_PER_LAYER 128
|
||||
|
||||
typedef struct {
|
||||
int num_inputs; // Number of input nodes, i.e. features.
|
||||
int num_outputs; // Number of output nodes.
|
||||
int num_hidden_layers; // Number of hidden layers, maximum 10.
|
||||
// Number of nodes for each hidden layer.
|
||||
int num_hidden_nodes[NN_MAX_HIDDEN_LAYERS];
|
||||
// Weight parameters, indexed by layer.
|
||||
const float *weights[NN_MAX_HIDDEN_LAYERS + 1];
|
||||
// Bias parameters, indexed by layer.
|
||||
const float *bias[NN_MAX_HIDDEN_LAYERS + 1];
|
||||
} NN_CONFIG;
|
||||
|
||||
// Calculate prediction based on the given input features and neural net config.
|
||||
// Assume there are no more than NN_MAX_NODES_PER_LAYER nodes in each hidden
|
||||
// layer.
|
||||
void av1_nn_predict(const float *features, const NN_CONFIG *nn_config,
|
||||
float *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_RD_H_
|
||||
28
third_party/aom/av1/encoder/palette.c
vendored
28
third_party/aom/av1/encoder/palette.c
vendored
|
|
@ -23,16 +23,14 @@
|
|||
#include "av1/encoder/k_means_template.h"
|
||||
#undef AV1_K_MEANS_DIM
|
||||
|
||||
static int float_comparer(const void *a, const void *b) {
|
||||
const float fa = *(const float *)a;
|
||||
const float fb = *(const float *)b;
|
||||
return (fa > fb) - (fa < fb);
|
||||
static int int_comparer(const void *a, const void *b) {
|
||||
return (*(int *)a - *(int *)b);
|
||||
}
|
||||
|
||||
int av1_remove_duplicates(float *centroids, int num_centroids) {
|
||||
int av1_remove_duplicates(int *centroids, int num_centroids) {
|
||||
int num_unique; // number of unique centroids
|
||||
int i;
|
||||
qsort(centroids, num_centroids, sizeof(*centroids), float_comparer);
|
||||
qsort(centroids, num_centroids, sizeof(*centroids), int_comparer);
|
||||
// Remove duplicates.
|
||||
num_unique = 1;
|
||||
for (i = 1; i < num_centroids; ++i) {
|
||||
|
|
@ -43,7 +41,6 @@ int av1_remove_duplicates(float *centroids, int num_centroids) {
|
|||
return num_unique;
|
||||
}
|
||||
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
static int delta_encode_cost(const int *colors, int num, int bit_depth,
|
||||
int min_val) {
|
||||
if (num <= 0) return 0;
|
||||
|
|
@ -116,15 +113,11 @@ int av1_get_palette_delta_bits_v(const PALETTE_MODE_INFO *const pmi,
|
|||
}
|
||||
return AOMMAX(av1_ceil_log2(max_d + 1), *min_bits);
|
||||
}
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
|
||||
int av1_palette_color_cost_y(const PALETTE_MODE_INFO *const pmi,
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
uint16_t *color_cache, int n_cache,
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
int bit_depth) {
|
||||
const int n = pmi->palette_size[0];
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
int out_cache_colors[PALETTE_MAX_SIZE];
|
||||
uint8_t cache_color_found[2 * PALETTE_MAX_SIZE];
|
||||
const int n_out_cache =
|
||||
|
|
@ -132,19 +125,13 @@ int av1_palette_color_cost_y(const PALETTE_MODE_INFO *const pmi,
|
|||
cache_color_found, out_cache_colors);
|
||||
const int total_bits =
|
||||
n_cache + delta_encode_cost(out_cache_colors, n_out_cache, bit_depth, 1);
|
||||
return total_bits * av1_cost_bit(128, 0);
|
||||
#else
|
||||
return bit_depth * n * av1_cost_bit(128, 0);
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
return av1_cost_literal(total_bits);
|
||||
}
|
||||
|
||||
int av1_palette_color_cost_uv(const PALETTE_MODE_INFO *const pmi,
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
uint16_t *color_cache, int n_cache,
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
int bit_depth) {
|
||||
const int n = pmi->palette_size[1];
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
int total_bits = 0;
|
||||
// U channel palette color cost.
|
||||
int out_cache_colors[PALETTE_MAX_SIZE];
|
||||
|
|
@ -163,8 +150,5 @@ int av1_palette_color_cost_uv(const PALETTE_MODE_INFO *const pmi,
|
|||
2 + bit_depth + (bits_v + 1) * (n - 1) - zero_count;
|
||||
const int bits_using_raw = bit_depth * n;
|
||||
total_bits += 1 + AOMMIN(bits_using_delta, bits_using_raw);
|
||||
return total_bits * av1_cost_bit(128, 0);
|
||||
#else
|
||||
return 2 * bit_depth * n * av1_cost_bit(128, 0);
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
return av1_cost_literal(total_bits);
|
||||
}
|
||||
|
|
|
|||
27
third_party/aom/av1/encoder/palette.h
vendored
27
third_party/aom/av1/encoder/palette.h
vendored
|
|
@ -20,22 +20,22 @@ extern "C" {
|
|||
|
||||
#define AV1_K_MEANS_RENAME(func, dim) func##_dim##dim
|
||||
|
||||
void AV1_K_MEANS_RENAME(av1_calc_indices, 1)(const float *data,
|
||||
const float *centroids,
|
||||
void AV1_K_MEANS_RENAME(av1_calc_indices, 1)(const int *data,
|
||||
const int *centroids,
|
||||
uint8_t *indices, int n, int k);
|
||||
void AV1_K_MEANS_RENAME(av1_calc_indices, 2)(const float *data,
|
||||
const float *centroids,
|
||||
void AV1_K_MEANS_RENAME(av1_calc_indices, 2)(const int *data,
|
||||
const int *centroids,
|
||||
uint8_t *indices, int n, int k);
|
||||
void AV1_K_MEANS_RENAME(av1_k_means, 1)(const float *data, float *centroids,
|
||||
void AV1_K_MEANS_RENAME(av1_k_means, 1)(const int *data, int *centroids,
|
||||
uint8_t *indices, int n, int k,
|
||||
int max_itr);
|
||||
void AV1_K_MEANS_RENAME(av1_k_means, 2)(const float *data, float *centroids,
|
||||
void AV1_K_MEANS_RENAME(av1_k_means, 2)(const int *data, int *centroids,
|
||||
uint8_t *indices, int n, int k,
|
||||
int max_itr);
|
||||
|
||||
// Given 'n' 'data' points and 'k' 'centroids' each of dimension 'dim',
|
||||
// calculate the centroid 'indices' for the data points.
|
||||
static INLINE void av1_calc_indices(const float *data, const float *centroids,
|
||||
static INLINE void av1_calc_indices(const int *data, const int *centroids,
|
||||
uint8_t *indices, int n, int k, int dim) {
|
||||
if (dim == 1) {
|
||||
AV1_K_MEANS_RENAME(av1_calc_indices, 1)(data, centroids, indices, n, k);
|
||||
|
|
@ -50,7 +50,7 @@ static INLINE void av1_calc_indices(const float *data, const float *centroids,
|
|||
// dimension 'dim', runs up to 'max_itr' iterations of k-means algorithm to get
|
||||
// updated 'centroids' and the centroid 'indices' for elements in 'data'.
|
||||
// Note: the output centroids are rounded off to nearest integers.
|
||||
static INLINE void av1_k_means(const float *data, float *centroids,
|
||||
static INLINE void av1_k_means(const int *data, int *centroids,
|
||||
uint8_t *indices, int n, int k, int dim,
|
||||
int max_itr) {
|
||||
if (dim == 1) {
|
||||
|
|
@ -66,9 +66,8 @@ static INLINE void av1_k_means(const float *data, float *centroids,
|
|||
// puts these unique centroids in first 'k' indices of 'centroids' array.
|
||||
// Ideally, the centroids should be rounded to integers before calling this
|
||||
// method.
|
||||
int av1_remove_duplicates(float *centroids, int num_centroids);
|
||||
int av1_remove_duplicates(int *centroids, int num_centroids);
|
||||
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
// Given a color cache and a set of base colors, find if each cache color is
|
||||
// present in the base colors, record the binary results in "cache_color_found".
|
||||
// Record the colors that are not in the color cache in "out_cache_colors".
|
||||
|
|
@ -80,20 +79,14 @@ int av1_index_color_cache(const uint16_t *color_cache, int n_cache,
|
|||
// assign zero_count with the number of deltas being 0.
|
||||
int av1_get_palette_delta_bits_v(const PALETTE_MODE_INFO *const pmi,
|
||||
int bit_depth, int *zero_count, int *min_bits);
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
|
||||
// Return the rate cost for transmitting luma palette color values.
|
||||
int av1_palette_color_cost_y(const PALETTE_MODE_INFO *const pmi,
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
uint16_t *color_cache, int n_cache,
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
int bit_depth);
|
||||
uint16_t *color_cache, int n_cache, int bit_depth);
|
||||
|
||||
// Return the rate cost for transmitting chroma palette color values.
|
||||
int av1_palette_color_cost_uv(const PALETTE_MODE_INFO *const pmi,
|
||||
#if CONFIG_PALETTE_DELTA_ENCODING
|
||||
uint16_t *color_cache, int n_cache,
|
||||
#endif // CONFIG_PALETTE_DELTA_ENCODING
|
||||
int bit_depth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
97
third_party/aom/av1/encoder/pickcdef.c
vendored
97
third_party/aom/av1/encoder/pickcdef.c
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "./aom_scale_rtcd.h"
|
||||
#include "config/aom_scale_rtcd.h"
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "av1/common/cdef.h"
|
||||
#include "av1/common/onyxc_int.h"
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
#define REDUCED_TOTAL_STRENGTHS (REDUCED_PRI_STRENGTHS * CDEF_SEC_STRENGTHS)
|
||||
#define TOTAL_STRENGTHS (CDEF_PRI_STRENGTHS * CDEF_SEC_STRENGTHS)
|
||||
|
||||
static int priconv[REDUCED_PRI_STRENGTHS] = { 0, 1, 2, 3, 4, 7, 12, 25 };
|
||||
static int priconv[REDUCED_PRI_STRENGTHS] = { 0, 1, 2, 3, 5, 7, 10, 13 };
|
||||
|
||||
/* Search for the best strength to add as an option, knowing we
|
||||
already selected nb_strengths options. */
|
||||
|
|
@ -68,16 +69,11 @@ static uint64_t search_one_dual(int *lev0, int *lev1, int nb_strengths,
|
|||
uint64_t (**mse)[TOTAL_STRENGTHS], int sb_count,
|
||||
int fast) {
|
||||
uint64_t tot_mse[TOTAL_STRENGTHS][TOTAL_STRENGTHS];
|
||||
#if !CONFIG_CDEF_SINGLEPASS
|
||||
const int total_strengths = fast ? REDUCED_TOTAL_STRENGTHS : TOTAL_STRENGTHS;
|
||||
#endif
|
||||
int i, j;
|
||||
uint64_t best_tot_mse = (uint64_t)1 << 63;
|
||||
int best_id0 = 0;
|
||||
int best_id1 = 0;
|
||||
#if CONFIG_CDEF_SINGLEPASS
|
||||
const int total_strengths = fast ? REDUCED_TOTAL_STRENGTHS : TOTAL_STRENGTHS;
|
||||
#endif
|
||||
memset(tot_mse, 0, sizeof(tot_mse));
|
||||
for (i = 0; i < sb_count; i++) {
|
||||
int gi;
|
||||
|
|
@ -204,10 +200,9 @@ static INLINE uint64_t dist_8x8_16bit(uint16_t *dst, int dstride, uint16_t *src,
|
|||
svar = sum_s2 - ((sum_s * sum_s + 32) >> 6);
|
||||
dvar = sum_d2 - ((sum_d * sum_d + 32) >> 6);
|
||||
return (uint64_t)floor(
|
||||
.5 +
|
||||
(sum_d2 + sum_s2 - 2 * sum_sd) * .5 *
|
||||
(svar + dvar + (400 << 2 * coeff_shift)) /
|
||||
(sqrt((20000 << 4 * coeff_shift) + svar * (double)dvar)));
|
||||
.5 + (sum_d2 + sum_s2 - 2 * sum_sd) * .5 *
|
||||
(svar + dvar + (400 << 2 * coeff_shift)) /
|
||||
(sqrt((20000 << 4 * coeff_shift) + svar * (double)dvar)));
|
||||
}
|
||||
|
||||
static INLINE uint64_t mse_8x8_16bit(uint16_t *dst, int dstride, uint16_t *src,
|
||||
|
|
@ -290,7 +285,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int fbr, fbc;
|
||||
uint16_t *src[3];
|
||||
uint16_t *ref_coeff[3];
|
||||
cdef_list dlist[MI_SIZE_64X64 * MI_SIZE_64X64];
|
||||
static cdef_list dlist[MI_SIZE_128X128 * MI_SIZE_128X128];
|
||||
int dir[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
|
||||
int var[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
|
||||
int stride[3];
|
||||
|
|
@ -310,32 +305,27 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int *sb_index = aom_malloc(nvfb * nhfb * sizeof(*sb_index));
|
||||
int *selected_strength = aom_malloc(nvfb * nhfb * sizeof(*sb_index));
|
||||
uint64_t(*mse[2])[TOTAL_STRENGTHS];
|
||||
#if CONFIG_CDEF_SINGLEPASS
|
||||
int pri_damping = 3 + (cm->base_qindex >> 6);
|
||||
#else
|
||||
int pri_damping = 6;
|
||||
#endif
|
||||
int sec_damping = 3 + (cm->base_qindex >> 6);
|
||||
int i;
|
||||
int nb_strengths;
|
||||
int nb_strength_bits;
|
||||
int quantizer;
|
||||
double lambda;
|
||||
int nplanes = 3;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
const int total_strengths = fast ? REDUCED_TOTAL_STRENGTHS : TOTAL_STRENGTHS;
|
||||
DECLARE_ALIGNED(32, uint16_t, inbuf[CDEF_INBUF_SIZE]);
|
||||
uint16_t *in;
|
||||
DECLARE_ALIGNED(32, uint16_t, tmp_dst[CDEF_BLOCKSIZE * CDEF_BLOCKSIZE]);
|
||||
int chroma_cdef = xd->plane[1].subsampling_x == xd->plane[1].subsampling_y &&
|
||||
xd->plane[2].subsampling_x == xd->plane[2].subsampling_y;
|
||||
DECLARE_ALIGNED(32, uint16_t, tmp_dst[1 << (MAX_SB_SIZE_LOG2 * 2)]);
|
||||
quantizer =
|
||||
av1_ac_quant(cm->base_qindex, 0, cm->bit_depth) >> (cm->bit_depth - 8);
|
||||
av1_ac_quant_Q3(cm->base_qindex, 0, cm->bit_depth) >> (cm->bit_depth - 8);
|
||||
lambda = .12 * quantizer * quantizer / 256.;
|
||||
|
||||
av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0);
|
||||
av1_setup_dst_planes(xd->plane, cm->seq_params.sb_size, frame, 0, 0, 0,
|
||||
num_planes);
|
||||
mse[0] = aom_malloc(sizeof(**mse) * nvfb * nhfb);
|
||||
mse[1] = aom_malloc(sizeof(**mse) * nvfb * nhfb);
|
||||
for (pli = 0; pli < nplanes; pli++) {
|
||||
for (pli = 0; pli < num_planes; pli++) {
|
||||
uint8_t *ref_buffer;
|
||||
int ref_stride;
|
||||
switch (pli) {
|
||||
|
|
@ -371,20 +361,16 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
|
||||
for (r = 0; r < frame_height; ++r) {
|
||||
for (c = 0; c < frame_width; ++c) {
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (cm->use_highbitdepth) {
|
||||
src[pli][r * stride[pli] + c] = CONVERT_TO_SHORTPTR(
|
||||
xd->plane[pli].dst.buf)[r * xd->plane[pli].dst.stride + c];
|
||||
ref_coeff[pli][r * stride[pli] + c] =
|
||||
CONVERT_TO_SHORTPTR(ref_buffer)[r * ref_stride + c];
|
||||
} else {
|
||||
#endif
|
||||
src[pli][r * stride[pli] + c] =
|
||||
xd->plane[pli].dst.buf[r * xd->plane[pli].dst.stride + c];
|
||||
ref_coeff[pli][r * stride[pli] + c] = ref_buffer[r * ref_stride + c];
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -397,13 +383,33 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int dirinit = 0;
|
||||
nhb = AOMMIN(MI_SIZE_64X64, cm->mi_cols - MI_SIZE_64X64 * fbc);
|
||||
nvb = AOMMIN(MI_SIZE_64X64, cm->mi_rows - MI_SIZE_64X64 * fbr);
|
||||
cm->mi_grid_visible[MI_SIZE_64X64 * fbr * cm->mi_stride +
|
||||
MI_SIZE_64X64 * fbc]
|
||||
->mbmi.cdef_strength = -1;
|
||||
int hb_step = 1;
|
||||
int vb_step = 1;
|
||||
BLOCK_SIZE bs = BLOCK_64X64;
|
||||
MB_MODE_INFO *const mbmi =
|
||||
cm->mi_grid_visible[MI_SIZE_64X64 * fbr * cm->mi_stride +
|
||||
MI_SIZE_64X64 * fbc];
|
||||
if (((fbc & 1) &&
|
||||
(mbmi->sb_type == BLOCK_128X128 || mbmi->sb_type == BLOCK_128X64)) ||
|
||||
((fbr & 1) &&
|
||||
(mbmi->sb_type == BLOCK_128X128 || mbmi->sb_type == BLOCK_64X128)))
|
||||
continue;
|
||||
if (mbmi->sb_type == BLOCK_128X128 || mbmi->sb_type == BLOCK_128X64 ||
|
||||
mbmi->sb_type == BLOCK_64X128)
|
||||
bs = mbmi->sb_type;
|
||||
if (bs == BLOCK_128X128 || bs == BLOCK_128X64) {
|
||||
nhb = AOMMIN(MI_SIZE_128X128, cm->mi_cols - MI_SIZE_64X64 * fbc);
|
||||
hb_step = 2;
|
||||
}
|
||||
if (bs == BLOCK_128X128 || bs == BLOCK_64X128) {
|
||||
nvb = AOMMIN(MI_SIZE_128X128, cm->mi_rows - MI_SIZE_64X64 * fbr);
|
||||
vb_step = 2;
|
||||
}
|
||||
// No filtering if the entire filter block is skipped
|
||||
if (sb_all_skip(cm, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64)) continue;
|
||||
cdef_count = sb_compute_cdef_list(cm, fbr * MI_SIZE_64X64,
|
||||
fbc * MI_SIZE_64X64, dlist, 1);
|
||||
for (pli = 0; pli < nplanes; pli++) {
|
||||
fbc * MI_SIZE_64X64, dlist, bs);
|
||||
for (pli = 0; pli < num_planes; pli++) {
|
||||
for (i = 0; i < CDEF_INBUF_SIZE; i++) inbuf[i] = CDEF_VERY_LARGE;
|
||||
for (gi = 0; gi < total_strengths; gi++) {
|
||||
int threshold;
|
||||
|
|
@ -411,7 +417,6 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int sec_strength;
|
||||
threshold = gi / CDEF_SEC_STRENGTHS;
|
||||
if (fast) threshold = priconv[threshold];
|
||||
if (pli > 0 && !chroma_cdef) threshold = 0;
|
||||
/* We avoid filtering the pixels for which some of the pixels to
|
||||
average
|
||||
are outside the frame. We could change the filter instead, but it
|
||||
|
|
@ -419,11 +424,10 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int yoff = CDEF_VBORDER * (fbr != 0);
|
||||
int xoff = CDEF_HBORDER * (fbc != 0);
|
||||
int ysize = (nvb << mi_high_l2[pli]) +
|
||||
CDEF_VBORDER * (fbr != nvfb - 1) + yoff;
|
||||
CDEF_VBORDER * (fbr + vb_step < nvfb) + yoff;
|
||||
int xsize = (nhb << mi_wide_l2[pli]) +
|
||||
CDEF_HBORDER * (fbc != nhfb - 1) + xoff;
|
||||
CDEF_HBORDER * (fbc + hb_step < nhfb) + xoff;
|
||||
sec_strength = gi % CDEF_SEC_STRENGTHS;
|
||||
#if CONFIG_CDEF_SINGLEPASS
|
||||
copy_sb16_16(&in[(-yoff * CDEF_BSTRIDE - xoff)], CDEF_BSTRIDE,
|
||||
src[pli],
|
||||
(fbr * MI_SIZE_64X64 << mi_high_l2[pli]) - yoff,
|
||||
|
|
@ -433,19 +437,6 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
dir, &dirinit, var, pli, dlist, cdef_count, threshold,
|
||||
sec_strength + (sec_strength == 3), pri_damping,
|
||||
sec_damping, coeff_shift);
|
||||
#else
|
||||
if (sec_strength == 0)
|
||||
copy_sb16_16(&in[(-yoff * CDEF_BSTRIDE - xoff)], CDEF_BSTRIDE,
|
||||
src[pli],
|
||||
(fbr * MI_SIZE_64X64 << mi_high_l2[pli]) - yoff,
|
||||
(fbc * MI_SIZE_64X64 << mi_wide_l2[pli]) - xoff,
|
||||
stride[pli], ysize, xsize);
|
||||
cdef_filter_fb(sec_strength ? NULL : (uint8_t *)in, CDEF_BSTRIDE,
|
||||
tmp_dst, in, xdec[pli], ydec[pli], dir, &dirinit, var,
|
||||
pli, dlist, cdef_count, threshold,
|
||||
sec_strength + (sec_strength == 3), sec_damping,
|
||||
pri_damping, coeff_shift, sec_strength != 0, 1);
|
||||
#endif
|
||||
curr_mse = compute_cdef_dist(
|
||||
ref_coeff[pli] +
|
||||
(fbr * MI_SIZE_64X64 << mi_high_l2[pli]) * stride[pli] +
|
||||
|
|
@ -470,7 +461,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
int best_lev0[CDEF_MAX_STRENGTHS];
|
||||
int best_lev1[CDEF_MAX_STRENGTHS] = { 0 };
|
||||
nb_strengths = 1 << i;
|
||||
if (nplanes >= 3)
|
||||
if (num_planes >= 3)
|
||||
tot_mse = joint_strength_search_dual(best_lev0, best_lev1, nb_strengths,
|
||||
mse, sb_count, fast);
|
||||
else
|
||||
|
|
@ -500,14 +491,14 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
best_gi = 0;
|
||||
for (gi = 0; gi < cm->nb_cdef_strengths; gi++) {
|
||||
uint64_t curr = mse[0][i][cm->cdef_strengths[gi]];
|
||||
if (nplanes >= 3) curr += mse[1][i][cm->cdef_uv_strengths[gi]];
|
||||
if (num_planes >= 3) curr += mse[1][i][cm->cdef_uv_strengths[gi]];
|
||||
if (curr < best_mse) {
|
||||
best_gi = gi;
|
||||
best_mse = curr;
|
||||
}
|
||||
}
|
||||
selected_strength[i] = best_gi;
|
||||
cm->mi_grid_visible[sb_index[i]]->mbmi.cdef_strength = best_gi;
|
||||
cm->mi_grid_visible[sb_index[i]]->cdef_strength = best_gi;
|
||||
}
|
||||
|
||||
if (fast) {
|
||||
|
|
@ -526,7 +517,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
|
|||
cm->cdef_sec_damping = sec_damping;
|
||||
aom_free(mse[0]);
|
||||
aom_free(mse[1]);
|
||||
for (pli = 0; pli < nplanes; pli++) {
|
||||
for (pli = 0; pli < num_planes; pli++) {
|
||||
aom_free(src[pli]);
|
||||
aom_free(ref_coeff[pli]);
|
||||
}
|
||||
|
|
|
|||
384
third_party/aom/av1/encoder/picklpf.c
vendored
384
third_party/aom/av1/encoder/picklpf.c
vendored
|
|
@ -12,7 +12,7 @@
|
|||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "./aom_scale_rtcd.h"
|
||||
#include "config/aom_scale_rtcd.h"
|
||||
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_dsp/psnr.h"
|
||||
|
|
@ -27,74 +27,6 @@
|
|||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/picklpf.h"
|
||||
|
||||
#if CONFIG_LPF_SB
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
static int compute_sb_y_sse_highbd(const YV12_BUFFER_CONFIG *src,
|
||||
const YV12_BUFFER_CONFIG *frame,
|
||||
AV1_COMMON *const cm, int mi_row,
|
||||
int mi_col) {
|
||||
int sse = 0;
|
||||
const int mi_row_start = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET);
|
||||
const int mi_col_start = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
|
||||
const int mi_row_range = mi_row - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
|
||||
const int mi_col_range = mi_col - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
|
||||
const int mi_row_end = AOMMIN(mi_row_range, cm->mi_rows);
|
||||
const int mi_col_end = AOMMIN(mi_col_range, cm->mi_cols);
|
||||
|
||||
const int row = mi_row_start * MI_SIZE;
|
||||
const int col = mi_col_start * MI_SIZE;
|
||||
const uint16_t *src_y =
|
||||
CONVERT_TO_SHORTPTR(src->y_buffer) + row * src->y_stride + col;
|
||||
const uint16_t *frame_y =
|
||||
CONVERT_TO_SHORTPTR(frame->y_buffer) + row * frame->y_stride + col;
|
||||
const int row_end = (mi_row_end - mi_row_start) * MI_SIZE;
|
||||
const int col_end = (mi_col_end - mi_col_start) * MI_SIZE;
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < row_end; ++y) {
|
||||
for (x = 0; x < col_end; ++x) {
|
||||
const int diff = src_y[x] - frame_y[x];
|
||||
sse += diff * diff;
|
||||
}
|
||||
src_y += src->y_stride;
|
||||
frame_y += frame->y_stride;
|
||||
}
|
||||
return sse;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int compute_sb_y_sse(const YV12_BUFFER_CONFIG *src,
|
||||
const YV12_BUFFER_CONFIG *frame,
|
||||
AV1_COMMON *const cm, int mi_row, int mi_col) {
|
||||
int sse = 0;
|
||||
const int mi_row_start = AOMMAX(0, mi_row - FILT_BOUNDARY_MI_OFFSET);
|
||||
const int mi_col_start = AOMMAX(0, mi_col - FILT_BOUNDARY_MI_OFFSET);
|
||||
const int mi_row_range = mi_row - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
|
||||
const int mi_col_range = mi_col - FILT_BOUNDARY_MI_OFFSET + MAX_MIB_SIZE;
|
||||
const int mi_row_end = AOMMIN(mi_row_range, cm->mi_rows);
|
||||
const int mi_col_end = AOMMIN(mi_col_range, cm->mi_cols);
|
||||
|
||||
const int row = mi_row_start * MI_SIZE;
|
||||
const int col = mi_col_start * MI_SIZE;
|
||||
const uint8_t *src_y = src->y_buffer + row * src->y_stride + col;
|
||||
const uint8_t *frame_y = frame->y_buffer + row * frame->y_stride + col;
|
||||
const int row_end = (mi_row_end - mi_row_start) * MI_SIZE;
|
||||
const int col_end = (mi_col_end - mi_col_start) * MI_SIZE;
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < row_end; ++y) {
|
||||
for (x = 0; x < col_end; ++x) {
|
||||
const int diff = src_y[x] - frame_y[x];
|
||||
sse += diff * diff;
|
||||
}
|
||||
src_y += src->y_stride;
|
||||
frame_y += frame->y_stride;
|
||||
}
|
||||
return sse;
|
||||
}
|
||||
#endif // CONFIG_LPF_SB
|
||||
|
||||
#if !CONFIG_LPF_SB
|
||||
static void yv12_copy_plane(const YV12_BUFFER_CONFIG *src_bc,
|
||||
YV12_BUFFER_CONFIG *dst_bc, int plane) {
|
||||
switch (plane) {
|
||||
|
|
@ -104,7 +36,6 @@ static void yv12_copy_plane(const YV12_BUFFER_CONFIG *src_bc,
|
|||
default: assert(plane >= 0 && plane <= 2); break;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_LPF_SB
|
||||
|
||||
int av1_get_max_filter_level(const AV1_COMP *cpi) {
|
||||
if (cpi->oxcf.pass == 2) {
|
||||
|
|
@ -115,195 +46,58 @@ int av1_get_max_filter_level(const AV1_COMP *cpi) {
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_LPF_SB
|
||||
// TODO(chengchen): reduce memory usage by copy superblock instead of frame
|
||||
static int try_filter_superblock(const YV12_BUFFER_CONFIG *sd,
|
||||
AV1_COMP *const cpi, int filt_level,
|
||||
int partial_frame, int mi_row, int mi_col) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
int filt_err;
|
||||
|
||||
#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION || CONFIG_CB4X4
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level, 1,
|
||||
partial_frame, mi_row, mi_col);
|
||||
#else
|
||||
if (cpi->num_workers > 1)
|
||||
av1_loop_filter_frame_mt(cm->frame_to_show, cm, cpi->td.mb.e_mbd.plane,
|
||||
filt_level, 1, partial_frame, cpi->workers,
|
||||
cpi->num_workers, &cpi->lf_row_sync);
|
||||
else
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level,
|
||||
1, partial_frame);
|
||||
#endif
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (cm->use_highbitdepth) {
|
||||
filt_err =
|
||||
compute_sb_y_sse_highbd(sd, cm->frame_to_show, cm, mi_row, mi_col);
|
||||
} else {
|
||||
filt_err = compute_sb_y_sse(sd, cm->frame_to_show, cm, mi_row, mi_col);
|
||||
}
|
||||
#else
|
||||
filt_err = compute_sb_y_sse(sd, cm->frame_to_show, cm, mi_row, mi_col);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
// TODO(chengchen): Copy the superblock only
|
||||
// Re-instate the unfiltered frame
|
||||
aom_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
|
||||
|
||||
return filt_err;
|
||||
}
|
||||
|
||||
static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
||||
int partial_frame, double *best_cost_ret,
|
||||
int mi_row, int mi_col, int last_lvl) {
|
||||
assert(partial_frame == 1);
|
||||
assert(last_lvl >= 0);
|
||||
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCK *x = &cpi->td.mb;
|
||||
|
||||
int min_filter_level = AOMMAX(0, last_lvl - MAX_LPF_OFFSET);
|
||||
int max_filter_level =
|
||||
AOMMIN(av1_get_max_filter_level(cpi), last_lvl + MAX_LPF_OFFSET);
|
||||
|
||||
// search a larger range for the start superblock
|
||||
if (mi_row == 0 && mi_col == 0) {
|
||||
min_filter_level = 0;
|
||||
max_filter_level = av1_get_max_filter_level(cpi);
|
||||
}
|
||||
|
||||
// TODO(chengchen): Copy for superblock only
|
||||
// Make a copy of the unfiltered / processed recon buffer
|
||||
aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
|
||||
|
||||
int estimate_err =
|
||||
try_filter_superblock(sd, cpi, last_lvl, partial_frame, mi_row, mi_col);
|
||||
|
||||
int best_err = estimate_err;
|
||||
int filt_best = last_lvl;
|
||||
|
||||
int i;
|
||||
for (i = min_filter_level; i <= max_filter_level; i += LPF_STEP) {
|
||||
if (i == last_lvl) continue;
|
||||
|
||||
int filt_err =
|
||||
try_filter_superblock(sd, cpi, i, partial_frame, mi_row, mi_col);
|
||||
|
||||
if (filt_err < best_err) {
|
||||
best_err = filt_err;
|
||||
filt_best = i;
|
||||
}
|
||||
}
|
||||
|
||||
// If previous sb filter level has similar filtering performance as current
|
||||
// best filter level, use previous level such that we can only send one bit
|
||||
// to indicate current filter level is the same as the previous.
|
||||
int threshold = 400;
|
||||
|
||||
// ratio = the filtering area / a superblock size
|
||||
int ratio = 1;
|
||||
if (mi_row + MAX_MIB_SIZE > cm->mi_rows) {
|
||||
ratio *= (cm->mi_rows - mi_row);
|
||||
} else {
|
||||
if (mi_row == 0) {
|
||||
ratio *= (MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET);
|
||||
} else {
|
||||
ratio *= MAX_MIB_SIZE;
|
||||
}
|
||||
}
|
||||
if (mi_col + MAX_MIB_SIZE > cm->mi_cols) {
|
||||
ratio *= (cm->mi_cols - mi_col);
|
||||
} else {
|
||||
if (mi_col == 0) {
|
||||
ratio *= (MAX_MIB_SIZE - FILT_BOUNDARY_MI_OFFSET);
|
||||
} else {
|
||||
ratio *= MAX_MIB_SIZE;
|
||||
}
|
||||
}
|
||||
threshold = threshold * ratio / (MAX_MIB_SIZE * MAX_MIB_SIZE);
|
||||
|
||||
const int diff = abs(estimate_err - best_err);
|
||||
|
||||
const int percent_thresh = (int)((double)estimate_err * 0.01);
|
||||
threshold = AOMMAX(threshold, percent_thresh);
|
||||
if (diff < threshold) {
|
||||
best_err = estimate_err;
|
||||
filt_best = last_lvl;
|
||||
}
|
||||
|
||||
// Compute rdcost to determine whether to reuse previous filter lvl
|
||||
if (filt_best != last_lvl) {
|
||||
}
|
||||
|
||||
if (best_cost_ret) *best_cost_ret = RDCOST_DBL(x->rdmult, 0, best_err);
|
||||
return filt_best;
|
||||
}
|
||||
|
||||
#else // CONFIG_LPF_SB
|
||||
static int64_t try_filter_frame(const YV12_BUFFER_CONFIG *sd,
|
||||
AV1_COMP *const cpi, int filt_level,
|
||||
int partial_frame
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
,
|
||||
int plane, int dir
|
||||
#endif
|
||||
) {
|
||||
int partial_frame, int plane, int dir) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
int64_t filt_err;
|
||||
|
||||
#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION || CONFIG_CB4X4
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
assert(plane >= 0 && plane <= 2);
|
||||
int filter_level[2] = { filt_level, filt_level };
|
||||
if (plane == 0 && dir == 0) filter_level[1] = cm->lf.filter_level[1];
|
||||
if (plane == 0 && dir == 1) filter_level[0] = cm->lf.filter_level[0];
|
||||
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd,
|
||||
filter_level[0], filter_level[1], plane, partial_frame);
|
||||
#else
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level, 1,
|
||||
partial_frame);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
// set base filters for use of get_filter_level when in DELTA_Q_LF mode
|
||||
switch (plane) {
|
||||
case 0:
|
||||
cm->lf.filter_level[0] = filter_level[0];
|
||||
cm->lf.filter_level[1] = filter_level[1];
|
||||
break;
|
||||
case 1: cm->lf.filter_level_u = filter_level[0]; break;
|
||||
case 2: cm->lf.filter_level_v = filter_level[0]; break;
|
||||
}
|
||||
|
||||
// TODO(any): please enable multi-thread and remove the flag when loop
|
||||
// filter mask is compatible with multi-thread.
|
||||
#if LOOP_FILTER_BITMASK
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, plane,
|
||||
plane + 1, partial_frame);
|
||||
#else
|
||||
if (cpi->num_workers > 1)
|
||||
av1_loop_filter_frame_mt(cm->frame_to_show, cm, cpi->td.mb.e_mbd.plane,
|
||||
filt_level, 1, partial_frame, cpi->workers,
|
||||
av1_loop_filter_frame_mt(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, plane,
|
||||
plane + 1, partial_frame, cpi->workers,
|
||||
cpi->num_workers, &cpi->lf_row_sync);
|
||||
else
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level,
|
||||
1, partial_frame);
|
||||
av1_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, plane,
|
||||
plane + 1, partial_frame);
|
||||
#endif
|
||||
|
||||
int highbd = 0;
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
highbd = cm->use_highbitdepth;
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
filt_err = aom_get_sse_plane(sd, cm->frame_to_show, plane, highbd);
|
||||
|
||||
// Re-instate the unfiltered frame
|
||||
yv12_copy_plane(&cpi->last_frame_uf, cm->frame_to_show, plane);
|
||||
#else
|
||||
filt_err = aom_get_sse_plane(sd, cm->frame_to_show, 0, highbd);
|
||||
|
||||
// Re-instate the unfiltered frame
|
||||
yv12_copy_plane(&cpi->last_frame_uf, cm->frame_to_show, 0);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
|
||||
return filt_err;
|
||||
}
|
||||
|
||||
static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
||||
int partial_frame, double *best_cost_ret
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
,
|
||||
int plane, int dir
|
||||
#endif
|
||||
) {
|
||||
int partial_frame,
|
||||
const int *last_frame_filter_level,
|
||||
double *best_cost_ret, int plane, int dir) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const struct loopfilter *const lf = &cm->lf;
|
||||
const int min_filter_level = 0;
|
||||
const int max_filter_level = av1_get_max_filter_level(cpi);
|
||||
int filt_direction = 0;
|
||||
|
|
@ -311,39 +105,24 @@ static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
int filt_best;
|
||||
MACROBLOCK *x = &cpi->td.mb;
|
||||
|
||||
// Start the search at the previous frame filter level unless it is now out of
|
||||
// range.
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
// Start the search at the previous frame filter level unless it is now out of
|
||||
// range.
|
||||
int lvl;
|
||||
switch (plane) {
|
||||
case 0: lvl = (dir == 1) ? lf->filter_level[1] : lf->filter_level[0]; break;
|
||||
case 1: lvl = lf->filter_level_u; break;
|
||||
case 2: lvl = lf->filter_level_v; break;
|
||||
case 0: lvl = last_frame_filter_level[dir]; break;
|
||||
case 1: lvl = last_frame_filter_level[2]; break;
|
||||
case 2: lvl = last_frame_filter_level[3]; break;
|
||||
default: assert(plane >= 0 && plane <= 2); return 0;
|
||||
}
|
||||
int filt_mid = clamp(lvl, min_filter_level, max_filter_level);
|
||||
#else
|
||||
int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
|
||||
// Sum squared error at each filter level
|
||||
int64_t ss_err[MAX_LOOP_FILTER + 1];
|
||||
|
||||
// Set each entry to -1
|
||||
memset(ss_err, 0xFF, sizeof(ss_err));
|
||||
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
yv12_copy_plane(cm->frame_to_show, &cpi->last_frame_uf, plane);
|
||||
#else
|
||||
// Make a copy of the unfiltered / processed recon buffer
|
||||
aom_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame, plane, dir);
|
||||
#else
|
||||
best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
filt_best = filt_mid;
|
||||
ss_err[filt_mid] = best_err;
|
||||
|
||||
|
|
@ -363,12 +142,8 @@ static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
if (filt_direction <= 0 && filt_low != filt_mid) {
|
||||
// Get Low filter error score
|
||||
if (ss_err[filt_low] < 0) {
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
ss_err[filt_low] =
|
||||
try_filter_frame(sd, cpi, filt_low, partial_frame, plane, dir);
|
||||
#else
|
||||
ss_err[filt_low] = try_filter_frame(sd, cpi, filt_low, partial_frame);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
}
|
||||
// If value is close to the best so far then bias towards a lower loop
|
||||
// filter value.
|
||||
|
|
@ -384,12 +159,8 @@ static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
// Now look at filt_high
|
||||
if (filt_direction >= 0 && filt_high != filt_mid) {
|
||||
if (ss_err[filt_high] < 0) {
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
ss_err[filt_high] =
|
||||
try_filter_frame(sd, cpi, filt_high, partial_frame, plane, dir);
|
||||
#else
|
||||
ss_err[filt_high] = try_filter_frame(sd, cpi, filt_high, partial_frame);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
}
|
||||
// If value is significantly better than previous best, bias added against
|
||||
// raising filter value
|
||||
|
|
@ -415,33 +186,36 @@ static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
if (best_cost_ret) *best_cost_ret = RDCOST_DBL(x->rdmult, 0, best_err);
|
||||
return filt_best;
|
||||
}
|
||||
#endif // CONFIG_LPF_SB
|
||||
|
||||
void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
||||
LPF_PICK_METHOD method) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
struct loopfilter *const lf = &cm->lf;
|
||||
(void)sd;
|
||||
|
||||
lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0 : cpi->oxcf.sharpness;
|
||||
lf->sharpness_level = 0;
|
||||
|
||||
if (method == LPF_PICK_MINIMAL_LPF) {
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
lf->filter_level[0] = 0;
|
||||
lf->filter_level[1] = 0;
|
||||
#else
|
||||
lf->filter_level = 0;
|
||||
#endif
|
||||
} else if (method >= LPF_PICK_FROM_Q) {
|
||||
const int min_filter_level = 0;
|
||||
const int max_filter_level = av1_get_max_filter_level(cpi);
|
||||
const int q = av1_ac_quant(cm->base_qindex, 0, cm->bit_depth);
|
||||
// These values were determined by linear fitting the result of the
|
||||
// searched level, filt_guess = q * 0.316206 + 3.87252
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
const int q = av1_ac_quant_Q3(cm->base_qindex, 0, cm->bit_depth);
|
||||
// These values were determined by linear fitting the result of the
|
||||
// searched level for 8 bit depth:
|
||||
// Keyframes: filt_guess = q * 0.06699 - 1.60817
|
||||
// Other frames: filt_guess = q * 0.02295 + 2.48225
|
||||
//
|
||||
// And high bit depth separately:
|
||||
// filt_guess = q * 0.316206 + 3.87252
|
||||
int filt_guess;
|
||||
switch (cm->bit_depth) {
|
||||
case AOM_BITS_8:
|
||||
filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18);
|
||||
filt_guess = (cm->frame_type == KEY_FRAME)
|
||||
? ROUND_POWER_OF_TWO(q * 17563 - 421574, 18)
|
||||
: ROUND_POWER_OF_TWO(q * 6017 + 650707, 18);
|
||||
break;
|
||||
case AOM_BITS_10:
|
||||
filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 4060632, 20);
|
||||
|
|
@ -455,58 +229,36 @@ void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
"or AOM_BITS_12");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
int filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
if (cm->frame_type == KEY_FRAME) filt_guess -= 4;
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
if (cm->bit_depth != AOM_BITS_8 && cm->frame_type == KEY_FRAME)
|
||||
filt_guess -= 4;
|
||||
// TODO(chengchen): retrain the model for Y, U, V filter levels
|
||||
lf->filter_level[0] = clamp(filt_guess, min_filter_level, max_filter_level);
|
||||
lf->filter_level[1] = clamp(filt_guess, min_filter_level, max_filter_level);
|
||||
#else
|
||||
lf->filter_level = clamp(filt_guess, min_filter_level, max_filter_level);
|
||||
#endif
|
||||
lf->filter_level_u = clamp(filt_guess, min_filter_level, max_filter_level);
|
||||
lf->filter_level_v = clamp(filt_guess, min_filter_level, max_filter_level);
|
||||
} else {
|
||||
#if CONFIG_LPF_SB
|
||||
int mi_row, mi_col;
|
||||
// TODO(chengchen): init last_lvl using previous frame's info?
|
||||
int last_lvl = 0;
|
||||
// TODO(chengchen): if the frame size makes the last superblock very small,
|
||||
// consider merge it to the previous superblock to save bits.
|
||||
// Example, if frame size 1080x720, then in the last row of superblock,
|
||||
// there're (FILT_BOUNDAR_OFFSET + 16) pixels.
|
||||
for (mi_row = 0; mi_row < cm->mi_rows; mi_row += MAX_MIB_SIZE) {
|
||||
for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MAX_MIB_SIZE) {
|
||||
int lvl =
|
||||
search_filter_level(sd, cpi, 1, NULL, mi_row, mi_col, last_lvl);
|
||||
const int last_frame_filter_level[4] = { lf->filter_level[0],
|
||||
lf->filter_level[1],
|
||||
lf->filter_level_u,
|
||||
lf->filter_level_v };
|
||||
|
||||
av1_loop_filter_sb_level_init(cm, mi_row, mi_col, lvl);
|
||||
lf->filter_level[0] = lf->filter_level[1] =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
|
||||
last_frame_filter_level, NULL, 0, 2);
|
||||
lf->filter_level[0] =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
|
||||
last_frame_filter_level, NULL, 0, 0);
|
||||
lf->filter_level[1] =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
|
||||
last_frame_filter_level, NULL, 0, 1);
|
||||
|
||||
// For the superblock at row start, its previous filter level should be
|
||||
// the one above it, not the one at the end of last row
|
||||
if (mi_col + MAX_MIB_SIZE >= cm->mi_cols) {
|
||||
last_lvl = cm->mi_grid_visible[mi_row * cm->mi_stride]->mbmi.filt_lvl;
|
||||
} else {
|
||||
last_lvl = lvl;
|
||||
}
|
||||
}
|
||||
if (num_planes > 1) {
|
||||
lf->filter_level_u =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
|
||||
last_frame_filter_level, NULL, 1, 0);
|
||||
lf->filter_level_v =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
|
||||
last_frame_filter_level, NULL, 2, 0);
|
||||
}
|
||||
#else // CONFIG_LPF_SB
|
||||
#if CONFIG_LOOPFILTER_LEVEL
|
||||
lf->filter_level[0] = lf->filter_level[1] = search_filter_level(
|
||||
sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 0, 2);
|
||||
lf->filter_level[0] = search_filter_level(
|
||||
sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 0, 0);
|
||||
lf->filter_level[1] = search_filter_level(
|
||||
sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 0, 1);
|
||||
|
||||
lf->filter_level_u = search_filter_level(
|
||||
sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 1, 0);
|
||||
lf->filter_level_v = search_filter_level(
|
||||
sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 2, 0);
|
||||
#else
|
||||
lf->filter_level =
|
||||
search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL);
|
||||
#endif // CONFIG_LOOPFILTER_LEVEL
|
||||
#endif // CONFIG_LPF_SB
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1483
third_party/aom/av1/encoder/pickrst.c
vendored
1483
third_party/aom/av1/encoder/pickrst.c
vendored
File diff suppressed because it is too large
Load diff
3
third_party/aom/av1/encoder/pickrst.h
vendored
3
third_party/aom/av1/encoder/pickrst.h
vendored
|
|
@ -20,8 +20,7 @@ extern "C" {
|
|||
struct yv12_buffer_config;
|
||||
struct AV1_COMP;
|
||||
|
||||
void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
||||
LPF_PICK_METHOD method);
|
||||
void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
229
third_party/aom/av1/encoder/pustats.h
vendored
Normal file
229
third_party/aom/av1/encoder/pustats.h
vendored
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_PUSTATS_H_
|
||||
#define AV1_ENCODER_PUSTATS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "av1/encoder/ml.h"
|
||||
|
||||
#define NUM_FEATURES 20
|
||||
#define NUM_HIDDEN_LAYERS 2
|
||||
#define HIDDEN_LAYERS_0_NODES 10
|
||||
#define HIDDEN_LAYERS_1_NODES 10
|
||||
#define LOGITS_NODES 1
|
||||
|
||||
static const float
|
||||
av1_pustats_rate_hiddenlayer_0_kernel[NUM_FEATURES *
|
||||
HIDDEN_LAYERS_0_NODES] = {
|
||||
13.8498f, 19.6630f, 13.3036f, 5.2448f, -18.0270f, 21.6671f,
|
||||
-0.2135f, -0.0060f, 0.1211f, -0.3549f, -0.3550f, 0.0190f,
|
||||
0.0167f, -0.1192f, 0.2003f, 8.6663f, 32.0264f, 9.9558f,
|
||||
9.0935f, -110.4994f, 51.8056f, 64.8041f, 58.5392f, 53.0189f,
|
||||
-61.6300f, 4.7540f, -0.0140f, 0.0185f, -15.8050f, 0.0790f,
|
||||
0.0707f, 0.0784f, 0.0766f, -0.3030f, 0.0392f, 49.3312f,
|
||||
63.3326f, 61.4025f, 54.2723f, -62.2769f, -147.1736f, -84.9432f,
|
||||
-82.5422f, -70.4857f, 46.7622f, -1.0285f, -0.4809f, 0.0068f,
|
||||
1.0888f, -0.0515f, -0.0384f, -0.0232f, -0.0396f, 0.2429f,
|
||||
0.2040f, -144.4016f, -88.0868f, -80.3134f, -70.6685f, 66.8528f,
|
||||
-53.8097f, -45.4011f, -52.8680f, -58.7226f, 99.7830f, 2.3728f,
|
||||
0.0229f, 0.0002f, -0.3288f, -0.0563f, -0.0550f, -0.0552f,
|
||||
-0.0563f, 0.2214f, 0.0139f, -60.8965f, -45.5251f, -50.4188f,
|
||||
-51.5623f, 85.7369f, 77.3415f, 47.4930f, 53.8120f, 58.2311f,
|
||||
-45.9650f, -2.4938f, 0.1639f, -0.5270f, -75.4622f, -0.0026f,
|
||||
0.0031f, 0.0047f, 0.0015f, 0.0092f, 0.0654f, 75.6402f,
|
||||
54.7447f, 54.8156f, 52.6834f, -9.1246f, -34.0108f, -35.6423f,
|
||||
-34.2911f, -38.5444f, 72.1123f, 10.9750f, -0.1595f, 0.1983f,
|
||||
22.5724f, -0.0556f, -0.0618f, -0.0571f, -0.0608f, 0.2439f,
|
||||
-0.0805f, -32.5107f, -28.9688f, -33.7284f, -48.1365f, 61.5297f,
|
||||
39.2492f, -35.1928f, -11.5000f, 7.7038f, -94.2469f, 13.5586f,
|
||||
0.7541f, 0.0105f, 4.4041f, 0.1799f, 0.1339f, 0.1567f,
|
||||
-0.6668f, -0.7384f, 0.2185f, 17.1700f, -26.4601f, -1.8970f,
|
||||
38.9635f, -30.1916f, 31.8139f, 14.6157f, 10.0565f, 3.3340f,
|
||||
-40.6985f, -2.1186f, 0.0116f, 0.0962f, 0.7115f, -1.4071f,
|
||||
-1.3701f, -1.4728f, -1.3404f, -1.7286f, 5.5632f, 28.4998f,
|
||||
5.4087f, 16.2668f, 11.8693f, -39.4153f, 106.3281f, 38.3075f,
|
||||
39.4933f, 47.3805f, -15.0514f, -21.2421f, -0.2358f, -0.0024f,
|
||||
0.3505f, -0.0429f, -0.0377f, -0.0322f, -0.0344f, 0.2020f,
|
||||
0.1417f, 99.6711f, 35.3896f, 43.1117f, 59.8879f, -17.8250f,
|
||||
-16.6976f, 18.5100f, 6.3383f, 25.3020f, -55.8824f, 25.1027f,
|
||||
-0.9926f, -0.0738f, -1.4892f, 0.0269f, -0.0051f, -5.8168f,
|
||||
-0.0579f, -0.1500f, 0.7224f, 8.3066f, -3.8805f, -12.1482f,
|
||||
14.3492f, -20.8118f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_rate_hiddenlayer_0_bias[HIDDEN_LAYERS_0_NODES] =
|
||||
{
|
||||
17.6566f, 62.2217f, -107.2644f, -56.2255f, 68.2252f,
|
||||
-37.5662f, 9.587f, 18.5206f, 69.6873f, 4.3903f,
|
||||
};
|
||||
|
||||
static const float
|
||||
av1_pustats_rate_hiddenlayer_1_kernel[HIDDEN_LAYERS_0_NODES *
|
||||
HIDDEN_LAYERS_1_NODES] = {
|
||||
-0.0494f, 0.3505f, -0.0461f, -1.3451f, 0.0198f, -0.0746f, -0.2217f,
|
||||
-0.9525f, 0.0633f, -0.0737f, -0.3568f, 1.8569f, -0.0189f, -1.8269f,
|
||||
0.6281f, -1.3266f, -0.9202f, 2.8978f, -0.6437f, -0.8709f, -1.5066f,
|
||||
-1.0582f, -1.9509f, -0.0417f, -0.1315f, -0.3368f, 0.0014f, -0.5734f,
|
||||
-1.4640f, -1.6042f, 3.3911f, -1.6815f, -1.9026f, -4.8702f, -0.1012f,
|
||||
-1.4517f, -3.2156f, 0.8448f, 0.2331f, -0.1593f, 2.6627f, -0.8451f,
|
||||
-1.7382f, 0.9303f, 2.3003f, -0.0659f, 0.5772f, 0.4253f, 0.2083f,
|
||||
0.3649f, -0.9198f, -0.2183f, -0.5381f, -1.0831f, 2.0359f, 0.0040f,
|
||||
-0.0871f, -0.1715f, 2.2453f, 0.5099f, -0.5900f, -0.6313f, -1.3028f,
|
||||
-1.7257f, 1.4130f, -0.7189f, -0.4336f, 1.9266f, 1.7495f, -0.3321f,
|
||||
0.2827f, 0.4015f, -0.5044f, -1.0420f, -0.1258f, -0.0342f, -0.1190f,
|
||||
-3.1263f, 0.7485f, -0.3161f, -0.2224f, 2.5533f, -0.2121f, -1.3389f,
|
||||
0.5556f, -0.9407f, -0.7456f, 1.4137f, -0.0353f, -0.0521f, 2.4382f,
|
||||
0.1493f, -11.5631f, -1.6178f, 3.5538f, -3.6538f, -0.5972f, -3.0038f,
|
||||
-2.1640f, 0.5754f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_rate_hiddenlayer_1_bias[HIDDEN_LAYERS_1_NODES] =
|
||||
{
|
||||
69.1995f, 41.7369f, -1.4885f, -35.785f, 26.1678f,
|
||||
58.4472f, 36.2223f, 66.327f, 50.8867f, 2.8306f,
|
||||
};
|
||||
|
||||
static const float
|
||||
av1_pustats_rate_logits_kernel[HIDDEN_LAYERS_1_NODES * LOGITS_NODES] = {
|
||||
1.811f, 0.9009f, 0.0694f, -0.9985f, -0.039f,
|
||||
0.2076f, 0.5643f, 0.5408f, 0.6071f, 0.277f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_rate_logits_bias[LOGITS_NODES] = {
|
||||
39.5529f,
|
||||
};
|
||||
|
||||
static const NN_CONFIG av1_pustats_rate_nnconfig = {
|
||||
NUM_FEATURES, // num_inputs
|
||||
LOGITS_NODES, // num_outputs
|
||||
NUM_HIDDEN_LAYERS, // num_hidden_layers
|
||||
{ HIDDEN_LAYERS_0_NODES, HIDDEN_LAYERS_1_NODES }, // num_hidden_nodes
|
||||
{
|
||||
av1_pustats_rate_hiddenlayer_0_kernel,
|
||||
av1_pustats_rate_hiddenlayer_1_kernel,
|
||||
av1_pustats_rate_logits_kernel,
|
||||
},
|
||||
{
|
||||
av1_pustats_rate_hiddenlayer_0_bias,
|
||||
av1_pustats_rate_hiddenlayer_1_bias,
|
||||
av1_pustats_rate_logits_bias,
|
||||
},
|
||||
};
|
||||
|
||||
static const float
|
||||
av1_pustats_dist_hiddenlayer_0_kernel[NUM_FEATURES *
|
||||
HIDDEN_LAYERS_0_NODES] = {
|
||||
-39.0787f, -212.9998f, -174.2088f, -264.1454f, 292.7151f, -60.8750f,
|
||||
-5.9915f, 0.0712f, -60.2312f, -0.2020f, -0.2135f, -0.1663f,
|
||||
-0.0711f, 0.2267f, 0.9152f, -36.1294f, -159.9320f, -222.9809f,
|
||||
-270.2556f, 300.7162f, 159.9224f, -172.5735f, -7.6852f, 54.3985f,
|
||||
110.6721f, 19.2907f, -15.1039f, -0.0457f, 0.3289f, 0.4529f,
|
||||
-8.2222f, 1.3213f, -0.8378f, -0.2605f, 3.9600f, 17.3407f,
|
||||
113.1116f, 34.6326f, 11.6688f, 109.3541f, 240.8123f, 45.0615f,
|
||||
80.7443f, 39.2500f, -21.0931f, -27.1989f, -0.4264f, -0.1345f,
|
||||
1.6269f, -0.0716f, 0.0989f, -0.1382f, 0.0248f, 0.0913f,
|
||||
4.3903f, 244.1014f, 32.2567f, 58.6171f, 62.2273f, -2.8647f,
|
||||
-227.5659f, 16.0031f, -70.5256f, 23.8071f, 290.7356f, 13.6094f,
|
||||
-2.1842f, 0.0104f, -2.8760f, 0.3708f, 0.8501f, -3.2964f,
|
||||
-0.2088f, -0.4474f, 1.2248f, 40.5180f, -130.7891f, -188.1583f,
|
||||
-174.0906f, 205.9622f, 0.3425f, 0.2531f, 0.2822f, 0.0488f,
|
||||
0.1416f, -0.0433f, -0.1195f, -0.0413f, -0.0708f, -0.0787f,
|
||||
-0.0889f, -0.4022f, -0.5055f, -0.4715f, 0.2315f, 0.1021f,
|
||||
-0.3676f, -0.3499f, -0.0715f, 0.1913f, 205.7521f, 125.2265f,
|
||||
92.0640f, 77.5566f, -164.4280f, -19.3715f, -0.1346f, -0.4060f,
|
||||
0.5042f, -0.2395f, -0.1329f, -0.1397f, 0.2175f, 0.2895f,
|
||||
5.5019f, 198.9799f, 114.0018f, 94.9015f, 86.8434f, -183.4237f,
|
||||
121.5626f, 94.8945f, 65.0803f, 93.6487f, -346.5279f, -47.6168f,
|
||||
0.0633f, 0.0135f, -0.0692f, -0.1015f, -0.1146f, -0.1341f,
|
||||
-0.1175f, 0.4186f, 0.1505f, 130.7402f, 107.8443f, 62.8497f,
|
||||
65.3501f, -312.7407f, 282.8321f, 98.1531f, 75.6648f, 25.8733f,
|
||||
-176.9298f, -37.2695f, -0.3760f, 0.0017f, 0.1030f, -0.1483f,
|
||||
0.0787f, -0.0962f, 0.4109f, -0.2292f, 9.1681f, 274.3607f,
|
||||
60.9538f, 75.9405f, 68.3776f, -167.3098f, -335.1045f, -69.2583f,
|
||||
-76.3441f, -16.5793f, 218.5244f, 28.2405f, 0.9169f, -0.0026f,
|
||||
-0.8077f, -1.5756f, -0.0804f, 0.1404f, 1.2656f, 0.0272f,
|
||||
-0.2529f, -340.8659f, -112.7778f, -58.3890f, -4.1224f, 108.1709f,
|
||||
-180.7382f, -93.7114f, -77.8686f, -131.8134f, 353.3893f, 4.8233f,
|
||||
0.0205f, 0.0000f, -1.1654f, -0.0161f, -0.0255f, -0.0358f,
|
||||
-0.0412f, 0.1103f, 0.1041f, -188.9934f, -110.1792f, -88.6301f,
|
||||
-93.7226f, 336.9746f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_dist_hiddenlayer_0_bias[HIDDEN_LAYERS_0_NODES] =
|
||||
{ -175.6918f, 43.4519f, 154.196f, -81.1015f, -0.0758f,
|
||||
136.5695f, 110.8713f, 142.029f, -153.0901f, -145.2688f };
|
||||
|
||||
static const float
|
||||
av1_pustats_dist_hiddenlayer_1_kernel[HIDDEN_LAYERS_0_NODES *
|
||||
HIDDEN_LAYERS_1_NODES] = {
|
||||
-0.1727f, -0.2859f, -0.3757f, -0.4260f, -0.5441f, -0.0666f, -0.3792f,
|
||||
-0.1335f, -0.1521f, -0.0821f, -3.1590f, 0.2711f, 0.5889f, 0.0878f,
|
||||
0.4693f, 0.7773f, -9.2989f, 0.0414f, 0.4485f, 22.8958f, -3.7024f,
|
||||
-2.4672f, -43.2908f, 0.0956f, 0.4431f, 2.3429f, 1.7183f, 0.3985f,
|
||||
-0.2275f, -3.1583f, -0.3485f, 0.3280f, 0.3763f, 0.2069f, 0.4231f,
|
||||
0.7366f, -6.9527f, 0.0713f, 0.1359f, 16.6500f, -1.7655f, -0.1651f,
|
||||
0.1280f, -0.2678f, -0.2120f, 1.6243f, 1.8773f, -0.7543f, -0.3292f,
|
||||
-0.7627f, -0.2001f, -0.1125f, -0.8100f, -0.1866f, 0.0567f, -0.4002f,
|
||||
3.2429f, 0.6427f, -0.3759f, -11.6518f, -2.2893f, 0.7708f, -1.8637f,
|
||||
1.7148f, 0.3124f, -0.7129f, -0.4927f, 0.1964f, -0.2570f, -25.0783f,
|
||||
2.5061f, 0.1457f, -1.1239f, 0.0570f, -0.2526f, -0.0669f, 0.6791f,
|
||||
1.1531f, -0.7246f, -0.3180f, -0.0015f, -0.0061f, -0.1626f, -0.0181f,
|
||||
0.1271f, -0.0140f, -0.6027f, 0.0736f, -0.0157f, 1.2420f, -6.4055f,
|
||||
0.2128f, -0.0386f, 0.3446f, 0.1840f, -0.7208f, -1.6979f, -0.0442f,
|
||||
0.3230f, -1.9745f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_dist_hiddenlayer_1_bias[HIDDEN_LAYERS_1_NODES] =
|
||||
{ 0.f, 70.3414f, 9.6036f, -118.1096f, 49.2507f,
|
||||
95.1849f, 81.8015f, 167.0967f, -337.7945f, 169.8344f };
|
||||
|
||||
static const float
|
||||
av1_pustats_dist_logits_kernel[HIDDEN_LAYERS_1_NODES * LOGITS_NODES] = {
|
||||
-0.3627f, 1.2272f, 0.2201f, -1.7406f, -0.6885f,
|
||||
0.8487f, -0.2761f, 0.7731f, -5.2096f, -0.7351f,
|
||||
};
|
||||
|
||||
static const float av1_pustats_dist_logits_bias[LOGITS_NODES] = {
|
||||
48.2331f,
|
||||
};
|
||||
|
||||
static const NN_CONFIG av1_pustats_dist_nnconfig = {
|
||||
NUM_FEATURES, // num_inputs
|
||||
LOGITS_NODES, // num_outputs
|
||||
NUM_HIDDEN_LAYERS, // num_hidden_layers
|
||||
{ HIDDEN_LAYERS_0_NODES, HIDDEN_LAYERS_1_NODES }, // num_hidden_nodes
|
||||
{
|
||||
av1_pustats_dist_hiddenlayer_0_kernel,
|
||||
av1_pustats_dist_hiddenlayer_1_kernel,
|
||||
av1_pustats_dist_logits_kernel,
|
||||
},
|
||||
{
|
||||
av1_pustats_dist_hiddenlayer_0_bias,
|
||||
av1_pustats_dist_hiddenlayer_1_bias,
|
||||
av1_pustats_dist_logits_bias,
|
||||
},
|
||||
};
|
||||
|
||||
#undef NUM_FEATURES
|
||||
#undef NUM_HIDDEN_LAYERS
|
||||
#undef HIDDEN_LAYERS_0_NODES
|
||||
#undef HIDDEN_LAYERS_1_NODES
|
||||
#undef LOGITS_NODES
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_PUSTATS_H_
|
||||
988
third_party/aom/av1/encoder/pvq_encoder.c
vendored
988
third_party/aom/av1/encoder/pvq_encoder.c
vendored
|
|
@ -1,988 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "aom_dsp/entcode.h"
|
||||
#include "aom_dsp/entenc.h"
|
||||
#include "av1/common/blockd.h"
|
||||
#include "av1/common/odintrin.h"
|
||||
#include "av1/common/partition.h"
|
||||
#include "av1/common/pvq_state.h"
|
||||
#include "av1/encoder/encodemb.h"
|
||||
#include "av1/encoder/pvq_encoder.h"
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
/*Shift to ensure that the upper bound (i.e. for the max blocksize) of the
|
||||
dot-product of the 1st band of chroma with the luma ref doesn't overflow.*/
|
||||
#define OD_CFL_FLIP_SHIFT (OD_LIMIT_BSIZE_MAX + 0)
|
||||
|
||||
void aom_write_symbol_pvq(aom_writer *w, int symb, aom_cdf_prob *cdf,
|
||||
int nsymbs) {
|
||||
if (cdf[0] == 0)
|
||||
aom_cdf_init_q15_1D(cdf, nsymbs, CDF_SIZE(nsymbs));
|
||||
aom_write_symbol(w, symb, cdf, nsymbs);
|
||||
}
|
||||
|
||||
static void aom_encode_pvq_codeword(aom_writer *w, od_pvq_codeword_ctx *adapt,
|
||||
const od_coeff *in, int n, int k) {
|
||||
int i;
|
||||
aom_encode_band_pvq_splits(w, adapt, in, n, k, 0);
|
||||
for (i = 0; i < n; i++) if (in[i]) aom_write_bit(w, in[i] < 0);
|
||||
}
|
||||
|
||||
/* Computes 1/sqrt(i) using a table for small values. */
|
||||
static double od_rsqrt_table(int i) {
|
||||
static double table[16] = {
|
||||
1.000000, 0.707107, 0.577350, 0.500000,
|
||||
0.447214, 0.408248, 0.377964, 0.353553,
|
||||
0.333333, 0.316228, 0.301511, 0.288675,
|
||||
0.277350, 0.267261, 0.258199, 0.250000};
|
||||
if (i <= 16) return table[i-1];
|
||||
else return 1./sqrt(i);
|
||||
}
|
||||
|
||||
/*Computes 1/sqrt(start+2*i+1) using a lookup table containing the results
|
||||
where 0 <= i < table_size.*/
|
||||
static double od_custom_rsqrt_dynamic_table(const double* table,
|
||||
const int table_size, const double start, const int i) {
|
||||
if (i < table_size) return table[i];
|
||||
else return od_rsqrt_table((int)(start + 2*i + 1));
|
||||
}
|
||||
|
||||
/*Fills tables used in od_custom_rsqrt_dynamic_table for a given start.*/
|
||||
static void od_fill_dynamic_rsqrt_table(double *table, const int table_size,
|
||||
const double start) {
|
||||
int i;
|
||||
for (i = 0; i < table_size; i++)
|
||||
table[i] = od_rsqrt_table((int)(start + 2*i + 1));
|
||||
}
|
||||
|
||||
/** Find the codepoint on the given PSphere closest to the desired
|
||||
* vector. Double-precision PVQ search just to make sure our tests
|
||||
* aren't limited by numerical accuracy.
|
||||
*
|
||||
* @param [in] xcoeff input vector to quantize (x in the math doc)
|
||||
* @param [in] n number of dimensions
|
||||
* @param [in] k number of pulses
|
||||
* @param [out] ypulse optimal codevector found (y in the math doc)
|
||||
* @param [out] g2 multiplier for the distortion (typically squared
|
||||
* gain units)
|
||||
* @param [in] pvq_norm_lambda enc->pvq_norm_lambda for quantized RDO
|
||||
* @param [in] prev_k number of pulses already in ypulse that we should
|
||||
* reuse for the search (or 0 for a new search)
|
||||
* @return cosine distance between x and y (between 0 and 1)
|
||||
*/
|
||||
double pvq_search_rdo_double_c(const od_val16 *xcoeff, int n, int k,
|
||||
od_coeff *ypulse, double g2, double pvq_norm_lambda, int prev_k) {
|
||||
int i, j;
|
||||
double xy;
|
||||
double yy;
|
||||
/* TODO - This blows our 8kB stack space budget and should be fixed when
|
||||
converting PVQ to fixed point. */
|
||||
double x[MAXN];
|
||||
double xx;
|
||||
double lambda;
|
||||
double norm_1;
|
||||
int rdo_pulses;
|
||||
double delta_rate;
|
||||
xx = xy = yy = 0;
|
||||
for (j = 0; j < n; j++) {
|
||||
x[j] = fabs((float)xcoeff[j]);
|
||||
xx += x[j]*x[j];
|
||||
}
|
||||
norm_1 = 1./sqrt(1e-30 + xx);
|
||||
lambda = pvq_norm_lambda/(1e-30 + g2);
|
||||
i = 0;
|
||||
if (prev_k > 0 && prev_k <= k) {
|
||||
/* We reuse pulses from a previous search so we don't have to search them
|
||||
again. */
|
||||
for (j = 0; j < n; j++) {
|
||||
ypulse[j] = abs(ypulse[j]);
|
||||
xy += x[j]*ypulse[j];
|
||||
yy += ypulse[j]*ypulse[j];
|
||||
i += ypulse[j];
|
||||
}
|
||||
}
|
||||
else if (k > 2) {
|
||||
double l1_norm;
|
||||
double l1_inv;
|
||||
l1_norm = 0;
|
||||
for (j = 0; j < n; j++) l1_norm += x[j];
|
||||
l1_inv = 1./OD_MAXF(l1_norm, 1e-100);
|
||||
for (j = 0; j < n; j++) {
|
||||
double tmp;
|
||||
tmp = k*x[j]*l1_inv;
|
||||
ypulse[j] = OD_MAXI(0, (int)floor(tmp));
|
||||
xy += x[j]*ypulse[j];
|
||||
yy += ypulse[j]*ypulse[j];
|
||||
i += ypulse[j];
|
||||
}
|
||||
}
|
||||
else OD_CLEAR(ypulse, n);
|
||||
|
||||
/* Only use RDO on the last few pulses. This not only saves CPU, but using
|
||||
RDO on all pulses actually makes the results worse for reasons I don't
|
||||
fully understand. */
|
||||
rdo_pulses = 1 + k/4;
|
||||
/* Rough assumption for now, the last position costs about 3 bits more than
|
||||
the first. */
|
||||
delta_rate = 3./n;
|
||||
/* Search one pulse at a time */
|
||||
for (; i < k - rdo_pulses; i++) {
|
||||
int pos;
|
||||
double best_xy;
|
||||
double best_yy;
|
||||
pos = 0;
|
||||
best_xy = -10;
|
||||
best_yy = 1;
|
||||
for (j = 0; j < n; j++) {
|
||||
double tmp_xy;
|
||||
double tmp_yy;
|
||||
tmp_xy = xy + x[j];
|
||||
tmp_yy = yy + 2*ypulse[j] + 1;
|
||||
tmp_xy *= tmp_xy;
|
||||
if (j == 0 || tmp_xy*best_yy > best_xy*tmp_yy) {
|
||||
best_xy = tmp_xy;
|
||||
best_yy = tmp_yy;
|
||||
pos = j;
|
||||
}
|
||||
}
|
||||
xy = xy + x[pos];
|
||||
yy = yy + 2*ypulse[pos] + 1;
|
||||
ypulse[pos]++;
|
||||
}
|
||||
/* Search last pulses with RDO. Distortion is D = (x-y)^2 = x^2 - 2*x*y + y^2
|
||||
and since x^2 and y^2 are constant, we just maximize x*y, plus a
|
||||
lambda*rate term. Note that since x and y aren't normalized here,
|
||||
we need to divide by sqrt(x^2)*sqrt(y^2). */
|
||||
for (; i < k; i++) {
|
||||
double rsqrt_table[4];
|
||||
int rsqrt_table_size = 4;
|
||||
int pos;
|
||||
double best_cost;
|
||||
pos = 0;
|
||||
best_cost = -1e5;
|
||||
/*Fill the small rsqrt lookup table with inputs relative to yy.
|
||||
Specifically, the table of n values is filled with
|
||||
rsqrt(yy + 1), rsqrt(yy + 2 + 1) .. rsqrt(yy + 2*(n-1) + 1).*/
|
||||
od_fill_dynamic_rsqrt_table(rsqrt_table, rsqrt_table_size, yy);
|
||||
for (j = 0; j < n; j++) {
|
||||
double tmp_xy;
|
||||
double tmp_yy;
|
||||
tmp_xy = xy + x[j];
|
||||
/*Calculate rsqrt(yy + 2*ypulse[j] + 1) using an optimized method.*/
|
||||
tmp_yy = od_custom_rsqrt_dynamic_table(rsqrt_table, rsqrt_table_size,
|
||||
yy, ypulse[j]);
|
||||
tmp_xy = 2*tmp_xy*norm_1*tmp_yy - lambda*j*delta_rate;
|
||||
if (j == 0 || tmp_xy > best_cost) {
|
||||
best_cost = tmp_xy;
|
||||
pos = j;
|
||||
}
|
||||
}
|
||||
xy = xy + x[pos];
|
||||
yy = yy + 2*ypulse[pos] + 1;
|
||||
ypulse[pos]++;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if (xcoeff[i] < 0) ypulse[i] = -ypulse[i];
|
||||
}
|
||||
return xy/(1e-100 + sqrt(xx*yy));
|
||||
}
|
||||
|
||||
/** Encodes the gain so that the return value increases with the
|
||||
* distance |x-ref|, so that we can encode a zero when x=ref. The
|
||||
* value x=0 is not covered because it is only allowed in the noref
|
||||
* case.
|
||||
*
|
||||
* @param [in] x quantized gain to encode
|
||||
* @param [in] ref quantized gain of the reference
|
||||
* @return interleave-encoded quantized gain value
|
||||
*/
|
||||
static int neg_interleave(int x, int ref) {
|
||||
if (x < ref) return -2*(x - ref) - 1;
|
||||
else if (x < 2*ref) return 2*(x - ref);
|
||||
else return x-1;
|
||||
}
|
||||
|
||||
int od_vector_is_null(const od_coeff *x, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; i++) if (x[i]) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static double od_pvq_rate(int qg, int icgr, int theta, int ts,
|
||||
const od_adapt_ctx *adapt, const od_coeff *y0, int k, int n, int speed) {
|
||||
double rate;
|
||||
if (k == 0) rate = 0;
|
||||
else if (speed > 0) {
|
||||
int i;
|
||||
int sum;
|
||||
double f;
|
||||
/* Compute "center of mass" of the pulse vector. */
|
||||
sum = 0;
|
||||
for (i = 0; i < n - (theta != -1); i++) sum += i*abs(y0[i]);
|
||||
f = sum/(double)(k*n);
|
||||
/* Estimates the number of bits it will cost to encode K pulses in
|
||||
N dimensions based on hand-tuned fit for bitrate vs K, N and
|
||||
"center of mass". */
|
||||
rate = (1 + .4*f)*n*OD_LOG2(1 + OD_MAXF(0, log(n*2*(1*f + .025))*k/n)) + 3;
|
||||
}
|
||||
else {
|
||||
aom_writer w;
|
||||
od_pvq_codeword_ctx cd;
|
||||
int tell;
|
||||
#if !CONFIG_ANS
|
||||
od_ec_enc_init(&w.ec, 1000);
|
||||
#else
|
||||
# error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
OD_COPY(&cd, &adapt->pvq.pvq_codeword_ctx, 1);
|
||||
#if !CONFIG_ANS
|
||||
tell = od_ec_enc_tell_frac(&w.ec);
|
||||
#else
|
||||
# error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
aom_encode_pvq_codeword(&w, &cd, y0, n - (theta != -1), k);
|
||||
#if !CONFIG_ANS
|
||||
rate = (od_ec_enc_tell_frac(&w.ec)-tell)/8.;
|
||||
od_ec_enc_clear(&w.ec);
|
||||
#else
|
||||
# error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
}
|
||||
if (qg > 0 && theta >= 0) {
|
||||
/* Approximate cost of entropy-coding theta */
|
||||
rate += .9*OD_LOG2(ts);
|
||||
if (qg == icgr) rate -= .5;
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
#define MAX_PVQ_ITEMS (20)
|
||||
/* This stores the information about a PVQ search candidate, so we can sort
|
||||
based on K. */
|
||||
typedef struct {
|
||||
int gain;
|
||||
int k;
|
||||
od_val32 qtheta;
|
||||
int theta;
|
||||
int ts;
|
||||
od_val32 qcg;
|
||||
} pvq_search_item;
|
||||
|
||||
int items_compare(pvq_search_item *a, pvq_search_item *b) {
|
||||
/* Break ties in K with gain to ensure a stable sort.
|
||||
Otherwise, the order depends on qsort implementation. */
|
||||
return a->k == b->k ? a->gain - b->gain : a->k - b->k;
|
||||
}
|
||||
|
||||
/** Perform PVQ quantization with prediction, trying several
|
||||
* possible gains and angles. See draft-valin-videocodec-pvq and
|
||||
* http://jmvalin.ca/slides/pvq.pdf for more details.
|
||||
*
|
||||
* @param [out] out coefficients after quantization
|
||||
* @param [in] x0 coefficients before quantization
|
||||
* @param [in] r0 reference, aka predicted coefficients
|
||||
* @param [in] n number of dimensions
|
||||
* @param [in] q0 quantization step size
|
||||
* @param [out] y pulse vector (i.e. selected PVQ codevector)
|
||||
* @param [out] itheta angle between input and reference (-1 if noref)
|
||||
* @param [out] vk total number of pulses
|
||||
* @param [in] beta per-band activity masking beta param
|
||||
* @param [out] skip_diff distortion cost of skipping this block
|
||||
* (accumulated)
|
||||
* @param [in] is_keyframe whether we're encoding a keyframe
|
||||
* @param [in] pli plane index
|
||||
* @param [in] adapt probability adaptation context
|
||||
* @param [in] qm QM with magnitude compensation
|
||||
* @param [in] qm_inv Inverse of QM with magnitude compensation
|
||||
* @param [in] pvq_norm_lambda enc->pvq_norm_lambda for quantized RDO
|
||||
* @param [in] speed Make search faster by making approximations
|
||||
* @return gain index of the quatized gain
|
||||
*/
|
||||
static int pvq_theta(od_coeff *out, const od_coeff *x0, const od_coeff *r0,
|
||||
int n, int q0, od_coeff *y, int *itheta, int *vk,
|
||||
od_val16 beta, double *skip_diff, int is_keyframe, int pli,
|
||||
const od_adapt_ctx *adapt, const int16_t *qm, const int16_t *qm_inv,
|
||||
double pvq_norm_lambda, int speed) {
|
||||
od_val32 g;
|
||||
od_val32 gr;
|
||||
od_coeff y_tmp[MAXN + 3];
|
||||
int i;
|
||||
/* Number of pulses. */
|
||||
int k;
|
||||
/* Companded gain of x and reference, normalized to q. */
|
||||
od_val32 cg;
|
||||
od_val32 cgr;
|
||||
int icgr;
|
||||
int qg;
|
||||
/* Best RDO cost (D + lamdba*R) so far. */
|
||||
double best_cost;
|
||||
double dist0;
|
||||
/* Distortion (D) that corresponds to the best RDO cost. */
|
||||
double best_dist;
|
||||
double dist;
|
||||
/* Sign of Householder reflection. */
|
||||
int s;
|
||||
/* Dimension on which Householder reflects. */
|
||||
int m;
|
||||
od_val32 theta;
|
||||
double corr;
|
||||
int best_k;
|
||||
od_val32 best_qtheta;
|
||||
od_val32 gain_offset;
|
||||
int noref;
|
||||
double skip_dist;
|
||||
int cfl_enabled;
|
||||
int skip;
|
||||
double gain_weight;
|
||||
od_val16 x16[MAXN];
|
||||
od_val16 r16[MAXN];
|
||||
int xshift;
|
||||
int rshift;
|
||||
/* Give more weight to gain error when calculating the total distortion. */
|
||||
gain_weight = 1.0;
|
||||
OD_ASSERT(n > 1);
|
||||
corr = 0;
|
||||
#if !defined(OD_FLOAT_PVQ)
|
||||
/* Shift needed to make x fit in 16 bits even after rotation.
|
||||
This shift value is not normative (it can be changed without breaking
|
||||
the bitstream) */
|
||||
xshift = OD_MAXI(0, od_vector_log_mag(x0, n) - 15);
|
||||
/* Shift needed to make the reference fit in 15 bits, so that the Householder
|
||||
vector can fit in 16 bits.
|
||||
This shift value *is* normative, and has to match the decoder. */
|
||||
rshift = OD_MAXI(0, od_vector_log_mag(r0, n) - 14);
|
||||
#else
|
||||
xshift = 0;
|
||||
rshift = 0;
|
||||
#endif
|
||||
for (i = 0; i < n; i++) {
|
||||
#if defined(OD_FLOAT_PVQ)
|
||||
/*This is slightly different from the original float PVQ code,
|
||||
where the qm was applied in the accumulation in od_pvq_compute_gain and
|
||||
the vectors were od_coeffs, not od_val16 (i.e. double).*/
|
||||
x16[i] = x0[i]*(double)qm[i]*OD_QM_SCALE_1;
|
||||
r16[i] = r0[i]*(double)qm[i]*OD_QM_SCALE_1;
|
||||
#else
|
||||
x16[i] = OD_SHR_ROUND(x0[i]*qm[i], OD_QM_SHIFT + xshift);
|
||||
r16[i] = OD_SHR_ROUND(r0[i]*qm[i], OD_QM_SHIFT + rshift);
|
||||
#endif
|
||||
corr += OD_MULT16_16(x16[i], r16[i]);
|
||||
}
|
||||
cfl_enabled = is_keyframe && pli != 0 && !OD_DISABLE_CFL;
|
||||
cg = od_pvq_compute_gain(x16, n, q0, &g, beta, xshift);
|
||||
cgr = od_pvq_compute_gain(r16, n, q0, &gr, beta, rshift);
|
||||
if (cfl_enabled) cgr = OD_CGAIN_SCALE;
|
||||
/* gain_offset is meant to make sure one of the quantized gains has
|
||||
exactly the same gain as the reference. */
|
||||
#if defined(OD_FLOAT_PVQ)
|
||||
icgr = (int)floor(.5 + cgr);
|
||||
#else
|
||||
icgr = OD_SHR_ROUND(cgr, OD_CGAIN_SHIFT);
|
||||
#endif
|
||||
gain_offset = cgr - OD_SHL(icgr, OD_CGAIN_SHIFT);
|
||||
/* Start search with null case: gain=0, no pulse. */
|
||||
qg = 0;
|
||||
dist = gain_weight*cg*cg*OD_CGAIN_SCALE_2;
|
||||
best_dist = dist;
|
||||
best_cost = dist + pvq_norm_lambda*od_pvq_rate(0, 0, -1, 0, adapt, NULL, 0,
|
||||
n, speed);
|
||||
noref = 1;
|
||||
best_k = 0;
|
||||
*itheta = -1;
|
||||
OD_CLEAR(y, n);
|
||||
best_qtheta = 0;
|
||||
m = 0;
|
||||
s = 1;
|
||||
corr = corr/(1e-100 + g*(double)gr/OD_SHL(1, xshift + rshift));
|
||||
corr = OD_MAXF(OD_MINF(corr, 1.), -1.);
|
||||
if (is_keyframe) skip_dist = gain_weight*cg*cg*OD_CGAIN_SCALE_2;
|
||||
else {
|
||||
skip_dist = gain_weight*(cg - cgr)*(cg - cgr)
|
||||
+ cgr*(double)cg*(2 - 2*corr);
|
||||
skip_dist *= OD_CGAIN_SCALE_2;
|
||||
}
|
||||
if (!is_keyframe) {
|
||||
/* noref, gain=0 isn't allowed, but skip is allowed. */
|
||||
od_val32 scgr;
|
||||
scgr = OD_MAXF(0,gain_offset);
|
||||
if (icgr == 0) {
|
||||
best_dist = gain_weight*(cg - scgr)*(cg - scgr)
|
||||
+ scgr*(double)cg*(2 - 2*corr);
|
||||
best_dist *= OD_CGAIN_SCALE_2;
|
||||
}
|
||||
best_cost = best_dist + pvq_norm_lambda*od_pvq_rate(0, icgr, 0, 0, adapt,
|
||||
NULL, 0, n, speed);
|
||||
best_qtheta = 0;
|
||||
*itheta = 0;
|
||||
noref = 0;
|
||||
}
|
||||
dist0 = best_dist;
|
||||
if (n <= OD_MAX_PVQ_SIZE && !od_vector_is_null(r0, n) && corr > 0) {
|
||||
od_val16 xr[MAXN];
|
||||
int gain_bound;
|
||||
int prev_k;
|
||||
pvq_search_item items[MAX_PVQ_ITEMS];
|
||||
int idx;
|
||||
int nitems;
|
||||
double cos_dist;
|
||||
idx = 0;
|
||||
gain_bound = OD_SHR(cg - gain_offset, OD_CGAIN_SHIFT);
|
||||
/* Perform theta search only if prediction is useful. */
|
||||
theta = OD_ROUND32(OD_THETA_SCALE*acos(corr));
|
||||
m = od_compute_householder(r16, n, gr, &s, rshift);
|
||||
od_apply_householder(xr, x16, r16, n);
|
||||
prev_k = 0;
|
||||
for (i = m; i < n - 1; i++) xr[i] = xr[i + 1];
|
||||
/* Compute all candidate PVQ searches within a reasonable range of gain
|
||||
and theta. */
|
||||
for (i = OD_MAXI(1, gain_bound - 1); i <= gain_bound + 1; i++) {
|
||||
int j;
|
||||
od_val32 qcg;
|
||||
int ts;
|
||||
int theta_lower;
|
||||
int theta_upper;
|
||||
/* Quantized companded gain */
|
||||
qcg = OD_SHL(i, OD_CGAIN_SHIFT) + gain_offset;
|
||||
/* Set angular resolution (in ra) to match the encoded gain */
|
||||
ts = od_pvq_compute_max_theta(qcg, beta);
|
||||
theta_lower = OD_MAXI(0, (int)floor(.5 +
|
||||
theta*OD_THETA_SCALE_1*2/M_PI*ts) - 2);
|
||||
theta_upper = OD_MINI(ts - 1, (int)ceil(theta*OD_THETA_SCALE_1*2/M_PI*ts));
|
||||
/* Include the angles within a reasonable range. */
|
||||
for (j = theta_lower; j <= theta_upper; j++) {
|
||||
od_val32 qtheta;
|
||||
qtheta = od_pvq_compute_theta(j, ts);
|
||||
k = od_pvq_compute_k(qcg, j, 0, n, beta);
|
||||
items[idx].gain = i;
|
||||
items[idx].theta = j;
|
||||
items[idx].k = k;
|
||||
items[idx].qcg = qcg;
|
||||
items[idx].qtheta = qtheta;
|
||||
items[idx].ts = ts;
|
||||
idx++;
|
||||
OD_ASSERT(idx < MAX_PVQ_ITEMS);
|
||||
}
|
||||
}
|
||||
nitems = idx;
|
||||
cos_dist = 0;
|
||||
/* Sort PVQ search candidates in ascending order of pulses K so that
|
||||
we can reuse all the previously searched pulses across searches. */
|
||||
qsort(items, nitems, sizeof(items[0]),
|
||||
(int (*)(const void *, const void *))items_compare);
|
||||
/* Search for the best gain/theta in order. */
|
||||
for (idx = 0; idx < nitems; idx++) {
|
||||
int j;
|
||||
od_val32 qcg;
|
||||
int ts;
|
||||
double cost;
|
||||
double dist_theta;
|
||||
double sin_prod;
|
||||
od_val32 qtheta;
|
||||
/* Quantized companded gain */
|
||||
qcg = items[idx].qcg;
|
||||
i = items[idx].gain;
|
||||
j = items[idx].theta;
|
||||
/* Set angular resolution (in ra) to match the encoded gain */
|
||||
ts = items[idx].ts;
|
||||
/* Search for the best angle within a reasonable range. */
|
||||
qtheta = items[idx].qtheta;
|
||||
k = items[idx].k;
|
||||
/* Compute the minimal possible distortion by not taking the PVQ
|
||||
cos_dist into account. */
|
||||
dist_theta = 2 - 2.*od_pvq_cos(theta - qtheta)*OD_TRIG_SCALE_1;
|
||||
dist = gain_weight*(qcg - cg)*(qcg - cg) + qcg*(double)cg*dist_theta;
|
||||
dist *= OD_CGAIN_SCALE_2;
|
||||
/* If we have no hope of beating skip (including a 1-bit worst-case
|
||||
penalty), stop now. */
|
||||
if (dist > dist0 + 1.0*pvq_norm_lambda && k != 0) continue;
|
||||
sin_prod = od_pvq_sin(theta)*OD_TRIG_SCALE_1*od_pvq_sin(qtheta)*
|
||||
OD_TRIG_SCALE_1;
|
||||
/* PVQ search, using a gain of qcg*cg*sin(theta)*sin(qtheta) since
|
||||
that's the factor by which cos_dist is multiplied to get the
|
||||
distortion metric. */
|
||||
if (k == 0) {
|
||||
cos_dist = 0;
|
||||
OD_CLEAR(y_tmp, n-1);
|
||||
}
|
||||
else if (k != prev_k) {
|
||||
cos_dist = pvq_search_rdo_double(xr, n - 1, k, y_tmp,
|
||||
qcg*(double)cg*sin_prod*OD_CGAIN_SCALE_2, pvq_norm_lambda, prev_k);
|
||||
}
|
||||
prev_k = k;
|
||||
/* See Jmspeex' Journal of Dubious Theoretical Results. */
|
||||
dist_theta = 2 - 2.*od_pvq_cos(theta - qtheta)*OD_TRIG_SCALE_1
|
||||
+ sin_prod*(2 - 2*cos_dist);
|
||||
dist = gain_weight*(qcg - cg)*(qcg - cg) + qcg*(double)cg*dist_theta;
|
||||
dist *= OD_CGAIN_SCALE_2;
|
||||
/* Do approximate RDO. */
|
||||
cost = dist + pvq_norm_lambda*od_pvq_rate(i, icgr, j, ts, adapt, y_tmp,
|
||||
k, n, speed);
|
||||
if (cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_dist = dist;
|
||||
qg = i;
|
||||
best_k = k;
|
||||
best_qtheta = qtheta;
|
||||
*itheta = j;
|
||||
noref = 0;
|
||||
OD_COPY(y, y_tmp, n - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Don't bother with no-reference version if there's a reasonable
|
||||
correlation. */
|
||||
if (n <= OD_MAX_PVQ_SIZE && (corr < .5
|
||||
|| cg < (od_val32)(OD_SHL(2, OD_CGAIN_SHIFT)))) {
|
||||
int gain_bound;
|
||||
int prev_k;
|
||||
gain_bound = OD_SHR(cg, OD_CGAIN_SHIFT);
|
||||
prev_k = 0;
|
||||
/* Search for the best gain (haven't determined reasonable range yet). */
|
||||
for (i = OD_MAXI(1, gain_bound); i <= gain_bound + 1; i++) {
|
||||
double cos_dist;
|
||||
double cost;
|
||||
od_val32 qcg;
|
||||
qcg = OD_SHL(i, OD_CGAIN_SHIFT);
|
||||
k = od_pvq_compute_k(qcg, -1, 1, n, beta);
|
||||
/* Compute the minimal possible distortion by not taking the PVQ
|
||||
cos_dist into account. */
|
||||
dist = gain_weight*(qcg - cg)*(qcg - cg);
|
||||
dist *= OD_CGAIN_SCALE_2;
|
||||
if (dist > dist0 && k != 0) continue;
|
||||
cos_dist = pvq_search_rdo_double(x16, n, k, y_tmp,
|
||||
qcg*(double)cg*OD_CGAIN_SCALE_2, pvq_norm_lambda, prev_k);
|
||||
prev_k = k;
|
||||
/* See Jmspeex' Journal of Dubious Theoretical Results. */
|
||||
dist = gain_weight*(qcg - cg)*(qcg - cg)
|
||||
+ qcg*(double)cg*(2 - 2*cos_dist);
|
||||
dist *= OD_CGAIN_SCALE_2;
|
||||
/* Do approximate RDO. */
|
||||
cost = dist + pvq_norm_lambda*od_pvq_rate(i, 0, -1, 0, adapt, y_tmp, k,
|
||||
n, speed);
|
||||
if (cost <= best_cost) {
|
||||
best_cost = cost;
|
||||
best_dist = dist;
|
||||
qg = i;
|
||||
noref = 1;
|
||||
best_k = k;
|
||||
*itheta = -1;
|
||||
OD_COPY(y, y_tmp, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
k = best_k;
|
||||
theta = best_qtheta;
|
||||
skip = 0;
|
||||
if (noref) {
|
||||
if (qg == 0) skip = OD_PVQ_SKIP_ZERO;
|
||||
}
|
||||
else {
|
||||
if (!is_keyframe && qg == 0) {
|
||||
skip = (icgr ? OD_PVQ_SKIP_ZERO : OD_PVQ_SKIP_COPY);
|
||||
}
|
||||
if (qg == icgr && *itheta == 0 && !cfl_enabled) skip = OD_PVQ_SKIP_COPY;
|
||||
}
|
||||
/* Synthesize like the decoder would. */
|
||||
if (skip) {
|
||||
if (skip == OD_PVQ_SKIP_COPY) OD_COPY(out, r0, n);
|
||||
else OD_CLEAR(out, n);
|
||||
}
|
||||
else {
|
||||
if (noref) gain_offset = 0;
|
||||
g = od_gain_expand(OD_SHL(qg, OD_CGAIN_SHIFT) + gain_offset, q0, beta);
|
||||
od_pvq_synthesis_partial(out, y, r16, n, noref, g, theta, m, s,
|
||||
qm_inv);
|
||||
}
|
||||
*vk = k;
|
||||
*skip_diff += skip_dist - best_dist;
|
||||
/* Encode gain differently depending on whether we use prediction or not.
|
||||
Special encoding on inter frames where qg=0 is allowed for noref=0
|
||||
but not noref=1.*/
|
||||
if (is_keyframe) return noref ? qg : neg_interleave(qg, icgr);
|
||||
else return noref ? qg - 1 : neg_interleave(qg + 1, icgr + 1);
|
||||
}
|
||||
|
||||
/** Encodes a single vector of integers (eg, a partition within a
|
||||
* coefficient block) using PVQ
|
||||
*
|
||||
* @param [in,out] w multi-symbol entropy encoder
|
||||
* @param [in] qg quantized gain
|
||||
* @param [in] theta quantized post-prediction theta
|
||||
* @param [in] in coefficient vector to code
|
||||
* @param [in] n number of coefficients in partition
|
||||
* @param [in] k number of pulses in partition
|
||||
* @param [in,out] model entropy encoder state
|
||||
* @param [in,out] adapt adaptation context
|
||||
* @param [in,out] exg ExQ16 expectation of gain value
|
||||
* @param [in,out] ext ExQ16 expectation of theta value
|
||||
* @param [in] cdf_ctx selects which cdf context to use
|
||||
* @param [in] is_keyframe whether we're encoding a keyframe
|
||||
* @param [in] code_skip whether the "skip rest" flag is allowed
|
||||
* @param [in] skip_rest when set, we skip all higher bands
|
||||
* @param [in] encode_flip whether we need to encode the CfL flip flag now
|
||||
* @param [in] flip value of the CfL flip flag
|
||||
*/
|
||||
void pvq_encode_partition(aom_writer *w,
|
||||
int qg,
|
||||
int theta,
|
||||
const od_coeff *in,
|
||||
int n,
|
||||
int k,
|
||||
generic_encoder model[3],
|
||||
od_adapt_ctx *adapt,
|
||||
int *exg,
|
||||
int *ext,
|
||||
int cdf_ctx,
|
||||
int is_keyframe,
|
||||
int code_skip,
|
||||
int skip_rest,
|
||||
int encode_flip,
|
||||
int flip) {
|
||||
int noref;
|
||||
int id;
|
||||
noref = (theta == -1);
|
||||
id = (qg > 0) + 2*OD_MINI(theta + 1,3) + 8*code_skip*skip_rest;
|
||||
if (is_keyframe) {
|
||||
OD_ASSERT(id != 8);
|
||||
if (id >= 8) id--;
|
||||
}
|
||||
else {
|
||||
OD_ASSERT(id != 10);
|
||||
if (id >= 10) id--;
|
||||
}
|
||||
/* Jointly code gain, theta and noref for small values. Then we handle
|
||||
larger gain and theta values. For noref, theta = -1. */
|
||||
aom_write_symbol_pvq(w, id, &adapt->pvq.pvq_gaintheta_cdf[cdf_ctx][0],
|
||||
8 + 7*code_skip);
|
||||
if (encode_flip) {
|
||||
/* We could eventually do some smarter entropy coding here, but it would
|
||||
have to be good enough to overcome the overhead of the entropy coder.
|
||||
An early attempt using a "toogle" flag with simple adaptation wasn't
|
||||
worth the trouble. */
|
||||
aom_write_bit(w, flip);
|
||||
}
|
||||
if (qg > 0) {
|
||||
int tmp;
|
||||
tmp = *exg;
|
||||
generic_encode(w, &model[!noref], qg - 1, &tmp, 2);
|
||||
OD_IIR_DIADIC(*exg, qg << 16, 2);
|
||||
}
|
||||
if (theta > 1) {
|
||||
int tmp;
|
||||
tmp = *ext;
|
||||
generic_encode(w, &model[2], theta - 2, &tmp, 2);
|
||||
OD_IIR_DIADIC(*ext, theta << 16, 2);
|
||||
}
|
||||
aom_encode_pvq_codeword(w, &adapt->pvq.pvq_codeword_ctx, in,
|
||||
n - (theta != -1), k);
|
||||
}
|
||||
|
||||
/** Quantizes a scalar with rate-distortion optimization (RDO)
|
||||
* @param [in] x unquantized value
|
||||
* @param [in] q quantization step size
|
||||
* @param [in] delta0 rate increase for encoding a 1 instead of a 0
|
||||
* @param [in] pvq_norm_lambda enc->pvq_norm_lambda for quantized RDO
|
||||
* @retval quantized value
|
||||
*/
|
||||
int od_rdo_quant(od_coeff x, int q, double delta0, double pvq_norm_lambda) {
|
||||
int n;
|
||||
/* Optimal quantization threshold is 1/2 + lambda*delta_rate/2. See
|
||||
Jmspeex' Journal of Dubious Theoretical Results for details. */
|
||||
n = OD_DIV_R0(abs(x), q);
|
||||
if ((double)abs(x)/q < (double)n/2 + pvq_norm_lambda*delta0/(2*n)) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return OD_DIV_R0(x, q);
|
||||
}
|
||||
}
|
||||
|
||||
/** Encode a coefficient block (excepting DC) using PVQ
|
||||
*
|
||||
* @param [in,out] enc daala encoder context
|
||||
* @param [in] ref 'reference' (prediction) vector
|
||||
* @param [in] in coefficient block to quantize and encode
|
||||
* @param [out] out quantized coefficient block
|
||||
* @param [in] q0 scale/quantizer
|
||||
* @param [in] pli plane index
|
||||
* @param [in] bs log of the block size minus two
|
||||
* @param [in] beta per-band activity masking beta param
|
||||
* @param [in] is_keyframe whether we're encoding a keyframe
|
||||
* @param [in] qm QM with magnitude compensation
|
||||
* @param [in] qm_inv Inverse of QM with magnitude compensation
|
||||
* @param [in] speed Make search faster by making approximations
|
||||
* @param [in] pvq_info If null, conisdered as RDO search mode
|
||||
* @return Returns block skip info indicating whether DC/AC are coded.
|
||||
* bit0: DC is coded, bit1: AC is coded (1 means coded)
|
||||
*
|
||||
*/
|
||||
PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc,
|
||||
od_coeff *ref,
|
||||
const od_coeff *in,
|
||||
od_coeff *out,
|
||||
int q_dc,
|
||||
int q_ac,
|
||||
int pli,
|
||||
int bs,
|
||||
const od_val16 *beta,
|
||||
int is_keyframe,
|
||||
const int16_t *qm,
|
||||
const int16_t *qm_inv,
|
||||
int speed,
|
||||
PVQ_INFO *pvq_info){
|
||||
int theta[PVQ_MAX_PARTITIONS];
|
||||
int qg[PVQ_MAX_PARTITIONS];
|
||||
int k[PVQ_MAX_PARTITIONS];
|
||||
od_coeff y[OD_TXSIZE_MAX*OD_TXSIZE_MAX];
|
||||
int *exg;
|
||||
int *ext;
|
||||
int nb_bands;
|
||||
int i;
|
||||
const int *off;
|
||||
int size[PVQ_MAX_PARTITIONS];
|
||||
generic_encoder *model;
|
||||
double skip_diff;
|
||||
int tell;
|
||||
uint16_t *skip_cdf;
|
||||
od_rollback_buffer buf;
|
||||
int dc_quant;
|
||||
int flip;
|
||||
int cfl_encoded;
|
||||
int skip_rest;
|
||||
int skip_dir;
|
||||
int skip_theta_value;
|
||||
const unsigned char *pvq_qm;
|
||||
double dc_rate;
|
||||
int use_masking;
|
||||
PVQ_SKIP_TYPE ac_dc_coded;
|
||||
|
||||
aom_clear_system_state();
|
||||
|
||||
use_masking = enc->use_activity_masking;
|
||||
|
||||
if (use_masking)
|
||||
pvq_qm = &enc->state.pvq_qm_q4[pli][0];
|
||||
else
|
||||
pvq_qm = 0;
|
||||
|
||||
exg = &enc->state.adapt->pvq.pvq_exg[pli][bs][0];
|
||||
ext = enc->state.adapt->pvq.pvq_ext + bs*PVQ_MAX_PARTITIONS;
|
||||
skip_cdf = enc->state.adapt->skip_cdf[2*bs + (pli != 0)];
|
||||
model = enc->state.adapt->pvq.pvq_param_model;
|
||||
nb_bands = OD_BAND_OFFSETS[bs][0];
|
||||
off = &OD_BAND_OFFSETS[bs][1];
|
||||
|
||||
if (use_masking)
|
||||
dc_quant = OD_MAXI(1, q_dc * pvq_qm[od_qm_get_index(bs, 0)] >> 4);
|
||||
else
|
||||
dc_quant = OD_MAXI(1, q_dc);
|
||||
|
||||
tell = 0;
|
||||
for (i = 0; i < nb_bands; i++) size[i] = off[i+1] - off[i];
|
||||
skip_diff = 0;
|
||||
flip = 0;
|
||||
/*If we are coding a chroma block of a keyframe, we are doing CfL.*/
|
||||
if (pli != 0 && is_keyframe) {
|
||||
od_val32 xy;
|
||||
xy = 0;
|
||||
/*Compute the dot-product of the first band of chroma with the luma ref.*/
|
||||
for (i = off[0]; i < off[1]; i++) {
|
||||
#if defined(OD_FLOAT_PVQ)
|
||||
xy += ref[i]*(double)qm[i]*OD_QM_SCALE_1*
|
||||
(double)in[i]*(double)qm[i]*OD_QM_SCALE_1;
|
||||
#else
|
||||
od_val32 rq;
|
||||
od_val32 inq;
|
||||
rq = ref[i]*qm[i];
|
||||
inq = in[i]*qm[i];
|
||||
xy += OD_SHR(rq*(int64_t)inq, OD_SHL(OD_QM_SHIFT + OD_CFL_FLIP_SHIFT,
|
||||
1));
|
||||
#endif
|
||||
}
|
||||
/*If cos(theta) < 0, then |theta| > pi/2 and we should negate the ref.*/
|
||||
if (xy < 0) {
|
||||
flip = 1;
|
||||
for(i = off[0]; i < off[nb_bands]; i++) ref[i] = -ref[i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nb_bands; i++) {
|
||||
int q;
|
||||
|
||||
if (use_masking)
|
||||
q = OD_MAXI(1, q_ac * pvq_qm[od_qm_get_index(bs, i + 1)] >> 4);
|
||||
else
|
||||
q = OD_MAXI(1, q_ac);
|
||||
|
||||
qg[i] = pvq_theta(out + off[i], in + off[i], ref + off[i], size[i],
|
||||
q, y + off[i], &theta[i], &k[i], beta[i], &skip_diff, is_keyframe,
|
||||
pli, enc->state.adapt, qm + off[i], qm_inv + off[i],
|
||||
enc->pvq_norm_lambda, speed);
|
||||
}
|
||||
od_encode_checkpoint(enc, &buf);
|
||||
if (is_keyframe) out[0] = 0;
|
||||
else {
|
||||
int n;
|
||||
n = OD_DIV_R0(abs(in[0] - ref[0]), dc_quant);
|
||||
if (n == 0) {
|
||||
out[0] = 0;
|
||||
} else {
|
||||
int tell2;
|
||||
od_rollback_buffer dc_buf;
|
||||
|
||||
dc_rate = -OD_LOG2((double)(OD_ICDF(skip_cdf[3]) - OD_ICDF(skip_cdf[2]))/
|
||||
(double)(OD_ICDF(skip_cdf[2]) - OD_ICDF(skip_cdf[1])));
|
||||
dc_rate += 1;
|
||||
|
||||
#if !CONFIG_ANS
|
||||
tell2 = od_ec_enc_tell_frac(&enc->w.ec);
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
od_encode_checkpoint(enc, &dc_buf);
|
||||
generic_encode(&enc->w, &enc->state.adapt->model_dc[pli],
|
||||
n - 1, &enc->state.adapt->ex_dc[pli][bs][0], 2);
|
||||
#if !CONFIG_ANS
|
||||
tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2;
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
dc_rate += tell2/8.0;
|
||||
od_encode_rollback(enc, &dc_buf);
|
||||
|
||||
out[0] = od_rdo_quant(in[0] - ref[0], dc_quant, dc_rate,
|
||||
enc->pvq_norm_lambda);
|
||||
}
|
||||
}
|
||||
#if !CONFIG_ANS
|
||||
tell = od_ec_enc_tell_frac(&enc->w.ec);
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
/* Code as if we're not skipping. */
|
||||
aom_write_symbol(&enc->w, 2 + (out[0] != 0), skip_cdf, 4);
|
||||
ac_dc_coded = AC_CODED + (out[0] != 0);
|
||||
cfl_encoded = 0;
|
||||
skip_rest = 1;
|
||||
skip_theta_value = is_keyframe ? -1 : 0;
|
||||
for (i = 1; i < nb_bands; i++) {
|
||||
if (theta[i] != skip_theta_value || qg[i]) skip_rest = 0;
|
||||
}
|
||||
skip_dir = 0;
|
||||
if (nb_bands > 1) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
int j;
|
||||
int tmp;
|
||||
tmp = 1;
|
||||
// ToDo(yaowu): figure out better stop condition without gcc warning.
|
||||
for (j = i + 1; j < nb_bands && j < PVQ_MAX_PARTITIONS; j += 3) {
|
||||
if (theta[j] != skip_theta_value || qg[j]) tmp = 0;
|
||||
}
|
||||
skip_dir |= tmp << i;
|
||||
}
|
||||
}
|
||||
if (theta[0] == skip_theta_value && qg[0] == 0 && skip_rest) nb_bands = 0;
|
||||
|
||||
/* NOTE: There was no other better place to put this function. */
|
||||
if (pvq_info)
|
||||
av1_store_pvq_enc_info(pvq_info, qg, theta, k, y, nb_bands, off, size,
|
||||
skip_rest, skip_dir, bs);
|
||||
|
||||
for (i = 0; i < nb_bands; i++) {
|
||||
int encode_flip;
|
||||
/* Encode CFL flip bit just after the first time it's used. */
|
||||
encode_flip = pli != 0 && is_keyframe && theta[i] != -1 && !cfl_encoded;
|
||||
if (i == 0 || (!skip_rest && !(skip_dir & (1 << ((i - 1)%3))))) {
|
||||
pvq_encode_partition(&enc->w, qg[i], theta[i], y + off[i],
|
||||
size[i], k[i], model, enc->state.adapt, exg + i, ext + i,
|
||||
(pli != 0)*OD_TXSIZES*PVQ_MAX_PARTITIONS + bs*PVQ_MAX_PARTITIONS + i,
|
||||
is_keyframe, i == 0 && (i < nb_bands - 1), skip_rest, encode_flip, flip);
|
||||
}
|
||||
if (i == 0 && !skip_rest && bs > 0) {
|
||||
aom_write_symbol(&enc->w, skip_dir,
|
||||
&enc->state.adapt->pvq.pvq_skip_dir_cdf[(pli != 0) + 2*(bs - 1)][0], 7);
|
||||
}
|
||||
if (encode_flip) cfl_encoded = 1;
|
||||
}
|
||||
#if !CONFIG_ANS
|
||||
tell = od_ec_enc_tell_frac(&enc->w.ec) - tell;
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
/* Account for the rate of skipping the AC, based on the same DC decision
|
||||
we made when trying to not skip AC. */
|
||||
{
|
||||
double skip_rate;
|
||||
if (out[0] != 0) {
|
||||
skip_rate = -OD_LOG2((OD_ICDF(skip_cdf[1]) - OD_ICDF(skip_cdf[0]))/
|
||||
(double)OD_ICDF(skip_cdf[3]));
|
||||
}
|
||||
else {
|
||||
skip_rate = -OD_LOG2(OD_ICDF(skip_cdf[0])/
|
||||
(double)OD_ICDF(skip_cdf[3]));
|
||||
}
|
||||
tell -= (int)floor(.5+8*skip_rate);
|
||||
}
|
||||
if (nb_bands == 0 || skip_diff <= enc->pvq_norm_lambda/8*tell) {
|
||||
if (is_keyframe) out[0] = 0;
|
||||
else {
|
||||
int n;
|
||||
n = OD_DIV_R0(abs(in[0] - ref[0]), dc_quant);
|
||||
if (n == 0) {
|
||||
out[0] = 0;
|
||||
} else {
|
||||
int tell2;
|
||||
od_rollback_buffer dc_buf;
|
||||
|
||||
dc_rate = -OD_LOG2((double)(OD_ICDF(skip_cdf[1]) - OD_ICDF(skip_cdf[0]))/
|
||||
(double)OD_ICDF(skip_cdf[0]));
|
||||
dc_rate += 1;
|
||||
|
||||
#if !CONFIG_ANS
|
||||
tell2 = od_ec_enc_tell_frac(&enc->w.ec);
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
od_encode_checkpoint(enc, &dc_buf);
|
||||
generic_encode(&enc->w, &enc->state.adapt->model_dc[pli],
|
||||
n - 1, &enc->state.adapt->ex_dc[pli][bs][0], 2);
|
||||
#if !CONFIG_ANS
|
||||
tell2 = od_ec_enc_tell_frac(&enc->w.ec) - tell2;
|
||||
#else
|
||||
#error "CONFIG_PVQ currently requires !CONFIG_ANS."
|
||||
#endif
|
||||
dc_rate += tell2/8.0;
|
||||
od_encode_rollback(enc, &dc_buf);
|
||||
|
||||
out[0] = od_rdo_quant(in[0] - ref[0], dc_quant, dc_rate,
|
||||
enc->pvq_norm_lambda);
|
||||
}
|
||||
}
|
||||
/* We decide to skip, roll back everything as it was before. */
|
||||
od_encode_rollback(enc, &buf);
|
||||
aom_write_symbol(&enc->w, out[0] != 0, skip_cdf, 4);
|
||||
ac_dc_coded = (out[0] != 0);
|
||||
if (is_keyframe) for (i = 1; i < 1 << (2*bs + 4); i++) out[i] = 0;
|
||||
else for (i = 1; i < 1 << (2*bs + 4); i++) out[i] = ref[i];
|
||||
}
|
||||
if (pvq_info)
|
||||
pvq_info->ac_dc_coded = ac_dc_coded;
|
||||
return ac_dc_coded;
|
||||
}
|
||||
53
third_party/aom/av1/encoder/pvq_encoder.h
vendored
53
third_party/aom/av1/encoder/pvq_encoder.h
vendored
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#if !defined(_pvq_encoder_H)
|
||||
# define _pvq_encoder_H (1)
|
||||
# include "aom_dsp/bitwriter.h"
|
||||
# include "aom_dsp/entenc.h"
|
||||
# include "av1/common/blockd.h"
|
||||
# include "av1/common/pvq.h"
|
||||
# include "av1/encoder/encint.h"
|
||||
|
||||
void aom_write_symbol_pvq(aom_writer *w, int symb, aom_cdf_prob *cdf,
|
||||
int nsymbs);
|
||||
|
||||
void aom_encode_band_pvq_splits(aom_writer *w, od_pvq_codeword_ctx *adapt,
|
||||
const int *y, int n, int k, int level);
|
||||
|
||||
void aom_laplace_encode_special(aom_writer *w, int x, unsigned decay);
|
||||
|
||||
void pvq_encode_partition(aom_writer *w,
|
||||
int qg,
|
||||
int theta,
|
||||
const od_coeff *in,
|
||||
int n,
|
||||
int k,
|
||||
generic_encoder model[3],
|
||||
od_adapt_ctx *adapt,
|
||||
int *exg,
|
||||
int *ext,
|
||||
int cdf_ctx,
|
||||
int is_keyframe,
|
||||
int code_skip,
|
||||
int skip_rest,
|
||||
int encode_flip,
|
||||
int flip);
|
||||
|
||||
PVQ_SKIP_TYPE od_pvq_encode(daala_enc_ctx *enc, od_coeff *ref,
|
||||
const od_coeff *in, od_coeff *out, int q_dc, int q_ac, int pli, int bs,
|
||||
const od_val16 *beta, int is_keyframe,
|
||||
const int16_t *qm, const int16_t *qm_inv, int speed,
|
||||
PVQ_INFO *pvq_info);
|
||||
|
||||
#endif
|
||||
313
third_party/aom/av1/encoder/ransac.c
vendored
313
third_party/aom/av1/encoder/ransac.c
vendored
|
|
@ -80,60 +80,6 @@ static void project_points_double_affine(double *mat, double *points,
|
|||
}
|
||||
}
|
||||
|
||||
static void project_points_double_hortrapezoid(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
const int stride_proj) {
|
||||
int i;
|
||||
double x, y, Z, Z_inv;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
Z_inv = mat[7] * y + 1;
|
||||
assert(fabs(Z_inv) > 0.000001);
|
||||
Z = 1. / Z_inv;
|
||||
*(proj++) = (mat[2] * x + mat[3] * y + mat[0]) * Z;
|
||||
*(proj++) = (mat[5] * y + mat[1]) * Z;
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void project_points_double_vertrapezoid(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
const int stride_proj) {
|
||||
int i;
|
||||
double x, y, Z, Z_inv;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
Z_inv = mat[6] * x + 1;
|
||||
assert(fabs(Z_inv) > 0.000001);
|
||||
Z = 1. / Z_inv;
|
||||
*(proj++) = (mat[2] * x + mat[0]) * Z;
|
||||
*(proj++) = (mat[4] * x + mat[5] * y + mat[1]) * Z;
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void project_points_double_homography(double *mat, double *points,
|
||||
double *proj, const int n,
|
||||
const int stride_points,
|
||||
const int stride_proj) {
|
||||
int i;
|
||||
double x, y, Z, Z_inv;
|
||||
for (i = 0; i < n; ++i) {
|
||||
x = *(points++), y = *(points++);
|
||||
Z_inv = mat[6] * x + mat[7] * y + 1;
|
||||
assert(fabs(Z_inv) > 0.000001);
|
||||
Z = 1. / Z_inv;
|
||||
*(proj++) = (mat[2] * x + mat[3] * y + mat[0]) * Z;
|
||||
*(proj++) = (mat[4] * x + mat[5] * y + mat[1]) * Z;
|
||||
points += stride_points - 2;
|
||||
proj += stride_proj - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void normalize_homography(double *pts, int n, double *T) {
|
||||
double *p = pts;
|
||||
double mean[2] = { 0, 0 };
|
||||
|
|
@ -193,22 +139,6 @@ static void denormalize_homography(double *params, double *T1, double *T2) {
|
|||
multiply_mat(iT2, params2, params, 3, 3, 3);
|
||||
}
|
||||
|
||||
static void denormalize_homography_reorder(double *params, double *T1,
|
||||
double *T2) {
|
||||
double params_denorm[MAX_PARAMDIM];
|
||||
memcpy(params_denorm, params, sizeof(*params) * 8);
|
||||
params_denorm[8] = 1.0;
|
||||
denormalize_homography(params_denorm, T1, T2);
|
||||
params[0] = params_denorm[2];
|
||||
params[1] = params_denorm[5];
|
||||
params[2] = params_denorm[0];
|
||||
params[3] = params_denorm[1];
|
||||
params[4] = params_denorm[3];
|
||||
params[5] = params_denorm[4];
|
||||
params[6] = params_denorm[6];
|
||||
params[7] = params_denorm[7];
|
||||
}
|
||||
|
||||
static void denormalize_affine_reorder(double *params, double *T1, double *T2) {
|
||||
double params_denorm[MAX_PARAMDIM];
|
||||
params_denorm[0] = params[0];
|
||||
|
|
@ -377,217 +307,6 @@ static int find_affine(int np, double *pts1, double *pts2, double *mat) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int find_vertrapezoid(int np, double *pts1, double *pts2, double *mat) {
|
||||
const int np3 = np * 3;
|
||||
double *a = (double *)aom_malloc(sizeof(*a) * np3 * 14);
|
||||
double *U = a + np3 * 7;
|
||||
double S[7], V[7 * 7], H[9];
|
||||
int i, mini;
|
||||
double sx, sy, dx, dy;
|
||||
double T1[9], T2[9];
|
||||
|
||||
normalize_homography(pts1, np, T1);
|
||||
normalize_homography(pts2, np, T2);
|
||||
|
||||
for (i = 0; i < np; ++i) {
|
||||
dx = *(pts2++);
|
||||
dy = *(pts2++);
|
||||
sx = *(pts1++);
|
||||
sy = *(pts1++);
|
||||
|
||||
a[i * 3 * 7 + 0] = a[i * 3 * 7 + 1] = 0;
|
||||
a[i * 3 * 7 + 2] = -sx;
|
||||
a[i * 3 * 7 + 3] = -sy;
|
||||
a[i * 3 * 7 + 4] = -1;
|
||||
a[i * 3 * 7 + 5] = dy * sx;
|
||||
a[i * 3 * 7 + 6] = dy;
|
||||
|
||||
a[(i * 3 + 1) * 7 + 0] = sx;
|
||||
a[(i * 3 + 1) * 7 + 1] = 1;
|
||||
a[(i * 3 + 1) * 7 + 2] = a[(i * 3 + 1) * 7 + 3] = a[(i * 3 + 1) * 7 + 4] =
|
||||
0;
|
||||
a[(i * 3 + 1) * 7 + 5] = -dx * sx;
|
||||
a[(i * 3 + 1) * 7 + 6] = -dx;
|
||||
|
||||
a[(i * 3 + 2) * 7 + 0] = -dy * sx;
|
||||
a[(i * 3 + 2) * 7 + 1] = -dy;
|
||||
a[(i * 3 + 2) * 7 + 2] = dx * sx;
|
||||
a[(i * 3 + 2) * 7 + 3] = dx * sy;
|
||||
a[(i * 3 + 2) * 7 + 4] = dx;
|
||||
a[(i * 3 + 2) * 7 + 5] = a[(i * 3 + 2) * 7 + 6] = 0;
|
||||
}
|
||||
if (SVD(U, S, V, a, np3, 7)) {
|
||||
aom_free(a);
|
||||
return 1;
|
||||
} else {
|
||||
double minS = 1e12;
|
||||
mini = -1;
|
||||
for (i = 0; i < 7; ++i) {
|
||||
if (S[i] < minS) {
|
||||
minS = S[i];
|
||||
mini = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
H[1] = H[7] = 0;
|
||||
for (i = 0; i < 1; i++) H[i] = V[i * 7 + mini];
|
||||
for (; i < 6; i++) H[i + 1] = V[i * 7 + mini];
|
||||
for (; i < 7; i++) H[i + 2] = V[i * 7 + mini];
|
||||
|
||||
denormalize_homography_reorder(H, T1, T2);
|
||||
aom_free(a);
|
||||
if (H[8] == 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
// normalize
|
||||
double f = 1.0 / H[8];
|
||||
for (i = 0; i < 8; i++) mat[i] = f * H[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_hortrapezoid(int np, double *pts1, double *pts2, double *mat) {
|
||||
const int np3 = np * 3;
|
||||
double *a = (double *)aom_malloc(sizeof(*a) * np3 * 14);
|
||||
double *U = a + np3 * 7;
|
||||
double S[7], V[7 * 7], H[9];
|
||||
int i, mini;
|
||||
double sx, sy, dx, dy;
|
||||
double T1[9], T2[9];
|
||||
|
||||
normalize_homography(pts1, np, T1);
|
||||
normalize_homography(pts2, np, T2);
|
||||
|
||||
for (i = 0; i < np; ++i) {
|
||||
dx = *(pts2++);
|
||||
dy = *(pts2++);
|
||||
sx = *(pts1++);
|
||||
sy = *(pts1++);
|
||||
|
||||
a[i * 3 * 7 + 0] = a[i * 3 * 7 + 1] = a[i * 3 * 7 + 2] = 0;
|
||||
a[i * 3 * 7 + 3] = -sy;
|
||||
a[i * 3 * 7 + 4] = -1;
|
||||
a[i * 3 * 7 + 5] = dy * sy;
|
||||
a[i * 3 * 7 + 6] = dy;
|
||||
|
||||
a[(i * 3 + 1) * 7 + 0] = sx;
|
||||
a[(i * 3 + 1) * 7 + 1] = sy;
|
||||
a[(i * 3 + 1) * 7 + 2] = 1;
|
||||
a[(i * 3 + 1) * 7 + 3] = a[(i * 3 + 1) * 7 + 4] = 0;
|
||||
a[(i * 3 + 1) * 7 + 5] = -dx * sy;
|
||||
a[(i * 3 + 1) * 7 + 6] = -dx;
|
||||
|
||||
a[(i * 3 + 2) * 7 + 0] = -dy * sx;
|
||||
a[(i * 3 + 2) * 7 + 1] = -dy * sy;
|
||||
a[(i * 3 + 2) * 7 + 2] = -dy;
|
||||
a[(i * 3 + 2) * 7 + 3] = dx * sy;
|
||||
a[(i * 3 + 2) * 7 + 4] = dx;
|
||||
a[(i * 3 + 2) * 7 + 5] = a[(i * 3 + 2) * 7 + 6] = 0;
|
||||
}
|
||||
|
||||
if (SVD(U, S, V, a, np3, 7)) {
|
||||
aom_free(a);
|
||||
return 1;
|
||||
} else {
|
||||
double minS = 1e12;
|
||||
mini = -1;
|
||||
for (i = 0; i < 7; ++i) {
|
||||
if (S[i] < minS) {
|
||||
minS = S[i];
|
||||
mini = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
H[3] = H[6] = 0;
|
||||
for (i = 0; i < 3; i++) H[i] = V[i * 7 + mini];
|
||||
for (; i < 5; i++) H[i + 1] = V[i * 7 + mini];
|
||||
for (; i < 7; i++) H[i + 2] = V[i * 7 + mini];
|
||||
|
||||
denormalize_homography_reorder(H, T1, T2);
|
||||
aom_free(a);
|
||||
if (H[8] == 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
// normalize
|
||||
double f = 1.0 / H[8];
|
||||
for (i = 0; i < 8; i++) mat[i] = f * H[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_homography(int np, double *pts1, double *pts2, double *mat) {
|
||||
// Implemented from Peter Kovesi's normalized implementation
|
||||
const int np3 = np * 3;
|
||||
double *a = (double *)aom_malloc(sizeof(*a) * np3 * 18);
|
||||
double *U = a + np3 * 9;
|
||||
double S[9], V[9 * 9], H[9];
|
||||
int i, mini;
|
||||
double sx, sy, dx, dy;
|
||||
double T1[9], T2[9];
|
||||
|
||||
normalize_homography(pts1, np, T1);
|
||||
normalize_homography(pts2, np, T2);
|
||||
|
||||
for (i = 0; i < np; ++i) {
|
||||
dx = *(pts2++);
|
||||
dy = *(pts2++);
|
||||
sx = *(pts1++);
|
||||
sy = *(pts1++);
|
||||
|
||||
a[i * 3 * 9 + 0] = a[i * 3 * 9 + 1] = a[i * 3 * 9 + 2] = 0;
|
||||
a[i * 3 * 9 + 3] = -sx;
|
||||
a[i * 3 * 9 + 4] = -sy;
|
||||
a[i * 3 * 9 + 5] = -1;
|
||||
a[i * 3 * 9 + 6] = dy * sx;
|
||||
a[i * 3 * 9 + 7] = dy * sy;
|
||||
a[i * 3 * 9 + 8] = dy;
|
||||
|
||||
a[(i * 3 + 1) * 9 + 0] = sx;
|
||||
a[(i * 3 + 1) * 9 + 1] = sy;
|
||||
a[(i * 3 + 1) * 9 + 2] = 1;
|
||||
a[(i * 3 + 1) * 9 + 3] = a[(i * 3 + 1) * 9 + 4] = a[(i * 3 + 1) * 9 + 5] =
|
||||
0;
|
||||
a[(i * 3 + 1) * 9 + 6] = -dx * sx;
|
||||
a[(i * 3 + 1) * 9 + 7] = -dx * sy;
|
||||
a[(i * 3 + 1) * 9 + 8] = -dx;
|
||||
|
||||
a[(i * 3 + 2) * 9 + 0] = -dy * sx;
|
||||
a[(i * 3 + 2) * 9 + 1] = -dy * sy;
|
||||
a[(i * 3 + 2) * 9 + 2] = -dy;
|
||||
a[(i * 3 + 2) * 9 + 3] = dx * sx;
|
||||
a[(i * 3 + 2) * 9 + 4] = dx * sy;
|
||||
a[(i * 3 + 2) * 9 + 5] = dx;
|
||||
a[(i * 3 + 2) * 9 + 6] = a[(i * 3 + 2) * 9 + 7] = a[(i * 3 + 2) * 9 + 8] =
|
||||
0;
|
||||
}
|
||||
|
||||
if (SVD(U, S, V, a, np3, 9)) {
|
||||
aom_free(a);
|
||||
return 1;
|
||||
} else {
|
||||
double minS = 1e12;
|
||||
mini = -1;
|
||||
for (i = 0; i < 9; ++i) {
|
||||
if (S[i] < minS) {
|
||||
minS = S[i];
|
||||
mini = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; i++) H[i] = V[i * 9 + mini];
|
||||
denormalize_homography_reorder(H, T1, T2);
|
||||
aom_free(a);
|
||||
if (H[8] == 0.0) {
|
||||
return 1;
|
||||
} else {
|
||||
// normalize
|
||||
double f = 1.0 / H[8];
|
||||
for (i = 0; i < 8; i++) mat[i] = f * H[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_rand_indices(int npoints, int minpts, int *indices,
|
||||
unsigned int *seed) {
|
||||
int i, j;
|
||||
|
|
@ -860,11 +579,6 @@ static int is_degenerate_affine(double *p) {
|
|||
return is_collinear3(p, p + 2, p + 4);
|
||||
}
|
||||
|
||||
static int is_degenerate_homography(double *p) {
|
||||
return is_collinear3(p, p + 2, p + 4) || is_collinear3(p, p + 2, p + 6) ||
|
||||
is_collinear3(p, p + 4, p + 6) || is_collinear3(p + 2, p + 4, p + 6);
|
||||
}
|
||||
|
||||
int ransac_translation(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_desired_motions) {
|
||||
|
|
@ -887,30 +601,3 @@ int ransac_affine(int *matched_points, int npoints, int *num_inliers_by_motion,
|
|||
params_by_motion, num_desired_motions, 3, is_degenerate_affine,
|
||||
find_affine, project_points_double_affine);
|
||||
}
|
||||
|
||||
int ransac_homography(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_desired_motions) {
|
||||
return ransac(matched_points, npoints, num_inliers_by_motion,
|
||||
params_by_motion, num_desired_motions, 4,
|
||||
is_degenerate_homography, find_homography,
|
||||
project_points_double_homography);
|
||||
}
|
||||
|
||||
int ransac_hortrapezoid(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_desired_motions) {
|
||||
return ransac(matched_points, npoints, num_inliers_by_motion,
|
||||
params_by_motion, num_desired_motions, 4,
|
||||
is_degenerate_homography, find_hortrapezoid,
|
||||
project_points_double_hortrapezoid);
|
||||
}
|
||||
|
||||
int ransac_vertrapezoid(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_desired_motions) {
|
||||
return ransac(matched_points, npoints, num_inliers_by_motion,
|
||||
params_by_motion, num_desired_motions, 4,
|
||||
is_degenerate_homography, find_vertrapezoid,
|
||||
project_points_double_vertrapezoid);
|
||||
}
|
||||
|
|
|
|||
9
third_party/aom/av1/encoder/ransac.h
vendored
9
third_party/aom/av1/encoder/ransac.h
vendored
|
|
@ -25,17 +25,8 @@ typedef int (*RansacFunc)(int *matched_points, int npoints,
|
|||
|
||||
/* Each of these functions fits a motion model from a set of
|
||||
corresponding points in 2 frames using RANSAC. */
|
||||
int ransac_homography(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_motions);
|
||||
int ransac_affine(int *matched_points, int npoints, int *num_inliers_by_motion,
|
||||
double *params_by_motion, int num_motions);
|
||||
int ransac_hortrapezoid(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_motions);
|
||||
int ransac_vertrapezoid(int *matched_points, int npoints,
|
||||
int *num_inliers_by_motion, double *params_by_motion,
|
||||
int num_motions);
|
||||
int ransac_rotzoom(int *matched_points, int npoints, int *num_inliers_by_motion,
|
||||
double *params_by_motion, int num_motions);
|
||||
int ransac_translation(int *matched_points, int npoints,
|
||||
|
|
|
|||
161
third_party/aom/av1/encoder/ratectrl.c
vendored
161
third_party/aom/av1/encoder/ratectrl.c
vendored
|
|
@ -44,7 +44,6 @@
|
|||
#define MAX_BPB_FACTOR 50
|
||||
|
||||
#define FRAME_OVERHEAD_BITS 200
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
#define ASSIGN_MINQ_TABLE(bit_depth, name) \
|
||||
do { \
|
||||
switch (bit_depth) { \
|
||||
|
|
@ -58,13 +57,6 @@
|
|||
name = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define ASSIGN_MINQ_TABLE(bit_depth, name) \
|
||||
do { \
|
||||
(void)bit_depth; \
|
||||
name = name##_8; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// Tables relating active max Q to active min Q
|
||||
static int kf_low_motion_minq_8[QINDEX_RANGE];
|
||||
|
|
@ -74,7 +66,6 @@ static int arfgf_high_motion_minq_8[QINDEX_RANGE];
|
|||
static int inter_minq_8[QINDEX_RANGE];
|
||||
static int rtc_minq_8[QINDEX_RANGE];
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
static int kf_low_motion_minq_10[QINDEX_RANGE];
|
||||
static int kf_high_motion_minq_10[QINDEX_RANGE];
|
||||
static int arfgf_low_motion_minq_10[QINDEX_RANGE];
|
||||
|
|
@ -87,7 +78,6 @@ static int arfgf_low_motion_minq_12[QINDEX_RANGE];
|
|||
static int arfgf_high_motion_minq_12[QINDEX_RANGE];
|
||||
static int inter_minq_12[QINDEX_RANGE];
|
||||
static int rtc_minq_12[QINDEX_RANGE];
|
||||
#endif
|
||||
|
||||
static int gf_high = 2000;
|
||||
static int gf_low = 400;
|
||||
|
|
@ -97,7 +87,6 @@ static int kf_low = 400;
|
|||
// How many times less pixels there are to encode given the current scaling.
|
||||
// Temporary replacement for rcf_mult and rate_thresh_mult.
|
||||
static double resize_rate_factor(const AV1_COMP *cpi, int width, int height) {
|
||||
(void)cpi;
|
||||
return (double)(cpi->oxcf.width * cpi->oxcf.height) / (width * height);
|
||||
}
|
||||
|
||||
|
|
@ -140,33 +129,27 @@ void av1_rc_init_minq_luts(void) {
|
|||
init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8,
|
||||
arfgf_low_motion_minq_8, arfgf_high_motion_minq_8,
|
||||
inter_minq_8, rtc_minq_8, AOM_BITS_8);
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
init_minq_luts(kf_low_motion_minq_10, kf_high_motion_minq_10,
|
||||
arfgf_low_motion_minq_10, arfgf_high_motion_minq_10,
|
||||
inter_minq_10, rtc_minq_10, AOM_BITS_10);
|
||||
init_minq_luts(kf_low_motion_minq_12, kf_high_motion_minq_12,
|
||||
arfgf_low_motion_minq_12, arfgf_high_motion_minq_12,
|
||||
inter_minq_12, rtc_minq_12, AOM_BITS_12);
|
||||
#endif
|
||||
}
|
||||
|
||||
// These functions use formulaic calculations to make playing with the
|
||||
// quantizer tables easier. If necessary they can be replaced by lookup
|
||||
// tables if and when things settle down in the experimental bitstream
|
||||
double av1_convert_qindex_to_q(int qindex, aom_bit_depth_t bit_depth) {
|
||||
// Convert the index to a real Q value (scaled down to match old Q values)
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
// Convert the index to a real Q value (scaled down to match old Q values)
|
||||
switch (bit_depth) {
|
||||
case AOM_BITS_8: return av1_ac_quant(qindex, 0, bit_depth) / 4.0;
|
||||
case AOM_BITS_10: return av1_ac_quant(qindex, 0, bit_depth) / 16.0;
|
||||
case AOM_BITS_12: return av1_ac_quant(qindex, 0, bit_depth) / 64.0;
|
||||
case AOM_BITS_8: return av1_ac_quant_Q3(qindex, 0, bit_depth) / 4.0;
|
||||
case AOM_BITS_10: return av1_ac_quant_Q3(qindex, 0, bit_depth) / 16.0;
|
||||
case AOM_BITS_12: return av1_ac_quant_Q3(qindex, 0, bit_depth) / 64.0;
|
||||
default:
|
||||
assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
|
||||
return -1.0;
|
||||
}
|
||||
#else
|
||||
return av1_ac_quant(qindex, 0, bit_depth) / 4.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int av1_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,
|
||||
|
|
@ -196,12 +179,8 @@ int av1_rc_clamp_pframe_target_size(const AV1_COMP *const cpi, int target) {
|
|||
const AV1EncoderConfig *oxcf = &cpi->oxcf;
|
||||
const int min_frame_target =
|
||||
AOMMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
|
||||
// Clip the frame target to the minimum setup value.
|
||||
#if CONFIG_EXT_REFS
|
||||
// Clip the frame target to the minimum setup value.
|
||||
if (cpi->rc.is_src_frame_alt_ref) {
|
||||
#else
|
||||
if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
|
||||
#endif // CONFIG_EXT_REFS
|
||||
// If there is an active ARF at this location use the minimum
|
||||
// bits on this frame even if it is a constructed arf.
|
||||
// The active maximum quantizer insures that an appropriate
|
||||
|
|
@ -239,14 +218,10 @@ static void update_buffer_level(AV1_COMP *cpi, int encoded_frame_size) {
|
|||
const AV1_COMMON *const cm = &cpi->common;
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
|
||||
// Non-viewable frames are a special case and are treated as pure overhead.
|
||||
#if CONFIG_EXT_REFS
|
||||
// Non-viewable frames are a special case and are treated as pure overhead.
|
||||
// TODO(zoeliu): To further explore whether we should treat BWDREF_FRAME
|
||||
// differently, since it is a no-show frame.
|
||||
if (!cm->show_frame && !rc->is_bwd_ref_frame)
|
||||
#else
|
||||
if (!cm->show_frame)
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rc->bits_off_target -= encoded_frame_size;
|
||||
else
|
||||
rc->bits_off_target += rc->avg_frame_bandwidth - encoded_frame_size;
|
||||
|
|
@ -590,11 +565,9 @@ static int calc_active_worst_quality_one_pass_vbr(const AV1_COMP *cpi) {
|
|||
active_worst_quality =
|
||||
curr_frame == 0 ? rc->worst_quality : rc->last_q[KEY_FRAME] * 2;
|
||||
} else {
|
||||
if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_alt2_ref_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->refresh_alt_ref_frame)) {
|
||||
if (!rc->is_src_frame_alt_ref &&
|
||||
(cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
|
||||
cpi->refresh_alt_ref_frame)) {
|
||||
active_worst_quality = curr_frame == 1 ? rc->last_q[KEY_FRAME] * 5 / 4
|
||||
: rc->last_q[INTER_FRAME];
|
||||
} else {
|
||||
|
|
@ -931,26 +904,9 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const AV1_COMP *cpi, int width,
|
|||
}
|
||||
|
||||
int av1_frame_type_qdelta(const AV1_COMP *cpi, int rf_level, int q) {
|
||||
static const double rate_factor_deltas[RATE_FACTOR_LEVELS] = {
|
||||
1.00, // INTER_NORMAL
|
||||
#if CONFIG_EXT_REFS
|
||||
0.80, // INTER_LOW
|
||||
1.50, // INTER_HIGH
|
||||
1.25, // GF_ARF_LOW
|
||||
#else
|
||||
1.00, // INTER_HIGH
|
||||
1.50, // GF_ARF_LOW
|
||||
#endif // CONFIG_EXT_REFS
|
||||
2.00, // GF_ARF_STD
|
||||
2.00, // KF_STD
|
||||
static const FRAME_TYPE frame_type[RATE_FACTOR_LEVELS] = {
|
||||
INTER_FRAME, INTER_FRAME, INTER_FRAME, INTER_FRAME, INTER_FRAME, KEY_FRAME
|
||||
};
|
||||
static const FRAME_TYPE frame_type[RATE_FACTOR_LEVELS] =
|
||||
#if CONFIG_EXT_REFS
|
||||
{ INTER_FRAME, INTER_FRAME, INTER_FRAME,
|
||||
INTER_FRAME, INTER_FRAME, KEY_FRAME };
|
||||
#else
|
||||
{ INTER_FRAME, INTER_FRAME, INTER_FRAME, INTER_FRAME, KEY_FRAME };
|
||||
#endif // CONFIG_EXT_REFS
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
int qdelta =
|
||||
av1_compute_qdelta_by_rate(&cpi->rc, frame_type[rf_level], q,
|
||||
|
|
@ -1020,11 +976,9 @@ static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width,
|
|||
active_best_quality +=
|
||||
av1_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth);
|
||||
}
|
||||
} else if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_alt2_ref_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->refresh_alt_ref_frame)) {
|
||||
} else if (!rc->is_src_frame_alt_ref &&
|
||||
(cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
|
||||
cpi->refresh_alt_ref_frame)) {
|
||||
// Use the lower of active_worst_quality and recent
|
||||
// average Q as basis for GF/ARF best Q limit unless last frame was
|
||||
// a key frame.
|
||||
|
|
@ -1044,11 +998,7 @@ static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width,
|
|||
active_best_quality = active_best_quality * 15 / 16;
|
||||
|
||||
} else if (oxcf->rc_mode == AOM_Q) {
|
||||
#if CONFIG_EXT_REFS
|
||||
if (!cpi->refresh_alt_ref_frame && !cpi->refresh_alt2_ref_frame) {
|
||||
#else
|
||||
if (!cpi->refresh_alt_ref_frame) {
|
||||
#endif // CONFIG_EXT_REFS
|
||||
active_best_quality = cq_level;
|
||||
} else {
|
||||
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
|
||||
|
|
@ -1080,11 +1030,9 @@ static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width,
|
|||
if ((cpi->oxcf.rc_mode != AOM_Q) &&
|
||||
(cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD)) {
|
||||
if (frame_is_intra_only(cm) ||
|
||||
(!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_alt2_ref_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->refresh_alt_ref_frame))) {
|
||||
(!rc->is_src_frame_alt_ref &&
|
||||
(cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
|
||||
cpi->refresh_alt_ref_frame))) {
|
||||
active_best_quality -=
|
||||
(cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast);
|
||||
active_worst_quality += (cpi->twopass.extend_maxq / 2);
|
||||
|
|
@ -1106,7 +1054,7 @@ static int rc_pick_q_and_bounds_two_pass(const AV1_COMP *cpi, int width,
|
|||
}
|
||||
|
||||
// Modify active_best_quality for downscaled normal frames.
|
||||
if (!av1_frame_unscaled(cm) && !frame_is_kf_gf_arf(cpi)) {
|
||||
if (av1_frame_scaled(cm) && !frame_is_kf_gf_arf(cpi)) {
|
||||
int qdelta = av1_compute_qdelta_by_rate(
|
||||
rc, cm->frame_type, active_best_quality, 2.0, cm->bit_depth);
|
||||
active_best_quality =
|
||||
|
|
@ -1193,7 +1141,7 @@ static void rc_set_frame_target(AV1_COMP *cpi, int target, int width,
|
|||
rc->this_frame_target = target;
|
||||
|
||||
// Modify frame size target when down-scaled.
|
||||
if (!av1_frame_unscaled(cm))
|
||||
if (av1_frame_scaled(cm))
|
||||
rc->this_frame_target =
|
||||
(int)(rc->this_frame_target * resize_rate_factor(cpi, width, height));
|
||||
|
||||
|
|
@ -1217,21 +1165,13 @@ static void update_alt_ref_frame_stats(AV1_COMP *cpi) {
|
|||
static void update_golden_frame_stats(AV1_COMP *cpi) {
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
// Update the Golden frame usage counts.
|
||||
// NOTE(weitinglin): If we use show_existing_frame for an OVERLAY frame,
|
||||
// only the virtual indices for the reference frame will be
|
||||
// updated and cpi->refresh_golden_frame will still be zero.
|
||||
if (cpi->refresh_golden_frame || rc->is_src_frame_alt_ref) {
|
||||
#else // !CONFIG_EXT_REFS
|
||||
// Update the Golden frame usage counts.
|
||||
if (cpi->refresh_golden_frame) {
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
// We will not use internal overlay frames to replace the golden frame
|
||||
if (!rc->is_src_frame_ext_arf)
|
||||
#endif // CONFIG_EXT_REFS
|
||||
// this frame refreshes means next frames don't unless specified by user
|
||||
rc->frames_since_golden = 0;
|
||||
|
||||
|
|
@ -1248,11 +1188,7 @@ static void update_golden_frame_stats(AV1_COMP *cpi) {
|
|||
// Decrement count down till next gf
|
||||
if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
} else if (!cpi->refresh_alt_ref_frame && !cpi->refresh_alt2_ref_frame) {
|
||||
#else
|
||||
} else if (!cpi->refresh_alt_ref_frame) {
|
||||
#endif // CONFIG_EXT_REFS
|
||||
// Decrement count down till next gf
|
||||
if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
|
||||
|
||||
|
|
@ -1282,10 +1218,7 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
|||
ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2);
|
||||
} else {
|
||||
if (!rc->is_src_frame_alt_ref &&
|
||||
!(cpi->refresh_golden_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_alt2_ref_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
!(cpi->refresh_golden_frame || cpi->refresh_alt2_ref_frame ||
|
||||
cpi->refresh_alt_ref_frame)) {
|
||||
rc->last_q[INTER_FRAME] = qindex;
|
||||
rc->avg_frame_qindex[INTER_FRAME] =
|
||||
|
|
@ -1307,10 +1240,7 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
|||
// This is used to help set quality in forced key frames to reduce popping
|
||||
if ((qindex < rc->last_boosted_qindex) || (cm->frame_type == KEY_FRAME) ||
|
||||
(!rc->constrained_gf_group &&
|
||||
(cpi->refresh_alt_ref_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_alt2_ref_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(cpi->refresh_alt_ref_frame || cpi->refresh_alt2_ref_frame ||
|
||||
(cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) {
|
||||
rc->last_boosted_qindex = qindex;
|
||||
}
|
||||
|
|
@ -1320,7 +1250,7 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
|||
|
||||
// Rolling monitors of whether we are over or underspending used to help
|
||||
// regulate min and Max Q in two pass.
|
||||
if (!av1_frame_unscaled(cm))
|
||||
if (av1_frame_scaled(cm))
|
||||
rc->this_frame_target =
|
||||
(int)(rc->this_frame_target /
|
||||
resize_rate_factor(cpi, cm->width, cm->height));
|
||||
|
|
@ -1337,14 +1267,10 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
|||
|
||||
// Actual bits spent
|
||||
rc->total_actual_bits += rc->projected_frame_size;
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(zoeliu): To investigate whether we should treat BWDREF_FRAME
|
||||
// differently here for rc->avg_frame_bandwidth.
|
||||
rc->total_target_bits +=
|
||||
(cm->show_frame || rc->is_bwd_ref_frame) ? rc->avg_frame_bandwidth : 0;
|
||||
#else
|
||||
rc->total_target_bits += cm->show_frame ? rc->avg_frame_bandwidth : 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
|
||||
|
||||
|
|
@ -1358,13 +1284,9 @@ void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
|
|||
|
||||
if (cm->frame_type == KEY_FRAME) rc->frames_since_key = 0;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(zoeliu): To investigate whether we should treat BWDREF_FRAME
|
||||
// differently here for rc->avg_frame_bandwidth.
|
||||
if (cm->show_frame || rc->is_bwd_ref_frame) {
|
||||
#else
|
||||
if (cm->show_frame) {
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rc->frames_since_key++;
|
||||
rc->frames_to_key--;
|
||||
}
|
||||
|
|
@ -1417,6 +1339,10 @@ void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi) {
|
|||
AV1_COMMON *const cm = &cpi->common;
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
int target;
|
||||
int altref_enabled = is_altref_enabled(cpi);
|
||||
int sframe_dist = cpi->oxcf.sframe_dist;
|
||||
int sframe_mode = cpi->oxcf.sframe_mode;
|
||||
int sframe_enabled = cpi->oxcf.sframe_enabled;
|
||||
// TODO(yaowu): replace the "auto_key && 0" below with proper decision logic.
|
||||
if (!cpi->refresh_alt_ref_frame &&
|
||||
(cm->current_video_frame == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY) ||
|
||||
|
|
@ -1429,6 +1355,37 @@ void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi) {
|
|||
rc->source_alt_ref_active = 0;
|
||||
} else {
|
||||
cm->frame_type = INTER_FRAME;
|
||||
if (sframe_enabled) {
|
||||
if (altref_enabled) {
|
||||
if (sframe_mode == 1) {
|
||||
// sframe_mode == 1: insert sframe if it matches altref frame.
|
||||
|
||||
if (cm->current_video_frame % sframe_dist == 0 &&
|
||||
cm->frame_type != KEY_FRAME && cm->current_video_frame != 0 &&
|
||||
cpi->refresh_alt_ref_frame) {
|
||||
cm->frame_type = S_FRAME;
|
||||
}
|
||||
} else {
|
||||
// sframe_mode != 1: if sframe will be inserted at the next available
|
||||
// altref frame
|
||||
|
||||
if (cm->current_video_frame % sframe_dist == 0 &&
|
||||
cm->frame_type != KEY_FRAME && cm->current_video_frame != 0) {
|
||||
rc->sframe_due = 1;
|
||||
}
|
||||
|
||||
if (rc->sframe_due && cpi->refresh_alt_ref_frame) {
|
||||
cm->frame_type = S_FRAME;
|
||||
rc->sframe_due = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cm->current_video_frame % sframe_dist == 0 &&
|
||||
cm->frame_type != KEY_FRAME && cm->current_video_frame != 0) {
|
||||
cm->frame_type = S_FRAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rc->frames_till_gf_update_due == 0) {
|
||||
rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
|
||||
|
|
@ -1444,6 +1401,10 @@ void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi) {
|
|||
rc->source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
|
||||
rc->gfu_boost = DEFAULT_GF_BOOST;
|
||||
}
|
||||
|
||||
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
||||
av1_cyclic_refresh_update_parameters(cpi);
|
||||
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
target = calc_iframe_target_size_one_pass_vbr(cpi);
|
||||
else
|
||||
|
|
|
|||
25
third_party/aom/av1/encoder/ratectrl.h
vendored
25
third_party/aom/av1/encoder/ratectrl.h
vendored
|
|
@ -28,7 +28,6 @@ extern "C" {
|
|||
#define MAX_GF_INTERVAL 16
|
||||
#define FIXED_GF_INTERVAL 8 // Used in some testing modes only
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
typedef enum {
|
||||
INTER_NORMAL = 0,
|
||||
INTER_LOW = 1,
|
||||
|
|
@ -38,23 +37,20 @@ typedef enum {
|
|||
KF_STD = 5,
|
||||
RATE_FACTOR_LEVELS = 6
|
||||
} RATE_FACTOR_LEVEL;
|
||||
#else
|
||||
typedef enum {
|
||||
INTER_NORMAL = 0,
|
||||
INTER_HIGH = 1,
|
||||
GF_ARF_LOW = 2,
|
||||
GF_ARF_STD = 3,
|
||||
KF_STD = 4,
|
||||
RATE_FACTOR_LEVELS = 5
|
||||
} RATE_FACTOR_LEVEL;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
static const double rate_factor_deltas[RATE_FACTOR_LEVELS] = {
|
||||
1.00, // INTER_NORMAL
|
||||
0.80, // INTER_LOW
|
||||
1.50, // INTER_HIGH
|
||||
1.25, // GF_ARF_LOW
|
||||
2.00, // GF_ARF_STD
|
||||
2.00, // KF_STD
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int resize_width;
|
||||
int resize_height;
|
||||
#if CONFIG_FRAME_SUPERRES
|
||||
uint8_t superres_denom;
|
||||
#endif // CONFIG_FRAME_SUPERRES
|
||||
} size_params_type;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -88,8 +84,8 @@ typedef struct {
|
|||
int source_alt_ref_pending;
|
||||
int source_alt_ref_active;
|
||||
int is_src_frame_alt_ref;
|
||||
int sframe_due;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
// Length of the bi-predictive frame group interval
|
||||
int bipred_group_interval;
|
||||
|
||||
|
|
@ -99,7 +95,6 @@ typedef struct {
|
|||
int is_last_bipred_frame;
|
||||
int is_bipred_frame;
|
||||
int is_src_frame_ext_arf;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
int avg_frame_bandwidth; // Average frame size target for clip
|
||||
int min_frame_bandwidth; // Minimum allocation used for any frame
|
||||
|
|
|
|||
1244
third_party/aom/av1/encoder/ratectrl_xiph.c
vendored
1244
third_party/aom/av1/encoder/ratectrl_xiph.c
vendored
File diff suppressed because it is too large
Load diff
200
third_party/aom/av1/encoder/ratectrl_xiph.h
vendored
200
third_party/aom/av1/encoder/ratectrl_xiph.h
vendored
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2017, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#if !defined(_ratectrl_xiph_H)
|
||||
#define _ratectrl_xiph_H (1)
|
||||
|
||||
#include "av1/encoder/ratectrl.h"
|
||||
#include "aom/internal/aom_codec_internal.h"
|
||||
|
||||
/*Frame types.*/
|
||||
#define OD_I_FRAME (0)
|
||||
#define OD_P_FRAME (1)
|
||||
#define OD_GOLDEN_P_FRAME (2)
|
||||
#define OD_ALTREF_P_FRAME (3)
|
||||
|
||||
#define OD_FRAME_NSUBTYPES (OD_ALTREF_P_FRAME + 1)
|
||||
|
||||
/* Periodic boost (in between golden frames) strength - lower is more */
|
||||
#define OD_PERIODIC_BOOST_DIV (10)
|
||||
|
||||
/* Constants for frame QP modulation <- tweak these
|
||||
* Adjusts how the rate control system decides the quantizers per frame
|
||||
* (sub)type */
|
||||
#define OD_MQP_I (0.98)
|
||||
#define OD_MQP_P (1.06)
|
||||
#define OD_MQP_GP (0.99)
|
||||
#define OD_MQP_AP (0.92)
|
||||
#define OD_DQP_I (-2)
|
||||
#define OD_DQP_P (0)
|
||||
#define OD_DQP_GP (-2)
|
||||
#define OD_DQP_AP (-2)
|
||||
|
||||
/*Fractional_coded_quantizer ~=
|
||||
log2(quantizer / (1 << OD_COEFF_SHIFT))*6.307 + 6.235*/
|
||||
/*Base/scale factor for linear quantizer to fractional coded quantizer
|
||||
conversion (6.307 * 2^12) */
|
||||
#define OD_LOG_QUANTIZER_BASE_Q12 (0x0064EB)
|
||||
/*Inverse of above scale factor.*/
|
||||
#define OD_LOG_QUANTIZER_EXP_Q12 (0x000289)
|
||||
/*Offset for linear quantizer to fractional coded quantizer
|
||||
conversion (6.235 * 2^45) */
|
||||
#define OD_LOG_QUANTIZER_OFFSET_Q45 (0x0000C7851EB851ECLL)
|
||||
|
||||
#define OD_RC_2PASS_MAGIC (0x53015641) /* [A, V, 1, S] in little endian */
|
||||
#define OD_RC_2PASS_SUMMARY_SZ (4 + 1 + (4 + 4 + 8) * OD_FRAME_NSUBTYPES)
|
||||
#define OD_RC_2PASS_PACKET_SZ (1 + 4)
|
||||
#define OD_RC_2PASS_MIN (OD_RC_2PASS_PACKET_SZ + OD_RC_2PASS_SUMMARY_SZ)
|
||||
#define OD_RC_2PASS_VERSION (1)
|
||||
|
||||
/*A 2nd order low-pass Bessel follower.
|
||||
We use this for rate control because it has fast reaction time, but is
|
||||
critically damped.*/
|
||||
typedef struct od_iir_bessel2 {
|
||||
int32_t c[2];
|
||||
int64_t g;
|
||||
int32_t x[2];
|
||||
int32_t y[2];
|
||||
} od_iir_bessel2;
|
||||
|
||||
/* The 2-pass metrics associated with a single frame. */
|
||||
typedef struct od_frame_metrics {
|
||||
/*The log base 2 of the scale factor for this frame in Q24 format.*/
|
||||
int64_t log_scale;
|
||||
/*The frame type from pass 1.*/
|
||||
unsigned frame_type : 1;
|
||||
} od_frame_metrics;
|
||||
|
||||
/*Rate control setup and working state information.*/
|
||||
typedef struct od_rc_state {
|
||||
/* Image format */
|
||||
int frame_width;
|
||||
int frame_height;
|
||||
int bit_depth;
|
||||
|
||||
/* Framerate */
|
||||
double framerate;
|
||||
/* Keyframe rate */
|
||||
int keyframe_rate;
|
||||
/* Golden frame period */
|
||||
int goldenframe_rate;
|
||||
/* Altref frame period */
|
||||
int altref_rate;
|
||||
/*The target bit-rate in bits per second.*/
|
||||
int64_t target_bitrate;
|
||||
/* Quality level for non-bitrate-targeting */
|
||||
int quality;
|
||||
/* Copied from oxcf->frame_periodic_boost */
|
||||
int periodic_boosts;
|
||||
/* Max Q */
|
||||
int maxq;
|
||||
/* Min Q */
|
||||
int minq;
|
||||
/* Quantizer to use for the first pass */
|
||||
int firstpass_quant;
|
||||
|
||||
/* 2-pass metrics */
|
||||
od_frame_metrics cur_metrics;
|
||||
|
||||
/* 2-pass state */
|
||||
int64_t scale_sum[OD_FRAME_NSUBTYPES];
|
||||
int nframes[OD_FRAME_NSUBTYPES];
|
||||
|
||||
/* 2-pass bytestream reader/writer context */
|
||||
uint8_t *twopass_buffer;
|
||||
int twopass_buffer_bytes;
|
||||
|
||||
/* Pass 1 stats packet storage */
|
||||
uint8_t firstpass_buffer[OD_RC_2PASS_SUMMARY_SZ];
|
||||
|
||||
/* Every state packet from the first pass in a single buffer */
|
||||
uint8_t *twopass_allframes_buf;
|
||||
size_t twopass_allframes_buf_size;
|
||||
|
||||
/* Actual returned quantizer */
|
||||
int target_quantizer;
|
||||
/*The full-precision, unmodulated quantizer upon which
|
||||
our modulated quantizers are based.*/
|
||||
int base_quantizer;
|
||||
|
||||
/* Increments by 1 for each frame. */
|
||||
int64_t cur_frame;
|
||||
|
||||
/* End of input flag */
|
||||
int end_of_input;
|
||||
/* Closed GOP flag */
|
||||
int closed_gop;
|
||||
/*The number of frames over which to distribute the reservoir usage.*/
|
||||
int reservoir_frame_delay;
|
||||
/*Will we drop frames to meet bitrate target?*/
|
||||
unsigned char drop_frames;
|
||||
/*Do we respect the maximum reservoir fullness?*/
|
||||
unsigned char cap_overflow;
|
||||
/*Can the reservoir go negative?*/
|
||||
unsigned char cap_underflow;
|
||||
/*Two-pass mode state.
|
||||
0 => 1-pass encoding.
|
||||
1 => 1st pass of 2-pass encoding.
|
||||
2 => 2nd pass of 2-pass encoding.*/
|
||||
int twopass_state;
|
||||
/*The log of the number of pixels in a frame in Q57 format.*/
|
||||
int64_t log_npixels;
|
||||
/*The target average bits per frame.*/
|
||||
int64_t bits_per_frame;
|
||||
/*The current bit reservoir fullness (bits available to be used).*/
|
||||
int64_t reservoir_fullness;
|
||||
/*The target buffer fullness.
|
||||
This is where we'd like to be by the last keyframe the appears in the next
|
||||
buf_delay frames.*/
|
||||
int64_t reservoir_target;
|
||||
/*The maximum buffer fullness (total size of the buffer).*/
|
||||
int64_t reservoir_max;
|
||||
/*The log of estimated scale factor for the rate model in Q57 format.*/
|
||||
int64_t log_scale[OD_FRAME_NSUBTYPES];
|
||||
/*The exponent used in the rate model in Q8 format.*/
|
||||
unsigned exp[OD_FRAME_NSUBTYPES];
|
||||
/*The log of an estimated scale factor used to obtain the real framerate, for
|
||||
VFR sources or, e.g., 12 fps content doubled to 24 fps, etc.*/
|
||||
int64_t log_drop_scale[OD_FRAME_NSUBTYPES];
|
||||
/*The total drop count from the previous frame.*/
|
||||
uint32_t prev_drop_count[OD_FRAME_NSUBTYPES];
|
||||
/*Second-order lowpass filters to track scale and VFR/drops.*/
|
||||
od_iir_bessel2 scalefilter[OD_FRAME_NSUBTYPES];
|
||||
od_iir_bessel2 vfrfilter[OD_FRAME_NSUBTYPES];
|
||||
int frame_count[OD_FRAME_NSUBTYPES];
|
||||
int inter_p_delay;
|
||||
int inter_delay_target;
|
||||
/*The total accumulated estimation bias.*/
|
||||
int64_t rate_bias;
|
||||
} od_rc_state;
|
||||
|
||||
int od_enc_rc_init(od_rc_state *rc, int64_t bitrate, int delay_ms);
|
||||
|
||||
int od_enc_rc_select_quantizers_and_lambdas(od_rc_state *rc,
|
||||
int is_golden_frame,
|
||||
int is_altref_frame, int frame_type,
|
||||
int *bottom_idx, int *top_idx);
|
||||
|
||||
/* Returns 1 if the frame should be dropped */
|
||||
int od_enc_rc_update_state(od_rc_state *rc, int64_t bits, int is_golden_frame,
|
||||
int is_altref_frame, int frame_type, int droppable);
|
||||
|
||||
int od_frame_type(od_rc_state *rc, int64_t coding_frame_count, int *is_golden,
|
||||
int *is_altref, int64_t *ip_count);
|
||||
|
||||
int od_enc_rc_resize(od_rc_state *rc);
|
||||
|
||||
int od_enc_rc_2pass_out(od_rc_state *rc, struct aom_codec_pkt_list *pkt_list,
|
||||
int summary);
|
||||
|
||||
int od_enc_rc_2pass_in(od_rc_state *rc);
|
||||
|
||||
#endif
|
||||
1207
third_party/aom/av1/encoder/rd.c
vendored
1207
third_party/aom/av1/encoder/rd.c
vendored
File diff suppressed because it is too large
Load diff
235
third_party/aom/av1/encoder/rd.h
vendored
235
third_party/aom/av1/encoder/rd.h
vendored
|
|
@ -14,9 +14,6 @@
|
|||
|
||||
#include <limits.h>
|
||||
|
||||
#if CONFIG_ANS
|
||||
#include "aom_dsp/ans.h"
|
||||
#endif // CONFIG_ANS
|
||||
#include "av1/common/blockd.h"
|
||||
|
||||
#include "av1/encoder/block.h"
|
||||
|
|
@ -30,9 +27,9 @@ extern "C" {
|
|||
#define RDDIV_BITS 7
|
||||
#define RD_EPB_SHIFT 6
|
||||
|
||||
#define RDCOST(RM, R, D) \
|
||||
(ROUND_POWER_OF_TWO(((int64_t)R) * (RM), AV1_PROB_COST_SHIFT) + \
|
||||
(D << RDDIV_BITS))
|
||||
#define RDCOST(RM, R, D) \
|
||||
(ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), AV1_PROB_COST_SHIFT) + \
|
||||
((D) * (1 << RDDIV_BITS)))
|
||||
|
||||
#define RDCOST_DBL(RM, R, D) \
|
||||
(((((double)(R)) * (RM)) / (double)(1 << AV1_PROB_COST_SHIFT)) + \
|
||||
|
|
@ -50,102 +47,43 @@ extern "C" {
|
|||
// const MODE_DEFINITION av1_mode_order[MAX_MODES] used in the rd code.
|
||||
typedef enum {
|
||||
THR_NEARESTMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEARESTL2,
|
||||
THR_NEARESTL3,
|
||||
THR_NEARESTB,
|
||||
THR_NEARESTA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEARESTA,
|
||||
THR_NEARESTG,
|
||||
|
||||
THR_DC,
|
||||
|
||||
THR_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEWL2,
|
||||
THR_NEWL3,
|
||||
THR_NEWB,
|
||||
THR_NEWA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEWA,
|
||||
THR_NEWG,
|
||||
|
||||
THR_NEARMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEARL2,
|
||||
THR_NEARL3,
|
||||
THR_NEARB,
|
||||
THR_NEARA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEARA,
|
||||
THR_NEARG,
|
||||
|
||||
THR_ZEROMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_ZEROL2,
|
||||
THR_ZEROL3,
|
||||
THR_ZEROB,
|
||||
THR_ZEROA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_ZEROA,
|
||||
THR_ZEROG,
|
||||
|
||||
#if CONFIG_COMPOUND_SINGLEREF
|
||||
THR_SR_NEAREST_NEARMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_SR_NEAREST_NEARL2,
|
||||
THR_SR_NEAREST_NEARL3,
|
||||
THR_SR_NEAREST_NEARB,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_SR_NEAREST_NEARG,
|
||||
THR_SR_NEAREST_NEARA,
|
||||
|
||||
/*
|
||||
THR_SR_NEAREST_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_SR_NEAREST_NEWL2,
|
||||
THR_SR_NEAREST_NEWL3,
|
||||
THR_SR_NEAREST_NEWB,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_SR_NEAREST_NEWG,
|
||||
THR_SR_NEAREST_NEWA,*/
|
||||
|
||||
THR_SR_NEAR_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_SR_NEAR_NEWL2,
|
||||
THR_SR_NEAR_NEWL3,
|
||||
THR_SR_NEAR_NEWB,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_SR_NEAR_NEWG,
|
||||
THR_SR_NEAR_NEWA,
|
||||
|
||||
THR_SR_ZERO_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_SR_ZERO_NEWL2,
|
||||
THR_SR_ZERO_NEWL3,
|
||||
THR_SR_ZERO_NEWB,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_SR_ZERO_NEWG,
|
||||
THR_SR_ZERO_NEWA,
|
||||
|
||||
THR_SR_NEW_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_SR_NEW_NEWL2,
|
||||
THR_SR_NEW_NEWL3,
|
||||
THR_SR_NEW_NEWB,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_SR_NEW_NEWG,
|
||||
THR_SR_NEW_NEWA,
|
||||
#endif // CONFIG_COMPOUND_SINGLEREF
|
||||
THR_GLOBALMV,
|
||||
THR_GLOBALL2,
|
||||
THR_GLOBALL3,
|
||||
THR_GLOBALB,
|
||||
THR_GLOBALA2,
|
||||
THR_GLOBALA,
|
||||
THR_GLOBALG,
|
||||
|
||||
THR_COMP_NEAREST_NEARESTLA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEAREST_NEARESTL2A,
|
||||
THR_COMP_NEAREST_NEARESTL3A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_NEAREST_NEARESTGA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEAREST_NEARESTLB,
|
||||
THR_COMP_NEAREST_NEARESTL2B,
|
||||
THR_COMP_NEAREST_NEARESTL3B,
|
||||
|
|
@ -154,21 +92,16 @@ typedef enum {
|
|||
THR_COMP_NEAREST_NEARESTL2A2,
|
||||
THR_COMP_NEAREST_NEARESTL3A2,
|
||||
THR_COMP_NEAREST_NEARESTGA2,
|
||||
#if CONFIG_EXT_COMP_REFS
|
||||
THR_COMP_NEAREST_NEARESTLL2,
|
||||
THR_COMP_NEAREST_NEARESTLL3,
|
||||
THR_COMP_NEAREST_NEARESTLG,
|
||||
THR_COMP_NEAREST_NEARESTBA,
|
||||
#endif // CONFIG_EXT_COMP_REFS
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
THR_TM,
|
||||
THR_PAETH,
|
||||
|
||||
THR_SMOOTH,
|
||||
#if CONFIG_SMOOTH_HV
|
||||
THR_SMOOTH_V,
|
||||
THR_SMOOTH_H,
|
||||
#endif // CONFIG_SMOOTH_HV
|
||||
|
||||
THR_COMP_NEAR_NEARLA,
|
||||
THR_COMP_NEW_NEARESTLA,
|
||||
|
|
@ -176,16 +109,15 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARLA,
|
||||
THR_COMP_NEAR_NEWLA,
|
||||
THR_COMP_NEW_NEWLA,
|
||||
THR_COMP_ZERO_ZEROLA,
|
||||
THR_COMP_GLOBAL_GLOBALLA,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEAR_NEARL2A,
|
||||
THR_COMP_NEW_NEARESTL2A,
|
||||
THR_COMP_NEAREST_NEWL2A,
|
||||
THR_COMP_NEW_NEARL2A,
|
||||
THR_COMP_NEAR_NEWL2A,
|
||||
THR_COMP_NEW_NEWL2A,
|
||||
THR_COMP_ZERO_ZEROL2A,
|
||||
THR_COMP_GLOBAL_GLOBALL2A,
|
||||
|
||||
THR_COMP_NEAR_NEARL3A,
|
||||
THR_COMP_NEW_NEARESTL3A,
|
||||
|
|
@ -193,8 +125,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARL3A,
|
||||
THR_COMP_NEAR_NEWL3A,
|
||||
THR_COMP_NEW_NEWL3A,
|
||||
THR_COMP_ZERO_ZEROL3A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_GLOBAL_GLOBALL3A,
|
||||
|
||||
THR_COMP_NEAR_NEARGA,
|
||||
THR_COMP_NEW_NEARESTGA,
|
||||
|
|
@ -202,16 +133,15 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARGA,
|
||||
THR_COMP_NEAR_NEWGA,
|
||||
THR_COMP_NEW_NEWGA,
|
||||
THR_COMP_ZERO_ZEROGA,
|
||||
THR_COMP_GLOBAL_GLOBALGA,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEAR_NEARLB,
|
||||
THR_COMP_NEW_NEARESTLB,
|
||||
THR_COMP_NEAREST_NEWLB,
|
||||
THR_COMP_NEW_NEARLB,
|
||||
THR_COMP_NEAR_NEWLB,
|
||||
THR_COMP_NEW_NEWLB,
|
||||
THR_COMP_ZERO_ZEROLB,
|
||||
THR_COMP_GLOBAL_GLOBALLB,
|
||||
|
||||
THR_COMP_NEAR_NEARL2B,
|
||||
THR_COMP_NEW_NEARESTL2B,
|
||||
|
|
@ -219,7 +149,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARL2B,
|
||||
THR_COMP_NEAR_NEWL2B,
|
||||
THR_COMP_NEW_NEWL2B,
|
||||
THR_COMP_ZERO_ZEROL2B,
|
||||
THR_COMP_GLOBAL_GLOBALL2B,
|
||||
|
||||
THR_COMP_NEAR_NEARL3B,
|
||||
THR_COMP_NEW_NEARESTL3B,
|
||||
|
|
@ -227,7 +157,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARL3B,
|
||||
THR_COMP_NEAR_NEWL3B,
|
||||
THR_COMP_NEW_NEWL3B,
|
||||
THR_COMP_ZERO_ZEROL3B,
|
||||
THR_COMP_GLOBAL_GLOBALL3B,
|
||||
|
||||
THR_COMP_NEAR_NEARGB,
|
||||
THR_COMP_NEW_NEARESTGB,
|
||||
|
|
@ -235,7 +165,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARGB,
|
||||
THR_COMP_NEAR_NEWGB,
|
||||
THR_COMP_NEW_NEWGB,
|
||||
THR_COMP_ZERO_ZEROGB,
|
||||
THR_COMP_GLOBAL_GLOBALGB,
|
||||
|
||||
THR_COMP_NEAR_NEARLA2,
|
||||
THR_COMP_NEW_NEARESTLA2,
|
||||
|
|
@ -243,7 +173,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARLA2,
|
||||
THR_COMP_NEAR_NEWLA2,
|
||||
THR_COMP_NEW_NEWLA2,
|
||||
THR_COMP_ZERO_ZEROLA2,
|
||||
THR_COMP_GLOBAL_GLOBALLA2,
|
||||
|
||||
THR_COMP_NEAR_NEARL2A2,
|
||||
THR_COMP_NEW_NEARESTL2A2,
|
||||
|
|
@ -251,7 +181,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARL2A2,
|
||||
THR_COMP_NEAR_NEWL2A2,
|
||||
THR_COMP_NEW_NEWL2A2,
|
||||
THR_COMP_ZERO_ZEROL2A2,
|
||||
THR_COMP_GLOBAL_GLOBALL2A2,
|
||||
|
||||
THR_COMP_NEAR_NEARL3A2,
|
||||
THR_COMP_NEW_NEARESTL3A2,
|
||||
|
|
@ -259,7 +189,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARL3A2,
|
||||
THR_COMP_NEAR_NEWL3A2,
|
||||
THR_COMP_NEW_NEWL3A2,
|
||||
THR_COMP_ZERO_ZEROL3A2,
|
||||
THR_COMP_GLOBAL_GLOBALL3A2,
|
||||
|
||||
THR_COMP_NEAR_NEARGA2,
|
||||
THR_COMP_NEW_NEARESTGA2,
|
||||
|
|
@ -267,16 +197,24 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARGA2,
|
||||
THR_COMP_NEAR_NEWGA2,
|
||||
THR_COMP_NEW_NEWGA2,
|
||||
THR_COMP_ZERO_ZEROGA2,
|
||||
THR_COMP_GLOBAL_GLOBALGA2,
|
||||
|
||||
THR_H_PRED,
|
||||
THR_V_PRED,
|
||||
THR_D135_PRED,
|
||||
THR_D203_PRED,
|
||||
THR_D157_PRED,
|
||||
THR_D67_PRED,
|
||||
THR_D113_PRED,
|
||||
THR_D45_PRED,
|
||||
|
||||
#if CONFIG_EXT_COMP_REFS
|
||||
THR_COMP_NEAR_NEARLL2,
|
||||
THR_COMP_NEW_NEARESTLL2,
|
||||
THR_COMP_NEAREST_NEWLL2,
|
||||
THR_COMP_NEW_NEARLL2,
|
||||
THR_COMP_NEAR_NEWLL2,
|
||||
THR_COMP_NEW_NEWLL2,
|
||||
THR_COMP_ZERO_ZEROLL2,
|
||||
THR_COMP_GLOBAL_GLOBALLL2,
|
||||
|
||||
THR_COMP_NEAR_NEARLL3,
|
||||
THR_COMP_NEW_NEARESTLL3,
|
||||
|
|
@ -284,7 +222,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARLL3,
|
||||
THR_COMP_NEAR_NEWLL3,
|
||||
THR_COMP_NEW_NEWLL3,
|
||||
THR_COMP_ZERO_ZEROLL3,
|
||||
THR_COMP_GLOBAL_GLOBALLL3,
|
||||
|
||||
THR_COMP_NEAR_NEARLG,
|
||||
THR_COMP_NEW_NEARESTLG,
|
||||
|
|
@ -292,7 +230,7 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARLG,
|
||||
THR_COMP_NEAR_NEWLG,
|
||||
THR_COMP_NEW_NEWLG,
|
||||
THR_COMP_ZERO_ZEROLG,
|
||||
THR_COMP_GLOBAL_GLOBALLG,
|
||||
|
||||
THR_COMP_NEAR_NEARBA,
|
||||
THR_COMP_NEW_NEARESTBA,
|
||||
|
|
@ -300,79 +238,25 @@ typedef enum {
|
|||
THR_COMP_NEW_NEARBA,
|
||||
THR_COMP_NEAR_NEWBA,
|
||||
THR_COMP_NEW_NEWBA,
|
||||
THR_COMP_ZERO_ZEROBA,
|
||||
#endif // CONFIG_EXT_COMP_REFS
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_GLOBAL_GLOBALBA,
|
||||
|
||||
THR_H_PRED,
|
||||
THR_V_PRED,
|
||||
THR_D135_PRED,
|
||||
THR_D207_PRED,
|
||||
THR_D153_PRED,
|
||||
THR_D63_PRED,
|
||||
THR_D117_PRED,
|
||||
THR_D45_PRED,
|
||||
|
||||
THR_COMP_INTERINTRA_ZEROL,
|
||||
THR_COMP_INTERINTRA_NEARESTL,
|
||||
THR_COMP_INTERINTRA_NEARL,
|
||||
THR_COMP_INTERINTRA_NEWL,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_INTERINTRA_ZEROL2,
|
||||
THR_COMP_INTERINTRA_NEARESTL2,
|
||||
THR_COMP_INTERINTRA_NEARL2,
|
||||
THR_COMP_INTERINTRA_NEWL2,
|
||||
|
||||
THR_COMP_INTERINTRA_ZEROL3,
|
||||
THR_COMP_INTERINTRA_NEARESTL3,
|
||||
THR_COMP_INTERINTRA_NEARL3,
|
||||
THR_COMP_INTERINTRA_NEWL3,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
THR_COMP_INTERINTRA_ZEROG,
|
||||
THR_COMP_INTERINTRA_NEARESTG,
|
||||
THR_COMP_INTERINTRA_NEARG,
|
||||
THR_COMP_INTERINTRA_NEWG,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_INTERINTRA_ZEROB,
|
||||
THR_COMP_INTERINTRA_NEARESTB,
|
||||
THR_COMP_INTERINTRA_NEARB,
|
||||
THR_COMP_INTERINTRA_NEWB,
|
||||
|
||||
THR_COMP_INTERINTRA_ZEROA2,
|
||||
THR_COMP_INTERINTRA_NEARESTA2,
|
||||
THR_COMP_INTERINTRA_NEARA2,
|
||||
THR_COMP_INTERINTRA_NEWA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
THR_COMP_INTERINTRA_ZEROA,
|
||||
THR_COMP_INTERINTRA_NEARESTA,
|
||||
THR_COMP_INTERINTRA_NEARA,
|
||||
THR_COMP_INTERINTRA_NEWA,
|
||||
MAX_MODES
|
||||
} THR_MODES;
|
||||
|
||||
typedef enum {
|
||||
THR_LAST,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_LAST2,
|
||||
THR_LAST3,
|
||||
THR_BWDR,
|
||||
THR_ALTR2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_GOLD,
|
||||
THR_ALTR,
|
||||
|
||||
THR_COMP_LA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_L2A,
|
||||
THR_COMP_L3A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_GA,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_LB,
|
||||
THR_COMP_L2B,
|
||||
THR_COMP_L3B,
|
||||
|
|
@ -382,7 +266,6 @@ typedef enum {
|
|||
THR_COMP_L2A2,
|
||||
THR_COMP_L3A2,
|
||||
THR_COMP_GA2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
THR_INTRA,
|
||||
|
||||
|
|
@ -399,7 +282,7 @@ typedef struct RD_OPT {
|
|||
|
||||
int threshes[MAX_SEGMENTS][BLOCK_SIZES_ALL][MAX_MODES];
|
||||
|
||||
int64_t prediction_type_threshes[TOTAL_REFS_PER_FRAME][REFERENCE_MODES];
|
||||
int64_t prediction_type_threshes[REF_FRAMES][REFERENCE_MODES];
|
||||
|
||||
int RDMULT;
|
||||
} RD_OPT;
|
||||
|
|
@ -417,16 +300,16 @@ static INLINE void av1_init_rd_stats(RD_STATS *rd_stats) {
|
|||
rd_stats->invalid_rate = 0;
|
||||
rd_stats->ref_rdcost = INT64_MAX;
|
||||
#if CONFIG_RD_DEBUG
|
||||
// This may run into problems when monochrome video is
|
||||
// encoded, as there will only be 1 plane
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
rd_stats->txb_coeff_cost[plane] = 0;
|
||||
#if CONFIG_VAR_TX
|
||||
{
|
||||
int r, c;
|
||||
for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r)
|
||||
for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c)
|
||||
rd_stats->txb_coeff_cost_map[plane][r][c] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -444,16 +327,16 @@ static INLINE void av1_invalid_rd_stats(RD_STATS *rd_stats) {
|
|||
rd_stats->invalid_rate = 1;
|
||||
rd_stats->ref_rdcost = INT64_MAX;
|
||||
#if CONFIG_RD_DEBUG
|
||||
// This may run into problems when monochrome video is
|
||||
// encoded, as there will only be 1 plane
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
rd_stats->txb_coeff_cost[plane] = INT_MAX;
|
||||
#if CONFIG_VAR_TX
|
||||
{
|
||||
int r, c;
|
||||
for (r = 0; r < TXB_COEFF_COST_MAP_SIZE; ++r)
|
||||
for (c = 0; c < TXB_COEFF_COST_MAP_SIZE; ++c)
|
||||
rd_stats->txb_coeff_cost_map[plane][r][c] = INT_MAX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -464,14 +347,17 @@ static INLINE void av1_merge_rd_stats(RD_STATS *rd_stats_dst,
|
|||
int plane;
|
||||
#endif
|
||||
rd_stats_dst->rate += rd_stats_src->rate;
|
||||
if (!rd_stats_dst->zero_rate)
|
||||
rd_stats_dst->zero_rate = rd_stats_src->zero_rate;
|
||||
rd_stats_dst->dist += rd_stats_src->dist;
|
||||
rd_stats_dst->sse += rd_stats_src->sse;
|
||||
rd_stats_dst->skip &= rd_stats_src->skip;
|
||||
rd_stats_dst->invalid_rate &= rd_stats_src->invalid_rate;
|
||||
#if CONFIG_RD_DEBUG
|
||||
// This may run into problems when monochrome video is
|
||||
// encoded, as there will only be 1 plane
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
rd_stats_dst->txb_coeff_cost[plane] += rd_stats_src->txb_coeff_cost[plane];
|
||||
#if CONFIG_VAR_TX
|
||||
{
|
||||
// TODO(angiebird): optimize this part
|
||||
int r, c;
|
||||
|
|
@ -484,21 +370,10 @@ static INLINE void av1_merge_rd_stats(RD_STATS *rd_stats_dst,
|
|||
}
|
||||
assert(ref_txb_coeff_cost == rd_stats_dst->txb_coeff_cost[plane]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE int av1_get_coeff_token_cost(int token, int eob_val, int is_first,
|
||||
const int *head_cost_table,
|
||||
const int *tail_cost_table) {
|
||||
if (eob_val == LAST_EOB) return av1_cost_zero(128);
|
||||
const int comb_symb = 2 * AOMMIN(token, TWO_TOKEN) - eob_val + is_first;
|
||||
int cost = head_cost_table[comb_symb];
|
||||
if (token > ONE_TOKEN) cost += tail_cost_table[token - TWO_TOKEN];
|
||||
return cost;
|
||||
}
|
||||
|
||||
struct TileInfo;
|
||||
struct TileDataEnc;
|
||||
struct AV1_COMP;
|
||||
|
|
@ -528,13 +403,12 @@ YV12_BUFFER_CONFIG *av1_get_scaled_ref_frame(const struct AV1_COMP *cpi,
|
|||
|
||||
void av1_init_me_luts(void);
|
||||
|
||||
void av1_set_mvcost(MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame, int ref,
|
||||
int ref_mv_idx);
|
||||
void av1_set_mvcost(MACROBLOCK *x, int ref, int ref_mv_idx);
|
||||
|
||||
void av1_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
void av1_get_entropy_contexts(BLOCK_SIZE bsize,
|
||||
const struct macroblockd_plane *pd,
|
||||
ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE],
|
||||
ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE]);
|
||||
ENTROPY_CONTEXT t_above[MAX_MIB_SIZE],
|
||||
ENTROPY_CONTEXT t_left[MAX_MIB_SIZE]);
|
||||
|
||||
void av1_set_rd_speed_thresholds(struct AV1_COMP *cpi);
|
||||
|
||||
|
|
@ -562,7 +436,8 @@ void av1_setup_pred_block(const MACROBLOCKD *xd,
|
|||
struct buf_2d dst[MAX_MB_PLANE],
|
||||
const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
|
||||
const struct scale_factors *scale,
|
||||
const struct scale_factors *scale_uv);
|
||||
const struct scale_factors *scale_uv,
|
||||
const int num_planes);
|
||||
|
||||
int av1_get_intra_cost_penalty(int qindex, int qdelta,
|
||||
aom_bit_depth_t bit_depth);
|
||||
|
|
@ -570,12 +445,8 @@ int av1_get_intra_cost_penalty(int qindex, int qdelta,
|
|||
void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x,
|
||||
FRAME_CONTEXT *fc);
|
||||
|
||||
#if CONFIG_LV_MAP
|
||||
void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc);
|
||||
#endif
|
||||
|
||||
void av1_fill_token_costs_from_cdf(av1_coeff_cost *cost,
|
||||
coeff_cdf_model (*cdf)[PLANE_TYPES]);
|
||||
void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc,
|
||||
const int num_planes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
14831
third_party/aom/av1/encoder/rdopt.c
vendored
14831
third_party/aom/av1/encoder/rdopt.c
vendored
File diff suppressed because it is too large
Load diff
130
third_party/aom/av1/encoder/rdopt.h
vendored
130
third_party/aom/av1/encoder/rdopt.h
vendored
|
|
@ -13,16 +13,20 @@
|
|||
#define AV1_ENCODER_RDOPT_H_
|
||||
|
||||
#include "av1/common/blockd.h"
|
||||
#include "av1/common/txb_common.h"
|
||||
|
||||
#include "av1/encoder/block.h"
|
||||
#include "av1/encoder/context_tree.h"
|
||||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/encodetxb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_REF_MV_SERCH 3
|
||||
|
||||
struct TileInfo;
|
||||
struct AV1_COMP;
|
||||
struct macroblock;
|
||||
struct RD_STATS;
|
||||
|
||||
|
|
@ -35,7 +39,6 @@ static INLINE void av1_update_txb_coeff_cost(RD_STATS *rd_stats, int plane,
|
|||
(void)tx_size;
|
||||
rd_stats->txb_coeff_cost[plane] += txb_coeff_cost;
|
||||
|
||||
#if CONFIG_VAR_TX
|
||||
{
|
||||
const int txb_h = tx_size_high_unit[tx_size];
|
||||
const int txb_w = tx_size_wide_unit[tx_size];
|
||||
|
|
@ -48,113 +51,86 @@ static INLINE void av1_update_txb_coeff_cost(RD_STATS *rd_stats, int plane,
|
|||
}
|
||||
assert(blk_row < TXB_COEFF_COST_MAP_SIZE);
|
||||
assert(blk_col < TXB_COEFF_COST_MAP_SIZE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef enum OUTPUT_STATUS {
|
||||
OUTPUT_HAS_PREDICTED_PIXELS,
|
||||
OUTPUT_HAS_DECODED_PIXELS
|
||||
} OUTPUT_STATUS;
|
||||
|
||||
// Returns the number of colors in 'src'.
|
||||
int av1_count_colors(const uint8_t *src, int stride, int rows, int cols);
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
int av1_count_colors(const uint8_t *src, int stride, int rows, int cols,
|
||||
int *val_count);
|
||||
// Same as av1_count_colors(), but for high-bitdepth mode.
|
||||
int av1_count_colors_highbd(const uint8_t *src8, int stride, int rows, int cols,
|
||||
int bit_depth);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
void av1_dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
||||
BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col,
|
||||
TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse,
|
||||
OUTPUT_STATUS output_status);
|
||||
int bit_depth, int *val_count);
|
||||
|
||||
#if CONFIG_DIST_8X8
|
||||
int64_t av1_dist_8x8(const AV1_COMP *const cpi, const MACROBLOCK *x,
|
||||
int64_t av1_dist_8x8(const struct AV1_COMP *const cpi, const MACROBLOCK *x,
|
||||
const uint8_t *src, int src_stride, const uint8_t *dst,
|
||||
int dst_stride, const BLOCK_SIZE tx_bsize, int bsw,
|
||||
int bsh, int visible_w, int visible_h, int qindex);
|
||||
#endif
|
||||
|
||||
#if !CONFIG_PVQ || CONFIG_VAR_TX
|
||||
int av1_cost_coeffs(const AV1_COMP *const cpi, MACROBLOCK *x, int plane,
|
||||
int blk_row, int blk_col, int block, TX_SIZE tx_size,
|
||||
const SCAN_ORDER *scan_order, const ENTROPY_CONTEXT *a,
|
||||
const ENTROPY_CONTEXT *l, int use_fast_coef_costing);
|
||||
#endif
|
||||
void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
|
||||
struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
|
||||
PICK_MODE_CONTEXT *ctx, int64_t best_rd);
|
||||
static INLINE int av1_cost_skip_txb(MACROBLOCK *x, const TXB_CTX *const txb_ctx,
|
||||
int plane, TX_SIZE tx_size) {
|
||||
const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
|
||||
const PLANE_TYPE plane_type = get_plane_type(plane);
|
||||
const LV_MAP_COEFF_COST *const coeff_costs =
|
||||
&x->coeff_costs[txs_ctx][plane_type];
|
||||
return coeff_costs->txb_skip_cost[txb_ctx->txb_skip_ctx][1];
|
||||
}
|
||||
|
||||
unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
|
||||
static INLINE int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x,
|
||||
int plane, int blk_row, int blk_col,
|
||||
int block, TX_SIZE tx_size,
|
||||
const TXB_CTX *const txb_ctx,
|
||||
int use_fast_coef_costing) {
|
||||
#if TXCOEFF_COST_TIMER
|
||||
struct aom_usec_timer timer;
|
||||
aom_usec_timer_start(&timer);
|
||||
#endif
|
||||
(void)use_fast_coef_costing;
|
||||
const int cost = av1_cost_coeffs_txb(cm, x, plane, blk_row, blk_col, block,
|
||||
tx_size, txb_ctx);
|
||||
#if TXCOEFF_COST_TIMER
|
||||
AV1_COMMON *tmp_cm = (AV1_COMMON *)&cpi->common;
|
||||
aom_usec_timer_mark(&timer);
|
||||
const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
|
||||
tmp_cm->txcoeff_cost_timer += elapsed_time;
|
||||
++tmp_cm->txcoeff_cost_count;
|
||||
#endif
|
||||
return cost;
|
||||
}
|
||||
|
||||
void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
|
||||
int mi_row, int mi_col, struct RD_STATS *rd_cost,
|
||||
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
|
||||
int64_t best_rd);
|
||||
|
||||
unsigned int av1_get_sby_perpixel_variance(const struct AV1_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs);
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
|
||||
unsigned int av1_high_get_sby_perpixel_variance(const struct AV1_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs, int bd);
|
||||
#endif
|
||||
|
||||
void av1_rd_pick_inter_mode_sb(const struct AV1_COMP *cpi,
|
||||
struct TileDataEnc *tile_data,
|
||||
struct macroblock *x, int mi_row, int mi_col,
|
||||
struct RD_STATS *rd_cost,
|
||||
#if CONFIG_SUPERTX
|
||||
int *returnrate_nocoef,
|
||||
#endif // CONFIG_SUPERTX
|
||||
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
|
||||
int64_t best_rd_so_far);
|
||||
struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
|
||||
PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far);
|
||||
|
||||
void av1_rd_pick_inter_mode_sb_seg_skip(
|
||||
const struct AV1_COMP *cpi, struct TileDataEnc *tile_data,
|
||||
struct macroblock *x, int mi_row, int mi_col, struct RD_STATS *rd_cost,
|
||||
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far);
|
||||
|
||||
int av1_internal_image_edge(const struct AV1_COMP *cpi);
|
||||
int av1_active_h_edge(const struct AV1_COMP *cpi, int mi_row, int mi_step);
|
||||
int av1_active_v_edge(const struct AV1_COMP *cpi, int mi_col, int mi_step);
|
||||
int av1_active_edge_sb(const struct AV1_COMP *cpi, int mi_row, int mi_col);
|
||||
|
||||
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
|
||||
void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
|
||||
int mi_row, int mi_col);
|
||||
#endif // CONFIG_MOTION_VAR && CONFIG_NCOBMC
|
||||
|
||||
#if CONFIG_SUPERTX
|
||||
#if CONFIG_VAR_TX
|
||||
void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
|
||||
int blk_row, int blk_col, int plane, int block,
|
||||
int plane_bsize, const ENTROPY_CONTEXT *a,
|
||||
const ENTROPY_CONTEXT *l, RD_STATS *rd_stats);
|
||||
#if CONFIG_COLLECT_INTER_MODE_RD_STATS
|
||||
#define INTER_MODE_RD_TEST 0
|
||||
void av1_inter_mode_data_init();
|
||||
void av1_inter_mode_data_fit(int rdmult);
|
||||
void av1_inter_mode_data_show(const AV1_COMMON *cm);
|
||||
#endif
|
||||
|
||||
void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
|
||||
int64_t *distortion, int *skippable,
|
||||
int64_t *sse, int64_t ref_best_rd, int plane,
|
||||
BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
int use_fast_coef_casting);
|
||||
#endif // CONFIG_SUPERTX
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
int av1_tx_type_cost(const AV1_COMMON *cm, const MACROBLOCK *x,
|
||||
const MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
|
||||
TX_SIZE tx_size, TX_TYPE tx_type);
|
||||
|
||||
int64_t get_prediction_rd_cost(const struct AV1_COMP *cpi, struct macroblock *x,
|
||||
int mi_row, int mi_col, int *skip_blk,
|
||||
MB_MODE_INFO *backup_mbmi);
|
||||
|
||||
#if CONFIG_NCOBMC_ADAPT_WEIGHT
|
||||
void av1_check_ncobmc_adapt_weight_rd(const struct AV1_COMP *cpi,
|
||||
struct macroblock *x, int mi_row,
|
||||
int mi_col);
|
||||
int get_ncobmc_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
|
||||
MACROBLOCKD *xd, int mi_row, int mi_col, int bsize);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_RDOPT_H_
|
||||
|
|
|
|||
277
third_party/aom/av1/encoder/segmentation.c
vendored
277
third_party/aom/av1/encoder/segmentation.c
vendored
|
|
@ -18,26 +18,21 @@
|
|||
|
||||
#include "av1/encoder/cost.h"
|
||||
#include "av1/encoder/segmentation.h"
|
||||
#include "av1/encoder/subexp.h"
|
||||
|
||||
void av1_enable_segmentation(struct segmentation *seg) {
|
||||
seg->enabled = 1;
|
||||
seg->update_map = 1;
|
||||
seg->update_data = 1;
|
||||
seg->temporal_update = 0;
|
||||
}
|
||||
|
||||
void av1_disable_segmentation(struct segmentation *seg) {
|
||||
seg->enabled = 0;
|
||||
seg->update_map = 0;
|
||||
seg->update_data = 0;
|
||||
seg->temporal_update = 0;
|
||||
}
|
||||
|
||||
void av1_set_segment_data(struct segmentation *seg, int8_t *feature_data,
|
||||
unsigned char abs_delta) {
|
||||
seg->abs_delta = abs_delta;
|
||||
|
||||
memcpy(seg->feature_data, feature_data, sizeof(seg->feature_data));
|
||||
}
|
||||
void av1_disable_segfeature(struct segmentation *seg, int segment_id,
|
||||
SEG_LVL_FEATURES feature_id) {
|
||||
seg->feature_mask[segment_id] &= ~(1 << feature_id);
|
||||
|
|
@ -48,76 +43,8 @@ void av1_clear_segdata(struct segmentation *seg, int segment_id,
|
|||
seg->feature_data[segment_id][feature_id] = 0;
|
||||
}
|
||||
|
||||
// Based on set of segment counts calculate a probability tree
|
||||
static void calc_segtree_probs(unsigned *segcounts,
|
||||
aom_prob *segment_tree_probs,
|
||||
const aom_prob *cur_tree_probs,
|
||||
const int probwt) {
|
||||
// Work out probabilities of each segment
|
||||
const unsigned cc[4] = { segcounts[0] + segcounts[1],
|
||||
segcounts[2] + segcounts[3],
|
||||
segcounts[4] + segcounts[5],
|
||||
segcounts[6] + segcounts[7] };
|
||||
const unsigned ccc[2] = { cc[0] + cc[1], cc[2] + cc[3] };
|
||||
int i;
|
||||
|
||||
segment_tree_probs[0] = get_binary_prob(ccc[0], ccc[1]);
|
||||
segment_tree_probs[1] = get_binary_prob(cc[0], cc[1]);
|
||||
segment_tree_probs[2] = get_binary_prob(cc[2], cc[3]);
|
||||
segment_tree_probs[3] = get_binary_prob(segcounts[0], segcounts[1]);
|
||||
segment_tree_probs[4] = get_binary_prob(segcounts[2], segcounts[3]);
|
||||
segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
|
||||
segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
const unsigned *ct =
|
||||
i == 0 ? ccc : i < 3 ? cc + (i & 2) : segcounts + (i - 3) * 2;
|
||||
av1_prob_diff_update_savings_search(ct, cur_tree_probs[i],
|
||||
&segment_tree_probs[i],
|
||||
DIFF_UPDATE_PROB, probwt);
|
||||
}
|
||||
}
|
||||
|
||||
// Based on set of segment counts and probabilities calculate a cost estimate
|
||||
static int cost_segmap(unsigned *segcounts, aom_prob *probs) {
|
||||
const int c01 = segcounts[0] + segcounts[1];
|
||||
const int c23 = segcounts[2] + segcounts[3];
|
||||
const int c45 = segcounts[4] + segcounts[5];
|
||||
const int c67 = segcounts[6] + segcounts[7];
|
||||
const int c0123 = c01 + c23;
|
||||
const int c4567 = c45 + c67;
|
||||
|
||||
// Cost the top node of the tree
|
||||
int cost = c0123 * av1_cost_zero(probs[0]) + c4567 * av1_cost_one(probs[0]);
|
||||
|
||||
// Cost subsequent levels
|
||||
if (c0123 > 0) {
|
||||
cost += c01 * av1_cost_zero(probs[1]) + c23 * av1_cost_one(probs[1]);
|
||||
|
||||
if (c01 > 0)
|
||||
cost += segcounts[0] * av1_cost_zero(probs[3]) +
|
||||
segcounts[1] * av1_cost_one(probs[3]);
|
||||
if (c23 > 0)
|
||||
cost += segcounts[2] * av1_cost_zero(probs[4]) +
|
||||
segcounts[3] * av1_cost_one(probs[4]);
|
||||
}
|
||||
|
||||
if (c4567 > 0) {
|
||||
cost += c45 * av1_cost_zero(probs[2]) + c67 * av1_cost_one(probs[2]);
|
||||
|
||||
if (c45 > 0)
|
||||
cost += segcounts[4] * av1_cost_zero(probs[5]) +
|
||||
segcounts[5] * av1_cost_one(probs[5]);
|
||||
if (c67 > 0)
|
||||
cost += segcounts[6] * av1_cost_zero(probs[6]) +
|
||||
segcounts[7] * av1_cost_one(probs[6]);
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
static void count_segs(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
||||
const TileInfo *tile, MODE_INFO **mi,
|
||||
const TileInfo *tile, MB_MODE_INFO **mi,
|
||||
unsigned *no_pred_segcounts,
|
||||
unsigned (*temporal_predictor_count)[2],
|
||||
unsigned *t_unpred_seg_counts, int bw, int bh,
|
||||
|
|
@ -127,29 +54,27 @@ static void count_segs(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
|
||||
|
||||
xd->mi = mi;
|
||||
segment_id = xd->mi[0]->mbmi.segment_id;
|
||||
segment_id = xd->mi[0]->segment_id;
|
||||
|
||||
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw,
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
cm->dependent_horz_tiles,
|
||||
#endif // CONFIG_DEPENDENT_HORZTILES
|
||||
cm->mi_rows, cm->mi_cols);
|
||||
set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
|
||||
|
||||
// Count the number of hits on each segment with no prediction
|
||||
no_pred_segcounts[segment_id]++;
|
||||
|
||||
// Temporal prediction not allowed on key frames
|
||||
if (cm->frame_type != KEY_FRAME) {
|
||||
const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
|
||||
const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
|
||||
// Test to see if the segment id matches the predicted value.
|
||||
const int pred_segment_id =
|
||||
get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col);
|
||||
cm->last_frame_seg_map
|
||||
? get_segment_id(cm, cm->last_frame_seg_map, bsize, mi_row, mi_col)
|
||||
: 0;
|
||||
const int pred_flag = pred_segment_id == segment_id;
|
||||
const int pred_context = av1_get_pred_context_seg_id(xd);
|
||||
|
||||
// Store the prediction status for this mb and update counts
|
||||
// as appropriate
|
||||
xd->mi[0]->mbmi.seg_id_predicted = pred_flag;
|
||||
xd->mi[0]->seg_id_predicted = pred_flag;
|
||||
temporal_predictor_count[pred_context][pred_flag]++;
|
||||
|
||||
// Update the "unpredicted" segment count
|
||||
|
|
@ -158,21 +83,15 @@ static void count_segs(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
}
|
||||
|
||||
static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
||||
const TileInfo *tile, MODE_INFO **mi,
|
||||
const TileInfo *tile, MB_MODE_INFO **mi,
|
||||
unsigned *no_pred_segcounts,
|
||||
unsigned (*temporal_predictor_count)[2],
|
||||
unsigned *t_unpred_seg_counts, int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize) {
|
||||
const int mis = cm->mi_stride;
|
||||
const int bs = mi_size_wide[bsize], hbs = bs / 2;
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
PARTITION_TYPE partition;
|
||||
#if CONFIG_EXT_PARTITION_TYPES_AB
|
||||
const int qbs = bs / 4;
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES_AB
|
||||
#else
|
||||
int bw, bh;
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
|
||||
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
|
||||
|
||||
|
|
@ -181,7 +100,6 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, \
|
||||
(cs_bw), (cs_bh), mi_row + (cs_rowoff), mi_col + (cs_coloff));
|
||||
|
||||
#if CONFIG_EXT_PARTITION_TYPES
|
||||
if (bsize == BLOCK_8X8)
|
||||
partition = PARTITION_NONE;
|
||||
else
|
||||
|
|
@ -196,55 +114,43 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
CSEGS(hbs, bs, 0, 0);
|
||||
CSEGS(hbs, bs, 0, hbs);
|
||||
break;
|
||||
#if CONFIG_EXT_PARTITION_TYPES_AB
|
||||
case PARTITION_HORZ_A:
|
||||
CSEGS(hbs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, 0, hbs);
|
||||
CSEGS(bs, hbs, hbs, 0);
|
||||
break;
|
||||
case PARTITION_HORZ_B:
|
||||
CSEGS(bs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, hbs, 0);
|
||||
CSEGS(hbs, hbs, hbs, hbs);
|
||||
break;
|
||||
case PARTITION_VERT_A:
|
||||
CSEGS(hbs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, hbs, 0);
|
||||
CSEGS(hbs, bs, 0, hbs);
|
||||
break;
|
||||
case PARTITION_VERT_B:
|
||||
CSEGS(hbs, bs, 0, 0);
|
||||
CSEGS(hbs, hbs, 0, hbs);
|
||||
CSEGS(hbs, hbs, hbs, hbs);
|
||||
break;
|
||||
case PARTITION_HORZ_4:
|
||||
CSEGS(bs, qbs, 0, 0);
|
||||
CSEGS(bs, qbs, qbs, 0);
|
||||
CSEGS(bs, hbs, hbs, 0);
|
||||
break;
|
||||
case PARTITION_HORZ_B:
|
||||
CSEGS(bs, hbs, 0, 0);
|
||||
CSEGS(bs, qbs, hbs, 0);
|
||||
CSEGS(bs, qbs, 2 * qbs, 0);
|
||||
if (mi_row + 3 * qbs < cm->mi_rows) CSEGS(bs, qbs, 3 * qbs, 0);
|
||||
break;
|
||||
case PARTITION_VERT_A:
|
||||
|
||||
case PARTITION_VERT_4:
|
||||
CSEGS(qbs, bs, 0, 0);
|
||||
CSEGS(qbs, bs, 0, qbs);
|
||||
CSEGS(hbs, bs, 0, hbs);
|
||||
break;
|
||||
case PARTITION_VERT_B:
|
||||
CSEGS(hbs, bs, 0, 0);
|
||||
CSEGS(qbs, bs, 0, hbs);
|
||||
CSEGS(qbs, bs, 0, 2 * qbs);
|
||||
if (mi_col + 3 * qbs < cm->mi_cols) CSEGS(qbs, bs, 0, 3 * qbs);
|
||||
break;
|
||||
#else
|
||||
case PARTITION_HORZ_A:
|
||||
CSEGS(hbs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, 0, hbs);
|
||||
CSEGS(bs, hbs, hbs, 0);
|
||||
break;
|
||||
case PARTITION_HORZ_B:
|
||||
CSEGS(bs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, hbs, 0);
|
||||
CSEGS(hbs, hbs, hbs, hbs);
|
||||
break;
|
||||
case PARTITION_VERT_A:
|
||||
CSEGS(hbs, hbs, 0, 0);
|
||||
CSEGS(hbs, hbs, hbs, 0);
|
||||
CSEGS(hbs, bs, 0, hbs);
|
||||
break;
|
||||
case PARTITION_VERT_B:
|
||||
CSEGS(hbs, bs, 0, 0);
|
||||
CSEGS(hbs, hbs, 0, hbs);
|
||||
CSEGS(hbs, hbs, hbs, hbs);
|
||||
break;
|
||||
#endif
|
||||
case PARTITION_SPLIT: {
|
||||
const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
|
||||
int n;
|
||||
|
||||
assert(num_8x8_blocks_wide_lookup[mi[0]->mbmi.sb_type] < bs &&
|
||||
num_8x8_blocks_high_lookup[mi[0]->mbmi.sb_type] < bs);
|
||||
case PARTITION_SPLIT: {
|
||||
const BLOCK_SIZE subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
const int mi_dc = hbs * (n & 1);
|
||||
|
|
@ -257,34 +163,6 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
} break;
|
||||
default: assert(0);
|
||||
}
|
||||
#else
|
||||
bw = mi_size_wide[mi[0]->mbmi.sb_type];
|
||||
bh = mi_size_high[mi[0]->mbmi.sb_type];
|
||||
|
||||
if (bw == bs && bh == bs) {
|
||||
CSEGS(bs, bs, 0, 0);
|
||||
} else if (bw == bs && bh < bs) {
|
||||
CSEGS(bs, hbs, 0, 0);
|
||||
CSEGS(bs, hbs, hbs, 0);
|
||||
} else if (bw < bs && bh == bs) {
|
||||
CSEGS(hbs, bs, 0, 0);
|
||||
CSEGS(hbs, bs, 0, hbs);
|
||||
} else {
|
||||
const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
|
||||
int n;
|
||||
|
||||
assert(bw < bs && bh < bs);
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
const int mi_dc = hbs * (n & 1);
|
||||
const int mi_dr = hbs * (n >> 1);
|
||||
|
||||
count_segs_sb(cm, xd, tile, &mi[mi_dr * mis + mi_dc], no_pred_segcounts,
|
||||
temporal_predictor_count, t_unpred_seg_counts,
|
||||
mi_row + mi_dr, mi_col + mi_dc, subsize);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_EXT_PARTITION_TYPES
|
||||
|
||||
#undef CSEGS
|
||||
}
|
||||
|
|
@ -292,83 +170,58 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
|||
void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
|
||||
struct segmentation *seg = &cm->seg;
|
||||
struct segmentation_probs *segp = &cm->fc->seg;
|
||||
|
||||
int no_pred_cost;
|
||||
int t_pred_cost = INT_MAX;
|
||||
|
||||
int tile_col, tile_row, mi_row, mi_col;
|
||||
const int probwt = cm->num_tg;
|
||||
|
||||
unsigned(*temporal_predictor_count)[2] = cm->counts.seg.pred;
|
||||
unsigned *no_pred_segcounts = cm->counts.seg.tree_total;
|
||||
unsigned *t_unpred_seg_counts = cm->counts.seg.tree_mispred;
|
||||
|
||||
aom_prob no_pred_tree[SEG_TREE_PROBS];
|
||||
aom_prob t_pred_tree[SEG_TREE_PROBS];
|
||||
#if !CONFIG_NEW_MULTISYMBOL
|
||||
aom_prob t_nopred_prob[PREDICTION_PROBS];
|
||||
#endif
|
||||
|
||||
unsigned temporal_predictor_count[SEG_TEMPORAL_PRED_CTXS][2] = { { 0 } };
|
||||
unsigned no_pred_segcounts[MAX_SEGMENTS] = { 0 };
|
||||
unsigned t_unpred_seg_counts[MAX_SEGMENTS] = { 0 };
|
||||
(void)xd;
|
||||
|
||||
// We are about to recompute all the segment counts, so zero the accumulators.
|
||||
av1_zero(cm->counts.seg);
|
||||
|
||||
// First of all generate stats regarding how well the last segment map
|
||||
// predicts this one
|
||||
for (tile_row = 0; tile_row < cm->tile_rows; tile_row++) {
|
||||
TileInfo tile_info;
|
||||
av1_tile_set_row(&tile_info, cm, tile_row);
|
||||
for (tile_col = 0; tile_col < cm->tile_cols; tile_col++) {
|
||||
MODE_INFO **mi_ptr;
|
||||
MB_MODE_INFO **mi_ptr;
|
||||
av1_tile_set_col(&tile_info, cm, tile_col);
|
||||
#if CONFIG_DEPENDENT_HORZTILES
|
||||
av1_tile_set_tg_boundary(&tile_info, cm, tile_row, tile_col);
|
||||
#endif
|
||||
mi_ptr = cm->mi_grid_visible + tile_info.mi_row_start * cm->mi_stride +
|
||||
tile_info.mi_col_start;
|
||||
for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
|
||||
mi_row += cm->mib_size, mi_ptr += cm->mib_size * cm->mi_stride) {
|
||||
MODE_INFO **mi = mi_ptr;
|
||||
mi_row += cm->seq_params.mib_size,
|
||||
mi_ptr += cm->seq_params.mib_size * cm->mi_stride) {
|
||||
MB_MODE_INFO **mi = mi_ptr;
|
||||
for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
|
||||
mi_col += cm->mib_size, mi += cm->mib_size) {
|
||||
mi_col += cm->seq_params.mib_size, mi += cm->seq_params.mib_size) {
|
||||
count_segs_sb(cm, xd, &tile_info, mi, no_pred_segcounts,
|
||||
temporal_predictor_count, t_unpred_seg_counts, mi_row,
|
||||
mi_col, cm->sb_size);
|
||||
mi_col, cm->seq_params.sb_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Work out probability tree for coding segments without prediction
|
||||
// and the cost.
|
||||
calc_segtree_probs(no_pred_segcounts, no_pred_tree, segp->tree_probs, probwt);
|
||||
no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree);
|
||||
int seg_id_cost[MAX_SEGMENTS];
|
||||
av1_cost_tokens_from_cdf(seg_id_cost, segp->tree_cdf, NULL);
|
||||
no_pred_cost = 0;
|
||||
for (int i = 0; i < MAX_SEGMENTS; ++i)
|
||||
no_pred_cost += no_pred_segcounts[i] * seg_id_cost[i];
|
||||
|
||||
// Key frames cannot use temporal prediction
|
||||
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,
|
||||
probwt);
|
||||
t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree);
|
||||
#if !CONFIG_NEW_MULTISYMBOL
|
||||
// Add in the cost of the signaling for each prediction context.
|
||||
int i;
|
||||
for (i = 0; i < PREDICTION_PROBS; i++) {
|
||||
const int count0 = temporal_predictor_count[i][0];
|
||||
const int count1 = temporal_predictor_count[i][1];
|
||||
|
||||
t_nopred_prob[i] = get_binary_prob(count0, count1);
|
||||
av1_prob_diff_update_savings_search(
|
||||
temporal_predictor_count[i], segp->pred_probs[i], &t_nopred_prob[i],
|
||||
DIFF_UPDATE_PROB, probwt);
|
||||
|
||||
// Add in the predictor signaling cost
|
||||
t_pred_cost += count0 * av1_cost_zero(t_nopred_prob[i]) +
|
||||
count1 * av1_cost_one(t_nopred_prob[i]);
|
||||
// Frames without past dependency cannot use temporal prediction
|
||||
if (cm->primary_ref_frame != PRIMARY_REF_NONE) {
|
||||
int pred_flag_cost[SEG_TEMPORAL_PRED_CTXS][2];
|
||||
for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i)
|
||||
av1_cost_tokens_from_cdf(pred_flag_cost[i], segp->pred_cdf[i], NULL);
|
||||
t_pred_cost = 0;
|
||||
// Cost for signaling the prediction flag.
|
||||
for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i) {
|
||||
for (int j = 0; j < 2; ++j)
|
||||
t_pred_cost += temporal_predictor_count[i][j] * pred_flag_cost[i][j];
|
||||
}
|
||||
#endif
|
||||
// Cost for signaling the unpredicted segment id.
|
||||
for (int i = 0; i < MAX_SEGMENTS; ++i)
|
||||
t_pred_cost += t_unpred_seg_counts[i] * seg_id_cost[i];
|
||||
}
|
||||
|
||||
// Now choose which coding method to use.
|
||||
|
|
|
|||
13
third_party/aom/av1/encoder/segmentation.h
vendored
13
third_party/aom/av1/encoder/segmentation.h
vendored
|
|
@ -27,19 +27,6 @@ void av1_disable_segfeature(struct segmentation *seg, int segment_id,
|
|||
void av1_clear_segdata(struct segmentation *seg, int segment_id,
|
||||
SEG_LVL_FEATURES feature_id);
|
||||
|
||||
// The values given for each segment can be either deltas (from the default
|
||||
// value chosen for the frame) or absolute values.
|
||||
//
|
||||
// Valid range for abs values is (0-127 for MB_LVL_ALT_Q), (0-63 for
|
||||
// SEGMENT_ALT_LF)
|
||||
// Valid range for delta values are (+/-127 for MB_LVL_ALT_Q), (+/-63 for
|
||||
// SEGMENT_ALT_LF)
|
||||
//
|
||||
// abs_delta = SEGMENT_DELTADATA (deltas) abs_delta = SEGMENT_ABSDATA (use
|
||||
// the absolute values given).
|
||||
void av1_set_segment_data(struct segmentation *seg, int8_t *feature_data,
|
||||
unsigned char abs_delta);
|
||||
|
||||
void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd);
|
||||
|
||||
void av1_reset_segment_features(AV1_COMMON *cm);
|
||||
|
|
|
|||
354
third_party/aom/av1/encoder/speed_features.c
vendored
354
third_party/aom/av1/encoder/speed_features.c
vendored
|
|
@ -17,6 +17,12 @@
|
|||
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
|
||||
// Setting this to 1 will disable trellis optimization completely.
|
||||
// Setting this to 2 will disable trellis optimization within the
|
||||
// transform search. Trellis optimization will still be applied
|
||||
// in the final encode.
|
||||
#define DISABLE_TRELLISQ_SEARCH 0
|
||||
|
||||
#define MAX_MESH_SPEED 5 // Max speed setting for mesh motion method
|
||||
static MESH_PATTERN
|
||||
good_quality_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
|
||||
|
|
@ -28,23 +34,21 @@ static MESH_PATTERN
|
|||
{ { 64, 16 }, { 24, 8 }, { 12, 4 }, { 7, 1 } },
|
||||
};
|
||||
static unsigned char good_quality_max_mesh_pct[MAX_MESH_SPEED + 1] = {
|
||||
50, 25, 15, 5, 1, 1
|
||||
50, 50, 25, 15, 5, 1
|
||||
};
|
||||
|
||||
#if CONFIG_INTRABC
|
||||
// TODO(aconverse@google.com): These settings are pretty relaxed, tune them for
|
||||
// TODO(huisu@google.com): These settings are pretty relaxed, tune them for
|
||||
// each speed setting
|
||||
static MESH_PATTERN intrabc_mesh_patterns[MAX_MESH_SPEED + 1][MAX_MESH_STEP] = {
|
||||
{ { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 256, 1 }, { 256, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 64, 1 }, { 64, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
{ { 64, 4 }, { 16, 1 }, { 0, 0 }, { 0, 0 } },
|
||||
};
|
||||
static uint8_t intrabc_max_mesh_pct[MAX_MESH_SPEED + 1] = { 100, 100, 100,
|
||||
25, 25, 10 };
|
||||
#endif
|
||||
|
||||
// Intra only frames, golden frames (except alt ref overlays) and
|
||||
// alt ref frames tend to be coded at a higher than ambient quality
|
||||
|
|
@ -74,22 +78,18 @@ static BLOCK_SIZE set_partition_min_limit(AV1_COMMON *const cm) {
|
|||
}
|
||||
}
|
||||
|
||||
// Do we have an internal image edge (e.g. formatting bars).
|
||||
static int has_internal_image_edge(const AV1_COMP *cpi) {
|
||||
return (cpi->oxcf.pass == 2) &&
|
||||
((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
|
||||
(cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
|
||||
}
|
||||
|
||||
static void set_good_speed_feature_framesize_dependent(AV1_COMP *cpi,
|
||||
SPEED_FEATURES *sf,
|
||||
int speed) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
|
||||
if (speed >= 1) {
|
||||
if (AOMMIN(cm->width, cm->height) >= 720) {
|
||||
sf->disable_split_mask =
|
||||
cm->show_frame ? DISABLE_ALL_SPLIT : DISABLE_ALL_INTER_SPLIT;
|
||||
sf->partition_search_breakout_dist_thr = (1 << 23);
|
||||
} else {
|
||||
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
|
||||
sf->partition_search_breakout_dist_thr = (1 << 21);
|
||||
}
|
||||
}
|
||||
|
||||
if (speed >= 2) {
|
||||
if (AOMMIN(cm->width, cm->height) >= 720) {
|
||||
sf->disable_split_mask =
|
||||
|
|
@ -121,11 +121,11 @@ static void set_good_speed_feature_framesize_dependent(AV1_COMP *cpi,
|
|||
}
|
||||
|
||||
// If this is a two pass clip that fits the criteria for animated or
|
||||
// graphics content then reset disable_split_mask for speeds 1-4.
|
||||
// graphics content then reset disable_split_mask for speeds 2+.
|
||||
// Also if the image edge is internal to the coded area.
|
||||
if ((speed >= 1) && (cpi->oxcf.pass == 2) &&
|
||||
if ((speed >= 2) && (cpi->oxcf.pass == 2) &&
|
||||
((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
|
||||
(av1_internal_image_edge(cpi)))) {
|
||||
(has_internal_image_edge(cpi)))) {
|
||||
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
|
||||
}
|
||||
|
||||
|
|
@ -145,85 +145,83 @@ static void set_good_speed_features_framesize_independent(AV1_COMP *cpi,
|
|||
AV1_COMMON *const cm = &cpi->common;
|
||||
const int boosted = frame_is_boosted(cpi);
|
||||
|
||||
// Speed 0 for all speed features that give neutral coding performance change.
|
||||
sf->reduce_inter_modes = 1;
|
||||
sf->prune_ext_partition_types_search_level = 1;
|
||||
sf->ml_prune_ab_partition = 1;
|
||||
sf->adaptive_txb_search_level = 1;
|
||||
sf->jnt_comp_skip_mv_search = 1;
|
||||
sf->model_based_prune_tx_search_level = 1;
|
||||
sf->model_based_post_interp_filter_breakout = 1;
|
||||
sf->inter_mode_rd_model_estimation = 1;
|
||||
|
||||
if (speed >= 1) {
|
||||
sf->tx_type_search.fast_intra_tx_type_search = 1;
|
||||
sf->tx_type_search.fast_inter_tx_type_search = 1;
|
||||
sf->gm_erroradv_type = GM_ERRORADV_TR_1;
|
||||
sf->selective_ref_frame = 1;
|
||||
sf->inter_tx_size_search_init_depth_rect = 1;
|
||||
sf->inter_tx_size_search_init_depth_sqr = 1;
|
||||
sf->intra_tx_size_search_init_depth_rect = 1;
|
||||
sf->intra_tx_size_search_init_depth_sqr = 1;
|
||||
sf->tx_size_search_lgr_block = 1;
|
||||
sf->two_pass_partition_search = 1;
|
||||
sf->mode_pruning_based_on_two_pass_partition_search = 1;
|
||||
sf->prune_ext_partition_types_search_level = 2;
|
||||
sf->use_fast_interpolation_filter_search = 1;
|
||||
sf->skip_repeat_interpolation_filter_search = 1;
|
||||
sf->tx_type_search.skip_tx_search = 1;
|
||||
sf->tx_type_search.ml_tx_split_thresh = 40;
|
||||
sf->model_based_prune_tx_search_level = 0;
|
||||
sf->model_based_post_interp_filter_breakout = 0;
|
||||
// TODO(angiebird): Re-evaluate the impact of inter_mode_rd_model_estimation
|
||||
// on speed 1
|
||||
sf->inter_mode_rd_model_estimation = 0;
|
||||
sf->adaptive_txb_search_level = 2;
|
||||
sf->use_intra_txb_hash = 1;
|
||||
sf->optimize_b_precheck = 1;
|
||||
sf->dual_sgr_penalty_level = 1;
|
||||
}
|
||||
|
||||
if (speed >= 2) {
|
||||
if ((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
|
||||
av1_internal_image_edge(cpi)) {
|
||||
sf->use_square_partition_only = !frame_is_boosted(cpi);
|
||||
} else {
|
||||
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
||||
}
|
||||
sf->gm_erroradv_type = GM_ERRORADV_TR_2;
|
||||
|
||||
sf->less_rectangular_check = 1;
|
||||
sf->selective_ref_frame = 2;
|
||||
sf->fast_cdef_search = 1;
|
||||
|
||||
sf->use_rd_breakout = 1;
|
||||
sf->adaptive_motion_search = 1;
|
||||
sf->mv.auto_mv_step_size = 1;
|
||||
sf->adaptive_rd_thresh = 1;
|
||||
sf->mv.auto_mv_step_size = 1;
|
||||
sf->mv.subpel_iters_per_step = 1;
|
||||
sf->mode_skip_start = 10;
|
||||
sf->adaptive_pred_interp_filter = 1;
|
||||
sf->disable_filter_search_var_thresh = 100;
|
||||
sf->comp_inter_joint_search_thresh = BLOCK_SIZES_ALL;
|
||||
|
||||
sf->recode_loop = ALLOW_RECODE_KFARFGF;
|
||||
#if CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC_H_V;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[TX_64X64] = UV_INTRA_DC_H_V_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[TX_64X64] = INTRA_DC_H_V;
|
||||
#endif // CONFIG_CFL
|
||||
#endif // CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[TX_32X32] = UV_INTRA_DC_H_V_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||
#endif
|
||||
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[TX_16X16] = UV_INTRA_DC_H_V_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||
#endif
|
||||
|
||||
sf->tx_size_search_breakout = 1;
|
||||
sf->partition_search_breakout_rate_thr = 80;
|
||||
sf->tx_type_search.prune_mode = PRUNE_ONE;
|
||||
// Use transform domain distortion.
|
||||
// Note var-tx expt always uses pixel domain distortion.
|
||||
sf->use_transform_domain_distortion = 1;
|
||||
sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
|
||||
sf->allow_partition_search_skip = 1;
|
||||
sf->disable_wedge_search_var_thresh = 100;
|
||||
sf->fast_wedge_sign_estimate = 1;
|
||||
}
|
||||
|
||||
if (speed >= 3) {
|
||||
sf->tx_size_search_method =
|
||||
frame_is_boosted(cpi) ? USE_FULL_RD : USE_LARGESTALL;
|
||||
sf->mode_search_skip_flags =
|
||||
(cm->frame_type == KEY_FRAME)
|
||||
? 0
|
||||
: FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
|
||||
FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR;
|
||||
sf->disable_filter_search_var_thresh = 100;
|
||||
sf->comp_inter_joint_search_thresh = BLOCK_SIZES_ALL;
|
||||
sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
|
||||
sf->allow_partition_search_skip = 1;
|
||||
sf->use_upsampled_references = 0;
|
||||
sf->tx_size_search_method = boosted ? USE_FULL_RD : USE_LARGESTALL;
|
||||
sf->less_rectangular_check = 1;
|
||||
sf->mode_skip_start = 10;
|
||||
sf->adaptive_pred_interp_filter = 1;
|
||||
// adaptive_motion_search breaks encoder multi-thread tests.
|
||||
// The values in x->pred_mv[] differ for single and multi-thread cases.
|
||||
// See aomedia:1778.
|
||||
// sf->adaptive_motion_search = 1;
|
||||
sf->recode_loop = ALLOW_RECODE_KFARFGF;
|
||||
sf->use_transform_domain_distortion = 1;
|
||||
sf->use_accurate_subpel_search = 0;
|
||||
sf->adaptive_rd_thresh = 2;
|
||||
#if CONFIG_EXT_TX
|
||||
sf->tx_type_search.prune_mode = PRUNE_TWO;
|
||||
#endif
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
sf->tx_type_search.prune_mode = PRUNE_2D_FAST;
|
||||
sf->gm_search_type = GM_DISABLE_SEARCH;
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
}
|
||||
|
||||
if (speed >= 4) {
|
||||
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
||||
sf->tx_type_search.fast_intra_tx_type_search = 1;
|
||||
sf->tx_type_search.fast_inter_tx_type_search = 1;
|
||||
sf->use_square_partition_only = !boosted;
|
||||
sf->tx_size_search_method =
|
||||
frame_is_intra_only(cm) ? USE_FULL_RD : USE_LARGESTALL;
|
||||
sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED;
|
||||
|
|
@ -232,52 +230,44 @@ static void set_good_speed_features_framesize_independent(AV1_COMP *cpi,
|
|||
sf->cb_partition_search = !boosted;
|
||||
sf->cb_pred_filter_search = 1;
|
||||
sf->alt_ref_search_fp = 1;
|
||||
sf->recode_loop = ALLOW_RECODE_KFMAXBW;
|
||||
sf->adaptive_rd_thresh = 3;
|
||||
sf->mode_skip_start = 6;
|
||||
#if CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[TX_64X64] = UV_INTRA_DC_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[TX_64X64] = INTRA_DC;
|
||||
#endif // CONFIG_CFL
|
||||
#endif // CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[TX_32X32] = UV_INTRA_DC_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC;
|
||||
#endif // CONFIG_CFL
|
||||
sf->adaptive_interp_filter_search = 1;
|
||||
}
|
||||
|
||||
if (speed >= 5) {
|
||||
sf->recode_loop = ALLOW_RECODE_KFMAXBW;
|
||||
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC_H_V;
|
||||
sf->intra_uv_mode_mask[TX_64X64] = UV_INTRA_DC_H_V_CFL;
|
||||
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||
sf->intra_uv_mode_mask[TX_32X32] = UV_INTRA_DC_H_V_CFL;
|
||||
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||
sf->intra_uv_mode_mask[TX_16X16] = UV_INTRA_DC_H_V_CFL;
|
||||
sf->use_square_partition_only = 1;
|
||||
sf->tx_size_search_method = USE_LARGESTALL;
|
||||
sf->mv.search_method = BIGDIA;
|
||||
sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED_MORE;
|
||||
sf->adaptive_rd_thresh = 4;
|
||||
if (cm->frame_type != KEY_FRAME)
|
||||
sf->mode_search_skip_flags |= FLAG_EARLY_TERMINATE;
|
||||
sf->mode_search_skip_flags =
|
||||
(cm->frame_type == KEY_FRAME)
|
||||
? 0
|
||||
: FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER |
|
||||
FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_INTRA_LOWVAR |
|
||||
FLAG_EARLY_TERMINATE;
|
||||
sf->disable_filter_search_var_thresh = 200;
|
||||
sf->use_fast_coef_updates = ONE_LOOP_REDUCED;
|
||||
sf->use_fast_coef_costing = 1;
|
||||
sf->partition_search_breakout_rate_thr = 300;
|
||||
sf->use_transform_domain_distortion = 2;
|
||||
}
|
||||
|
||||
if (speed >= 6) {
|
||||
int i;
|
||||
sf->optimize_coefficients = 0;
|
||||
sf->optimize_coefficients = NO_TRELLIS_OPT;
|
||||
sf->mv.search_method = HEX;
|
||||
sf->disable_filter_search_var_thresh = 500;
|
||||
for (i = 0; i < TX_SIZES; ++i) {
|
||||
sf->intra_y_mode_mask[i] = INTRA_DC;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[i] = UV_INTRA_DC_CFL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[i] = INTRA_DC;
|
||||
#endif // CONFIG_CFL
|
||||
}
|
||||
sf->partition_search_breakout_rate_thr = 500;
|
||||
sf->mv.reduce_first_step_size = 1;
|
||||
|
|
@ -288,9 +278,7 @@ static void set_good_speed_features_framesize_independent(AV1_COMP *cpi,
|
|||
const int frames_since_key = is_keyframe ? 0 : cpi->rc.frames_since_key;
|
||||
sf->default_max_partition_size = BLOCK_32X32;
|
||||
sf->default_min_partition_size = BLOCK_8X8;
|
||||
#if CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_64X64] = INTRA_DC;
|
||||
#endif // CONFIG_TX64X64
|
||||
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC;
|
||||
sf->frame_parameter_update = 0;
|
||||
sf->mv.search_method = FAST_HEX;
|
||||
|
|
@ -298,13 +286,10 @@ static void set_good_speed_features_framesize_independent(AV1_COMP *cpi,
|
|||
sf->inter_mode_mask[BLOCK_32X64] = INTER_NEAREST;
|
||||
sf->inter_mode_mask[BLOCK_64X32] = INTER_NEAREST;
|
||||
sf->inter_mode_mask[BLOCK_64X64] = INTER_NEAREST;
|
||||
#if CONFIG_EXT_PARTITION
|
||||
sf->inter_mode_mask[BLOCK_64X128] = INTER_NEAREST;
|
||||
sf->inter_mode_mask[BLOCK_128X64] = INTER_NEAREST;
|
||||
sf->inter_mode_mask[BLOCK_128X128] = INTER_NEAREST;
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
sf->partition_search_type = REFERENCE_PARTITION;
|
||||
sf->default_min_partition_size = BLOCK_8X8;
|
||||
sf->reuse_inter_pred_sby = 1;
|
||||
sf->force_frame_boost =
|
||||
is_keyframe ||
|
||||
|
|
@ -324,31 +309,9 @@ static void set_good_speed_features_framesize_independent(AV1_COMP *cpi,
|
|||
void av1_set_speed_features_framesize_dependent(AV1_COMP *cpi) {
|
||||
SPEED_FEATURES *const sf = &cpi->sf;
|
||||
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
RD_OPT *const rd = &cpi->rd;
|
||||
int i;
|
||||
|
||||
// Limit memory usage for high resolutions
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(zoeliu): Temporary solution to resolve the insufficient RAM issue for
|
||||
// ext-refs. Need to work with @yunqingwang to have a more
|
||||
// effective solution.
|
||||
if (AOMMIN(cm->width, cm->height) > 720) {
|
||||
// Turn off the use of upsampled references for HD resolution
|
||||
sf->use_upsampled_references = 0;
|
||||
} else if ((AOMMIN(cm->width, cm->height) > 540) &&
|
||||
(oxcf->profile != PROFILE_0)) {
|
||||
sf->use_upsampled_references = 0;
|
||||
}
|
||||
#else
|
||||
if (AOMMIN(cm->width, cm->height) > 1080) {
|
||||
sf->use_upsampled_references = 0;
|
||||
} else if ((AOMMIN(cm->width, cm->height) > 720) &&
|
||||
(oxcf->profile != PROFILE_0)) {
|
||||
sf->use_upsampled_references = 0;
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
if (oxcf->mode == GOOD) {
|
||||
set_good_speed_feature_framesize_dependent(cpi, sf, oxcf->speed);
|
||||
}
|
||||
|
|
@ -371,6 +334,52 @@ void av1_set_speed_features_framesize_dependent(AV1_COMP *cpi) {
|
|||
cpi->find_fractional_mv_step = av1_return_min_sub_pixel_mv;
|
||||
}
|
||||
|
||||
static void set_dev_sf(AV1_COMP *cpi, SPEED_FEATURES *sf, int speed) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
|
||||
if (speed & TXFM_CODING_SF) {
|
||||
sf->inter_tx_size_search_init_depth_rect = 1;
|
||||
sf->inter_tx_size_search_init_depth_sqr = 1;
|
||||
sf->intra_tx_size_search_init_depth_rect = 1;
|
||||
sf->intra_tx_size_search_init_depth_sqr = 1;
|
||||
sf->tx_size_search_method = USE_FAST_RD;
|
||||
sf->tx_type_search.fast_intra_tx_type_search = 1;
|
||||
sf->tx_type_search.fast_inter_tx_type_search = 1;
|
||||
}
|
||||
|
||||
if (speed & INTER_PRED_SF) {
|
||||
sf->selective_ref_frame = 2;
|
||||
// sf->adaptive_motion_search = 1;
|
||||
sf->mv.auto_mv_step_size = 1;
|
||||
sf->adaptive_rd_thresh = 1;
|
||||
sf->mv.subpel_iters_per_step = 1;
|
||||
sf->adaptive_pred_interp_filter = 1;
|
||||
}
|
||||
|
||||
if (speed & INTRA_PRED_SF) {
|
||||
sf->max_intra_bsize = BLOCK_32X32;
|
||||
}
|
||||
|
||||
if (speed & PARTITION_SF) {
|
||||
if ((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
|
||||
has_internal_image_edge(cpi)) {
|
||||
sf->use_square_partition_only = !frame_is_boosted(cpi);
|
||||
} else {
|
||||
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
||||
}
|
||||
sf->less_rectangular_check = 1;
|
||||
sf->prune_ext_partition_types_search_level = 2;
|
||||
}
|
||||
|
||||
if (speed & LOOP_FILTER_SF) {
|
||||
sf->fast_cdef_search = 1;
|
||||
}
|
||||
|
||||
if (speed & RD_SKIP_SF) {
|
||||
sf->use_rd_breakout = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
SPEED_FEATURES *const sf = &cpi->sf;
|
||||
|
|
@ -378,7 +387,6 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
|
||||
int i;
|
||||
|
||||
(void)cm;
|
||||
// best quality defaults
|
||||
sf->frame_parameter_update = 1;
|
||||
sf->mv.search_method = NSTEP;
|
||||
|
|
@ -386,7 +394,19 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->mv.subpel_search_method = SUBPEL_TREE;
|
||||
sf->mv.subpel_iters_per_step = 2;
|
||||
sf->mv.subpel_force_stop = 0;
|
||||
sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf);
|
||||
#if DISABLE_TRELLISQ_SEARCH == 2
|
||||
sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf)
|
||||
? FINAL_PASS_TRELLIS_OPT
|
||||
: NO_TRELLIS_OPT;
|
||||
#elif DISABLE_TRELLISQ_SEARCH == 1
|
||||
sf->optimize_coefficients = NO_TRELLIS_OPT;
|
||||
#else
|
||||
if (is_lossless_requested(&cpi->oxcf))
|
||||
sf->optimize_coefficients = NO_TRELLIS_OPT;
|
||||
else
|
||||
sf->optimize_coefficients = FULL_TRELLIS_OPT;
|
||||
#endif // DISABLE_TRELLISQ_SEARCH
|
||||
sf->gm_erroradv_type = GM_ERRORADV_TR_0;
|
||||
sf->mv.reduce_first_step_size = 0;
|
||||
sf->coeff_prob_appx_step = 1;
|
||||
sf->mv.auto_mv_step_size = 0;
|
||||
|
|
@ -394,6 +414,15 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->comp_inter_joint_search_thresh = BLOCK_4X4;
|
||||
sf->adaptive_rd_thresh = 0;
|
||||
sf->tx_size_search_method = USE_FULL_RD;
|
||||
sf->inter_tx_size_search_init_depth_sqr = 0;
|
||||
sf->inter_tx_size_search_init_depth_rect = 0;
|
||||
sf->intra_tx_size_search_init_depth_rect = 0;
|
||||
sf->intra_tx_size_search_init_depth_sqr = 0;
|
||||
sf->tx_size_search_lgr_block = 0;
|
||||
sf->model_based_prune_tx_search_level = 0;
|
||||
sf->model_based_post_interp_filter_breakout = 0;
|
||||
sf->reduce_inter_modes = 0;
|
||||
sf->selective_ref_gm = 1;
|
||||
sf->adaptive_motion_search = 0;
|
||||
sf->adaptive_pred_interp_filter = 0;
|
||||
sf->adaptive_mode_search = 0;
|
||||
|
|
@ -401,10 +430,13 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->cb_partition_search = 0;
|
||||
sf->alt_ref_search_fp = 0;
|
||||
sf->partition_search_type = SEARCH_PARTITION;
|
||||
sf->tx_type_search.prune_mode = NO_PRUNE;
|
||||
sf->tx_type_search.prune_mode = PRUNE_2D_ACCURATE;
|
||||
sf->tx_type_search.ml_tx_split_thresh = 30;
|
||||
sf->tx_type_search.use_skip_flag_prediction = 1;
|
||||
sf->tx_type_search.fast_intra_tx_type_search = 0;
|
||||
sf->tx_type_search.fast_inter_tx_type_search = 0;
|
||||
sf->tx_type_search.skip_tx_search = 0;
|
||||
sf->selective_ref_frame = 0;
|
||||
sf->less_rectangular_check = 0;
|
||||
sf->use_square_partition_only = 0;
|
||||
sf->auto_min_max_partition_size = NOT_IN_USE;
|
||||
|
|
@ -420,17 +452,25 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->disable_filter_search_var_thresh = 0;
|
||||
sf->adaptive_interp_filter_search = 0;
|
||||
sf->allow_partition_search_skip = 0;
|
||||
sf->use_upsampled_references = 1;
|
||||
sf->use_accurate_subpel_search = 1;
|
||||
sf->disable_wedge_search_var_thresh = 0;
|
||||
sf->fast_wedge_sign_estimate = 0;
|
||||
sf->drop_ref = 0;
|
||||
sf->skip_intra_in_interframe = 1;
|
||||
sf->txb_split_cap = 1;
|
||||
sf->adaptive_txb_search_level = 0;
|
||||
sf->two_pass_partition_search = 0;
|
||||
sf->mode_pruning_based_on_two_pass_partition_search = 0;
|
||||
sf->use_intra_txb_hash = 0;
|
||||
sf->use_inter_txb_hash = 1;
|
||||
sf->use_mb_rd_hash = 1;
|
||||
sf->optimize_b_precheck = 0;
|
||||
sf->jnt_comp_fast_tx_search = 0;
|
||||
sf->jnt_comp_skip_mv_search = 0;
|
||||
|
||||
for (i = 0; i < TX_SIZES; i++) {
|
||||
sf->intra_y_mode_mask[i] = INTRA_ALL;
|
||||
#if CONFIG_CFL
|
||||
sf->intra_uv_mode_mask[i] = UV_INTRA_ALL;
|
||||
#else
|
||||
sf->intra_uv_mode_mask[i] = INTRA_ALL;
|
||||
#endif // CONFIG_CFL
|
||||
}
|
||||
sf->use_rd_breakout = 0;
|
||||
sf->lpf_pick = LPF_PICK_FROM_FULL_IMAGE;
|
||||
|
|
@ -448,22 +488,28 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
// Recode loop tolerance %.
|
||||
sf->recode_tolerance = 25;
|
||||
sf->default_interp_filter = SWITCHABLE;
|
||||
sf->tx_size_search_breakout = 0;
|
||||
sf->partition_search_breakout_dist_thr = 0;
|
||||
sf->partition_search_breakout_rate_thr = 0;
|
||||
sf->simple_model_rd_from_var = 0;
|
||||
sf->prune_ext_partition_types_search_level = 0;
|
||||
sf->ml_prune_ab_partition = 0;
|
||||
sf->fast_cdef_search = 0;
|
||||
|
||||
// Set this at the appropriate speed levels
|
||||
sf->use_transform_domain_distortion = 0;
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
sf->gm_search_type = GM_FULL_SEARCH;
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
sf->use_fast_interpolation_filter_search = 0;
|
||||
sf->skip_repeat_interpolation_filter_search = 0;
|
||||
sf->use_hash_based_trellis = 0;
|
||||
|
||||
if (oxcf->mode == GOOD
|
||||
#if CONFIG_XIPHRC
|
||||
|| oxcf->pass == 1
|
||||
#endif
|
||||
)
|
||||
// Set decoder side speed feature to use less dual sgr modes
|
||||
sf->dual_sgr_penalty_level = 0;
|
||||
|
||||
sf->inter_mode_rd_model_estimation = 0;
|
||||
|
||||
set_dev_sf(cpi, sf, oxcf->dev_sf);
|
||||
|
||||
if (oxcf->mode == GOOD)
|
||||
set_good_speed_features_framesize_independent(cpi, sf, oxcf->speed);
|
||||
|
||||
// sf->partition_search_breakout_dist_thr is set assuming max 64x64
|
||||
|
|
@ -472,7 +518,6 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->partition_search_breakout_dist_thr <<= 2 * (MAX_SB_SIZE_LOG2 - 6);
|
||||
}
|
||||
|
||||
cpi->full_search_sad = av1_full_search_sad;
|
||||
cpi->diamond_search_sad = av1_diamond_search_sad;
|
||||
|
||||
sf->allow_exhaustive_searches = 1;
|
||||
|
|
@ -490,7 +535,6 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
sf->mesh_patterns[i].interval =
|
||||
good_quality_mesh_patterns[speed][i].interval;
|
||||
}
|
||||
#if CONFIG_INTRABC
|
||||
if ((frame_is_intra_only(cm) && cm->allow_screen_content_tools) &&
|
||||
(cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION ||
|
||||
cpi->oxcf.content == AOM_CONTENT_SCREEN)) {
|
||||
|
|
@ -500,18 +544,15 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
}
|
||||
sf->max_exaustive_pct = intrabc_max_mesh_pct[speed];
|
||||
}
|
||||
#endif // CONFIG_INTRABC
|
||||
|
||||
#if !CONFIG_XIPHRC
|
||||
// Slow quant, dct and trellis not worthwhile for first pass
|
||||
// so make sure they are always turned off.
|
||||
if (oxcf->pass == 1) sf->optimize_coefficients = 0;
|
||||
#endif
|
||||
if (oxcf->pass == 1) sf->optimize_coefficients = NO_TRELLIS_OPT;
|
||||
|
||||
// No recode for 1 pass.
|
||||
if (oxcf->pass == 0) {
|
||||
sf->recode_loop = DISALLOW_RECODE;
|
||||
sf->optimize_coefficients = 0;
|
||||
sf->optimize_coefficients = NO_TRELLIS_OPT;
|
||||
}
|
||||
|
||||
if (sf->mv.subpel_search_method == SUBPEL_TREE) {
|
||||
|
|
@ -524,12 +565,11 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
cpi->find_fractional_mv_step = av1_find_best_sub_pixel_tree_pruned_evenmore;
|
||||
}
|
||||
|
||||
#if !CONFIG_AOM_QM
|
||||
x->optimize = sf->optimize_coefficients == 1 && oxcf->pass != 1;
|
||||
#else
|
||||
cpi->optimize_speed_feature =
|
||||
oxcf->pass != 1 ? sf->optimize_coefficients : NO_TRELLIS_OPT;
|
||||
// FIXME: trellis not very efficient for quantisation matrices
|
||||
x->optimize = 0;
|
||||
#endif
|
||||
if (cm->using_qmatrix) cpi->optimize_speed_feature = NO_TRELLIS_OPT;
|
||||
if (oxcf->disable_trellis_quant) cpi->optimize_speed_feature = NO_TRELLIS_OPT;
|
||||
|
||||
x->min_partition_size = sf->default_min_partition_size;
|
||||
x->max_partition_size = sf->default_max_partition_size;
|
||||
|
|
@ -543,4 +583,8 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi) {
|
|||
cpi->find_fractional_mv_step = av1_return_max_sub_pixel_mv;
|
||||
else if (cpi->oxcf.motion_vector_unit_test == 2)
|
||||
cpi->find_fractional_mv_step = av1_return_min_sub_pixel_mv;
|
||||
|
||||
#if CONFIG_DIST_8X8
|
||||
if (sf->use_transform_domain_distortion > 0) cpi->oxcf.using_dist_8x8 = 0;
|
||||
#endif // CONFIG_DIST_8X8
|
||||
}
|
||||
|
|
|
|||
253
third_party/aom/av1/encoder/speed_features.h
vendored
253
third_party/aom/av1/encoder/speed_features.h
vendored
|
|
@ -20,64 +20,51 @@ extern "C" {
|
|||
|
||||
enum {
|
||||
INTRA_ALL = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED) | (1 << D45_PRED) |
|
||||
(1 << D135_PRED) | (1 << D117_PRED) | (1 << D153_PRED) |
|
||||
(1 << D207_PRED) | (1 << D63_PRED) | (1 << SMOOTH_PRED) |
|
||||
#if CONFIG_SMOOTH_HV
|
||||
(1 << SMOOTH_V_PRED) | (1 << SMOOTH_H_PRED) |
|
||||
#endif // CONFIG_SMOOTH_HV
|
||||
(1 << TM_PRED),
|
||||
#if CONFIG_CFL
|
||||
UV_INTRA_ALL = (1 << UV_DC_PRED) | (1 << UV_V_PRED) | (1 << UV_H_PRED) |
|
||||
(1 << UV_D45_PRED) | (1 << UV_D135_PRED) |
|
||||
(1 << UV_D117_PRED) | (1 << UV_D153_PRED) |
|
||||
(1 << UV_D207_PRED) | (1 << UV_D63_PRED) |
|
||||
(1 << UV_SMOOTH_PRED) |
|
||||
#if CONFIG_SMOOTH_HV
|
||||
(1 << UV_SMOOTH_V_PRED) | (1 << UV_SMOOTH_H_PRED) |
|
||||
#endif // CONFIG_SMOOTH_HV
|
||||
(1 << UV_TM_PRED) | (1 << UV_CFL_PRED),
|
||||
(1 << D135_PRED) | (1 << D113_PRED) | (1 << D157_PRED) |
|
||||
(1 << D203_PRED) | (1 << D67_PRED) | (1 << SMOOTH_PRED) |
|
||||
(1 << SMOOTH_V_PRED) | (1 << SMOOTH_H_PRED) | (1 << PAETH_PRED),
|
||||
UV_INTRA_ALL =
|
||||
(1 << UV_DC_PRED) | (1 << UV_V_PRED) | (1 << UV_H_PRED) |
|
||||
(1 << UV_D45_PRED) | (1 << UV_D135_PRED) | (1 << UV_D113_PRED) |
|
||||
(1 << UV_D157_PRED) | (1 << UV_D203_PRED) | (1 << UV_D67_PRED) |
|
||||
(1 << UV_SMOOTH_PRED) | (1 << UV_SMOOTH_V_PRED) |
|
||||
(1 << UV_SMOOTH_H_PRED) | (1 << UV_PAETH_PRED) | (1 << UV_CFL_PRED),
|
||||
UV_INTRA_DC = (1 << UV_DC_PRED),
|
||||
UV_INTRA_DC_CFL = (1 << UV_DC_PRED) | (1 << UV_CFL_PRED),
|
||||
UV_INTRA_DC_TM = (1 << UV_DC_PRED) | (1 << UV_TM_PRED),
|
||||
UV_INTRA_DC_TM_CFL =
|
||||
(1 << UV_DC_PRED) | (1 << UV_TM_PRED) | (1 << UV_CFL_PRED),
|
||||
UV_INTRA_DC_TM = (1 << UV_DC_PRED) | (1 << UV_PAETH_PRED),
|
||||
UV_INTRA_DC_PAETH_CFL =
|
||||
(1 << UV_DC_PRED) | (1 << UV_PAETH_PRED) | (1 << UV_CFL_PRED),
|
||||
UV_INTRA_DC_H_V = (1 << UV_DC_PRED) | (1 << UV_V_PRED) | (1 << UV_H_PRED),
|
||||
UV_INTRA_DC_H_V_CFL = (1 << UV_DC_PRED) | (1 << UV_V_PRED) |
|
||||
(1 << UV_H_PRED) | (1 << UV_CFL_PRED),
|
||||
UV_INTRA_DC_TM_H_V = (1 << UV_DC_PRED) | (1 << UV_TM_PRED) |
|
||||
(1 << UV_V_PRED) | (1 << UV_H_PRED),
|
||||
UV_INTRA_DC_TM_H_V_CFL = (1 << UV_DC_PRED) | (1 << UV_TM_PRED) |
|
||||
(1 << UV_V_PRED) | (1 << UV_H_PRED) |
|
||||
(1 << UV_CFL_PRED),
|
||||
#endif // CONFIG_CFL
|
||||
UV_INTRA_DC_PAETH_H_V = (1 << UV_DC_PRED) | (1 << UV_PAETH_PRED) |
|
||||
(1 << UV_V_PRED) | (1 << UV_H_PRED),
|
||||
UV_INTRA_DC_PAETH_H_V_CFL = (1 << UV_DC_PRED) | (1 << UV_PAETH_PRED) |
|
||||
(1 << UV_V_PRED) | (1 << UV_H_PRED) |
|
||||
(1 << UV_CFL_PRED),
|
||||
INTRA_DC = (1 << DC_PRED),
|
||||
INTRA_DC_TM = (1 << DC_PRED) | (1 << TM_PRED),
|
||||
INTRA_DC_TM = (1 << DC_PRED) | (1 << PAETH_PRED),
|
||||
INTRA_DC_H_V = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED),
|
||||
INTRA_DC_TM_H_V =
|
||||
(1 << DC_PRED) | (1 << TM_PRED) | (1 << V_PRED) | (1 << H_PRED)
|
||||
INTRA_DC_PAETH_H_V =
|
||||
(1 << DC_PRED) | (1 << PAETH_PRED) | (1 << V_PRED) | (1 << H_PRED)
|
||||
};
|
||||
|
||||
enum {
|
||||
#if CONFIG_COMPOUND_SINGLEREF
|
||||
// TODO(zoeliu): To further consider following single ref comp modes:
|
||||
// SR_NEAREST_NEARMV, SR_NEAREST_NEWMV, SR_NEAR_NEWMV,
|
||||
// SR_ZERO_NEWMV, and SR_NEW_NEWMV.
|
||||
#endif // CONFIG_COMPOUND_SINGLEREF
|
||||
INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << NEAR_NEARMV) | (1 << NEW_NEWMV) |
|
||||
(1 << NEAREST_NEWMV) | (1 << NEAR_NEWMV) | (1 << NEW_NEARMV) |
|
||||
(1 << NEW_NEARESTMV) | (1 << ZERO_ZEROMV),
|
||||
INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << GLOBALMV) |
|
||||
(1 << NEWMV) | (1 << NEAREST_NEARESTMV) | (1 << NEAR_NEARMV) |
|
||||
(1 << NEW_NEWMV) | (1 << NEAREST_NEWMV) | (1 << NEAR_NEWMV) |
|
||||
(1 << NEW_NEARMV) | (1 << NEW_NEARESTMV) | (1 << GLOBAL_GLOBALMV),
|
||||
INTER_NEAREST = (1 << NEARESTMV) | (1 << NEAREST_NEARESTMV) |
|
||||
(1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV),
|
||||
INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << NEW_NEWMV) |
|
||||
(1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
|
||||
(1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
|
||||
INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
|
||||
INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << GLOBALMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << GLOBAL_GLOBALMV) |
|
||||
(1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV),
|
||||
INTER_NEAREST_NEW_ZERO = (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
|
||||
INTER_NEAREST_NEW_ZERO = (1 << NEARESTMV) | (1 << GLOBALMV) | (1 << NEWMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << GLOBAL_GLOBALMV) |
|
||||
(1 << NEW_NEWMV) | (1 << NEW_NEARESTMV) |
|
||||
(1 << NEAREST_NEWMV) | (1 << NEW_NEARMV) |
|
||||
(1 << NEAR_NEWMV),
|
||||
|
|
@ -86,8 +73,8 @@ enum {
|
|||
(1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
|
||||
(1 << NEW_NEARMV) | (1 << NEAR_NEWMV) |
|
||||
(1 << NEAR_NEARMV),
|
||||
INTER_NEAREST_NEAR_ZERO = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
|
||||
INTER_NEAREST_NEAR_ZERO = (1 << NEARESTMV) | (1 << NEARMV) | (1 << GLOBALMV) |
|
||||
(1 << NEAREST_NEARESTMV) | (1 << GLOBAL_GLOBALMV) |
|
||||
(1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV) |
|
||||
(1 << NEW_NEARMV) | (1 << NEAR_NEWMV) |
|
||||
(1 << NEAR_NEARMV),
|
||||
|
|
@ -105,6 +92,17 @@ enum {
|
|||
(1 << THR_ALTR) | (1 << THR_GOLD)
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TXFM_CODING_SF = 1,
|
||||
INTER_PRED_SF = 2,
|
||||
INTRA_PRED_SF = 4,
|
||||
PARTITION_SF = 8,
|
||||
LOOP_FILTER_SF = 16,
|
||||
RD_SKIP_SF = 32,
|
||||
RESERVE_2_SF = 64,
|
||||
RESERVE_3_SF = 128,
|
||||
} DEV_SPEED_FEATURES;
|
||||
|
||||
typedef enum {
|
||||
DIAMOND = 0,
|
||||
NSTEP = 1,
|
||||
|
|
@ -141,8 +139,8 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
USE_FULL_RD = 0,
|
||||
USE_FAST_RD,
|
||||
USE_LARGESTALL,
|
||||
USE_TX_8X8
|
||||
} TX_SIZE_SEARCH_METHOD;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -190,10 +188,13 @@ typedef enum {
|
|||
NO_PRUNE = 0,
|
||||
// eliminates one tx type in vertical and horizontal direction
|
||||
PRUNE_ONE = 1,
|
||||
#if CONFIG_EXT_TX
|
||||
// eliminates two tx types in each direction
|
||||
PRUNE_TWO = 2,
|
||||
#endif
|
||||
// adaptively prunes the least perspective tx types out of all 16
|
||||
// (tuned to provide negligible quality loss)
|
||||
PRUNE_2D_ACCURATE = 3,
|
||||
// similar, but applies much more aggressive pruning to get better speed-up
|
||||
PRUNE_2D_FAST = 4,
|
||||
} TX_TYPE_PRUNE_MODE;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -204,6 +205,13 @@ typedef struct {
|
|||
// Use a skip flag prediction model to detect blocks with skip = 1 early
|
||||
// and avoid doing full TX type search for such blocks.
|
||||
int use_skip_flag_prediction;
|
||||
|
||||
// Threshold used by the ML based method to predict TX block split decisions.
|
||||
int ml_tx_split_thresh;
|
||||
|
||||
// skip remaining transform type search when we found the rdcost of skip is
|
||||
// better than applying transform
|
||||
int skip_tx_search;
|
||||
} TX_TYPE_SEARCH;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -261,13 +269,29 @@ typedef struct MESH_PATTERN {
|
|||
int interval;
|
||||
} MESH_PATTERN;
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
typedef enum {
|
||||
GM_FULL_SEARCH,
|
||||
GM_REDUCED_REF_SEARCH,
|
||||
GM_DISABLE_SEARCH
|
||||
} GM_SEARCH_TYPE;
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
|
||||
typedef enum {
|
||||
GM_ERRORADV_TR_0,
|
||||
GM_ERRORADV_TR_1,
|
||||
GM_ERRORADV_TR_2,
|
||||
GM_ERRORADV_TR_TYPES,
|
||||
} GM_ERRORADV_TYPE;
|
||||
|
||||
typedef enum {
|
||||
NO_TRELLIS_OPT, // No trellis optimization
|
||||
FULL_TRELLIS_OPT, // Trellis optimization in all stages
|
||||
FINAL_PASS_TRELLIS_OPT // Trellis optimization in only the final encode pass
|
||||
} TRELLIS_OPT_TYPE;
|
||||
|
||||
typedef enum {
|
||||
FULL_TXFM_RD,
|
||||
LOW_TXFM_RD,
|
||||
} TXFM_RD_MODEL;
|
||||
|
||||
typedef struct SPEED_FEATURES {
|
||||
MV_SPEED_FEATURES mv;
|
||||
|
|
@ -277,8 +301,11 @@ typedef struct SPEED_FEATURES {
|
|||
|
||||
RECODE_LOOP_TYPE recode_loop;
|
||||
|
||||
// Trellis (dynamic programming) optimization of quantized values (+1, 0).
|
||||
int optimize_coefficients;
|
||||
// Trellis (dynamic programming) optimization of quantized values
|
||||
TRELLIS_OPT_TYPE optimize_coefficients;
|
||||
|
||||
// Global motion warp error threshold
|
||||
GM_ERRORADV_TYPE gm_erroradv_type;
|
||||
|
||||
// Always set to 0. If on it enables 0 cost background transmission
|
||||
// (except for the initial transmission of the segmentation). The feature is
|
||||
|
|
@ -287,6 +314,14 @@ typedef struct SPEED_FEATURES {
|
|||
// adds overhead.
|
||||
int static_segmentation;
|
||||
|
||||
// Limit the inter mode tested in the RD loop
|
||||
int reduce_inter_modes;
|
||||
|
||||
// Do not compute the global motion parameters for a LAST2_FRAME or
|
||||
// LAST3_FRAME if the GOLDEN_FRAME is closer and it has a non identity
|
||||
// global model.
|
||||
int selective_ref_gm;
|
||||
|
||||
// If 1 we iterate finding a best reference for 2 ref frames together - via
|
||||
// a log search that iterates 4 times (check around mv for last for best
|
||||
// error of combined predictor then check around mv for alt). If 0 we
|
||||
|
|
@ -309,6 +344,17 @@ typedef struct SPEED_FEATURES {
|
|||
// for intra and model coefs for the rest.
|
||||
TX_SIZE_SEARCH_METHOD tx_size_search_method;
|
||||
|
||||
// Init search depth for square and rectangular transform partitions.
|
||||
// Values:
|
||||
// 0 - search full tree, 1: search 1 level, 2: search the highest level only
|
||||
int inter_tx_size_search_init_depth_sqr;
|
||||
int inter_tx_size_search_init_depth_rect;
|
||||
int intra_tx_size_search_init_depth_sqr;
|
||||
int intra_tx_size_search_init_depth_rect;
|
||||
// If any dimension of a coding block size above 64, always search the
|
||||
// largest transform only, since the largest transform block size is 64x64.
|
||||
int tx_size_search_lgr_block;
|
||||
|
||||
// After looking at the first set of modes (set by index here), skip
|
||||
// checking modes for reference frames that don't match the reference frame
|
||||
// of the best so far.
|
||||
|
|
@ -318,9 +364,51 @@ typedef struct SPEED_FEATURES {
|
|||
|
||||
TX_TYPE_SEARCH tx_type_search;
|
||||
|
||||
// Skip split transform block partition when the collocated bigger block
|
||||
// is selected as all zero coefficients.
|
||||
int txb_split_cap;
|
||||
|
||||
// Shortcut the transform block partition and type search when the target
|
||||
// rdcost is relatively lower.
|
||||
// Values are 0 (not used) , or 1 - 2 with progressively increasing
|
||||
// aggressiveness
|
||||
int adaptive_txb_search_level;
|
||||
|
||||
// Prune level for tx_size_type search for inter based on rd model
|
||||
// 0: no pruning
|
||||
// 1-2: progressively increasing aggressiveness of pruning
|
||||
int model_based_prune_tx_search_level;
|
||||
|
||||
// Model based breakout after interpolation filter search
|
||||
// 0: no breakout
|
||||
// 1: use model based rd breakout
|
||||
int model_based_post_interp_filter_breakout;
|
||||
|
||||
// Used if partition_search_type = FIXED_SIZE_PARTITION
|
||||
BLOCK_SIZE always_this_block_size;
|
||||
|
||||
// Drop less likely to be picked reference frames in the RD search.
|
||||
// Has three levels for now: 0, 1 and 2, where higher levels prune more
|
||||
// aggressively than lower ones. (0 means no pruning).
|
||||
int selective_ref_frame;
|
||||
|
||||
// Prune extended partition types search
|
||||
// Can take values 0 - 2, 0 referring to no pruning, and 1 - 2 increasing
|
||||
// aggressiveness of pruning in order.
|
||||
int prune_ext_partition_types_search_level;
|
||||
|
||||
// Use a ML model to prune horz_a, horz_b, vert_a and vert_b partitions.
|
||||
int ml_prune_ab_partition;
|
||||
|
||||
int fast_cdef_search;
|
||||
|
||||
// 2-pass coding block partition search
|
||||
int two_pass_partition_search;
|
||||
|
||||
// Use the mode decisions made in the initial partition search to prune mode
|
||||
// candidates, e.g. ref frames.
|
||||
int mode_pruning_based_on_two_pass_partition_search;
|
||||
|
||||
// Skip rectangular partition test when partition type none gives better
|
||||
// rd than partition type split.
|
||||
int less_rectangular_check;
|
||||
|
|
@ -427,7 +515,7 @@ typedef struct SPEED_FEATURES {
|
|||
// by only looking at counts from 1/2 the bands.
|
||||
FAST_COEFF_UPDATE use_fast_coef_updates;
|
||||
|
||||
// A binary mask indicating if NEARESTMV, NEARMV, ZEROMV, NEWMV
|
||||
// A binary mask indicating if NEARESTMV, NEARMV, GLOBALMV, NEWMV
|
||||
// modes are used in order from LSB to MSB for each BLOCK_SIZE.
|
||||
int inter_mode_mask[BLOCK_SIZES_ALL];
|
||||
|
||||
|
|
@ -456,10 +544,6 @@ typedef struct SPEED_FEATURES {
|
|||
// default interp filter choice
|
||||
InterpFilter default_interp_filter;
|
||||
|
||||
// Early termination in transform size search, which only applies while
|
||||
// tx_size_search_method is USE_FULL_RD.
|
||||
int tx_size_search_breakout;
|
||||
|
||||
// adaptive interp_filter search to allow skip of certain filter types.
|
||||
int adaptive_interp_filter_search;
|
||||
|
||||
|
|
@ -476,16 +560,67 @@ typedef struct SPEED_FEATURES {
|
|||
// Fast approximation of av1_model_rd_from_var_lapndz
|
||||
int simple_model_rd_from_var;
|
||||
|
||||
// Do sub-pixel search in up-sampled reference frames
|
||||
int use_upsampled_references;
|
||||
// If true, sub-pixel search uses the exact convolve function used for final
|
||||
// encoding and decoding; otherwise, it uses bilinear interpolation.
|
||||
int use_accurate_subpel_search;
|
||||
|
||||
// Whether to compute distortion in the image domain (slower but
|
||||
// more accurate), or in the transform domain (faster but less acurate).
|
||||
// 0: use image domain
|
||||
// 1: use transform domain in tx_type search, and use image domain for
|
||||
// RD_STATS
|
||||
// 2: use transform domain
|
||||
int use_transform_domain_distortion;
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
GM_SEARCH_TYPE gm_search_type;
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
|
||||
// Do limited interpolation filter search for dual filters, since best choice
|
||||
// usually includes EIGHTTAP_REGULAR.
|
||||
int use_fast_interpolation_filter_search;
|
||||
|
||||
// Save results of interpolation_filter_search for a block
|
||||
// Check mv and ref_frames before search, if they are same with previous
|
||||
// saved results, it can be skipped.
|
||||
int skip_repeat_interpolation_filter_search;
|
||||
|
||||
// Use a hash table to store previously computed optimized qcoeffs from
|
||||
// expensive calls to optimize_txb.
|
||||
int use_hash_based_trellis;
|
||||
|
||||
// flag to drop some ref frames in compound motion search
|
||||
int drop_ref;
|
||||
|
||||
// flag to allow skipping intra mode for inter frame prediction
|
||||
int skip_intra_in_interframe;
|
||||
|
||||
// Use hash table to store intra(keyframe only) txb transform search results
|
||||
// to avoid repeated search on the same residue signal.
|
||||
int use_intra_txb_hash;
|
||||
|
||||
// Use hash table to store inter txb transform search results
|
||||
// to avoid repeated search on the same residue signal.
|
||||
int use_inter_txb_hash;
|
||||
|
||||
// Use hash table to store macroblock RD search results
|
||||
// to avoid repeated search on the same residue signal.
|
||||
int use_mb_rd_hash;
|
||||
|
||||
// Calculate RD cost before doing optimize_b, and skip if the cost is large.
|
||||
int optimize_b_precheck;
|
||||
|
||||
// Use model rd instead of transform search in jnt_comp
|
||||
int jnt_comp_fast_tx_search;
|
||||
|
||||
// Skip mv search in jnt_comp
|
||||
int jnt_comp_skip_mv_search;
|
||||
|
||||
// Decoder side speed feature to add penalty for use of dual-sgr filters.
|
||||
// Takes values 0 - 10, 0 indicating no penalty and each additional level
|
||||
// adding a penalty of 1%
|
||||
int dual_sgr_penalty_level;
|
||||
|
||||
// Dynamically estimate final rd from prediction error and mode cost
|
||||
int inter_mode_rd_model_estimation;
|
||||
} SPEED_FEATURES;
|
||||
|
||||
struct AV1_COMP;
|
||||
|
|
|
|||
164
third_party/aom/av1/encoder/subexp.c
vendored
164
third_party/aom/av1/encoder/subexp.c
vendored
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
|
||||
#include "av1/common/common.h"
|
||||
#include "av1/common/entropy.h"
|
||||
#include "av1/encoder/cost.h"
|
||||
#include "av1/encoder/subexp.h"
|
||||
|
||||
static const uint8_t update_bits[255] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 0,
|
||||
};
|
||||
#define MIN_DELP_BITS 5
|
||||
|
||||
static int recenter_nonneg(int v, int m) {
|
||||
if (v > (m << 1))
|
||||
return v;
|
||||
else if (v >= m)
|
||||
return ((v - m) << 1);
|
||||
else
|
||||
return ((m - v) << 1) - 1;
|
||||
}
|
||||
|
||||
static int remap_prob(int v, int m) {
|
||||
int i;
|
||||
static const uint8_t map_table[MAX_PROB - 1] = {
|
||||
// generated by:
|
||||
// map_table[j] = split_index(j, MAX_PROB - 1, MODULUS_PARAM);
|
||||
20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||
34, 35, 36, 37, 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 2, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
|
||||
3, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 4, 74,
|
||||
75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 5, 86, 87, 88,
|
||||
89, 90, 91, 92, 93, 94, 95, 96, 97, 6, 98, 99, 100, 101, 102,
|
||||
103, 104, 105, 106, 107, 108, 109, 7, 110, 111, 112, 113, 114, 115, 116,
|
||||
117, 118, 119, 120, 121, 8, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||
131, 132, 133, 9, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
|
||||
145, 10, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11,
|
||||
158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12, 170, 171,
|
||||
172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13, 182, 183, 184, 185,
|
||||
186, 187, 188, 189, 190, 191, 192, 193, 14, 194, 195, 196, 197, 198, 199,
|
||||
200, 201, 202, 203, 204, 205, 15, 206, 207, 208, 209, 210, 211, 212, 213,
|
||||
214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||
228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
||||
18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19,
|
||||
};
|
||||
v--;
|
||||
m--;
|
||||
if ((m << 1) <= MAX_PROB)
|
||||
i = recenter_nonneg(v, m) - 1;
|
||||
else
|
||||
i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1;
|
||||
|
||||
i = map_table[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
static int prob_diff_update_cost(aom_prob newp, aom_prob oldp) {
|
||||
int delp = remap_prob(newp, oldp);
|
||||
return update_bits[delp] << AV1_PROB_COST_SHIFT;
|
||||
}
|
||||
|
||||
static void encode_uniform(aom_writer *w, int v) {
|
||||
const int l = 8;
|
||||
const int m = (1 << l) - 190;
|
||||
if (v < m) {
|
||||
aom_write_literal(w, v, l - 1);
|
||||
} else {
|
||||
aom_write_literal(w, m + ((v - m) >> 1), l - 1);
|
||||
aom_write_literal(w, (v - m) & 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE int write_bit_gte(aom_writer *w, int word, int test) {
|
||||
aom_write_literal(w, word >= test, 1);
|
||||
return word >= test;
|
||||
}
|
||||
|
||||
static void encode_term_subexp(aom_writer *w, int word) {
|
||||
if (!write_bit_gte(w, word, 16)) {
|
||||
aom_write_literal(w, word, 4);
|
||||
} else if (!write_bit_gte(w, word, 32)) {
|
||||
aom_write_literal(w, word - 16, 4);
|
||||
} else if (!write_bit_gte(w, word, 64)) {
|
||||
aom_write_literal(w, word - 32, 5);
|
||||
} else {
|
||||
encode_uniform(w, word - 64);
|
||||
}
|
||||
}
|
||||
|
||||
void av1_write_prob_diff_update(aom_writer *w, aom_prob newp, aom_prob oldp) {
|
||||
const int delp = remap_prob(newp, oldp);
|
||||
encode_term_subexp(w, delp);
|
||||
}
|
||||
|
||||
int av1_prob_diff_update_savings_search(const unsigned int *ct, aom_prob oldp,
|
||||
aom_prob *bestp, aom_prob upd,
|
||||
int probwt) {
|
||||
const uint32_t old_b = cost_branch256(ct, oldp);
|
||||
int bestsavings = 0;
|
||||
aom_prob newp, bestnewp = oldp;
|
||||
const int step = *bestp > oldp ? -1 : 1;
|
||||
const int upd_cost = av1_cost_one(upd) - av1_cost_zero(upd);
|
||||
|
||||
if (old_b > (uint32_t)upd_cost + (MIN_DELP_BITS << AV1_PROB_COST_SHIFT)) {
|
||||
for (newp = *bestp; newp != oldp; newp += step) {
|
||||
const int new_b = cost_branch256(ct, newp);
|
||||
const int update_b = prob_diff_update_cost(newp, oldp) + upd_cost;
|
||||
const int savings = (int)((int64_t)old_b - new_b - update_b * probwt);
|
||||
if (savings > bestsavings) {
|
||||
bestsavings = savings;
|
||||
bestnewp = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
*bestp = bestnewp;
|
||||
return bestsavings;
|
||||
}
|
||||
|
||||
void av1_cond_prob_diff_update(aom_writer *w, aom_prob *oldp,
|
||||
const unsigned int ct[2], int probwt) {
|
||||
const aom_prob upd = DIFF_UPDATE_PROB;
|
||||
aom_prob newp = get_binary_prob(ct[0], ct[1]);
|
||||
const int savings =
|
||||
av1_prob_diff_update_savings_search(ct, *oldp, &newp, upd, probwt);
|
||||
assert(newp >= 1);
|
||||
if (savings > 0) {
|
||||
aom_write(w, 1, upd);
|
||||
av1_write_prob_diff_update(w, newp, *oldp);
|
||||
*oldp = newp;
|
||||
} else {
|
||||
aom_write(w, 0, upd);
|
||||
}
|
||||
}
|
||||
|
||||
int av1_cond_prob_diff_update_savings(aom_prob *oldp, const unsigned int ct[2],
|
||||
int probwt) {
|
||||
const aom_prob upd = DIFF_UPDATE_PROB;
|
||||
aom_prob newp = get_binary_prob(ct[0], ct[1]);
|
||||
const int savings =
|
||||
av1_prob_diff_update_savings_search(ct, *oldp, &newp, upd, probwt);
|
||||
return savings;
|
||||
}
|
||||
42
third_party/aom/av1/encoder/subexp.h
vendored
42
third_party/aom/av1/encoder/subexp.h
vendored
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_SUBEXP_H_
|
||||
#define AV1_ENCODER_SUBEXP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
void av1_write_prob_diff_update(aom_writer *w, aom_prob newp, aom_prob oldpm);
|
||||
|
||||
void av1_cond_prob_diff_update(aom_writer *w, aom_prob *oldp,
|
||||
const unsigned int ct[2], int probwt);
|
||||
|
||||
int av1_prob_diff_update_savings_search(const unsigned int *ct, aom_prob oldp,
|
||||
aom_prob *bestp, aom_prob upd,
|
||||
int probwt);
|
||||
|
||||
int av1_prob_diff_update_savings_search_model(const unsigned int *ct,
|
||||
const aom_prob oldp,
|
||||
aom_prob *bestp, aom_prob upd,
|
||||
int stepsize, int probwt);
|
||||
|
||||
int av1_cond_prob_diff_update_savings(aom_prob *oldp, const unsigned int ct[2],
|
||||
int probwt);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_SUBEXP_H_
|
||||
328
third_party/aom/av1/encoder/temporal_filter.c
vendored
328
third_party/aom/av1/encoder/temporal_filter.c
vendored
|
|
@ -12,7 +12,8 @@
|
|||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "av1/common/alloccommon.h"
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/common/quant_common.h"
|
||||
|
|
@ -35,26 +36,17 @@
|
|||
static void temporal_filter_predictors_mb_c(
|
||||
MACROBLOCKD *xd, uint8_t *y_mb_ptr, uint8_t *u_mb_ptr, uint8_t *v_mb_ptr,
|
||||
int stride, int uv_block_width, int uv_block_height, int mv_row, int mv_col,
|
||||
uint8_t *pred, struct scale_factors *scale, int x, int y) {
|
||||
uint8_t *pred, struct scale_factors *scale, int x, int y,
|
||||
int can_use_previous) {
|
||||
const int which_mv = 0;
|
||||
const MV mv = { mv_row, mv_col };
|
||||
enum mv_precision mv_precision_uv;
|
||||
int uv_stride;
|
||||
// TODO(angiebird): change plane setting accordingly
|
||||
ConvolveParams conv_params = get_conv_params(which_mv, which_mv, 0);
|
||||
|
||||
#if USE_TEMPORALFILTER_12TAP
|
||||
const InterpFilters interp_filters =
|
||||
av1_broadcast_interp_filter(TEMPORALFILTER_12TAP);
|
||||
(void)xd;
|
||||
#else
|
||||
const InterpFilters interp_filters = xd->mi[0]->mbmi.interp_filters;
|
||||
#endif // USE_TEMPORALFILTER_12TAP
|
||||
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
ConvolveParams conv_params = get_conv_params(which_mv, 0, 0, xd->bd);
|
||||
const InterpFilters interp_filters = xd->mi[0]->interp_filters;
|
||||
WarpTypesAllowed warp_types;
|
||||
memset(&warp_types, 0, sizeof(WarpTypesAllowed));
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
|
||||
if (uv_block_width == 8) {
|
||||
uv_stride = (stride + 1) >> 1;
|
||||
|
|
@ -64,55 +56,36 @@ static void temporal_filter_predictors_mb_c(
|
|||
mv_precision_uv = MV_PRECISION_Q3;
|
||||
}
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
av1_highbd_build_inter_predictor(y_mb_ptr, stride, &pred[0], 16, &mv, scale,
|
||||
16, 16, which_mv, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
0, MV_PRECISION_Q3, x, y, xd);
|
||||
&warp_types, x, y, 0, MV_PRECISION_Q3, x,
|
||||
y, xd, can_use_previous);
|
||||
|
||||
av1_highbd_build_inter_predictor(u_mb_ptr, uv_stride, &pred[256],
|
||||
uv_block_width, &mv, scale, uv_block_width,
|
||||
uv_block_height, which_mv, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
1, mv_precision_uv, x, y, xd);
|
||||
av1_highbd_build_inter_predictor(
|
||||
u_mb_ptr, uv_stride, &pred[256], uv_block_width, &mv, scale,
|
||||
uv_block_width, uv_block_height, which_mv, interp_filters, &warp_types,
|
||||
x, y, 1, mv_precision_uv, x, y, xd, can_use_previous);
|
||||
|
||||
av1_highbd_build_inter_predictor(v_mb_ptr, uv_stride, &pred[512],
|
||||
uv_block_width, &mv, scale, uv_block_width,
|
||||
uv_block_height, which_mv, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
2, mv_precision_uv, x, y, xd);
|
||||
av1_highbd_build_inter_predictor(
|
||||
v_mb_ptr, uv_stride, &pred[512], uv_block_width, &mv, scale,
|
||||
uv_block_width, uv_block_height, which_mv, interp_filters, &warp_types,
|
||||
x, y, 2, mv_precision_uv, x, y, xd, can_use_previous);
|
||||
return;
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
av1_build_inter_predictor(y_mb_ptr, stride, &pred[0], 16, &mv, scale, 16, 16,
|
||||
&conv_params, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y, 0, 0,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
MV_PRECISION_Q3, x, y, xd);
|
||||
&conv_params, interp_filters, &warp_types, x, y, 0,
|
||||
0, MV_PRECISION_Q3, x, y, xd, can_use_previous);
|
||||
|
||||
av1_build_inter_predictor(u_mb_ptr, uv_stride, &pred[256], uv_block_width,
|
||||
&mv, scale, uv_block_width, uv_block_height,
|
||||
&conv_params, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y, 1, 0,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
mv_precision_uv, x, y, xd);
|
||||
&conv_params, interp_filters, &warp_types, x, y, 1,
|
||||
0, mv_precision_uv, x, y, xd, can_use_previous);
|
||||
|
||||
av1_build_inter_predictor(v_mb_ptr, uv_stride, &pred[512], uv_block_width,
|
||||
&mv, scale, uv_block_width, uv_block_height,
|
||||
&conv_params, interp_filters,
|
||||
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
&warp_types, x, y, 2, 0,
|
||||
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
|
||||
mv_precision_uv, x, y, xd);
|
||||
&conv_params, interp_filters, &warp_types, x, y, 2,
|
||||
0, mv_precision_uv, x, y, xd, can_use_previous);
|
||||
}
|
||||
|
||||
void av1_temporal_filter_apply_c(uint8_t *frame1, unsigned int stride,
|
||||
|
|
@ -176,7 +149,6 @@ void av1_temporal_filter_apply_c(uint8_t *frame1, unsigned int stride,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
void av1_highbd_temporal_filter_apply_c(
|
||||
uint8_t *frame1_8, unsigned int stride, uint8_t *frame2_8,
|
||||
unsigned int block_width, unsigned int block_height, int strength,
|
||||
|
|
@ -238,7 +210,6 @@ void av1_highbd_temporal_filter_apply_c(
|
|||
byte += stride - block_width;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
|
||||
static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
||||
uint8_t *arf_frame_buf,
|
||||
|
|
@ -255,7 +226,7 @@ static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
|||
int cost_list[5];
|
||||
MvLimits tmp_mv_limits = x->mv_limits;
|
||||
|
||||
MV best_ref_mv1 = { 0, 0 };
|
||||
MV best_ref_mv1 = kZeroMv;
|
||||
MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
|
||||
|
||||
// Save input state
|
||||
|
|
@ -276,8 +247,8 @@ static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
|||
|
||||
av1_set_mv_search_range(&x->mv_limits, &best_ref_mv1);
|
||||
|
||||
x->mvcost = x->mv_cost_stack[0];
|
||||
x->nmvjointcost = x->nmv_vec_cost[0];
|
||||
x->mvcost = x->mv_cost_stack;
|
||||
x->nmvjointcost = x->nmv_vec_cost;
|
||||
|
||||
// Use mv costing from x->mvcost directly
|
||||
av1_hex_search(x, &best_ref_mv1_full, step_param, sadpb, 1,
|
||||
|
|
@ -286,9 +257,8 @@ static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
|||
|
||||
x->mv_limits = tmp_mv_limits;
|
||||
|
||||
// Ignore mv costing by sending NULL pointer instead of cost array
|
||||
#if CONFIG_AMVR
|
||||
if (cpi->common.cur_frame_mv_precision_level == 1) {
|
||||
// Ignore mv costing by sending NULL pointer instead of cost array
|
||||
if (cpi->common.cur_frame_force_integer_mv == 1) {
|
||||
const uint8_t *const src_address = x->plane[0].src.buf;
|
||||
const int src_stride = x->plane[0].src.stride;
|
||||
const uint8_t *const y = xd->plane[0].pre[0].buf;
|
||||
|
|
@ -301,17 +271,15 @@ static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
|||
bestsme = cpi->fn_ptr[BLOCK_16X16].vf(y + offset, y_stride, src_address,
|
||||
src_stride, &sse);
|
||||
} else {
|
||||
#endif
|
||||
bestsme = cpi->find_fractional_mv_step(
|
||||
x, &best_ref_mv1, cpi->common.allow_high_precision_mv, x->errorperbit,
|
||||
x, &cpi->common, 0, 0, &best_ref_mv1,
|
||||
cpi->common.allow_high_precision_mv, x->errorperbit,
|
||||
&cpi->fn_ptr[BLOCK_16X16], 0, mv_sf->subpel_iters_per_step,
|
||||
cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL,
|
||||
NULL, 0, 0, 0, 0, 0);
|
||||
#if CONFIG_AMVR
|
||||
}
|
||||
#endif
|
||||
|
||||
x->e_mbd.mi[0]->bmi[0].as_mv[0] = x->best_mv;
|
||||
x->e_mbd.mi[0]->mv[0] = x->best_mv;
|
||||
|
||||
// Restore input state
|
||||
x->plane[0].src = src;
|
||||
|
|
@ -321,13 +289,12 @@ static int temporal_filter_find_matching_mb_c(AV1_COMP *cpi,
|
|||
}
|
||||
|
||||
static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
||||
#if CONFIG_BGSPRITE
|
||||
YV12_BUFFER_CONFIG *target,
|
||||
#endif // CONFIG_BGSPRITE
|
||||
YV12_BUFFER_CONFIG **frames,
|
||||
int frame_count, int alt_ref_index,
|
||||
int strength,
|
||||
struct scale_factors *scale) {
|
||||
const AV1_COMMON *cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
int byte;
|
||||
int frame;
|
||||
int mb_col, mb_row;
|
||||
|
|
@ -341,28 +308,22 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
MACROBLOCKD *mbd = &cpi->td.mb.e_mbd;
|
||||
YV12_BUFFER_CONFIG *f = frames[alt_ref_index];
|
||||
uint8_t *dst1, *dst2;
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, predictor16[16 * 16 * 3]);
|
||||
DECLARE_ALIGNED(16, uint8_t, predictor8[16 * 16 * 3]);
|
||||
DECLARE_ALIGNED(32, uint16_t, predictor16[16 * 16 * 3]);
|
||||
DECLARE_ALIGNED(32, uint8_t, predictor8[16 * 16 * 3]);
|
||||
uint8_t *predictor;
|
||||
#else
|
||||
DECLARE_ALIGNED(16, uint8_t, predictor[16 * 16 * 3]);
|
||||
#endif
|
||||
const int mb_uv_height = 16 >> mbd->plane[1].subsampling_y;
|
||||
const int mb_uv_width = 16 >> mbd->plane[1].subsampling_x;
|
||||
|
||||
// Save input state
|
||||
uint8_t *input_buffer[MAX_MB_PLANE];
|
||||
int i;
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
predictor = CONVERT_TO_BYTEPTR(predictor16);
|
||||
} else {
|
||||
predictor = predictor8;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) input_buffer[i] = mbd->plane[i].pre[0].buf;
|
||||
for (i = 0; i < num_planes; i++) input_buffer[i] = mbd->plane[i].pre[0].buf;
|
||||
|
||||
for (mb_row = 0; mb_row < mb_rows; mb_row++) {
|
||||
// Source frames are extended to 16 pixels. This is different than
|
||||
|
|
@ -399,8 +360,9 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
|
||||
if (frames[frame] == NULL) continue;
|
||||
|
||||
mbd->mi[0]->bmi[0].as_mv[0].as_mv.row = 0;
|
||||
mbd->mi[0]->bmi[0].as_mv[0].as_mv.col = 0;
|
||||
mbd->mi[0]->mv[0].as_mv.row = 0;
|
||||
mbd->mi[0]->mv[0].as_mv.col = 0;
|
||||
mbd->mi[0]->motion_mode = SIMPLE_TRANSLATION;
|
||||
|
||||
if (frame == alt_ref_index) {
|
||||
filter_weight = 2;
|
||||
|
|
@ -422,60 +384,51 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
mbd, frames[frame]->y_buffer + mb_y_offset,
|
||||
frames[frame]->u_buffer + mb_uv_offset,
|
||||
frames[frame]->v_buffer + mb_uv_offset, frames[frame]->y_stride,
|
||||
mb_uv_width, mb_uv_height, mbd->mi[0]->bmi[0].as_mv[0].as_mv.row,
|
||||
mbd->mi[0]->bmi[0].as_mv[0].as_mv.col, predictor, scale,
|
||||
mb_col * 16, mb_row * 16);
|
||||
mb_uv_width, mb_uv_height, mbd->mi[0]->mv[0].as_mv.row,
|
||||
mbd->mi[0]->mv[0].as_mv.col, predictor, scale, mb_col * 16,
|
||||
mb_row * 16, cm->allow_warped_motion);
|
||||
|
||||
// Apply the filter (YUV)
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
// Apply the filter (YUV)
|
||||
if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
int adj_strength = strength + 2 * (mbd->bd - 8);
|
||||
av1_highbd_temporal_filter_apply(
|
||||
f->y_buffer + mb_y_offset, f->y_stride, predictor, 16, 16,
|
||||
adj_strength, filter_weight, accumulator, count);
|
||||
av1_highbd_temporal_filter_apply(
|
||||
f->u_buffer + mb_uv_offset, f->uv_stride, predictor + 256,
|
||||
mb_uv_width, mb_uv_height, adj_strength, filter_weight,
|
||||
accumulator + 256, count + 256);
|
||||
av1_highbd_temporal_filter_apply(
|
||||
f->v_buffer + mb_uv_offset, f->uv_stride, predictor + 512,
|
||||
mb_uv_width, mb_uv_height, adj_strength, filter_weight,
|
||||
accumulator + 512, count + 512);
|
||||
if (num_planes > 1) {
|
||||
av1_highbd_temporal_filter_apply(
|
||||
f->u_buffer + mb_uv_offset, f->uv_stride, predictor + 256,
|
||||
mb_uv_width, mb_uv_height, adj_strength, filter_weight,
|
||||
accumulator + 256, count + 256);
|
||||
av1_highbd_temporal_filter_apply(
|
||||
f->v_buffer + mb_uv_offset, f->uv_stride, predictor + 512,
|
||||
mb_uv_width, mb_uv_height, adj_strength, filter_weight,
|
||||
accumulator + 512, count + 512);
|
||||
}
|
||||
} else {
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
av1_temporal_filter_apply_c(f->y_buffer + mb_y_offset, f->y_stride,
|
||||
predictor, 16, 16, strength,
|
||||
filter_weight, accumulator, count);
|
||||
av1_temporal_filter_apply_c(
|
||||
f->u_buffer + mb_uv_offset, f->uv_stride, predictor + 256,
|
||||
mb_uv_width, mb_uv_height, strength, filter_weight,
|
||||
accumulator + 256, count + 256);
|
||||
av1_temporal_filter_apply_c(
|
||||
f->v_buffer + mb_uv_offset, f->uv_stride, predictor + 512,
|
||||
mb_uv_width, mb_uv_height, strength, filter_weight,
|
||||
accumulator + 512, count + 512);
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
if (num_planes > 1) {
|
||||
av1_temporal_filter_apply_c(
|
||||
f->u_buffer + mb_uv_offset, f->uv_stride, predictor + 256,
|
||||
mb_uv_width, mb_uv_height, strength, filter_weight,
|
||||
accumulator + 256, count + 256);
|
||||
av1_temporal_filter_apply_c(
|
||||
f->v_buffer + mb_uv_offset, f->uv_stride, predictor + 512,
|
||||
mb_uv_width, mb_uv_height, strength, filter_weight,
|
||||
accumulator + 512, count + 512);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize filter output to produce AltRef frame
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
// Normalize filter output to produce AltRef frame
|
||||
if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
uint16_t *dst1_16;
|
||||
uint16_t *dst2_16;
|
||||
#if CONFIG_BGSPRITE
|
||||
dst1 = target->y_buffer;
|
||||
#else
|
||||
dst1 = cpi->alt_ref_buffer.y_buffer;
|
||||
#endif // CONFIG_BGSPRITE
|
||||
dst1_16 = CONVERT_TO_SHORTPTR(dst1);
|
||||
#if CONFIG_BGSPRITE
|
||||
stride = target->y_stride;
|
||||
#else
|
||||
stride = cpi->alt_ref_buffer.y_stride;
|
||||
#endif // CONFIG_BGSPRITE
|
||||
byte = mb_y_offset;
|
||||
for (i = 0, k = 0; i < 16; i++) {
|
||||
for (j = 0; j < 16; j++, k++) {
|
||||
|
|
@ -488,40 +441,31 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
|
||||
byte += stride - 16;
|
||||
}
|
||||
|
||||
dst1 = cpi->alt_ref_buffer.u_buffer;
|
||||
dst2 = cpi->alt_ref_buffer.v_buffer;
|
||||
dst1_16 = CONVERT_TO_SHORTPTR(dst1);
|
||||
dst2_16 = CONVERT_TO_SHORTPTR(dst2);
|
||||
stride = cpi->alt_ref_buffer.uv_stride;
|
||||
byte = mb_uv_offset;
|
||||
for (i = 0, k = 256; i < mb_uv_height; i++) {
|
||||
for (j = 0; j < mb_uv_width; j++, k++) {
|
||||
int m = k + 256;
|
||||
|
||||
// U
|
||||
dst1_16[byte] =
|
||||
(uint16_t)OD_DIVU(accumulator[k] + (count[k] >> 1), count[k]);
|
||||
|
||||
// V
|
||||
dst2_16[byte] =
|
||||
(uint16_t)OD_DIVU(accumulator[m] + (count[m] >> 1), count[m]);
|
||||
|
||||
// move to next pixel
|
||||
byte++;
|
||||
if (num_planes > 1) {
|
||||
dst1 = cpi->alt_ref_buffer.u_buffer;
|
||||
dst2 = cpi->alt_ref_buffer.v_buffer;
|
||||
dst1_16 = CONVERT_TO_SHORTPTR(dst1);
|
||||
dst2_16 = CONVERT_TO_SHORTPTR(dst2);
|
||||
stride = cpi->alt_ref_buffer.uv_stride;
|
||||
byte = mb_uv_offset;
|
||||
for (i = 0, k = 256; i < mb_uv_height; i++) {
|
||||
for (j = 0; j < mb_uv_width; j++, k++) {
|
||||
int m = k + 256;
|
||||
// U
|
||||
dst1_16[byte] =
|
||||
(uint16_t)OD_DIVU(accumulator[k] + (count[k] >> 1), count[k]);
|
||||
// V
|
||||
dst2_16[byte] =
|
||||
(uint16_t)OD_DIVU(accumulator[m] + (count[m] >> 1), count[m]);
|
||||
// move to next pixel
|
||||
byte++;
|
||||
}
|
||||
byte += stride - mb_uv_width;
|
||||
}
|
||||
|
||||
byte += stride - mb_uv_width;
|
||||
}
|
||||
} else {
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
#if CONFIG_BGSPRITE
|
||||
dst1 = target->y_buffer;
|
||||
stride = target->y_stride;
|
||||
#else
|
||||
dst1 = cpi->alt_ref_buffer.y_buffer;
|
||||
stride = cpi->alt_ref_buffer.y_stride;
|
||||
#endif // CONFIG_BGSPRITE
|
||||
dst1 = cpi->alt_ref_buffer.y_buffer;
|
||||
stride = cpi->alt_ref_buffer.y_stride;
|
||||
byte = mb_y_offset;
|
||||
for (i = 0, k = 0; i < 16; i++) {
|
||||
for (j = 0; j < 16; j++, k++) {
|
||||
|
|
@ -533,36 +477,27 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
}
|
||||
byte += stride - 16;
|
||||
}
|
||||
#if CONFIG_BGSPRITE
|
||||
dst1 = target->u_buffer;
|
||||
dst2 = target->v_buffer;
|
||||
stride = target->uv_stride;
|
||||
#else
|
||||
dst1 = cpi->alt_ref_buffer.u_buffer;
|
||||
dst2 = cpi->alt_ref_buffer.v_buffer;
|
||||
stride = cpi->alt_ref_buffer.uv_stride;
|
||||
#endif // CONFIG_BGSPRITE
|
||||
byte = mb_uv_offset;
|
||||
for (i = 0, k = 256; i < mb_uv_height; i++) {
|
||||
for (j = 0; j < mb_uv_width; j++, k++) {
|
||||
int m = k + 256;
|
||||
|
||||
// U
|
||||
dst1[byte] =
|
||||
(uint8_t)OD_DIVU(accumulator[k] + (count[k] >> 1), count[k]);
|
||||
|
||||
// V
|
||||
dst2[byte] =
|
||||
(uint8_t)OD_DIVU(accumulator[m] + (count[m] >> 1), count[m]);
|
||||
|
||||
// move to next pixel
|
||||
byte++;
|
||||
if (num_planes > 1) {
|
||||
dst1 = cpi->alt_ref_buffer.u_buffer;
|
||||
dst2 = cpi->alt_ref_buffer.v_buffer;
|
||||
stride = cpi->alt_ref_buffer.uv_stride;
|
||||
byte = mb_uv_offset;
|
||||
for (i = 0, k = 256; i < mb_uv_height; i++) {
|
||||
for (j = 0; j < mb_uv_width; j++, k++) {
|
||||
int m = k + 256;
|
||||
// U
|
||||
dst1[byte] =
|
||||
(uint8_t)OD_DIVU(accumulator[k] + (count[k] >> 1), count[k]);
|
||||
// V
|
||||
dst2[byte] =
|
||||
(uint8_t)OD_DIVU(accumulator[m] + (count[m] >> 1), count[m]);
|
||||
// move to next pixel
|
||||
byte++;
|
||||
}
|
||||
byte += stride - mb_uv_width;
|
||||
}
|
||||
byte += stride - mb_uv_width;
|
||||
}
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
}
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
mb_y_offset += 16;
|
||||
mb_uv_offset += mb_uv_width;
|
||||
}
|
||||
|
|
@ -571,7 +506,7 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi,
|
|||
}
|
||||
|
||||
// Restore input state
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) mbd->plane[i].pre[0].buf = input_buffer[i];
|
||||
for (i = 0; i < num_planes; i++) mbd->plane[i].pre[0].buf = input_buffer[i];
|
||||
}
|
||||
|
||||
// Apply buffer limits and context specific adjustments to arnr filter.
|
||||
|
|
@ -633,11 +568,7 @@ static void adjust_arnr_filter(AV1_COMP *cpi, int distance, int group_boost,
|
|||
*arnr_strength = strength;
|
||||
}
|
||||
|
||||
void av1_temporal_filter(AV1_COMP *cpi,
|
||||
#if CONFIG_BGSPRITE
|
||||
YV12_BUFFER_CONFIG *bg, YV12_BUFFER_CONFIG *target,
|
||||
#endif // CONFIG_BGSPRITE
|
||||
int distance) {
|
||||
void av1_temporal_filter(AV1_COMP *cpi, int distance) {
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
int frame;
|
||||
int frames_to_blur;
|
||||
|
|
@ -647,17 +578,14 @@ void av1_temporal_filter(AV1_COMP *cpi,
|
|||
int frames_to_blur_forward;
|
||||
struct scale_factors sf;
|
||||
YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
|
||||
#if CONFIG_EXT_REFS
|
||||
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
// Apply context specific adjustments to the arnr filter parameters.
|
||||
adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, &strength);
|
||||
// TODO(weitinglin): Currently, we enforce the filtering strength on
|
||||
// extra ARFs' to be zeros. We should investigate in which
|
||||
// case it is more beneficial to use non-zero strength
|
||||
// filtering.
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(weitinglin): Currently, we enforce the filtering strength on
|
||||
// extra ARFs' to be zeros. We should investigate in which
|
||||
// case it is more beneficial to use non-zero strength
|
||||
// filtering.
|
||||
if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE) {
|
||||
strength = 0;
|
||||
frames_to_blur = 1;
|
||||
|
|
@ -685,7 +613,7 @@ void av1_temporal_filter(AV1_COMP *cpi,
|
|||
cpi->is_arf_filter_off[which_arf] = 1;
|
||||
else
|
||||
cpi->is_arf_filter_off[which_arf] = 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->common.showable_frame = cpi->is_arf_filter_off[which_arf];
|
||||
|
||||
frames_to_blur_backward = (frames_to_blur / 2);
|
||||
frames_to_blur_forward = ((frames_to_blur - 1) / 2);
|
||||
|
|
@ -694,40 +622,20 @@ void av1_temporal_filter(AV1_COMP *cpi,
|
|||
// Setup frame pointers, NULL indicates frame not included in filter.
|
||||
for (frame = 0; frame < frames_to_blur; ++frame) {
|
||||
const int which_buffer = start_frame - frame;
|
||||
#if CONFIG_BGSPRITE
|
||||
if (frame == frames_to_blur_backward && bg != NULL) {
|
||||
// Insert bg into frames at ARF index.
|
||||
frames[frames_to_blur - 1 - frame] = bg;
|
||||
} else {
|
||||
#endif // CONFIG_BGSPRITE
|
||||
struct lookahead_entry *buf =
|
||||
av1_lookahead_peek(cpi->lookahead, which_buffer);
|
||||
frames[frames_to_blur - 1 - frame] = &buf->img;
|
||||
#if CONFIG_BGSPRITE
|
||||
}
|
||||
#endif // CONFIG_BGSPRITE
|
||||
struct lookahead_entry *buf =
|
||||
av1_lookahead_peek(cpi->lookahead, which_buffer);
|
||||
frames[frames_to_blur - 1 - frame] = &buf->img;
|
||||
}
|
||||
|
||||
if (frames_to_blur > 0) {
|
||||
// Setup scaling factors. Scaling on each of the arnr frames is not
|
||||
// supported.
|
||||
// ARF is produced at the native frame size and resized when coded.
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
av1_setup_scale_factors_for_frame(
|
||||
&sf, frames[0]->y_crop_width, frames[0]->y_crop_height,
|
||||
frames[0]->y_crop_width, frames[0]->y_crop_height,
|
||||
cpi->common.use_highbitdepth);
|
||||
#else
|
||||
// Setup scaling factors. Scaling on each of the arnr frames is not
|
||||
// supported.
|
||||
// ARF is produced at the native frame size and resized when coded.
|
||||
av1_setup_scale_factors_for_frame(
|
||||
&sf, frames[0]->y_crop_width, frames[0]->y_crop_height,
|
||||
frames[0]->y_crop_width, frames[0]->y_crop_height);
|
||||
#endif // CONFIG_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
temporal_filter_iterate_c(cpi,
|
||||
#if CONFIG_BGSPRITE
|
||||
target,
|
||||
#endif // CONFIG_BGSPRITE
|
||||
frames, frames_to_blur, frames_to_blur_backward,
|
||||
strength, &sf);
|
||||
temporal_filter_iterate_c(cpi, frames, frames_to_blur,
|
||||
frames_to_blur_backward, strength, &sf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void av1_temporal_filter(AV1_COMP *cpi,
|
||||
#if CONFIG_BGSPRITE
|
||||
YV12_BUFFER_CONFIG *bg, YV12_BUFFER_CONFIG *target,
|
||||
#endif // CONFIG_BGSPRITE
|
||||
int distance);
|
||||
void av1_temporal_filter(AV1_COMP *cpi, int distance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
820
third_party/aom/av1/encoder/tokenize.c
vendored
820
third_party/aom/av1/encoder/tokenize.c
vendored
|
|
@ -23,314 +23,13 @@
|
|||
|
||||
#include "av1/encoder/cost.h"
|
||||
#include "av1/encoder/encoder.h"
|
||||
#if CONFIG_LV_MAP
|
||||
#include "av1/encoder/encodetxb.c"
|
||||
#endif
|
||||
#include "av1/encoder/encodetxb.h"
|
||||
#include "av1/encoder/rdopt.h"
|
||||
#include "av1/encoder/tokenize.h"
|
||||
|
||||
static const TOKENVALUE dct_cat_lt_10_value_tokens[] = {
|
||||
{ 9, 63 }, { 9, 61 }, { 9, 59 }, { 9, 57 }, { 9, 55 }, { 9, 53 }, { 9, 51 },
|
||||
{ 9, 49 }, { 9, 47 }, { 9, 45 }, { 9, 43 }, { 9, 41 }, { 9, 39 }, { 9, 37 },
|
||||
{ 9, 35 }, { 9, 33 }, { 9, 31 }, { 9, 29 }, { 9, 27 }, { 9, 25 }, { 9, 23 },
|
||||
{ 9, 21 }, { 9, 19 }, { 9, 17 }, { 9, 15 }, { 9, 13 }, { 9, 11 }, { 9, 9 },
|
||||
{ 9, 7 }, { 9, 5 }, { 9, 3 }, { 9, 1 }, { 8, 31 }, { 8, 29 }, { 8, 27 },
|
||||
{ 8, 25 }, { 8, 23 }, { 8, 21 }, { 8, 19 }, { 8, 17 }, { 8, 15 }, { 8, 13 },
|
||||
{ 8, 11 }, { 8, 9 }, { 8, 7 }, { 8, 5 }, { 8, 3 }, { 8, 1 }, { 7, 15 },
|
||||
{ 7, 13 }, { 7, 11 }, { 7, 9 }, { 7, 7 }, { 7, 5 }, { 7, 3 }, { 7, 1 },
|
||||
{ 6, 7 }, { 6, 5 }, { 6, 3 }, { 6, 1 }, { 5, 3 }, { 5, 1 }, { 4, 1 },
|
||||
{ 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
|
||||
{ 4, 0 }, { 5, 0 }, { 5, 2 }, { 6, 0 }, { 6, 2 }, { 6, 4 }, { 6, 6 },
|
||||
{ 7, 0 }, { 7, 2 }, { 7, 4 }, { 7, 6 }, { 7, 8 }, { 7, 10 }, { 7, 12 },
|
||||
{ 7, 14 }, { 8, 0 }, { 8, 2 }, { 8, 4 }, { 8, 6 }, { 8, 8 }, { 8, 10 },
|
||||
{ 8, 12 }, { 8, 14 }, { 8, 16 }, { 8, 18 }, { 8, 20 }, { 8, 22 }, { 8, 24 },
|
||||
{ 8, 26 }, { 8, 28 }, { 8, 30 }, { 9, 0 }, { 9, 2 }, { 9, 4 }, { 9, 6 },
|
||||
{ 9, 8 }, { 9, 10 }, { 9, 12 }, { 9, 14 }, { 9, 16 }, { 9, 18 }, { 9, 20 },
|
||||
{ 9, 22 }, { 9, 24 }, { 9, 26 }, { 9, 28 }, { 9, 30 }, { 9, 32 }, { 9, 34 },
|
||||
{ 9, 36 }, { 9, 38 }, { 9, 40 }, { 9, 42 }, { 9, 44 }, { 9, 46 }, { 9, 48 },
|
||||
{ 9, 50 }, { 9, 52 }, { 9, 54 }, { 9, 56 }, { 9, 58 }, { 9, 60 }, { 9, 62 }
|
||||
};
|
||||
const TOKENVALUE *av1_dct_cat_lt_10_value_tokens =
|
||||
dct_cat_lt_10_value_tokens +
|
||||
(sizeof(dct_cat_lt_10_value_tokens) / sizeof(*dct_cat_lt_10_value_tokens)) /
|
||||
2;
|
||||
// The corresponding costs of the extrabits for the tokens in the above table
|
||||
// are stored in the table below. The values are obtained from looking up the
|
||||
// entry for the specified extrabits in the table corresponding to the token
|
||||
// (as defined in cost element av1_extra_bits)
|
||||
// e.g. {9, 63} maps to cat5_cost[63 >> 1], {1, 1} maps to sign_cost[1 >> 1]
|
||||
static const int dct_cat_lt_10_value_cost[] = {
|
||||
3773, 3750, 3704, 3681, 3623, 3600, 3554, 3531, 3432, 3409, 3363, 3340, 3282,
|
||||
3259, 3213, 3190, 3136, 3113, 3067, 3044, 2986, 2963, 2917, 2894, 2795, 2772,
|
||||
2726, 2703, 2645, 2622, 2576, 2553, 3197, 3116, 3058, 2977, 2881, 2800, 2742,
|
||||
2661, 2615, 2534, 2476, 2395, 2299, 2218, 2160, 2079, 2566, 2427, 2334, 2195,
|
||||
2023, 1884, 1791, 1652, 1893, 1696, 1453, 1256, 1229, 864, 512, 512, 512,
|
||||
512, 0, 512, 512, 512, 512, 864, 1229, 1256, 1453, 1696, 1893, 1652,
|
||||
1791, 1884, 2023, 2195, 2334, 2427, 2566, 2079, 2160, 2218, 2299, 2395, 2476,
|
||||
2534, 2615, 2661, 2742, 2800, 2881, 2977, 3058, 3116, 3197, 2553, 2576, 2622,
|
||||
2645, 2703, 2726, 2772, 2795, 2894, 2917, 2963, 2986, 3044, 3067, 3113, 3136,
|
||||
3190, 3213, 3259, 3282, 3340, 3363, 3409, 3432, 3531, 3554, 3600, 3623, 3681,
|
||||
3704, 3750, 3773,
|
||||
};
|
||||
const int *av1_dct_cat_lt_10_value_cost =
|
||||
dct_cat_lt_10_value_cost +
|
||||
(sizeof(dct_cat_lt_10_value_cost) / sizeof(*dct_cat_lt_10_value_cost)) / 2;
|
||||
|
||||
// Array indices are identical to previously-existing CONTEXT_NODE indices
|
||||
/* clang-format off */
|
||||
const aom_tree_index av1_coef_tree[TREE_SIZE(ENTROPY_TOKENS)] = {
|
||||
-EOB_TOKEN, 2, // 0 = EOB
|
||||
-ZERO_TOKEN, 4, // 1 = ZERO
|
||||
-ONE_TOKEN, 6, // 2 = ONE
|
||||
8, 12, // 3 = LOW_VAL
|
||||
-TWO_TOKEN, 10, // 4 = TWO
|
||||
-THREE_TOKEN, -FOUR_TOKEN, // 5 = THREE
|
||||
14, 16, // 6 = HIGH_LOW
|
||||
-CATEGORY1_TOKEN, -CATEGORY2_TOKEN, // 7 = CAT_ONE
|
||||
18, 20, // 8 = CAT_THREEFOUR
|
||||
-CATEGORY3_TOKEN, -CATEGORY4_TOKEN, // 9 = CAT_THREE
|
||||
-CATEGORY5_TOKEN, -CATEGORY6_TOKEN // 10 = CAT_FIVE
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static const int16_t zero_cost[] = { 0 };
|
||||
static const int16_t sign_cost[1] = { 512 };
|
||||
static const int16_t cat1_cost[1 << 1] = { 864, 1229 };
|
||||
static const int16_t cat2_cost[1 << 2] = { 1256, 1453, 1696, 1893 };
|
||||
static const int16_t cat3_cost[1 << 3] = { 1652, 1791, 1884, 2023,
|
||||
2195, 2334, 2427, 2566 };
|
||||
static const int16_t cat4_cost[1 << 4] = { 2079, 2160, 2218, 2299, 2395, 2476,
|
||||
2534, 2615, 2661, 2742, 2800, 2881,
|
||||
2977, 3058, 3116, 3197 };
|
||||
static const int16_t cat5_cost[1 << 5] = {
|
||||
2553, 2576, 2622, 2645, 2703, 2726, 2772, 2795, 2894, 2917, 2963,
|
||||
2986, 3044, 3067, 3113, 3136, 3190, 3213, 3259, 3282, 3340, 3363,
|
||||
3409, 3432, 3531, 3554, 3600, 3623, 3681, 3704, 3750, 3773
|
||||
};
|
||||
const int16_t av1_cat6_low_cost[256] = {
|
||||
3378, 3390, 3401, 3413, 3435, 3447, 3458, 3470, 3517, 3529, 3540, 3552, 3574,
|
||||
3586, 3597, 3609, 3671, 3683, 3694, 3706, 3728, 3740, 3751, 3763, 3810, 3822,
|
||||
3833, 3845, 3867, 3879, 3890, 3902, 3973, 3985, 3996, 4008, 4030, 4042, 4053,
|
||||
4065, 4112, 4124, 4135, 4147, 4169, 4181, 4192, 4204, 4266, 4278, 4289, 4301,
|
||||
4323, 4335, 4346, 4358, 4405, 4417, 4428, 4440, 4462, 4474, 4485, 4497, 4253,
|
||||
4265, 4276, 4288, 4310, 4322, 4333, 4345, 4392, 4404, 4415, 4427, 4449, 4461,
|
||||
4472, 4484, 4546, 4558, 4569, 4581, 4603, 4615, 4626, 4638, 4685, 4697, 4708,
|
||||
4720, 4742, 4754, 4765, 4777, 4848, 4860, 4871, 4883, 4905, 4917, 4928, 4940,
|
||||
4987, 4999, 5010, 5022, 5044, 5056, 5067, 5079, 5141, 5153, 5164, 5176, 5198,
|
||||
5210, 5221, 5233, 5280, 5292, 5303, 5315, 5337, 5349, 5360, 5372, 4988, 5000,
|
||||
5011, 5023, 5045, 5057, 5068, 5080, 5127, 5139, 5150, 5162, 5184, 5196, 5207,
|
||||
5219, 5281, 5293, 5304, 5316, 5338, 5350, 5361, 5373, 5420, 5432, 5443, 5455,
|
||||
5477, 5489, 5500, 5512, 5583, 5595, 5606, 5618, 5640, 5652, 5663, 5675, 5722,
|
||||
5734, 5745, 5757, 5779, 5791, 5802, 5814, 5876, 5888, 5899, 5911, 5933, 5945,
|
||||
5956, 5968, 6015, 6027, 6038, 6050, 6072, 6084, 6095, 6107, 5863, 5875, 5886,
|
||||
5898, 5920, 5932, 5943, 5955, 6002, 6014, 6025, 6037, 6059, 6071, 6082, 6094,
|
||||
6156, 6168, 6179, 6191, 6213, 6225, 6236, 6248, 6295, 6307, 6318, 6330, 6352,
|
||||
6364, 6375, 6387, 6458, 6470, 6481, 6493, 6515, 6527, 6538, 6550, 6597, 6609,
|
||||
6620, 6632, 6654, 6666, 6677, 6689, 6751, 6763, 6774, 6786, 6808, 6820, 6831,
|
||||
6843, 6890, 6902, 6913, 6925, 6947, 6959, 6970, 6982
|
||||
};
|
||||
const int av1_cat6_high_cost[CAT6_HIGH_COST_ENTRIES] = {
|
||||
100, 2263, 2739, 4902, 3160, 5323, 5799, 7962, 3678, 5841, 6317,
|
||||
8480, 6738, 8901, 9377, 11540, 3678, 5841, 6317, 8480, 6738, 8901,
|
||||
9377, 11540, 7256, 9419, 9895, 12058, 10316, 12479, 12955, 15118, 3678,
|
||||
5841, 6317, 8480, 6738, 8901, 9377, 11540, 7256, 9419, 9895, 12058,
|
||||
10316, 12479, 12955, 15118, 7256, 9419, 9895, 12058, 10316, 12479, 12955,
|
||||
15118, 10834, 12997, 13473, 15636, 13894, 16057, 16533, 18696,
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
4193, 6356, 6832, 8995, 7253, 9416, 9892, 12055, 7771, 9934, 10410,
|
||||
12573, 10831, 12994, 13470, 15633, 7771, 9934, 10410, 12573, 10831, 12994,
|
||||
13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 7771,
|
||||
9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151,
|
||||
14409, 16572, 17048, 19211, 11349, 13512, 13988, 16151, 14409, 16572, 17048,
|
||||
19211, 14927, 17090, 17566, 19729, 17987, 20150, 20626, 22789, 4193, 6356,
|
||||
6832, 8995, 7253, 9416, 9892, 12055, 7771, 9934, 10410, 12573, 10831,
|
||||
12994, 13470, 15633, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633,
|
||||
11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 7771, 9934, 10410,
|
||||
12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572,
|
||||
17048, 19211, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 14927,
|
||||
17090, 17566, 19729, 17987, 20150, 20626, 22789, 8286, 10449, 10925, 13088,
|
||||
11346, 13509, 13985, 16148, 11864, 14027, 14503, 16666, 14924, 17087, 17563,
|
||||
19726, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605,
|
||||
18081, 20244, 18502, 20665, 21141, 23304, 11864, 14027, 14503, 16666, 14924,
|
||||
17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304,
|
||||
15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 19020, 21183, 21659,
|
||||
23822, 22080, 24243, 24719, 26882, 4193, 6356, 6832, 8995, 7253, 9416,
|
||||
9892, 12055, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 7771,
|
||||
9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151,
|
||||
14409, 16572, 17048, 19211, 7771, 9934, 10410, 12573, 10831, 12994, 13470,
|
||||
15633, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 11349, 13512,
|
||||
13988, 16151, 14409, 16572, 17048, 19211, 14927, 17090, 17566, 19729, 17987,
|
||||
20150, 20626, 22789, 8286, 10449, 10925, 13088, 11346, 13509, 13985, 16148,
|
||||
11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027, 14503,
|
||||
16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665,
|
||||
21141, 23304, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442,
|
||||
17605, 18081, 20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081, 20244,
|
||||
18502, 20665, 21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243, 24719,
|
||||
26882, 8286, 10449, 10925, 13088, 11346, 13509, 13985, 16148, 11864, 14027,
|
||||
14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027, 14503, 16666, 14924,
|
||||
17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304,
|
||||
11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081,
|
||||
20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081, 20244, 18502, 20665,
|
||||
21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243, 24719, 26882, 12379,
|
||||
14542, 15018, 17181, 15439, 17602, 18078, 20241, 15957, 18120, 18596, 20759,
|
||||
19017, 21180, 21656, 23819, 15957, 18120, 18596, 20759, 19017, 21180, 21656,
|
||||
23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 15957, 18120,
|
||||
18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595,
|
||||
24758, 25234, 27397, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397,
|
||||
23113, 25276, 25752, 27915, 26173, 28336, 28812, 30975, 4193, 6356, 6832,
|
||||
8995, 7253, 9416, 9892, 12055, 7771, 9934, 10410, 12573, 10831, 12994,
|
||||
13470, 15633, 7771, 9934, 10410, 12573, 10831, 12994, 13470, 15633, 11349,
|
||||
13512, 13988, 16151, 14409, 16572, 17048, 19211, 7771, 9934, 10410, 12573,
|
||||
10831, 12994, 13470, 15633, 11349, 13512, 13988, 16151, 14409, 16572, 17048,
|
||||
19211, 11349, 13512, 13988, 16151, 14409, 16572, 17048, 19211, 14927, 17090,
|
||||
17566, 19729, 17987, 20150, 20626, 22789, 8286, 10449, 10925, 13088, 11346,
|
||||
13509, 13985, 16148, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726,
|
||||
11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081,
|
||||
20244, 18502, 20665, 21141, 23304, 11864, 14027, 14503, 16666, 14924, 17087,
|
||||
17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 15442,
|
||||
17605, 18081, 20244, 18502, 20665, 21141, 23304, 19020, 21183, 21659, 23822,
|
||||
22080, 24243, 24719, 26882, 8286, 10449, 10925, 13088, 11346, 13509, 13985,
|
||||
16148, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726, 11864, 14027,
|
||||
14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244, 18502,
|
||||
20665, 21141, 23304, 11864, 14027, 14503, 16666, 14924, 17087, 17563, 19726,
|
||||
15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 15442, 17605, 18081,
|
||||
20244, 18502, 20665, 21141, 23304, 19020, 21183, 21659, 23822, 22080, 24243,
|
||||
24719, 26882, 12379, 14542, 15018, 17181, 15439, 17602, 18078, 20241, 15957,
|
||||
18120, 18596, 20759, 19017, 21180, 21656, 23819, 15957, 18120, 18596, 20759,
|
||||
19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234,
|
||||
27397, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698,
|
||||
22174, 24337, 22595, 24758, 25234, 27397, 19535, 21698, 22174, 24337, 22595,
|
||||
24758, 25234, 27397, 23113, 25276, 25752, 27915, 26173, 28336, 28812, 30975,
|
||||
8286, 10449, 10925, 13088, 11346, 13509, 13985, 16148, 11864, 14027, 14503,
|
||||
16666, 14924, 17087, 17563, 19726, 11864, 14027, 14503, 16666, 14924, 17087,
|
||||
17563, 19726, 15442, 17605, 18081, 20244, 18502, 20665, 21141, 23304, 11864,
|
||||
14027, 14503, 16666, 14924, 17087, 17563, 19726, 15442, 17605, 18081, 20244,
|
||||
18502, 20665, 21141, 23304, 15442, 17605, 18081, 20244, 18502, 20665, 21141,
|
||||
23304, 19020, 21183, 21659, 23822, 22080, 24243, 24719, 26882, 12379, 14542,
|
||||
15018, 17181, 15439, 17602, 18078, 20241, 15957, 18120, 18596, 20759, 19017,
|
||||
21180, 21656, 23819, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819,
|
||||
19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 15957, 18120, 18596,
|
||||
20759, 19017, 21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758,
|
||||
25234, 27397, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 23113,
|
||||
25276, 25752, 27915, 26173, 28336, 28812, 30975, 12379, 14542, 15018, 17181,
|
||||
15439, 17602, 18078, 20241, 15957, 18120, 18596, 20759, 19017, 21180, 21656,
|
||||
23819, 15957, 18120, 18596, 20759, 19017, 21180, 21656, 23819, 19535, 21698,
|
||||
22174, 24337, 22595, 24758, 25234, 27397, 15957, 18120, 18596, 20759, 19017,
|
||||
21180, 21656, 23819, 19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397,
|
||||
19535, 21698, 22174, 24337, 22595, 24758, 25234, 27397, 23113, 25276, 25752,
|
||||
27915, 26173, 28336, 28812, 30975, 16472, 18635, 19111, 21274, 19532, 21695,
|
||||
22171, 24334, 20050, 22213, 22689, 24852, 23110, 25273, 25749, 27912, 20050,
|
||||
22213, 22689, 24852, 23110, 25273, 25749, 27912, 23628, 25791, 26267, 28430,
|
||||
26688, 28851, 29327, 31490, 20050, 22213, 22689, 24852, 23110, 25273, 25749,
|
||||
27912, 23628, 25791, 26267, 28430, 26688, 28851, 29327, 31490, 23628, 25791,
|
||||
26267, 28430, 26688, 28851, 29327, 31490, 27206, 29369, 29845, 32008, 30266,
|
||||
32429, 32905, 35068
|
||||
#endif
|
||||
};
|
||||
|
||||
const uint8_t av1_cat6_skipped_bits_discount[8] = {
|
||||
0, 3, 6, 9, 12, 18, 24, 30
|
||||
};
|
||||
|
||||
#if CONFIG_NEW_MULTISYMBOL
|
||||
const av1_extra_bit av1_extra_bits[ENTROPY_TOKENS] = {
|
||||
{ 0, 0, 0, zero_cost }, // ZERO_TOKEN
|
||||
{ 0, 0, 1, sign_cost }, // ONE_TOKEN
|
||||
{ 0, 0, 2, sign_cost }, // TWO_TOKEN
|
||||
{ 0, 0, 3, sign_cost }, // THREE_TOKEN
|
||||
{ 0, 0, 4, sign_cost }, // FOUR_TOKEN
|
||||
{ av1_cat1_cdf, 1, CAT1_MIN_VAL, cat1_cost }, // CATEGORY1_TOKEN
|
||||
{ av1_cat2_cdf, 2, CAT2_MIN_VAL, cat2_cost }, // CATEGORY2_TOKEN
|
||||
{ av1_cat3_cdf, 3, CAT3_MIN_VAL, cat3_cost }, // CATEGORY3_TOKEN
|
||||
{ av1_cat4_cdf, 4, CAT4_MIN_VAL, cat4_cost }, // CATEGORY4_TOKEN
|
||||
{ av1_cat5_cdf, 5, CAT5_MIN_VAL, cat5_cost }, // CATEGORY5_TOKEN
|
||||
{ av1_cat6_cdf, 18, CAT6_MIN_VAL, 0 }, // CATEGORY6_TOKEN
|
||||
{ 0, 0, 0, zero_cost } // EOB_TOKEN
|
||||
};
|
||||
#else
|
||||
const av1_extra_bit av1_extra_bits[ENTROPY_TOKENS] = {
|
||||
{ 0, 0, 0, zero_cost }, // ZERO_TOKEN
|
||||
{ 0, 0, 1, sign_cost }, // ONE_TOKEN
|
||||
{ 0, 0, 2, sign_cost }, // TWO_TOKEN
|
||||
{ 0, 0, 3, sign_cost }, // THREE_TOKEN
|
||||
{ 0, 0, 4, sign_cost }, // FOUR_TOKEN
|
||||
{ av1_cat1_prob, 1, CAT1_MIN_VAL, cat1_cost }, // CATEGORY1_TOKEN
|
||||
{ av1_cat2_prob, 2, CAT2_MIN_VAL, cat2_cost }, // CATEGORY2_TOKEN
|
||||
{ av1_cat3_prob, 3, CAT3_MIN_VAL, cat3_cost }, // CATEGORY3_TOKEN
|
||||
{ av1_cat4_prob, 4, CAT4_MIN_VAL, cat4_cost }, // CATEGORY4_TOKEN
|
||||
{ av1_cat5_prob, 5, CAT5_MIN_VAL, cat5_cost }, // CATEGORY5_TOKEN
|
||||
{ av1_cat6_prob, 18, CAT6_MIN_VAL, 0 }, // CATEGORY6_TOKEN
|
||||
{ 0, 0, 0, zero_cost } // EOB_TOKEN
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !CONFIG_PVQ || CONFIG_VAR_TX
|
||||
static void cost_coeffs_b(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args *const args = arg;
|
||||
const AV1_COMP *const cpi = args->cpi;
|
||||
const AV1_COMMON *cm = &cpi->common;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
|
||||
struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
const PLANE_TYPE type = pd->plane_type;
|
||||
const TX_TYPE tx_type =
|
||||
av1_get_tx_type(type, xd, blk_row, blk_col, block, tx_size);
|
||||
const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
|
||||
const int rate = av1_cost_coeffs(
|
||||
cpi, x, plane, blk_row, blk_col, block, tx_size, scan_order,
|
||||
pd->above_context + blk_col, pd->left_context + blk_row, 0);
|
||||
args->this_rate += rate;
|
||||
(void)plane_bsize;
|
||||
av1_set_contexts(xd, pd, plane, tx_size, p->eobs[block] > 0, blk_col,
|
||||
blk_row);
|
||||
}
|
||||
|
||||
static void set_entropy_context_b(int plane, int block, int blk_row,
|
||||
int blk_col, BLOCK_SIZE plane_bsize,
|
||||
TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args *const args = arg;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
(void)plane_bsize;
|
||||
av1_set_contexts(xd, pd, plane, tx_size, p->eobs[block] > 0, blk_col,
|
||||
blk_row);
|
||||
}
|
||||
|
||||
static INLINE void add_token(TOKENEXTRA **t,
|
||||
aom_cdf_prob (*tail_cdf)[CDF_SIZE(ENTROPY_TOKENS)],
|
||||
aom_cdf_prob (*head_cdf)[CDF_SIZE(ENTROPY_TOKENS)],
|
||||
int eob_val, int first_val, int32_t extra,
|
||||
uint8_t token) {
|
||||
(*t)->token = token;
|
||||
(*t)->extra = extra;
|
||||
(*t)->tail_cdf = tail_cdf;
|
||||
(*t)->head_cdf = head_cdf;
|
||||
(*t)->eob_val = eob_val;
|
||||
(*t)->first_val = first_val;
|
||||
(*t)++;
|
||||
|
||||
if (token == BLOCK_Z_TOKEN) {
|
||||
update_cdf(*head_cdf, 0, HEAD_TOKENS + 1);
|
||||
} else {
|
||||
if (eob_val != LAST_EOB) {
|
||||
const int symb = 2 * AOMMIN(token, TWO_TOKEN) - eob_val + first_val;
|
||||
update_cdf(*head_cdf, symb, HEAD_TOKENS + first_val);
|
||||
}
|
||||
if (token > ONE_TOKEN)
|
||||
update_cdf(*tail_cdf, token - TWO_TOKEN, TAIL_TOKENS);
|
||||
}
|
||||
}
|
||||
#endif // !CONFIG_PVQ || CONFIG_VAR_TX
|
||||
|
||||
static int cost_and_tokenize_map(Av1ColorMapParam *param, TOKENEXTRA **t,
|
||||
int calc_rate) {
|
||||
int plane, int calc_rate, int allow_update_cdf,
|
||||
FRAME_COUNTS *counts) {
|
||||
const uint8_t *const color_map = param->color_map;
|
||||
MapCdf map_cdf = param->map_cdf;
|
||||
ColorCost color_cost = param->color_cost;
|
||||
|
|
@ -338,28 +37,37 @@ static int cost_and_tokenize_map(Av1ColorMapParam *param, TOKENEXTRA **t,
|
|||
const int rows = param->rows;
|
||||
const int cols = param->cols;
|
||||
const int n = param->n_colors;
|
||||
|
||||
const int palette_size_idx = n - PALETTE_MIN_SIZE;
|
||||
int this_rate = 0;
|
||||
uint8_t color_order[PALETTE_MAX_SIZE];
|
||||
#if CONFIG_PALETTE_THROUGHPUT
|
||||
|
||||
(void)plane;
|
||||
(void)counts;
|
||||
|
||||
for (int k = 1; k < rows + cols - 1; ++k) {
|
||||
for (int j = AOMMIN(k, cols - 1); j >= AOMMAX(0, k - rows + 1); --j) {
|
||||
int i = k - j;
|
||||
#else
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
for (int j = (i == 0 ? 1 : 0); j < cols; ++j) {
|
||||
#endif // CONFIG_PALETTE_THROUGHPUT
|
||||
int color_new_idx;
|
||||
const int color_ctx = av1_get_palette_color_index_context(
|
||||
color_map, plane_block_width, i, j, n, color_order, &color_new_idx);
|
||||
assert(color_new_idx >= 0 && color_new_idx < n);
|
||||
if (calc_rate) {
|
||||
this_rate +=
|
||||
(*color_cost)[n - PALETTE_MIN_SIZE][color_ctx][color_new_idx];
|
||||
this_rate += (*color_cost)[palette_size_idx][color_ctx][color_new_idx];
|
||||
} else {
|
||||
(*t)->token = color_new_idx;
|
||||
(*t)->color_map_cdf = map_cdf[n - PALETTE_MIN_SIZE][color_ctx];
|
||||
(*t)->color_map_cdf = map_cdf[palette_size_idx][color_ctx];
|
||||
++(*t);
|
||||
if (allow_update_cdf)
|
||||
update_cdf(map_cdf[palette_size_idx][color_ctx], color_new_idx, n);
|
||||
#if CONFIG_ENTROPY_STATS
|
||||
if (plane) {
|
||||
++counts->palette_uv_color_index[palette_size_idx][color_ctx]
|
||||
[color_new_idx];
|
||||
} else {
|
||||
++counts->palette_y_color_index[palette_size_idx][color_ctx]
|
||||
[color_new_idx];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -370,7 +78,7 @@ static int cost_and_tokenize_map(Av1ColorMapParam *param, TOKENEXTRA **t,
|
|||
static void get_palette_params(const MACROBLOCK *const x, int plane,
|
||||
BLOCK_SIZE bsize, Av1ColorMapParam *params) {
|
||||
const MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
const MB_MODE_INFO *const mbmi = xd->mi[0];
|
||||
const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
|
||||
params->color_map = xd->plane[plane].color_index_map;
|
||||
params->map_cdf = plane ? xd->tile_ctx->palette_uv_color_index_cdf
|
||||
|
|
@ -382,263 +90,62 @@ static void get_palette_params(const MACROBLOCK *const x, int plane,
|
|||
¶ms->rows, ¶ms->cols);
|
||||
}
|
||||
|
||||
#if CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
static void get_mrc_params(const MACROBLOCK *const x, int block,
|
||||
TX_SIZE tx_size, Av1ColorMapParam *params) {
|
||||
memset(params, 0, sizeof(*params));
|
||||
const MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
const int is_inter = is_inter_block(mbmi);
|
||||
params->color_map = BLOCK_OFFSET(xd->mrc_mask, block);
|
||||
params->map_cdf = is_inter ? xd->tile_ctx->mrc_mask_inter_cdf
|
||||
: xd->tile_ctx->mrc_mask_intra_cdf;
|
||||
params->color_cost =
|
||||
is_inter ? &x->mrc_mask_inter_cost : &x->mrc_mask_intra_cost;
|
||||
params->n_colors = 2;
|
||||
params->plane_width = tx_size_wide[tx_size];
|
||||
params->rows = tx_size_high[tx_size];
|
||||
params->cols = tx_size_wide[tx_size];
|
||||
}
|
||||
#endif // CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
|
||||
static void get_color_map_params(const MACROBLOCK *const x, int plane,
|
||||
int block, BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
COLOR_MAP_TYPE type,
|
||||
Av1ColorMapParam *params) {
|
||||
(void)block;
|
||||
(void)tx_size;
|
||||
memset(params, 0, sizeof(*params));
|
||||
switch (type) {
|
||||
case PALETTE_MAP: get_palette_params(x, plane, bsize, params); break;
|
||||
#if CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
case MRC_MAP: get_mrc_params(x, block, tx_size, params); break;
|
||||
#endif // CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
default: assert(0 && "Invalid color map type"); return;
|
||||
}
|
||||
}
|
||||
|
||||
int av1_cost_color_map(const MACROBLOCK *const x, int plane, int block,
|
||||
BLOCK_SIZE bsize, TX_SIZE tx_size, COLOR_MAP_TYPE type) {
|
||||
int av1_cost_color_map(const MACROBLOCK *const x, int plane, BLOCK_SIZE bsize,
|
||||
TX_SIZE tx_size, COLOR_MAP_TYPE type) {
|
||||
assert(plane == 0 || plane == 1);
|
||||
Av1ColorMapParam color_map_params;
|
||||
get_color_map_params(x, plane, block, bsize, tx_size, type,
|
||||
&color_map_params);
|
||||
return cost_and_tokenize_map(&color_map_params, NULL, 1);
|
||||
get_color_map_params(x, plane, bsize, tx_size, type, &color_map_params);
|
||||
return cost_and_tokenize_map(&color_map_params, NULL, plane, 1, 0, NULL);
|
||||
}
|
||||
|
||||
void av1_tokenize_color_map(const MACROBLOCK *const x, int plane, int block,
|
||||
void av1_tokenize_color_map(const MACROBLOCK *const x, int plane,
|
||||
TOKENEXTRA **t, BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
COLOR_MAP_TYPE type) {
|
||||
COLOR_MAP_TYPE type, int allow_update_cdf,
|
||||
FRAME_COUNTS *counts) {
|
||||
assert(plane == 0 || plane == 1);
|
||||
#if CONFIG_MRC_TX
|
||||
if (type == MRC_MAP) {
|
||||
const int is_inter = is_inter_block(&x->e_mbd.mi[0]->mbmi);
|
||||
if ((is_inter && !SIGNAL_MRC_MASK_INTER) ||
|
||||
(!is_inter && !SIGNAL_MRC_MASK_INTRA))
|
||||
return;
|
||||
}
|
||||
#endif // CONFIG_MRC_TX
|
||||
Av1ColorMapParam color_map_params;
|
||||
get_color_map_params(x, plane, block, bsize, tx_size, type,
|
||||
&color_map_params);
|
||||
get_color_map_params(x, plane, bsize, tx_size, type, &color_map_params);
|
||||
// The first color index does not use context or entropy.
|
||||
(*t)->token = color_map_params.color_map[0];
|
||||
(*t)->color_map_cdf = NULL;
|
||||
++(*t);
|
||||
cost_and_tokenize_map(&color_map_params, t, 0);
|
||||
cost_and_tokenize_map(&color_map_params, t, plane, 0, allow_update_cdf,
|
||||
counts);
|
||||
}
|
||||
|
||||
#if CONFIG_PVQ
|
||||
static void add_pvq_block(AV1_COMMON *const cm, MACROBLOCK *const x,
|
||||
PVQ_INFO *pvq) {
|
||||
PVQ_QUEUE *q = x->pvq_q;
|
||||
if (q->curr_pos >= q->buf_len) {
|
||||
int new_buf_len = 2 * q->buf_len + 1;
|
||||
PVQ_INFO *new_buf;
|
||||
CHECK_MEM_ERROR(cm, new_buf, aom_malloc(new_buf_len * sizeof(PVQ_INFO)));
|
||||
memcpy(new_buf, q->buf, q->buf_len * sizeof(PVQ_INFO));
|
||||
aom_free(q->buf);
|
||||
q->buf = new_buf;
|
||||
q->buf_len = new_buf_len;
|
||||
}
|
||||
OD_COPY(q->buf + q->curr_pos, pvq, 1);
|
||||
++q->curr_pos;
|
||||
}
|
||||
|
||||
// NOTE: This does not actually generate tokens, instead we store the encoding
|
||||
// decisions made for PVQ in a queue that we will read from when
|
||||
// actually writing the bitstream in write_modes_b
|
||||
static void tokenize_pvq(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
|
||||
struct tokenize_b_args *const args = arg;
|
||||
const AV1_COMP *cpi = args->cpi;
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
PVQ_INFO *pvq_info;
|
||||
|
||||
(void)block;
|
||||
(void)blk_row;
|
||||
(void)blk_col;
|
||||
(void)plane_bsize;
|
||||
(void)tx_size;
|
||||
|
||||
assert(block < MAX_PVQ_BLOCKS_IN_SB);
|
||||
pvq_info = &x->pvq[block][plane];
|
||||
add_pvq_block((AV1_COMMON * const) cm, x, pvq_info);
|
||||
}
|
||||
#endif // CONFIG_PVQ
|
||||
|
||||
static void tokenize_b(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
|
||||
#if !CONFIG_PVQ
|
||||
struct tokenize_b_args *const args = arg;
|
||||
const AV1_COMP *cpi = args->cpi;
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
ThreadData *const td = args->td;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
TOKENEXTRA **tp = args->tp;
|
||||
uint8_t token_cache[MAX_TX_SQUARE];
|
||||
struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
|
||||
int pt; /* near block/prev token context index */
|
||||
int c;
|
||||
TOKENEXTRA *t = *tp; /* store tokens starting here */
|
||||
const int eob = p->eobs[block];
|
||||
const PLANE_TYPE type = pd->plane_type;
|
||||
const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
#if CONFIG_SUPERTX
|
||||
const int segment_id = AOMMIN(mbmi->segment_id, mbmi->segment_id_supertx);
|
||||
#else
|
||||
const int segment_id = mbmi->segment_id;
|
||||
#endif // CONFIG_SUEPRTX
|
||||
const int16_t *scan, *nb;
|
||||
const TX_TYPE tx_type =
|
||||
av1_get_tx_type(type, xd, blk_row, blk_col, block, tx_size);
|
||||
const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
|
||||
const int ref = is_inter_block(mbmi);
|
||||
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
|
||||
aom_cdf_prob(
|
||||
*const coef_head_cdfs)[COEFF_CONTEXTS][CDF_SIZE(ENTROPY_TOKENS)] =
|
||||
ec_ctx->coef_head_cdfs[txsize_sqr_map[tx_size]][type][ref];
|
||||
aom_cdf_prob(
|
||||
*const coef_tail_cdfs)[COEFF_CONTEXTS][CDF_SIZE(ENTROPY_TOKENS)] =
|
||||
ec_ctx->coef_tail_cdfs[txsize_sqr_map[tx_size]][type][ref];
|
||||
int eob_val;
|
||||
int first_val = 1;
|
||||
const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
|
||||
const uint8_t *const band = get_band_translate(tx_size);
|
||||
int16_t token;
|
||||
EXTRABIT extra;
|
||||
(void)plane_bsize;
|
||||
pt = get_entropy_context(tx_size, pd->above_context + blk_col,
|
||||
pd->left_context + blk_row);
|
||||
scan = scan_order->scan;
|
||||
nb = scan_order->neighbors;
|
||||
c = 0;
|
||||
|
||||
#if CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
if (tx_type == MRC_DCT)
|
||||
av1_tokenize_color_map(x, plane, block, &t, plane_bsize, tx_size, MRC_MAP);
|
||||
#endif // CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
|
||||
|
||||
if (eob == 0)
|
||||
add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt], 1,
|
||||
1, 0, BLOCK_Z_TOKEN);
|
||||
|
||||
while (c < eob) {
|
||||
int v = qcoeff[scan[c]];
|
||||
first_val = (c == 0);
|
||||
|
||||
if (!v) {
|
||||
add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt],
|
||||
0, first_val, 0, ZERO_TOKEN);
|
||||
token_cache[scan[c]] = 0;
|
||||
} else {
|
||||
eob_val =
|
||||
(c + 1 == eob) ? (c + 1 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
|
||||
av1_get_token_extra(v, &token, &extra);
|
||||
add_token(&t, &coef_tail_cdfs[band[c]][pt], &coef_head_cdfs[band[c]][pt],
|
||||
eob_val, first_val, extra, (uint8_t)token);
|
||||
token_cache[scan[c]] = av1_pt_energy_class[token];
|
||||
}
|
||||
++c;
|
||||
pt = get_coef_context(nb, token_cache, AOMMIN(c, eob - 1));
|
||||
}
|
||||
|
||||
#if CONFIG_COEF_INTERLEAVE
|
||||
t->token = EOSB_TOKEN;
|
||||
t++;
|
||||
#endif
|
||||
|
||||
*tp = t;
|
||||
|
||||
#if CONFIG_ADAPT_SCAN
|
||||
// Since dqcoeff is not available here, we pass qcoeff into
|
||||
// av1_update_scan_count_facade(). The update behavior should be the same
|
||||
// because av1_update_scan_count_facade() only cares if coefficients are zero
|
||||
// or not.
|
||||
av1_update_scan_count_facade((AV1_COMMON *)cm, td->counts, tx_size, tx_type,
|
||||
qcoeff, c);
|
||||
#endif
|
||||
|
||||
av1_set_contexts(xd, pd, plane, tx_size, c > 0, blk_col, blk_row);
|
||||
#else // !CONFIG_PVQ
|
||||
tokenize_pvq(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
|
||||
#endif // !CONFIG_PVQ
|
||||
}
|
||||
|
||||
struct is_skippable_args {
|
||||
uint16_t *eobs;
|
||||
int *skippable;
|
||||
};
|
||||
static void is_skippable(int plane, int block, int blk_row, int blk_col,
|
||||
BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *argv) {
|
||||
struct is_skippable_args *args = argv;
|
||||
(void)plane;
|
||||
(void)plane_bsize;
|
||||
(void)tx_size;
|
||||
(void)blk_row;
|
||||
(void)blk_col;
|
||||
args->skippable[0] &= (!args->eobs[block]);
|
||||
}
|
||||
|
||||
// TODO(yaowu): rewrite and optimize this function to remove the usage of
|
||||
// av1_foreach_transform_block() and simplify is_skippable().
|
||||
int av1_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
|
||||
int result = 1;
|
||||
struct is_skippable_args args = { x->plane[plane].eobs, &result };
|
||||
av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, plane, is_skippable,
|
||||
&args);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if CONFIG_VAR_TX
|
||||
void tokenize_vartx(ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run,
|
||||
TX_SIZE tx_size, BLOCK_SIZE plane_bsize, int blk_row,
|
||||
int blk_col, int block, int plane, void *arg) {
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
MB_MODE_INFO *const mbmi = xd->mi[0];
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
const int tx_row = blk_row >> (1 - pd->subsampling_y);
|
||||
const int tx_col = blk_col >> (1 - pd->subsampling_x);
|
||||
const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
|
||||
const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
|
||||
TX_SIZE plane_tx_size;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
|
||||
|
||||
plane_tx_size =
|
||||
plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
|
||||
: mbmi->inter_tx_size[tx_row][tx_col];
|
||||
const TX_SIZE plane_tx_size =
|
||||
plane ? av1_get_max_uv_txsize(mbmi->sb_type, pd->subsampling_x,
|
||||
pd->subsampling_y)
|
||||
: mbmi->inter_tx_size[av1_get_txb_size_index(plane_bsize, blk_row,
|
||||
blk_col)];
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
plane_bsize = get_plane_block_size(mbmi->sb_type, pd);
|
||||
#if CONFIG_LV_MAP
|
||||
if (tx_size == plane_tx_size || plane) {
|
||||
plane_bsize = get_plane_block_size(mbmi->sb_type, pd->subsampling_x,
|
||||
pd->subsampling_y);
|
||||
if (!dry_run) {
|
||||
av1_update_and_record_txb_context(plane, block, blk_row, blk_col,
|
||||
plane_bsize, tx_size, arg);
|
||||
|
|
@ -649,120 +156,71 @@ void tokenize_vartx(ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run,
|
|||
printf("DRY_RUN_COSTCOEFFS is not supported yet\n");
|
||||
assert(0);
|
||||
}
|
||||
#else
|
||||
if (!dry_run)
|
||||
tokenize_b(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
|
||||
else if (dry_run == DRY_RUN_NORMAL)
|
||||
set_entropy_context_b(plane, block, blk_row, blk_col, plane_bsize,
|
||||
tx_size, arg);
|
||||
else if (dry_run == DRY_RUN_COSTCOEFFS)
|
||||
cost_coeffs_b(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_RECT_TX_EXT
|
||||
int is_qttx = plane_tx_size == quarter_txsize_lookup[plane_bsize];
|
||||
const TX_SIZE sub_txs = is_qttx ? plane_tx_size : sub_tx_size_map[tx_size];
|
||||
#else
|
||||
// Half the block size in transform block unit.
|
||||
const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
|
||||
#endif
|
||||
const int bsl = tx_size_wide_unit[sub_txs];
|
||||
int i;
|
||||
const int bsw = tx_size_wide_unit[sub_txs];
|
||||
const int bsh = tx_size_high_unit[sub_txs];
|
||||
const int step = bsw * bsh;
|
||||
|
||||
assert(bsl > 0);
|
||||
assert(bsw > 0 && bsh > 0);
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
#if CONFIG_RECT_TX_EXT
|
||||
int is_wide_tx = tx_size_wide_unit[sub_txs] > tx_size_high_unit[sub_txs];
|
||||
const int offsetr =
|
||||
is_qttx ? (is_wide_tx ? i * tx_size_high_unit[sub_txs] : 0)
|
||||
: blk_row + ((i >> 1) * bsl);
|
||||
const int offsetc =
|
||||
is_qttx ? (is_wide_tx ? 0 : i * tx_size_wide_unit[sub_txs])
|
||||
: blk_col + ((i & 0x01) * bsl);
|
||||
#else
|
||||
const int offsetr = blk_row + ((i >> 1) * bsl);
|
||||
const int offsetc = blk_col + ((i & 0x01) * bsl);
|
||||
#endif
|
||||
for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) {
|
||||
for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
|
||||
const int offsetr = blk_row + row;
|
||||
const int offsetc = blk_col + col;
|
||||
|
||||
int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
|
||||
if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
|
||||
|
||||
if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
|
||||
|
||||
tokenize_vartx(td, t, dry_run, sub_txs, plane_bsize, offsetr, offsetc,
|
||||
block, plane, arg);
|
||||
block += step;
|
||||
tokenize_vartx(td, t, dry_run, sub_txs, plane_bsize, offsetr, offsetc,
|
||||
block, plane, arg);
|
||||
block += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
RUN_TYPE dry_run, int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize, int *rate) {
|
||||
BLOCK_SIZE bsize, int *rate,
|
||||
uint8_t allow_update_cdf) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
#if CONFIG_LV_MAP
|
||||
MB_MODE_INFO *const mbmi = xd->mi[0];
|
||||
(void)t;
|
||||
#else
|
||||
TOKENEXTRA *t_backup = *t;
|
||||
#endif
|
||||
const int ctx = av1_get_skip_context(xd);
|
||||
const int skip_inc =
|
||||
!segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
|
||||
struct tokenize_b_args arg = { cpi, td, t, 0 };
|
||||
int plane;
|
||||
struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf };
|
||||
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
|
||||
|
||||
if (mbmi->skip) {
|
||||
if (!dry_run) td->counts->skip[ctx][1] += skip_inc;
|
||||
av1_reset_skip_context(xd, mi_row, mi_col, bsize);
|
||||
#if !CONFIG_LV_MAP
|
||||
if (dry_run) *t = t_backup;
|
||||
#endif
|
||||
av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dry_run) td->counts->skip[ctx][0] += skip_inc;
|
||||
#if !CONFIG_LV_MAP
|
||||
else
|
||||
*t = t_backup;
|
||||
#endif
|
||||
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
#if CONFIG_CB4X4
|
||||
for (int plane = 0; plane < num_planes; ++plane) {
|
||||
if (!is_chroma_reference(mi_row, mi_col, bsize,
|
||||
xd->plane[plane].subsampling_x,
|
||||
xd->plane[plane].subsampling_y)) {
|
||||
#if !CONFIG_PVQ && !CONFIG_LV_MAP
|
||||
if (!dry_run) {
|
||||
(*t)->token = EOSB_TOKEN;
|
||||
(*t)++;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
#if CONFIG_CHROMA_SUB8X8
|
||||
const BLOCK_SIZE bsizec =
|
||||
scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y);
|
||||
const BLOCK_SIZE plane_bsize =
|
||||
AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
|
||||
#else
|
||||
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
|
||||
#endif
|
||||
get_plane_block_size(bsizec, pd->subsampling_x, pd->subsampling_y);
|
||||
const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
|
||||
const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
|
||||
const TX_SIZE max_tx_size = get_vartx_max_txsize(
|
||||
mbmi, plane_bsize, pd->subsampling_x || pd->subsampling_y);
|
||||
const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
|
||||
const TX_SIZE max_tx_size = get_vartx_max_txsize(xd, plane_bsize, plane);
|
||||
const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
|
||||
int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
|
||||
int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
|
||||
int bh = block_size_high[txb_size] >> tx_size_high_log2[0];
|
||||
int idx, idy;
|
||||
int block = 0;
|
||||
int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
|
||||
|
||||
const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
|
||||
const BLOCK_SIZE max_unit_bsize =
|
||||
get_plane_block_size(BLOCK_64X64, pd->subsampling_x, pd->subsampling_y);
|
||||
int mu_blocks_wide =
|
||||
block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
|
||||
int mu_blocks_high =
|
||||
|
|
@ -785,144 +243,6 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
|||
}
|
||||
}
|
||||
}
|
||||
#if !CONFIG_LV_MAP
|
||||
if (!dry_run) {
|
||||
(*t)->token = EOSB_TOKEN;
|
||||
(*t)++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rate) *rate += arg.this_rate;
|
||||
}
|
||||
#endif // CONFIG_VAR_TX
|
||||
|
||||
void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
|
||||
const int mi_row, const int mi_col) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCK *const x = &td->mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
const int ctx = av1_get_skip_context(xd);
|
||||
const int skip_inc =
|
||||
!segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
|
||||
struct tokenize_b_args arg = { cpi, td, t, 0 };
|
||||
if (mbmi->skip) {
|
||||
if (!dry_run) td->counts->skip[ctx][1] += skip_inc;
|
||||
av1_reset_skip_context(xd, mi_row, mi_col, bsize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dry_run) {
|
||||
#if CONFIG_COEF_INTERLEAVE
|
||||
td->counts->skip[ctx][0] += skip_inc;
|
||||
av1_foreach_transformed_block_interleave(xd, bsize, tokenize_b, &arg);
|
||||
#else
|
||||
int plane;
|
||||
|
||||
td->counts->skip[ctx][0] += skip_inc;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
#if CONFIG_CB4X4
|
||||
if (!is_chroma_reference(mi_row, mi_col, bsize,
|
||||
xd->plane[plane].subsampling_x,
|
||||
xd->plane[plane].subsampling_y)) {
|
||||
#if !CONFIG_PVQ
|
||||
(*t)->token = EOSB_TOKEN;
|
||||
(*t)++;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
(void)mi_row;
|
||||
(void)mi_col;
|
||||
#endif
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane, tokenize_b,
|
||||
&arg);
|
||||
#if !CONFIG_PVQ
|
||||
(*t)->token = EOSB_TOKEN;
|
||||
(*t)++;
|
||||
#endif // !CONFIG_PVQ
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if !CONFIG_PVQ
|
||||
else if (dry_run == DRY_RUN_NORMAL) {
|
||||
int plane;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
#if CONFIG_CB4X4
|
||||
if (!is_chroma_reference(mi_row, mi_col, bsize,
|
||||
xd->plane[plane].subsampling_x,
|
||||
xd->plane[plane].subsampling_y))
|
||||
continue;
|
||||
#else
|
||||
(void)mi_row;
|
||||
(void)mi_col;
|
||||
#endif
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane,
|
||||
set_entropy_context_b, &arg);
|
||||
}
|
||||
} else if (dry_run == DRY_RUN_COSTCOEFFS) {
|
||||
int plane;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
#if CONFIG_CB4X4
|
||||
if (!is_chroma_reference(mi_row, mi_col, bsize,
|
||||
xd->plane[plane].subsampling_x,
|
||||
xd->plane[plane].subsampling_y))
|
||||
continue;
|
||||
#else
|
||||
(void)mi_row;
|
||||
(void)mi_col;
|
||||
#endif
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane, cost_coeffs_b,
|
||||
&arg);
|
||||
}
|
||||
}
|
||||
#endif // !CONFIG_PVQ
|
||||
|
||||
if (rate) *rate += arg.this_rate;
|
||||
}
|
||||
|
||||
#if CONFIG_SUPERTX
|
||||
void av1_tokenize_sb_supertx(const AV1_COMP *cpi, ThreadData *td,
|
||||
TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int *rate) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCKD *const xd = &td->mb.e_mbd;
|
||||
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
TOKENEXTRA *t_backup = *t;
|
||||
const int ctx = av1_get_skip_context(xd);
|
||||
const int skip_inc =
|
||||
!segfeature_active(&cm->seg, mbmi->segment_id_supertx, SEG_LVL_SKIP);
|
||||
struct tokenize_b_args arg = { cpi, td, t, 0 };
|
||||
if (mbmi->skip) {
|
||||
if (!dry_run) td->counts->skip[ctx][1] += skip_inc;
|
||||
av1_reset_skip_context(xd, mi_row, mi_col, bsize);
|
||||
if (dry_run) *t = t_backup;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dry_run) {
|
||||
int plane;
|
||||
td->counts->skip[ctx][0] += skip_inc;
|
||||
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane, tokenize_b,
|
||||
&arg);
|
||||
(*t)->token = EOSB_TOKEN;
|
||||
(*t)++;
|
||||
}
|
||||
} else if (dry_run == DRY_RUN_NORMAL) {
|
||||
int plane;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane)
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane,
|
||||
set_entropy_context_b, &arg);
|
||||
*t = t_backup;
|
||||
} else if (dry_run == DRY_RUN_COSTCOEFFS) {
|
||||
int plane;
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane)
|
||||
av1_foreach_transformed_block_in_plane(xd, bsize, plane, cost_coeffs_b,
|
||||
&arg);
|
||||
}
|
||||
if (rate) *rate += arg.this_rate;
|
||||
}
|
||||
#endif // CONFIG_SUPERTX
|
||||
|
|
|
|||
102
third_party/aom/av1/encoder/tokenize.h
vendored
102
third_party/aom/av1/encoder/tokenize.h
vendored
|
|
@ -13,51 +13,29 @@
|
|||
#define AV1_ENCODER_TOKENIZE_H_
|
||||
|
||||
#include "av1/common/entropy.h"
|
||||
|
||||
#include "av1/encoder/block.h"
|
||||
#include "av1/encoder/treewriter.h"
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EOSB_TOKEN 127 // Not signalled, encoder only
|
||||
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
typedef int32_t EXTRABIT;
|
||||
#else
|
||||
typedef int16_t EXTRABIT;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int16_t token;
|
||||
EXTRABIT extra;
|
||||
} TOKENVALUE;
|
||||
|
||||
typedef struct {
|
||||
aom_cdf_prob (*tail_cdf)[CDF_SIZE(ENTROPY_TOKENS)];
|
||||
aom_cdf_prob (*head_cdf)[CDF_SIZE(ENTROPY_TOKENS)];
|
||||
aom_cdf_prob *color_map_cdf;
|
||||
int eob_val;
|
||||
int first_val;
|
||||
const aom_prob *context_tree;
|
||||
EXTRABIT extra;
|
||||
// TODO(yaowu: use packed enum type if appropriate)
|
||||
uint8_t token;
|
||||
} TOKENEXTRA;
|
||||
|
||||
extern const aom_tree_index av1_coef_tree[];
|
||||
extern const aom_tree_index av1_coef_con_tree[];
|
||||
|
||||
int av1_is_skippable_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
|
||||
|
||||
struct AV1_COMP;
|
||||
struct ThreadData;
|
||||
struct FRAME_COUNTS;
|
||||
|
||||
struct tokenize_b_args {
|
||||
const struct AV1_COMP *cpi;
|
||||
struct ThreadData *td;
|
||||
TOKENEXTRA **tp;
|
||||
int this_rate;
|
||||
uint8_t allow_update_cdf;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -69,78 +47,22 @@ typedef enum {
|
|||
// Note in all the tokenize functions rate if non NULL is incremented
|
||||
// with the coefficient token cost only if dry_run = DRY_RUN_COSTCOEFS,
|
||||
// otherwise rate is not incremented.
|
||||
#if CONFIG_VAR_TX
|
||||
void av1_tokenize_sb_vartx(const struct AV1_COMP *cpi, struct ThreadData *td,
|
||||
TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int *rate);
|
||||
#endif
|
||||
int mi_col, BLOCK_SIZE bsize, int *rate,
|
||||
uint8_t allow_update_cdf);
|
||||
|
||||
int av1_cost_color_map(const MACROBLOCK *const x, int plane, int block,
|
||||
BLOCK_SIZE bsize, TX_SIZE tx_size, COLOR_MAP_TYPE type);
|
||||
int av1_cost_color_map(const MACROBLOCK *const x, int plane, BLOCK_SIZE bsize,
|
||||
TX_SIZE tx_size, COLOR_MAP_TYPE type);
|
||||
|
||||
void av1_tokenize_color_map(const MACROBLOCK *const x, int plane, int block,
|
||||
void av1_tokenize_color_map(const MACROBLOCK *const x, int plane,
|
||||
TOKENEXTRA **t, BLOCK_SIZE bsize, TX_SIZE tx_size,
|
||||
COLOR_MAP_TYPE type);
|
||||
|
||||
void av1_tokenize_sb(const struct AV1_COMP *cpi, struct ThreadData *td,
|
||||
TOKENEXTRA **t, RUN_TYPE dry_run, BLOCK_SIZE bsize,
|
||||
int *rate, const int mi_row, const int mi_col);
|
||||
#if CONFIG_SUPERTX
|
||||
void av1_tokenize_sb_supertx(const struct AV1_COMP *cpi, struct ThreadData *td,
|
||||
TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int *rate);
|
||||
#endif
|
||||
|
||||
extern const int16_t *av1_dct_value_cost_ptr;
|
||||
/* TODO: The Token field should be broken out into a separate char array to
|
||||
* improve cache locality, since it's needed for costing when the rest of the
|
||||
* fields are not.
|
||||
*/
|
||||
extern const TOKENVALUE *av1_dct_value_tokens_ptr;
|
||||
extern const TOKENVALUE *av1_dct_cat_lt_10_value_tokens;
|
||||
extern const int *av1_dct_cat_lt_10_value_cost;
|
||||
extern const int16_t av1_cat6_low_cost[256];
|
||||
#if CONFIG_HIGHBITDEPTH
|
||||
#define CAT6_HIGH_COST_ENTRIES 1024
|
||||
#else
|
||||
#define CAT6_HIGH_COST_ENTRIES 64
|
||||
#endif
|
||||
extern const int av1_cat6_high_cost[CAT6_HIGH_COST_ENTRIES];
|
||||
extern const uint8_t av1_cat6_skipped_bits_discount[8];
|
||||
|
||||
static INLINE void av1_get_token_extra(int v, int16_t *token, EXTRABIT *extra) {
|
||||
if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) {
|
||||
*token = CATEGORY6_TOKEN;
|
||||
if (v >= CAT6_MIN_VAL)
|
||||
*extra = 2 * v - 2 * CAT6_MIN_VAL;
|
||||
else
|
||||
*extra = -2 * v - 2 * CAT6_MIN_VAL + 1;
|
||||
return;
|
||||
}
|
||||
*token = av1_dct_cat_lt_10_value_tokens[v].token;
|
||||
*extra = av1_dct_cat_lt_10_value_tokens[v].extra;
|
||||
}
|
||||
static INLINE int16_t av1_get_token(int v) {
|
||||
if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) return 10;
|
||||
return av1_dct_cat_lt_10_value_tokens[v].token;
|
||||
}
|
||||
|
||||
static INLINE int av1_get_token_cost(int v, int16_t *token, int cat6_bits) {
|
||||
if (v >= CAT6_MIN_VAL || v <= -CAT6_MIN_VAL) {
|
||||
EXTRABIT extrabits;
|
||||
*token = CATEGORY6_TOKEN;
|
||||
extrabits = abs(v) - CAT6_MIN_VAL;
|
||||
return av1_cat6_low_cost[extrabits & 0xff] +
|
||||
av1_cat6_high_cost[extrabits >> 8] -
|
||||
av1_cat6_skipped_bits_discount[18 - cat6_bits];
|
||||
}
|
||||
*token = av1_dct_cat_lt_10_value_tokens[v].token;
|
||||
return av1_dct_cat_lt_10_value_cost[v];
|
||||
}
|
||||
COLOR_MAP_TYPE type, int allow_update_cdf,
|
||||
struct FRAME_COUNTS *counts);
|
||||
|
||||
static INLINE int av1_get_tx_eob(const struct segmentation *seg, int segment_id,
|
||||
TX_SIZE tx_size) {
|
||||
const int eob_max = tx_size_2d[tx_size];
|
||||
const int eob_max = av1_get_max_eob(tx_size);
|
||||
return segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
|
||||
}
|
||||
|
||||
|
|
|
|||
59
third_party/aom/av1/encoder/treewriter.c
vendored
59
third_party/aom/av1/encoder/treewriter.c
vendored
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "av1/encoder/treewriter.h"
|
||||
|
||||
static void tree2tok(struct av1_token *tokens, const aom_tree_index *tree,
|
||||
int i, int v, int l) {
|
||||
v += v;
|
||||
++l;
|
||||
|
||||
do {
|
||||
const aom_tree_index j = tree[i++];
|
||||
if (j <= 0) {
|
||||
tokens[-j].value = v;
|
||||
tokens[-j].len = l;
|
||||
} else {
|
||||
tree2tok(tokens, tree, j, v, l);
|
||||
}
|
||||
} while (++v & 1);
|
||||
}
|
||||
|
||||
void av1_tokens_from_tree(struct av1_token *tokens,
|
||||
const aom_tree_index *tree) {
|
||||
tree2tok(tokens, tree, 0, 0, 0);
|
||||
}
|
||||
|
||||
static unsigned int convert_distribution(unsigned int i, aom_tree tree,
|
||||
unsigned int branch_ct[][2],
|
||||
const unsigned int num_events[]) {
|
||||
unsigned int left, right;
|
||||
|
||||
if (tree[i] <= 0)
|
||||
left = num_events[-tree[i]];
|
||||
else
|
||||
left = convert_distribution(tree[i], tree, branch_ct, num_events);
|
||||
|
||||
if (tree[i + 1] <= 0)
|
||||
right = num_events[-tree[i + 1]];
|
||||
else
|
||||
right = convert_distribution(tree[i + 1], tree, branch_ct, num_events);
|
||||
|
||||
branch_ct[i >> 1][0] = left;
|
||||
branch_ct[i >> 1][1] = right;
|
||||
return left + right;
|
||||
}
|
||||
|
||||
void av1_tree_probs_from_distribution(aom_tree tree,
|
||||
unsigned int branch_ct[/* n-1 */][2],
|
||||
const unsigned int num_events[/* n */]) {
|
||||
convert_distribution(0, tree, branch_ct, num_events);
|
||||
}
|
||||
42
third_party/aom/av1/encoder/treewriter.h
vendored
42
third_party/aom/av1/encoder/treewriter.h
vendored
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AV1_ENCODER_TREEWRITER_H_
|
||||
#define AV1_ENCODER_TREEWRITER_H_
|
||||
|
||||
#include "aom_dsp/bitwriter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void av1_tree_probs_from_distribution(aom_tree tree,
|
||||
unsigned int branch_ct[/* n - 1 */][2],
|
||||
const unsigned int num_events[/* n */]);
|
||||
|
||||
struct av1_token {
|
||||
int value;
|
||||
int len;
|
||||
};
|
||||
|
||||
void av1_tokens_from_tree(struct av1_token *, const aom_tree_index *);
|
||||
|
||||
static INLINE void av1_write_token(aom_writer *w, const aom_tree_index *tree,
|
||||
const aom_prob *probs,
|
||||
const struct av1_token *token) {
|
||||
aom_write_tree(w, tree, probs, token->value, token->len, 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AV1_ENCODER_TREEWRITER_H_
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue