Update aom to commit id f5bdeac22930ff4c6b219be49c843db35970b918

This commit is contained in:
trav90 2018-10-18 06:04:57 -05:00 • committed by Roy Tam
commit 2ab8fcbfd1
370 changed files with 56185 additions and 32026 deletions

View file

@ -33,6 +33,8 @@ set(AOM_AV1_COMMON_SOURCES
"${AOM_ROOT}/av1/common/common_data.h"
"${AOM_ROOT}/av1/common/convolve.c"
"${AOM_ROOT}/av1/common/convolve.h"
"${AOM_ROOT}/av1/common/daala_tx.c"
"${AOM_ROOT}/av1/common/daala_tx.h"
"${AOM_ROOT}/av1/common/debugmodes.c"
"${AOM_ROOT}/av1/common/entropy.c"
"${AOM_ROOT}/av1/common/entropy.h"
@ -158,9 +160,11 @@ set(AOM_AV1_COMMON_INTRIN_SSSE3
set(AOM_AV1_COMMON_INTRIN_SSE4_1
"${AOM_ROOT}/av1/common/x86/av1_fwd_txfm1d_sse4.c"
"${AOM_ROOT}/av1/common/x86/av1_fwd_txfm2d_sse4.c")
"${AOM_ROOT}/av1/common/x86/av1_fwd_txfm2d_sse4.c"
"${AOM_ROOT}/av1/common/x86/highbd_inv_txfm_sse4.c")
set(AOM_AV1_COMMON_INTRIN_AVX2
"${AOM_ROOT}/av1/common/x86/highbd_inv_txfm_avx2.c"
"${AOM_ROOT}/av1/common/x86/hybrid_inv_txfm_avx2.c")
set(AOM_AV1_COMMON_INTRIN_DSPR2
@ -189,7 +193,14 @@ set(AOM_AV1_ENCODER_ASM_SSSE3_X86_64
set(AOM_AV1_ENCODER_INTRIN_SSSE3
"${AOM_ROOT}/av1/encoder/x86/dct_ssse3.c")
set(AOM_AV1_ENCODER_INTRIN_SSE4_1
${AOM_AV1_ENCODER_INTRIN_SSE4_1}
"${AOM_ROOT}/av1/encoder/x86/av1_highbd_quantize_sse4.c"
"${AOM_ROOT}/av1/encoder/x86/highbd_fwd_txfm_sse4.c")
set(AOM_AV1_ENCODER_INTRIN_AVX2
"${AOM_ROOT}/av1/encoder/x86/av1_quantize_avx2.c"
"${AOM_ROOT}/av1/encoder/x86/av1_highbd_quantize_avx2.c"
"${AOM_ROOT}/av1/encoder/x86/error_intrin_avx2.c"
"${AOM_ROOT}/av1/encoder/x86/hybrid_fwd_txfm_avx2.c")
@ -207,17 +218,7 @@ set(AOM_AV1_ENCODER_INTRIN_MSA
if (CONFIG_HIGHBITDEPTH)
set(AOM_AV1_COMMON_INTRIN_SSE4_1
${AOM_AV1_COMMON_INTRIN_SSE4_1}
"${AOM_ROOT}/av1/common/x86/av1_highbd_convolve_sse4.c"
"${AOM_ROOT}/av1/common/x86/highbd_inv_txfm_sse4.c")
set(AOM_AV1_COMMON_INTRIN_AVX2
${AOM_AV1_COMMON_INTRIN_AVX2}
"${AOM_ROOT}/av1/common/x86/highbd_inv_txfm_avx2.c")
set(AOM_AV1_ENCODER_INTRIN_SSE4_1
${AOM_AV1_ENCODER_INTRIN_SSE4_1}
"${AOM_ROOT}/av1/encoder/x86/av1_highbd_quantize_sse4.c"
"${AOM_ROOT}/av1/encoder/x86/highbd_fwd_txfm_sse4.c")
"${AOM_ROOT}/av1/common/x86/av1_highbd_convolve_sse4.c")
else ()
set(AOM_AV1_COMMON_INTRIN_NEON
${AOM_AV1_COMMON_INTRIN_NEON}
@ -234,7 +235,6 @@ if (CONFIG_CDEF)
set(AOM_AV1_COMMON_SOURCES
${AOM_AV1_COMMON_SOURCES}
"${AOM_ROOT}/av1/common/clpf.c"
"${AOM_ROOT}/av1/common/clpf.h"
"${AOM_ROOT}/av1/common/clpf_simd.h"
"${AOM_ROOT}/av1/common/cdef_simd.h"
"${AOM_ROOT}/av1/common/cdef.c"
@ -268,6 +268,12 @@ if (CONFIG_CDEF)
"${AOM_ROOT}/av1/common/od_dering_neon.c")
endif ()
if (CONFIG_CONVOLVE_ROUND)
set(AOM_AV1_COMMON_INTRIN_AVX2
${AOM_AV1_COMMON_INTRIN_AVX2}
"${AOM_ROOT}/av1/common/x86/convolve_avx2.c")
endif ()
if (CONFIG_EXT_INTER)
set(AOM_AV1_ENCODER_SOURCES
${AOM_AV1_ENCODER_SOURCES}
@ -442,25 +448,33 @@ endif ()
# this function is called.
function (setup_av1_targets)
add_library(aom_av1_common OBJECT ${AOM_AV1_COMMON_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_av1_common)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_av1_common>)
list(APPEND AOM_LIB_TARGETS aom_av1_common)
create_dummy_source_file("aom_av1" "c" "dummy_source_file")
add_library(aom_av1 OBJECT "${dummy_source_file}")
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_av1_common>)
list(APPEND AOM_LIB_TARGETS aom_av1)
# Not all generators support libraries consisting only of object files. Add a
# dummy source file to the aom_av1 target.
add_dummy_source_file_to_target("aom_av1" "c")
if (CONFIG_AV1_DECODER)
add_library(aom_av1_decoder OBJECT ${AOM_AV1_DECODER_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_av1_decoder)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_av1_decoder>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_av1_decoder>)
endif ()
if (CONFIG_AV1_ENCODER)
add_library(aom_av1_encoder OBJECT ${AOM_AV1_ENCODER_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_av1_encoder)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_av1_encoder>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_av1_encoder>)
endif ()
if (HAVE_SSE2)
require_flag_nomsvc("-msse2" NO)
add_intrinsics_object_library("-msse2" "sse2" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_SSE2")
"AOM_AV1_COMMON_INTRIN_SSE2" "aom")
if (CONFIG_AV1_DECODER)
if (AOM_AV1_DECODER_ASM_SSE2)
add_asm_library("aom_av1_decoder_sse2" "AOM_AV1_DECODER_ASM_SSE2" "aom")
@ -468,39 +482,39 @@ function (setup_av1_targets)
if (AOM_AV1_DECODER_INTRIN_SSE2)
add_intrinsics_object_library("-msse2" "sse2" "aom_av1_decoder"
"AOM_AV1_DECODER_INTRIN_SSE2")
"AOM_AV1_DECODER_INTRIN_SSE2" "aom")
endif ()
endif ()
if (CONFIG_AV1_ENCODER)
add_asm_library("aom_av1_encoder_sse2" "AOM_AV1_ENCODER_ASM_SSE2" "aom")
add_intrinsics_object_library("-msse2" "sse2" "aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_SSE2")
"AOM_AV1_ENCODER_INTRIN_SSE2" "aom")
endif ()
endif ()
if (HAVE_SSSE3)
require_flag_nomsvc("-mssse3" NO)
add_intrinsics_object_library("-mssse3" "ssse3" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_SSSE3")
"AOM_AV1_COMMON_INTRIN_SSSE3" "aom")
if (CONFIG_AV1_DECODER)
if (AOM_AV1_DECODER_INTRIN_SSSE3)
add_intrinsics_object_library("-mssse3" "ssse3" "aom_av1_decoder"
"AOM_AV1_DECODER_INTRIN_SSSE3")
"AOM_AV1_DECODER_INTRIN_SSSE3" "aom")
endif ()
endif ()
if (CONFIG_AV1_ENCODER)
add_intrinsics_object_library("-mssse3" "ssse3" "aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_SSSE3")
"AOM_AV1_ENCODER_INTRIN_SSSE3" "aom")
endif ()
endif ()
if (HAVE_SSE4_1)
require_flag_nomsvc("-msse4.1" NO)
add_intrinsics_object_library("-msse4.1" "sse4" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_SSE4_1")
"AOM_AV1_COMMON_INTRIN_SSE4_1" "aom")
if (CONFIG_AV1_ENCODER)
if ("${AOM_TARGET_CPU}" STREQUAL "x86_64")
@ -510,7 +524,7 @@ function (setup_av1_targets)
if (AOM_AV1_ENCODER_INTRIN_SSE4_1)
add_intrinsics_object_library("-msse4.1" "sse4" "aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_SSE4_1")
"AOM_AV1_ENCODER_INTRIN_SSE4_1" "aom")
endif ()
endif ()
endif ()
@ -518,11 +532,11 @@ function (setup_av1_targets)
if (HAVE_AVX2)
require_flag_nomsvc("-mavx2" NO)
add_intrinsics_object_library("-mavx2" "avx2" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_AVX2")
"AOM_AV1_COMMON_INTRIN_AVX2" "aom")
if (CONFIG_AV1_ENCODER)
add_intrinsics_object_library("-mavx2" "avx2" "aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_AVX2")
"AOM_AV1_ENCODER_INTRIN_AVX2" "aom")
endif ()
endif ()
@ -531,29 +545,32 @@ function (setup_av1_targets)
add_intrinsics_object_library("${AOM_INTRIN_NEON_FLAG}"
"neon"
"aom_av1_common"
"AOM_AV1_COMMON_INTRIN_NEON")
"AOM_AV1_COMMON_INTRIN_NEON" "aom")
endif ()
if (AOM_AV1_ENCODER_INTRIN_NEON)
add_intrinsics_object_library("${AOM_INTRIN_NEON_FLAG}"
"neon"
"aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_NEON")
"AOM_AV1_ENCODER_INTRIN_NEON" "aom")
endif ()
endif ()
if (HAVE_DSPR2)
add_intrinsics_object_library("" "dspr2" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_DSPR2")
"AOM_AV1_COMMON_INTRIN_DSPR2" "aom")
endif ()
if (HAVE_MSA)
add_intrinsics_object_library("" "msa" "aom_av1_common"
"AOM_AV1_COMMON_INTRIN_MSA")
"AOM_AV1_COMMON_INTRIN_MSA" "aom")
add_intrinsics_object_library("" "msa" "aom_av1_encoder"
"AOM_AV1_ENCODER_INTRIN_MSA")
"AOM_AV1_ENCODER_INTRIN_MSA" "aom")
endif ()
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_dsp>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_scale>)
# Pass the new lib targets up to the parent scope instance of
# $AOM_LIB_TARGETS.
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)

View file

@ -24,6 +24,8 @@ AV1_COMMON_SRCS-yes += common/frame_buffers.h
AV1_COMMON_SRCS-yes += common/alloccommon.h
AV1_COMMON_SRCS-yes += common/blockd.h
AV1_COMMON_SRCS-yes += common/common.h
AV1_COMMON_SRCS-yes += common/daala_tx.c
AV1_COMMON_SRCS-yes += common/daala_tx.h
AV1_COMMON_SRCS-yes += common/entropy.h
AV1_COMMON_SRCS-yes += common/entropymode.h
AV1_COMMON_SRCS-yes += common/entropymv.h
@ -71,6 +73,7 @@ AV1_COMMON_SRCS-yes += common/av1_fwd_txfm2d.c
AV1_COMMON_SRCS-yes += common/av1_fwd_txfm1d_cfg.h
AV1_COMMON_SRCS-yes += common/av1_inv_txfm2d.c
AV1_COMMON_SRCS-yes += common/av1_inv_txfm1d_cfg.h
AV1_COMMON_SRCS-$(HAVE_AVX2) += common/x86/convolve_avx2.c
AV1_COMMON_SRCS-$(HAVE_SSSE3) += common/x86/av1_convolve_ssse3.c
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/av1_highbd_convolve_sse4.c
@ -88,7 +91,6 @@ AV1_COMMON_SRCS-yes += common/warped_motion.c
endif
ifeq ($(CONFIG_CDEF),yes)
AV1_COMMON_SRCS-yes += common/clpf.c
AV1_COMMON_SRCS-yes += common/clpf.h
AV1_COMMON_SRCS-yes += common/clpf_simd.h
AV1_COMMON_SRCS-yes += common/cdef_simd.h
AV1_COMMON_SRCS-$(HAVE_SSE2) += common/clpf_sse2.c
@ -154,11 +156,10 @@ AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/av1_txfm1d_sse4.h
AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/av1_fwd_txfm1d_sse4.c
AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/av1_fwd_txfm2d_sse4.c
endif
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/highbd_txfm_utility_sse4.h
AV1_COMMON_SRCS-$(HAVE_SSE4_1) += common/x86/highbd_inv_txfm_sse4.c
AV1_COMMON_SRCS-$(HAVE_AVX2) += common/x86/highbd_inv_txfm_avx2.c
endif
ifneq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/iht4x4_add_neon.c
@ -177,4 +178,11 @@ AV1_COMMON_SRCS-$(HAVE_SSSE3) += common/x86/highbd_warp_plane_ssse3.c
endif
endif
ifeq ($(CONFIG_CONVOLVE_ROUND),yes)
AV1_COMMON_SRCS-$(HAVE_SSE2) += common/x86/convolve_2d_sse2.c
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_COMMON_SRCS-$(HAVE_SSSE3) += common/x86/highbd_convolve_2d_ssse3.c
endif
endif
$(eval $(call rtcd_h_template,av1_rtcd,av1/common/av1_rtcd_defs.pl))

View file

@ -21,6 +21,8 @@ AV1_CX_SRCS-yes += av1_cx_iface.c
AV1_CX_SRCS-yes += encoder/av1_quantize.c
AV1_CX_SRCS-yes += encoder/av1_quantize.h
AV1_CX_SRCS-yes += encoder/bitstream.c
AV1_CX_SRCS-$(CONFIG_BGSPRITE) += encoder/bgsprite.c
AV1_CX_SRCS-$(CONFIG_BGSPRITE) += encoder/bgsprite.h
AV1_CX_SRCS-yes += encoder/context_tree.c
AV1_CX_SRCS-yes += encoder/context_tree.h
AV1_CX_SRCS-yes += encoder/cost.h
@ -121,10 +123,12 @@ AV1_CX_SRCS-yes += encoder/encint.h
endif
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/av1_quantize_sse2.c
AV1_CX_SRCS-$(HAVE_AVX2) += encoder/x86/av1_quantize_avx2.c
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/temporal_filter_apply_sse2.asm
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/highbd_block_error_intrin_sse2.c
endif
AV1_CX_SRCS-$(HAVE_AVX2) += encoder/x86/av1_highbd_quantize_avx2.c
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/dct_sse2.asm
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/error_sse2.asm
@ -136,10 +140,10 @@ endif
AV1_CX_SRCS-$(HAVE_SSE2) += encoder/x86/dct_intrin_sse2.c
AV1_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/dct_ssse3.c
AV1_CX_SRCS-$(HAVE_AVX2) += encoder/x86/hybrid_fwd_txfm_avx2.c
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
AV1_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/av1_highbd_quantize_sse4.c
AV1_CX_SRCS-$(HAVE_SSE4_1) += encoder/x86/highbd_fwd_txfm_sse4.c
endif
ifeq ($(CONFIG_EXT_INTER),yes)
AV1_CX_SRCS-yes += encoder/wedge_utils.c

View file

@ -55,10 +55,8 @@ struct av1_extracfg {
unsigned int qm_min;
unsigned int qm_max;
#endif
#if CONFIG_TILE_GROUPS
unsigned int num_tg;
unsigned int mtu_size;
#endif
#if CONFIG_TEMPMV_SIGNALING
unsigned int disable_tempmv;
#endif
@ -71,6 +69,10 @@ struct av1_extracfg {
aom_bit_depth_t bit_depth;
aom_tune_content content;
aom_color_space_t color_space;
#if CONFIG_COLORSPACE_HEADERS
aom_transfer_function_t transfer_function;
aom_chroma_sample_position_t chroma_sample_position;
#endif
int color_range;
int render_width;
int render_height;
@ -79,7 +81,7 @@ struct av1_extracfg {
int ans_window_size_log2;
#endif
#if CONFIG_EXT_TILE
unsigned int tile_encoding_mode;
unsigned int single_tile_decoding;
#endif // CONFIG_EXT_TILE
unsigned int motion_vector_unit_test;
@ -94,15 +96,10 @@ static struct av1_extracfg default_extra_cfg = {
0, // noise_sensitivity
0, // sharpness
0, // static_thresh
#if CONFIG_EXT_TILE
UINT_MAX, // tile_columns
UINT_MAX, // tile_rows
#else
0, // tile_columns
0, // tile_rows
#endif // CONFIG_EXT_TILE
0, // tile_columns
0, // tile_rows
#if CONFIG_DEPENDENT_HORZTILES
0, // Depdendent Horizontal tiles
0, // Dependent Horizontal tiles
#endif
#if CONFIG_LOOPFILTERING_ACROSS_TILES
1, // loop_filter_across_tiles_enabled
@ -122,10 +119,8 @@ static struct av1_extracfg default_extra_cfg = {
DEFAULT_QM_FIRST, // qm_min
DEFAULT_QM_LAST, // qm_max
#endif
#if CONFIG_TILE_GROUPS
1, // max number of tile groups
0, // mtu_size
#endif
#if CONFIG_TEMPMV_SIGNALING
0, // disable temporal mv prediction
#endif
@ -134,10 +129,14 @@ static struct av1_extracfg default_extra_cfg = {
#if CONFIG_EXT_DELTA_Q
NO_DELTA_Q, // deltaq_mode
#endif
CONFIG_XIPHRC, // frame_periodic_delta_q
AOM_BITS_8, // Bit depth
AOM_CONTENT_DEFAULT, // content
AOM_CS_UNKNOWN, // color space
CONFIG_XIPHRC, // frame_periodic_delta_q
AOM_BITS_8, // Bit depth
AOM_CONTENT_DEFAULT, // content
AOM_CS_UNKNOWN, // color space
#if CONFIG_COLORSPACE_HEADERS
AOM_TF_UNKNOWN, // transfer function
AOM_CSP_UNKNOWN, // chroma sample position
#endif
0, // color range
0, // render width
0, // render height
@ -146,7 +145,7 @@ static struct av1_extracfg default_extra_cfg = {
23, // ans_window_size_log2
#endif
#if CONFIG_EXT_TILE
0, // Tile encoding mode is TILE_NORMAL by default.
0, // Single tile decoding is off by default.
#endif // CONFIG_EXT_TILE
0, // motion_vector_unit_test
@ -235,10 +234,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100);
RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_LAST_PASS);
RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
@ -250,10 +246,18 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
(MAX_LAG_BUFFERS - 1));
}
if (cfg->rc_resize_allowed == 1) {
RANGE_CHECK_HI(cfg, rc_scaled_width, cfg->g_w);
RANGE_CHECK_HI(cfg, rc_scaled_height, cfg->g_h);
}
RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_DYNAMIC);
RANGE_CHECK(cfg, rc_resize_numerator, SCALE_DENOMINATOR / 2,
SCALE_DENOMINATOR);
RANGE_CHECK(cfg, rc_resize_kf_numerator, SCALE_DENOMINATOR / 2,
SCALE_DENOMINATOR);
#if CONFIG_FRAME_SUPERRES
RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_DYNAMIC);
RANGE_CHECK(cfg, rc_superres_numerator, SCALE_DENOMINATOR / 2,
SCALE_DENOMINATOR);
RANGE_CHECK(cfg, rc_superres_kf_numerator, SCALE_DENOMINATOR / 2,
SCALE_DENOMINATOR);
#endif // CONFIG_FRAME_SUPERRES
// AV1 does not support a lower bound on the keyframe interval in
// automatic keyframe placement mode.
@ -273,28 +277,34 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
AOM_SUPERBLOCK_SIZE_DYNAMIC);
#if CONFIG_EXT_TILE
RANGE_CHECK_HI(cfg, large_scale_tile, 1);
RANGE_CHECK_HI(extra_cfg, single_tile_decoding, 1);
if (cfg->large_scale_tile) {
// TODO(any): Waring. If CONFIG_EXT_TILE is true, tile_columns really
// means tile_width, and tile_rows really means tile_hight. The interface
// should be sanitized.
#if CONFIG_EXT_PARTITION
if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
if (extra_cfg->tile_columns != UINT_MAX)
RANGE_CHECK(extra_cfg, tile_columns, 1, 32);
if (extra_cfg->tile_rows != UINT_MAX)
RANGE_CHECK(extra_cfg, tile_rows, 1, 32);
} else
if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
if (extra_cfg->tile_columns != 0)
RANGE_CHECK(extra_cfg, tile_columns, 1, 32);
if (extra_cfg->tile_rows != 0) RANGE_CHECK(extra_cfg, tile_rows, 1, 32);
} else {
#endif // CONFIG_EXT_PARTITION
{
if (extra_cfg->tile_columns != UINT_MAX)
RANGE_CHECK(extra_cfg, tile_columns, 1, 64);
if (extra_cfg->tile_rows != UINT_MAX)
RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
}
RANGE_CHECK_HI(extra_cfg, tile_encoding_mode, 1);
#else
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
if (extra_cfg->tile_columns != 0)
RANGE_CHECK(extra_cfg, tile_columns, 1, 64);
if (extra_cfg->tile_rows != 0) RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
#if CONFIG_EXT_PARTITION
}
#endif // CONFIG_EXT_PARTITION
} else {
#endif // CONFIG_EXT_TILE
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
#if CONFIG_EXT_TILE
}
#endif // CONFIG_EXT_TILE
#if CONFIG_DEPENDENT_HORZTILES
RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1);
#endif
@ -354,7 +364,14 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
cfg->g_bit_depth == AOM_BITS_8) {
ERROR("Codec bit-depth 8 not supported in profile > 1");
}
#if CONFIG_COLORSPACE_HEADERS
RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_ICTCP);
RANGE_CHECK(extra_cfg, transfer_function, AOM_TF_UNKNOWN, AOM_TF_HLG);
RANGE_CHECK(extra_cfg, chroma_sample_position, AOM_CSP_UNKNOWN,
AOM_CSP_COLOCATED);
#else
RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_SRGB);
#endif
RANGE_CHECK(extra_cfg, color_range, 0, 1);
#if CONFIG_ANS && ANS_MAX_SYMBOLS
RANGE_CHECK(extra_cfg, ans_window_size_log2, 8, 23);
@ -461,10 +478,12 @@ static aom_codec_err_t set_encoder_config(
oxcf->qm_maxlevel = extra_cfg->qm_max;
#endif
#if CONFIG_TILE_GROUPS
oxcf->num_tile_groups = extra_cfg->num_tg;
#if CONFIG_EXT_TILE
// In large-scale tile encoding mode, num_tile_groups is always 1.
if (cfg->large_scale_tile) oxcf->num_tile_groups = 1;
#endif // CONFIG_EXT_TILE
oxcf->mtu = extra_cfg->mtu_size;
#endif
#if CONFIG_TEMPMV_SIGNALING
oxcf->disable_tempmv = extra_cfg->disable_tempmv;
@ -472,26 +491,23 @@ static aom_codec_err_t set_encoder_config(
oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
oxcf->scaled_frame_width = cfg->rc_scaled_width;
oxcf->scaled_frame_height = cfg->rc_scaled_height;
if (cfg->rc_resize_allowed == 1) {
oxcf->resize_mode =
(oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0)
? RESIZE_DYNAMIC
: RESIZE_FIXED;
} else {
oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
oxcf->resize_scale_numerator = (uint8_t)cfg->rc_resize_numerator;
oxcf->resize_kf_scale_numerator = (uint8_t)cfg->rc_resize_kf_numerator;
if (oxcf->resize_mode == RESIZE_FIXED &&
oxcf->resize_scale_numerator == SCALE_DENOMINATOR &&
oxcf->resize_kf_scale_numerator == SCALE_DENOMINATOR)
oxcf->resize_mode = RESIZE_NONE;
}
// Initialize to input resolution if not specified.
if (oxcf->resize_mode != RESIZE_FIXED) {
oxcf->scaled_frame_width = oxcf->width;
oxcf->scaled_frame_height = oxcf->height;
}
#if CONFIG_FRAME_SUPERRES
oxcf->superres_enabled = 1; // TODO(afergs): Check the config
#endif // CONFIG_FRAME_SUPERRES
oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
oxcf->superres_scale_numerator = (uint8_t)cfg->rc_superres_numerator;
oxcf->superres_kf_scale_numerator = (uint8_t)cfg->rc_superres_kf_numerator;
if (oxcf->superres_mode == SUPERRES_FIXED &&
oxcf->superres_scale_numerator == SCALE_DENOMINATOR &&
oxcf->superres_kf_scale_numerator == SCALE_DENOMINATOR)
oxcf->superres_mode = SUPERRES_NONE;
#endif // CONFIG_FRAME_SUPERRES
oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
@ -523,6 +539,10 @@ static aom_codec_err_t set_encoder_config(
#endif
oxcf->color_space = extra_cfg->color_space;
#if CONFIG_COLORSPACE_HEADERS
oxcf->transfer_function = extra_cfg->transfer_function;
oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
#endif
oxcf->color_range = extra_cfg->color_range;
oxcf->render_width = extra_cfg->render_width;
oxcf->render_height = extra_cfg->render_height;
@ -542,23 +562,38 @@ static aom_codec_err_t set_encoder_config(
#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
#if CONFIG_EXT_TILE
{
oxcf->large_scale_tile = cfg->large_scale_tile;
oxcf->single_tile_decoding =
(oxcf->large_scale_tile) ? extra_cfg->single_tile_decoding : 0;
if (oxcf->large_scale_tile) {
#if CONFIG_EXT_PARTITION
const unsigned int max =
extra_cfg->superblock_size == AOM_SUPERBLOCK_SIZE_64X64 ? 64 : 32;
#else
const unsigned int max = 64;
#endif // CONFIG_EXT_PARTITION
oxcf->tile_columns = AOMMIN(extra_cfg->tile_columns, max);
oxcf->tile_rows = AOMMIN(extra_cfg->tile_rows, max);
oxcf->tile_encoding_mode = extra_cfg->tile_encoding_mode;
}
#else
oxcf->tile_columns = extra_cfg->tile_columns;
oxcf->tile_rows = extra_cfg->tile_rows;
// If tile size is not set, set it to the default value.
const unsigned int tc =
(!extra_cfg->tile_columns) ? UINT_MAX : extra_cfg->tile_columns;
const unsigned int tr =
(!extra_cfg->tile_rows) ? UINT_MAX : extra_cfg->tile_rows;
oxcf->tile_columns = AOMMIN(tc, max);
oxcf->tile_rows = AOMMIN(tr, max);
} else {
#endif // CONFIG_EXT_TILE
oxcf->tile_columns = extra_cfg->tile_columns;
oxcf->tile_rows = extra_cfg->tile_rows;
#if CONFIG_EXT_TILE
}
#endif // CONFIG_EXT_TILE
#if CONFIG_DEPENDENT_HORZTILES
oxcf->dependent_horz_tiles = extra_cfg->dependent_horz_tiles;
oxcf->dependent_horz_tiles =
#if CONFIG_EXT_TILE
(cfg->large_scale_tile) ? 0 :
#endif // CONFIG_EXT_TILE
extra_cfg->dependent_horz_tiles;
#endif
#if CONFIG_LOOPFILTERING_ACROSS_TILES
oxcf->loop_filter_across_tiles_enabled =
@ -828,7 +863,6 @@ static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
}
#endif
#if CONFIG_TILE_GROUPS
static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
@ -841,7 +875,6 @@ static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
return update_extra_cfg(ctx, &extra_cfg);
}
#endif
#if CONFIG_TEMPMV_SIGNALING
static aom_codec_err_t ctrl_set_disable_tempmv(aom_codec_alg_priv_t *ctx,
va_list args) {
@ -859,10 +892,10 @@ static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
}
#if CONFIG_EXT_TILE
static aom_codec_err_t ctrl_set_tile_encoding_mode(aom_codec_alg_priv_t *ctx,
va_list args) {
static aom_codec_err_t ctrl_set_single_tile_decoding(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.tile_encoding_mode = CAST(AV1E_SET_TILE_ENCODING_MODE, args);
extra_cfg.single_tile_decoding = CAST(AV1E_SET_SINGLE_TILE_DECODING, args);
return update_extra_cfg(ctx, &extra_cfg);
}
#endif // CONFIG_EXT_TILE
@ -992,12 +1025,10 @@ static void pick_quickcompress_mode(aom_codec_alg_priv_t *ctx,
}
// Turn on to test if supplemental superframe data breaks decoding
// #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA
#define TEST_SUPPLEMENTAL_SUPERFRAME_DATA 0
static int write_superframe_index(aom_codec_alg_priv_t *ctx) {
uint8_t marker = 0xc0;
unsigned int mask;
int mag, index_sz;
int i;
size_t max_frame_sz = 0;
assert(ctx->pending_frame_count);
@ -1005,12 +1036,14 @@ static int write_superframe_index(aom_codec_alg_priv_t *ctx) {
// Add the number of frames to the marker byte
marker |= ctx->pending_frame_count - 1;
for (i = 0; i < ctx->pending_frame_count - 1; i++) {
const size_t frame_sz = (unsigned int)ctx->pending_frame_sizes[i] - 1;
max_frame_sz = frame_sz > max_frame_sz ? frame_sz : max_frame_sz;
for (int i = 0; i < ctx->pending_frame_count - 1; i++) {
const size_t frame_sz = ctx->pending_frame_sizes[i] - 1;
max_frame_sz = AOMMAX(frame_sz, max_frame_sz);
}
// Choose the magnitude
int mag;
unsigned int mask;
for (mag = 0, mask = 0xff; mag < 4; mag++) {
if (max_frame_sz <= mask) break;
mask <<= 8;
@ -1019,43 +1052,43 @@ static int write_superframe_index(aom_codec_alg_priv_t *ctx) {
marker |= mag << 3;
// Write the index
index_sz = 2 + (mag + 1) * (ctx->pending_frame_count - 1);
if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
uint8_t buffer[256];
uint8_t *x = buffer;
if (TEST_SUPPLEMENTAL_SUPERFRAME_DATA) {
uint8_t marker_test = 0xc0;
int mag_test = 2; // 1 - 4
int frames_test = 4; // 1 - 8
int index_sz_test = 2 + mag_test * frames_test;
marker_test |= frames_test - 1;
marker_test |= (mag_test - 1) << 3;
*x++ = marker_test;
for (i = 0; i < mag_test * frames_test; ++i)
for (int i = 0; i < mag_test * frames_test; ++i)
*x++ = 0; // fill up with arbitrary data
*x++ = marker_test;
ctx->pending_cx_data_sz += index_sz_test;
printf("Added supplemental superframe data\n");
#endif
*x++ = marker;
for (i = 0; i < ctx->pending_frame_count - 1; i++) {
unsigned int this_sz;
int j;
assert(ctx->pending_frame_sizes[i] > 0);
this_sz = (unsigned int)ctx->pending_frame_sizes[i] - 1;
for (j = 0; j <= mag; j++) {
*x++ = this_sz & 0xff;
this_sz >>= 8;
}
}
*x++ = marker;
ctx->pending_cx_data_sz += index_sz;
#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
index_sz += index_sz_test;
#endif
}
return index_sz;
*x++ = marker;
for (int i = 0; i < ctx->pending_frame_count - 1; i++) {
assert(ctx->pending_frame_sizes[i] > 0);
unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i] - 1;
for (int j = 0; j <= mag; j++) {
*x++ = this_sz & 0xff;
this_sz >>= 8;
}
}
*x++ = marker;
const size_t index_sz = x - buffer;
assert(ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz);
// move the frame to make room for the index
memmove(ctx->pending_cx_data + index_sz, ctx->pending_cx_data,
ctx->pending_cx_data_sz);
memcpy(ctx->pending_cx_data, buffer, index_sz);
ctx->pending_cx_data_sz += index_sz;
return (int)index_sz;
}
// av1 uses 10,000,000 ticks/second as time stamp
@ -1091,10 +1124,8 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
unsigned long deadline) {
const size_t kMinCompressedSize = 8192;
volatile aom_codec_err_t res = AOM_CODEC_OK;
volatile aom_enc_frame_flags_t flags = enc_flags;
AV1_COMP *const cpi = ctx->cpi;
const aom_rational_t *const timebase = &ctx->cfg.g_timebase;
size_t data_sz;
if (cpi == NULL) return AOM_CODEC_INVALID_PARAM;
@ -1104,14 +1135,15 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
// failure condition, encoder setup is done fully in init() currently.
if (res == AOM_CODEC_OK) {
#if CONFIG_EXT_REFS
data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img);
size_t data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img);
#else
// There's no codec control for multiple alt-refs so check the encoder
// instance for its status to determine the compressed data size.
data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img) / 8 *
(cpi->multi_arf_allowed ? 8 : 2);
size_t data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) *
get_image_bps(img) / 8 *
(cpi->multi_arf_allowed ? 8 : 2);
#endif // CONFIG_EXT_REFS
if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize;
if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) {
@ -1128,6 +1160,8 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
pick_quickcompress_mode(ctx, deadline);
aom_codec_pkt_list_init(&ctx->pkt_list);
volatile aom_enc_frame_flags_t flags = enc_flags;
// Handle Flags
if (((flags & AOM_EFLAG_NO_UPD_GF) && (flags & AOM_EFLAG_FORCE_GF)) ||
((flags & AOM_EFLAG_NO_UPD_ARF) && (flags & AOM_EFLAG_FORCE_ARF))) {
@ -1155,18 +1189,15 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
}
if (res == AOM_CODEC_OK) {
unsigned int lib_flags = 0;
YV12_BUFFER_CONFIG sd;
int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts);
int64_t dst_end_time_stamp =
timebase_units_to_ticks(timebase, pts + duration);
size_t size, cx_data_sz;
unsigned char *cx_data;
// Set up internal flags
if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1;
if (img != NULL) {
YV12_BUFFER_CONFIG sd;
res = image2yuvconfig(img, &sd);
// Store the original flags in to the frame buffer. Will extract the
@ -1178,8 +1209,8 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
ctx->next_frame_flags = 0;
}
cx_data = ctx->cx_data;
cx_data_sz = ctx->cx_data_sz;
unsigned char *cx_data = ctx->cx_data;
size_t cx_data_sz = ctx->cx_data_sz;
/* Any pending invisible frames? */
if (ctx->pending_cx_data) {
@ -1198,8 +1229,10 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
}
}
size_t frame_size;
unsigned int lib_flags = 0;
while (cx_data_sz >= ctx->cx_data_sz / 2 &&
-1 != av1_get_compressed_data(cpi, &lib_flags, &size, cx_data,
-1 != av1_get_compressed_data(cpi, &lib_flags, &frame_size, cx_data,
&dst_time_stamp, &dst_end_time_stamp,
!img)) {
#if CONFIG_REFERENCE_BUFFER
@ -1208,47 +1241,45 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
return AOM_CODEC_ERROR;
}
#endif
if (size) {
aom_codec_cx_pkt_t pkt;
if (!frame_size) continue;
// Pack invisible frames with the next visible frame
if (!cpi->common.show_frame) {
if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
ctx->pending_cx_data_sz += size;
ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
cx_data += size;
cx_data_sz -= size;
if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
continue;
}
ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
ctx->pending_cx_data_sz += frame_size;
// Add the frame packet to the list of returned packets.
pkt.kind = AOM_CODEC_CX_FRAME_PKT;
pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units(
timebase, dst_end_time_stamp - dst_time_stamp);
pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
cx_data += frame_size;
cx_data_sz -= frame_size;
if (ctx->pending_cx_data) {
ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
ctx->pending_cx_data_sz += size;
size += write_superframe_index(ctx);
pkt.data.frame.buf = ctx->pending_cx_data;
pkt.data.frame.sz = ctx->pending_cx_data_sz;
ctx->pending_cx_data = NULL;
ctx->pending_cx_data_sz = 0;
ctx->pending_frame_count = 0;
} else {
pkt.data.frame.buf = cx_data;
pkt.data.frame.sz = size;
}
pkt.data.frame.partition_id = -1;
// invisible frames get packed with the next visible frame
if (!cpi->common.show_frame) continue;
aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
cx_data += size;
cx_data_sz -= size;
// insert superframe index if needed
if (ctx->pending_frame_count > 1) {
const size_t index_size = write_superframe_index(ctx);
cx_data += index_size;
cx_data_sz -= index_size;
}
// Add the frame packet to the list of returned packets.
aom_codec_cx_pkt_t pkt;
pkt.kind = AOM_CODEC_CX_FRAME_PKT;
pkt.data.frame.buf = ctx->pending_cx_data;
pkt.data.frame.sz = ctx->pending_cx_data_sz;
pkt.data.frame.partition_id = -1;
pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
pkt.data.frame.duration = (uint32_t)ticks_to_timebase_units(
timebase, dst_end_time_stamp - dst_time_stamp);
aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
ctx->pending_cx_data = NULL;
ctx->pending_cx_data_sz = 0;
ctx->pending_frame_count = 0;
}
}
@ -1419,6 +1450,23 @@ static aom_codec_err_t ctrl_set_color_space(aom_codec_alg_priv_t *ctx,
return update_extra_cfg(ctx, &extra_cfg);
}
#if CONFIG_COLORSPACE_HEADERS
static aom_codec_err_t ctrl_set_transfer_function(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.transfer_function = CAST(AV1E_SET_TRANSFER_FUNCTION, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static aom_codec_err_t ctrl_set_chroma_sample_position(
aom_codec_alg_priv_t *ctx, va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.chroma_sample_position =
CAST(AV1E_SET_CHROMA_SAMPLE_POSITION, args);
return update_extra_cfg(ctx, &extra_cfg);
}
#endif
static aom_codec_err_t ctrl_set_color_range(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
@ -1489,10 +1537,8 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AV1E_SET_QM_MIN, ctrl_set_qm_min },
{ AV1E_SET_QM_MAX, ctrl_set_qm_max },
#endif
#if CONFIG_TILE_GROUPS
{ AV1E_SET_NUM_TG, ctrl_set_num_tg },
{ AV1E_SET_MTU, ctrl_set_mtu },
#endif
#if CONFIG_TEMPMV_SIGNALING
{ AV1E_SET_DISABLE_TEMPMV, ctrl_set_disable_tempmv },
#endif
@ -1504,6 +1550,10 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
{ AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
{ AV1E_SET_COLOR_SPACE, ctrl_set_color_space },
#if CONFIG_COLORSPACE_HEADERS
{ AV1E_SET_TRANSFER_FUNCTION, ctrl_set_transfer_function },
{ AV1E_SET_CHROMA_SAMPLE_POSITION, ctrl_set_chroma_sample_position },
#endif
{ AV1E_SET_COLOR_RANGE, ctrl_set_color_range },
{ AV1E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity },
{ AV1E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval },
@ -1514,7 +1564,7 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AV1E_SET_ANS_WINDOW_SIZE_LOG2, ctrl_set_ans_window_size_log2 },
#endif
#if CONFIG_EXT_TILE
{ AV1E_SET_TILE_ENCODING_MODE, ctrl_set_tile_encoding_mode },
{ AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding },
#endif // CONFIG_EXT_TILE
{ AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
@ -1549,12 +1599,14 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
25, // g_lag_in_frames
0, // rc_dropframe_thresh
0, // rc_resize_allowed
0, // rc_scaled_width
0, // rc_scaled_height
60, // rc_resize_down_thresold
30, // rc_resize_up_thresold
0, // rc_dropframe_thresh
RESIZE_NONE, // rc_resize_mode
SCALE_DENOMINATOR, // rc_resize_numerator
SCALE_DENOMINATOR, // rc_resize_kf_numerator
0, // rc_superres_mode
SCALE_DENOMINATOR, // rc_superres_numerator
SCALE_DENOMINATOR, // rc_superres_kf_numerator
AOM_VBR, // rc_end_usage
{ NULL, 0 }, // rc_twopass_stats_in
@ -1577,6 +1629,7 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
AOM_KF_AUTO, // g_kfmode
0, // kf_min_dist
9999, // kf_max_dist
0, // large_scale_tile
} },
};

View file

@ -106,6 +106,8 @@ static aom_codec_err_t decoder_init(aom_codec_ctx_t *ctx,
(ctx->init_flags & AOM_CODEC_USE_FRAME_THREADING))
? 1
: 0;
// TODO(tdaede): this should not be exposed to the API
priv->cfg.allow_lowbitdepth = CONFIG_LOWBITDEPTH;
if (ctx->config.dec) {
priv->cfg = *ctx->config.dec;
ctx->config.dec = &priv->cfg;
@ -154,14 +156,40 @@ static aom_codec_err_t decoder_destroy(aom_codec_alg_priv_t *ctx) {
static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile,
struct aom_read_bit_buffer *rb) {
aom_color_space_t color_space;
#if CONFIG_COLORSPACE_HEADERS
int subsampling_x = 0;
int subsampling_y = 0;
#endif
if (profile >= PROFILE_2) rb->bit_offset += 1; // Bit-depth 10 or 12.
#if CONFIG_COLORSPACE_HEADERS
color_space = (aom_color_space_t)aom_rb_read_literal(rb, 5);
rb->bit_offset += 5; // Transfer function
#else
color_space = (aom_color_space_t)aom_rb_read_literal(rb, 3);
#endif
if (color_space != AOM_CS_SRGB) {
rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range.
if (profile == PROFILE_1 || profile == PROFILE_3) {
#if CONFIG_COLORSPACE_HEADERS
subsampling_x = aom_rb_read_bit(rb);
subsampling_y = aom_rb_read_bit(rb);
#else
rb->bit_offset += 2; // subsampling x/y.
#endif
rb->bit_offset += 1; // unused.
#if CONFIG_COLORSPACE_HEADERS
} else {
subsampling_x = 1;
subsampling_y = 1;
}
if (subsampling_x == 1 && subsampling_y == 1) {
rb->bit_offset += 2;
}
#else
}
#endif
} else {
if (profile == PROFILE_1 || profile == PROFILE_3) {
rb->bit_offset += 1; // unused
@ -196,6 +224,9 @@ static aom_codec_err_t decoder_peek_si_internal(
struct aom_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
const int frame_marker = aom_rb_read_literal(&rb, 2);
const BITSTREAM_PROFILE profile = av1_read_profile(&rb);
#if CONFIG_EXT_TILE
unsigned int large_scale_tile;
#endif // CONFIG_EXT_TILE
if (frame_marker != AOM_FRAME_MARKER) return AOM_CODEC_UNSUP_BITSTREAM;
@ -204,6 +235,10 @@ static aom_codec_err_t decoder_peek_si_internal(
if ((profile >= 2 && data_sz <= 1) || data_sz < 1)
return AOM_CODEC_UNSUP_BITSTREAM;
#if CONFIG_EXT_TILE
large_scale_tile = aom_rb_read_literal(&rb, 1);
#endif // CONFIG_EXT_TILE
if (aom_rb_read_bit(&rb)) { // show an existing frame
aom_rb_read_literal(&rb, 3); // Frame buffer to show.
return AOM_CODEC_OK;
@ -220,6 +255,9 @@ static aom_codec_err_t decoder_peek_si_internal(
int frame_id_len;
SequenceHeader seq_params;
read_sequence_header(&seq_params);
#if CONFIG_EXT_TILE
if (large_scale_tile) seq_params.frame_id_numbers_present_flag = 0;
#endif // CONFIG_EXT_TILE
if (seq_params.frame_id_numbers_present_flag) {
frame_id_len = seq_params.frame_id_length_minus7 + 7;
aom_rb_read_literal(&rb, frame_id_len);
@ -417,6 +455,8 @@ static aom_codec_err_t init_decoder(aom_codec_alg_priv_t *ctx) {
return AOM_CODEC_MEM_ERROR;
}
#endif
frame_worker_data->pbi->allow_lowbitdepth = ctx->cfg.allow_lowbitdepth;
// If decoding in serial mode, FrameWorker thread could create tile worker
// thread or loopfilter thread.
frame_worker_data->pbi->max_threads =
@ -597,10 +637,14 @@ static aom_codec_err_t decoder_decode(aom_codec_alg_priv_t *ctx,
if (res != AOM_CODEC_OK) return res;
}
int index_size = 0;
res = av1_parse_superframe_index(data, data_sz, frame_sizes, &frame_count,
ctx->decrypt_cb, ctx->decrypt_state);
&index_size, ctx->decrypt_cb,
ctx->decrypt_state);
if (res != AOM_CODEC_OK) return res;
data_start += index_size;
if (ctx->frame_parallel_decode) {
// Decode in frame parallel mode. When decoding in this mode, the frame
// passed to the decoder must be either a normal frame or a superframe with
@ -752,7 +796,7 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx,
yuvconfig2image(&ctx->img, &sd, frame_worker_data->user_priv);
#if CONFIG_EXT_TILE
if (cm->tile_encoding_mode &&
if (cm->single_tile_decoding &&
frame_worker_data->pbi->dec_tile_row >= 0) {
const int tile_row =
AOMMIN(frame_worker_data->pbi->dec_tile_row, cm->tile_rows - 1);
@ -768,7 +812,7 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx,
AOMMIN(cm->tile_height, cm->mi_rows - mi_row) * MI_SIZE;
}
if (cm->tile_encoding_mode &&
if (cm->single_tile_decoding &&
frame_worker_data->pbi->dec_tile_col >= 0) {
const int tile_col =
AOMMIN(frame_worker_data->pbi->dec_tile_col, cm->tile_cols - 1);

View file

@ -38,6 +38,10 @@ static void yuvconfig2image(aom_image_t *img, const YV12_BUFFER_CONFIG *yv12,
}
}
img->cs = yv12->color_space;
#if CONFIG_COLORSPACE_HEADERS
img->tf = yv12->transfer_function;
img->csp = yv12->chroma_sample_position;
#endif
img->range = yv12->color_range;
img->bit_depth = 8;
img->w = yv12->y_stride;
@ -102,6 +106,10 @@ static aom_codec_err_t image2yuvconfig(const aom_image_t *img,
yv12->y_stride = img->stride[AOM_PLANE_Y];
yv12->uv_stride = img->stride[AOM_PLANE_U];
yv12->color_space = img->cs;
#if CONFIG_COLORSPACE_HEADERS
yv12->transfer_function = img->tf;
yv12->chroma_sample_position = img->csp;
#endif
yv12->color_range = img->range;
#if CONFIG_HIGHBITDEPTH

View file

@ -93,11 +93,18 @@ void av1_free_ref_frame_buffers(BufferPool *pool) {
// Assumes cm->rst_info[p].restoration_tilesize is already initialized
void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
int p;
av1_alloc_restoration_struct(cm, &cm->rst_info[0], cm->width, cm->height);
#if CONFIG_FRAME_SUPERRES
int width = cm->superres_upscaled_width;
int height = cm->superres_upscaled_height;
#else
int width = cm->width;
int height = cm->height;
#endif // CONFIG_FRAME_SUPERRES
av1_alloc_restoration_struct(cm, &cm->rst_info[0], width, height);
for (p = 1; p < MAX_MB_PLANE; ++p)
av1_alloc_restoration_struct(
cm, &cm->rst_info[p], ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x),
ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y));
av1_alloc_restoration_struct(cm, &cm->rst_info[p],
ROUND_POWER_OF_TWO(width, cm->subsampling_x),
ROUND_POWER_OF_TWO(height, cm->subsampling_y));
aom_free(cm->rst_internal.tmpbuf);
CHECK_MEM_ERROR(cm, cm->rst_internal.tmpbuf,
(int32_t *)aom_memalign(16, RESTORATION_TMPBUF_SIZE));

View file

@ -134,7 +134,7 @@ static INLINE void IADST4x4_1D(int16x4_t *d3s16, int16x4_t *d4s16,
}
void av1_iht4x4_16_add_neon(const tran_low_t *input, uint8_t *dest,
int dest_stride, int tx_type) {
int dest_stride, const TxfmParam *txfm_param) {
uint8x8_t d26u8, d27u8;
int16x4_t d0s16, d1s16, d2s16, d3s16, d4s16, d5s16;
uint32x2_t d26u32, d27u32;
@ -148,9 +148,10 @@ void av1_iht4x4_16_add_neon(const tran_low_t *input, uint8_t *dest,
TRANSPOSE4X4(&q8s16, &q9s16);
int tx_type = txfm_param->tx_type;
switch (tx_type) {
case 0: // idct_idct is not supported. Fall back to C
av1_iht4x4_16_add_c(input, dest, dest_stride, tx_type);
av1_iht4x4_16_add_c(input, dest, dest_stride, txfm_param);
return;
break;
case 1: // iadst_idct

View file

@ -458,7 +458,7 @@ static INLINE void IADST8X8_1D(int16x8_t *q8s16, int16x8_t *q9s16,
}
void av1_iht8x8_64_add_neon(const tran_low_t *input, uint8_t *dest,
int dest_stride, int tx_type) {
int dest_stride, const TxfmParam *txfm_param) {
int i;
uint8_t *d1, *d2;
uint8x8_t d0u8, d1u8, d2u8, d3u8;
@ -478,9 +478,10 @@ void av1_iht8x8_64_add_neon(const tran_low_t *input, uint8_t *dest,
TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
&q15s16);
int tx_type = txfm_param->tx_type;
switch (tx_type) {
case 0: // idct_idct is not supported. Fall back to C
av1_iht8x8_64_add_c(input, dest, dest_stride, tx_type);
av1_iht8x8_64_add_c(input, dest, dest_stride, txfm_param);
return;
break;
case 1: // iadst_idct

View file

@ -13,8 +13,6 @@
#define AV1_FWD_TXFM2D_CFG_H_
#include "av1/common/enums.h"
#include "av1/common/av1_fwd_txfm1d.h"
// Identity will always use max bitdepth regardless of size
static const int8_t fwd_stage_range_identity[1] = { 12 };
// ---------------- 4x4 1D constants -----------------------
// shift
@ -25,6 +23,8 @@ static const int8_t fwd_stage_range_col_dct_4[4] = { 15, 16, 17, 17 };
static const int8_t fwd_stage_range_row_dct_4[4] = { 17, 18, 18, 18 };
static const int8_t fwd_stage_range_col_adst_4[6] = { 15, 15, 16, 17, 17, 17 };
static const int8_t fwd_stage_range_row_adst_4[6] = { 17, 17, 17, 18, 18, 18 };
static const int8_t fwd_stage_range_idx_4[1] = { 18 };
// cos bit
static const int8_t fwd_cos_bit_col_dct_4[4] = { 13, 13, 13, 13 };
static const int8_t fwd_cos_bit_row_dct_4[4] = { 13, 13, 13, 13 };
@ -42,6 +42,7 @@ static const int8_t fwd_stage_range_col_adst_8[8] = { 15, 15, 16, 17,
17, 18, 18, 18 };
static const int8_t fwd_stage_range_row_adst_8[8] = { 17, 17, 17, 18,
18, 19, 19, 19 };
static const int8_t fwd_stage_range_idx_8[1] = { 19 };
// cos bit
static const int8_t fwd_cos_bit_col_dct_8[6] = { 13, 13, 13, 13, 13, 13 };
@ -66,6 +67,7 @@ static const int8_t fwd_stage_range_col_adst_16[10] = { 15, 15, 16, 17, 17,
18, 18, 19, 19, 19 };
static const int8_t fwd_stage_range_row_adst_16[10] = { 17, 17, 17, 18, 18,
19, 19, 20, 20, 20 };
static const int8_t fwd_stage_range_idx_16[1] = { 20 };
// cos bit
static const int8_t fwd_cos_bit_col_dct_16[8] = {
@ -94,6 +96,7 @@ static const int8_t fwd_stage_range_col_adst_32[12] = {
static const int8_t fwd_stage_range_row_adst_32[12] = {
16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 20
};
static const int8_t fwd_stage_range_idx_32[1] = { 20 };
// cos bit
static const int8_t fwd_cos_bit_col_dct_32[10] = { 12, 12, 12, 12, 12,
@ -114,6 +117,7 @@ static const int8_t fwd_stage_range_col_dct_64[12] = { 13, 14, 15, 16, 17, 18,
19, 19, 19, 19, 19, 19 };
static const int8_t fwd_stage_range_row_dct_64[12] = { 17, 18, 19, 20, 21, 22,
22, 22, 22, 22, 22, 22 };
static const int8_t fwd_stage_range_idx_64[1] = { 22 };
// cos bit
static const int8_t fwd_cos_bit_col_dct_64[12] = { 15, 15, 15, 15, 15, 14,
@ -322,10 +326,10 @@ static const TXFM_1D_CFG fwd_txfm_1d_cfg_identity_4 = {
4, // .txfm_size
1, // .stage_num
// 0, // .log_scale
fwd_shift_4, // .shift
fwd_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY4, // .txfm_type
fwd_shift_4, // .shift
fwd_stage_range_idx_4, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY4, // .txfm_type
};
// ---------------- row/col config fwd_identity_8 ----------------
@ -333,10 +337,10 @@ static const TXFM_1D_CFG fwd_txfm_1d_cfg_identity_8 = {
8, // .txfm_size
1, // .stage_num
// 0, // .log_scale
fwd_shift_8, // .shift
fwd_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY8, // .txfm_type
fwd_shift_8, // .shift
fwd_stage_range_idx_8, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY8, // .txfm_type
};
// ---------------- row/col config fwd_identity_16 ----------------
@ -344,10 +348,10 @@ static const TXFM_1D_CFG fwd_txfm_1d_cfg_identity_16 = {
16, // .txfm_size
1, // .stage_num
// 0, // .log_scale
fwd_shift_16, // .shift
fwd_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY16, // .txfm_type
fwd_shift_16, // .shift
fwd_stage_range_idx_16, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY16, // .txfm_type
};
// ---------------- row/col config fwd_identity_32 ----------------
@ -355,10 +359,10 @@ static const TXFM_1D_CFG fwd_txfm_1d_cfg_identity_32 = {
32, // .txfm_size
1, // .stage_num
// 1, // .log_scale
fwd_shift_32, // .shift
fwd_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY32, // .txfm_type
fwd_shift_32, // .shift
fwd_stage_range_idx_32, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY32, // .txfm_type
};
#endif // CONFIG_EXT_TX
#endif // AV1_FWD_TXFM2D_CFG_H_

View file

@ -12,6 +12,7 @@
#include <assert.h>
#include "./av1_rtcd.h"
#include "aom_dsp/txfm_common.h"
#include "av1/common/enums.h"
#include "av1/common/av1_fwd_txfm1d.h"
#include "av1/common/av1_fwd_txfm1d_cfg.h"
@ -41,9 +42,17 @@ 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 c, r;
// TODO(sarahparker) must correct for rectangular transforms in follow up
const int txfm_size = cfg->row_cfg->txfm_size;
const int8_t *shift = cfg->row_cfg->shift;
// 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 = cfg->row_cfg->txfm_size;
const int txfm_size_row = cfg->col_cfg->txfm_size;
// Take the shift from the larger dimension in the rectangular case.
const int8_t *shift = (txfm_size_col > txfm_size_row) ? cfg->row_cfg->shift
: cfg->col_cfg->shift;
const int8_t *stage_range_col = cfg->col_cfg->stage_range;
const int8_t *stage_range_row = cfg->row_cfg->stage_range;
const int8_t *cos_bit_col = cfg->col_cfg->cos_bit;
@ -53,37 +62,99 @@ static INLINE void fwd_txfm2d_c(const int16_t *input, int32_t *output,
// use output buffer as temp buffer
int32_t *temp_in = output;
int32_t *temp_out = output + txfm_size;
int32_t *temp_out = output + txfm_size_row;
// Columns
for (c = 0; c < txfm_size; ++c) {
for (c = 0; c < txfm_size_col; ++c) {
if (cfg->ud_flip == 0) {
for (r = 0; r < txfm_size; ++r) temp_in[r] = input[r * stride + c];
for (r = 0; r < txfm_size_row; ++r) temp_in[r] = input[r * stride + c];
} else {
for (r = 0; r < txfm_size; ++r)
for (r = 0; r < txfm_size_row; ++r)
// flip upside down
temp_in[r] = input[(txfm_size - r - 1) * stride + c];
temp_in[r] = input[(txfm_size_row - r - 1) * stride + c];
}
round_shift_array(temp_in, txfm_size_row, -shift[0]);
// Multiply everything by Sqrt2 on the larger dimension if the
// transform is rectangular
if (txfm_size_col > txfm_size_row) {
for (r = 0; r < txfm_size_row; ++r)
temp_in[r] = (int32_t)fdct_round_shift(temp_in[r] * Sqrt2);
}
round_shift_array(temp_in, txfm_size, -shift[0]);
txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
round_shift_array(temp_out, txfm_size, -shift[1]);
round_shift_array(temp_out, txfm_size_row, -shift[1]);
if (cfg->lr_flip == 0) {
for (r = 0; r < txfm_size; ++r) buf[r * txfm_size + c] = temp_out[r];
for (r = 0; r < txfm_size_row; ++r)
buf[r * txfm_size_col + c] = temp_out[r];
} else {
for (r = 0; r < txfm_size; ++r)
for (r = 0; r < txfm_size_row; ++r)
// flip from left to right
buf[r * txfm_size + (txfm_size - c - 1)] = temp_out[r];
buf[r * txfm_size_col + (txfm_size_col - c - 1)] = temp_out[r];
}
}
// Rows
for (r = 0; r < txfm_size; ++r) {
txfm_func_row(buf + r * txfm_size, output + r * txfm_size, cos_bit_row,
stage_range_row);
round_shift_array(output + r * txfm_size, txfm_size, -shift[2]);
for (r = 0; r < txfm_size_row; ++r) {
// Multiply everything by Sqrt2 on the larger dimension if the
// transform is rectangular
if (txfm_size_row > txfm_size_col) {
for (c = 0; c < txfm_size_col; ++c)
buf[r * txfm_size_col + c] =
(int32_t)fdct_round_shift(buf[r * txfm_size_col + c] * Sqrt2);
}
txfm_func_row(buf + r * txfm_size_col, output + r * txfm_size_col,
cos_bit_row, stage_range_row);
round_shift_array(output + r * txfm_size_col, txfm_size_col, -shift[2]);
}
}
void av1_fwd_txfm2d_4x8_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[4 * 8];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_4X8);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_8x4_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[8 * 4];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_8X4);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_8x16_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[8 * 16];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_8X16);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_16x8_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[16 * 8];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_16X8);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_16x32_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[16 * 32];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_16X32);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_32x16_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[32 * 16];
TXFM_2D_FLIP_CFG cfg = av1_get_fwd_txfm_cfg(tx_type, TX_32X16);
(void)bd;
fwd_txfm2d_c(input, output, stride, &cfg, txfm_buf);
}
void av1_fwd_txfm2d_4x4_c(const int16_t *input, int32_t *output, int stride,
int tx_type, int bd) {
int32_t txfm_buf[4 * 4];
@ -193,10 +264,12 @@ static const TXFM_1D_CFG *fwd_txfm_row_cfg_ls[TX_TYPES_1D][TX_SIZES] = {
TXFM_2D_FLIP_CFG av1_get_fwd_txfm_cfg(int tx_type, int tx_size) {
TXFM_2D_FLIP_CFG cfg;
set_flip_cfg(tx_type, &cfg);
int tx_type_col = vtx_tab[tx_type];
int tx_type_row = htx_tab[tx_type];
cfg.col_cfg = fwd_txfm_col_cfg_ls[tx_type_col][tx_size];
cfg.row_cfg = fwd_txfm_row_cfg_ls[tx_type_row][tx_size];
const int tx_type_col = vtx_tab[tx_type];
const int tx_type_row = htx_tab[tx_type];
const int tx_size_col = txsize_vert_map[tx_size];
const int tx_size_row = txsize_horz_map[tx_size];
cfg.col_cfg = fwd_txfm_col_cfg_ls[tx_type_col][tx_size_col];
cfg.row_cfg = fwd_txfm_row_cfg_ls[tx_type_row][tx_size_row];
return cfg;
}

View file

@ -12,8 +12,6 @@
#ifndef AV1_INV_TXFM2D_CFG_H_
#define AV1_INV_TXFM2D_CFG_H_
#include "av1/common/av1_inv_txfm1d.h"
// Identity will always use max bitdepth regardless of size
static const int8_t inv_stage_range_identity[1] = { 12 };
// ---------------- 4x4 1D config -----------------------
// shift
@ -24,6 +22,8 @@ static const int8_t inv_stage_range_col_dct_4[4] = { 18, 18, 17, 17 };
static const int8_t inv_stage_range_row_dct_4[4] = { 18, 18, 18, 18 };
static const int8_t inv_stage_range_col_adst_4[6] = { 18, 18, 18, 18, 17, 17 };
static const int8_t inv_stage_range_row_adst_4[6] = { 18, 18, 18, 18, 18, 18 };
static const int8_t inv_stage_range_idx_4[1] = { 18 };
// cos bit
static const int8_t inv_cos_bit_col_dct_4[4] = { 13, 13, 13, 13 };
static const int8_t inv_cos_bit_row_dct_4[4] = { 13, 13, 13, 13 };
@ -41,6 +41,8 @@ static const int8_t inv_stage_range_col_adst_8[8] = { 19, 19, 19, 19,
19, 19, 18, 18 };
static const int8_t inv_stage_range_row_adst_8[8] = { 19, 19, 19, 19,
19, 19, 19, 19 };
static const int8_t inv_stage_range_idx_8[1] = { 19 };
// cos bit
static const int8_t inv_cos_bit_col_dct_8[6] = { 13, 13, 13, 13, 13, 13 };
static const int8_t inv_cos_bit_row_dct_8[6] = { 13, 13, 13, 13, 13, 13 };
@ -64,6 +66,7 @@ static const int8_t inv_stage_range_col_adst_16[10] = { 19, 19, 19, 19, 19,
19, 19, 19, 18, 18 };
static const int8_t inv_stage_range_row_adst_16[10] = { 20, 20, 20, 20, 20,
20, 20, 20, 20, 20 };
static const int8_t inv_stage_range_idx_16[1] = { 20 };
// cos bit
static const int8_t inv_cos_bit_col_dct_16[8] = {
@ -92,6 +95,7 @@ static const int8_t inv_stage_range_col_adst_32[12] = {
static const int8_t inv_stage_range_row_adst_32[12] = {
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
};
static const int8_t inv_stage_range_idx_32[1] = { 20 };
// cos bit
static const int8_t inv_cos_bit_col_dct_32[10] = { 13, 13, 13, 13, 13,
@ -112,6 +116,7 @@ static const int8_t inv_stage_range_col_dct_64[12] = { 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 18, 18 };
static const int8_t inv_stage_range_row_dct_64[12] = { 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20 };
static const int8_t inv_stage_range_idx_64[1] = { 20 };
// cos bit
static const int8_t inv_cos_bit_col_dct_64[12] = { 13, 13, 13, 13, 13, 13,
@ -320,10 +325,10 @@ static const TXFM_1D_CFG inv_txfm_1d_cfg_identity_4 = {
4, // .txfm_size
1, // .stage_num
// 0, // .log_scale
inv_shift_4, // .shift
inv_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY4, // .txfm_type
inv_shift_4, // .shift
inv_stage_range_idx_4, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY4, // .txfm_type
};
// ---------------- row/col config inv_identity_8 ----------------
@ -331,10 +336,10 @@ static const TXFM_1D_CFG inv_txfm_1d_cfg_identity_8 = {
8, // .txfm_size
1, // .stage_num
// 0, // .log_scale
inv_shift_8, // .shift
inv_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY8, // .txfm_type
inv_shift_8, // .shift
inv_stage_range_idx_8, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY8, // .txfm_type
};
// ---------------- row/col config inv_identity_16 ----------------
@ -342,10 +347,10 @@ static const TXFM_1D_CFG inv_txfm_1d_cfg_identity_16 = {
16, // .txfm_size
1, // .stage_num
// 0, // .log_scale
inv_shift_16, // .shift
inv_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY16, // .txfm_type
inv_shift_16, // .shift
inv_stage_range_idx_16, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY16, // .txfm_type
};
// ---------------- row/col config inv_identity_32 ----------------
@ -353,10 +358,10 @@ static const TXFM_1D_CFG inv_txfm_1d_cfg_identity_32 = {
32, // .txfm_size
1, // .stage_num
// 1, // .log_scale
inv_shift_32, // .shift
inv_stage_range_identity, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY32, // .txfm_type
inv_shift_32, // .shift
inv_stage_range_idx_32, // .stage_range
NULL, // .cos_bit
TXFM_TYPE_IDENTITY32, // .txfm_type
};
#endif // CONFIG_EXT_TX
#endif // AV1_INV_TXFM2D_CFG_H_

View file

@ -10,6 +10,7 @@
*/
#include "./av1_rtcd.h"
#include "aom_dsp/inv_txfm.h"
#include "av1/common/enums.h"
#include "av1/common/av1_txfm.h"
#include "av1/common/av1_inv_txfm1d.h"
@ -104,12 +105,12 @@ static const TXFM_1D_CFG *inv_txfm_row_cfg_ls[TX_TYPES_1D][TX_SIZES] = {
TXFM_2D_FLIP_CFG av1_get_inv_txfm_cfg(int tx_type, int tx_size) {
TXFM_2D_FLIP_CFG cfg;
set_flip_cfg(tx_type, &cfg);
int tx_type_col = vtx_tab[tx_type];
int tx_type_row = htx_tab[tx_type];
// TODO(sarahparker) this is currently only implemented for
// square transforms
cfg.col_cfg = inv_txfm_col_cfg_ls[tx_type_col][tx_size];
cfg.row_cfg = inv_txfm_row_cfg_ls[tx_type_row][tx_size];
const int tx_type_col = vtx_tab[tx_type];
const int tx_type_row = htx_tab[tx_type];
const int tx_size_col = txsize_vert_map[tx_size];
const int tx_size_row = txsize_horz_map[tx_size];
cfg.col_cfg = inv_txfm_col_cfg_ls[tx_type_col][tx_size_col];
cfg.row_cfg = inv_txfm_row_cfg_ls[tx_type_row][tx_size_row];
return cfg;
}
@ -126,12 +127,20 @@ TXFM_2D_FLIP_CFG av1_get_inv_txfm_64x64_cfg(int tx_type) {
return cfg;
}
static INLINE void inv_txfm2d_add_c(const int32_t *input, int16_t *output,
static INLINE void inv_txfm2d_add_c(const int32_t *input, uint16_t *output,
int stride, TXFM_2D_FLIP_CFG *cfg,
int32_t *txfm_buf) {
// TODO(sarahparker) must correct for rectangular transforms in follow up
const int txfm_size = cfg->row_cfg->txfm_size;
const int8_t *shift = cfg->row_cfg->shift;
int32_t *txfm_buf, int bd) {
// 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 = cfg->row_cfg->txfm_size;
const int txfm_size_row = cfg->col_cfg->txfm_size;
// Take the shift from the larger dimension in the rectangular case.
const int8_t *shift = (txfm_size_col > txfm_size_row) ? cfg->row_cfg->shift
: cfg->col_cfg->shift;
const int8_t *stage_range_col = cfg->col_cfg->stage_range;
const int8_t *stage_range_row = cfg->row_cfg->stage_range;
const int8_t *cos_bit_col = cfg->col_cfg->cos_bit;
@ -139,39 +148,50 @@ static INLINE void inv_txfm2d_add_c(const int32_t *input, int16_t *output,
const TxfmFunc txfm_func_col = inv_txfm_type_to_func(cfg->col_cfg->txfm_type);
const TxfmFunc txfm_func_row = inv_txfm_type_to_func(cfg->row_cfg->txfm_type);
// txfm_buf's length is txfm_size * txfm_size + 2 * txfm_size
// txfm_buf's length is txfm_size_row * txfm_size_col + 2 * txfm_size_row
// it is used for intermediate data buffering
int32_t *temp_in = txfm_buf;
int32_t *temp_out = temp_in + txfm_size;
int32_t *buf = temp_out + txfm_size;
int32_t *temp_out = temp_in + txfm_size_row;
int32_t *buf = temp_out + txfm_size_row;
int32_t *buf_ptr = buf;
int c, r;
// Rows
for (r = 0; r < txfm_size; ++r) {
for (r = 0; r < txfm_size_row; ++r) {
txfm_func_row(input, buf_ptr, cos_bit_row, stage_range_row);
round_shift_array(buf_ptr, txfm_size, -shift[0]);
input += txfm_size;
buf_ptr += txfm_size;
round_shift_array(buf_ptr, txfm_size_col, -shift[0]);
// Multiply everything by Sqrt2 if the transform is rectangular
if (txfm_size_row != txfm_size_col) {
for (c = 0; c < txfm_size_col; ++c)
buf_ptr[c] = (int32_t)dct_const_round_shift(buf_ptr[c] * Sqrt2);
}
input += txfm_size_col;
buf_ptr += txfm_size_col;
}
// Columns
for (c = 0; c < txfm_size; ++c) {
for (c = 0; c < txfm_size_col; ++c) {
if (cfg->lr_flip == 0) {
for (r = 0; r < txfm_size; ++r) temp_in[r] = buf[r * txfm_size + c];
for (r = 0; r < txfm_size_row; ++r)
temp_in[r] = buf[r * txfm_size_col + c];
} else {
// flip left right
for (r = 0; r < txfm_size; ++r)
temp_in[r] = buf[r * txfm_size + (txfm_size - c - 1)];
for (r = 0; r < txfm_size_row; ++r)
temp_in[r] = buf[r * txfm_size_col + (txfm_size_col - c - 1)];
}
txfm_func_col(temp_in, temp_out, cos_bit_col, stage_range_col);
round_shift_array(temp_out, txfm_size, -shift[1]);
round_shift_array(temp_out, txfm_size_row, -shift[1]);
if (cfg->ud_flip == 0) {
for (r = 0; r < txfm_size; ++r) output[r * stride + c] += temp_out[r];
for (r = 0; r < txfm_size_row; ++r) {
output[r * stride + c] =
highbd_clip_pixel_add(output[r * stride + c], temp_out[r], bd);
}
} else {
// flip upside down
for (r = 0; r < txfm_size; ++r)
output[r * stride + c] += temp_out[txfm_size - r - 1];
for (r = 0; r < txfm_size_row; ++r) {
output[r * stride + c] = highbd_clip_pixel_add(
output[r * stride + c], temp_out[txfm_size_row - r - 1], bd);
}
}
}
}
@ -179,17 +199,44 @@ static INLINE void inv_txfm2d_add_c(const int32_t *input, int16_t *output,
static INLINE void inv_txfm2d_add_facade(const int32_t *input, uint16_t *output,
int stride, int32_t *txfm_buf,
int tx_type, int tx_size, int bd) {
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
TXFM_2D_FLIP_CFG cfg = av1_get_inv_txfm_cfg(tx_type, tx_size);
inv_txfm2d_add_c(input, (int16_t *)output, stride, &cfg, txfm_buf);
// TODO(sarahparker) just using the cfg_row->txfm_size for now because
// we are assumint this is only used for square transforms. This will
// be adjusted in a follow up
clamp_block((int16_t *)output, cfg.row_cfg->txfm_size, stride, 0,
(1 << bd) - 1);
inv_txfm2d_add_c(input, output, stride, &cfg, txfm_buf, bd);
}
void av1_inv_txfm2d_add_4x8_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[4 * 8 + 8 + 8];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_4X8, bd);
}
void av1_inv_txfm2d_add_8x4_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[8 * 4 + 4 + 4];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_8X4, bd);
}
void av1_inv_txfm2d_add_8x16_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[8 * 16 + 16 + 16];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_8X16, bd);
}
void av1_inv_txfm2d_add_16x8_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[16 * 8 + 8 + 8];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_16X8, bd);
}
void av1_inv_txfm2d_add_16x32_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[16 * 32 + 32 + 32];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_16X32, bd);
}
void av1_inv_txfm2d_add_32x16_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[32 * 16 + 16 + 16];
inv_txfm2d_add_facade(input, output, stride, txfm_buf, tx_type, TX_32X16, bd);
}
void av1_inv_txfm2d_add_4x4_c(const int32_t *input, uint16_t *output,
@ -219,11 +266,6 @@ void av1_inv_txfm2d_add_32x32_c(const int32_t *input, uint16_t *output,
void av1_inv_txfm2d_add_64x64_c(const int32_t *input, uint16_t *output,
int stride, int tx_type, int bd) {
int txfm_buf[64 * 64 + 64 + 64];
// output contains the prediction signal which is always positive and smaller
// than (1 << bd) - 1
// since bd < 16-1, therefore we can treat the uint16_t* output buffer as an
// int16_t*
TXFM_2D_FLIP_CFG cfg = av1_get_inv_txfm_64x64_cfg(tx_type);
inv_txfm2d_add_c(input, (int16_t *)output, stride, &cfg, txfm_buf);
clamp_block((int16_t *)output, 64, stride, 0, (1 << bd) - 1);
inv_txfm2d_add_c(input, output, stride, &cfg, txfm_buf, bd);
}

File diff suppressed because it is too large Load diff

View file

@ -37,6 +37,10 @@ enum lf_path {
struct loopfilter {
int filter_level;
#if CONFIG_UV_LVL
int filter_level_u;
int filter_level_v;
#endif
int sharpness_level;
int last_sharpness_level;
@ -45,7 +49,8 @@ struct loopfilter {
uint8_t mode_ref_delta_update;
// 0 = Intra, Last, Last2+Last3(CONFIG_EXT_REFS),
// GF, BRF(CONFIG_EXT_REFS), ARF
// GF, BRF(CONFIG_EXT_REFS),
// ARF2(CONFIG_EXT_REFS+CONFIG_ALTREF2), ARF
signed char ref_deltas[TOTAL_REFS_PER_FRAME];
signed char last_ref_deltas[TOTAL_REFS_PER_FRAME];

View file

@ -5,6 +5,7 @@ print <<EOF
*/
#include "aom/aom_integer.h"
#include "aom_dsp/txfm_common.h"
#include "av1/common/common.h"
#include "av1/common/enums.h"
#include "av1/common/quant_common.h"
@ -17,6 +18,7 @@ struct macroblockd;
/* Encoder forward decls */
struct macroblock;
struct txfm_param;
struct aom_variance_vtable;
struct search_site_config;
struct mv;
@ -63,81 +65,81 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
{
add_proto qw/void av1_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht4x4_16_add sse2/;
add_proto qw/void av1_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht4x8_32_add sse2/;
add_proto qw/void av1_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x4_32_add sse2/;
add_proto qw/void av1_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x16_128_add sse2/;
add_proto qw/void av1_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht16x8_128_add sse2/;
add_proto qw/void av1_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht16x32_512_add sse2/;
add_proto qw/void av1_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht32x16_512_add sse2/;
add_proto qw/void av1_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x8_64_add sse2/;
add_proto qw/void av1_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
specialize qw/av1_iht16x16_256_add sse2 avx2/;
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
}
} else {
{
add_proto qw/void av1_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht4x4_16_add sse2 neon dspr2/;
add_proto qw/void av1_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht4x8_32_add sse2/;
add_proto qw/void av1_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x4_32_add sse2/;
add_proto qw/void av1_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x16_128_add sse2/;
add_proto qw/void av1_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht16x8_128_add sse2/;
add_proto qw/void av1_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht16x32_512_add sse2/;
add_proto qw/void av1_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht32x16_512_add sse2/;
add_proto qw/void av1_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type";
add_proto qw/void av1_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
specialize qw/av1_iht8x8_64_add sse2 neon dspr2/;
add_proto qw/void av1_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
specialize qw/av1_iht16x16_256_add sse2 avx2 dspr2/;
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
if (aom_config("CONFIG_EXT_TX") ne "yes") {
specialize qw/av1_iht4x4_16_add msa/;
@ -147,10 +149,10 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
}
}
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht32x32_1024_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_iht64x64_4096_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type";
add_proto qw/void av1_iht64x64_4096_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
}
if (aom_config("CONFIG_NEW_QUANT") eq "yes") {
@ -171,28 +173,28 @@ if (aom_config("CONFIG_NEW_QUANT") eq "yes") {
# FILTER_INTRA predictor functions
if (aom_config("CONFIG_FILTER_INTRA") eq "yes") {
add_proto qw/void av1_dc_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_v_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_h_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d45_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d135_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d117_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d153_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d207_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d63_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_tm_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_dc_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_v_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_h_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d45_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d135_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d117_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d153_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d207_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_d63_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
add_proto qw/void av1_tm_filter_predictor/, "uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint8_t *above, const uint8_t *left";
# High bitdepth functions
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void av1_highbd_dc_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_v_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_h_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d45_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d135_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d117_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d153_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d207_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d63_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_tm_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_dc_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_v_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_h_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d45_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d135_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d117_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d153_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d207_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_d63_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
add_proto qw/void av1_highbd_tm_filter_predictor/, "uint16_t *dst, ptrdiff_t stride, TX_SIZE tx_size, const uint16_t *above, const uint16_t *left, int bd";
}
}
@ -226,45 +228,49 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#
# dct
#
add_proto qw/void av1_highbd_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht4x8_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht8x4_32_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht8x16_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht16x8_128_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht16x32_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht32x16_512_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht4x16_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht16x4_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht8x32_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht32x8_256_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int tx_type, int bd";
add_proto qw/void av1_highbd_iht8x8_64_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, const struct txfm_param *param";
add_proto qw/void av1_highbd_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, int tx_type, int bd";
add_proto qw/void av1_highbd_iht16x16_256_add/, "const tran_low_t *input, uint8_t *output, int pitch, const struct txfm_param *param";
}
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#inv txfm
add_proto qw/void av1_inv_txfm2d_add_4x4/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_4x4 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_8x8/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_8x8 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_16x16/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_16x16 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_32x32/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_32x32 avx2/;
add_proto qw/void av1_inv_txfm2d_add_64x64/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
}
#inv txfm
add_proto qw/void av1_inv_txfm2d_add_4x8/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_8x4/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_8x16/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_16x8/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_16x32/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_32x16/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_inv_txfm2d_add_4x4/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_4x4 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_8x8/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_8x8 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_16x16/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_16x16 sse4_1/;
add_proto qw/void av1_inv_txfm2d_add_32x32/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
specialize qw/av1_inv_txfm2d_add_32x32 avx2/;
add_proto qw/void av1_inv_txfm2d_add_64x64/, "const int32_t *input, uint16_t *output, int stride, int tx_type, int bd";
#
# Encoder functions below this point.
@ -278,6 +284,7 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
# the transform coefficients are held in 32-bit
# values, so the assembler code for av1_block_error can no longer be used.
add_proto qw/int64_t av1_block_error/, "const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz";
specialize qw/av1_block_error avx2/;
add_proto qw/void av1_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t *iqm_ptr";
@ -310,11 +317,13 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
# the transform coefficients are held in 32-bit
# values, so the assembler code for av1_block_error can no longer be used.
add_proto qw/int64_t av1_block_error/, "const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz";
specialize qw/av1_block_error avx2/;
add_proto qw/void av1_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/av1_quantize_fp sse2/;
specialize qw/av1_quantize_fp sse2 avx2/;
add_proto qw/void av1_quantize_fp_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/av1_quantize_fp_32x32 avx2/;
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_quantize_fp_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
@ -329,10 +338,10 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
specialize qw/av1_block_error_fp neon sse2/;
add_proto qw/void av1_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/av1_quantize_fp neon sse2/, "$ssse3_x86_64";
specialize qw/av1_quantize_fp neon sse2 avx2/, "$ssse3_x86_64";
add_proto qw/void av1_quantize_fp_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/av1_quantize_fp_32x32/, "$ssse3_x86_64";
specialize qw/av1_quantize_fp_32x32 avx2/, "$ssse3_x86_64";
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_quantize_fp_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
@ -346,49 +355,49 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
# fdct functions
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht4x4 sse2/;
add_proto qw/void av1_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht8x8 sse2/;
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht16x16 sse2 avx2/;
add_proto qw/void av1_fht32x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht32x32/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht32x32 sse2 avx2/;
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_fht64x64/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht64x64/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
}
add_proto qw/void av1_fht4x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht4x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht4x8 sse2/;
add_proto qw/void av1_fht8x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x4/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht8x4 sse2/;
add_proto qw/void av1_fht8x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht8x16 sse2/;
add_proto qw/void av1_fht16x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht16x8 sse2/;
add_proto qw/void av1_fht16x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x32/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht16x32 sse2/;
add_proto qw/void av1_fht32x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht32x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht32x16 sse2/;
add_proto qw/void av1_fht4x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht4x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
add_proto qw/void av1_fht16x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x4/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
add_proto qw/void av1_fht8x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x32/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
add_proto qw/void av1_fht32x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht32x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
if (aom_config("CONFIG_HIGHBITDEPTH") ne "yes") {
if (aom_config("CONFIG_EXT_TX") ne "yes") {
@ -403,23 +412,30 @@ add_proto qw/void av1_fwd_idtx/, "const int16_t *src_diff, tran_low_t *coeff, in
if (aom_config("CONFIG_DPCM_INTRA") eq "yes") {
@sizes = (4, 8, 16, 32);
foreach $size (@sizes) {
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto "void", "av1_hbd_dpcm_ft$size", "const int16_t *input, int stride, TX_TYPE_1D tx_type, tran_low_t *output, int dir";
}
add_proto "void", "av1_dpcm_ft$size", "const int16_t *input, int stride, TX_TYPE_1D tx_type, tran_low_t *output";
}
}
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#fwd txfm
add_proto qw/void av1_fwd_txfm2d_4x4/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_4x4 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_8x8/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_8x8 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_16x16/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_16x16 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_32x32/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_32x32 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_64x64/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_64x64 sse4_1/;
}
#fwd txfm
add_proto qw/void av1_fwd_txfm2d_4x8/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_8x4/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_8x16/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_16x8/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_16x32/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_32x16/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
add_proto qw/void av1_fwd_txfm2d_4x4/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_4x4 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_8x8/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_8x8 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_16x16/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_16x16 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_32x32/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_32x32 sse4_1/;
add_proto qw/void av1_fwd_txfm2d_64x64/, "const int16_t *input, int32_t *output, int stride, int tx_type, int bd";
specialize qw/av1_fwd_txfm2d_64x64 sse4_1/;
#
# Motion search
@ -464,62 +480,34 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/int64_t av1_highbd_block_error/, "const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz, int bd";
specialize qw/av1_highbd_block_error sse2/;
if (aom_config("CONFIG_AOM_QM") eq "yes") {
add_proto qw/void av1_highbd_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
add_proto qw/void av1_highbd_quantize_fp_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_highbd_quantize_fp_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
}
add_proto qw/void av1_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
} else {
add_proto qw/void av1_highbd_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, int log_scale";
specialize qw/av1_highbd_quantize_fp sse4_1/;
add_proto qw/void av1_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, int log_scale";
}
# fdct functions
add_proto qw/void av1_highbd_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
specialize qw/av1_highbd_fht4x4 sse4_1/;
add_proto qw/void av1_highbd_fht4x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht8x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht8x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht16x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht16x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht32x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht4x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht16x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht8x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht32x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_highbd_fht32x32/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_highbd_fht64x64/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
}
add_proto qw/void av1_highbd_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
add_proto qw/void av1_highbd_temporal_filter_apply/, "uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count";
}
if (aom_config("CONFIG_AOM_QM") eq "yes") {
add_proto qw/void av1_highbd_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
add_proto qw/void av1_highbd_quantize_fp_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
if (aom_config("CONFIG_TX64X64") eq "yes") {
add_proto qw/void av1_highbd_quantize_fp_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
}
add_proto qw/void av1_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr, int log_scale";
} else {
add_proto qw/void av1_highbd_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, int log_scale";
specialize qw/av1_highbd_quantize_fp sse4_1 avx2/;
add_proto qw/void av1_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, int log_scale";
}
add_proto qw/void av1_highbd_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
# End av1_high encoder functions
if (aom_config("CONFIG_EXT_INTER") eq "yes") {
@ -539,25 +527,25 @@ if (aom_config("CONFIG_PVQ") eq "yes") {
# fdct functions
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht4x4 sse2/;
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht8x8 sse2/;
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht16x16 sse2/;
add_proto qw/void av1_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/av1_fwht4x4 sse2/;
} else {
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht4x4/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht4x4 sse2 msa/;
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht8x8/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht8x8 sse2 msa/;
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, int tx_type";
add_proto qw/void av1_fht16x16/, "const int16_t *input, tran_low_t *output, int stride, struct txfm_param *param";
specialize qw/av1_fht16x16 sse2 msa/;
add_proto qw/void av1_fwht4x4/, "const int16_t *input, tran_low_t *output, int stride";
@ -616,12 +604,19 @@ if (aom_config("CONFIG_PVQ") eq "yes") {
if ((aom_config("CONFIG_WARPED_MOTION") eq "yes") ||
(aom_config("CONFIG_GLOBAL_MOTION") eq "yes")) {
add_proto qw/void av1_warp_affine/, "const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, int comp_avg, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
add_proto qw/void av1_warp_affine/, "const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
specialize qw/av1_warp_affine sse2 ssse3/;
if (aom_config("CONFIG_CONVOLVE_ROUND") eq "yes") {
add_proto qw/void av1_warp_affine_post_round/, "const int32_t *mat, const uint8_t *ref, int width, int height, int stride, uint8_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
}
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void av1_highbd_warp_affine/, "const int32_t *mat, const uint16_t *ref, int width, int height, int stride, uint16_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, int bd, int comp_avg, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
add_proto qw/void av1_highbd_warp_affine/, "const int32_t *mat, const uint16_t *ref, int width, int height, int stride, uint16_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, int bd, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
specialize qw/av1_highbd_warp_affine ssse3/;
if (aom_config("CONFIG_CONVOLVE_ROUND") eq "yes") {
add_proto qw/void av1_highbd_warp_affine_post_round/, "const int32_t *mat, const uint16_t *ref, int width, int height, int stride, uint16_t *pred, int p_col, int p_row, int p_width, int p_height, int p_stride, int subsampling_x, int subsampling_y, int bd, ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma, int16_t delta";
}
}
}
@ -655,4 +650,20 @@ if (aom_config("CONFIG_LOOP_RESTORATION") eq "yes") {
}
}
# CONVOLVE_ROUND/COMPOUND_ROUND functions
if (aom_config("CONFIG_CONVOLVE_ROUND") eq "yes") {
add_proto qw/void av1_convolve_2d/, "const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst, int dst_stride, int w, int h, InterpFilterParams *filter_params_x, InterpFilterParams *filter_params_y, const int subpel_x_q4, const int subpel_y_q4, ConvolveParams *conv_params";
specialize qw/av1_convolve_2d sse2/;
add_proto qw/void av1_convolve_rounding/, "const int32_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, int bits";
specialize qw/av1_convolve_rounding avx2/;
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void av1_highbd_convolve_2d/, "const uint16_t *src, int src_stride, CONV_BUF_TYPE *dst, int dst_stride, int w, int h, InterpFilterParams *filter_params_x, InterpFilterParams *filter_params_y, const int subpel_x_q4, const int subpel_y_q4, ConvolveParams *conv_params, int bd";
specialize qw/av1_highbd_convolve_2d ssse3/;
add_proto qw/void av1_highbd_convolve_rounding/, "const int32_t *src, int src_stride, uint8_t *dst, int dst_stride, int w, int h, int bits, int bd";
specialize qw/av1_highbd_convolve_rounding avx2/;
}
}
1;

View file

@ -120,11 +120,12 @@ static INLINE int get_max_bit(int x) {
}
// TODO(angiebird): implement SSE
static INLINE void clamp_block(int16_t *block, int block_size, int stride,
int low, int high) {
static INLINE void clamp_block(int16_t *block, int block_size_row,
int block_size_col, int stride, int low,
int high) {
int i, j;
for (i = 0; i < block_size; ++i) {
for (j = 0; j < block_size; ++j) {
for (i = 0; i < block_size_row; ++i) {
for (j = 0; j < block_size_col; ++j) {
block[i * stride + j] = clamp(block[i * stride + j], low, high);
}
}
@ -208,6 +209,16 @@ static INLINE void set_flip_cfg(int tx_type, TXFM_2D_FLIP_CFG *cfg) {
}
}
#if CONFIG_MRC_TX
static INLINE void get_mrc_mask(const uint8_t *pred, int pred_stride, int *mask,
int mask_stride, int width, int height) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j)
mask[i * mask_stride + j] = pred[i * pred_stride + j] > 100 ? 1 : 0;
}
}
#endif // CONFIG_MRC_TX
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -49,7 +49,7 @@ void av1_foreach_transformed_block_interleave(
const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const TX_SIZE tx_log2_y = mbmi->tx_size;
const TX_SIZE tx_log2_c = get_uv_tx_size(mbmi, pd_c);
const TX_SIZE tx_log2_c = av1_get_uv_tx_size(mbmi, pd_c);
const int tx_sz_y = (1 << tx_log2_y);
const int tx_sz_c = (1 << tx_log2_c);
@ -127,8 +127,8 @@ void av1_foreach_transformed_block_in_plane(
// block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
// 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
// transform size varies per plane, look it up in a common way.
const TX_SIZE tx_size = get_tx_size(plane, xd);
#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
#if CONFIG_CHROMA_SUB8X8
const BLOCK_SIZE plane_bsize =
AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
#else
@ -145,13 +145,27 @@ void av1_foreach_transformed_block_in_plane(
const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
int blk_row, blk_col;
const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
int mu_blocks_wide = block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
int mu_blocks_high = block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);
// Keep track of the row and column of the blocks we use so that we know
// if we are in the unrestricted motion border.
for (r = 0; r < max_blocks_high; r += txh_unit) {
for (r = 0; r < max_blocks_high; r += mu_blocks_high) {
const int unit_height = AOMMIN(mu_blocks_high + r, max_blocks_high);
// Skip visiting the sub blocks that are wholly within the UMV.
for (c = 0; c < max_blocks_wide; c += txw_unit) {
visit(plane, i, r, c, plane_bsize, tx_size, arg);
i += step;
for (c = 0; c < max_blocks_wide; c += mu_blocks_wide) {
const int unit_width = AOMMIN(mu_blocks_wide + c, max_blocks_wide);
for (blk_row = r; blk_row < unit_height; blk_row += txh_unit) {
for (blk_col = c; blk_col < unit_width; blk_col += txw_unit) {
visit(plane, i, blk_row, blk_col, plane_bsize, tx_size, arg);
i += step;
}
}
}
}
}
@ -178,49 +192,6 @@ void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
}
#endif
#if CONFIG_DAALA_DIST
void av1_foreach_8x8_transformed_block_in_yplane(
const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
foreach_transformed_block_visitor visit,
foreach_transformed_block_visitor mi_visit, void *arg) {
const struct macroblockd_plane *const pd = &xd->plane[0];
// block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
// 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
// transform size varies per plane, look it up in a common way.
const TX_SIZE tx_size = get_tx_size(0, xd);
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
const uint8_t txw_unit = tx_size_wide_unit[tx_size];
const uint8_t txh_unit = tx_size_high_unit[tx_size];
const int step = txw_unit * txh_unit;
int i = 0, r, c;
// If mb_to_right_edge is < 0 we are in a situation in which
// the current block size extends into the UMV and we won't
// visit the sub blocks that are wholly within the UMV.
const int max_blocks_wide = max_block_wide(xd, plane_bsize, 0);
const int max_blocks_high = max_block_high(xd, plane_bsize, 0);
const int skip_check_r = tx_size_high[tx_size] == 8 ? 1 : 0;
const int skip_check_c = tx_size_wide[tx_size] == 8 ? 1 : 0;
assert(plane_bsize >= BLOCK_8X8);
assert(tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4);
// Keep track of the row and column of the blocks we use so that we know
// if we are in the unrestricted motion border.
for (r = 0; r < max_blocks_high; r += txh_unit) {
// Skip visiting the sub blocks that are wholly within the UMV.
for (c = 0; c < max_blocks_wide; c += txw_unit) {
visit(0, i, r, c, plane_bsize, tx_size, arg);
// Call whenever each 8x8 tx block is done
if (((r & txh_unit) || skip_check_r) && ((c & txw_unit) || skip_check_c))
mi_visit(0, i, r - (1 - skip_check_r) * txh_unit,
c - (1 - skip_check_c) * txw_unit, plane_bsize, tx_size, arg);
i += step;
}
}
}
#endif
#if !CONFIG_PVQ || CONFIG_VAR_TX
void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
int plane, TX_SIZE tx_size, int has_eob, int aoff,
@ -282,11 +253,11 @@ void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col,
#endif
for (i = 0; i < nplanes; i++) {
struct macroblockd_plane *const pd = &xd->plane[i];
#if CONFIG_CHROMA_2X2 || !CONFIG_CB4X4
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#else
#if CONFIG_CHROMA_SUB8X8
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
const int txs_wide = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
const int txs_high = block_size_high[plane_bsize] >> tx_size_high_log2[0];

View file

@ -119,14 +119,17 @@ typedef struct {
static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
return mode >= NEARESTMV && mode <= NEWMV;
}
static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
}
#if CONFIG_COMPOUND_SINGLEREF
static INLINE int is_inter_singleref_comp_mode(PREDICTION_MODE mode) {
return mode >= SR_NEAREST_NEARMV && mode <= SR_NEW_NEWMV;
}
#endif // CONFIG_COMPOUND_SINGLEREF
static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
static INLINE int is_inter_anyref_comp_mode(PREDICTION_MODE mode) {
return is_inter_compound_mode(mode) || is_inter_singleref_comp_mode(mode);
}
#endif // CONFIG_COMPOUND_SINGLEREF
static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) {
static PREDICTION_MODE lut[] = {
@ -153,7 +156,7 @@ static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) {
MB_MODE_COUNT, // NEWMV
#if CONFIG_COMPOUND_SINGLEREF
NEARESTMV, // SR_NEAREST_NEARMV
NEARESTMV, // SR_NEAREST_NEWMV
// NEARESTMV, // SR_NEAREST_NEWMV
NEARMV, // SR_NEAR_NEWMV
ZEROMV, // SR_ZERO_NEWMV
NEWMV, // SR_NEW_NEWMV
@ -168,7 +171,11 @@ static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) {
NEWMV, // NEW_NEWMV
};
assert(NELEMENTS(lut) == MB_MODE_COUNT);
#if CONFIG_COMPOUND_SINGLEREF
assert(is_inter_anyref_comp_mode(mode));
#else // !CONFIG_COMPOUND_SINGLEREF
assert(is_inter_compound_mode(mode));
#endif // CONFIG_COMPOUND_SINGLEREF
return lut[mode];
}
@ -196,8 +203,8 @@ static INLINE PREDICTION_MODE compound_ref1_mode(PREDICTION_MODE mode) {
MB_MODE_COUNT, // ZEROMV
MB_MODE_COUNT, // NEWMV
#if CONFIG_COMPOUND_SINGLEREF
NEARMV, // SR_NEAREST_NEARMV
NEWMV, // SR_NEAREST_NEWMV
NEARMV, // SR_NEAREST_NEARMV
// NEWMV, // SR_NEAREST_NEWMV
NEWMV, // SR_NEAR_NEWMV
NEWMV, // SR_ZERO_NEWMV
NEWMV, // SR_NEW_NEWMV
@ -212,17 +219,28 @@ static INLINE PREDICTION_MODE compound_ref1_mode(PREDICTION_MODE mode) {
NEWMV, // NEW_NEWMV
};
assert(NELEMENTS(lut) == MB_MODE_COUNT);
#if CONFIG_COMPOUND_SINGLEREF
assert(is_inter_anyref_comp_mode(mode));
#else // !CONFIG_COMPOUND_SINGLEREF
assert(is_inter_compound_mode(mode));
#endif // CONFIG_COMPOUND_SINGLEREF
return lut[mode];
}
static INLINE int have_nearmv_in_inter_mode(PREDICTION_MODE mode) {
return (mode == NEARMV || mode == NEAR_NEARMV || mode == NEAR_NEWMV ||
#if CONFIG_COMPOUND_SINGLEREF
mode == SR_NEAREST_NEARMV || mode == SR_NEAR_NEWMV ||
#endif // CONFIG_COMPOUND_SINGLEREF
mode == NEW_NEARMV);
}
static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
return (mode == NEWMV || mode == NEW_NEWMV || mode == NEAREST_NEWMV ||
#if CONFIG_COMPOUND_SINGLEREF
/* mode == SR_NEAREST_NEWMV || */ mode == SR_NEAR_NEWMV ||
mode == SR_ZERO_NEWMV || mode == SR_NEW_NEWMV ||
#endif // CONFIG_COMPOUND_SINGLEREF
mode == NEW_NEARESTMV || mode == NEAR_NEWMV || mode == NEW_NEARMV);
}
@ -246,7 +264,8 @@ static INLINE int is_masked_compound_type(COMPOUND_TYPE type) {
(void)type;
return 0;
}
#else
#else // !CONFIG_EXT_INTER
static INLINE int have_nearmv_in_inter_mode(PREDICTION_MODE mode) {
return (mode == NEARMV);
@ -278,9 +297,6 @@ typedef struct {
uint8_t palette_size[2];
// Value of base colors for Y, U, and V
uint16_t palette_colors[3 * PALETTE_MAX_SIZE];
// Only used by encoder to store the color index of the top left pixel.
// TODO(huisu): move this to encoder
uint8_t palette_first_color_idx[2];
} PALETTE_MODE_INFO;
#endif // CONFIG_PALETTE
@ -310,7 +326,9 @@ typedef struct RD_STATS {
int64_t rdcost;
int64_t sse;
int skip; // sse should equal to dist when skip == 1
#if CONFIG_DAALA_DIST && CONFIG_CB4X4
int64_t ref_rdcost;
int zero_rate;
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
int64_t dist_y;
#endif
#if CONFIG_RD_DEBUG
@ -359,7 +377,7 @@ typedef struct MB_MODE_INFO {
int8_t seg_id_predicted; // valid only when temporal_update is enabled
// Only for INTRA blocks
PREDICTION_MODE uv_mode;
UV_PREDICTION_MODE uv_mode;
#if CONFIG_PALETTE
PALETTE_MODE_INFO palette_mode_info;
#endif // CONFIG_PALETTE
@ -413,6 +431,13 @@ typedef struct MB_MODE_INFO {
MOTION_MODE motion_mode;
#if CONFIG_MOTION_VAR
int overlappable_neighbors[2];
#if CONFIG_NCOBMC_ADAPT_WEIGHT
// Applying different weighting kernels in ncobmc
// In current implementation, interpolation modes only defined for squared
// blocks. A rectangular block is divided into two squared blocks and each
// squared block has an interpolation mode.
NCOBMC_MODE ncobmc_mode[2];
#endif
#endif // CONFIG_MOTION_VAR
int_mv mv[2];
int_mv pred_mv[2];
@ -472,6 +497,33 @@ static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) {
#endif
}
#if CONFIG_CFL
static INLINE PREDICTION_MODE get_uv_mode(UV_PREDICTION_MODE mode) {
static const PREDICTION_MODE uv2y[UV_INTRA_MODES] = {
DC_PRED, // UV_DC_PRED
V_PRED, // UV_V_PRED
H_PRED, // UV_H_PRED
D45_PRED, // UV_D45_PRED
D135_PRED, // UV_D135_PRED
D117_PRED, // UV_D117_PRED
D153_PRED, // UV_D153_PRED
D207_PRED, // UV_D207_PRED
D63_PRED, // UV_D63_PRED
#if CONFIG_ALT_INTRA
SMOOTH_PRED, // UV_SMOOTH_PRED
#if CONFIG_SMOOTH_HV
SMOOTH_V_PRED, // UV_SMOOTH_V_PRED
SMOOTH_H_PRED, // UV_SMOOTH_H_PRED
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
TM_PRED, // UV_TM_PRED
};
return uv2y[mode];
}
#else
static INLINE PREDICTION_MODE get_uv_mode(PREDICTION_MODE mode) { return mode; }
#endif // CONFIG_CFL
static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
#if CONFIG_INTRABC
if (is_intrabc_block(mbmi)) return 1;
@ -483,6 +535,35 @@ static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[1] > INTRA_FRAME;
}
#if CONFIG_EXT_COMP_REFS
static INLINE int has_uni_comp_refs(const MB_MODE_INFO *mbmi) {
return has_second_ref(mbmi) && (!((mbmi->ref_frame[0] >= BWDREF_FRAME) ^
(mbmi->ref_frame[1] >= BWDREF_FRAME)));
}
static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) {
static const MV_REFERENCE_FRAME lut[] = {
LAST_FRAME, // LAST_LAST2_FRAMES,
LAST_FRAME, // LAST_LAST3_FRAMES,
LAST_FRAME, // LAST_GOLDEN_FRAMES,
BWDREF_FRAME, // BWDREF_ALTREF_FRAMES,
};
assert(NELEMENTS(lut) == UNIDIR_COMP_REFS);
return lut[ref_idx];
}
static INLINE MV_REFERENCE_FRAME comp_ref1(int ref_idx) {
static const MV_REFERENCE_FRAME lut[] = {
LAST2_FRAME, // LAST_LAST2_FRAMES,
LAST3_FRAME, // LAST_LAST3_FRAMES,
GOLDEN_FRAME, // LAST_GOLDEN_FRAMES,
ALTREF_FRAME, // BWDREF_ALTREF_FRAMES,
};
assert(NELEMENTS(lut) == UNIDIR_COMP_REFS);
return lut[ref_idx];
}
#endif // CONFIG_EXT_COMP_REFS
PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi,
const MODE_INFO *left_mi, int b);
@ -553,8 +634,10 @@ typedef struct macroblockd_plane {
const dequant_val_type_nuq *dequant_val_nuq[QUANT_PROFILES];
#endif // CONFIG_NEW_QUANT
#if CONFIG_PVQ || CONFIG_DAALA_DIST
#if CONFIG_PVQ || CONFIG_DIST_8X8
DECLARE_ALIGNED(16, int16_t, pred[MAX_SB_SQUARE]);
#endif
#if CONFIG_PVQ
// PVQ: forward transformed predicted image, a reference for PVQ.
tran_low_t *pvq_ref_coeff;
#endif
@ -567,6 +650,9 @@ typedef struct RefBuffer {
int idx;
YV12_BUFFER_CONFIG *buf;
struct scale_factors sf;
#if CONFIG_VAR_REFS
int is_valid;
#endif // CONFIG_VAR_REFS
} RefBuffer;
#if CONFIG_ADAPT_SCAN
@ -644,9 +730,7 @@ typedef struct macroblockd {
#if CONFIG_PVQ
daala_dec_ctx daala_dec;
#endif
#if CONFIG_EC_ADAPT
FRAME_CONTEXT *tile_ctx;
#endif
/* Bit depth: 8, 10, 12 */
int bd;
@ -686,6 +770,10 @@ typedef struct macroblockd {
#endif
} MACROBLOCKD;
static INLINE int get_bitdepth_data_path_index(const MACROBLOCKD *xd) {
return xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? 1 : 0;
}
static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
PARTITION_TYPE partition) {
if (partition == PARTITION_INVALID)
@ -735,18 +823,50 @@ typedef enum {
// DCT only
EXT_TX_SET_DCTONLY = 0,
// DCT + Identity only
EXT_TX_SET_DCT_IDTX = 1,
EXT_TX_SET_DCT_IDTX,
#if CONFIG_MRC_TX
// DCT + MRC_DCT
EXT_TX_SET_MRC_DCT,
// DCT + MRC_DCT + IDTX
EXT_TX_SET_MRC_DCT_IDTX,
#endif // CONFIG_MRC_TX
// Discrete Trig transforms w/o flip (4) + Identity (1)
EXT_TX_SET_DTT4_IDTX = 2,
EXT_TX_SET_DTT4_IDTX,
// Discrete Trig transforms w/o flip (4) + Identity (1) + 1D Hor/vert DCT (2)
EXT_TX_SET_DTT4_IDTX_1DDCT = 3,
EXT_TX_SET_DTT4_IDTX_1DDCT,
// Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver DCT (2)
EXT_TX_SET_DTT9_IDTX_1DDCT = 4,
EXT_TX_SET_DTT9_IDTX_1DDCT,
// Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6)
EXT_TX_SET_ALL16 = 5,
EXT_TX_SET_ALL16,
EXT_TX_SET_TYPES
} TxSetType;
#if CONFIG_MRC_TX
// Number of transform types in each set type
static const int num_ext_tx_set[EXT_TX_SET_TYPES] = {
1, 2, 2, 3, 5, 7, 12, 16
};
// Maps intra set index to the set type
static const int ext_tx_set_type_intra[EXT_TX_SETS_INTRA] = {
EXT_TX_SET_DCTONLY, EXT_TX_SET_DTT4_IDTX_1DDCT, EXT_TX_SET_DTT4_IDTX,
EXT_TX_SET_MRC_DCT
};
// Maps inter set index to the set type
static const int ext_tx_set_type_inter[EXT_TX_SETS_INTER] = {
EXT_TX_SET_DCTONLY, EXT_TX_SET_ALL16, EXT_TX_SET_DTT9_IDTX_1DDCT,
EXT_TX_SET_DCT_IDTX, EXT_TX_SET_MRC_DCT_IDTX
};
// Maps set types above to the indices used for intra
static const int ext_tx_set_index_intra[EXT_TX_SET_TYPES] = { 0, -1, 3, -1,
2, 1, -1, -1 };
// Maps set types above to the indices used for inter
static const int ext_tx_set_index_inter[EXT_TX_SET_TYPES] = { 0, 3, -1, 4,
-1, -1, 2, 1 };
#else // CONFIG_MRC_TX
// Number of transform types in each set type
static const int num_ext_tx_set[EXT_TX_SET_TYPES] = { 1, 2, 5, 7, 12, 16 };
@ -769,6 +889,7 @@ static const int ext_tx_set_index_intra[EXT_TX_SET_TYPES] = { 0, -1, 2,
static const int ext_tx_set_index_inter[EXT_TX_SET_TYPES] = {
0, 3, -1, -1, 2, 1
};
#endif // CONFIG_MRC_TX
static INLINE TxSetType get_ext_tx_set_type(TX_SIZE tx_size, BLOCK_SIZE bs,
int is_inter, int use_reduced_set) {
@ -782,6 +903,10 @@ static INLINE TxSetType get_ext_tx_set_type(TX_SIZE tx_size, BLOCK_SIZE bs,
#endif
if (use_reduced_set)
return is_inter ? EXT_TX_SET_DCT_IDTX : EXT_TX_SET_DTT4_IDTX;
#if CONFIG_MRC_TX
if (tx_size == TX_32X32)
return is_inter ? EXT_TX_SET_MRC_DCT_IDTX : EXT_TX_SET_MRC_DCT;
#endif // CONFIG_MRC_TX
if (tx_size_sqr_up == TX_32X32)
return is_inter ? EXT_TX_SET_DCT_IDTX : EXT_TX_SET_DCTONLY;
if (is_inter)
@ -800,6 +925,63 @@ static INLINE int get_ext_tx_set(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter,
: ext_tx_set_index_intra[set_type];
}
#if CONFIG_MRC_TX
static const int use_intra_ext_tx_for_txsize[EXT_TX_SETS_INTRA][EXT_TX_SIZES] =
{
#if CONFIG_CHROMA_2X2
{ 1, 1, 1, 1, 1 }, // unused
{ 0, 1, 1, 0, 0 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1 },
#else
{ 1, 1, 1, 1 }, // unused
{ 1, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
#endif // CONFIG_CHROMA_2X2
};
static const int use_inter_ext_tx_for_txsize[EXT_TX_SETS_INTER][EXT_TX_SIZES] =
{
#if CONFIG_CHROMA_2X2
{ 1, 1, 1, 1, 1 }, // unused
{ 0, 1, 1, 0, 0 }, { 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1 }, { 0, 0, 0, 0, 1 },
#else
{ 1, 1, 1, 1 }, // unused
{ 1, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 1 },
#endif // CONFIG_CHROMA_2X2
};
// Transform types used in each intra set
static const int ext_tx_used_intra[EXT_TX_SETS_INTRA][TX_TYPES] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
};
// Numbers of transform types used in each intra set
static const int ext_tx_cnt_intra[EXT_TX_SETS_INTRA] = { 1, 7, 5, 2 };
// Transform types used in each inter set
static const int ext_tx_used_inter[EXT_TX_SETS_INTER][TX_TYPES] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
};
// Numbers of transform types used in each inter set
static const int ext_tx_cnt_inter[EXT_TX_SETS_INTER] = { 1, 16, 12, 2, 3 };
// 1D Transforms used in inter set, this needs to be changed if
// ext_tx_used_inter is changed
static const int ext_tx_used_inter_1D[EXT_TX_SETS_INTER][TX_TYPES_1D] = {
{ 1, 0, 0, 0 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 0, 0, 1 }, { 1, 0, 0, 1 }
};
#else // CONFIG_MRC_TX
static const int use_intra_ext_tx_for_txsize[EXT_TX_SETS_INTRA][EXT_TX_SIZES] =
{
#if CONFIG_CHROMA_2X2
@ -854,6 +1036,7 @@ static const int ext_tx_cnt_inter[EXT_TX_SETS_INTER] = { 1, 16, 12, 2 };
static const int ext_tx_used_inter_1D[EXT_TX_SETS_INTER][TX_TYPES_1D] = {
{ 1, 0, 0, 0 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 0, 0, 1 },
};
#endif // CONFIG_MRC_TX
static INLINE int get_ext_tx_types(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter,
int use_reduced_set) {
@ -864,8 +1047,8 @@ static INLINE int get_ext_tx_types(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter,
#if CONFIG_RECT_TX
static INLINE int is_rect_tx_allowed_bsize(BLOCK_SIZE bsize) {
static const char LUT[BLOCK_SIZES] = {
#if CONFIG_CB4X4
static const char LUT[BLOCK_SIZES_ALL] = {
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
0, // BLOCK_2X2
0, // BLOCK_2X4
0, // BLOCK_4X2
@ -888,6 +1071,10 @@ static INLINE int is_rect_tx_allowed_bsize(BLOCK_SIZE bsize) {
0, // BLOCK_128X64
0, // BLOCK_128X128
#endif // CONFIG_EXT_PARTITION
0, // BLOCK_4X16
0, // BLOCK_16X4
0, // BLOCK_8X32
0, // BLOCK_32X8
};
return LUT[bsize];
@ -898,11 +1085,13 @@ static INLINE int is_rect_tx_allowed(const MACROBLOCKD *xd,
return is_rect_tx_allowed_bsize(mbmi->sb_type) &&
!xd->lossless[mbmi->segment_id];
}
#endif // CONFIG_RECT_TX
#endif // CONFIG_EXT_TX
#if CONFIG_RECT_TX_EXT
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
static INLINE int is_quarter_tx_allowed_bsize(BLOCK_SIZE bsize) {
static const char LUT_QTTX[BLOCK_SIZES] = {
#if CONFIG_CB4X4
static const char LUT_QTTX[BLOCK_SIZES_ALL] = {
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
0, // BLOCK_2X2
0, // BLOCK_2X4
0, // BLOCK_4X2
@ -925,6 +1114,10 @@ static INLINE int is_quarter_tx_allowed_bsize(BLOCK_SIZE bsize) {
0, // BLOCK_128X64
0, // BLOCK_128X128
#endif // CONFIG_EXT_PARTITION
0, // BLOCK_4X16
0, // BLOCK_16X4
0, // BLOCK_8X32
0, // BLOCK_32X8
};
return LUT_QTTX[bsize];
@ -936,9 +1129,7 @@ static INLINE int is_quarter_tx_allowed(const MACROBLOCKD *xd,
return is_quarter_tx_allowed_bsize(mbmi->sb_type) && is_inter &&
!xd->lossless[mbmi->segment_id];
}
#endif // CONFIG_RECT_TX_EXT
#endif // CONFIG_RECT_TX
#endif // CONFIG_EXT_TX
#endif
static INLINE TX_SIZE tx_size_from_tx_mode(BLOCK_SIZE bsize, TX_MODE tx_mode,
int is_inter) {
@ -992,7 +1183,11 @@ int av1_is_intra_filter_switchable(int angle);
#endif // CONFIG_INTRA_INTERP
#endif // CONFIG_EXT_INTRA
#if CONFIG_DCT_ONLY
#define FIXED_TX_TYPE 1
#else
#define FIXED_TX_TYPE 0
#endif
// Converts block_index for given transform size to index of the block in raster
// order.
@ -1015,36 +1210,76 @@ static INLINE int av1_raster_order_to_block_index(TX_SIZE tx_size,
return (tx_size == TX_4X4) ? raster_order : (raster_order > 0) ? 2 : 0;
}
#if CONFIG_DPCM_INTRA || CONFIG_LGT
static INLINE PREDICTION_MODE get_prediction_mode(const MODE_INFO *mi,
int plane, TX_SIZE tx_size,
int block_idx) {
const MB_MODE_INFO *const mbmi = &mi->mbmi;
if (is_inter_block(mbmi)) return mbmi->mode;
int block_raster_idx = av1_block_index_to_raster_order(tx_size, block_idx);
return (plane == PLANE_TYPE_Y) ? get_y_mode(mi, block_raster_idx)
: get_uv_mode(mbmi->uv_mode);
}
#endif
static INLINE TX_TYPE get_default_tx_type(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int block_idx,
TX_SIZE tx_size) {
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
if (is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y ||
if (CONFIG_DCT_ONLY || is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y ||
xd->lossless[mbmi->segment_id] || tx_size >= TX_32X32)
return DCT_DCT;
return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
? get_y_mode(xd->mi[0], block_idx)
: mbmi->uv_mode];
: get_uv_mode(mbmi->uv_mode)];
}
static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd,
int block, TX_SIZE tx_size) {
static INLINE TX_TYPE av1_get_tx_type(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int blk_row,
int blk_col, int block, TX_SIZE tx_size) {
const MODE_INFO *const mi = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
(void)blk_row;
(void)blk_col;
#if CONFIG_INTRABC && (!CONFIG_EXT_TX || CONFIG_TXK_SEL)
// TODO(aconverse@google.com): Handle INTRABC + EXT_TX + TXK_SEL
if (is_intrabc_block(mbmi)) return DCT_DCT;
#endif // CONFIG_INTRABC && (!CONFIG_EXT_TX || CONFIG_TXK_SEL)
#if !CONFIG_TXK_SEL
#if CONFIG_TXK_SEL
TX_TYPE tx_type;
if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] >= TX_32X32) {
tx_type = DCT_DCT;
} else {
if (plane_type == PLANE_TYPE_Y)
tx_type = mbmi->txk_type[(blk_row << 4) + blk_col];
else if (is_inter_block(mbmi))
tx_type = mbmi->txk_type[(blk_row << 5) + (blk_col << 1)];
else
tx_type = intra_mode_to_tx_type_context[mbmi->uv_mode];
}
assert(tx_type >= DCT_DCT && tx_type < TX_TYPES);
return tx_type;
#endif // CONFIG_TXK_SEL
#if FIXED_TX_TYPE
const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
return get_default_tx_type(plane_type, xd, block_raster_idx, tx_size);
#elif CONFIG_EXT_TX
#if !CONFIG_CB4X4
const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
#endif // !CONFIG_CB4X4
#endif // FIXED_TX_TYPE
#if CONFIG_EXT_TX
#if CONFIG_MRC_TX
if (mbmi->tx_type == MRC_DCT) {
if (plane_type == PLANE_TYPE_Y) {
assert(tx_size == TX_32X32);
return mbmi->tx_type;
}
return DCT_DCT;
}
#endif // CONFIG_MRC_TX
if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] > TX_32X32 ||
(txsize_sqr_map[tx_size] >= TX_32X32 && !is_inter_block(mbmi)))
return DCT_DCT;
@ -1073,37 +1308,36 @@ static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd,
if (tx_size < TX_4X4)
return DCT_DCT;
else
#endif
return intra_mode_to_tx_type_context[mbmi->uv_mode];
#endif // CONFIG_CHROMA_2X2
return intra_mode_to_tx_type_context[get_uv_mode(mbmi->uv_mode)];
#else // CONFIG_CB4X4
// Sub8x8-Inter/Intra OR UV-Intra
if (is_inter_block(mbmi)) // Sub8x8-Inter
if (is_inter_block(mbmi)) { // Sub8x8-Inter
return DCT_DCT;
else // Sub8x8 Intra OR UV-Intra
} else { // Sub8x8 Intra OR UV-Intra
const int block_raster_idx =
av1_block_index_to_raster_order(tx_size, block);
return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
? get_y_mode(mi, block_raster_idx)
: mbmi->uv_mode];
: get_uv_mode(mbmi->uv_mode)];
}
#endif // CONFIG_CB4X4
#else // CONFIG_EXT_TX
(void)block;
#if CONFIG_MRC_TX
if (mbmi->tx_type == MRC_DCT) {
if (plane_type == PLANE_TYPE_Y && !xd->lossless[mbmi->segment_id]) {
assert(tx_size == TX_32X32);
return mbmi->tx_type;
}
return DCT_DCT;
}
#endif // CONFIG_MRC_TX
if (plane_type != PLANE_TYPE_Y || xd->lossless[mbmi->segment_id] ||
txsize_sqr_map[tx_size] >= TX_32X32)
return DCT_DCT;
return mbmi->tx_type;
#endif // CONFIG_EXT_TX
#else // !CONFIG_TXK_SEL
(void)tx_size;
TX_TYPE tx_type;
if (plane_type != PLANE_TYPE_Y || xd->lossless[mbmi->segment_id] ||
mbmi->tx_size >= TX_32X32) {
tx_type = DCT_DCT;
} else {
tx_type = mbmi->txk_type[block];
}
assert(tx_type >= DCT_DCT && tx_type < TX_TYPES);
return tx_type;
#endif // !CONFIG_TXK_SEL
}
void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);
@ -1116,12 +1350,11 @@ static INLINE TX_SIZE depth_to_tx_size(int depth) {
return (TX_SIZE)(depth + TX_SIZE_LUMA_MIN);
}
static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi,
const struct macroblockd_plane *pd) {
TX_SIZE uv_txsize;
static INLINE TX_SIZE av1_get_uv_tx_size(const MB_MODE_INFO *mbmi,
const struct macroblockd_plane *pd) {
#if CONFIG_CHROMA_2X2
assert(mbmi->tx_size > TX_2X2);
#endif
#endif // CONFIG_CHROMA_2X2
#if CONFIG_SUPERTX
if (supertx_enabled(mbmi))
@ -1129,17 +1362,18 @@ static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi,
[pd->subsampling_x][pd->subsampling_y];
#endif // CONFIG_SUPERTX
uv_txsize = uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][pd->subsampling_x]
[pd->subsampling_y];
const TX_SIZE uv_txsize =
uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][pd->subsampling_x]
[pd->subsampling_y];
assert(uv_txsize != TX_INVALID);
return uv_txsize;
}
static INLINE TX_SIZE get_tx_size(int plane, const MACROBLOCKD *xd) {
static INLINE TX_SIZE av1_get_tx_size(int plane, const MACROBLOCKD *xd) {
const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
if (plane == 0) return mbmi->tx_size;
const MACROBLOCKD_PLANE *pd = &xd->plane[plane];
const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
return tx_size;
return av1_get_uv_tx_size(mbmi, pd);
}
static INLINE BLOCK_SIZE
@ -1166,13 +1400,6 @@ void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
void *arg);
#endif
#if CONFIG_DAALA_DIST
void av1_foreach_8x8_transformed_block_in_yplane(
const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
foreach_transformed_block_visitor visit,
foreach_transformed_block_visitor mi_visit, void *arg);
#endif
#if CONFIG_COEF_INTERLEAVE
static INLINE int get_max_4x4_size(int num_4x4, int mb_to_edge,
int subsampling) {
@ -1225,7 +1452,7 @@ static INLINE int is_interintra_allowed(const MB_MODE_INFO *mbmi) {
static INLINE int is_interintra_allowed_bsize_group(int group) {
int i;
for (i = 0; i < BLOCK_SIZES; i++) {
for (i = 0; i < BLOCK_SIZES_ALL; i++) {
if (size_group_lookup[i] == group &&
is_interintra_allowed_bsize((BLOCK_SIZE)i)) {
return 1;
@ -1258,7 +1485,11 @@ static INLINE int is_motion_variation_allowed_bsize(BLOCK_SIZE bsize) {
static INLINE int is_motion_variation_allowed_compound(
const MB_MODE_INFO *mbmi) {
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
if (!has_second_ref(mbmi) && !is_inter_singleref_comp_mode(mbmi->mode))
#else
if (!has_second_ref(mbmi))
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
return 1;
else
return 0;
@ -1275,15 +1506,18 @@ static INLINE int check_num_overlappable_neighbors(const MB_MODE_INFO *mbmi) {
#endif
static INLINE MOTION_MODE motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
int block, const WarpedMotionParams *gm_params,
#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
const MACROBLOCKD *xd,
#endif
const MODE_INFO *mi) {
const MB_MODE_INFO *mbmi = &mi->mbmi;
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
const TransformationType gm_type = gm_params[mbmi->ref_frame[0]].wmtype;
if (is_global_mv_block(mi, block, gm_type)) return SIMPLE_TRANSLATION;
#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_EXT_INTER
if (is_motion_variation_allowed_bsize(mbmi->sb_type) &&
is_inter_mode(mbmi->mode) && mbmi->ref_frame[1] != INTRA_FRAME &&
@ -1296,7 +1530,8 @@ static INLINE MOTION_MODE motion_mode_allowed(
if (!check_num_overlappable_neighbors(mbmi)) return SIMPLE_TRANSLATION;
#endif
#if CONFIG_WARPED_MOTION
if (!has_second_ref(mbmi) && mbmi->num_proj_ref[0] >= 1)
if (!has_second_ref(mbmi) && mbmi->num_proj_ref[0] >= 1 &&
!av1_is_scaled(&(xd->block_refs[0]->sf)))
return WARPED_CAUSAL;
else
#endif // CONFIG_WARPED_MOTION
@ -1310,17 +1545,68 @@ static INLINE MOTION_MODE motion_mode_allowed(
}
}
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
static INLINE NCOBMC_MODE ncobmc_mode_allowed_bsize(BLOCK_SIZE bsize) {
if (bsize < BLOCK_8X8 || bsize > BLOCK_64X64)
return NO_OVERLAP;
else
return (NCOBMC_MODE)(MAX_NCOBMC_MODES - 1);
}
static INLINE MOTION_MODE
motion_mode_allowed_wrapper(int for_mv_search,
#if CONFIG_GLOBAL_MOTION
int block, const WarpedMotionParams *gm_params,
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
const MACROBLOCKD *xd,
#endif
const MODE_INFO *mi) {
const MB_MODE_INFO *mbmi = &mi->mbmi;
MOTION_MODE motion_mode_for_mv_search = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION
int block, const WarpedMotionParams *gm_params,
#endif
#if CONFIG_WARPED_MOTION
xd,
#endif
mi);
int ncobmc_mode_allowed =
ncobmc_mode_allowed_bsize(mbmi->sb_type) && is_inter_mode(mbmi->mode);
if (for_mv_search)
return motion_mode_for_mv_search;
else
return ncobmc_mode_allowed ? NCOBMC_ADAPT_WEIGHT
: motion_mode_for_mv_search;
}
#endif
static INLINE void assert_motion_mode_valid(MOTION_MODE mode,
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
int block,
const WarpedMotionParams *gm_params,
#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
const MACROBLOCKD *xd,
#endif
const MODE_INFO *mi) {
#if CONFIG_NCOBMC_ADAPT_WEIGHT
const MOTION_MODE last_motion_mode_allowed =
motion_mode_allowed_wrapper(0,
#if CONFIG_GLOBAL_MOTION
block, gm_params,
#endif // CONFIG_GLOBAL_MOTION
mi);
#else
const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
block, gm_params,
#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
xd,
#endif
mi);
#endif
// Check that the input mode is not illegal
if (last_motion_mode_allowed < mode)
assert(0 && "Illegal motion mode selected");
@ -1381,11 +1667,10 @@ static INLINE int is_nontrans_global_motion(const MACROBLOCKD *xd) {
#endif // CONFIG_EXT_INTER
} else {
#if CONFIG_EXT_INTER
if (mi->bmi[0].as_mode != ZEROMV || mi->bmi[1].as_mode != ZEROMV ||
mi->bmi[2].as_mode != ZEROMV || mi->bmi[3].as_mode != ZEROMV ||
mi->bmi[0].as_mode != ZERO_ZEROMV ||
mi->bmi[1].as_mode != ZERO_ZEROMV ||
mi->bmi[2].as_mode != ZERO_ZEROMV || mi->bmi[3].as_mode != ZERO_ZEROMV)
if ((mi->bmi[0].as_mode != ZEROMV && mi->bmi[0].as_mode != ZERO_ZEROMV) ||
(mi->bmi[1].as_mode != ZEROMV && mi->bmi[1].as_mode != ZERO_ZEROMV) ||
(mi->bmi[2].as_mode != ZEROMV && mi->bmi[2].as_mode != ZERO_ZEROMV) ||
(mi->bmi[3].as_mode != ZEROMV && mi->bmi[3].as_mode != ZERO_ZEROMV))
return 0;
#else
if (mi->bmi[0].as_mode != ZEROMV || mi->bmi[1].as_mode != ZEROMV ||

View file

@ -27,8 +27,8 @@ int sb_all_skip(const AV1_COMMON *const cm, int mi_row, int mi_col) {
maxc = cm->mi_cols - mi_col;
maxr = cm->mi_rows - mi_row;
maxr = AOMMIN(maxr, cm->mib_size);
maxc = AOMMIN(maxc, cm->mib_size);
maxr = AOMMIN(maxr, MI_SIZE_64X64);
maxc = AOMMIN(maxc, MI_SIZE_64X64);
for (r = 0; r < maxr; r++) {
for (c = 0; c < maxc; c++) {
@ -60,8 +60,8 @@ int sb_compute_dering_list(const AV1_COMMON *const cm, int mi_row, int mi_col,
maxc = cm->mi_cols - mi_col;
maxr = cm->mi_rows - mi_row;
maxr = AOMMIN(maxr, cm->mib_size);
maxc = AOMMIN(maxc, cm->mib_size);
maxr = AOMMIN(maxr, MI_SIZE_64X64);
maxc = AOMMIN(maxc, MI_SIZE_64X64);
const int r_step = mi_size_high[BLOCK_8X8];
const int c_step = mi_size_wide[BLOCK_8X8];
@ -117,9 +117,9 @@ void copy_rect8_16bit_to_16bit_c(uint16_t *dst, int dstride,
}
}
void copy_sb8_16(UNUSED AV1_COMMON *cm, uint16_t *dst, int dstride,
const uint8_t *src, int src_voffset, int src_hoffset,
int sstride, int vsize, int hsize) {
static void copy_sb8_16(UNUSED AV1_COMMON *cm, uint16_t *dst, int dstride,
const uint8_t *src, int src_voffset, int src_hoffset,
int sstride, int vsize, int hsize) {
#if CONFIG_HIGHBITDEPTH
if (cm->use_highbitdepth) {
const uint16_t *base =
@ -161,7 +161,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
uint16_t src[OD_DERING_INBUF_SIZE];
uint16_t *linebuf[3];
uint16_t *colbuf[3];
dering_list dlist[MAX_MIB_SIZE * MAX_MIB_SIZE];
dering_list dlist[MI_SIZE_64X64 * MI_SIZE_64X64];
unsigned char *row_dering, *prev_row_dering, *curr_row_dering;
int dering_count;
int dir[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS] = { { 0 } };
@ -178,8 +178,8 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
int chroma_dering =
xd->plane[1].subsampling_x == xd->plane[1].subsampling_y &&
xd->plane[2].subsampling_x == xd->plane[2].subsampling_y;
nvsb = (cm->mi_rows + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
nhsb = (cm->mi_cols + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
nvsb = (cm->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
nhsb = (cm->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0);
row_dering = aom_malloc(sizeof(*row_dering) * (nhsb + 2) * 2);
memset(row_dering, 1, sizeof(*row_dering) * (nhsb + 2) * 2);
@ -202,7 +202,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
for (sbr = 0; sbr < nvsb; sbr++) {
for (pli = 0; pli < nplanes; pli++) {
const int block_height =
(MAX_MIB_SIZE << mi_high_l2[pli]) + 2 * OD_FILT_VBORDER;
(MI_SIZE_64X64 << mi_high_l2[pli]) + 2 * OD_FILT_VBORDER;
fill_rect(colbuf[pli], OD_FILT_HBORDER, block_height, OD_FILT_HBORDER,
OD_DERING_VERY_LARGE);
}
@ -213,43 +213,41 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
int nhb, nvb;
int cstart = 0;
curr_row_dering[sbc] = 0;
if (cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
MAX_MIB_SIZE * sbc] == NULL ||
cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
MAX_MIB_SIZE * sbc]
if (cm->mi_grid_visible[MI_SIZE_64X64 * sbr * cm->mi_stride +
MI_SIZE_64X64 * sbc] == NULL ||
cm->mi_grid_visible[MI_SIZE_64X64 * sbr * cm->mi_stride +
MI_SIZE_64X64 * sbc]
->mbmi.cdef_strength == -1) {
dering_left = 0;
continue;
}
if (!dering_left) cstart = -OD_FILT_HBORDER;
nhb = AOMMIN(MAX_MIB_SIZE, cm->mi_cols - MAX_MIB_SIZE * sbc);
nvb = AOMMIN(MAX_MIB_SIZE, cm->mi_rows - MAX_MIB_SIZE * sbr);
nhb = AOMMIN(MI_SIZE_64X64, cm->mi_cols - MI_SIZE_64X64 * sbc);
nvb = AOMMIN(MI_SIZE_64X64, cm->mi_rows - MI_SIZE_64X64 * sbr);
int tile_top, tile_left, tile_bottom, tile_right;
int mi_idx = MAX_MIB_SIZE * sbr * cm->mi_stride + MAX_MIB_SIZE * sbc;
BOUNDARY_TYPE boundary_tl =
cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
MAX_MIB_SIZE * sbc]
->mbmi.boundary_info;
int mi_idx = MI_SIZE_64X64 * sbr * cm->mi_stride + MI_SIZE_64X64 * sbc;
MODE_INFO *const mi_tl = cm->mi + mi_idx;
BOUNDARY_TYPE boundary_tl = mi_tl->mbmi.boundary_info;
tile_top = boundary_tl & TILE_ABOVE_BOUNDARY;
tile_left = boundary_tl & TILE_LEFT_BOUNDARY;
/* Right and bottom information appear unreliable, so we use the top
and left flags for the next superblocks. */
if (sbr != nvsb - 1 &&
cm->mi_grid_visible[mi_idx + MAX_MIB_SIZE * cm->mi_stride])
tile_bottom = cm->mi_grid_visible[mi_idx + MAX_MIB_SIZE * cm->mi_stride]
->mbmi.boundary_info &
TILE_ABOVE_BOUNDARY;
(&cm->mi[mi_idx + (MI_SIZE_64X64 - 1) * cm->mi_stride]))
tile_bottom = cm->mi[mi_idx + (MI_SIZE_64X64 - 1) * cm->mi_stride]
.mbmi.boundary_info &
TILE_BOTTOM_BOUNDARY;
else
tile_bottom = 1;
if (sbc != nhsb - 1 && cm->mi_grid_visible[mi_idx + MAX_MIB_SIZE])
tile_right =
cm->mi_grid_visible[mi_idx + MAX_MIB_SIZE]->mbmi.boundary_info &
TILE_LEFT_BOUNDARY;
if (sbc != nhsb - 1 && (&cm->mi[mi_idx + MI_SIZE_64X64 - 1]))
tile_right = cm->mi[mi_idx + MI_SIZE_64X64 - 1].mbmi.boundary_info &
TILE_RIGHT_BOUNDARY;
else
tile_right = 1;
const int mbmi_cdef_strength =
cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
MAX_MIB_SIZE * sbc]
cm->mi_grid_visible[MI_SIZE_64X64 * sbr * cm->mi_stride +
MI_SIZE_64X64 * sbc]
->mbmi.cdef_strength;
level = cm->cdef_strengths[mbmi_cdef_strength] / CLPF_STRENGTHS;
clpf_strength = cm->cdef_strengths[mbmi_cdef_strength] % CLPF_STRENGTHS;
@ -261,7 +259,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
if ((level == 0 && clpf_strength == 0 && uv_level == 0 &&
uv_clpf_strength == 0) ||
(dering_count = sb_compute_dering_list(
cm, sbr * MAX_MIB_SIZE, sbc * MAX_MIB_SIZE, dlist,
cm, sbr * MI_SIZE_64X64, sbc * MI_SIZE_64X64, dlist,
get_filter_skip(level) || get_filter_skip(uv_level))) == 0) {
dering_left = 0;
continue;
@ -295,7 +293,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
else
rend = vsize + OD_FILT_VBORDER;
coffset = sbc * MAX_MIB_SIZE << mi_wide_l2[pli];
coffset = sbc * MI_SIZE_64X64 << mi_wide_l2[pli];
if (sbc == nhsb - 1) {
/* On the last superblock column, fill in the right border with
OD_DERING_VERY_LARGE to avoid filtering with the outside. */
@ -316,14 +314,14 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
cm,
&src[OD_FILT_VBORDER * OD_FILT_BSTRIDE + OD_FILT_HBORDER + cstart],
OD_FILT_BSTRIDE, xd->plane[pli].dst.buf,
(MAX_MIB_SIZE << mi_high_l2[pli]) * sbr, coffset + cstart,
(MI_SIZE_64X64 << mi_high_l2[pli]) * sbr, coffset + cstart,
xd->plane[pli].dst.stride, rend, cend - cstart);
if (!prev_row_dering[sbc]) {
copy_sb8_16(cm, &src[OD_FILT_HBORDER], OD_FILT_BSTRIDE,
xd->plane[pli].dst.buf,
(MAX_MIB_SIZE << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset, xd->plane[pli].dst.stride, OD_FILT_VBORDER,
hsize);
copy_sb8_16(
cm, &src[OD_FILT_HBORDER], OD_FILT_BSTRIDE,
xd->plane[pli].dst.buf,
(MI_SIZE_64X64 << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset, xd->plane[pli].dst.stride, OD_FILT_VBORDER, hsize);
} else if (sbr > 0) {
copy_rect(&src[OD_FILT_HBORDER], OD_FILT_BSTRIDE,
&linebuf[pli][coffset], stride, OD_FILT_VBORDER, hsize);
@ -332,10 +330,11 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
hsize, OD_DERING_VERY_LARGE);
}
if (!prev_row_dering[sbc - 1]) {
copy_sb8_16(cm, src, OD_FILT_BSTRIDE, xd->plane[pli].dst.buf,
(MAX_MIB_SIZE << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset - OD_FILT_HBORDER, xd->plane[pli].dst.stride,
OD_FILT_VBORDER, OD_FILT_HBORDER);
copy_sb8_16(
cm, src, OD_FILT_BSTRIDE, xd->plane[pli].dst.buf,
(MI_SIZE_64X64 << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset - OD_FILT_HBORDER, xd->plane[pli].dst.stride,
OD_FILT_VBORDER, OD_FILT_HBORDER);
} else if (sbr > 0 && sbc > 0) {
copy_rect(src, OD_FILT_BSTRIDE,
&linebuf[pli][coffset - OD_FILT_HBORDER], stride,
@ -345,11 +344,12 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
OD_DERING_VERY_LARGE);
}
if (!prev_row_dering[sbc + 1]) {
copy_sb8_16(cm, &src[OD_FILT_HBORDER + (nhb << mi_wide_l2[pli])],
OD_FILT_BSTRIDE, xd->plane[pli].dst.buf,
(MAX_MIB_SIZE << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset + hsize, xd->plane[pli].dst.stride,
OD_FILT_VBORDER, OD_FILT_HBORDER);
copy_sb8_16(
cm, &src[OD_FILT_HBORDER + (nhb << mi_wide_l2[pli])],
OD_FILT_BSTRIDE, xd->plane[pli].dst.buf,
(MI_SIZE_64X64 << mi_high_l2[pli]) * sbr - OD_FILT_VBORDER,
coffset + hsize, xd->plane[pli].dst.stride, OD_FILT_VBORDER,
OD_FILT_HBORDER);
} else if (sbr > 0 && sbc < nhsb - 1) {
copy_rect(&src[hsize + OD_FILT_HBORDER], OD_FILT_BSTRIDE,
&linebuf[pli][coffset + hsize], stride, OD_FILT_VBORDER,
@ -370,7 +370,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
rend + OD_FILT_VBORDER, OD_FILT_HBORDER);
copy_sb8_16(
cm, &linebuf[pli][coffset], stride, xd->plane[pli].dst.buf,
(MAX_MIB_SIZE << mi_high_l2[pli]) * (sbr + 1) - OD_FILT_VBORDER,
(MI_SIZE_64X64 << mi_high_l2[pli]) * (sbr + 1) - OD_FILT_VBORDER,
coffset, xd->plane[pli].dst.stride, OD_FILT_VBORDER, hsize);
if (tile_top) {
@ -397,8 +397,8 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
(uint8_t *)&CONVERT_TO_SHORTPTR(
xd->plane[pli]
.dst.buf)[xd->plane[pli].dst.stride *
(MAX_MIB_SIZE * sbr << mi_high_l2[pli]) +
(sbc * MAX_MIB_SIZE << mi_wide_l2[pli])],
(MI_SIZE_64X64 * sbr << mi_high_l2[pli]) +
(sbc * MI_SIZE_64X64 << mi_wide_l2[pli])],
xd->plane[pli].dst.stride, dst,
&src[OD_FILT_VBORDER * OD_FILT_BSTRIDE + OD_FILT_HBORDER],
xdec[pli], ydec[pli], dir, NULL, var, pli, dlist, dering_count,
@ -408,8 +408,8 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
#endif
od_dering(&xd->plane[pli]
.dst.buf[xd->plane[pli].dst.stride *
(MAX_MIB_SIZE * sbr << mi_high_l2[pli]) +
(sbc * MAX_MIB_SIZE << mi_wide_l2[pli])],
(MI_SIZE_64X64 * sbr << mi_high_l2[pli]) +
(sbc * MI_SIZE_64X64 << mi_wide_l2[pli])],
xd->plane[pli].dst.stride, dst,
&src[OD_FILT_VBORDER * OD_FILT_BSTRIDE + OD_FILT_HBORDER],
xdec[pli], ydec[pli], dir, NULL, var, pli, dlist,

View file

@ -45,7 +45,7 @@ int sb_compute_dering_list(const AV1_COMMON *const cm, int mi_row, int mi_col,
void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, MACROBLOCKD *xd);
void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
AV1_COMMON *cm, MACROBLOCKD *xd);
AV1_COMMON *cm, MACROBLOCKD *xd, int fast);
#ifdef __cplusplus
} // extern "C"

View file

@ -15,21 +15,106 @@
#include "aom/internal/aom_codec_internal.h"
void cfl_init(CFL_CTX *cfl, AV1_COMMON *cm, int subsampling_x,
int subsampling_y) {
if (!((subsampling_x == 0 && subsampling_y == 0) ||
(subsampling_x == 1 && subsampling_y == 1))) {
void cfl_init(CFL_CTX *cfl, AV1_COMMON *cm) {
if (!((cm->subsampling_x == 0 && cm->subsampling_y == 0) ||
(cm->subsampling_x == 1 && cm->subsampling_y == 1))) {
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"Only 4:4:4 and 4:2:0 are currently supported by CfL");
}
memset(&cfl->y_pix, 0, sizeof(uint8_t) * MAX_SB_SQUARE);
cfl->subsampling_x = subsampling_x;
cfl->subsampling_y = subsampling_y;
cfl->subsampling_x = cm->subsampling_x;
cfl->subsampling_y = cm->subsampling_y;
cfl->are_parameters_computed = 0;
}
// Load from the CfL pixel buffer into output
static void cfl_load(CFL_CTX *cfl, int row, int col, int width, int height) {
const int sub_x = cfl->subsampling_x;
const int sub_y = cfl->subsampling_y;
const int off_log2 = tx_size_wide_log2[0];
// TODO(ltrudeau) convert to uint16 to add HBD support
const uint8_t *y_pix;
// TODO(ltrudeau) convert to uint16 to add HBD support
uint8_t *output = cfl->y_down_pix;
int pred_row_offset = 0;
int output_row_offset = 0;
// TODO(ltrudeau) should be faster to downsample when we store the values
// TODO(ltrudeau) add support for 4:2:2
if (sub_y == 0 && sub_x == 0) {
y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << off_log2];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
// In 4:4:4, pixels match 1 to 1
output[output_row_offset + i] = y_pix[pred_row_offset + i];
}
pred_row_offset += MAX_SB_SIZE;
output_row_offset += MAX_SB_SIZE;
}
} else if (sub_y == 1 && sub_x == 1) {
y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << (off_log2 + sub_y)];
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int top_left = (pred_row_offset + i) << sub_y;
int bot_left = top_left + MAX_SB_SIZE;
// In 4:2:0, average pixels in 2x2 grid
output[output_row_offset + i] = OD_SHR_ROUND(
y_pix[top_left] + y_pix[top_left + 1] // Top row
+ y_pix[bot_left] + y_pix[bot_left + 1] // Bottom row
,
2);
}
pred_row_offset += MAX_SB_SIZE;
output_row_offset += MAX_SB_SIZE;
}
} else {
assert(0); // Unsupported chroma subsampling
}
// Due to frame boundary issues, it is possible that the total area of
// covered by Chroma exceeds that of Luma. When this happens, we write over
// the broken data by repeating the last columns and/or rows.
//
// Note that in order to manage the case where both rows and columns
// overrun,
// we apply rows first. This way, when the rows overrun the bottom of the
// frame, the columns will be copied over them.
const int uv_width = (col << off_log2) + width;
const int uv_height = (row << off_log2) + height;
const int diff_width = uv_width - (cfl->y_width >> sub_x);
const int diff_height = uv_height - (cfl->y_height >> sub_y);
if (diff_width > 0) {
int last_pixel;
output_row_offset = width - diff_width;
for (int j = 0; j < height; j++) {
last_pixel = output_row_offset - 1;
for (int i = 0; i < diff_width; i++) {
output[output_row_offset + i] = output[last_pixel];
}
output_row_offset += MAX_SB_SIZE;
}
}
if (diff_height > 0) {
output_row_offset = (height - diff_height) * MAX_SB_SIZE;
const int last_row_offset = output_row_offset - MAX_SB_SIZE;
for (int j = 0; j < diff_height; j++) {
for (int i = 0; i < width; i++) {
output[output_row_offset + i] = output[last_row_offset + i];
}
output_row_offset += MAX_SB_SIZE;
}
}
}
// CfL computes its own block-level DC_PRED. This is required to compute both
// alpha_cb and alpha_cr before the prediction are computed.
void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
static void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize) {
const struct macroblockd_plane *const pd_u = &xd->plane[AOM_PLANE_U];
const struct macroblockd_plane *const pd_v = &xd->plane[AOM_PLANE_V];
@ -39,15 +124,16 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
const int dst_u_stride = pd_u->dst.stride;
const int dst_v_stride = pd_v->dst.stride;
const int block_width = (plane_bsize != BLOCK_INVALID)
? block_size_wide[plane_bsize]
: tx_size_wide[tx_size];
const int block_height = (plane_bsize != BLOCK_INVALID)
? block_size_high[plane_bsize]
: tx_size_high[tx_size];
CFL_CTX *const cfl = xd->cfl;
// Compute DC_PRED until block boundary. We can't assume the neighbor will use
// the same transform size.
const int width = max_block_wide(xd, plane_bsize, AOM_PLANE_U)
<< tx_size_wide_log2[0];
const int height = max_block_high(xd, plane_bsize, AOM_PLANE_U)
<< tx_size_high_log2[0];
// Number of pixel on the top and left borders.
const double num_pel = block_width + block_height;
const int num_pel = width + height;
int sum_u = 0;
int sum_v = 0;
@ -68,13 +154,13 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
if (xd->up_available && xd->mb_to_right_edge >= 0) {
#endif
// TODO(ltrudeau) replace this with DC_PRED assembly
for (int i = 0; i < block_width; i++) {
for (int i = 0; i < width; i++) {
sum_u += dst_u[-dst_u_stride + i];
sum_v += dst_v[-dst_v_stride + i];
}
} else {
sum_u = block_width * 127;
sum_v = block_width * 127;
sum_u = width * 127;
sum_v = width * 127;
}
#if CONFIG_CHROMA_SUB8X8
@ -82,56 +168,158 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
#else
if (xd->left_available && xd->mb_to_bottom_edge >= 0) {
#endif
for (int i = 0; i < block_height; i++) {
for (int i = 0; i < height; i++) {
sum_u += dst_u[i * dst_u_stride - 1];
sum_v += dst_v[i * dst_v_stride - 1];
}
} else {
sum_u += block_height * 129;
sum_v += block_height * 129;
sum_u += height * 129;
sum_v += height * 129;
}
xd->cfl->dc_pred[CFL_PRED_U] = sum_u / num_pel;
xd->cfl->dc_pred[CFL_PRED_V] = sum_v / num_pel;
// TODO(ltrudeau) Because of max_block_wide and max_block_high, num_pel will
// not be a power of two. So these divisions will have to use a lookup table.
cfl->dc_pred[CFL_PRED_U] = (sum_u + (num_pel >> 1)) / num_pel;
cfl->dc_pred[CFL_PRED_V] = (sum_v + (num_pel >> 1)) / num_pel;
}
static void cfl_compute_averages(CFL_CTX *cfl, TX_SIZE tx_size) {
const int width = cfl->uv_width;
const int height = cfl->uv_height;
const int tx_height = tx_size_high[tx_size];
const int tx_width = tx_size_wide[tx_size];
const int stride = width >> tx_size_wide_log2[tx_size];
const int block_row_stride = MAX_SB_SIZE << tx_size_high_log2[tx_size];
const int num_pel_log2 =
(tx_size_high_log2[tx_size] + tx_size_wide_log2[tx_size]);
// TODO(ltrudeau) Convert to uint16 for HBD support
const uint8_t *y_pix = cfl->y_down_pix;
// TODO(ltrudeau) Convert to uint16 for HBD support
const uint8_t *t_y_pix;
int *averages_q3 = cfl->y_averages_q3;
cfl_load(cfl, 0, 0, width, height);
int a = 0;
for (int b_j = 0; b_j < height; b_j += tx_height) {
for (int b_i = 0; b_i < width; b_i += tx_width) {
int sum = 0;
t_y_pix = y_pix;
for (int t_j = 0; t_j < tx_height; t_j++) {
for (int t_i = b_i; t_i < b_i + tx_width; t_i++) {
sum += t_y_pix[t_i];
}
t_y_pix += MAX_SB_SIZE;
}
averages_q3[a++] =
((sum << 3) + (1 << (num_pel_log2 - 1))) >> num_pel_log2;
// Loss is never more than 1/2 (in Q3)
assert(fabs((double)averages_q3[a - 1] -
(sum / ((double)(1 << num_pel_log2))) * (1 << 3)) <= 0.5);
}
assert(a % stride == 0);
y_pix += block_row_stride;
}
cfl->y_averages_stride = stride;
assert(a <= MAX_NUM_TXB);
}
static INLINE int cfl_idx_to_alpha(int alpha_idx, CFL_SIGN_TYPE alpha_sign,
CFL_PRED_TYPE pred_type) {
const int mag_idx = cfl_alpha_codes[alpha_idx][pred_type];
const int abs_alpha_q3 = cfl_alpha_mags_q3[mag_idx];
if (alpha_sign == CFL_SIGN_POS) {
return abs_alpha_q3;
} else {
assert(abs_alpha_q3 != 0);
assert(cfl_alpha_mags_q3[mag_idx + 1] == -abs_alpha_q3);
return -abs_alpha_q3;
}
}
// Predict the current transform block using CfL.
void cfl_predict_block(const CFL_CTX *cfl, uint8_t *dst, int dst_stride,
int row, int col, TX_SIZE tx_size, double dc_pred,
double alpha) {
void cfl_predict_block(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
int row, int col, TX_SIZE tx_size, int plane) {
CFL_CTX *const cfl = xd->cfl;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
// CfL parameters must be computed before prediction can be done.
assert(cfl->are_parameters_computed == 1);
const int width = tx_size_wide[tx_size];
const int height = tx_size_high[tx_size];
// TODO(ltrudeau) Convert to uint16 to support HBD
const uint8_t *y_pix = cfl->y_down_pix;
const double y_avg = cfl_load(cfl, dst, dst_stride, row, col, width, height);
const int dc_pred = cfl->dc_pred[plane - 1];
const int alpha_q3 = cfl_idx_to_alpha(
mbmi->cfl_alpha_idx, mbmi->cfl_alpha_signs[plane - 1], plane - 1);
const int avg_row =
(row << tx_size_wide_log2[0]) >> tx_size_wide_log2[tx_size];
const int avg_col =
(col << tx_size_high_log2[0]) >> tx_size_high_log2[tx_size];
const int avg_q3 =
cfl->y_averages_q3[cfl->y_averages_stride * avg_row + avg_col];
cfl_load(cfl, row, col, width, height);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
dst[i] = (uint8_t)(alpha * (dst[i] - y_avg) + dc_pred + 0.5);
// TODO(ltrudeau) add support for HBD.
dst[i] =
clip_pixel(get_scaled_luma_q0(alpha_q3, y_pix[i], avg_q3) + dc_pred);
}
dst += dst_stride;
y_pix += MAX_SB_SIZE;
}
}
void cfl_store(CFL_CTX *cfl, const uint8_t *input, int input_stride, int row,
int col, TX_SIZE tx_size) {
int col, TX_SIZE tx_size, BLOCK_SIZE bsize) {
const int tx_width = tx_size_wide[tx_size];
const int tx_height = tx_size_high[tx_size];
const int tx_off_log2 = tx_size_wide_log2[0];
// Store the input into the CfL pixel buffer
uint8_t *y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << tx_off_log2];
#if CONFIG_CHROMA_SUB8X8
if (bsize < BLOCK_8X8) {
// Transform cannot be smaller than
assert(tx_width >= 4);
assert(tx_height >= 4);
// Check that we remain inside the pixel buffer.
assert(MAX_SB_SIZE * (row + tx_height - 1) + col + tx_width - 1 <
MAX_SB_SQUARE);
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
for (int j = 0; j < tx_height; j++) {
for (int i = 0; i < tx_width; i++) {
y_pix[i] = input[i];
// For chroma_sub8x8, the CfL prediction for prediction blocks smaller than
// 8X8 uses non chroma reference reconstructed luma pixels. To do so, we
// combine the 4X4 non chroma reference into the CfL pixel buffers based on
// their row and column index.
// The following code is adapted from the is_chroma_reference() function.
if ((cfl->mi_row &
0x01) // Increment the row index for odd indexed 4X4 blocks
&& (bh == 4) // But not for 4X8 blocks
&& cfl->subsampling_y) { // And only when chroma is subsampled
assert(row == 0);
row++;
}
if ((cfl->mi_col &
0x01) // Increment the col index for odd indexed 4X4 blocks
&& (bw == 4) // But not for 8X4 blocks
&& cfl->subsampling_x) { // And only when chroma is subsampled
assert(col == 0);
col++;
}
y_pix += MAX_SB_SIZE;
input += input_stride;
}
#else
(void)bsize;
#endif
// Invalidate current parameters
cfl->are_parameters_computed = 0;
// Store the surface of the pixel buffer that was written to, this way we
// can manage chroma overrun (e.g. when the chroma surfaces goes beyond the
@ -143,101 +331,54 @@ void cfl_store(CFL_CTX *cfl, const uint8_t *input, int input_stride, int row,
cfl->y_width = OD_MAXI((col << tx_off_log2) + tx_width, cfl->y_width);
cfl->y_height = OD_MAXI((row << tx_off_log2) + tx_height, cfl->y_height);
}
// Check that we will remain inside the pixel buffer.
assert((row << tx_off_log2) + tx_height <= MAX_SB_SIZE);
assert((col << tx_off_log2) + tx_width <= MAX_SB_SIZE);
// Store the input into the CfL pixel buffer
uint8_t *y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << tx_off_log2];
// TODO(ltrudeau) Speedup possible by moving the downsampling to cfl_store
for (int j = 0; j < tx_height; j++) {
for (int i = 0; i < tx_width; i++) {
y_pix[i] = input[i];
}
y_pix += MAX_SB_SIZE;
input += input_stride;
}
}
// Load from the CfL pixel buffer into output
double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row,
int col, int width, int height) {
const int sub_x = cfl->subsampling_x;
const int sub_y = cfl->subsampling_y;
const int tx_off_log2 = tx_size_wide_log2[0];
void cfl_compute_parameters(MACROBLOCKD *const xd, TX_SIZE tx_size) {
CFL_CTX *const cfl = xd->cfl;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const uint8_t *y_pix;
// Do not call cfl_compute_parameters multiple time on the same values.
assert(cfl->are_parameters_computed == 0);
int diff_width = 0;
int diff_height = 0;
#if CONFIG_CHROMA_SUB8X8
const BLOCK_SIZE plane_bsize = AOMMAX(
BLOCK_4X4, get_plane_block_size(mbmi->sb_type, &xd->plane[AOM_PLANE_U]));
#else
const BLOCK_SIZE plane_bsize =
get_plane_block_size(mbmi->sb_type, &xd->plane[AOM_PLANE_U]);
#endif
// AOM_PLANE_U is used, but both planes will have the same sizes.
cfl->uv_width = max_intra_block_width(xd, plane_bsize, AOM_PLANE_U, tx_size);
cfl->uv_height =
max_intra_block_height(xd, plane_bsize, AOM_PLANE_U, tx_size);
int pred_row_offset = 0;
int output_row_offset = 0;
int top_left, bot_left;
// TODO(ltrudeau) add support for 4:2:2
if (sub_y == 0 && sub_x == 0) {
y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << tx_off_log2];
int uv_width = (col << tx_off_log2) + width;
diff_width = uv_width - cfl->y_width;
int uv_height = (row << tx_off_log2) + height;
diff_height = uv_height - cfl->y_height;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
// In 4:4:4, pixels match 1 to 1
output[output_row_offset + i] = y_pix[pred_row_offset + i];
}
pred_row_offset += MAX_SB_SIZE;
output_row_offset += output_stride;
}
} else if (sub_y == 1 && sub_x == 1) {
y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << (tx_off_log2 + sub_y)];
int uv_width = ((col << tx_off_log2) + width) << sub_x;
diff_width = (uv_width - cfl->y_width) >> sub_x;
int uv_height = ((row << tx_off_log2) + height) << sub_y;
diff_height = (uv_height - cfl->y_height) >> sub_y;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
top_left = (pred_row_offset + i) << sub_y;
bot_left = top_left + MAX_SB_SIZE;
// In 4:2:0, average pixels in 2x2 grid
output[output_row_offset + i] = OD_SHR_ROUND(
y_pix[top_left] + y_pix[top_left + 1] // Top row
+ y_pix[bot_left] + y_pix[bot_left + 1] // Bottom row
,
2);
}
pred_row_offset += MAX_SB_SIZE;
output_row_offset += output_stride;
}
} else {
assert(0); // Unsupported chroma subsampling
#if CONFIG_DEBUG
if (mbmi->sb_type >= BLOCK_8X8) {
assert(cfl->y_width <= cfl->uv_width << cfl->subsampling_x);
assert(cfl->y_height <= cfl->uv_height << cfl->subsampling_y);
}
// Due to frame boundary issues, it is possible that the total area of
// covered by Chroma exceeds that of Luma. When this happens, we write over
// the broken data by repeating the last columns and/or rows.
//
// Note that in order to manage the case where both rows and columns
// overrun,
// we apply rows first. This way, when the rows overrun the bottom of the
// frame, the columns will be copied over them.
if (diff_width > 0) {
int last_pixel;
output_row_offset = width - diff_width;
#endif
for (int j = 0; j < height; j++) {
last_pixel = output_row_offset - 1;
for (int i = 0; i < diff_width; i++) {
output[output_row_offset + i] = output[last_pixel];
}
output_row_offset += output_stride;
}
}
if (diff_height > 0) {
output_row_offset = diff_height * output_stride;
const int last_row_offset = output_row_offset - output_stride;
for (int j = 0; j < diff_height; j++) {
for (int i = 0; i < width; i++) {
output[output_row_offset + i] = output[last_row_offset + i];
}
output_row_offset += output_stride;
}
}
int avg = 0;
output_row_offset = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
avg += output[output_row_offset + i];
}
output_row_offset += output_stride;
}
return avg / (double)(width * height);
// Compute block-level DC_PRED for both chromatic planes.
// DC_PRED replaces beta in the linear model.
cfl_dc_pred(xd, plane_bsize);
// Compute transform-level average on reconstructed luma input.
cfl_compute_averages(cfl, tx_size);
cfl->are_parameters_computed = 1;
}

View file

@ -26,62 +26,66 @@ typedef struct macroblockd MACROBLOCKD;
typedef struct {
// Pixel buffer containing the luma pixels used as prediction for chroma
// TODO(ltrudeau) Convert to uint16 for HBD support
uint8_t y_pix[MAX_SB_SQUARE];
// Pixel buffer containing the downsampled luma pixels used as prediction for
// chroma
// TODO(ltrudeau) Convert to uint16 for HBD support
uint8_t y_down_pix[MAX_SB_SQUARE];
// Height and width of the luma prediction block currently in the pixel buffer
int y_height, y_width;
// Height and width of the chroma prediction block currently associated with
// this context
int uv_height, uv_width;
// Transform level averages of the luma reconstructed values over the entire
// prediction unit
// Fixed point y_averages is Q12.3:
// * Worst case division is 1/1024
// * Max error will be 1/16th.
// Note: 3 is chosen so that y_averages fits in 15 bits when 12 bit input is
// used
int y_averages_q3[MAX_NUM_TXB];
int y_averages_stride;
int are_parameters_computed;
// Chroma subsampling
int subsampling_x, subsampling_y;
// CfL Performs its own block level DC_PRED for each chromatic plane
double dc_pred[CFL_PRED_PLANES];
// Block level DC_PRED for each chromatic plane
int dc_pred[CFL_PRED_PLANES];
// The rate associated with each alpha codeword
int costs[CFL_ALPHABET_SIZE];
// Count the number of TX blocks in a predicted block to know when you are at
// the last one, so you can check for skips.
// TODO(any) Is there a better way to do this?
int num_tx_blk[CFL_PRED_PLANES];
int mi_row, mi_col;
} CFL_CTX;
static const double cfl_alpha_mags[CFL_MAGS_SIZE] = {
0., 0.125, -0.125, 0.25, -0.25, 0.5, -0.5
};
static const int cfl_alpha_mags_q3[CFL_MAGS_SIZE] = { 0, 1, -1, 2, -2, 4, -4 };
static const int cfl_alpha_codes[CFL_ALPHABET_SIZE][CFL_PRED_PLANES] = {
// barrbrain's simple 1D quant ordered by subset 3 likelihood
{ 0, 0 }, { 1, 1 }, { 3, 0 }, { 3, 1 }, { 1, 0 }, { 3, 3 },
{ 0, 1 }, { 5, 5 }, { 5, 3 }, { 1, 3 }, { 5, 3 }, { 3, 5 },
{ 0, 0 }, { 1, 1 }, { 3, 0 }, { 3, 3 }, { 1, 0 }, { 3, 1 },
{ 5, 5 }, { 0, 1 }, { 5, 3 }, { 5, 0 }, { 3, 5 }, { 1, 3 },
{ 0, 3 }, { 5, 1 }, { 1, 5 }, { 0, 5 }
};
void cfl_init(CFL_CTX *cfl, AV1_COMMON *cm, int subsampling_x,
int subsampling_y);
void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
static INLINE double cfl_idx_to_alpha(int alpha_idx, CFL_SIGN_TYPE alpha_sign,
CFL_PRED_TYPE pred_type) {
const int mag_idx = cfl_alpha_codes[alpha_idx][pred_type];
const double abs_alpha = cfl_alpha_mags[mag_idx];
if (alpha_sign == CFL_SIGN_POS) {
return abs_alpha;
} else {
assert(abs_alpha != 0.0);
assert(cfl_alpha_mags[mag_idx + 1] == -abs_alpha);
return -abs_alpha;
}
static INLINE int get_scaled_luma_q0(int alpha_q3, int y_pix, int avg_q3) {
return (alpha_q3 * ((y_pix << 3) - avg_q3) + 32) >> 6;
}
void cfl_predict_block(const CFL_CTX *cfl, uint8_t *dst, int dst_stride,
int row, int col, TX_SIZE tx_size, double dc_pred,
double alpha);
void cfl_init(CFL_CTX *cfl, AV1_COMMON *cm);
void cfl_predict_block(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
int row, int col, TX_SIZE tx_size, int plane);
void cfl_store(CFL_CTX *cfl, const uint8_t *input, int input_stride, int row,
int col, TX_SIZE tx_size);
int col, TX_SIZE tx_size, BLOCK_SIZE bsize);
void cfl_compute_parameters(MACROBLOCKD *const xd, TX_SIZE tx_size);
double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row,
int col, int width, int height);
#endif // AV1_COMMON_CFL_H_

View file

@ -9,14 +9,13 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include "./clpf.h"
#include "./av1_rtcd.h"
#include "./cdef.h"
#include "aom/aom_image.h"
#include "aom_dsp/aom_dsp_common.h"
int av1_clpf_sample(int X, int A, int B, int C, int D, int E, int F, int G,
int H, int s, unsigned int dmp) {
static int clpf_sample(int X, int A, int B, int C, int D, int E, int F, int G,
int H, int s, unsigned int dmp) {
int delta = 1 * constrain(A - X, s, dmp) + 3 * constrain(B - X, s, dmp) +
1 * constrain(C - X, s, dmp) + 3 * constrain(D - X, s, dmp) +
3 * constrain(E - X, s, dmp) + 1 * constrain(F - X, s, dmp) +
@ -24,8 +23,8 @@ int av1_clpf_sample(int X, int A, int B, int C, int D, int E, int F, int G,
return (8 + delta - (delta < 0)) >> 4;
}
int av1_clpf_hsample(int X, int A, int B, int C, int D, int s,
unsigned int dmp) {
static int clpf_hsample(int X, int A, int B, int C, int D, int s,
unsigned int dmp) {
int delta = 1 * constrain(A - X, s, dmp) + 3 * constrain(B - X, s, dmp) +
3 * constrain(C - X, s, dmp) + 1 * constrain(D - X, s, dmp);
return (4 + delta - (delta < 0)) >> 3;
@ -48,7 +47,7 @@ void aom_clpf_block_c(uint8_t *dst, const uint16_t *src, int dstride,
const int G = src[(y + 1) * sstride + x];
const int H = src[(y + 2) * sstride + x];
const int delta =
av1_clpf_sample(X, A, B, C, D, E, F, G, H, strength, damping);
clpf_sample(X, A, B, C, D, E, F, G, H, strength, damping);
dst[y * dstride + x] = X + delta;
}
}
@ -72,7 +71,7 @@ void aom_clpf_block_hbd_c(uint16_t *dst, const uint16_t *src, int dstride,
const int G = src[(y + 1) * sstride + x];
const int H = src[(y + 2) * sstride + x];
const int delta =
av1_clpf_sample(X, A, B, C, D, E, F, G, H, strength, damping);
clpf_sample(X, A, B, C, D, E, F, G, H, strength, damping);
dst[y * dstride + x] = X + delta;
}
}
@ -91,7 +90,7 @@ void aom_clpf_hblock_c(uint8_t *dst, const uint16_t *src, int dstride,
const int B = src[y * sstride + x - 1];
const int C = src[y * sstride + x + 1];
const int D = src[y * sstride + x + 2];
const int delta = av1_clpf_hsample(X, A, B, C, D, strength, damping);
const int delta = clpf_hsample(X, A, B, C, D, strength, damping);
dst[y * dstride + x] = X + delta;
}
}
@ -109,7 +108,7 @@ void aom_clpf_hblock_hbd_c(uint16_t *dst, const uint16_t *src, int dstride,
const int B = src[y * sstride + x - 1];
const int C = src[y * sstride + x + 1];
const int D = src[y * sstride + x + 2];
const int delta = av1_clpf_hsample(X, A, B, C, D, strength, damping);
const int delta = clpf_hsample(X, A, B, C, D, strength, damping);
dst[y * dstride + x] = X + delta;
}
}

View file

@ -1,18 +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_COMMON_CLPF_H_
#define AV1_COMMON_CLPF_H_
#include "av1/common/reconinter.h"
int av1_clpf_sample(int X, int A, int B, int C, int D, int E, int F, int G,
int H, int b, unsigned int dmp);
#endif

File diff suppressed because it is too large Load diff

View file

@ -43,7 +43,7 @@ void av1_convolve_horiz_c(const uint8_t *src, int src_stride, uint8_t *dst,
for (k = 0; k < filter_size; ++k) sum += src_x[k] * x_filter[k];
sum = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
if (conv_params->ref)
if (conv_params->do_average)
dst[x] = ROUND_POWER_OF_TWO(dst[x] + sum, 1);
else
dst[x] = sum;
@ -55,6 +55,39 @@ void av1_convolve_horiz_c(const uint8_t *src, int src_stride, uint8_t *dst,
}
}
void av1_convolve_horiz_scale(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilterParams filter_params,
const int subpel_x_qn, int x_step_qn,
ConvolveParams *conv_params) {
int x, y;
int filter_size = filter_params.taps;
assert(conv_params->round == CONVOLVE_OPT_ROUND);
src -= filter_size / 2 - 1;
for (y = 0; y < h; ++y) {
int x_qn = subpel_x_qn;
for (x = 0; x < w; ++x) {
const uint8_t *const src_x = &src[x_qn >> SCALE_SUBPEL_BITS];
const int x_filter_idx = (x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(x_filter_idx < SUBPEL_SHIFTS);
const int16_t *x_filter =
av1_get_interp_filter_subpel_kernel(filter_params, x_filter_idx);
int k, sum = 0;
for (k = 0; k < filter_size; ++k) sum += src_x[k] * x_filter[k];
sum = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
if (conv_params->do_average)
dst[x] = ROUND_POWER_OF_TWO(dst[x] + sum, 1);
else
dst[x] = sum;
x_qn += x_step_qn;
}
src += src_stride;
dst += dst_stride;
}
}
void av1_convolve_vert_c(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilterParams filter_params,
@ -75,7 +108,7 @@ void av1_convolve_vert_c(const uint8_t *src, int src_stride, uint8_t *dst,
sum += src_y[k * src_stride] * y_filter[k];
sum = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
if (conv_params->ref)
if (conv_params->do_average)
dst[y * dst_stride] = ROUND_POWER_OF_TWO(dst[y * dst_stride] + sum, 1);
else
dst[y * dst_stride] = sum;
@ -87,11 +120,46 @@ void av1_convolve_vert_c(const uint8_t *src, int src_stride, uint8_t *dst,
}
}
void av1_convolve_vert_scale(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilterParams filter_params,
const int subpel_y_qn, int y_step_qn,
ConvolveParams *conv_params) {
int x, y;
int filter_size = filter_params.taps;
assert(conv_params->round == CONVOLVE_OPT_ROUND);
src -= src_stride * (filter_size / 2 - 1);
for (x = 0; x < w; ++x) {
int y_qn = subpel_y_qn;
for (y = 0; y < h; ++y) {
const uint8_t *const src_y =
&src[(y_qn >> SCALE_SUBPEL_BITS) * src_stride];
const int y_filter_idx = (y_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(y_filter_idx < SUBPEL_SHIFTS);
const int16_t *y_filter =
av1_get_interp_filter_subpel_kernel(filter_params, y_filter_idx);
int k, sum = 0;
for (k = 0; k < filter_size; ++k)
sum += src_y[k * src_stride] * y_filter[k];
sum = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
if (conv_params->do_average)
dst[y * dst_stride] = ROUND_POWER_OF_TWO(dst[y * dst_stride] + sum, 1);
else
dst[y * dst_stride] = sum;
y_qn += y_step_qn;
}
++src;
++dst;
}
}
static void convolve_copy(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
ConvolveParams *conv_params) {
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (conv_params->ref == 0) {
if (conv_params->do_average == 0) {
int r;
for (r = 0; r < h; ++r) {
memcpy(dst, src, w);
@ -119,7 +187,7 @@ void av1_convolve_horiz_facade(const uint8_t *src, int src_stride, uint8_t *dst,
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_x =
av1_get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
if (conv_params->ref == 0)
if (conv_params->do_average == 0)
aom_convolve8_horiz(src, src_stride, dst, dst_stride, filter_x, x_step_q4,
NULL, -1, w, h);
else
@ -140,7 +208,7 @@ void av1_convolve_horiz_facade_c(const uint8_t *src, int src_stride,
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_x =
av1_get_interp_filter_subpel_kernel(filter_params, subpel_x_q4);
if (conv_params->ref == 0)
if (conv_params->do_average == 0)
aom_convolve8_horiz_c(src, src_stride, dst, dst_stride, filter_x,
x_step_q4, NULL, -1, w, h);
else
@ -152,6 +220,28 @@ void av1_convolve_horiz_facade_c(const uint8_t *src, int src_stride,
}
}
void av1_convolve_horiz_facade_scale(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
const InterpFilterParams filter_params,
const int subpel_x_qn, int x_step_qn,
ConvolveParams *conv_params) {
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_x = av1_get_interp_filter_subpel_kernel(
filter_params, subpel_x_qn >> SCALE_EXTRA_BITS);
if (conv_params->do_average == 0)
aom_convolve8_horiz_scale(src, src_stride, dst, dst_stride, filter_x,
subpel_x_qn, x_step_qn, NULL, 0, -1, w, h);
else
aom_convolve8_avg_horiz_scale(src, src_stride, dst, dst_stride, filter_x,
subpel_x_qn, x_step_qn, NULL, 0, -1, w, h);
} else {
av1_convolve_horiz_scale(src, src_stride, dst, dst_stride, w, h,
filter_params, subpel_x_qn, x_step_qn,
conv_params);
}
}
void av1_convolve_vert_facade(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilterParams filter_params,
@ -161,7 +251,7 @@ void av1_convolve_vert_facade(const uint8_t *src, int src_stride, uint8_t *dst,
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_y =
av1_get_interp_filter_subpel_kernel(filter_params, subpel_y_q4);
if (conv_params->ref == 0) {
if (conv_params->do_average == 0) {
aom_convolve8_vert(src, src_stride, dst, dst_stride, NULL, -1, filter_y,
y_step_q4, w, h);
} else {
@ -183,7 +273,7 @@ void av1_convolve_vert_facade_c(const uint8_t *src, int src_stride,
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_y =
av1_get_interp_filter_subpel_kernel(filter_params, subpel_y_q4);
if (conv_params->ref == 0) {
if (conv_params->do_average == 0) {
aom_convolve8_vert_c(src, src_stride, dst, dst_stride, NULL, -1, filter_y,
y_step_q4, w, h);
} else {
@ -196,52 +286,71 @@ void av1_convolve_vert_facade_c(const uint8_t *src, int src_stride,
}
}
void av1_convolve_vert_facade_scale(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
const InterpFilterParams filter_params,
const int subpel_y_qn, int y_step_qn,
ConvolveParams *conv_params) {
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (filter_params.taps == SUBPEL_TAPS) {
const int16_t *filter_y = av1_get_interp_filter_subpel_kernel(
filter_params, subpel_y_qn >> SCALE_EXTRA_BITS);
if (conv_params->do_average == 0) {
aom_convolve8_vert_scale(src, src_stride, dst, dst_stride, NULL, 0, -1,
filter_y, subpel_y_qn, y_step_qn, w, h);
} else {
aom_convolve8_avg_vert_scale(src, src_stride, dst, dst_stride, NULL, 0,
-1, filter_y, subpel_y_qn, y_step_qn, w, h);
}
} else {
av1_convolve_vert_scale(src, src_stride, dst, dst_stride, w, h,
filter_params, subpel_y_qn, y_step_qn, conv_params);
}
}
#if CONFIG_CONVOLVE_ROUND
void av1_convolve_rounding(const int32_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h, int bits) {
void av1_convolve_rounding_c(const int32_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h, int bits) {
int r, c;
for (r = 0; r < h; ++r) {
for (c = 0; c < w; ++c) {
dst[r * dst_stride + c] =
clip_pixel(ROUND_POWER_OF_TWO_SIGNED(src[r * src_stride + c], bits));
clip_pixel(ROUND_POWER_OF_TWO(src[r * src_stride + c], bits));
}
}
}
void av1_convolve_2d(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y, const int subpel_x_q4,
const int subpel_y_q4, ConvolveParams *conv_params) {
#if CONFIG_COMPOUND_ROUND
void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params) {
int x, y, k;
CONV_BUF_TYPE im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
uint8_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
(void)conv_params;
// horizontal filter
const uint8_t *src_horiz = src - fo_vert * src_stride;
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
for (y = 0; y < im_h; ++y) {
for (x = 0; x < w; ++x) {
CONV_BUF_TYPE sum = 0;
int32_t sum = 0;
for (k = 0; k < filter_params_x->taps; ++k) {
sum += x_filter[k] * src_horiz[y * src_stride + x - fo_horiz + k];
}
#if CONFIG_COMPOUND_ROUND
im_block[y * im_stride + x] =
clip_pixel(ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_0));
#else
im_block[y * im_stride + x] =
ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_0);
#endif
clip_pixel(ROUND_POWER_OF_TWO(sum, conv_params->round_0));
}
}
// vertical filter
CONV_BUF_TYPE *src_vert = im_block + fo_vert * im_stride;
uint8_t *src_vert = im_block + fo_vert * im_stride;
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
for (y = 0; y < h; ++y) {
@ -250,11 +359,68 @@ void av1_convolve_2d(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
for (k = 0; k < filter_params_y->taps; ++k) {
sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x];
}
dst[y * dst_stride + x] +=
ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_1);
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1);
dst[y * dst_stride + x] += res;
}
}
}
#else
/* When convolve-round is enabled and compound-round is disabled, we use a
high-precision convolve filter.
Note: For notes on hardware implementations, including the required
bit widths for various intermediate values, see the comments above
av1_warp_affine_c.
*/
void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params) {
int x, y, k;
int32_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const int bd = 8;
// horizontal filter
const uint8_t *src_horiz = src - fo_vert * src_stride;
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
for (y = 0; y < im_h; ++y) {
for (x = 0; x < w; ++x) {
int32_t sum = (1 << (bd + FILTER_BITS - 1));
for (k = 0; k < filter_params_x->taps; ++k) {
sum += x_filter[k] * src_horiz[y * src_stride + x - fo_horiz + k];
}
assert(0 <= sum && sum < (1 << (bd + FILTER_BITS + 1)));
im_block[y * im_stride + x] =
ROUND_POWER_OF_TWO(sum, conv_params->round_0);
}
}
// vertical filter
int32_t *src_vert = im_block + fo_vert * im_stride;
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
const int offset_bits = bd + 2 * FILTER_BITS - conv_params->round_0;
for (y = 0; y < h; ++y) {
for (x = 0; x < w; ++x) {
CONV_BUF_TYPE sum = 1 << offset_bits;
for (k = 0; k < filter_params_y->taps; ++k) {
sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x];
}
assert(0 <= sum && sum < (1 << (offset_bits + 2)));
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
((1 << (offset_bits - conv_params->round_1)) +
(1 << (offset_bits - conv_params->round_1 - 1)));
dst[y * dst_stride + x] += res;
}
}
}
#endif
static INLINE void transpose_uint8(uint8_t *dst, int dst_stride,
const uint8_t *src, int src_stride, int w,
@ -342,55 +508,50 @@ static INLINE void transpose_uint16(uint16_t *dst, int dst_stride,
for (c = 0; c < w; ++c) dst[c * dst_stride + r] = src[r * src_stride + c];
}
void av1_highbd_convolve_rounding(const int32_t *src, int src_stride,
uint8_t *dst8, int dst_stride, int w, int h,
int bits, int bd) {
void av1_highbd_convolve_rounding_c(const int32_t *src, int src_stride,
uint8_t *dst8, int dst_stride, int w, int h,
int bits, int bd) {
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
int r, c;
for (r = 0; r < h; ++r) {
for (c = 0; c < w; ++c) {
dst[r * dst_stride + c] = clip_pixel_highbd(
ROUND_POWER_OF_TWO_SIGNED(src[r * src_stride + c], bits), bd);
ROUND_POWER_OF_TWO(src[r * src_stride + c], bits), bd);
}
}
}
void av1_highbd_convolve_2d(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd) {
#if CONFIG_COMPOUND_ROUND
void av1_highbd_convolve_2d_c(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd) {
int x, y, k;
CONV_BUF_TYPE im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
uint16_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
(void)conv_params;
// horizontal filter
const uint16_t *src_horiz = src - fo_vert * src_stride;
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
for (y = 0; y < im_h; ++y) {
for (x = 0; x < w; ++x) {
CONV_BUF_TYPE sum = 0;
int32_t sum = 0;
for (k = 0; k < filter_params_x->taps; ++k) {
sum += x_filter[k] * src_horiz[y * src_stride + x - fo_horiz + k];
}
#if CONFIG_COMPOUND_ROUND
im_block[y * im_stride + x] = clip_pixel_highbd(
ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_0), bd);
#else
(void)bd;
im_block[y * im_stride + x] =
ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_0);
#endif
clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, conv_params->round_0), bd);
}
}
// vertical filter
CONV_BUF_TYPE *src_vert = im_block + fo_vert * im_stride;
uint16_t *src_vert = im_block + fo_vert * im_stride;
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
for (y = 0; y < h; ++y) {
@ -399,11 +560,62 @@ void av1_highbd_convolve_2d(const uint16_t *src, int src_stride,
for (k = 0; k < filter_params_y->taps; ++k) {
sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x];
}
dst[y * dst_stride + x] +=
ROUND_POWER_OF_TWO_SIGNED(sum, conv_params->round_1);
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1);
dst[y * dst_stride + x] += res;
}
}
}
#else
void av1_highbd_convolve_2d_c(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd) {
int x, y, k;
int32_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
// horizontal filter
const uint16_t *src_horiz = src - fo_vert * src_stride;
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
for (y = 0; y < im_h; ++y) {
for (x = 0; x < w; ++x) {
int32_t sum = (1 << (bd + FILTER_BITS - 1));
for (k = 0; k < filter_params_x->taps; ++k) {
sum += x_filter[k] * src_horiz[y * src_stride + x - fo_horiz + k];
}
assert(0 <= sum && sum < (1 << (bd + FILTER_BITS + 1)));
(void)bd;
im_block[y * im_stride + x] =
ROUND_POWER_OF_TWO(sum, conv_params->round_0);
}
}
// vertical filter
int32_t *src_vert = im_block + fo_vert * im_stride;
const int offset_bits = bd + 2 * FILTER_BITS - conv_params->round_0;
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
for (y = 0; y < h; ++y) {
for (x = 0; x < w; ++x) {
CONV_BUF_TYPE sum = 1 << offset_bits;
for (k = 0; k < filter_params_y->taps; ++k) {
sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x];
}
assert(0 <= sum && sum < (1 << (offset_bits + 2)));
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
((1 << (offset_bits - conv_params->round_1)) +
(1 << (offset_bits - conv_params->round_1 - 1)));
dst[y * dst_stride + x] += res;
}
}
}
#endif
void av1_highbd_convolve_2d_facade(const uint8_t *src8, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
@ -487,8 +699,8 @@ static void convolve_helper(const uint8_t *src, int src_stride, uint8_t *dst,
ConvolveParams *conv_params,
ConvolveFunc convolve_horiz,
ConvolveFunc convolve_vert) {
int ignore_horiz = x_step_q4 == 16 && subpel_x_q4 == 0;
int ignore_vert = y_step_q4 == 16 && subpel_y_q4 == 0;
int ignore_horiz = x_step_q4 == SUBPEL_SHIFTS && subpel_x_q4 == 0;
int ignore_vert = y_step_q4 == SUBPEL_SHIFTS && subpel_y_q4 == 0;
#if CONFIG_DUAL_FILTER
InterpFilterParams filter_params_x =
av1_get_interp_filter_params(interp_filter[1 + 2 * conv_params->ref]);
@ -545,6 +757,7 @@ static void convolve_helper(const uint8_t *src, int src_stride, uint8_t *dst,
int temp_stride = max_intermediate_size;
ConvolveParams temp_conv_params;
temp_conv_params.ref = 0;
temp_conv_params.do_average = 0;
temp_conv_params.round = CONVOLVE_OPT_ROUND;
filter_params = filter_params_y;
filter_size = filter_params_x.taps;
@ -569,6 +782,7 @@ static void convolve_helper(const uint8_t *src, int src_stride, uint8_t *dst,
int temp_stride = MAX_SB_SIZE;
ConvolveParams temp_conv_params;
temp_conv_params.ref = 0;
temp_conv_params.do_average = 0;
temp_conv_params.round = CONVOLVE_OPT_ROUND;
#if CONFIG_DUAL_FILTER
filter_params = filter_params_x;
@ -599,6 +813,135 @@ static void convolve_helper(const uint8_t *src, int src_stride, uint8_t *dst,
}
}
static void convolve_scale_helper(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
const InterpFilter interp_filter,
#endif
const int subpel_x_qn, int x_step_qn,
const int subpel_y_qn, int y_step_qn,
ConvolveParams *conv_params,
ConvolveFunc convolve_horiz,
ConvolveFunc convolve_vert) {
int ignore_horiz = x_step_qn == SCALE_SUBPEL_SHIFTS && subpel_x_qn == 0;
int ignore_vert = y_step_qn == SCALE_SUBPEL_SHIFTS && subpel_y_qn == 0;
#if CONFIG_DUAL_FILTER
InterpFilterParams filter_params_x =
av1_get_interp_filter_params(interp_filter[1 + 2 * conv_params->ref]);
InterpFilterParams filter_params_y =
av1_get_interp_filter_params(interp_filter[0 + 2 * conv_params->ref]);
InterpFilterParams filter_params;
#else
InterpFilterParams filter_params =
av1_get_interp_filter_params(interp_filter);
#endif
assert(conv_params->round == CONVOLVE_OPT_ROUND);
assert(w <= MAX_BLOCK_WIDTH);
assert(h <= MAX_BLOCK_HEIGHT);
assert(y_step_qn <= (MAX_STEP << SCALE_EXTRA_BITS));
assert(x_step_qn <= (MAX_STEP << SCALE_EXTRA_BITS));
if (ignore_horiz && ignore_vert) {
convolve_copy(src, src_stride, dst, dst_stride, w, h, conv_params);
} else if (ignore_vert) {
#if CONFIG_DUAL_FILTER
filter_params = filter_params_x;
#endif
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_horiz(src, src_stride, dst, dst_stride, w, h, filter_params,
subpel_x_qn, x_step_qn, conv_params);
} else if (ignore_horiz) {
#if CONFIG_DUAL_FILTER
filter_params = filter_params_y;
#endif
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_vert(src, src_stride, dst, dst_stride, w, h, filter_params,
subpel_y_qn, y_step_qn, conv_params);
} else {
// temp's size is set to a 256 aligned value to facilitate SIMD
// implementation. The value is greater than (maximum possible intermediate
// height or width) * MAX_SB_SIZE
DECLARE_ALIGNED(16, uint8_t,
temp[((MAX_SB_SIZE * 2 + 16) + 16) * MAX_SB_SIZE]);
int max_intermediate_size = ((MAX_SB_SIZE * 2 + 16) + 16);
int filter_size;
#if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
if (interp_filter[0 + 2 * conv_params->ref] == MULTITAP_SHARP &&
interp_filter[1 + 2 * conv_params->ref] == MULTITAP_SHARP) {
// Avoid two directions both using 12-tap filter.
// This will reduce hardware implementation cost.
filter_params_y = av1_get_interp_filter_params(EIGHTTAP_SHARP);
}
// we do filter with fewer taps first to reduce hardware implementation
// complexity
if (filter_params_y.taps < filter_params_x.taps) {
int intermediate_width;
int temp_stride = max_intermediate_size;
ConvolveParams temp_conv_params;
temp_conv_params.ref = 0;
temp_conv_params.do_average = 0;
temp_conv_params.round = CONVOLVE_OPT_ROUND;
filter_params = filter_params_y;
filter_size = filter_params_x.taps;
intermediate_width =
(((w - 1) * x_step_qn + subpel_x_qn) >> SCALE_SUBPEL_BITS) +
filter_size;
assert(intermediate_width <= max_intermediate_size);
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_vert(src - (filter_size / 2 - 1), src_stride, temp, temp_stride,
intermediate_width, h, filter_params, subpel_y_qn,
y_step_qn, &temp_conv_params);
filter_params = filter_params_x;
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_horiz(temp + (filter_size / 2 - 1), temp_stride, dst, dst_stride,
w, h, filter_params, subpel_x_qn, x_step_qn, conv_params);
} else {
#endif // CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
int intermediate_height;
int temp_stride = MAX_SB_SIZE;
ConvolveParams temp_conv_params;
temp_conv_params.ref = 0;
temp_conv_params.do_average = 0;
temp_conv_params.round = CONVOLVE_OPT_ROUND;
#if CONFIG_DUAL_FILTER
filter_params = filter_params_x;
filter_size = filter_params_y.taps;
#else
filter_size = filter_params.taps;
#endif
intermediate_height =
(((h - 1) * y_step_qn + subpel_y_qn) >> SCALE_SUBPEL_BITS) +
filter_size;
assert(intermediate_height <= max_intermediate_size);
(void)max_intermediate_size;
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_horiz(src - src_stride * (filter_size / 2 - 1), src_stride, temp,
temp_stride, w, intermediate_height, filter_params,
subpel_x_qn, x_step_qn, &temp_conv_params);
#if CONFIG_DUAL_FILTER
filter_params = filter_params_y;
#endif
assert(filter_params.taps <= MAX_FILTER_TAP);
convolve_vert(temp + temp_stride * (filter_size / 2 - 1), temp_stride,
dst, dst_stride, w, h, filter_params, subpel_y_qn,
y_step_qn, conv_params);
#if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
}
#endif // CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
}
}
void av1_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
@ -627,6 +970,22 @@ void av1_convolve_c(const uint8_t *src, int src_stride, uint8_t *dst,
av1_convolve_horiz_facade_c, av1_convolve_vert_facade_c);
}
void av1_convolve_scale(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
const InterpFilter interp_filter,
#endif
const int subpel_x_qn, int x_step_qn,
const int subpel_y_qn, int y_step_qn,
ConvolveParams *conv_params) {
convolve_scale_helper(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x_qn, x_step_qn, subpel_y_qn, y_step_qn,
conv_params, av1_convolve_horiz_facade_scale,
av1_convolve_vert_facade_scale);
}
void av1_lowbd_convolve_init_c(void) {
// A placeholder for SIMD initialization
return;
@ -681,6 +1040,39 @@ void av1_highbd_convolve_horiz_c(const uint16_t *src, int src_stride,
}
}
void av1_highbd_convolve_horiz_scale(const uint16_t *src, int src_stride,
uint16_t *dst, int dst_stride, int w,
int h,
const InterpFilterParams filter_params,
const int subpel_x_qn, int x_step_qn,
int avg, int bd) {
int x, y;
int filter_size = filter_params.taps;
src -= filter_size / 2 - 1;
for (y = 0; y < h; ++y) {
int x_qn = subpel_x_qn;
for (x = 0; x < w; ++x) {
const uint16_t *const src_x = &src[x_qn >> SCALE_SUBPEL_BITS];
const int x_filter_idx = (x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(x_filter_idx < SUBPEL_SHIFTS);
const int16_t *x_filter =
av1_get_interp_filter_subpel_kernel(filter_params, x_filter_idx);
int k, sum = 0;
for (k = 0; k < filter_size; ++k) sum += src_x[k] * x_filter[k];
if (avg)
dst[x] = ROUND_POWER_OF_TWO(
dst[x] +
clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd),
1);
else
dst[x] = clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
x_qn += x_step_qn;
}
src += src_stride;
dst += dst_stride;
}
}
void av1_highbd_convolve_vert_c(const uint16_t *src, int src_stride,
uint16_t *dst, int dst_stride, int w, int h,
const InterpFilterParams filter_params,
@ -715,6 +1107,43 @@ void av1_highbd_convolve_vert_c(const uint16_t *src, int src_stride,
}
}
void av1_highbd_convolve_vert_scale(const uint16_t *src, int src_stride,
uint16_t *dst, int dst_stride, int w, int h,
const InterpFilterParams filter_params,
const int subpel_y_qn, int y_step_qn,
int avg, int bd) {
int x, y;
int filter_size = filter_params.taps;
src -= src_stride * (filter_size / 2 - 1);
for (x = 0; x < w; ++x) {
int y_qn = subpel_y_qn;
for (y = 0; y < h; ++y) {
const uint16_t *const src_y =
&src[(y_qn >> SCALE_SUBPEL_BITS) * src_stride];
const int y_filter_idx = (y_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(y_filter_idx < SUBPEL_SHIFTS);
const int16_t *y_filter =
av1_get_interp_filter_subpel_kernel(filter_params, y_filter_idx);
int k, sum = 0;
for (k = 0; k < filter_size; ++k)
sum += src_y[k * src_stride] * y_filter[k];
if (avg) {
dst[y * dst_stride] = ROUND_POWER_OF_TWO(
dst[y * dst_stride] +
clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd),
1);
} else {
dst[y * dst_stride] =
clip_pixel_highbd(ROUND_POWER_OF_TWO(sum, FILTER_BITS), bd);
}
y_qn += y_step_qn;
}
++src;
++dst;
}
}
static void highbd_convolve_copy(const uint16_t *src, int src_stride,
uint16_t *dst, int dst_stride, int w, int h,
int avg, int bd) {
@ -760,6 +1189,19 @@ void av1_highbd_convolve_horiz_facade(const uint8_t *src8, int src_stride,
}
}
void av1_highbd_convolve_horiz_facade_scale(
const uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride, int w,
int h, const InterpFilterParams filter_params, const int subpel_x_qn,
int x_step_qn, int avg, int bd) {
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
// TODO(debargha): Add special functions for filter_params.taps == SUBPEL_TAPS
// as in the function above.
av1_highbd_convolve_horiz_scale(src, src_stride, dst, dst_stride, w, h,
filter_params, subpel_x_qn, x_step_qn, avg,
bd);
}
void av1_highbd_convolve_vert_facade(const uint8_t *src8, int src_stride,
uint8_t *dst8, int dst_stride, int w,
int h,
@ -785,6 +1227,19 @@ void av1_highbd_convolve_vert_facade(const uint8_t *src8, int src_stride,
}
}
void av1_highbd_convolve_vert_facade_scale(
const uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride, int w,
int h, const InterpFilterParams filter_params, const int subpel_y_qn,
int y_step_qn, int avg, int bd) {
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
// TODO(debargha): Add special functions for filter_params.taps == SUBPEL_TAPS
// as in the function above.
av1_highbd_convolve_vert_scale(src, src_stride, dst, dst_stride, w, h,
filter_params, subpel_y_qn, y_step_qn, avg,
bd);
}
void av1_highbd_convolve(const uint8_t *src8, int src_stride, uint8_t *dst8,
int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
@ -797,8 +1252,8 @@ void av1_highbd_convolve(const uint8_t *src8, int src_stride, uint8_t *dst8,
int bd) {
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
int ignore_horiz = x_step_q4 == 16 && subpel_x_q4 == 0;
int ignore_vert = y_step_q4 == 16 && subpel_y_q4 == 0;
int ignore_horiz = x_step_q4 == SUBPEL_SHIFTS && subpel_x_q4 == 0;
int ignore_vert = y_step_q4 == SUBPEL_SHIFTS && subpel_y_q4 == 0;
assert(w <= MAX_BLOCK_WIDTH);
assert(h <= MAX_BLOCK_HEIGHT);
@ -908,4 +1363,131 @@ void av1_highbd_convolve(const uint8_t *src8, int src_stride, uint8_t *dst8,
}
}
}
void av1_highbd_convolve_scale(const uint8_t *src8, int src_stride,
uint8_t *dst8, int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
const InterpFilter interp_filter,
#endif
const int subpel_x_qn, int x_step_qn,
const int subpel_y_qn, int y_step_qn,
int ref_idx, int bd) {
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
int ignore_horiz = x_step_qn == SCALE_SUBPEL_SHIFTS && subpel_x_qn == 0;
int ignore_vert = y_step_qn == SCALE_SUBPEL_SHIFTS && subpel_y_qn == 0;
assert(w <= MAX_BLOCK_WIDTH);
assert(h <= MAX_BLOCK_HEIGHT);
assert(y_step_qn <= (MAX_STEP << SCALE_EXTRA_BITS));
assert(x_step_qn <= (MAX_STEP << SCALE_EXTRA_BITS));
if (ignore_horiz && ignore_vert) {
highbd_convolve_copy(src, src_stride, dst, dst_stride, w, h, ref_idx, bd);
} else if (ignore_vert) {
#if CONFIG_DUAL_FILTER
InterpFilterParams filter_params =
av1_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
#else
InterpFilterParams filter_params =
av1_get_interp_filter_params(interp_filter);
#endif
av1_highbd_convolve_horiz_facade_scale(src8, src_stride, dst8, dst_stride,
w, h, filter_params, subpel_x_qn,
x_step_qn, ref_idx, bd);
} else if (ignore_horiz) {
#if CONFIG_DUAL_FILTER
InterpFilterParams filter_params =
av1_get_interp_filter_params(interp_filter[0 + 2 * ref_idx]);
#else
InterpFilterParams filter_params =
av1_get_interp_filter_params(interp_filter);
#endif
av1_highbd_convolve_vert_facade_scale(src8, src_stride, dst8, dst_stride, w,
h, filter_params, subpel_y_qn,
y_step_qn, ref_idx, bd);
} else {
// temp's size is set to a 256 aligned value to facilitate SIMD
// implementation. The value is greater than (maximum possible intermediate
// height or width) * MAX_SB_SIZE
DECLARE_ALIGNED(16, uint16_t,
temp[((MAX_SB_SIZE * 2 + 16) + 16) * MAX_SB_SIZE]);
uint8_t *temp8 = CONVERT_TO_BYTEPTR(temp);
int max_intermediate_size = ((MAX_SB_SIZE * 2 + 16) + 16);
int filter_size;
InterpFilterParams filter_params;
#if CONFIG_DUAL_FILTER
InterpFilterParams filter_params_x =
av1_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
InterpFilterParams filter_params_y =
av1_get_interp_filter_params(interp_filter[0 + 2 * ref_idx]);
#endif
#if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
if (interp_filter[0 + 2 * ref_idx] == MULTITAP_SHARP &&
interp_filter[1 + 2 * ref_idx] == MULTITAP_SHARP) {
// Avoid two directions both using 12-tap filter.
// This will reduce hardware implementation cost.
filter_params_y = av1_get_interp_filter_params(EIGHTTAP_SHARP);
}
if (filter_params_y.taps < filter_params_x.taps) {
int intermediate_width;
int temp_stride = max_intermediate_size;
filter_params = filter_params_y;
filter_size = filter_params_x.taps;
intermediate_width =
(((w - 1) * x_step_qn + subpel_x_qn) >> SCALE_SUBPEL_BITS) +
filter_size;
assert(intermediate_width <= max_intermediate_size);
assert(filter_params.taps <= MAX_FILTER_TAP);
av1_highbd_convolve_vert_facade_scale(
src8 - (filter_size / 2 - 1), src_stride, temp8, temp_stride,
intermediate_width, h, filter_params, subpel_y_qn, y_step_qn, 0, bd);
filter_params = filter_params_x;
assert(filter_params.taps <= MAX_FILTER_TAP);
av1_highbd_convolve_horiz_facade_scale(
temp8 + (filter_size / 2 - 1), temp_stride, dst8, dst_stride, w, h,
filter_params, subpel_x_qn, x_step_qn, ref_idx, bd);
} else {
#endif // CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
int intermediate_height;
int temp_stride = MAX_SB_SIZE;
#if CONFIG_DUAL_FILTER
filter_params = filter_params_x;
filter_size = filter_params_y.taps;
#else
filter_params = av1_get_interp_filter_params(interp_filter);
filter_size = filter_params.taps;
#endif
intermediate_height =
(((h - 1) * y_step_qn + subpel_y_qn) >> SCALE_SUBPEL_BITS) +
filter_size;
assert(intermediate_height <= max_intermediate_size);
(void)max_intermediate_size;
av1_highbd_convolve_horiz_facade_scale(
src8 - src_stride * (filter_size / 2 - 1), src_stride, temp8,
temp_stride, w, intermediate_height, filter_params, subpel_x_qn,
x_step_qn, 0, bd);
#if CONFIG_DUAL_FILTER
filter_params = filter_params_y;
#endif
filter_size = filter_params.taps;
assert(filter_params.taps <= MAX_FILTER_TAP);
av1_highbd_convolve_vert_facade_scale(
temp8 + temp_stride * (filter_size / 2 - 1), temp_stride, dst8,
dst_stride, w, h, filter_params, subpel_y_qn, y_step_qn, ref_idx, bd);
#if CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
}
#endif // CONFIG_DUAL_FILTER && USE_EXTRA_FILTER
}
}
#endif // CONFIG_HIGHBITDEPTH

View file

@ -27,6 +27,7 @@ typedef int32_t CONV_BUF_TYPE;
typedef struct ConvolveParams {
int ref;
int do_average;
CONVOLVE_OPT round;
CONV_BUF_TYPE *dst;
int dst_stride;
@ -36,9 +37,11 @@ typedef struct ConvolveParams {
int do_post_rounding;
} ConvolveParams;
static INLINE ConvolveParams get_conv_params(int ref, int plane) {
static INLINE ConvolveParams get_conv_params(int ref, int do_average,
int plane) {
ConvolveParams conv_params;
conv_params.ref = ref;
conv_params.do_average = do_average;
conv_params.round = CONVOLVE_OPT_ROUND;
conv_params.plane = plane;
conv_params.do_post_rounding = 0;
@ -47,12 +50,6 @@ static INLINE ConvolveParams get_conv_params(int ref, int plane) {
struct AV1Common;
void av1_convolve_init(struct AV1Common *cm);
#if CONFIG_CONVOLVE_ROUND
void av1_convolve_2d(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y, const int subpel_x_q4,
const int subpel_y_q4, ConvolveParams *conv_params);
void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
const InterpFilter *interp_filter,
@ -60,11 +57,12 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst,
const int subpel_y_q4, int y_step_q4,
ConvolveParams *conv_params);
static INLINE ConvolveParams get_conv_params_no_round(int ref, int plane,
int32_t *dst,
static INLINE ConvolveParams get_conv_params_no_round(int ref, int do_average,
int plane, int32_t *dst,
int dst_stride) {
ConvolveParams conv_params;
conv_params.ref = ref;
conv_params.do_average = do_average;
conv_params.round = CONVOLVE_OPT_NO_ROUND;
#if CONFIG_COMPOUND_ROUND
conv_params.round_0 = FILTER_BITS;
@ -79,21 +77,7 @@ static INLINE ConvolveParams get_conv_params_no_round(int ref, int plane,
return conv_params;
}
void av1_convolve_rounding(const int32_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h, int bits);
#if CONFIG_HIGHBITDEPTH
void av1_highbd_convolve_rounding(const int32_t *src, int src_stride,
uint8_t *dst8, int dst_stride, int w, int h,
int bits, int bd);
void av1_highbd_convolve_2d(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd);
void av1_highbd_convolve_2d_facade(const uint8_t *src8, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
const InterpFilter *interp_filter,
@ -123,6 +107,16 @@ void av1_convolve_c(const uint8_t *src, int src_stride, uint8_t *dst,
const int subpel_x, int xstep, const int subpel_y,
int ystep, ConvolveParams *conv_params);
void av1_convolve_scale(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
const InterpFilter interp_filter,
#endif
const int subpel_x, int xstep, const int subpel_y,
int ystep, ConvolveParams *conv_params);
#if CONFIG_HIGHBITDEPTH
void av1_highbd_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
@ -133,6 +127,16 @@ void av1_highbd_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
#endif
const int subpel_x, int xstep, const int subpel_y,
int ystep, int avg, int bd);
void av1_highbd_convolve_scale(const uint8_t *src, int src_stride, uint8_t *dst,
int dst_stride, int w, int h,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
const InterpFilter interp_filter,
#endif // CONFIG_DUAL_FILTER
const int subpel_x, int xstep,
const int subpel_y, int ystep, int avg, int bd);
#endif // CONFIG_HIGHBITDEPTH
#ifdef __cplusplus

591
third_party/aom/av1/common/daala_tx.c vendored Normal file
View file

@ -0,0 +1,591 @@
#include "av1/common/daala_tx.h"
#include "av1/common/odintrin.h"
/* clang-format off */
# define OD_DCT_RSHIFT(_a, _b) OD_UNBIASED_RSHIFT32(_a, _b)
/* TODO: Daala DCT overflow checks need to be ported as a later test */
# if defined(OD_DCT_CHECK_OVERFLOW)
# else
# define OD_DCT_OVERFLOW_CHECK(val, scale, offset, idx)
# endif
#define OD_FDCT_2(p0, p1) \
/* Embedded 2-point orthonormal Type-II fDCT. */ \
do { \
/* 13573/32768 ~= Tan[pi/8] ~= 0.414213562373095 */ \
OD_DCT_OVERFLOW_CHECK(p1, 13573, 16384, 100); \
p0 -= (p1*13573 + 16384) >> 15; \
/* 5793/8192 ~= Sin[pi/4] ~= 0.707106781186547 */ \
OD_DCT_OVERFLOW_CHECK(p0, 5793, 4096, 101); \
p1 += (p0*5793 + 4096) >> 13; \
/* 3393/8192 ~= Tan[pi/8] ~= 0.414213562373095 */ \
OD_DCT_OVERFLOW_CHECK(p1, 3393, 4096, 102); \
p0 -= (p1*3393 + 4096) >> 13; \
} \
while (0)
#define OD_IDCT_2(p0, p1) \
/* Embedded 2-point orthonormal Type-II iDCT. */ \
do { \
/* 3393/8192 ~= Tan[pi/8] ~= 0.414213562373095 */ \
p0 += (p1*3393 + 4096) >> 13; \
/* 5793/8192 ~= Sin[pi/4] ~= 0.707106781186547 */ \
p1 -= (p0*5793 + 4096) >> 13; \
/* 13573/32768 ~= Tan[pi/8] ~= 0.414213562373095 */ \
p0 += (p1*13573 + 16384) >> 15; \
} \
while (0)
#define OD_FDCT_2_ASYM(p0, p1, p1h) \
/* Embedded 2-point asymmetric Type-II fDCT. */ \
do { \
p0 += p1h; \
p1 = p0 - p1; \
} \
while (0)
#define OD_IDCT_2_ASYM(p0, p1, p1h) \
/* Embedded 2-point asymmetric Type-II iDCT. */ \
do { \
p1 = p0 - p1; \
p1h = OD_DCT_RSHIFT(p1, 1); \
p0 -= p1h; \
} \
while (0)
#define OD_FDST_2(p0, p1) \
/* Embedded 2-point orthonormal Type-IV fDST. */ \
do { \
/* 10947/16384 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
OD_DCT_OVERFLOW_CHECK(p1, 10947, 8192, 103); \
p0 -= (p1*10947 + 8192) >> 14; \
/* 473/512 ~= Sin[3*Pi/8] ~= 0.923879532511287 */ \
OD_DCT_OVERFLOW_CHECK(p0, 473, 256, 104); \
p1 += (p0*473 + 256) >> 9; \
/* 10947/16384 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
OD_DCT_OVERFLOW_CHECK(p1, 10947, 8192, 105); \
p0 -= (p1*10947 + 8192) >> 14; \
} \
while (0)
#define OD_IDST_2(p0, p1) \
/* Embedded 2-point orthonormal Type-IV iDST. */ \
do { \
/* 10947/16384 ~= Tan[3*Pi/16]) ~= 0.668178637919299 */ \
p0 += (p1*10947 + 8192) >> 14; \
/* 473/512 ~= Sin[3*Pi/8] ~= 0.923879532511287 */ \
p1 -= (p0*473 + 256) >> 9; \
/* 10947/16384 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
p0 += (p1*10947 + 8192) >> 14; \
} \
while (0)
#define OD_FDST_2_ASYM(p0, p1) \
/* Embedded 2-point asymmetric Type-IV fDST. */ \
do { \
/* 11507/16384 ~= 4*Sin[Pi/8] - 2*Tan[Pi/8] ~= 0.702306604714169 */ \
OD_DCT_OVERFLOW_CHECK(p1, 11507, 8192, 187); \
p0 -= (p1*11507 + 8192) >> 14; \
/* 669/1024 ~= Cos[Pi/8]/Sqrt[2] ~= 0.653281482438188 */ \
OD_DCT_OVERFLOW_CHECK(p0, 669, 512, 188); \
p1 += (p0*669 + 512) >> 10; \
/* 4573/4096 ~= 4*Sin[Pi/8] - Tan[Pi/8] ~= 1.11652016708726 */ \
OD_DCT_OVERFLOW_CHECK(p1, 4573, 2048, 189); \
p0 -= (p1*4573 + 2048) >> 12; \
} \
while (0)
#define OD_IDST_2_ASYM(p0, p1) \
/* Embedded 2-point asymmetric Type-IV iDST. */ \
do { \
/* 4573/4096 ~= 4*Sin[Pi/8] - Tan[Pi/8] ~= 1.11652016708726 */ \
p0 += (p1*4573 + 2048) >> 12; \
/* 669/1024 ~= Cos[Pi/8]/Sqrt[2] ~= 0.653281482438188 */ \
p1 -= (p0*669 + 512) >> 10; \
/* 11507/16384 ~= 4*Sin[Pi/8] - 2*Tan[Pi/8] ~= 0.702306604714169 */ \
p0 += (p1*11507 + 8192) >> 14; \
} \
while (0)
#define OD_FDCT_4(q0, q2, q1, q3) \
/* Embedded 4-point orthonormal Type-II fDCT. */ \
do { \
int q2h; \
int q3h; \
q3 = q0 - q3; \
q3h = OD_DCT_RSHIFT(q3, 1); \
q0 -= q3h; \
q2 += q1; \
q2h = OD_DCT_RSHIFT(q2, 1); \
q1 = q2h - q1; \
OD_FDCT_2_ASYM(q0, q2, q2h); \
OD_FDST_2_ASYM(q3, q1); \
} \
while (0)
#define OD_IDCT_4(q0, q2, q1, q3) \
/* Embedded 4-point orthonormal Type-II iDCT. */ \
do { \
int q1h; \
int q3h; \
OD_IDST_2_ASYM(q3, q2); \
OD_IDCT_2_ASYM(q0, q1, q1h); \
q3h = OD_DCT_RSHIFT(q3, 1); \
q0 += q3h; \
q3 = q0 - q3; \
q2 = q1h - q2; \
q1 -= q2; \
} \
while (0)
#define OD_FDCT_4_ASYM(q0, q2, q2h, q1, q3, q3h) \
/* Embedded 4-point asymmetric Type-II fDCT. */ \
do { \
q0 += q3h; \
q3 = q0 - q3; \
q1 = q2h - q1; \
q2 = q1 - q2; \
OD_FDCT_2(q0, q2); \
OD_FDST_2(q3, q1); \
} \
while (0)
#define OD_IDCT_4_ASYM(q0, q2, q1, q1h, q3, q3h) \
/* Embedded 4-point asymmetric Type-II iDCT. */ \
do { \
OD_IDST_2(q3, q2); \
OD_IDCT_2(q0, q1); \
q1 = q2 - q1; \
q1h = OD_DCT_RSHIFT(q1, 1); \
q2 = q1h - q2; \
q3 = q0 - q3; \
q3h = OD_DCT_RSHIFT(q3, 1); \
q0 -= q3h; \
} \
while (0)
#define OD_FDST_4_ASYM(t0, t0h, t2, t1, t3) \
/* Embedded 4-point asymmetric Type-IV fDST. */ \
do { \
/* 7489/8192 ~= Tan[Pi/8] + Tan[Pi/4]/2 ~= 0.914213562373095 */ \
OD_DCT_OVERFLOW_CHECK(t1, 7489, 4096, 106); \
t2 -= (t1*7489 + 4096) >> 13; \
/* 11585/16384 ~= Sin[Pi/4] ~= 0.707106781186548 */ \
OD_DCT_OVERFLOW_CHECK(t1, 11585, 8192, 107); \
t1 += (t2*11585 + 8192) >> 14; \
/* -19195/32768 ~= Tan[Pi/8] - Tan[Pi/4] ~= -0.585786437626905 */ \
OD_DCT_OVERFLOW_CHECK(t1, 19195, 16384, 108); \
t2 += (t1*19195 + 16384) >> 15; \
t3 += OD_DCT_RSHIFT(t2, 1); \
t2 -= t3; \
t1 = t0h - t1; \
t0 -= t1; \
/* 6723/8192 ~= Tan[7*Pi/32] ~= 0.820678790828660 */ \
OD_DCT_OVERFLOW_CHECK(t0, 6723, 4096, 109); \
t3 += (t0*6723 + 4096) >> 13; \
/* 8035/8192 ~= Sin[7*Pi/16] ~= 0.980785280403230 */ \
OD_DCT_OVERFLOW_CHECK(t3, 8035, 4096, 110); \
t0 -= (t3*8035 + 4096) >> 13; \
/* 6723/8192 ~= Tan[7*Pi/32] ~= 0.820678790828660 */ \
OD_DCT_OVERFLOW_CHECK(t0, 6723, 4096, 111); \
t3 += (t0*6723 + 4096) >> 13; \
/* 8757/16384 ~= Tan[5*Pi/32] ~= 0.534511135950792 */ \
OD_DCT_OVERFLOW_CHECK(t1, 8757, 8192, 112); \
t2 += (t1*8757 + 8192) >> 14; \
/* 6811/8192 ~= Sin[5*Pi/16] ~= 0.831469612302545 */ \
OD_DCT_OVERFLOW_CHECK(t2, 6811, 4096, 113); \
t1 -= (t2*6811 + 4096) >> 13; \
/* 8757/16384 ~= Tan[5*Pi/32] ~= 0.534511135950792 */ \
OD_DCT_OVERFLOW_CHECK(t1, 8757, 8192, 114); \
t2 += (t1*8757 + 8192) >> 14; \
} \
while (0)
#define OD_IDST_4_ASYM(t0, t0h, t2, t1, t3) \
/* Embedded 4-point asymmetric Type-IV iDST. */ \
do { \
/* 8757/16384 ~= Tan[5*Pi/32] ~= 0.534511135950792 */ \
t1 -= (t2*8757 + 8192) >> 14; \
/* 6811/8192 ~= Sin[5*Pi/16] ~= 0.831469612302545 */ \
t2 += (t1*6811 + 4096) >> 13; \
/* 8757/16384 ~= Tan[5*Pi/32] ~= 0.534511135950792 */ \
t1 -= (t2*8757 + 8192) >> 14; \
/* 6723/8192 ~= Tan[7*Pi/32] ~= 0.820678790828660 */ \
t3 -= (t0*6723 + 4096) >> 13; \
/* 8035/8192 ~= Sin[7*Pi/16] ~= 0.980785280403230 */ \
t0 += (t3*8035 + 4096) >> 13; \
/* 6723/8192 ~= Tan[7*Pi/32] ~= 0.820678790828660 */ \
t3 -= (t0*6723 + 4096) >> 13; \
t0 += t2; \
t0h = OD_DCT_RSHIFT(t0, 1); \
t2 = t0h - t2; \
t1 += t3; \
t3 -= OD_DCT_RSHIFT(t1, 1); \
/* -19195/32768 ~= Tan[Pi/8] - Tan[Pi/4] ~= -0.585786437626905 */ \
t1 -= (t2*19195 + 16384) >> 15; \
/* 11585/16384 ~= Sin[Pi/4] ~= 0.707106781186548 */ \
t2 -= (t1*11585 + 8192) >> 14; \
/* 7489/8192 ~= Tan[Pi/8] + Tan[Pi/4]/2 ~= 0.914213562373095 */ \
t1 += (t2*7489 + 4096) >> 13; \
} \
while (0)
#define OD_FDCT_8(r0, r4, r2, r6, r1, r5, r3, r7) \
/* Embedded 8-point orthonormal Type-II fDCT. */ \
do { \
int r4h; \
int r5h; \
int r6h; \
int r7h; \
r7 = r0 - r7; \
r7h = OD_DCT_RSHIFT(r7, 1); \
r0 -= r7h; \
r6 += r1; \
r6h = OD_DCT_RSHIFT(r6, 1); \
r1 = r6h - r1; \
r5 = r2 - r5; \
r5h = OD_DCT_RSHIFT(r5, 1); \
r2 -= r5h; \
r4 += r3; \
r4h = OD_DCT_RSHIFT(r4, 1); \
r3 = r4h - r3; \
OD_FDCT_4_ASYM(r0, r4, r4h, r2, r6, r6h); \
OD_FDST_4_ASYM(r7, r7h, r3, r5, r1); \
} \
while (0)
#define OD_IDCT_8(r0, r4, r2, r6, r1, r5, r3, r7) \
/* Embedded 8-point orthonormal Type-II iDCT. */ \
do { \
int r1h; \
int r3h; \
int r5h; \
int r7h; \
OD_IDST_4_ASYM(r7, r7h, r5, r6, r4); \
OD_IDCT_4_ASYM(r0, r2, r1, r1h, r3, r3h); \
r0 += r7h; \
r7 = r0 - r7; \
r6 = r1h - r6; \
r1 -= r6; \
r5h = OD_DCT_RSHIFT(r5, 1); \
r2 += r5h; \
r5 = r2 - r5; \
r4 = r3h - r4; \
r3 -= r4; \
} \
while (0)
#define OD_FDST_8(t0, t4, t2, t6, t1, t5, t3, t7) \
/* Embedded 8-point orthonormal Type-IV fDST. */ \
do { \
int t0h; \
int t2h; \
int t5h; \
int t7h; \
/* 13573/32768 ~= Tan[Pi/8] ~= 0.414213562373095 */ \
OD_DCT_OVERFLOW_CHECK(t1, 13573, 16384, 115); \
t6 -= (t1*13573 + 16384) >> 15; \
/* 11585/16384 ~= Sin[Pi/4] ~= 0.707106781186547 */ \
OD_DCT_OVERFLOW_CHECK(t6, 11585, 8192, 116); \
t1 += (t6*11585 + 8192) >> 14; \
/* 13573/32768 ~= Tan[Pi/8] ~= 0.414213562373095 */ \
OD_DCT_OVERFLOW_CHECK(t1, 13573, 16384, 117); \
t6 -= (t1*13573 + 16384) >> 15; \
/* 21895/32768 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
OD_DCT_OVERFLOW_CHECK(t2, 21895, 16384, 118); \
t5 -= (t2*21895 + 16384) >> 15; \
/* 15137/16384 ~= Sin[3*Pi/8] ~= 0.923879532511287 */ \
OD_DCT_OVERFLOW_CHECK(t5, 15137, 8192, 119); \
t2 += (t5*15137 + 8192) >> 14; \
/* 10947/16384 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
OD_DCT_OVERFLOW_CHECK(t2, 10947, 8192, 120); \
t5 -= (t2*10947 + 8192) >> 14; \
/* 3259/16384 ~= Tan[Pi/16] ~= 0.198912367379658 */ \
OD_DCT_OVERFLOW_CHECK(t3, 3259, 8192, 121); \
t4 -= (t3*3259 + 8192) >> 14; \
/* 3135/8192 ~= Sin[Pi/8] ~= 0.382683432365090 */ \
OD_DCT_OVERFLOW_CHECK(t4, 3135, 4096, 122); \
t3 += (t4*3135 + 4096) >> 13; \
/* 3259/16384 ~= Tan[Pi/16] ~= 0.198912367379658 */ \
OD_DCT_OVERFLOW_CHECK(t3, 3259, 8192, 123); \
t4 -= (t3*3259 + 8192) >> 14; \
t7 += t1; \
t7h = OD_DCT_RSHIFT(t7, 1); \
t1 -= t7h; \
t2 = t3 - t2; \
t2h = OD_DCT_RSHIFT(t2, 1); \
t3 -= t2h; \
t0 -= t6; \
t0h = OD_DCT_RSHIFT(t0, 1); \
t6 += t0h; \
t5 = t4 - t5; \
t5h = OD_DCT_RSHIFT(t5, 1); \
t4 -= t5h; \
t1 += t5h; \
t5 = t1 - t5; \
t4 += t0h; \
t0 -= t4; \
t6 -= t2h; \
t2 += t6; \
t3 -= t7h; \
t7 += t3; \
/* TODO: Can we move this into another operation */ \
t7 = -t7; \
/* 7425/8192 ~= Tan[15*Pi/64] ~= 0.906347169019147 */ \
OD_DCT_OVERFLOW_CHECK(t7, 7425, 4096, 124); \
t0 -= (t7*7425 + 4096) >> 13; \
/* 8153/8192 ~= Sin[15*Pi/32] ~= 0.995184726672197 */ \
OD_DCT_OVERFLOW_CHECK(t0, 8153, 4096, 125); \
t7 += (t0*8153 + 4096) >> 13; \
/* 7425/8192 ~= Tan[15*Pi/64] ~= 0.906347169019147 */ \
OD_DCT_OVERFLOW_CHECK(t7, 7425, 4096, 126); \
t0 -= (t7*7425 + 4096) >> 13; \
/* 4861/32768 ~= Tan[3*Pi/64] ~= 0.148335987538347 */ \
OD_DCT_OVERFLOW_CHECK(t1, 4861, 16384, 127); \
t6 -= (t1*4861 + 16384) >> 15; \
/* 1189/4096 ~= Sin[3*Pi/32] ~= 0.290284677254462 */ \
OD_DCT_OVERFLOW_CHECK(t6, 1189, 2048, 128); \
t1 += (t6*1189 + 2048) >> 12; \
/* 4861/32768 ~= Tan[3*Pi/64] ~= 0.148335987538347 */ \
OD_DCT_OVERFLOW_CHECK(t1, 4861, 16384, 129); \
t6 -= (t1*4861 + 16384) >> 15; \
/* 2455/4096 ~= Tan[11*Pi/64] ~= 0.599376933681924 */ \
OD_DCT_OVERFLOW_CHECK(t5, 2455, 2048, 130); \
t2 -= (t5*2455 + 2048) >> 12; \
/* 7225/8192 ~= Sin[11*Pi/32] ~= 0.881921264348355 */ \
OD_DCT_OVERFLOW_CHECK(t2, 7225, 4096, 131); \
t5 += (t2*7225 + 4096) >> 13; \
/* 2455/4096 ~= Tan[11*Pi/64] ~= 0.599376933681924 */ \
OD_DCT_OVERFLOW_CHECK(t5, 2455, 2048, 132); \
t2 -= (t5*2455 + 2048) >> 12; \
/* 11725/32768 ~= Tan[7*Pi/64] ~= 0.357805721314524 */ \
OD_DCT_OVERFLOW_CHECK(t3, 11725, 16384, 133); \
t4 -= (t3*11725 + 16384) >> 15; \
/* 5197/8192 ~= Sin[7*Pi/32] ~= 0.634393284163645 */ \
OD_DCT_OVERFLOW_CHECK(t4, 5197, 4096, 134); \
t3 += (t4*5197 + 4096) >> 13; \
/* 11725/32768 ~= Tan[7*Pi/64] ~= 0.357805721314524 */ \
OD_DCT_OVERFLOW_CHECK(t3, 11725, 16384, 135); \
t4 -= (t3*11725 + 16384) >> 15; \
} \
while (0)
#define OD_IDST_8(t0, t4, t2, t6, t1, t5, t3, t7) \
/* Embedded 8-point orthonormal Type-IV iDST. */ \
do { \
int t0h; \
int t2h; \
int t5h_; \
int t7h_; \
/* 11725/32768 ~= Tan[7*Pi/64] ~= 0.357805721314524 */ \
t1 += (t6*11725 + 16384) >> 15; \
/* 5197/8192 ~= Sin[7*Pi/32] ~= 0.634393284163645 */ \
t6 -= (t1*5197 + 4096) >> 13; \
/* 11725/32768 ~= Tan[7*Pi/64] ~= 0.357805721314524 */ \
t1 += (t6*11725 + 16384) >> 15; \
/* 2455/4096 ~= Tan[11*Pi/64] ~= 0.599376933681924 */ \
t2 += (t5*2455 + 2048) >> 12; \
/* 7225/8192 ~= Sin[11*Pi/32] ~= 0.881921264348355 */ \
t5 -= (t2*7225 + 4096) >> 13; \
/* 2455/4096 ~= Tan[11*Pi/64] ~= 0.599376933681924 */ \
t2 += (t5*2455 + 2048) >> 12; \
/* 4861/32768 ~= Tan[3*Pi/64] ~= 0.148335987538347 */ \
t3 += (t4*4861 + 16384) >> 15; \
/* 1189/4096 ~= Sin[3*Pi/32] ~= 0.290284677254462 */ \
t4 -= (t3*1189 + 2048) >> 12; \
/* 4861/32768 ~= Tan[3*Pi/64] ~= 0.148335987538347 */ \
t3 += (t4*4861 + 16384) >> 15; \
/* 7425/8192 ~= Tan[15*Pi/64] ~= 0.906347169019147 */ \
t0 += (t7*7425 + 4096) >> 13; \
/* 8153/8192 ~= Sin[15*Pi/32] ~= 0.995184726672197 */ \
t7 -= (t0*8153 + 4096) >> 13; \
/* 7425/8192 ~= Tan[15*Pi/64] ~= 0.906347169019147 */ \
t0 += (t7*7425 + 4096) >> 13; \
/* TODO: Can we move this into another operation */ \
t7 = -t7; \
t7 -= t6; \
t7h_ = OD_DCT_RSHIFT(t7, 1); \
t6 += t7h_; \
t2 -= t3; \
t2h = OD_DCT_RSHIFT(t2, 1); \
t3 += t2h; \
t0 += t1; \
t0h = OD_DCT_RSHIFT(t0, 1); \
t1 -= t0h; \
t5 = t4 - t5; \
t5h_ = OD_DCT_RSHIFT(t5, 1); \
t4 -= t5h_; \
t1 += t5h_; \
t5 = t1 - t5; \
t3 -= t0h; \
t0 += t3; \
t6 += t2h; \
t2 = t6 - t2; \
t4 += t7h_; \
t7 -= t4; \
/* 3259/16384 ~= Tan[Pi/16] ~= 0.198912367379658 */ \
t1 += (t6*3259 + 8192) >> 14; \
/* 3135/8192 ~= Sin[Pi/8] ~= 0.382683432365090 */ \
t6 -= (t1*3135 + 4096) >> 13; \
/* 3259/16384 ~= Tan[Pi/16] ~= 0.198912367379658 */ \
t1 += (t6*3259 + 8192) >> 14; \
/* 10947/16384 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
t5 += (t2*10947 + 8192) >> 14; \
/* 15137/16384 ~= Sin[3*Pi/8] ~= 0.923879532511287 */ \
t2 -= (t5*15137 + 8192) >> 14; \
/* 21895/32768 ~= Tan[3*Pi/16] ~= 0.668178637919299 */ \
t5 += (t2*21895 + 16384) >> 15; \
/* 13573/32768 ~= Tan[Pi/8] ~= 0.414213562373095 */ \
t3 += (t4*13573 + 16384) >> 15; \
/* 11585/16384 ~= Sin[Pi/4] ~= 0.707106781186547 */ \
t4 -= (t3*11585 + 8192) >> 14; \
/* 13573/32768 ~= Tan[Pi/8] ~= 0.414213562373095 */ \
t3 += (t4*13573 + 16384) >> 15; \
} \
while (0)
void od_bin_fdct4(od_coeff y[4], const od_coeff *x, int xstride) {
int q0;
int q1;
int q2;
int q3;
q0 = x[0*xstride];
q2 = x[1*xstride];
q1 = x[2*xstride];
q3 = x[3*xstride];
OD_FDCT_4(q0, q2, q1, q3);
y[0] = (od_coeff)q0;
y[1] = (od_coeff)q1;
y[2] = (od_coeff)q2;
y[3] = (od_coeff)q3;
}
void od_bin_idct4(od_coeff *x, int xstride, const od_coeff y[4]) {
int q0;
int q1;
int q2;
int q3;
q0 = y[0];
q2 = y[1];
q1 = y[2];
q3 = y[3];
OD_IDCT_4(q0, q2, q1, q3);
x[0*xstride] = q0;
x[1*xstride] = q1;
x[2*xstride] = q2;
x[3*xstride] = q3;
}
void od_bin_fdct8(od_coeff y[8], const od_coeff *x, int xstride) {
int r0;
int r1;
int r2;
int r3;
int r4;
int r5;
int r6;
int r7;
r0 = x[0*xstride];
r4 = x[1*xstride];
r2 = x[2*xstride];
r6 = x[3*xstride];
r1 = x[4*xstride];
r5 = x[5*xstride];
r3 = x[6*xstride];
r7 = x[7*xstride];
OD_FDCT_8(r0, r4, r2, r6, r1, r5, r3, r7);
y[0] = (od_coeff)r0;
y[1] = (od_coeff)r1;
y[2] = (od_coeff)r2;
y[3] = (od_coeff)r3;
y[4] = (od_coeff)r4;
y[5] = (od_coeff)r5;
y[6] = (od_coeff)r6;
y[7] = (od_coeff)r7;
}
void od_bin_idct8(od_coeff *x, int xstride, const od_coeff y[8]) {
int r0;
int r1;
int r2;
int r3;
int r4;
int r5;
int r6;
int r7;
r0 = y[0];
r4 = y[1];
r2 = y[2];
r6 = y[3];
r1 = y[4];
r5 = y[5];
r3 = y[6];
r7 = y[7];
OD_IDCT_8(r0, r4, r2, r6, r1, r5, r3, r7);
x[0*xstride] = (od_coeff)r0;
x[1*xstride] = (od_coeff)r1;
x[2*xstride] = (od_coeff)r2;
x[3*xstride] = (od_coeff)r3;
x[4*xstride] = (od_coeff)r4;
x[5*xstride] = (od_coeff)r5;
x[6*xstride] = (od_coeff)r6;
x[7*xstride] = (od_coeff)r7;
}
void od_bin_fdst8(od_coeff y[8], const od_coeff *x, int xstride) {
int r0;
int r1;
int r2;
int r3;
int r4;
int r5;
int r6;
int r7;
r0 = x[0*xstride];
r4 = x[1*xstride];
r2 = x[2*xstride];
r6 = x[3*xstride];
r1 = x[4*xstride];
r5 = x[5*xstride];
r3 = x[6*xstride];
r7 = x[7*xstride];
OD_FDST_8(r0, r4, r2, r6, r1, r5, r3, r7);
y[0] = (od_coeff)r0;
y[1] = (od_coeff)r1;
y[2] = (od_coeff)r2;
y[3] = (od_coeff)r3;
y[4] = (od_coeff)r4;
y[5] = (od_coeff)r5;
y[6] = (od_coeff)r6;
y[7] = (od_coeff)r7;
}
void od_bin_idst8(od_coeff *x, int xstride, const od_coeff y[8]) {
int r0;
int r1;
int r2;
int r3;
int r4;
int r5;
int r6;
int r7;
r0 = y[0];
r4 = y[1];
r2 = y[2];
r6 = y[3];
r1 = y[4];
r5 = y[5];
r3 = y[6];
r7 = y[7];
OD_IDST_8(r0, r4, r2, r6, r1, r5, r3, r7);
x[0*xstride] = (od_coeff)r0;
x[1*xstride] = (od_coeff)r1;
x[2*xstride] = (od_coeff)r2;
x[3*xstride] = (od_coeff)r3;
x[4*xstride] = (od_coeff)r4;
x[5*xstride] = (od_coeff)r5;
x[6*xstride] = (od_coeff)r6;
x[7*xstride] = (od_coeff)r7;
}

13
third_party/aom/av1/common/daala_tx.h vendored Normal file
View file

@ -0,0 +1,13 @@
#ifndef AOM_DSP_DAALA_TX_H_
#define AOM_DSP_DAALA_TX_H_
#include "av1/common/odintrin.h"
void od_bin_fdct4(od_coeff y[4], const od_coeff *x, int xstride);
void od_bin_idct4(od_coeff *x, int xstride, const od_coeff y[4]);
void od_bin_fdct8(od_coeff y[8], const od_coeff *x, int xstride);
void od_bin_idct8(od_coeff *x, int xstride, const od_coeff y[8]);
void od_bin_fdst8(od_coeff y[8], const od_coeff *x, int xstride);
void od_bin_idst8(od_coeff *x, int xstride, const od_coeff y[8]);
#endif

View file

@ -5590,7 +5590,6 @@ void av1_adapt_coef_probs(AV1_COMMON *cm) {
#endif
}
#if CONFIG_EC_ADAPT
static void av1_average_cdf(aom_cdf_prob *cdf_ptr[], aom_cdf_prob *fc_cdf_ptr,
int cdf_size, const int num_tiles) {
int i;
@ -5639,9 +5638,14 @@ void av1_average_tile_mv_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
AVERAGE_TILE_CDFS(nmvc[j].joint_cdf)
for (k = 0; k < 2; ++k) {
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class_cdf);
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_fp_cdf);
AVERAGE_TILE_CDFS(nmvc[j].comps[k].fp_cdf);
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_fp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].fp_cdf)
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(nmvc[j].comps[k].hp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_hp_cdf)
AVERAGE_TILE_CDFS(nmvc[j].comps[k].class0_cdf)
#endif
}
}
}
@ -5652,20 +5656,21 @@ void av1_average_tile_intra_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
aom_cdf_prob *fc_cdf_ptr;
AVERAGE_TILE_CDFS(tx_size_cdf);
#if CONFIG_VAR_TX
// FIXME: txfm_partition probs
#endif
// FIXME: skip probs
AVERAGE_TILE_CDFS(tx_size_cdf)
AVERAGE_TILE_CDFS(intra_ext_tx_cdf)
AVERAGE_TILE_CDFS(inter_ext_tx_cdf);
AVERAGE_TILE_CDFS(inter_ext_tx_cdf)
AVERAGE_TILE_CDFS(seg.tree_cdf)
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(seg.pred_cdf)
#endif
AVERAGE_TILE_CDFS(uv_mode_cdf)
#if CONFIG_CFL
AVERAGE_TILE_CDFS(cfl_alpha_cdf)
#endif
AVERAGE_TILE_CDFS(partition_cdf)
#if CONFIG_DELTA_Q
@ -5677,6 +5682,19 @@ void av1_average_tile_intra_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
#if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
AVERAGE_TILE_CDFS(intra_filter_cdf)
#endif // CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(skip_cdfs)
#if CONFIG_VAR_TX
AVERAGE_TILE_CDFS(txfm_partition_cdf)
#endif
#if CONFIG_PALETTE
AVERAGE_TILE_CDFS(palette_y_size_cdf)
AVERAGE_TILE_CDFS(palette_uv_size_cdf)
AVERAGE_TILE_CDFS(palette_y_color_index_cdf)
AVERAGE_TILE_CDFS(palette_uv_color_index_cdf)
#endif
#endif // CONFIG_NEW_MULTISYMBOL
}
void av1_average_tile_inter_cdfs(AV1_COMMON *cm, FRAME_CONTEXT *fc,
@ -5686,26 +5704,57 @@ void av1_average_tile_inter_cdfs(AV1_COMMON *cm, FRAME_CONTEXT *fc,
aom_cdf_prob *fc_cdf_ptr;
// FIXME: comp_inter_cdf not defined
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(comp_inter_cdf)
#if CONFIG_EXT_REFS
AVERAGE_TILE_CDFS(comp_bwdref_cdf)
#endif
#endif
// FIXME: comp_ref_cdf and comp_bwd_ref not defined
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(single_ref_cdf)
// FIXME: single_ref_cdf not defined
AVERAGE_TILE_CDFS(newmv_cdf)
AVERAGE_TILE_CDFS(zeromv_cdf)
AVERAGE_TILE_CDFS(refmv_cdf)
AVERAGE_TILE_CDFS(drl_cdf)
#endif
// FIXME: cdfs not defined for newmv_mode, zeromv_mode, drl_mode, new2mv_mode
// FIXME: cdfs not defined for super_tx
// FIXME: cdfs not defined for motion_mode_prob, obmc_prob
#if CONFIG_EXT_INTER
AVERAGE_TILE_CDFS(inter_compound_mode_cdf)
// FIXME: cdfs not defined for super_tx
AVERAGE_TILE_CDFS(compound_type_cdf)
#if CONFIG_COMPOUND_SINGLEREF
AVERAGE_TILE_CDFS(inter_singleref_comp_mode_cdf)
#endif
// FIXME: CONFIG_EXT_INTER cdfs not defined for inter_compound_mode,
// interintra_mode etc
#if CONFIG_INTERINTRA
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(interintra_cdf)
AVERAGE_TILE_CDFS(wedge_interintra_cdf)
#endif
AVERAGE_TILE_CDFS(interintra_mode_cdf)
#endif
#endif // CONFIG_EXT_INTER
/* NB: kf_y_cdf is discarded after use, so no need
for backwards update */
AVERAGE_TILE_CDFS(y_mode_cdf)
if (cm->interp_filter == SWITCHABLE) {
AVERAGE_TILE_CDFS(switchable_interp_cdf)
}
#if CONFIG_NEW_MULTISYMBOL
AVERAGE_TILE_CDFS(intra_inter_cdf)
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
AVERAGE_TILE_CDFS(motion_mode_cdf)
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
AVERAGE_TILE_CDFS(obmc_cdf)
#endif
#endif
#endif
}
#if CONFIG_PVQ
@ -5771,4 +5820,3 @@ void av1_average_tile_pvq_cdfs(FRAME_CONTEXT *fc, FRAME_CONTEXT *ec_ctxs[],
AVERAGE_TILE_CDFS(pvq_context.pvq.pvq_skip_dir_cdf)
}
#endif // CONFIG_PVQ
#endif // CONFIG_EC_ADAPT

View file

@ -188,9 +188,7 @@ struct AV1Common;
struct frame_contexts;
void av1_default_coef_probs(struct AV1Common *cm);
void av1_adapt_coef_probs(struct AV1Common *cm);
#if CONFIG_EC_ADAPT
void av1_adapt_coef_cdfs(struct AV1Common *cm, struct frame_contexts *pre_fc);
#endif
// This is the index in the scan order beyond which all coefficients for
// 8x8 transform and above are in the top band.
@ -317,7 +315,7 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
*(const uint64_t *)(l + 16) | *(const uint64_t *)(l + 24));
break;
#endif // CONFIG_TX64X64
#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
case TX_4X16:
above_ec = !!*(const uint16_t *)a;
left_ec = !!*(const uint64_t *)l;
@ -334,7 +332,7 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
above_ec = !!(*(const uint64_t *)a | *(const uint64_t *)(a + 8));
left_ec = !!*(const uint32_t *)l;
break;
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#endif
default: assert(0 && "Invalid transform size."); break;
}
return combine_entropy_contexts(above_ec, left_ec);
@ -387,7 +385,7 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
left_ec = !!(*(const uint64_t *)l | *(const uint64_t *)(l + 8));
break;
#endif // CONFIG_TX64X64
#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
case TX_4X16:
above_ec = a[0] != 0;
left_ec = !!*(const uint32_t *)l;
@ -404,7 +402,7 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
above_ec = !!*(const uint64_t *)a;
left_ec = !!*(const uint16_t *)l;
break;
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#endif
default: assert(0 && "Invalid transform size."); break;
}
return combine_entropy_contexts(above_ec, left_ec);
@ -416,7 +414,11 @@ static INLINE int get_entropy_context(TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
#define COEF_MAX_UPDATE_FACTOR_AFTER_KEY 128
#if CONFIG_ADAPT_SCAN
#define ADAPT_SCAN_UPDATE_RATE_16 (1 << 13)
#define ADAPT_SCAN_PROB_PRECISION 16
// 1/8 update rate
#define ADAPT_SCAN_UPDATE_LOG_RATE 3
#define ADAPT_SCAN_UPDATE_RATE \
(1 << (ADAPT_SCAN_PROB_PRECISION - ADAPT_SCAN_UPDATE_LOG_RATE))
#endif
static INLINE aom_prob av1_merge_probs(aom_prob pre_prob,
@ -431,7 +433,6 @@ static INLINE aom_prob av1_mode_mv_merge_probs(aom_prob pre_prob,
return mode_mv_merge_probs(pre_prob, ct);
}
#if CONFIG_EC_ADAPT
void av1_average_tile_coef_cdfs(struct frame_contexts *fc,
struct frame_contexts *ec_ctxs[],
aom_cdf_prob *cdf_ptrs[], int num_tiles);
@ -450,7 +451,6 @@ void av1_default_pvq_probs(struct AV1Common *cm);
void av1_average_tile_pvq_cdfs(struct frame_contexts *fc,
struct frame_contexts *ec_ctxs[], int num_tiles);
#endif // CONFIG_PVQ
#endif // CONFIG_EC_ADAPT
#ifdef __cplusplus
} // extern "C"
#endif

File diff suppressed because it is too large Load diff

View file

@ -92,7 +92,7 @@ struct seg_counts {
typedef struct frame_contexts {
aom_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1];
aom_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
aom_prob uv_mode_prob[INTRA_MODES][UV_INTRA_MODES - 1];
#if CONFIG_EXT_PARTITION_TYPES
aom_prob partition_prob[PARTITION_CONTEXTS][EXT_PARTITION_TYPES - 1];
#else
@ -185,30 +185,79 @@ typedef struct frame_contexts {
aom_prob zeromv_prob[ZEROMV_MODE_CONTEXTS];
aom_prob refmv_prob[REFMV_MODE_CONTEXTS];
aom_prob drl_prob[DRL_MODE_CONTEXTS];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob newmv_cdf[NEWMV_MODE_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob zeromv_cdf[ZEROMV_MODE_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob refmv_cdf[REFMV_MODE_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob drl_cdf[DRL_MODE_CONTEXTS][CDF_SIZE(2)];
#endif
aom_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
#if CONFIG_EXT_INTER
aom_prob inter_compound_mode_probs[INTER_MODE_CONTEXTS]
[INTER_COMPOUND_MODES - 1];
aom_cdf_prob inter_compound_mode_cdf[INTER_MODE_CONTEXTS]
[CDF_SIZE(INTER_COMPOUND_MODES)];
#if CONFIG_COMPOUND_SINGLEREF
aom_prob inter_singleref_comp_mode_probs[INTER_MODE_CONTEXTS]
[INTER_SINGLEREF_COMP_MODES - 1];
aom_cdf_prob inter_singleref_comp_mode_cdf[INTER_MODE_CONTEXTS][CDF_SIZE(
INTER_SINGLEREF_COMP_MODES)];
#endif // CONFIG_COMPOUND_SINGLEREF
aom_prob compound_type_prob[BLOCK_SIZES][COMPOUND_TYPES - 1];
aom_prob compound_type_prob[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
aom_cdf_prob compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(COMPOUND_TYPES)];
#if CONFIG_INTERINTRA
aom_prob interintra_prob[BLOCK_SIZE_GROUPS];
aom_prob wedge_interintra_prob[BLOCK_SIZES_ALL];
aom_prob interintra_mode_prob[BLOCK_SIZE_GROUPS][INTERINTRA_MODES - 1];
aom_prob wedge_interintra_prob[BLOCK_SIZES];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob interintra_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(2)];
aom_cdf_prob wedge_interintra_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)];
#endif
aom_cdf_prob interintra_mode_cdf[BLOCK_SIZE_GROUPS]
[CDF_SIZE(INTERINTRA_MODES)];
#endif // CONFIG_INTERINTRA
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
aom_prob motion_mode_prob[BLOCK_SIZES][MOTION_MODES - 1];
aom_prob motion_mode_prob[BLOCK_SIZES_ALL][MOTION_MODES - 1];
aom_cdf_prob motion_mode_cdf[BLOCK_SIZES_ALL][CDF_SIZE(MOTION_MODES)];
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
aom_prob ncobmc_mode_prob[ADAPT_OVERLAP_BLOCKS][MAX_NCOBMC_MODES - 1];
aom_cdf_prob ncobmc_mode_cdf[ADAPT_OVERLAP_BLOCKS]
[CDF_SIZE(MAX_NCOBMC_MODES)];
#endif
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
aom_prob obmc_prob[BLOCK_SIZES];
aom_prob obmc_prob[BLOCK_SIZES_ALL];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob obmc_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)];
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
aom_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
aom_prob comp_inter_prob[COMP_INTER_CONTEXTS];
#if CONFIG_PALETTE
aom_cdf_prob palette_y_size_cdf[PALETTE_BLOCK_SIZES][CDF_SIZE(PALETTE_SIZES)];
aom_cdf_prob palette_uv_size_cdf[PALETTE_BLOCK_SIZES]
[CDF_SIZE(PALETTE_SIZES)];
aom_cdf_prob palette_y_color_index_cdf[PALETTE_SIZES]
[PALETTE_COLOR_INDEX_CONTEXTS]
[CDF_SIZE(PALETTE_COLORS)];
aom_cdf_prob palette_uv_color_index_cdf[PALETTE_SIZES]
[PALETTE_COLOR_INDEX_CONTEXTS]
[CDF_SIZE(PALETTE_COLORS)];
#endif // CONFIG_PALETTE
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob comp_inter_cdf[COMP_INTER_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1][CDF_SIZE(2)];
#endif
#if CONFIG_EXT_COMP_REFS
aom_prob comp_ref_type_prob[COMP_REF_TYPE_CONTEXTS];
aom_prob uni_comp_ref_prob[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob comp_ref_type_cdf[COMP_REF_TYPE_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]
[CDF_SIZE(2)];
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS
aom_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS - 1];
#if CONFIG_EXT_REFS
aom_prob comp_ref_prob[REF_CONTEXTS][FWD_REFS - 1];
@ -216,17 +265,32 @@ typedef struct frame_contexts {
#else
aom_prob comp_ref_prob[REF_CONTEXTS][COMP_REFS - 1];
#endif // CONFIG_EXT_REFS
#if CONFIG_NEW_MULTISYMBOL
#if CONFIG_EXT_REFS
aom_cdf_prob comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)];
aom_cdf_prob comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)];
#else
aom_cdf_prob comp_ref_cdf[REF_CONTEXTS][COMP_REFS - 1][CDF_SIZE(2)];
#endif // CONFIG_EXT_REFS
#endif
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
aom_prob comp_inter_mode_prob[COMP_INTER_MODE_CONTEXTS];
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
aom_prob tx_size_probs[MAX_TX_DEPTH][TX_SIZE_CONTEXTS][MAX_TX_DEPTH];
#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
aom_prob quarter_tx_size_prob;
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#endif
#if CONFIG_VAR_TX
aom_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob txfm_partition_cdf[TXFM_PARTITION_CONTEXTS][CDF_SIZE(2)];
#endif
#endif // CONFIG_VAR_TX
aom_prob skip_probs[SKIP_CONTEXTS];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob skip_cdfs[SKIP_CONTEXTS][CDF_SIZE(2)];
aom_cdf_prob intra_inter_cdf[INTRA_INTER_CONTEXTS][CDF_SIZE(2)];
#endif
nmv_context nmvc[NMV_CONTEXTS];
#if CONFIG_INTRABC
nmv_context ndvc;
@ -253,14 +317,11 @@ typedef struct frame_contexts {
#if CONFIG_FILTER_INTRA
aom_prob filter_intra_probs[PLANE_TYPES];
#endif // CONFIG_FILTER_INTRA
#if CONFIG_GLOBAL_MOTION
aom_prob global_motion_types_prob[GLOBAL_TRANS_TYPES - 1];
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_LOOP_RESTORATION
aom_prob switchable_restore_prob[RESTORE_SWITCHABLE_TYPES - 1];
#endif // CONFIG_LOOP_RESTORATION
aom_cdf_prob y_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTRA_MODES)];
aom_cdf_prob uv_mode_cdf[INTRA_MODES][CDF_SIZE(INTRA_MODES)];
aom_cdf_prob uv_mode_cdf[INTRA_MODES][CDF_SIZE(UV_INTRA_MODES)];
#if CONFIG_EXT_PARTITION_TYPES
aom_cdf_prob partition_cdf[PARTITION_CONTEXTS][CDF_SIZE(EXT_PARTITION_TYPES)];
#else
@ -268,9 +329,10 @@ typedef struct frame_contexts {
#endif
aom_cdf_prob switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS]
[CDF_SIZE(SWITCHABLE_FILTERS)];
aom_cdf_prob inter_mode_cdf[INTER_MODE_CONTEXTS][CDF_SIZE(INTER_MODES)];
/* Keep track of kf_y_cdf here, as this makes handling
multiple copies for adaptation in tiles easier */
/* kf_y_cdf is discarded after use, so does not require persistent storage.
However, we keep it with the other CDFs in this struct since it needs to
be copied to each tile to support parallelism just like the others.
*/
aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(INTRA_MODES)];
aom_cdf_prob tx_size_cdf[MAX_TX_DEPTH][TX_SIZE_CONTEXTS]
[CDF_SIZE(MAX_TX_DEPTH + 1)];
@ -309,11 +371,13 @@ typedef struct frame_contexts {
} FRAME_CONTEXT;
typedef struct FRAME_COUNTS {
// Note: This structure should only contain 'unsigned int' fields, or
// aggregates built solely from 'unsigned int' fields/elements
// 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[INTRA_MODES][INTRA_MODES][INTRA_MODES];
unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
unsigned int uv_mode[INTRA_MODES][INTRA_MODES];
unsigned int uv_mode[INTRA_MODES][UV_INTRA_MODES];
#endif // CONFIG_ENTROPY_STATS
#if CONFIG_EXT_PARTITION_TYPES
unsigned int partition[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
#else
@ -360,7 +424,6 @@ typedef struct FRAME_COUNTS {
unsigned int refmv_mode[REFMV_MODE_CONTEXTS][2];
unsigned int drl_mode[DRL_MODE_CONTEXTS][2];
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
#if CONFIG_EXT_INTER
unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
#if CONFIG_COMPOUND_SINGLEREF
@ -370,18 +433,25 @@ typedef struct FRAME_COUNTS {
#if CONFIG_INTERINTRA
unsigned int interintra[BLOCK_SIZE_GROUPS][2];
unsigned int interintra_mode[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
unsigned int wedge_interintra[BLOCK_SIZES][2];
unsigned int wedge_interintra[BLOCK_SIZES_ALL][2];
#endif // CONFIG_INTERINTRA
unsigned int compound_interinter[BLOCK_SIZES][COMPOUND_TYPES];
unsigned int compound_interinter[BLOCK_SIZES_ALL][COMPOUND_TYPES];
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
unsigned int motion_mode[BLOCK_SIZES][MOTION_MODES];
unsigned int motion_mode[BLOCK_SIZES_ALL][MOTION_MODES];
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
unsigned int ncobmc_mode[ADAPT_OVERLAP_BLOCKS][MAX_NCOBMC_MODES];
#endif
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
unsigned int obmc[BLOCK_SIZES][2];
unsigned int obmc[BLOCK_SIZES_ALL][2];
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
#if CONFIG_EXT_COMP_REFS
unsigned int comp_ref_type[COMP_REF_TYPE_CONTEXTS][2];
unsigned int uni_comp_ref[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1][2];
#endif // CONFIG_EXT_COMP_REFS
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS - 1][2];
#if CONFIG_EXT_REFS
unsigned int comp_ref[REF_CONTEXTS][FWD_REFS - 1][2];
@ -397,9 +467,9 @@ typedef struct FRAME_COUNTS {
// belong into this structure.
unsigned int tx_size_totals[TX_SIZES];
unsigned int tx_size[MAX_TX_DEPTH][TX_SIZE_CONTEXTS][MAX_TX_DEPTH + 1];
#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
unsigned int quarter_tx_size[2];
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
#endif
#if CONFIG_VAR_TX
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
#endif
@ -441,11 +511,6 @@ typedef struct FRAME_COUNTS {
#endif // CONFIG_FILTER_INTRA
} FRAME_COUNTS;
// Default probabilities for signaling Intra mode for Y plane -- used only for
// intra-only frames. ('default_if_y_probs' is used for inter frames).
// Contexts used: Intra mode (Y plane) of 'above' and 'left' blocks.
extern const aom_prob av1_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
[INTRA_MODES - 1];
// CDF version of 'av1_kf_y_mode_prob'.
extern const aom_cdf_prob av1_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES]
[CDF_SIZE(INTRA_MODES)];
@ -455,22 +520,10 @@ extern const aom_prob av1_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES]
[PALETTE_Y_MODE_CONTEXTS];
extern const aom_prob
av1_default_palette_uv_mode_prob[PALETTE_UV_MODE_CONTEXTS];
extern const aom_prob av1_default_palette_y_size_prob[PALETTE_BLOCK_SIZES]
[PALETTE_SIZES - 1];
extern const aom_prob av1_default_palette_uv_size_prob[PALETTE_BLOCK_SIZES]
[PALETTE_SIZES - 1];
extern const aom_prob av1_default_palette_y_color_index_prob
[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS][PALETTE_COLORS - 1];
extern const aom_prob av1_default_palette_uv_color_index_prob
[PALETTE_SIZES][PALETTE_COLOR_INDEX_CONTEXTS][PALETTE_COLORS - 1];
#endif // CONFIG_PALETTE
extern const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
extern const aom_tree_index av1_inter_mode_tree[TREE_SIZE(INTER_MODES)];
extern int av1_intra_mode_ind[INTRA_MODES];
extern int av1_intra_mode_inv[INTRA_MODES];
extern int av1_inter_mode_ind[INTER_MODES];
extern int av1_inter_mode_inv[INTER_MODES];
extern const int av1_intra_mode_ind[INTRA_MODES];
extern const int av1_intra_mode_inv[INTRA_MODES];
#if CONFIG_EXT_TX
extern int av1_ext_tx_intra_ind[EXT_TX_SETS_INTRA][TX_TYPES];
extern int av1_ext_tx_intra_inv[EXT_TX_SETS_INTRA][TX_TYPES];
@ -499,7 +552,6 @@ extern const aom_tree_index
extern const aom_tree_index
av1_switchable_interp_tree[TREE_SIZE(SWITCHABLE_FILTERS)];
#if CONFIG_PALETTE
extern const aom_tree_index av1_palette_size_tree[TREE_SIZE(PALETTE_SIZES)];
extern const aom_tree_index
av1_palette_color_index_tree[PALETTE_SIZES][TREE_SIZE(PALETTE_COLORS)];
#endif // CONFIG_PALETTE
@ -518,7 +570,9 @@ extern const aom_tree_index av1_ext_tx_tree[TREE_SIZE(TX_TYPES)];
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
extern const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)];
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
extern const aom_tree_index av1_ncobmc_mode_tree[TREE_SIZE(MAX_NCOBMC_MODES)];
#endif
#if CONFIG_LOOP_RESTORATION
#define RESTORE_NONE_SGRPROJ_PROB 64
#define RESTORE_NONE_BILATERAL_PROB 16
@ -530,10 +584,6 @@ extern const aom_tree_index
extern int av1_switchable_interp_ind[SWITCHABLE_FILTERS];
extern int av1_switchable_interp_inv[SWITCHABLE_FILTERS];
#if !CONFIG_EC_ADAPT
void av1_set_mode_cdfs(struct AV1Common *cm);
#endif
void av1_setup_past_independence(struct AV1Common *cm);
void av1_adapt_intra_frame_probs(struct AV1Common *cm);

View file

@ -64,6 +64,11 @@ static const nmv_context default_nmv_context = {
0 }, // fp_cdf
160, // class0_hp bit
128, // hp
#if CONFIG_NEW_MULTISYMBOL
{ AOM_ICDF(160 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(128 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(216 * 128), AOM_ICDF(32768), 0 },
#endif
},
{
// Horizontal component
@ -84,6 +89,11 @@ static const nmv_context default_nmv_context = {
0 }, // fp_cdf
160, // class0_hp bit
128, // hp
#if CONFIG_NEW_MULTISYMBOL
{ AOM_ICDF(160 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(128 * 128), AOM_ICDF(32768), 0 },
{ AOM_ICDF(216 * 128), AOM_ICDF(32768), 0 },
#endif
} },
};
@ -130,43 +140,6 @@ static const uint8_t log_in_base_2[] = {
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
};
#if CONFIG_GLOBAL_MOTION
#if GLOBAL_TRANS_TYPES == 7 // All models
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4,
-ROTZOOM, 6, -AFFINE, 8,
-HOMOGRAPHY, 10, -HORTRAPEZOID, -VERTRAPEZOID };
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
{ 224, 128, 192, 192, 32, 128 };
#elif GLOBAL_TRANS_TYPES == 6 // Do not allow full homography
const aom_tree_index
av1_global_motion_types_tree[TREE_SIZE(GLOBAL_TRANS_TYPES)] = {
-IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, 6, -AFFINE, 8, -HORTRAPEZOID,
-VERTRAPEZOID
};
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
{ 224, 128, 192, 192, 128 };
#elif GLOBAL_TRANS_TYPES == 4 // Upto Affine
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, -AFFINE };
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
{ 224, 128, 240 };
#elif GLOBAL_TRANS_TYPES == 3 // Upto rotation-zoom
const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, -ROTZOOM };
static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
{ 224, 128 };
#endif // GLOBAL_TRANS_TYPES
#endif // CONFIG_GLOBAL_MOTION
static INLINE int mv_class_base(MV_CLASS_TYPE c) {
return c ? CLASS0_SIZE << (c + 2) : 0;
}
@ -180,7 +153,7 @@ MV_CLASS_TYPE av1_get_mv_class(int z, int *offset) {
}
static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
int usehp) {
MvSubpelPrecision precision) {
int s, z, c, o, d, e, f;
assert(v != 0); /* should not be zero */
s = v < 0;
@ -196,27 +169,34 @@ static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
if (c == MV_CLASS_0) {
comp_counts->class0[d] += incr;
comp_counts->class0_fp[d][f] += incr;
if (usehp) comp_counts->class0_hp[e] += incr;
#if CONFIG_INTRABC
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->class0_fp[d][f] += incr;
if (precision > MV_SUBPEL_LOW_PRECISION) comp_counts->class0_hp[e] += incr;
} else {
int i;
int b = c + CLASS0_BITS - 1; // number of bits
for (i = 0; i < b; ++i) comp_counts->bits[i][((d >> i) & 1)] += incr;
comp_counts->fp[f] += incr;
if (usehp) comp_counts->hp[e] += incr;
#if CONFIG_INTRABC
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->fp[f] += incr;
if (precision > MV_SUBPEL_LOW_PRECISION) comp_counts->hp[e] += incr;
}
}
void av1_inc_mv(const MV *mv, nmv_context_counts *counts, const int usehp) {
void av1_inc_mv(const MV *mv, nmv_context_counts *counts,
MvSubpelPrecision precision) {
if (counts != NULL) {
const MV_JOINT_TYPE j = av1_get_mv_joint(mv);
++counts->joints[j];
if (mv_joint_vertical(j))
inc_mv_component(mv->row, &counts->comps[0], 1, usehp);
inc_mv_component(mv->row, &counts->comps[0], 1, precision);
if (mv_joint_horizontal(j))
inc_mv_component(mv->col, &counts->comps[1], 1, usehp);
inc_mv_component(mv->col, &counts->comps[1], 1, precision);
}
}
@ -258,25 +238,6 @@ void av1_adapt_mv_probs(AV1_COMMON *cm, int allow_hp) {
}
}
#if !CONFIG_EC_ADAPT
void av1_set_mv_cdfs(nmv_context *ctx) {
int i;
int j;
av1_tree_to_cdf(av1_mv_joint_tree, ctx->joints, ctx->joint_cdf);
for (i = 0; i < 2; ++i) {
nmv_component *const comp_ctx = &ctx->comps[i];
av1_tree_to_cdf(av1_mv_class_tree, comp_ctx->classes, comp_ctx->class_cdf);
for (j = 0; j < CLASS0_SIZE; ++j) {
av1_tree_to_cdf(av1_mv_fp_tree, comp_ctx->class0_fp[j],
comp_ctx->class0_fp_cdf[j]);
}
av1_tree_to_cdf(av1_mv_fp_tree, comp_ctx->fp, comp_ctx->fp_cdf);
}
}
#endif
void av1_init_mv_probs(AV1_COMMON *cm) {
int i;
for (i = 0; i < NMV_CONTEXTS; ++i) {
@ -286,7 +247,4 @@ void av1_init_mv_probs(AV1_COMMON *cm) {
#if CONFIG_INTRABC
cm->fc->ndvc = default_nmv_context;
#endif // CONFIG_INTRABC
#if CONFIG_GLOBAL_MOTION
av1_copy(cm->fc->global_motion_types_prob, default_global_motion_types_prob);
#endif // CONFIG_GLOBAL_MOTION
}

View file

@ -93,6 +93,11 @@ typedef struct {
aom_cdf_prob fp_cdf[CDF_SIZE(MV_FP_SIZE)];
aom_prob class0_hp;
aom_prob hp;
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob class0_hp_cdf[CDF_SIZE(2)];
aom_cdf_prob hp_cdf[CDF_SIZE(2)];
aom_cdf_prob class0_cdf[CDF_SIZE(CLASS0_SIZE)];
#endif
} nmv_component;
typedef struct {
@ -127,14 +132,16 @@ typedef struct {
nmv_component_counts comps[2];
} nmv_context_counts;
void av1_inc_mv(const MV *mv, nmv_context_counts *mvctx, const int usehp);
#if CONFIG_GLOBAL_MOTION
extern const aom_tree_index
av1_global_motion_types_tree[TREE_SIZE(GLOBAL_TRANS_TYPES)];
#endif // CONFIG_GLOBAL_MOTION
#if !CONFIG_EC_ADAPT
void av1_set_mv_cdfs(nmv_context *ctx);
typedef enum {
#if CONFIG_INTRABC
MV_SUBPEL_NONE = -1,
#endif
MV_SUBPEL_LOW_PRECISION = 0,
MV_SUBPEL_HIGH_PRECISION,
} MvSubpelPrecision;
void av1_inc_mv(const MV *mv, nmv_context_counts *mvctx,
MvSubpelPrecision precision);
#ifdef __cplusplus
} // extern "C"

View file

@ -54,9 +54,6 @@ extern "C" {
// Maximum number of tile rows and tile columns
#if CONFIG_EXT_TILE
#define TILE_NORMAL 0
#define TILE_VR 1
#define MAX_TILE_ROWS 1024
#define MAX_TILE_COLS 1024
#else
@ -68,6 +65,8 @@ extern "C" {
#define MAX_VARTX_DEPTH 2
#endif
#define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2)
// Bitstream profiles indicated by 2-3 bits in the uncompressed header.
// 00: Profile 0. 8-bit 4:2:0 only.
// 10: Profile 1. 8-bit 4:4:4, 4:2:2, and 4:4:0.
@ -87,7 +86,7 @@ typedef enum BITSTREAM_PROFILE {
// type, so that we can save memory when they are used in structs/arrays.
typedef enum ATTRIBUTE_PACKED {
#if CONFIG_CB4X4
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
BLOCK_2X2,
BLOCK_2X4,
BLOCK_4X2,
@ -130,6 +129,8 @@ typedef enum {
PARTITION_HORZ_B, // HORZ split and the right partition is split again
PARTITION_VERT_A, // VERT split and the top partition is split again
PARTITION_VERT_B, // VERT split and the bottom partition is split again
PARTITION_HORZ_4, // 4:1 horizontal partition
PARTITION_VERT_4, // 4:1 vertical partition
EXT_PARTITION_TYPES,
#endif // CONFIG_EXT_PARTITION_TYPES
PARTITION_TYPES = PARTITION_SPLIT + 1,
@ -193,6 +194,22 @@ typedef enum ATTRIBUTE_PACKED {
#define MAX_NUM_TXB (1 << (MAX_SB_SIZE_LOG2 - MIN_TX_SIZE_LOG2))
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
typedef enum ATTRIBUTE_PACKED {
NO_OVERLAP,
NCOBMC_MODE_1,
NCOBMC_MODE_2,
NCOBMC_MODE_3,
NCOBMC_MODE_4,
NCOBMC_MODE_5,
NCOBMC_MODE_6,
NCOBMC_MODE_7,
NCOBMC_MODE_8,
MAX_NCOBMC_MODES
} NCOBMC_MODE;
// #define MAX_INTRPL_MODES 9
#endif
// frame transform mode
typedef enum {
ONLY_4X4 = 0, // only 4x4 transform used
@ -212,6 +229,8 @@ typedef enum {
ADST_1D = 1,
FLIPADST_1D = 2,
IDTX_1D = 3,
// TODO(sarahparker) need to eventually put something here for the
// mrc experiment to make this work with the ext-tx pruning functions
TX_TYPES_1D = 4,
} TX_TYPE_1D;
@ -234,9 +253,18 @@ typedef enum {
V_FLIPADST = 14,
H_FLIPADST = 15,
#endif // CONFIG_EXT_TX
#if CONFIG_MRC_TX
MRC_DCT, // DCT in both directions with mrc based bitmask
#endif // CONFIG_MRC_TX
TX_TYPES,
} TX_TYPE;
#if CONFIG_EXT_TX
#define IS_2D_TRANSFORM(tx_type) (tx_type < IDTX)
#else
#define IS_2D_TRANSFORM(tx_type) 1
#endif
typedef enum {
TILE_LEFT_BOUNDARY = 1,
TILE_RIGHT_BOUNDARY = 2,
@ -252,10 +280,15 @@ typedef enum {
#if CONFIG_CHROMA_2X2
#define EXT_TX_SIZES 5 // number of sizes that use extended transforms
#else
#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
#endif // CONFIG_CHROMA_2X2
#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
#endif // CONFIG_CHROMA_2X2
#if CONFIG_MRC_TX
#define EXT_TX_SETS_INTER 5 // Sets of transform selections for INTER
#define EXT_TX_SETS_INTRA 4 // Sets of transform selections for INTRA
#else // CONFIG_MRC_TX
#define EXT_TX_SETS_INTER 4 // Sets of transform selections for INTER
#define EXT_TX_SETS_INTRA 3 // Sets of transform selections for INTRA
#endif // CONFIG_MRC_TX
#else
#if CONFIG_CHROMA_2X2
#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
@ -271,15 +304,33 @@ typedef enum {
AOM_LAST3_FLAG = 1 << 2,
AOM_GOLD_FLAG = 1 << 3,
AOM_BWD_FLAG = 1 << 4,
#if CONFIG_ALTREF2
AOM_ALT2_FLAG = 1 << 5,
AOM_ALT_FLAG = 1 << 6,
AOM_REFFRAME_ALL = (1 << 7) - 1
#else // !CONFIG_ALTREF2
AOM_ALT_FLAG = 1 << 5,
AOM_REFFRAME_ALL = (1 << 6) - 1
#else
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
AOM_GOLD_FLAG = 1 << 1,
AOM_ALT_FLAG = 1 << 2,
AOM_REFFRAME_ALL = (1 << 3) - 1
#endif // CONFIG_EXT_REFS
} AOM_REFFRAME;
#if CONFIG_EXT_COMP_REFS
#define USE_UNI_COMP_REFS 1
typedef enum {
UNIDIR_COMP_REFERENCE = 0,
BIDIR_COMP_REFERENCE = 1,
COMP_REFERENCE_TYPES = 2,
} COMP_REFERENCE_TYPE;
#else // !CONFIG_EXT_COMP_REFS
#define USE_UNI_COMP_REFS 0
#endif // CONFIG_EXT_COMP_REFS
typedef enum { PLANE_TYPE_Y = 0, PLANE_TYPE_UV = 1, PLANE_TYPES } PLANE_TYPE;
#if CONFIG_CFL
@ -318,6 +369,8 @@ typedef enum {
} PALETTE_COLOR;
#endif // CONFIG_PALETTE
// Note: All directional predictors must be between V_PRED and D63_PRED (both
// inclusive).
typedef enum ATTRIBUTE_PACKED {
DC_PRED, // Average of above and left pixels
V_PRED, // Vertical
@ -344,7 +397,7 @@ typedef enum ATTRIBUTE_PACKED {
#if CONFIG_COMPOUND_SINGLEREF
// Single ref compound modes
SR_NEAREST_NEARMV,
SR_NEAREST_NEWMV,
// SR_NEAREST_NEWMV,
SR_NEAR_NEWMV,
SR_ZERO_NEWMV,
SR_NEW_NEWMV,
@ -360,10 +413,41 @@ typedef enum ATTRIBUTE_PACKED {
NEW_NEWMV,
#endif // CONFIG_EXT_INTER
MB_MODE_COUNT,
INTRA_MODES = TM_PRED + 1,
INTRA_MODES = TM_PRED + 1, // TM_PRED has to be the last intra mode.
INTRA_INVALID = MB_MODE_COUNT // For uv_mode in inter blocks
} PREDICTION_MODE;
#if CONFIG_CFL
// TODO(ltrudeau) Do we really want to pack this?
// TODO(ltrudeau) Do we match with PREDICTION_MODE?
typedef enum ATTRIBUTE_PACKED {
UV_DC_PRED, // Average of above and left pixels
UV_V_PRED, // Vertical
UV_H_PRED, // Horizontal
UV_D45_PRED, // Directional 45 deg = round(arctan(1/1) * 180/pi)
UV_D135_PRED, // Directional 135 deg = 180 - 45
UV_D117_PRED, // Directional 117 deg = 180 - 63
UV_D153_PRED, // Directional 153 deg = 180 - 27
UV_D207_PRED, // Directional 207 deg = 180 + 27
UV_D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi)
#if CONFIG_ALT_INTRA
UV_SMOOTH_PRED, // Combination of horizontal and vertical interpolation
#if CONFIG_SMOOTH_HV
UV_SMOOTH_V_PRED, // Vertical interpolation
UV_SMOOTH_H_PRED, // Horizontal interpolation
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
UV_TM_PRED, // True-motion
UV_INTRA_MODES,
UV_MODE_INVALID, // For uv_mode in inter blocks
} UV_PREDICTION_MODE;
#else
#define UV_INTRA_MODES (INTRA_MODES)
#define UV_PREDICTION_MODE PREDICTION_MODE
#define UV_DC_PRED (DC_PRED)
#define UV_MODE_INVALID (INTRA_INVALID)
#endif // CONFIG_CFL
typedef enum {
SIMPLE_TRANSLATION = 0,
#if CONFIG_MOTION_VAR
@ -372,9 +456,23 @@ typedef enum {
#if CONFIG_WARPED_MOTION
WARPED_CAUSAL, // 2-sided WARPED
#endif // CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT
NCOBMC_ADAPT_WEIGHT,
#endif
MOTION_MODES
} MOTION_MODE;
#if CONFIG_NCOBMC_ADAPT_WEIGHT
typedef enum {
ADAPT_OVERLAP_BLOCK_8X8,
ADAPT_OVERLAP_BLOCK_16X16,
ADAPT_OVERLAP_BLOCK_32X32,
ADAPT_OVERLAP_BLOCK_64X64,
ADAPT_OVERLAP_BLOCKS,
ADAPT_OVERLAP_BLOCK_INVALID = 255
} ADAPT_OVERLAP_BLOCK;
#endif
#if CONFIG_EXT_INTER
#if CONFIG_INTERINTRA
typedef enum {
@ -479,6 +577,12 @@ typedef enum {
#define INTRA_INTER_CONTEXTS 4
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
#if CONFIG_EXT_COMP_REFS
#define COMP_REF_TYPE_CONTEXTS 5
#define UNI_COMP_REF_CONTEXTS 3
#endif // CONFIG_EXT_COMP_REFS
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#define COMP_INTER_MODE_CONTEXTS 4
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
@ -497,9 +601,16 @@ typedef uint8_t TXFM_CONTEXT;
#define LAST3_FRAME 3
#define GOLDEN_FRAME 4
#define BWDREF_FRAME 5
#if CONFIG_ALTREF2
#define ALTREF2_FRAME 6
#define ALTREF_FRAME 7
#else // !CONFIG_ALTREF2
#define ALTREF_FRAME 6
#endif // CONFIG_ALTREF2
#define LAST_REF_FRAMES (LAST3_FRAME - LAST_FRAME + 1)
#else
#else // !CONFIG_EXT_REFS
#define GOLDEN_FRAME 2
#define ALTREF_FRAME 3
#endif // CONFIG_EXT_REFS
@ -518,7 +629,18 @@ typedef uint8_t TXFM_CONTEXT;
#endif // CONFIG_EXT_REFS
#define SINGLE_REFS (FWD_REFS + BWD_REFS)
#if CONFIG_EXT_COMP_REFS
typedef enum {
LAST_LAST2_FRAMES, // { LAST_FRAME, LAST2_FRAME }
LAST_LAST3_FRAMES, // { LAST_FRAME, LAST3_FRAME }
LAST_GOLDEN_FRAMES, // { LAST_FRAME, GOLDEN_FRAME }
BWDREF_ALTREF_FRAMES, // { BWDREF_FRAME, ALTREF_FRAME }
UNIDIR_COMP_REFS
} UNIDIR_COMP_REF;
#define COMP_REFS (FWD_REFS * BWD_REFS + UNIDIR_COMP_REFS)
#else // !CONFIG_EXT_COMP_REFS
#define COMP_REFS (FWD_REFS * BWD_REFS)
#endif // CONFIG_EXT_COMP_REFS
#define MODE_CTX_REF_FRAMES (TOTAL_REFS_PER_FRAME + COMP_REFS)
@ -539,11 +661,23 @@ typedef enum {
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_FRAME_SUPERRES
#define SUPERRES_SCALE_DENOMINATOR 16
#define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_NUMERATOR_MIN 8
#endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LPF_DIRECT
typedef enum {
VERT_HORZ,
DEGREE_30,
DEGREE_45,
DEGREE_60,
DEGREE_120,
DEGREE_135,
DEGREE_150,
FILTER_DEGREES,
} FILTER_DEGREE;
#endif // CONFIG_LPF_DIRECT
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -51,16 +51,20 @@ typedef enum {
#endif
} InterpFilter;
#if CONFIG_DUAL_FILTER
#define MAX_SUBPEL_TAPS 12
#if USE_EXTRA_FILTER
#define LOG_SWITCHABLE_FILTERS \
3 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
#else
#define LOG_SWITCHABLE_FILTERS \
2 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
#endif
#if CONFIG_DUAL_FILTER
#define MAX_SUBPEL_TAPS 12
#define SWITCHABLE_FILTER_CONTEXTS ((SWITCHABLE_FILTERS + 1) * 4)
#define INTER_FILTER_COMP_OFFSET (SWITCHABLE_FILTERS + 1)
#define INTER_FILTER_DIR_OFFSET ((SWITCHABLE_FILTERS + 1) * 2)
#else // CONFIG_DUAL_FILTER
#define LOG_SWITCHABLE_FILTERS \
2 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
#define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1)
#endif // CONFIG_DUAL_FILTER

View file

@ -22,9 +22,7 @@ void aom_cdf_init_q15_1D(uint16_t *cdf, int nsyms, int cdf_size) {
for (i = 0; i < nsyms; i++)
cdf[i] = AOM_ICDF((i + 1)*CDF_PROB_TOP/nsyms);
#if CONFIG_EC_ADAPT
cdf[cdf_size - 1] = 0;
#endif
}
/** Adapts a Q15 cdf after encoding/decoding a symbol. */

View file

@ -47,7 +47,7 @@ void generic_model_init(generic_encoder *model);
#define OD_CDFS_INIT_Q15(cdfs) \
{ int n_cdfs = sizeof(cdfs)/sizeof(cdfs[0]); \
int cdf_size = sizeof(cdfs[0])/sizeof(cdfs[0][0]); \
int nsyms = cdf_size - CONFIG_EC_ADAPT; \
int nsyms = cdf_size - 1; \
int i_; \
for (i_ = 0; i_ < n_cdfs; i_++) \
aom_cdf_init_q15_1D(cdfs[i_], nsyms, cdf_size); \

File diff suppressed because it is too large Load diff

View file

@ -26,19 +26,7 @@
extern "C" {
#endif
typedef struct INV_TXFM_PARAM {
#if CONFIG_ADAPT_SCAN
const int16_t *eob_threshold;
#endif
TX_TYPE tx_type;
TX_SIZE tx_size;
int eob;
int lossless;
#if CONFIG_HIGHBITDEPTH
int bd;
#endif
} INV_TXFM_PARAM;
// TODO(kslu) move the common stuff in idct.h to av1_txfm.h or txfm_common.h
typedef void (*transform_1d)(const tran_low_t *, tran_low_t *);
typedef struct {
@ -57,33 +45,33 @@ typedef struct {
int av1_get_tx_scale(const TX_SIZE tx_size);
void av1_iwht4x4_add(const tran_low_t *input, uint8_t *dest, int stride,
int eob);
const TxfmParam *txfm_param);
void av1_idct4x4_add(const tran_low_t *input, uint8_t *dest, int stride,
int eob);
const TxfmParam *txfm_param);
void av1_inv_txfm_add(const tran_low_t *input, uint8_t *dest, int stride,
INV_TXFM_PARAM *inv_txfm_param);
TxfmParam *txfm_param);
void av1_inverse_transform_block(const MACROBLOCKD *xd,
const tran_low_t *dqcoeff, TX_TYPE tx_type,
TX_SIZE tx_size, uint8_t *dst, int stride,
int eob);
const tran_low_t *dqcoeff,
#if CONFIG_LGT
PREDICTION_MODE mode,
#endif
TX_TYPE tx_type, TX_SIZE tx_size, uint8_t *dst,
int stride, int eob);
void av1_inverse_transform_block_facade(MACROBLOCKD *xd, int plane, int block,
int blk_row, int blk_col, int eob);
#if CONFIG_HIGHBITDEPTH
void av1_highbd_iwht4x4_add(const tran_low_t *input, uint8_t *dest, int stride,
int eob, int bd);
void av1_highbd_idct4x4_add(const tran_low_t *input, uint8_t *dest, int stride,
int eob, int bd);
void av1_highbd_inv_txfm_add_4x4(const tran_low_t *input, uint8_t *dest,
int stride, int eob, int bd, TX_TYPE tx_type,
int lossless);
int stride, const TxfmParam *param);
void av1_highbd_inv_txfm_add_4x8(const tran_low_t *input, uint8_t *dest,
int stride, int eob, int bd, TX_TYPE tx_type);
int stride, const TxfmParam *param);
void av1_highbd_inv_txfm_add_8x4(const tran_low_t *input, uint8_t *dest,
int stride, int eob, int bd, TX_TYPE tx_type);
int stride, const TxfmParam *param);
void av1_highbd_inv_txfm_add(const tran_low_t *input, uint8_t *dest, int stride,
INV_TXFM_PARAM *inv_txfm_param);
#endif // CONFIG_HIGHBITDEPTH
TxfmParam *txfm_param);
#if CONFIG_DPCM_INTRA
void av1_dpcm_inv_txfm_add_4_c(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, uint8_t *dest);
@ -98,16 +86,20 @@ typedef void (*dpcm_inv_txfm_add_func)(const tran_low_t *input, int stride,
dpcm_inv_txfm_add_func av1_get_dpcm_inv_txfm_add_func(int tx_length);
#if CONFIG_HIGHBITDEPTH
void av1_hbd_dpcm_inv_txfm_add_4_c(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, int bd, uint16_t *dest);
TX_TYPE_1D tx_type, int bd, uint16_t *dest,
int dir);
void av1_hbd_dpcm_inv_txfm_add_8_c(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, int bd, uint16_t *dest);
TX_TYPE_1D tx_type, int bd, uint16_t *dest,
int dir);
void av1_hbd_dpcm_inv_txfm_add_16_c(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, int bd, uint16_t *dest);
TX_TYPE_1D tx_type, int bd, uint16_t *dest,
int dir);
void av1_hbd_dpcm_inv_txfm_add_32_c(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, int bd, uint16_t *dest);
TX_TYPE_1D tx_type, int bd, uint16_t *dest,
int dir);
typedef void (*hbd_dpcm_inv_txfm_add_func)(const tran_low_t *input, int stride,
TX_TYPE_1D tx_type, int bd,
uint16_t *dest);
uint16_t *dest, int dir);
hbd_dpcm_inv_txfm_add_func av1_get_hbd_dpcm_inv_txfm_add_func(int tx_length);
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_DPCM_INTRA

View file

@ -16,19 +16,19 @@
#include "./av1_rtcd.h"
#include "av1/common/common.h"
#include "av1/common/blockd.h"
#include "av1/common/idct.h"
#include "aom_dsp/mips/inv_txfm_dspr2.h"
#include "aom_dsp/txfm_common.h"
#include "aom_ports/mem.h"
#if HAVE_DSPR2
void av1_iht16x16_256_add_dspr2(const int16_t *input, uint8_t *dest, int pitch,
int tx_type) {
TxfmParam *txfm_param) {
int i, j;
DECLARE_ALIGNED(32, int16_t, out[16 * 16]);
int16_t *outptr = out;
int16_t temp_out[16];
uint32_t pos = 45;
int tx_type = txfm_param->tx_type;
/* bit positon for extract from acc */
__asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos));

View file

@ -16,19 +16,19 @@
#include "./av1_rtcd.h"
#include "av1/common/common.h"
#include "av1/common/blockd.h"
#include "av1/common/idct.h"
#include "aom_dsp/mips/inv_txfm_dspr2.h"
#include "aom_dsp/txfm_common.h"
#include "aom_ports/mem.h"
#if HAVE_DSPR2
void av1_iht4x4_16_add_dspr2(const int16_t *input, uint8_t *dest,
int dest_stride, int tx_type) {
int dest_stride, TxfmParam *txfm_param) {
int i, j;
DECLARE_ALIGNED(32, int16_t, out[4 * 4]);
int16_t *outptr = out;
int16_t temp_in[4 * 4], temp_out[4];
uint32_t pos = 45;
int tx_type = txfm_param->tx_type;
/* bit positon for extract from acc */
__asm__ __volatile__("wrdsp %[pos], 1 \n\t"

View file

@ -22,12 +22,13 @@
#if HAVE_DSPR2
void av1_iht8x8_64_add_dspr2(const int16_t *input, uint8_t *dest,
int dest_stride, int tx_type) {
int dest_stride, TxfmParam *txfm_param) {
int i, j;
DECLARE_ALIGNED(32, int16_t, out[8 * 8]);
int16_t *outptr = out;
int16_t temp_in[8 * 8], temp_out[8];
uint32_t pos = 45;
int tx_type = txfm_param->tx_type;
/* bit positon for extract from acc */
__asm__ __volatile__("wrdsp %[pos], 1 \n\t" : : [pos] "r"(pos));

View file

@ -15,10 +15,11 @@
#include "aom_dsp/mips/inv_txfm_msa.h"
void av1_iht16x16_256_add_msa(const int16_t *input, uint8_t *dst,
int32_t dst_stride, int32_t tx_type) {
int32_t dst_stride, TxfmParam *txfm_param) {
int32_t i;
DECLARE_ALIGNED(32, int16_t, out[16 * 16]);
int16_t *out_ptr = &out[0];
int32_t tx_type = txfm_param->tx_type;
switch (tx_type) {
case DCT_DCT:

View file

@ -15,8 +15,9 @@
#include "aom_dsp/mips/inv_txfm_msa.h"
void av1_iht4x4_16_add_msa(const int16_t *input, uint8_t *dst,
int32_t dst_stride, int32_t tx_type) {
int32_t dst_stride, TxfmParam *txfm_param) {
v8i16 in0, in1, in2, in3;
int32_t tx_type = txfm_param->tx_type;
/* load vector elements of 4x4 block */
LD4x4_SH(input, in0, in1, in2, in3);

View file

@ -15,8 +15,9 @@
#include "aom_dsp/mips/inv_txfm_msa.h"
void av1_iht8x8_64_add_msa(const int16_t *input, uint8_t *dst,
int32_t dst_stride, int32_t tx_type) {
int32_t dst_stride, TxfmParam *txfm_param) {
v8i16 in0, in1, in2, in3, in4, in5, in6, in7;
int32_t tx_type = txfm_param->tx_type;
/* load vector elements of 8x8 block */
LD_SH8(input, 8, in0, in1, in2, in3, in4, in5, in6, in7);

View file

@ -35,18 +35,18 @@ typedef struct mv32 {
int32_t col;
} MV32;
#if (CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR) && CONFIG_GLOBAL_MOTION
#define SEPARATE_GLOBAL_MOTION 1
#endif // (CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR) && CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
#define WARPED_MOTION_SORT_SAMPLES 1
#endif // CONFIG_WARPED_MOTION
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
// Bits of precision used for the model
#define WARPEDMODEL_PREC_BITS 16
#define WARPEDMODEL_ROW3HOMO_PREC_BITS 16
#define WARPEDMODEL_TRANS_CLAMP (128 << WARPEDMODEL_PREC_BITS)
#define WARPEDMODEL_DIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS + 1))
#define WARPEDMODEL_NONDIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 1))
#define WARPEDMODEL_ROW3HOMO_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 1))
#define WARPEDMODEL_NONDIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 3))
#define WARPEDMODEL_ROW3HOMO_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 2))
// Bits of subpel precision for warped interpolation
#define WARPEDPIXEL_PREC_BITS 6
@ -88,6 +88,11 @@ typedef enum {
// GLOBAL_TRANS_TYPES 7 - up to full homography
#define GLOBAL_TRANS_TYPES 4
// First bit indicates whether using identity or not
// GLOBAL_TYPE_BITS=ceiling(log2(GLOBAL_TRANS_TYPES-1)) is the
// number of bits needed to cover the remaining possibilities
#define GLOBAL_TYPE_BITS (get_msb(2 * GLOBAL_TRANS_TYPES - 3))
typedef struct {
#if CONFIG_GLOBAL_MOTION
int global_warp_allowed;

View file

@ -840,17 +840,21 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
av1_set_ref_frame(rf, ref_frame);
zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
cm->allow_high_precision_mv, bsize,
mi_col, mi_row, 0)
.as_int;
zeromv[1].as_int = (rf[1] != NONE_FRAME)
? gm_get_motion_vector(&cm->global_motion[rf[1]],
cm->allow_high_precision_mv,
bsize, mi_col, mi_row, 0)
.as_int
: 0;
if (!CONFIG_INTRABC || ref_frame != INTRA_FRAME) {
av1_set_ref_frame(rf, ref_frame);
zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
cm->allow_high_precision_mv, bsize,
mi_col, mi_row, 0)
.as_int;
zeromv[1].as_int = (rf[1] != NONE_FRAME)
? gm_get_motion_vector(&cm->global_motion[rf[1]],
cm->allow_high_precision_mv,
bsize, mi_col, mi_row, 0)
.as_int
: 0;
} else {
zeromv[0].as_int = zeromv[1].as_int = 0;
}
#else
zeromv[0].as_int = zeromv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
@ -925,10 +929,10 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
assert(MAX_MV_REF_CANDIDATES == 2);
#if CONFIG_GLOBAL_MOTION
zeromv.as_int =
gm_get_motion_vector(&cm->global_motion[ref], cm->allow_high_precision_mv,
mi->mbmi.sb_type, mi_col, mi_row, block)
.as_int;
zeromv.as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
cm->allow_high_precision_mv,
mi->mbmi.sb_type, mi_col, mi_row, block)
.as_int;
#else
zeromv.as_int = 0;
#endif
@ -991,6 +995,262 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
}
#if CONFIG_WARPED_MOTION
#if WARPED_MOTION_SORT_SAMPLES
static INLINE void record_samples(MB_MODE_INFO *mbmi, int *pts, int *pts_inref,
int *pts_mv, int global_offset_r,
int global_offset_c, int row_offset,
int sign_r, int col_offset, int sign_c) {
int bw = block_size_wide[mbmi->sb_type];
int bh = block_size_high[mbmi->sb_type];
int cr_offset = row_offset * MI_SIZE + sign_r * AOMMAX(bh, MI_SIZE) / 2 - 1;
int cc_offset = col_offset * MI_SIZE + sign_c * AOMMAX(bw, MI_SIZE) / 2 - 1;
int x = cc_offset + global_offset_c;
int y = cr_offset + global_offset_r;
pts[0] = (x * 8);
pts[1] = (y * 8);
pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
pts_inref[1] = (y * 8) + mbmi->mv[0].as_mv.row;
pts_mv[0] = mbmi->mv[0].as_mv.col;
pts_mv[1] = mbmi->mv[0].as_mv.row;
}
// Only sort pts and pts_inref, and pts_mv is not sorted.
#define TRIM_THR 16
int sortSamples(int *pts_mv, MV *mv, int *pts, int *pts_inref, int len) {
int pts_mvd[SAMPLES_ARRAY_SIZE] = { 0 };
int i, j, k;
int ret = len;
for (i = 0; i < len; ++i)
pts_mvd[i] =
abs(pts_mv[2 * i] - mv->col) + abs(pts_mv[2 * i + 1] - mv->row);
for (i = 1; i <= len - 1; ++i) {
for (j = 0; j < i; ++j) {
if (pts_mvd[j] > pts_mvd[i]) {
int temp, tempi, tempj, ptempi, ptempj;
temp = pts_mvd[i];
tempi = pts[2 * i];
tempj = pts[2 * i + 1];
ptempi = pts_inref[2 * i];
ptempj = pts_inref[2 * i + 1];
for (k = i; k > j; k--) {
pts_mvd[k] = pts_mvd[k - 1];
pts[2 * k] = pts[2 * (k - 1)];
pts[2 * k + 1] = pts[2 * (k - 1) + 1];
pts_inref[2 * k] = pts_inref[2 * (k - 1)];
pts_inref[2 * k + 1] = pts_inref[2 * (k - 1) + 1];
}
pts_mvd[j] = temp;
pts[2 * j] = tempi;
pts[2 * j + 1] = tempj;
pts_inref[2 * j] = ptempi;
pts_inref[2 * j + 1] = ptempj;
break;
}
}
}
for (i = len - 1; i >= 1; i--) {
int low = (i == 1) ? 1 : AOMMAX((pts_mvd[i - 1] - pts_mvd[0]) / (i - 1), 1);
if ((pts_mvd[i] - pts_mvd[i - 1]) >= TRIM_THR * low) ret = i;
}
if (ret > LEAST_SQUARES_SAMPLES_MAX) ret = LEAST_SQUARES_SAMPLES_MAX;
return ret;
}
// Note: Samples returned are at 1/8-pel precision
int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
int *pts, int *pts_inref, int *pts_mv) {
MB_MODE_INFO *const mbmi0 = &(xd->mi[0]->mbmi);
int ref_frame = mbmi0->ref_frame[0];
int up_available = xd->up_available;
int left_available = xd->left_available;
int i, mi_step = 1, np = 0, n, j, k;
int global_offset_c = mi_col * MI_SIZE;
int global_offset_r = mi_row * MI_SIZE;
const TileInfo *const tile = &xd->tile;
// Search nb range in the unit of mi
int bs =
(AOMMAX(xd->n8_w, xd->n8_h) > 1) ? (AOMMAX(xd->n8_w, xd->n8_h) >> 1) : 1;
int marked[16 * 32]; // max array size for 128x128
int do_tl = 1;
int do_tr = 1;
// scan the above rows
if (up_available) {
for (n = 0; n < bs; n++) {
int mi_row_offset = -1 * (n + 1);
if (!n) {
MODE_INFO *mi = xd->mi[mi_row_offset * xd->mi_stride];
MB_MODE_INFO *mbmi = &mi->mbmi;
uint8_t n8_w = mi_size_wide[mbmi->sb_type];
// Handle "current block width <= above block width" case.
if (xd->n8_w <= n8_w) {
int col_offset = -mi_col % n8_w;
if (col_offset < 0) do_tl = 0;
if (col_offset + n8_w > xd->n8_w) do_tr = 0;
if (mbmi->ref_frame[0] == ref_frame &&
mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, 0, -1, col_offset, 1);
pts += 2;
pts_inref += 2;
pts_mv += 2;
np++;
}
break;
}
}
// Handle "current block width > above block width" case.
if (!n) memset(marked, 0, bs * xd->n8_w * sizeof(*marked));
for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
int mi_col_offset = i;
MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
MB_MODE_INFO *mbmi = &mi->mbmi;
uint8_t n8_w = mi_size_wide[mbmi->sb_type];
uint8_t n8_h = mi_size_high[mbmi->sb_type];
mi_step = AOMMIN(xd->n8_w, n8_w);
// Processed already
if (marked[n * xd->n8_w + i]) continue;
for (j = 0; j < AOMMIN(bs, n8_h); j++)
for (k = 0; k < AOMMIN(xd->n8_w, n8_w); k++)
marked[(n + j) * xd->n8_w + i + k] = 1;
if (mbmi->ref_frame[0] == ref_frame &&
mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, -n, -1, i, 1);
pts += 2;
pts_inref += 2;
pts_mv += 2;
np++;
}
}
}
}
assert(2 * np <= SAMPLES_ARRAY_SIZE);
// scan the left columns
if (left_available) {
for (n = 0; n < bs; n++) {
int mi_col_offset = -1 * (n + 1);
if (!n) {
MODE_INFO *mi = xd->mi[mi_col_offset];
MB_MODE_INFO *mbmi = &mi->mbmi;
uint8_t n8_h = mi_size_high[mbmi->sb_type];
// Handle "current block height <= above block height" case.
if (xd->n8_h <= n8_h) {
int row_offset = -mi_row % n8_h;
if (row_offset < 0) do_tl = 0;
if (mbmi->ref_frame[0] == ref_frame &&
mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, row_offset, 1, 0, -1);
pts += 2;
pts_inref += 2;
pts_mv += 2;
np++;
}
break;
}
}
// Handle "current block height > above block height" case.
if (!n) memset(marked, 0, bs * xd->n8_h * sizeof(*marked));
for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
int mi_row_offset = i;
MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
MB_MODE_INFO *mbmi = &mi->mbmi;
uint8_t n8_w = mi_size_wide[mbmi->sb_type];
uint8_t n8_h = mi_size_high[mbmi->sb_type];
mi_step = AOMMIN(xd->n8_h, n8_h);
// Processed already
if (marked[n * xd->n8_h + i]) continue;
for (j = 0; j < AOMMIN(bs, n8_w); j++)
for (k = 0; k < AOMMIN(xd->n8_h, n8_h); k++)
marked[(n + j) * xd->n8_h + i + k] = 1;
if (mbmi->ref_frame[0] == ref_frame &&
mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, i, 1, -n, -1);
pts += 2;
pts_inref += 2;
pts_mv += 2;
np++;
}
}
}
}
assert(2 * np <= SAMPLES_ARRAY_SIZE);
// Top-left block
if (do_tl && left_available && up_available) {
int mi_row_offset = -1;
int mi_col_offset = -1;
MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
MB_MODE_INFO *mbmi = &mi->mbmi;
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, 0, -1, 0, -1);
pts += 2;
pts_inref += 2;
pts_mv += 2;
np++;
}
}
assert(2 * np <= SAMPLES_ARRAY_SIZE);
// Top-right block
if (do_tr && has_top_right(xd, mi_row, mi_col, AOMMAX(xd->n8_w, xd->n8_h))) {
POSITION trb_pos = { -1, xd->n8_w };
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &trb_pos)) {
int mi_row_offset = -1;
int mi_col_offset = xd->n8_w;
MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
MB_MODE_INFO *mbmi = &mi->mbmi;
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
global_offset_c, 0, -1, xd->n8_w, 1);
np++;
}
}
}
assert(2 * np <= SAMPLES_ARRAY_SIZE);
return np;
}
#else
void calc_projection_samples(MB_MODE_INFO *const mbmi, int x, int y,
int *pts_inref) {
pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
@ -1095,4 +1355,5 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
return np;
}
#endif // WARPED_MOTION_SORT_SAMPLES
#endif // CONFIG_WARPED_MOTION

View file

@ -66,7 +66,7 @@ static const int mode_2_counter[] = {
#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
0, // SR_NEAREST_NEARMV
1, // SR_NEAREST_NEWMV
// 1, // SR_NEAREST_NEWMV
1, // SR_NEAR_NEWMV
3, // SR_ZERO_NEWMV
1, // SR_NEW_NEWMV
@ -196,11 +196,7 @@ static INLINE int is_inside(const TileInfo *const tile, int mi_col, int mi_row,
const int dependent_horz_tile_flag = 0;
(void)cm;
#endif
#if CONFIG_TILE_GROUPS
if (dependent_horz_tile_flag && !tile->tg_horz_boundary) {
#else
if (dependent_horz_tile_flag) {
#endif
return !(mi_row + mi_pos->row < 0 ||
mi_col + mi_pos->col < tile->mi_col_start ||
mi_row + mi_pos->row >= mi_rows ||
@ -238,10 +234,41 @@ static INLINE int av1_nmv_ctx(const uint8_t ref_mv_count,
return 0;
}
#if CONFIG_EXT_COMP_REFS
static INLINE int8_t av1_uni_comp_ref_idx(const MV_REFERENCE_FRAME *const rf) {
// Single ref pred
if (rf[1] <= INTRA_FRAME) return -1;
// Bi-directional comp ref pred
if ((rf[0] < BWDREF_FRAME) && (rf[1] >= BWDREF_FRAME)) return -1;
for (int8_t ref_idx = 0; ref_idx < UNIDIR_COMP_REFS; ++ref_idx) {
if (rf[0] == comp_ref0(ref_idx) && rf[1] == comp_ref1(ref_idx))
return ref_idx;
}
return -1;
}
#endif // CONFIG_EXT_COMP_REFS
static INLINE int8_t av1_ref_frame_type(const MV_REFERENCE_FRAME *const rf) {
if (rf[1] > INTRA_FRAME) {
return TOTAL_REFS_PER_FRAME + FWD_RF_OFFSET(rf[0]) +
BWD_RF_OFFSET(rf[1]) * FWD_REFS;
#if CONFIG_EXT_COMP_REFS
int8_t uni_comp_ref_idx = av1_uni_comp_ref_idx(rf);
#if !USE_UNI_COMP_REFS
// NOTE: uni-directional comp refs disabled
assert(uni_comp_ref_idx < 0);
#endif // !USE_UNI_COMP_REFS
if (uni_comp_ref_idx >= 0) {
assert((TOTAL_REFS_PER_FRAME + FWD_REFS * BWD_REFS + uni_comp_ref_idx) <
MODE_CTX_REF_FRAMES);
return TOTAL_REFS_PER_FRAME + FWD_REFS * BWD_REFS + uni_comp_ref_idx;
} else {
#endif // CONFIG_EXT_COMP_REFS
return TOTAL_REFS_PER_FRAME + FWD_RF_OFFSET(rf[0]) +
BWD_RF_OFFSET(rf[1]) * FWD_REFS;
#if CONFIG_EXT_COMP_REFS
}
#endif // CONFIG_EXT_COMP_REFS
}
return rf[0];
@ -253,11 +280,24 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = {
{ LAST_FRAME, BWDREF_FRAME }, { LAST2_FRAME, BWDREF_FRAME },
{ LAST3_FRAME, BWDREF_FRAME }, { GOLDEN_FRAME, BWDREF_FRAME },
#if CONFIG_ALTREF2
{ LAST_FRAME, ALTREF2_FRAME }, { LAST2_FRAME, ALTREF2_FRAME },
{ LAST3_FRAME, ALTREF2_FRAME }, { GOLDEN_FRAME, ALTREF2_FRAME },
#endif // CONFIG_ALTREF2
{ LAST_FRAME, ALTREF_FRAME }, { LAST2_FRAME, ALTREF_FRAME },
{ LAST3_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME }
#else
// TODO(zoeliu): Temporarily disable uni-directional comp refs
#if CONFIG_EXT_COMP_REFS
, { LAST_FRAME, LAST2_FRAME }, { LAST_FRAME, LAST3_FRAME },
{ LAST_FRAME, GOLDEN_FRAME }, { BWDREF_FRAME, ALTREF_FRAME }
// TODO(zoeliu): When ALTREF2 is enabled, we may add:
// {BWDREF_FRAME, ALTREF2_FRAME}
#endif // CONFIG_EXT_COMP_REFS
#else // !CONFIG_EXT_REFS
{ LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME }
#endif
#endif // CONFIG_EXT_REFS
};
// clang-format on
@ -352,8 +392,14 @@ void av1_update_mv_context(const AV1_COMMON *cm, const MACROBLOCKD *xd,
#endif // CONFIG_EXT_INTER
#if CONFIG_WARPED_MOTION
#if WARPED_MOTION_SORT_SAMPLES
int sortSamples(int *pts_mv, MV *mv, int *pts, int *pts_inref, int len);
int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
int *pts, int *pts_inref, int *pts_mv);
#else
int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
int *pts, int *pts_inref);
#endif // WARPED_MOTION_SORT_SAMPLES
#endif // CONFIG_WARPED_MOTION
#if CONFIG_INTRABC

View file

@ -202,9 +202,9 @@ void copy_4x4_16bit_to_16bit_c(uint16_t *dst, int dstride, const uint16_t *src,
for (j = 0; j < 4; j++) dst[i * dstride + j] = src[i * sstride + j];
}
void copy_dering_16bit_to_16bit(uint16_t *dst, int dstride, uint16_t *src,
dering_list *dlist, int dering_count,
int bsize) {
static void copy_dering_16bit_to_16bit(uint16_t *dst, int dstride,
uint16_t *src, dering_list *dlist,
int dering_count, int bsize) {
int bi, bx, by;
if (bsize == BLOCK_8X8) {

View file

@ -39,9 +39,6 @@ typedef void (*od_filter_dering_direction_func)(uint16_t *y, int ystride,
const uint16_t *in,
int threshold, int dir,
int damping);
void copy_dering_16bit_to_16bit(uint16_t *dst, int dstride, uint16_t *src,
dering_list *dlist, int dering_count,
int bsize);
int get_filter_skip(int level);

View file

@ -89,6 +89,12 @@ extern "C" {
typedef int od_coeff;
/*This is the strength reduced version of ((_a)/(1 << (_b))).
This will not work for _b == 0, however currently this is only used for
b == 1 anyway.*/
# define OD_UNBIASED_RSHIFT32(_a, _b) \
(((int32_t)(((uint32_t)(_a) >> (32 - (_b))) + (_a))) >> (_b))
#define OD_DIVU_DMAX (1024)
extern uint32_t OD_DIVU_SMALL_CONSTS[OD_DIVU_DMAX][2];

View file

@ -153,6 +153,10 @@ typedef struct BufferPool {
typedef struct AV1Common {
struct aom_internal_error_info error;
aom_color_space_t color_space;
#if CONFIG_COLORSPACE_HEADERS
aom_transfer_function_t transfer_function;
aom_chroma_sample_position_t chroma_sample_position;
#endif
int color_range;
int width;
int height;
@ -302,6 +306,9 @@ typedef struct AV1Common {
#if CONFIG_FRAME_SUPERRES
// The numerator of the superres scale; the denominator is fixed.
uint8_t superres_scale_numerator;
uint8_t superres_kf_scale_numerator;
int superres_upscaled_width;
int superres_upscaled_height;
#endif // CONFIG_FRAME_SUPERRES
#if CONFIG_LOOP_RESTORATION
RestorationInfo rst_info[MAX_MB_PLANE];
@ -316,7 +323,7 @@ typedef struct AV1Common {
struct loopfilter lf;
struct segmentation seg;
int all_lossless;
int frame_parallel_decode; // frame-based threading.
#if CONFIG_EXT_TX
@ -348,22 +355,19 @@ typedef struct AV1Common {
int error_resilient_mode;
#if !CONFIG_EXT_TILE
int log2_tile_cols, log2_tile_rows;
#endif // !CONFIG_EXT_TILE
int log2_tile_cols, log2_tile_rows; // Used in non-large_scale_tile_coding.
int tile_cols, tile_rows;
int tile_width, tile_height; // In MI units
#if CONFIG_EXT_TILE
unsigned int tile_encoding_mode;
unsigned int large_scale_tile;
unsigned int single_tile_decoding;
#endif // CONFIG_EXT_TILE
#if CONFIG_DEPENDENT_HORZTILES
int dependent_horz_tiles;
#if CONFIG_TILE_GROUPS
int tile_group_start_row[MAX_TILE_ROWS][MAX_TILE_COLS];
int tile_group_start_col[MAX_TILE_ROWS][MAX_TILE_COLS];
#endif
#endif
#if CONFIG_LOOPFILTERING_ACROSS_TILES
int loop_filter_across_tiles_enabled;
#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
@ -421,9 +425,7 @@ typedef struct AV1Common {
int delta_lf_res;
#endif
#endif
#if CONFIG_TILE_GROUPS
int num_tg;
#endif
#if CONFIG_REFERENCE_BUFFER
int current_frame_id;
int ref_frame_id[REF_FRAMES];
@ -505,6 +507,33 @@ static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) {
bufs[new_idx].ref_count++;
}
#if CONFIG_VAR_REFS
#define LAST_IS_VALID(cm) ((cm)->frame_refs[LAST_FRAME - 1].is_valid)
#define LAST2_IS_VALID(cm) ((cm)->frame_refs[LAST2_FRAME - 1].is_valid)
#define LAST3_IS_VALID(cm) ((cm)->frame_refs[LAST3_FRAME - 1].is_valid)
#define GOLDEN_IS_VALID(cm) ((cm)->frame_refs[GOLDEN_FRAME - 1].is_valid)
#define BWDREF_IS_VALID(cm) ((cm)->frame_refs[BWDREF_FRAME - 1].is_valid)
#if CONFIG_ALTREF2
#define ALTREF2_IS_VALID(cm) ((cm)->frame_refs[ALTREF2_FRAME - 1].is_valid)
#endif // CONFIG_ALTREF2
#define ALTREF_IS_VALID(cm) ((cm)->frame_refs[ALTREF_FRAME - 1].is_valid)
#define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm))
#define L_AND_L2(cm) (LAST_IS_VALID(cm) && LAST2_IS_VALID(cm))
#define L_AND_L3(cm) (LAST_IS_VALID(cm) && LAST3_IS_VALID(cm))
#define L_AND_G(cm) (LAST_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
#define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm))
#define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
#if CONFIG_ALTREF2
#define BWD_OR_ALT2(cm) (BWDREF_IS_VALID(cm) || ALTREF2_IS_VALID(cm))
#define BWD_AND_ALT2(cm) (BWDREF_IS_VALID(cm) && ALTREF2_IS_VALID(cm))
#endif // CONFIG_ALTREF2
#define BWD_OR_ALT(cm) (BWDREF_IS_VALID(cm) || ALTREF_IS_VALID(cm))
#define BWD_AND_ALT(cm) (BWDREF_IS_VALID(cm) && ALTREF_IS_VALID(cm))
#endif // CONFIG_VAR_REFS
static INLINE int mi_cols_aligned_to_sb(const AV1_COMMON *cm) {
return ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
}
@ -525,16 +554,10 @@ static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd,
CFL_CTX *cfl,
#endif
tran_low_t *dqcoeff) {
int i;
for (i = 0; i < MAX_MB_PLANE; ++i) {
for (int i = 0; i < MAX_MB_PLANE; ++i) {
xd->plane[i].dqcoeff = dqcoeff;
#if CONFIG_PVQ
xd->plane[i].pvq_ref_coeff = pvq_ref_coeff;
#endif
#if CONFIG_CFL
xd->cfl = cfl;
cfl_init(cfl, cm, xd->plane[AOM_PLANE_U].subsampling_x,
xd->plane[AOM_PLANE_U].subsampling_y);
#endif
xd->above_context[i] = cm->above_context[i];
if (xd->plane[i].plane_type == PLANE_TYPE_Y) {
@ -558,11 +581,15 @@ static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd,
sizeof(cm->uv_dequant_nuq));
#endif
}
xd->fc = cm->fc;
}
xd->fc = cm->fc;
xd->above_seg_context = cm->above_seg_context;
#if CONFIG_VAR_TX
xd->above_txfm_context = cm->above_txfm_context;
#endif
#if CONFIG_CFL
cfl_init(cfl, cm);
xd->cfl = cfl;
#endif
xd->mi_stride = cm->mi_stride;
xd->error_info = &cm->error;
@ -623,11 +650,7 @@ static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile,
#if CONFIG_DEPENDENT_HORZTILES
if (dependent_horz_tile_flag) {
#if CONFIG_TILE_GROUPS
xd->up_available = (mi_row > tile->mi_row_start) || !tile->tg_horz_boundary;
#else
xd->up_available = (mi_row > 0);
#endif // CONFIG_TILE_GROUPS
} else {
#endif // CONFIG_DEPENDENT_HORZTILES
// Are edges available for intra prediction?
@ -742,6 +765,20 @@ static INLINE int is_chroma_reference(int mi_row, int mi_col, BLOCK_SIZE bsize,
#endif
}
#if CONFIG_SUPERTX
static INLINE int need_handle_chroma_sub8x8(BLOCK_SIZE bsize, int subsampling_x,
int subsampling_y) {
const int bw = mi_size_wide[bsize];
const int bh = mi_size_high[bsize];
if (bsize >= BLOCK_8X8 ||
((!(bh & 0x01) || !subsampling_y) && (!(bw & 0x01) || !subsampling_x)))
return 0;
else
return 1;
}
#endif
static INLINE BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
int subsampling_y) {
BLOCK_SIZE bs = bsize;
@ -773,6 +810,8 @@ static INLINE void update_ext_partition_context(MACROBLOCKD *xd, int mi_row,
case PARTITION_NONE:
case PARTITION_HORZ:
case PARTITION_VERT:
case PARTITION_HORZ_4:
case PARTITION_VERT_4:
update_partition_context(xd, mi_row, mi_col, subsize, bsize);
break;
case PARTITION_HORZ_A:
@ -861,6 +900,24 @@ static INLINE int max_block_high(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
return max_blocks_high >> tx_size_wide_log2[0];
}
#if CONFIG_CFL
static INLINE int max_intra_block_width(const MACROBLOCKD *xd,
BLOCK_SIZE plane_bsize, int plane,
TX_SIZE tx_size) {
const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane)
<< tx_size_wide_log2[0];
return ALIGN_POWER_OF_TWO(max_blocks_wide, tx_size_wide_log2[tx_size]);
}
static INLINE int max_intra_block_height(const MACROBLOCKD *xd,
BLOCK_SIZE plane_bsize, int plane,
TX_SIZE tx_size) {
const int max_blocks_high = max_block_high(xd, plane_bsize, plane)
<< tx_size_high_log2[0];
return ALIGN_POWER_OF_TWO(max_blocks_high, tx_size_high_log2[tx_size]);
}
#endif // CONFIG_CFL
static INLINE void av1_zero_above_context(AV1_COMMON *const cm,
int mi_col_start, int mi_col_end) {
const int width = mi_col_end - mi_col_start;
@ -891,12 +948,22 @@ static INLINE void av1_zero_left_context(MACROBLOCKD *const xd) {
#endif
}
#if CONFIG_VAR_TX
// Disable array-bounds checks as the TX_SIZE enum contains values larger than
// TX_SIZES_ALL (TX_INVALID) which make extending the array as a workaround
// infeasible. The assert is enough for static analysis and this or other tools
// asan, valgrind would catch oob access at runtime.
#if defined(__GNUC__) && __GNUC__ >= 4
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
static INLINE TX_SIZE get_min_tx_size(TX_SIZE tx_size) {
assert(tx_size < TX_SIZES_ALL);
return txsize_sqr_map[tx_size];
}
#if defined(__GNUC__) && __GNUC__ >= 4
#pragma GCC diagnostic warning "-Warray-bounds"
#endif
#if CONFIG_VAR_TX
static INLINE void set_txfm_ctx(TXFM_CONTEXT *txfm_ctx, uint8_t txs, int len) {
int i;
for (i = 0; i < len; ++i) txfm_ctx[i] = txs;
@ -986,6 +1053,9 @@ static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
assert(cm->mi_grid_visible[offset] == &cm->mi[offset]);
if (partition == PARTITION_HORZ_4 || partition == PARTITION_VERT_4)
return partition;
if (partition != PARTITION_NONE && bsize > BLOCK_8X8 &&
mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
const BLOCK_SIZE h = get_subsize(bsize, PARTITION_HORZ_A);
@ -1020,6 +1090,22 @@ static INLINE void set_sb_size(AV1_COMMON *const cm, BLOCK_SIZE sb_size) {
#endif
}
static INLINE int all_lossless(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
int i;
int all_lossless = 1;
if (cm->seg.enabled) {
for (i = 0; i < MAX_SEGMENTS; ++i) {
if (!xd->lossless[i]) {
all_lossless = 0;
break;
}
}
} else {
all_lossless = xd->lossless[0];
}
return all_lossless;
}
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -223,27 +223,34 @@ int av1_get_intra_inter_context(const MACROBLOCKD *xd) {
// The compound/single mode info data structure has one element border above and
// to the left of the entries corresponding to real macroblocks.
// The prediction flags in these dummy entries are initialized to 0.
// 0 - single/single
// 1 - single/--, --/single, --/--
// 2 - single/comp, comp/single
// 3 - comp/comp, comp/--, --/comp
int av1_get_inter_mode_context(const MACROBLOCKD *xd) {
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int has_above = xd->up_available;
const int has_left = xd->left_available;
if (has_above && has_left) { // both edges available (0/2/3)
const int above_inter_comp_mode = is_inter_compound_mode(above_mbmi->mode);
const int left_inter_comp_mode = is_inter_compound_mode(left_mbmi->mode);
return (above_inter_comp_mode && left_inter_comp_mode)
? 3
: (above_inter_comp_mode || left_inter_comp_mode) * 2;
} else if (has_above || has_left) { // one edge available (1/3)
if (has_above && has_left) { // both edges available
const int above_inter_comp_mode =
is_inter_anyref_comp_mode(above_mbmi->mode);
const int left_inter_comp_mode = is_inter_anyref_comp_mode(left_mbmi->mode);
if (above_inter_comp_mode && left_inter_comp_mode)
return 0;
else if (above_inter_comp_mode || left_inter_comp_mode)
return 1;
else if (!is_inter_block(above_mbmi) && !is_inter_block(left_mbmi))
return 2;
else
return 3;
} else if (has_above || has_left) { // one edge available
const MB_MODE_INFO *const edge_mbmi = has_above ? above_mbmi : left_mbmi;
return is_inter_compound_mode(edge_mbmi->mode) ? 3 : 1;
} else { // no edge available (1)
return 1;
if (is_inter_anyref_comp_mode(edge_mbmi->mode))
return 1;
else if (!is_inter_block(edge_mbmi))
return 2;
else
return 3;
} else { // no edge available
return 2;
}
}
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
@ -256,6 +263,9 @@ int av1_get_inter_mode_context(const MACROBLOCKD *xd) {
#define IS_BACKWARD_REF_FRAME(ref_frame) ((ref_frame) == cm->comp_fixed_ref)
#endif // CONFIG_EXT_REFS
#define CHECK_GOLDEN_OR_LAST3(ref_frame) \
(((ref_frame) == GOLDEN_FRAME) || ((ref_frame) == LAST3_FRAME))
int av1_get_reference_mode_context(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
int ctx;
@ -303,6 +313,247 @@ int av1_get_reference_mode_context(const AV1_COMMON *cm,
return ctx;
}
#if CONFIG_EXT_COMP_REFS
#define CHECK_BWDREF_OR_ALTREF(ref_frame) \
((ref_frame) == BWDREF_FRAME || (ref_frame) == ALTREF_FRAME)
// TODO(zoeliu): To try on the design of 3 contexts, instead of 5:
// COMP_REF_TYPE_CONTEXTS = 3
int av1_get_comp_reference_type_context(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
if (above_in_image && left_in_image) { // both edges available
const int above_intra = !is_inter_block(above_mbmi);
const int left_intra = !is_inter_block(left_mbmi);
if (above_intra && left_intra) { // intra/intra
pred_context = 2;
} else if (above_intra || left_intra) { // intra/inter
const MB_MODE_INFO *inter_mbmi = above_intra ? left_mbmi : above_mbmi;
if (!has_second_ref(inter_mbmi)) // single pred
pred_context = 2;
else // comp pred
pred_context = 1 + 2 * has_uni_comp_refs(inter_mbmi);
} else { // inter/inter
const int a_sg = !has_second_ref(above_mbmi);
const int l_sg = !has_second_ref(left_mbmi);
const MV_REFERENCE_FRAME frfa = above_mbmi->ref_frame[0];
const MV_REFERENCE_FRAME frfl = left_mbmi->ref_frame[0];
if (a_sg && l_sg) { // single/single
pred_context = 1 +
2 * (!(CHECK_BWDREF_OR_ALTREF(frfa) ^
CHECK_BWDREF_OR_ALTREF(frfl)));
} else if (l_sg || a_sg) { // single/comp
const int uni_rfc =
a_sg ? has_uni_comp_refs(left_mbmi) : has_uni_comp_refs(above_mbmi);
if (!uni_rfc) // comp bidir
pred_context = 1;
else // comp unidir
pred_context = 3 + (!(CHECK_BWDREF_OR_ALTREF(frfa) ^
CHECK_BWDREF_OR_ALTREF(frfl)));
} else { // comp/comp
const int a_uni_rfc = has_uni_comp_refs(above_mbmi);
const int l_uni_rfc = has_uni_comp_refs(left_mbmi);
if (!a_uni_rfc && !l_uni_rfc) // bidir/bidir
pred_context = 0;
else if (!a_uni_rfc || !l_uni_rfc) // unidir/bidir
pred_context = 2;
else // unidir/unidir
pred_context =
3 + (!((frfa == BWDREF_FRAME) ^ (frfl == BWDREF_FRAME)));
}
}
} else if (above_in_image || left_in_image) { // one edge available
const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
if (!is_inter_block(edge_mbmi)) { // intra
pred_context = 2;
} else { // inter
if (!has_second_ref(edge_mbmi)) // single pred
pred_context = 2;
else // comp pred
pred_context = 4 * has_uni_comp_refs(edge_mbmi);
}
} else { // no edges available
pred_context = 2;
}
assert(pred_context >= 0 && pred_context < COMP_REF_TYPE_CONTEXTS);
return pred_context;
}
// Returns a context number for the given MB prediction signal
//
// Signal the uni-directional compound reference frame pair as either
// (BWDREF, ALTREF), or (LAST, LAST2) / (LAST, LAST3) / (LAST, GOLDEN),
// conditioning on the pair is known as uni-directional.
//
// 3 contexts: Voting is used to compare the count of forward references with
// that of backward references from the spatial neighbors.
int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Count of forward references (L, L2, L3, or G)
int frf_count = 0;
// Count of backward references (B or A)
int brf_count = 0;
if (above_in_image && is_inter_block(above_mbmi)) {
if (above_mbmi->ref_frame[0] <= GOLDEN_FRAME)
++frf_count;
else
++brf_count;
if (has_second_ref(above_mbmi)) {
if (above_mbmi->ref_frame[1] <= GOLDEN_FRAME)
++frf_count;
else
++brf_count;
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
if (left_mbmi->ref_frame[0] <= GOLDEN_FRAME)
++frf_count;
else
++brf_count;
if (has_second_ref(left_mbmi)) {
if (left_mbmi->ref_frame[1] <= GOLDEN_FRAME)
++frf_count;
else
++brf_count;
}
}
pred_context =
(frf_count == brf_count) ? 1 : ((frf_count < brf_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
return pred_context;
}
// Returns a context number for the given MB prediction signal
//
// Signal the uni-directional compound reference frame pair as
// either (LAST, LAST2), or (LAST, LAST3) / (LAST, GOLDEN),
// conditioning on the pair is known as one of the above three.
//
// 3 contexts: Voting is used to compare the count of LAST2_FRAME with the
// total count of LAST3/GOLDEN from the spatial neighbors.
int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Count of LAST2
int last2_count = 0;
// Count of LAST3 or GOLDEN
int last3_or_gld_count = 0;
if (above_in_image && is_inter_block(above_mbmi)) {
last2_count = (above_mbmi->ref_frame[0] == LAST2_FRAME) ? last2_count + 1
: last2_count;
last3_or_gld_count = CHECK_GOLDEN_OR_LAST3(above_mbmi->ref_frame[0])
? last3_or_gld_count + 1
: last3_or_gld_count;
if (has_second_ref(above_mbmi)) {
last2_count = (above_mbmi->ref_frame[1] == LAST2_FRAME) ? last2_count + 1
: last2_count;
last3_or_gld_count = CHECK_GOLDEN_OR_LAST3(above_mbmi->ref_frame[1])
? last3_or_gld_count + 1
: last3_or_gld_count;
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
last2_count = (left_mbmi->ref_frame[0] == LAST2_FRAME) ? last2_count + 1
: last2_count;
last3_or_gld_count = CHECK_GOLDEN_OR_LAST3(left_mbmi->ref_frame[0])
? last3_or_gld_count + 1
: last3_or_gld_count;
if (has_second_ref(left_mbmi)) {
last2_count = (left_mbmi->ref_frame[1] == LAST2_FRAME) ? last2_count + 1
: last2_count;
last3_or_gld_count = CHECK_GOLDEN_OR_LAST3(left_mbmi->ref_frame[1])
? last3_or_gld_count + 1
: last3_or_gld_count;
}
}
pred_context = (last2_count == last3_or_gld_count)
? 1
: ((last2_count < last3_or_gld_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
return pred_context;
}
// Returns a context number for the given MB prediction signal
//
// Signal the uni-directional compound reference frame pair as
// either (LAST, LAST3) or (LAST, GOLDEN),
// conditioning on the pair is known as one of the above two.
//
// 3 contexts: Voting is used to compare the count of LAST3_FRAME with the
// total count of GOLDEN_FRAME from the spatial neighbors.
int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Count of LAST3
int last3_count = 0;
// Count of GOLDEN
int gld_count = 0;
if (above_in_image && is_inter_block(above_mbmi)) {
last3_count = (above_mbmi->ref_frame[0] == LAST3_FRAME) ? last3_count + 1
: last3_count;
gld_count =
(above_mbmi->ref_frame[0] == GOLDEN_FRAME) ? gld_count + 1 : gld_count;
if (has_second_ref(above_mbmi)) {
last3_count = (above_mbmi->ref_frame[1] == LAST3_FRAME) ? last3_count + 1
: last3_count;
gld_count = (above_mbmi->ref_frame[1] == GOLDEN_FRAME) ? gld_count + 1
: gld_count;
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
last3_count = (left_mbmi->ref_frame[0] == LAST3_FRAME) ? last3_count + 1
: last3_count;
gld_count =
(left_mbmi->ref_frame[0] == GOLDEN_FRAME) ? gld_count + 1 : gld_count;
if (has_second_ref(left_mbmi)) {
last3_count = (left_mbmi->ref_frame[1] == LAST3_FRAME) ? last3_count + 1
: last3_count;
gld_count =
(left_mbmi->ref_frame[1] == GOLDEN_FRAME) ? gld_count + 1 : gld_count;
}
}
pred_context =
(last3_count == gld_count) ? 1 : ((last3_count < gld_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < UNI_COMP_REF_CONTEXTS);
return pred_context;
}
#endif // CONFIG_EXT_COMP_REFS
#if CONFIG_EXT_REFS
// TODO(zoeliu): Future work will be conducted to optimize the context design
@ -311,22 +562,14 @@ int av1_get_reference_mode_context(const AV1_COMMON *cm,
#define CHECK_LAST_OR_LAST2(ref_frame) \
((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME))
#define CHECK_GOLDEN_OR_LAST3(ref_frame) \
((ref_frame == GOLDEN_FRAME) || (ref_frame == LAST3_FRAME))
// Returns a context number for the given MB prediction signal
// Signal the first reference frame for a compound mode be either
// GOLDEN/LAST3, or LAST/LAST2.
//
// NOTE(zoeliu): The probability of ref_frame[0] is either
// GOLDEN_FRAME or LAST3_FRAME.
#if CONFIG_ONE_SIDED_COMPOUND
int av1_get_pred_context_comp_ref_p(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#endif
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
@ -337,14 +580,16 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS // No change to bitstream
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
if (above_in_image && left_in_image) { // both edges available
const int above_intra = !is_inter_block(above_mbmi);
const int left_intra = !is_inter_block(left_mbmi);
@ -396,8 +641,11 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
if ((CHECK_LAST_OR_LAST2(frfa) && CHECK_LAST_OR_LAST2(frfl))) {
pred_context = 4;
} else {
// NOTE(zoeliu): Following assert may be removed once confirmed.
// NOTE(zoeliu): Following assert may be removed once confirmed.
#if !USE_UNI_COMP_REFS
// TODO(zoeliu): To further study the UNIDIR scenario
assert(CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl));
#endif // !USE_UNI_COMP_REFS
pred_context = 2;
}
}
@ -430,13 +678,8 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
//
// NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME,
// conditioning on it is either LAST_FRAME or LAST2_FRAME.
#if CONFIG_ONE_SIDED_COMPOUND
int av1_get_pred_context_comp_ref_p1(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#endif
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
@ -447,14 +690,16 @@ int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS // No change to bitstream
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
if (above_in_image && left_in_image) { // both edges available
const int above_intra = !is_inter_block(above_mbmi);
const int left_intra = !is_inter_block(left_mbmi);
@ -541,13 +786,8 @@ int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
//
// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME,
// conditioning on it is either GOLDEN or LAST3.
#if CONFIG_ONE_SIDED_COMPOUND
int av1_get_pred_context_comp_ref_p2(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#endif
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
@ -558,14 +798,16 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries correpsonding to real macroblocks.
// The prediction flags in these dummy entries are initialised to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS // No change to bitstream
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
if (above_in_image && left_in_image) { // both edges available
const int above_intra = !is_inter_block(above_mbmi);
const int left_intra = !is_inter_block(left_mbmi);
@ -645,14 +887,113 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
return pred_context;
}
// Returns a context number for the given MB prediction signal
#if CONFIG_ONE_SIDED_COMPOUND
int av1_get_pred_context_comp_bwdref_p(UNUSED const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#else
#if CONFIG_ALTREF2
// Obtain contexts to signal a reference frame be either BWDREF/ALTREF2, or
// ALTREF.
int av1_get_pred_context_brfarf2_or_arf(const MACROBLOCKD *xd) {
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Counts of BWDREF, ALTREF2, or ALTREF frames (B, A2, or A)
int bwdref_counts[ALTREF_FRAME - BWDREF_FRAME + 1] = { 0 };
if (above_in_image && is_inter_block(above_mbmi)) {
if (above_mbmi->ref_frame[0] >= BWDREF_FRAME)
++bwdref_counts[above_mbmi->ref_frame[0] - BWDREF_FRAME];
if (has_second_ref(above_mbmi)) {
if (above_mbmi->ref_frame[1] >= BWDREF_FRAME)
++bwdref_counts[above_mbmi->ref_frame[1] - BWDREF_FRAME];
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
if (left_mbmi->ref_frame[0] >= BWDREF_FRAME)
++bwdref_counts[left_mbmi->ref_frame[0] - BWDREF_FRAME];
if (has_second_ref(left_mbmi)) {
if (left_mbmi->ref_frame[1] >= BWDREF_FRAME)
++bwdref_counts[left_mbmi->ref_frame[1] - BWDREF_FRAME];
}
}
const int brfarf2_count = bwdref_counts[BWDREF_FRAME - BWDREF_FRAME] +
bwdref_counts[ALTREF2_FRAME - BWDREF_FRAME];
const int arf_count = bwdref_counts[ALTREF_FRAME - BWDREF_FRAME];
const int pred_context =
(brfarf2_count == arf_count) ? 1 : ((brfarf2_count < arf_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
}
// Obtain contexts to signal a reference frame be either BWDREF or ALTREF2.
int av1_get_pred_context_brf_or_arf2(const MACROBLOCKD *xd) {
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Count of BWDREF frames (B)
int brf_count = 0;
// Count of ALTREF2 frames (A2)
int arf2_count = 0;
if (above_in_image && is_inter_block(above_mbmi)) {
if (above_mbmi->ref_frame[0] == BWDREF_FRAME)
++brf_count;
else if (above_mbmi->ref_frame[0] == ALTREF2_FRAME)
++arf2_count;
if (has_second_ref(above_mbmi)) {
if (above_mbmi->ref_frame[1] == BWDREF_FRAME)
++brf_count;
else if (above_mbmi->ref_frame[1] == ALTREF2_FRAME)
++arf2_count;
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
if (left_mbmi->ref_frame[0] == BWDREF_FRAME)
++brf_count;
else if (left_mbmi->ref_frame[0] == ALTREF2_FRAME)
++arf2_count;
if (has_second_ref(left_mbmi)) {
if (left_mbmi->ref_frame[1] == BWDREF_FRAME)
++brf_count;
else if (left_mbmi->ref_frame[1] == ALTREF2_FRAME)
++arf2_count;
}
}
const int pred_context =
(brf_count == arf2_count) ? 1 : ((brf_count < arf2_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
}
// Signal the 2nd reference frame for a compound mode be either
// ALTREF, or ALTREF2/BWDREF.
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
(void)cm;
return av1_get_pred_context_brfarf2_or_arf(xd);
}
// Signal the 2nd reference frame for a compound mode be either
// ALTREF2 or BWDREF.
int av1_get_pred_context_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
(void)cm;
return av1_get_pred_context_brf_or_arf2(xd);
}
#else // !CONFIG_ALTREF2
// Returns a context number for the given MB prediction signal
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
#endif
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
@ -663,14 +1004,16 @@ int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real macroblocks.
// The prediction flags in these dummy entries are initialized to 0.
#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
#if CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS // No change to bitstream
// Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
const int bwd_ref_sign_idx = 1;
#else
const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#endif
#endif // CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS
const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
(void)cm;
if (above_in_image && left_in_image) { // both edges available
const int above_intra = !is_inter_block(above_mbmi);
const int left_intra = !is_inter_block(left_mbmi);
@ -709,8 +1052,11 @@ int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
a_brf == cm->comp_bwd_ref[1]) {
pred_context = 1;
} else {
// NOTE: Backward ref should be either BWDREF or ALTREF.
// NOTE: Backward ref should be either BWDREF or ALTREF.
#if !USE_UNI_COMP_REFS
// TODO(zoeliu): To further study the UNIDIR scenario
assert(l_brf == a_brf && l_brf != cm->comp_bwd_ref[1]);
#endif // !USE_UNI_COMP_REFS
pred_context = 3;
}
} else if (!l_comp && !a_comp) { // single/single
@ -722,8 +1068,11 @@ int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
} else if (l_frf == a_frf) {
pred_context = 3;
} else {
#if !USE_UNI_COMP_REFS
// TODO(zoeliu): To further study the UNIDIR scenario
assert(l_frf != a_frf && l_frf != cm->comp_bwd_ref[1] &&
a_frf != cm->comp_bwd_ref[1]);
#endif // !USE_UNI_COMP_REFS
pred_context = 4;
}
} else { // comp/single
@ -764,8 +1113,9 @@ int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
return pred_context;
}
#endif // CONFIG_ALTREF2
#else // CONFIG_EXT_REFS
#else // !CONFIG_EXT_REFS
// Returns a context number for the given MB prediction signal
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
@ -854,10 +1204,8 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
#if CONFIG_EXT_REFS
// For the bit to signal whether the single reference is a ALTREF_FRAME
// or a BWDREF_FRAME.
//
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF/BWDREF.
// For the bit to signal whether the single reference is a forward reference
// frame or a backward reference frame.
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
@ -919,11 +1267,12 @@ int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
}
// For the bit to signal whether the single reference is ALTREF_FRAME or
// BWDREF_FRAME, knowing that it shall be either of these 2 choices.
//
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF_FRAME, conditioning
// on it is either ALTREF_FRAME/BWDREF_FRAME.
// non-ALTREF backward reference frame, knowing that it shall be either of
// these 2 choices.
int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
#if CONFIG_ALTREF2
return av1_get_pred_context_brfarf2_or_arf(xd);
#else // !CONFIG_ALTREF2
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
@ -1010,13 +1359,11 @@ int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
#endif // CONFIG_ALTREF2
}
// For the bit to signal whether the single reference is LAST3/GOLDEN or
// LAST2/LAST, knowing that it shall be either of these 2 choices.
//
// NOTE(zoeliu): The probability of ref_frame[0] is LAST3/GOLDEN, conditioning
// on it is either LAST3/GOLDEN/LAST2/LAST.
int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
@ -1293,7 +1640,15 @@ int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd) {
return pred_context;
}
#else // CONFIG_EXT_REFS
#if CONFIG_ALTREF2
// For the bit to signal whether the single reference is ALTREF2_FRAME or
// BWDREF_FRAME, knowing that it shall be either of these 2 choices.
int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd) {
return av1_get_pred_context_brf_or_arf2(xd);
}
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
int pred_context;

View file

@ -54,6 +54,13 @@ static INLINE aom_prob av1_get_pred_prob_seg_id(
return segp->pred_probs[av1_get_pred_context_seg_id(xd)];
}
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_seg_id(
struct segmentation_probs *segp, const MACROBLOCKD *xd) {
return segp->pred_cdf[av1_get_pred_context_seg_id(xd)];
}
#endif
static INLINE int av1_get_skip_context(const MACROBLOCKD *xd) {
const MODE_INFO *const above_mi = xd->above_mi;
const MODE_INFO *const left_mi = xd->left_mi;
@ -101,10 +108,83 @@ static INLINE aom_prob av1_get_reference_mode_prob(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->comp_inter_prob[av1_get_reference_mode_context(cm, xd)];
}
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_reference_mode_cdf(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context(cm, xd)];
}
#endif
#if CONFIG_EXT_COMP_REFS
int av1_get_comp_reference_type_context(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_comp_reference_type_prob(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->comp_ref_type_prob[av1_get_comp_reference_type_context(xd)];
}
int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_uni_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
return cm->fc->uni_comp_ref_prob[pred_context][0];
}
int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd);
static INLINE aom_prob
av1_get_pred_prob_uni_comp_ref_p1(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
return cm->fc->uni_comp_ref_prob[pred_context][1];
}
int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd);
static INLINE aom_prob
av1_get_pred_prob_uni_comp_ref_p2(const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
return cm->fc->uni_comp_ref_prob[pred_context][2];
}
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_comp_reference_type_cdf(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_comp_reference_type_context(xd);
return xd->tile_ctx->comp_ref_type_cdf[pred_context];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2(
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
}
#endif // CONFIG_NEW_MULTISYMBOL
#endif // CONFIG_EXT_COMP_REFS
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p(cm, xd);
return xd->tile_ctx->comp_ref_cdf[pred_context][0];
}
#endif
static INLINE aom_prob av1_get_pred_prob_comp_ref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p(cm, xd);
@ -115,6 +195,14 @@ static INLINE aom_prob av1_get_pred_prob_comp_ref_p(const AV1_COMMON *cm,
int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p1(cm, xd);
return xd->tile_ctx->comp_ref_cdf[pred_context][1];
}
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p1(cm, xd);
@ -124,6 +212,14 @@ static INLINE aom_prob av1_get_pred_prob_comp_ref_p1(const AV1_COMMON *cm,
int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p2(cm, xd);
return xd->tile_ctx->comp_ref_cdf[pred_context][2];
}
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_ref_p2(cm, xd);
@ -133,11 +229,31 @@ static INLINE aom_prob av1_get_pred_prob_comp_ref_p2(const AV1_COMMON *cm,
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
}
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][0];
}
#if CONFIG_ALTREF2
// TODO(zoeliu): ALTREF2 to work with NEW_MULTISYMBOL
int av1_get_pred_context_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p1(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][1];
}
#endif // CONFIG_ALTREF2
#endif // CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
@ -175,8 +291,52 @@ static INLINE aom_prob av1_get_pred_prob_single_ref_p5(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p5(xd)][4];
}
#if CONFIG_ALTREF2
int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p6(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p6(xd)][5];
}
#endif // CONFIG_ALTREF2
#endif // CONFIG_EXT_REFS
#if CONFIG_NEW_MULTISYMBOL
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p1(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
return xd->tile_ctx
->single_ref_cdf[av1_get_pred_context_single_ref_p1(xd)][0];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p2(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
return xd->tile_ctx
->single_ref_cdf[av1_get_pred_context_single_ref_p2(xd)][1];
}
#if CONFIG_EXT_REFS
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p3(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
return xd->tile_ctx
->single_ref_cdf[av1_get_pred_context_single_ref_p3(xd)][2];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p4(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
return xd->tile_ctx
->single_ref_cdf[av1_get_pred_context_single_ref_p4(xd)][3];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p5(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
return xd->tile_ctx
->single_ref_cdf[av1_get_pred_context_single_ref_p5(xd)][4];
}
#endif // CONFIG_EXT_REFS
#endif // CONFIG_NEW_MULTISYMBOL
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
int av1_get_inter_mode_context(const MACROBLOCKD *xd);
@ -209,61 +369,6 @@ static INLINE int get_tx_size_context(const MACROBLOCKD *xd) {
return (above_ctx + left_ctx) > max_tx_size + TX_SIZE_LUMA_MIN;
}
#if CONFIG_VAR_TX
static void update_tx_counts(AV1_COMMON *cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, int blk_row, int blk_col,
TX_SIZE max_tx_size, int ctx) {
const struct macroblockd_plane *const pd = &xd->plane[0];
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 TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
const int max_blocks_high = max_block_high(xd, plane_bsize, 0);
const int max_blocks_wide = max_block_wide(xd, plane_bsize, 0);
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
if (tx_size == plane_tx_size) {
int depth;
depth = tx_size_to_depth(tx_size);
++xd->counts->tx_size[max_tx_size - TX_SIZE_CTX_MIN][ctx][depth];
mbmi->tx_size = tx_size;
} else {
int bsl = b_width_log2_lookup[bsize];
int i;
assert(bsl > 0);
--bsl;
for (i = 0; i < 4; ++i) {
const int offsetr = blk_row + ((i >> 1) << bsl);
const int offsetc = blk_col + ((i & 0x01) << bsl);
if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
update_tx_counts(cm, xd, mbmi, plane_bsize, (TX_SIZE)(tx_size - 1),
offsetr, offsetc, max_tx_size, ctx);
}
}
}
static INLINE void inter_block_tx_count_update(AV1_COMMON *cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi,
BLOCK_SIZE plane_bsize,
int ctx) {
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];
TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
int bh = tx_size_wide_unit[max_tx_size];
int idx, idy;
for (idy = 0; idy < mi_height; idy += bh)
for (idx = 0; idx < mi_width; idx += bh)
update_tx_counts(cm, xd, mbmi, plane_bsize, max_tx_size, idy, idx,
max_tx_size, ctx);
}
#endif
#ifdef __cplusplus
} // extern "C"
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,9 @@
extern "C" {
#endif
static INLINE int has_scale(int xs, int ys) { return xs != 16 || ys != 16; }
static INLINE int has_scale(int xs, int ys) {
return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
}
static INLINE void inter_predictor(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride, int subpel_x,
@ -59,39 +61,52 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
const InterpFilterParams interp_filter_params_y = interp_filter_params_x;
#endif
assert(conv_params->do_average == 0 || conv_params->do_average == 1);
assert(sf);
if (has_scale(xs, ys)) {
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params);
conv_params->do_post_rounding = 1;
#else
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
// TODO(afergs, debargha): Use a different scale convolve function
// that uses higher precision for subpel_x, subpel_y, xs, ys
av1_convolve_scale(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else {
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (w <= 2 || h <= 2) {
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS) {
const int16_t *kernel_x =
av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
const int16_t *kernel_y =
av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][conv_params->ref](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
subpel_x >>= SCALE_EXTRA_BITS;
subpel_y >>= SCALE_EXTRA_BITS;
xs >>= SCALE_EXTRA_BITS;
ys >>= SCALE_EXTRA_BITS;
assert(subpel_x < SUBPEL_SHIFTS);
assert(subpel_y < SUBPEL_SHIFTS);
assert(xs <= SUBPEL_SHIFTS);
assert(ys <= SUBPEL_SHIFTS);
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params);
conv_params->do_post_rounding = 1;
#else
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
} else {
av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
assert(conv_params->round == CONVOLVE_OPT_ROUND);
if (w <= 2 || h <= 2) {
av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
} else if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS) {
const int16_t *kernel_x = av1_get_interp_filter_subpel_kernel(
interp_filter_params_x, subpel_x);
const int16_t *kernel_y = av1_get_interp_filter_subpel_kernel(
interp_filter_params_y, subpel_y);
sf->predict[subpel_x != 0][subpel_y != 0][conv_params->do_average](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
} else {
av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, conv_params);
}
}
}
}
@ -99,8 +114,7 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
#if CONFIG_HIGHBITDEPTH
static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
uint8_t *dst, int dst_stride,
const int subpel_x,
const int subpel_y,
int subpel_x, int subpel_y,
const struct scale_factors *sf, int w,
int h, ConvolveParams *conv_params,
#if CONFIG_DUAL_FILTER
@ -109,12 +123,10 @@ static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
const InterpFilter interp_filter,
#endif
int xs, int ys, int bd) {
const int ref = conv_params->ref;
// ref > 0 means this is the second reference frame
// first reference frame's prediction result is already in dst
// therefore we need to average the first and second results
const int avg = ref > 0;
const int avg = conv_params->do_average;
assert(avg == 0 || avg == 1);
#if CONFIG_DUAL_FILTER
const int ref = conv_params->ref;
const InterpFilterParams interp_filter_params_x =
av1_get_interp_filter_params(interp_filter[1 + 2 * ref]);
const InterpFilterParams interp_filter_params_y =
@ -126,34 +138,47 @@ static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
#endif
if (has_scale(xs, ys)) {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, avg, bd);
} else if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params, bd);
conv_params->do_post_rounding = 1;
#else
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
av1_highbd_convolve_scale(
src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x >> SCALE_EXTRA_BITS, xs >> SCALE_EXTRA_BITS,
subpel_y >> SCALE_EXTRA_BITS, ys >> SCALE_EXTRA_BITS, avg, bd);
} else {
if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
const int16_t *kernel_x =
av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
const int16_t *kernel_y =
av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
bd);
subpel_x >>= SCALE_EXTRA_BITS;
subpel_y >>= SCALE_EXTRA_BITS;
xs >>= SCALE_EXTRA_BITS;
ys >>= SCALE_EXTRA_BITS;
assert(subpel_x < SUBPEL_SHIFTS);
assert(subpel_y < SUBPEL_SHIFTS);
assert(xs <= SUBPEL_SHIFTS);
assert(ys <= SUBPEL_SHIFTS);
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
#if CONFIG_DUAL_FILTER
interp_filter,
#else // CONFIG_DUAL_FILTER
&interp_filter,
#endif // CONFIG_DUAL_FILTER
subpel_x, xs, subpel_y, ys, conv_params,
bd);
conv_params->do_post_rounding = 1;
#else
assert(0);
#endif // CONFIG_CONVOLVE_ROUND
} else {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
subpel_x, xs, subpel_y, ys, avg, bd);
if (interp_filter_params_x.taps == SUBPEL_TAPS &&
interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
const int16_t *kernel_x = av1_get_interp_filter_subpel_kernel(
interp_filter_params_x, subpel_x);
const int16_t *kernel_y = av1_get_interp_filter_subpel_kernel(
interp_filter_params_y, subpel_y);
sf->highbd_predict[subpel_x != 0][subpel_y != 0][avg](
src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
bd);
} else {
av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h,
interp_filter, subpel_x, xs, subpel_y, ys, avg, bd);
}
}
}
}
@ -199,13 +224,17 @@ typedef struct {
wedge_masks_type *masks;
} wedge_params_type;
extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES];
extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES_ALL];
static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
BLOCK_SIZE sb_type) {
(void)sb_type;
switch (type) {
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
case COMPOUND_AVERAGE: return sb_type >= BLOCK_4X4;
#else // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
case COMPOUND_AVERAGE: return 1;
#endif // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
#if CONFIG_WEDGE
case COMPOUND_WEDGE: return wedge_params_lookup[sb_type].bits > 0;
#endif // CONFIG_WEDGE
@ -218,6 +247,9 @@ static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
static INLINE int is_any_masked_compound_used(BLOCK_SIZE sb_type) {
COMPOUND_TYPE comp_type;
#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
if (sb_type < BLOCK_4X4) return 0;
#endif // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
for (comp_type = 0; comp_type < COMPOUND_TYPES; comp_type++) {
if (is_masked_compound_type(comp_type) &&
is_interinter_compound_used(comp_type, sb_type))
@ -307,8 +339,8 @@ static INLINE int allow_warp(const MODE_INFO *const mi,
#if CONFIG_GLOBAL_MOTION && CONFIG_WARPED_MOTION && !CONFIG_MOTION_VAR
// When both are enabled, warped will take priority. The global parameters
// will only be used to compute projection samples to find the warped model.
// Note that, if SEPARATE_GLOBAL_MOTION is enabled and a block chooses
// global, it will not be possible to select WARPED_CAUSAL.
// Note that when a block chooses global, it will not be possible to
// select WARPED_CAUSAL.
if (warp_types->local_warp_allowed) {
memcpy(final_warp_params, &mbmi->wm_params[0], sizeof(*final_warp_params));
return 1;
@ -400,38 +432,44 @@ static INLINE void av1_make_inter_predictor(
// Make sure the selected motion mode is valid for this configuration
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
assert_motion_mode_valid(mi->mbmi.motion_mode,
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
xd,
#endif
mi);
#endif // CONFIG MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_WARPED_MOTION || CONFIG_GLOBAL_MOTION
WarpedMotionParams final_warp_params;
const int do_warp = allow_warp(mi, warp_types,
const int do_warp = allow_warp(
mi, warp_types,
#if CONFIG_GLOBAL_MOTION
&xd->global_motion[mi->mbmi.ref_frame[ref]],
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// TODO(zoeliu): To further check the single
// ref comp mode to work together with
// global motion.
has_second_ref(&mi->mbmi) ? &xd->global_motion[mi->mbmi.ref_frame[ref]]
: &xd->global_motion[mi->mbmi.ref_frame[0]],
#else // !(CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF)
&xd->global_motion[mi->mbmi.ref_frame[ref]],
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_MOTION_VAR
mi_col_offset, mi_row_offset,
mi_col_offset, mi_row_offset,
#endif // CONFIG_MOTION_VAR
&final_warp_params);
&final_warp_params);
if (do_warp) {
const struct macroblockd_plane *const pd = &xd->plane[plane];
const struct buf_2d *const pre_buf = &pd->pre[ref];
#if CONFIG_EXT_INTER
int compute_avg =
ref && mi->mbmi.interinter_compound_type == COMPOUND_AVERAGE;
#else
int compute_avg = ref;
#endif // CONFIG_EXT_INTER
av1_warp_plane(&final_warp_params,
#if CONFIG_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_HIGHBITDEPTH
pre_buf->buf0, pre_buf->width, pre_buf->height,
pre_buf->stride, dst, p_col, p_row, w, h, dst_stride,
pd->subsampling_x, pd->subsampling_y, xs, ys, compute_avg);
pd->subsampling_x, pd->subsampling_y, xs, ys, conv_params);
return;
}
#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
@ -452,7 +490,7 @@ void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
uint8_t *dst, int dst_stride,
const int subpel_x, const int subpel_y,
const struct scale_factors *sf, int w,
int h,
int h, ConvolveParams *conv_params,
#if CONFIG_DUAL_FILTER
const InterpFilter *interp_filter,
#else
@ -536,10 +574,6 @@ static INLINE MV average_split_mvs(const struct macroblockd_plane *pd,
return res;
}
void av1_build_inter_predictor_sub8x8(const AV1_COMMON *cm, MACROBLOCKD *xd,
int plane, int i, int ir, int ic,
int mi_row, int mi_col);
void av1_build_inter_predictors_sby(const AV1_COMMON *cm, MACROBLOCKD *xd,
int mi_row, int mi_col, BUFFER_SET *ctx,
BLOCK_SIZE bsize);
@ -553,20 +587,21 @@ void av1_build_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
BLOCK_SIZE bsize);
#if CONFIG_SUPERTX
void av1_build_inter_predictors_sb_sub8x8_extend(const AV1_COMMON *cm,
MACROBLOCKD *xd,
void av1_build_inter_predictor_sb_sub8x8_extend(const AV1_COMMON *cm,
MACROBLOCKD *xd,
#if CONFIG_EXT_INTER
int mi_row_ori, int mi_col_ori,
int mi_row_ori, int mi_col_ori,
#endif // CONFIG_EXT_INTER
int mi_row, int mi_col,
BLOCK_SIZE bsize, int block);
int mi_row, int mi_col,
int plane, BLOCK_SIZE bsize,
int block);
void av1_build_inter_predictors_sb_extend(const AV1_COMMON *cm, MACROBLOCKD *xd,
void av1_build_inter_predictor_sb_extend(const AV1_COMMON *cm, MACROBLOCKD *xd,
#if CONFIG_EXT_INTER
int mi_row_ori, int mi_col_ori,
int mi_row_ori, int mi_col_ori,
#endif // CONFIG_EXT_INTER
int mi_row, int mi_col,
BLOCK_SIZE bsize);
int mi_row, int mi_col, int plane,
BLOCK_SIZE bsize);
struct macroblockd_plane;
void av1_build_masked_inter_predictor_complex(
MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
@ -609,8 +644,10 @@ void av1_highbd_build_inter_predictor(
static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
const struct scale_factors *sf) {
const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset;
const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset;
const int x =
sf ? sf->scale_value_x(x_offset, sf) >> SCALE_EXTRA_BITS : x_offset;
const int y =
sf ? sf->scale_value_y(y_offset, sf) >> SCALE_EXTRA_BITS : y_offset;
return y * stride + x;
}

File diff suppressed because it is too large Load diff

View file

@ -73,17 +73,27 @@ static const INTERINTRA_MODE intra_to_interintra_mode[INTRA_MODES] = {
#define FILTER_INTRA_PREC_BITS 10
#endif // CONFIG_FILTER_INTRA
#define CONFIG_INTRA_EDGE_UPSAMPLE CONFIG_INTRA_EDGE
#define CONFIG_USE_ANGLE_DELTA_SUB8X8 0
#if CONFIG_EXT_INTRA
static INLINE int av1_is_directional_mode(PREDICTION_MODE mode,
BLOCK_SIZE bsize) {
return mode != DC_PRED && mode != TM_PRED &&
#if CONFIG_ALT_INTRA
mode != SMOOTH_PRED &&
#if CONFIG_SMOOTH_HV
mode != SMOOTH_V_PRED && mode != SMOOTH_H_PRED &&
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
bsize >= BLOCK_8X8;
#if CONFIG_INTRA_EDGE_UPSAMPLE
(void)bsize;
return mode >= V_PRED && mode <= D63_PRED;
#else
return mode >= V_PRED && mode <= D63_PRED && bsize >= BLOCK_8X8;
#endif
}
static INLINE int av1_use_angle_delta(BLOCK_SIZE bsize) {
(void)bsize;
#if CONFIG_USE_ANGLE_DELTA_SUB8X8
return 1;
#else
return bsize >= BLOCK_8X8;
#endif
}
#endif // CONFIG_EXT_INTRA

View file

@ -30,14 +30,17 @@
#define FILTER_BITS 7
#define INTERP_TAPS 8
#define SUBPEL_BITS_RS 5
#define SUBPEL_BITS_RS 6
#define SUBPEL_MASK_RS ((1 << SUBPEL_BITS_RS) - 1)
#define INTERP_PRECISION_BITS 32
#define SUBPEL_INTERP_EXTRA_BITS (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)
#define SUBPEL_INTERP_EXTRA_OFF (1 << (SUBPEL_INTERP_EXTRA_BITS - 1))
typedef int16_t interp_kernel[INTERP_TAPS];
// Filters for interpolation (0.5-band) - note this also filters integer pels.
static const interp_kernel filteredinterp_filters500[(1 << SUBPEL_BITS_RS)] = {
#if SUBPEL_BITS_RS == 5
{ -3, 0, 35, 64, 35, 0, -3, 0 }, { -3, -1, 34, 64, 36, 1, -3, 0 },
{ -3, -1, 32, 64, 38, 1, -3, 0 }, { -2, -2, 31, 63, 39, 2, -3, 0 },
{ -2, -2, 29, 63, 41, 2, -3, 0 }, { -2, -2, 28, 63, 42, 3, -4, 0 },
@ -53,11 +56,46 @@ static const interp_kernel filteredinterp_filters500[(1 << SUBPEL_BITS_RS)] = {
{ 0, -4, 5, 46, 62, 24, -3, -2 }, { 0, -4, 5, 45, 62, 25, -3, -2 },
{ 0, -4, 4, 43, 63, 27, -3, -2 }, { 0, -4, 3, 42, 63, 28, -2, -2 },
{ 0, -3, 2, 41, 63, 29, -2, -2 }, { 0, -3, 2, 39, 63, 31, -2, -2 },
{ 0, -3, 1, 38, 64, 32, -1, -3 }, { 0, -3, 1, 36, 64, 34, -1, -3 }
{ 0, -3, 1, 38, 64, 32, -1, -3 }, { 0, -3, 1, 36, 64, 34, -1, -3 },
#elif SUBPEL_BITS_RS == 6
{ -3, 0, 35, 64, 35, 0, -3, 0 }, { -3, 0, 34, 64, 36, 0, -3, 0 },
{ -3, -1, 34, 64, 36, 1, -3, 0 }, { -3, -1, 33, 64, 37, 1, -3, 0 },
{ -3, -1, 32, 64, 38, 1, -3, 0 }, { -3, -1, 31, 64, 39, 1, -3, 0 },
{ -3, -1, 31, 63, 39, 2, -3, 0 }, { -2, -2, 30, 63, 40, 2, -3, 0 },
{ -2, -2, 29, 63, 41, 2, -3, 0 }, { -2, -2, 29, 63, 41, 3, -4, 0 },
{ -2, -2, 28, 63, 42, 3, -4, 0 }, { -2, -2, 27, 63, 43, 3, -4, 0 },
{ -2, -3, 27, 63, 43, 4, -4, 0 }, { -2, -3, 26, 62, 44, 5, -4, 0 },
{ -2, -3, 25, 62, 45, 5, -4, 0 }, { -2, -3, 25, 62, 45, 5, -4, 0 },
{ -2, -3, 24, 62, 46, 5, -4, 0 }, { -2, -3, 23, 61, 47, 6, -4, 0 },
{ -2, -3, 23, 61, 47, 6, -4, 0 }, { -2, -3, 22, 61, 48, 7, -4, -1 },
{ -2, -3, 21, 60, 49, 7, -4, 0 }, { -1, -4, 20, 60, 49, 8, -4, 0 },
{ -1, -4, 20, 60, 50, 8, -4, -1 }, { -1, -4, 19, 59, 51, 9, -4, -1 },
{ -1, -4, 19, 59, 51, 9, -4, -1 }, { -1, -4, 18, 58, 52, 10, -4, -1 },
{ -1, -4, 17, 58, 52, 11, -4, -1 }, { -1, -4, 16, 58, 53, 11, -4, -1 },
{ -1, -4, 16, 57, 53, 12, -4, -1 }, { -1, -4, 15, 57, 54, 12, -4, -1 },
{ -1, -4, 15, 56, 54, 13, -4, -1 }, { -1, -4, 14, 56, 55, 13, -4, -1 },
{ -1, -4, 14, 55, 55, 14, -4, -1 }, { -1, -4, 13, 55, 56, 14, -4, -1 },
{ -1, -4, 13, 54, 56, 15, -4, -1 }, { -1, -4, 12, 54, 57, 15, -4, -1 },
{ -1, -4, 12, 53, 57, 16, -4, -1 }, { -1, -4, 11, 53, 58, 16, -4, -1 },
{ -1, -4, 11, 52, 58, 17, -4, -1 }, { -1, -4, 10, 52, 58, 18, -4, -1 },
{ -1, -4, 9, 51, 59, 19, -4, -1 }, { -1, -4, 9, 51, 59, 19, -4, -1 },
{ -1, -4, 8, 50, 60, 20, -4, -1 }, { 0, -4, 8, 49, 60, 20, -4, -1 },
{ 0, -4, 7, 49, 60, 21, -3, -2 }, { -1, -4, 7, 48, 61, 22, -3, -2 },
{ 0, -4, 6, 47, 61, 23, -3, -2 }, { 0, -4, 6, 47, 61, 23, -3, -2 },
{ 0, -4, 5, 46, 62, 24, -3, -2 }, { 0, -4, 5, 45, 62, 25, -3, -2 },
{ 0, -4, 5, 45, 62, 25, -3, -2 }, { 0, -4, 5, 44, 62, 26, -3, -2 },
{ 0, -4, 4, 43, 63, 27, -3, -2 }, { 0, -4, 3, 43, 63, 27, -2, -2 },
{ 0, -4, 3, 42, 63, 28, -2, -2 }, { 0, -4, 3, 41, 63, 29, -2, -2 },
{ 0, -3, 2, 41, 63, 29, -2, -2 }, { 0, -3, 2, 40, 63, 30, -2, -2 },
{ 0, -3, 2, 39, 63, 31, -1, -3 }, { 0, -3, 1, 39, 64, 31, -1, -3 },
{ 0, -3, 1, 38, 64, 32, -1, -3 }, { 0, -3, 1, 37, 64, 33, -1, -3 },
{ 0, -3, 1, 36, 64, 34, -1, -3 }, { 0, -3, 0, 36, 64, 34, 0, -3 },
#endif // SUBPEL_BITS_RS == 5
};
// Filters for interpolation (0.625-band) - note this also filters integer pels.
static const interp_kernel filteredinterp_filters625[(1 << SUBPEL_BITS_RS)] = {
#if SUBPEL_BITS_RS == 5
{ -1, -8, 33, 80, 33, -8, -1, 0 }, { -1, -8, 30, 80, 35, -8, -1, 1 },
{ -1, -8, 28, 80, 37, -7, -2, 1 }, { 0, -8, 26, 79, 39, -7, -2, 1 },
{ 0, -8, 24, 79, 41, -7, -2, 1 }, { 0, -8, 22, 78, 43, -6, -2, 1 },
@ -74,10 +112,45 @@ static const interp_kernel filteredinterp_filters625[(1 << SUBPEL_BITS_RS)] = {
{ 1, -3, -5, 45, 78, 20, -8, 0 }, { 1, -2, -6, 43, 78, 22, -8, 0 },
{ 1, -2, -7, 41, 79, 24, -8, 0 }, { 1, -2, -7, 39, 79, 26, -8, 0 },
{ 1, -2, -7, 37, 80, 28, -8, -1 }, { 1, -1, -8, 35, 80, 30, -8, -1 },
#elif SUBPEL_BITS_RS == 6
{ -1, -8, 33, 80, 33, -8, -1, 0 }, { -1, -8, 31, 80, 34, -8, -1, 1 },
{ -1, -8, 30, 80, 35, -8, -1, 1 }, { -1, -8, 29, 80, 36, -7, -2, 1 },
{ -1, -8, 28, 80, 37, -7, -2, 1 }, { -1, -8, 27, 80, 38, -7, -2, 1 },
{ 0, -8, 26, 79, 39, -7, -2, 1 }, { 0, -8, 25, 79, 40, -7, -2, 1 },
{ 0, -8, 24, 79, 41, -7, -2, 1 }, { 0, -8, 23, 78, 42, -6, -2, 1 },
{ 0, -8, 22, 78, 43, -6, -2, 1 }, { 0, -8, 21, 78, 44, -6, -2, 1 },
{ 0, -8, 20, 78, 45, -5, -3, 1 }, { 0, -8, 19, 77, 47, -5, -3, 1 },
{ 0, -8, 18, 77, 48, -5, -3, 1 }, { 0, -8, 17, 77, 49, -5, -3, 1 },
{ 0, -8, 16, 76, 50, -4, -3, 1 }, { 0, -8, 15, 76, 51, -4, -3, 1 },
{ 0, -8, 15, 75, 52, -3, -4, 1 }, { 0, -7, 14, 74, 53, -3, -4, 1 },
{ 0, -7, 13, 74, 54, -3, -4, 1 }, { 0, -7, 12, 73, 55, -2, -4, 1 },
{ 0, -7, 11, 73, 56, -2, -4, 1 }, { 0, -7, 10, 72, 57, -1, -4, 1 },
{ 1, -7, 10, 71, 58, -1, -5, 1 }, { 0, -7, 9, 71, 59, 0, -5, 1 },
{ 1, -7, 8, 70, 60, 0, -5, 1 }, { 1, -7, 7, 69, 61, 1, -5, 1 },
{ 1, -6, 6, 68, 62, 1, -5, 1 }, { 0, -6, 6, 68, 62, 2, -5, 1 },
{ 1, -6, 5, 67, 63, 2, -5, 1 }, { 1, -6, 5, 66, 64, 3, -6, 1 },
{ 1, -6, 4, 65, 65, 4, -6, 1 }, { 1, -6, 3, 64, 66, 5, -6, 1 },
{ 1, -5, 2, 63, 67, 5, -6, 1 }, { 1, -5, 2, 62, 68, 6, -6, 0 },
{ 1, -5, 1, 62, 68, 6, -6, 1 }, { 1, -5, 1, 61, 69, 7, -7, 1 },
{ 1, -5, 0, 60, 70, 8, -7, 1 }, { 1, -5, 0, 59, 71, 9, -7, 0 },
{ 1, -5, -1, 58, 71, 10, -7, 1 }, { 1, -4, -1, 57, 72, 10, -7, 0 },
{ 1, -4, -2, 56, 73, 11, -7, 0 }, { 1, -4, -2, 55, 73, 12, -7, 0 },
{ 1, -4, -3, 54, 74, 13, -7, 0 }, { 1, -4, -3, 53, 74, 14, -7, 0 },
{ 1, -4, -3, 52, 75, 15, -8, 0 }, { 1, -3, -4, 51, 76, 15, -8, 0 },
{ 1, -3, -4, 50, 76, 16, -8, 0 }, { 1, -3, -5, 49, 77, 17, -8, 0 },
{ 1, -3, -5, 48, 77, 18, -8, 0 }, { 1, -3, -5, 47, 77, 19, -8, 0 },
{ 1, -3, -5, 45, 78, 20, -8, 0 }, { 1, -2, -6, 44, 78, 21, -8, 0 },
{ 1, -2, -6, 43, 78, 22, -8, 0 }, { 1, -2, -6, 42, 78, 23, -8, 0 },
{ 1, -2, -7, 41, 79, 24, -8, 0 }, { 1, -2, -7, 40, 79, 25, -8, 0 },
{ 1, -2, -7, 39, 79, 26, -8, 0 }, { 1, -2, -7, 38, 80, 27, -8, -1 },
{ 1, -2, -7, 37, 80, 28, -8, -1 }, { 1, -2, -7, 36, 80, 29, -8, -1 },
{ 1, -1, -8, 35, 80, 30, -8, -1 }, { 1, -1, -8, 34, 80, 31, -8, -1 },
#endif // SUBPEL_BITS_RS == 5
};
// Filters for interpolation (0.75-band) - note this also filters integer pels.
static const interp_kernel filteredinterp_filters750[(1 << SUBPEL_BITS_RS)] = {
#if SUBPEL_BITS_RS == 5
{ 2, -11, 25, 96, 25, -11, 2, 0 }, { 2, -11, 22, 96, 28, -11, 2, 0 },
{ 2, -10, 19, 95, 31, -11, 2, 0 }, { 2, -10, 17, 95, 34, -12, 2, 0 },
{ 2, -9, 14, 94, 37, -12, 2, 0 }, { 2, -8, 12, 93, 40, -12, 1, 0 },
@ -93,11 +166,46 @@ static const interp_kernel filteredinterp_filters750[(1 << SUBPEL_BITS_RS)] = {
{ 0, 1, -12, 49, 90, 5, -7, 2 }, { 0, 1, -12, 46, 91, 7, -7, 2 },
{ 1, 1, -12, 43, 92, 9, -8, 2 }, { 0, 1, -12, 40, 93, 12, -8, 2 },
{ 0, 2, -12, 37, 94, 14, -9, 2 }, { 0, 2, -12, 34, 95, 17, -10, 2 },
{ 0, 2, -11, 31, 95, 19, -10, 2 }, { 0, 2, -11, 28, 96, 22, -11, 2 }
{ 0, 2, -11, 31, 95, 19, -10, 2 }, { 0, 2, -11, 28, 96, 22, -11, 2 },
#elif SUBPEL_BITS_RS == 6
{ 2, -11, 25, 96, 25, -11, 2, 0 }, { 2, -11, 24, 96, 26, -11, 2, 0 },
{ 2, -11, 22, 96, 28, -11, 2, 0 }, { 2, -10, 21, 96, 29, -12, 2, 0 },
{ 2, -10, 19, 96, 31, -12, 2, 0 }, { 2, -10, 18, 95, 32, -11, 2, 0 },
{ 2, -10, 17, 95, 34, -12, 2, 0 }, { 2, -9, 15, 95, 35, -12, 2, 0 },
{ 2, -9, 14, 94, 37, -12, 2, 0 }, { 2, -9, 13, 94, 38, -12, 2, 0 },
{ 2, -8, 12, 93, 40, -12, 1, 0 }, { 2, -8, 11, 93, 41, -12, 1, 0 },
{ 2, -8, 9, 92, 43, -12, 1, 1 }, { 2, -8, 8, 92, 44, -12, 1, 1 },
{ 2, -7, 7, 91, 46, -12, 1, 0 }, { 2, -7, 6, 90, 47, -12, 1, 1 },
{ 2, -7, 5, 90, 49, -12, 1, 0 }, { 2, -6, 4, 89, 50, -12, 1, 0 },
{ 2, -6, 3, 88, 52, -12, 0, 1 }, { 2, -6, 2, 87, 54, -12, 0, 1 },
{ 2, -5, 1, 86, 55, -12, 0, 1 }, { 2, -5, 0, 85, 57, -12, 0, 1 },
{ 2, -5, -1, 84, 58, -11, 0, 1 }, { 2, -5, -2, 83, 60, -11, 0, 1 },
{ 2, -4, -2, 82, 61, -11, -1, 1 }, { 1, -4, -3, 81, 63, -10, -1, 1 },
{ 2, -4, -4, 80, 64, -10, -1, 1 }, { 1, -4, -4, 79, 66, -10, -1, 1 },
{ 1, -3, -5, 77, 67, -9, -1, 1 }, { 1, -3, -6, 76, 69, -9, -1, 1 },
{ 1, -3, -6, 75, 70, -8, -2, 1 }, { 1, -2, -7, 74, 71, -8, -2, 1 },
{ 1, -2, -7, 72, 72, -7, -2, 1 }, { 1, -2, -8, 71, 74, -7, -2, 1 },
{ 1, -2, -8, 70, 75, -6, -3, 1 }, { 1, -1, -9, 69, 76, -6, -3, 1 },
{ 1, -1, -9, 67, 77, -5, -3, 1 }, { 1, -1, -10, 66, 79, -4, -4, 1 },
{ 1, -1, -10, 64, 80, -4, -4, 2 }, { 1, -1, -10, 63, 81, -3, -4, 1 },
{ 1, -1, -11, 61, 82, -2, -4, 2 }, { 1, 0, -11, 60, 83, -2, -5, 2 },
{ 1, 0, -11, 58, 84, -1, -5, 2 }, { 1, 0, -12, 57, 85, 0, -5, 2 },
{ 1, 0, -12, 55, 86, 1, -5, 2 }, { 1, 0, -12, 54, 87, 2, -6, 2 },
{ 1, 0, -12, 52, 88, 3, -6, 2 }, { 0, 1, -12, 50, 89, 4, -6, 2 },
{ 0, 1, -12, 49, 90, 5, -7, 2 }, { 1, 1, -12, 47, 90, 6, -7, 2 },
{ 0, 1, -12, 46, 91, 7, -7, 2 }, { 1, 1, -12, 44, 92, 8, -8, 2 },
{ 1, 1, -12, 43, 92, 9, -8, 2 }, { 0, 1, -12, 41, 93, 11, -8, 2 },
{ 0, 1, -12, 40, 93, 12, -8, 2 }, { 0, 2, -12, 38, 94, 13, -9, 2 },
{ 0, 2, -12, 37, 94, 14, -9, 2 }, { 0, 2, -12, 35, 95, 15, -9, 2 },
{ 0, 2, -12, 34, 95, 17, -10, 2 }, { 0, 2, -11, 32, 95, 18, -10, 2 },
{ 0, 2, -12, 31, 96, 19, -10, 2 }, { 0, 2, -12, 29, 96, 21, -10, 2 },
{ 0, 2, -11, 28, 96, 22, -11, 2 }, { 0, 2, -11, 26, 96, 24, -11, 2 },
#endif // SUBPEL_BITS_RS == 5
};
// Filters for interpolation (0.875-band) - note this also filters integer pels.
static const interp_kernel filteredinterp_filters875[(1 << SUBPEL_BITS_RS)] = {
#if SUBPEL_BITS_RS == 5
{ 3, -8, 13, 112, 13, -8, 3, 0 }, { 3, -7, 10, 112, 17, -9, 3, -1 },
{ 2, -6, 7, 111, 21, -9, 3, -1 }, { 2, -5, 4, 111, 24, -10, 3, -1 },
{ 2, -4, 1, 110, 28, -11, 3, -1 }, { 1, -3, -1, 108, 32, -12, 4, -1 },
@ -113,11 +221,46 @@ static const interp_kernel filteredinterp_filters875[(1 << SUBPEL_BITS_RS)] = {
{ -1, 4, -14, 44, 102, -7, -1, 1 }, { -1, 4, -14, 40, 105, -6, -1, 1 },
{ -1, 4, -13, 36, 106, -3, -2, 1 }, { -1, 4, -12, 32, 108, -1, -3, 1 },
{ -1, 3, -11, 28, 110, 1, -4, 2 }, { -1, 3, -10, 24, 111, 4, -5, 2 },
{ -1, 3, -9, 21, 111, 7, -6, 2 }, { -1, 3, -9, 17, 112, 10, -7, 3 }
{ -1, 3, -9, 21, 111, 7, -6, 2 }, { -1, 3, -9, 17, 112, 10, -7, 3 },
#elif SUBPEL_BITS_RS == 6
{ 3, -8, 13, 112, 13, -8, 3, 0 }, { 2, -7, 12, 112, 15, -8, 3, -1 },
{ 3, -7, 10, 112, 17, -9, 3, -1 }, { 2, -6, 8, 112, 19, -9, 3, -1 },
{ 2, -6, 7, 112, 21, -10, 3, -1 }, { 2, -5, 6, 111, 22, -10, 3, -1 },
{ 2, -5, 4, 111, 24, -10, 3, -1 }, { 2, -4, 3, 110, 26, -11, 3, -1 },
{ 2, -4, 1, 110, 28, -11, 3, -1 }, { 2, -4, 0, 109, 30, -12, 4, -1 },
{ 1, -3, -1, 108, 32, -12, 4, -1 }, { 1, -3, -2, 108, 34, -13, 4, -1 },
{ 1, -2, -4, 107, 36, -13, 4, -1 }, { 1, -2, -5, 106, 38, -13, 4, -1 },
{ 1, -1, -6, 105, 40, -14, 4, -1 }, { 1, -1, -7, 104, 42, -14, 4, -1 },
{ 1, -1, -7, 103, 44, -15, 4, -1 }, { 1, 0, -8, 101, 46, -15, 4, -1 },
{ 1, 0, -9, 100, 48, -15, 4, -1 }, { 1, 0, -10, 99, 50, -15, 4, -1 },
{ 1, 1, -11, 97, 53, -16, 4, -1 }, { 0, 1, -11, 96, 55, -16, 4, -1 },
{ 0, 1, -12, 95, 57, -16, 4, -1 }, { 0, 2, -13, 93, 59, -16, 4, -1 },
{ 0, 2, -13, 91, 61, -16, 4, -1 }, { 0, 2, -14, 90, 63, -16, 4, -1 },
{ 0, 2, -14, 88, 65, -16, 4, -1 }, { 0, 2, -15, 86, 67, -16, 4, 0 },
{ 0, 3, -15, 84, 69, -17, 4, 0 }, { 0, 3, -16, 83, 71, -17, 4, 0 },
{ 0, 3, -16, 81, 73, -16, 3, 0 }, { 0, 3, -16, 79, 75, -16, 3, 0 },
{ 0, 3, -16, 77, 77, -16, 3, 0 }, { 0, 3, -16, 75, 79, -16, 3, 0 },
{ 0, 3, -16, 73, 81, -16, 3, 0 }, { 0, 4, -17, 71, 83, -16, 3, 0 },
{ 0, 4, -17, 69, 84, -15, 3, 0 }, { 0, 4, -16, 67, 86, -15, 2, 0 },
{ -1, 4, -16, 65, 88, -14, 2, 0 }, { -1, 4, -16, 63, 90, -14, 2, 0 },
{ -1, 4, -16, 61, 91, -13, 2, 0 }, { -1, 4, -16, 59, 93, -13, 2, 0 },
{ -1, 4, -16, 57, 95, -12, 1, 0 }, { -1, 4, -16, 55, 96, -11, 1, 0 },
{ -1, 4, -16, 53, 97, -11, 1, 1 }, { -1, 4, -15, 50, 99, -10, 0, 1 },
{ -1, 4, -15, 48, 100, -9, 0, 1 }, { -1, 4, -15, 46, 101, -8, 0, 1 },
{ -1, 4, -15, 44, 103, -7, -1, 1 }, { -1, 4, -14, 42, 104, -7, -1, 1 },
{ -1, 4, -14, 40, 105, -6, -1, 1 }, { -1, 4, -13, 38, 106, -5, -2, 1 },
{ -1, 4, -13, 36, 107, -4, -2, 1 }, { -1, 4, -13, 34, 108, -2, -3, 1 },
{ -1, 4, -12, 32, 108, -1, -3, 1 }, { -1, 4, -12, 30, 109, 0, -4, 2 },
{ -1, 3, -11, 28, 110, 1, -4, 2 }, { -1, 3, -11, 26, 110, 3, -4, 2 },
{ -1, 3, -10, 24, 111, 4, -5, 2 }, { -1, 3, -10, 22, 111, 6, -5, 2 },
{ -1, 3, -10, 21, 112, 7, -6, 2 }, { -1, 3, -9, 19, 112, 8, -6, 2 },
{ -1, 3, -9, 17, 112, 10, -7, 3 }, { -1, 3, -8, 15, 112, 12, -7, 2 },
#endif // SUBPEL_BITS_RS == 5
};
// Filters for interpolation (full-band) - no filtering for integer pixels
static const interp_kernel filteredinterp_filters1000[(1 << SUBPEL_BITS_RS)] = {
#if SUBPEL_BITS_RS == 5
{ 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 1, -3, 128, 3, -1, 0, 0 },
{ -1, 2, -6, 127, 7, -2, 1, 0 }, { -1, 3, -9, 126, 12, -4, 1, 0 },
{ -1, 4, -12, 125, 16, -5, 1, 0 }, { -1, 4, -14, 123, 20, -6, 2, 0 },
@ -133,7 +276,41 @@ static const interp_kernel filteredinterp_filters1000[(1 << SUBPEL_BITS_RS)] = {
{ -1, 3, -10, 35, 114, -18, 6, -1 }, { -1, 3, -9, 30, 118, -17, 5, -1 },
{ 0, 2, -8, 25, 120, -15, 5, -1 }, { 0, 2, -6, 20, 123, -14, 4, -1 },
{ 0, 1, -5, 16, 125, -12, 4, -1 }, { 0, 1, -4, 12, 126, -9, 3, -1 },
{ 0, 1, -2, 7, 127, -6, 2, -1 }, { 0, 0, -1, 3, 128, -3, 1, 0 }
{ 0, 1, -2, 7, 127, -6, 2, -1 }, { 0, 0, -1, 3, 128, -3, 1, 0 },
#elif SUBPEL_BITS_RS == 6
{ 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 0, -1, 128, 2, -1, 0, 0 },
{ 0, 1, -3, 127, 4, -2, 1, 0 }, { 0, 1, -4, 127, 6, -3, 1, 0 },
{ 0, 2, -6, 126, 8, -3, 1, 0 }, { 0, 2, -7, 125, 11, -4, 1, 0 },
{ -1, 2, -8, 125, 13, -5, 2, 0 }, { -1, 3, -9, 124, 15, -6, 2, 0 },
{ -1, 3, -10, 123, 18, -6, 2, -1 }, { -1, 3, -11, 122, 20, -7, 3, -1 },
{ -1, 4, -12, 121, 22, -8, 3, -1 }, { -1, 4, -13, 120, 25, -9, 3, -1 },
{ -1, 4, -14, 118, 28, -9, 3, -1 }, { -1, 4, -15, 117, 30, -10, 4, -1 },
{ -1, 5, -16, 116, 32, -11, 4, -1 }, { -1, 5, -16, 114, 35, -12, 4, -1 },
{ -1, 5, -17, 112, 38, -12, 4, -1 }, { -1, 5, -18, 111, 40, -13, 5, -1 },
{ -1, 5, -18, 109, 43, -14, 5, -1 }, { -1, 6, -19, 107, 45, -14, 5, -1 },
{ -1, 6, -19, 105, 48, -15, 5, -1 }, { -1, 6, -19, 103, 51, -16, 5, -1 },
{ -1, 6, -20, 101, 53, -16, 6, -1 }, { -1, 6, -20, 99, 56, -17, 6, -1 },
{ -1, 6, -20, 97, 58, -17, 6, -1 }, { -1, 6, -20, 95, 61, -18, 6, -1 },
{ -2, 7, -20, 93, 64, -18, 6, -2 }, { -2, 7, -20, 91, 66, -19, 6, -1 },
{ -2, 7, -20, 88, 69, -19, 6, -1 }, { -2, 7, -20, 86, 71, -19, 6, -1 },
{ -2, 7, -20, 84, 74, -20, 7, -2 }, { -2, 7, -20, 81, 76, -20, 7, -1 },
{ -2, 7, -20, 79, 79, -20, 7, -2 }, { -1, 7, -20, 76, 81, -20, 7, -2 },
{ -2, 7, -20, 74, 84, -20, 7, -2 }, { -1, 6, -19, 71, 86, -20, 7, -2 },
{ -1, 6, -19, 69, 88, -20, 7, -2 }, { -1, 6, -19, 66, 91, -20, 7, -2 },
{ -2, 6, -18, 64, 93, -20, 7, -2 }, { -1, 6, -18, 61, 95, -20, 6, -1 },
{ -1, 6, -17, 58, 97, -20, 6, -1 }, { -1, 6, -17, 56, 99, -20, 6, -1 },
{ -1, 6, -16, 53, 101, -20, 6, -1 }, { -1, 5, -16, 51, 103, -19, 6, -1 },
{ -1, 5, -15, 48, 105, -19, 6, -1 }, { -1, 5, -14, 45, 107, -19, 6, -1 },
{ -1, 5, -14, 43, 109, -18, 5, -1 }, { -1, 5, -13, 40, 111, -18, 5, -1 },
{ -1, 4, -12, 38, 112, -17, 5, -1 }, { -1, 4, -12, 35, 114, -16, 5, -1 },
{ -1, 4, -11, 32, 116, -16, 5, -1 }, { -1, 4, -10, 30, 117, -15, 4, -1 },
{ -1, 3, -9, 28, 118, -14, 4, -1 }, { -1, 3, -9, 25, 120, -13, 4, -1 },
{ -1, 3, -8, 22, 121, -12, 4, -1 }, { -1, 3, -7, 20, 122, -11, 3, -1 },
{ -1, 2, -6, 18, 123, -10, 3, -1 }, { 0, 2, -6, 15, 124, -9, 3, -1 },
{ 0, 2, -5, 13, 125, -8, 2, -1 }, { 0, 1, -4, 11, 125, -7, 2, 0 },
{ 0, 1, -3, 8, 126, -6, 2, 0 }, { 0, 1, -3, 6, 127, -4, 1, 0 },
{ 0, 1, -2, 4, 127, -3, 1, 0 }, { 0, 0, -1, 2, 128, -1, 0, 0 },
#endif // SUBPEL_BITS_RS == 5
};
// Filters for factor of 2 downsampling.
@ -172,14 +349,14 @@ static void interpolate(const uint8_t *const input, int inlength,
choose_interp_filter(inlength, outlength);
x = 0;
y = offset;
y = offset + SUBPEL_INTERP_EXTRA_OFF;
while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) {
x++;
y += delta;
}
x1 = x;
x = outlength - 1;
y = delta * x + offset;
y = delta * x + offset + SUBPEL_INTERP_EXTRA_OFF;
while ((y >> INTERP_PRECISION_BITS) + (int64_t)(INTERP_TAPS / 2) >=
inlength) {
x--;
@ -187,11 +364,11 @@ static void interpolate(const uint8_t *const input, int inlength,
}
x2 = x;
if (x1 > x2) {
for (x = 0, y = offset; x < outlength; ++x, y += delta) {
for (x = 0, y = offset + SUBPEL_INTERP_EXTRA_OFF; x < outlength;
++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k) {
@ -202,11 +379,10 @@ static void interpolate(const uint8_t *const input, int inlength,
}
} else {
// Initial part.
for (x = 0, y = offset; x < x1; ++x, y += delta) {
for (x = 0, y = offset + SUBPEL_INTERP_EXTRA_OFF; x < x1; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -217,8 +393,7 @@ static void interpolate(const uint8_t *const input, int inlength,
for (; x <= x2; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -229,8 +404,7 @@ static void interpolate(const uint8_t *const input, int inlength,
for (; x < outlength; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -471,14 +645,14 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
choose_interp_filter(inlength, outlength);
x = 0;
y = offset;
y = offset + SUBPEL_INTERP_EXTRA_OFF;
while ((y >> INTERP_PRECISION_BITS) < (INTERP_TAPS / 2 - 1)) {
x++;
y += delta;
}
x1 = x;
x = outlength - 1;
y = delta * x + offset;
y = delta * x + offset + SUBPEL_INTERP_EXTRA_OFF;
while ((y >> INTERP_PRECISION_BITS) + (int64_t)(INTERP_TAPS / 2) >=
inlength) {
x--;
@ -486,11 +660,11 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
}
x2 = x;
if (x1 > x2) {
for (x = 0, y = offset; x < outlength; ++x, y += delta) {
for (x = 0, y = offset + SUBPEL_INTERP_EXTRA_OFF; x < outlength;
++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k) {
@ -501,11 +675,10 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
}
} else {
// Initial part.
for (x = 0, y = offset; x < x1; ++x, y += delta) {
for (x = 0, y = offset + SUBPEL_INTERP_EXTRA_OFF; x < x1; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -516,8 +689,7 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
for (; x <= x2; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -528,8 +700,7 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
for (; x < outlength; ++x, y += delta) {
const int16_t *filter;
int_pel = y >> INTERP_PRECISION_BITS;
sub_pel =
(y >> (INTERP_PRECISION_BITS - SUBPEL_BITS_RS)) & SUBPEL_MASK_RS;
sub_pel = (y >> SUBPEL_INTERP_EXTRA_BITS) & SUBPEL_MASK_RS;
filter = interp_filters[sub_pel];
sum = 0;
for (k = 0; k < INTERP_TAPS; ++k)
@ -539,6 +710,7 @@ static void highbd_interpolate(const uint16_t *const input, int inlength,
}
}
}
#ifndef __clang_analyzer__
static void highbd_down2_symeven(const uint16_t *const input, int length,
uint16_t *output, int bd) {
@ -816,11 +988,11 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride,
#endif // CONFIG_HIGHBITDEPTH
#if CONFIG_HIGHBITDEPTH
static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst, int bd) {
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst, int bd) {
#else
static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst) {
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst) {
#endif // CONFIG_HIGHBITDEPTH
// TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t
int i;
@ -855,8 +1027,8 @@ static void resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled) {
if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
cm->mi_rows * MI_SIZE != unscaled->y_height) {
if (cm->width != unscaled->y_crop_width ||
cm->height != unscaled->y_crop_height) {
// For 2x2 scaling down.
aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0);
aom_extend_frame_borders(scaled);
@ -869,14 +1041,111 @@ YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled) {
if (cm->width != unscaled->y_width || cm->height != unscaled->y_height) {
if (cm->width != unscaled->y_crop_width ||
cm->height != unscaled->y_crop_height) {
#if CONFIG_HIGHBITDEPTH
resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth);
av1_resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth);
#else
resize_and_extend_frame(unscaled, scaled);
av1_resize_and_extend_frame(unscaled, scaled);
#endif // CONFIG_HIGHBITDEPTH
return scaled;
} else {
return unscaled;
}
}
void av1_calculate_scaled_size(int *width, int *height, int num) {
if (num != SCALE_DENOMINATOR) {
*width = *width * num / SCALE_DENOMINATOR;
*height = *height * num / SCALE_DENOMINATOR;
// Make width and height even
*width += *width & 1;
*height += *height & 1;
}
}
#if CONFIG_FRAME_SUPERRES
// TODO(afergs): Look for in-place upscaling
// TODO(afergs): aom_ vs av1_ functions? Which can I use?
// Upscale decoded image.
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool) {
if (av1_superres_unscaled(cm)) return;
YV12_BUFFER_CONFIG copy_buffer;
memset(&copy_buffer, 0, sizeof(copy_buffer));
YV12_BUFFER_CONFIG *const frame_to_show = get_frame_new_buffer(cm);
if (aom_alloc_frame_buffer(&copy_buffer, cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment))
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate copy buffer for superres upscaling");
// Copy function assumes the frames are the same size, doesn't copy bit_depth.
aom_yv12_copy_frame(frame_to_show, &copy_buffer);
copy_buffer.bit_depth = frame_to_show->bit_depth;
assert(copy_buffer.y_crop_width == cm->width);
assert(copy_buffer.y_crop_height == cm->height);
// Realloc the current frame buffer at a higher resolution in place.
if (pool != NULL) {
// Use callbacks if on the decoder.
aom_codec_frame_buffer_t *fb =
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer;
aom_release_frame_buffer_cb_fn_t release_fb_cb = pool->release_fb_cb;
aom_get_frame_buffer_cb_fn_t cb = pool->get_fb_cb;
void *cb_priv = pool->cb_priv;
// Realloc with callback does not release the frame buffer - release first.
if (release_fb_cb(cb_priv, fb))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to free current frame buffer before superres upscaling");
if (aom_realloc_frame_buffer(
frame_to_show, cm->superres_upscaled_width,
cm->superres_upscaled_height, cm->subsampling_x, cm->subsampling_y,
#if CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment, fb, cb, cb_priv))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate current frame buffer for superres upscaling");
} else {
// Don't use callbacks on the encoder.
if (aom_alloc_frame_buffer(frame_to_show, cm->superres_upscaled_width,
cm->superres_upscaled_height, cm->subsampling_x,
cm->subsampling_y,
#if CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif // CONFIG_HIGHBITDEPTH
AOM_BORDER_IN_PIXELS, cm->byte_alignment))
aom_internal_error(
&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to reallocate current frame buffer for superres upscaling");
}
// TODO(afergs): verify frame_to_show is correct after realloc
// encoder:
// decoder:
frame_to_show->bit_depth = copy_buffer.bit_depth;
assert(frame_to_show->y_crop_width == cm->superres_upscaled_width);
assert(frame_to_show->y_crop_height == cm->superres_upscaled_height);
// Scale up and back into frame_to_show.
assert(frame_to_show->y_crop_width != cm->width);
assert(frame_to_show->y_crop_height != cm->height);
#if CONFIG_HIGHBITDEPTH
av1_resize_and_extend_frame(&copy_buffer, frame_to_show, (int)cm->bit_depth);
#else
av1_resize_and_extend_frame(&copy_buffer, frame_to_show);
#endif // CONFIG_HIGHBITDEPTH
// Free the copy buffer
aom_free_frame_buffer(&copy_buffer);
}
#endif // CONFIG_FRAME_SUPERRES

View file

@ -63,6 +63,14 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride,
int owidth, int bd);
#endif // CONFIG_HIGHBITDEPTH
#if CONFIG_HIGHBITDEPTH
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst, int bd);
#else
void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src,
YV12_BUFFER_CONFIG *dst);
#endif // CONFIG_HIGHBITDEPTH
YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled);
@ -71,6 +79,17 @@ YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
YV12_BUFFER_CONFIG *unscaled,
YV12_BUFFER_CONFIG *scaled);
void av1_calculate_scaled_size(int *width, int *height, int num);
#if CONFIG_FRAME_SUPERRES
void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool);
// Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
static INLINE int av1_superres_unscaled(const AV1_COMMON *cm) {
return (cm->superres_scale_numerator == SCALE_DENOMINATOR);
}
#endif // CONFIG_FRAME_SUPERRES
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1237,8 +1237,10 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
int components_pattern, RestorationInfo *rsi,
YV12_BUFFER_CONFIG *dst) {
const int ywidth = frame->y_crop_width;
const int ystride = frame->y_stride;
const int yheight = frame->y_crop_height;
const int uvwidth = frame->uv_crop_width;
const int uvheight = frame->uv_crop_height;
const int ystride = frame->y_stride;
const int uvstride = frame->uv_stride;
const int ystart = start_mi_row << MI_SIZE_LOG2;
const int uvstart = ystart >> cm->subsampling_y;
@ -1259,8 +1261,8 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
#endif // CONFIG_HIGHBITDEPTH
YV12_BUFFER_CONFIG dst_;
yend = AOMMIN(yend, cm->height);
uvend = AOMMIN(uvend, cm->subsampling_y ? (cm->height + 1) >> 1 : cm->height);
yend = AOMMIN(yend, yheight);
uvend = AOMMIN(uvend, uvheight);
if (components_pattern == (1 << AOM_PLANE_Y)) {
// Only y
@ -1295,7 +1297,7 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
dst = &dst_;
memset(dst, 0, sizeof(YV12_BUFFER_CONFIG));
if (aom_realloc_frame_buffer(
dst, cm->width, cm->height, cm->subsampling_x, cm->subsampling_y,
dst, ywidth, yheight, cm->subsampling_x, cm->subsampling_y,
#if CONFIG_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
@ -1307,7 +1309,7 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
if ((components_pattern >> AOM_PLANE_Y) & 1) {
if (rsi[0].frame_restoration_type != RESTORE_NONE) {
cm->rst_internal.ntiles = av1_get_rest_ntiles(
cm->width, cm->height, cm->rst_info[AOM_PLANE_Y].restoration_tilesize,
ywidth, yheight, cm->rst_info[AOM_PLANE_Y].restoration_tilesize,
&cm->rst_internal.tile_width, &cm->rst_internal.tile_height,
&cm->rst_internal.nhtiles, &cm->rst_internal.nvtiles);
cm->rst_internal.rsi = &rsi[0];
@ -1334,9 +1336,7 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
if ((components_pattern >> AOM_PLANE_U) & 1) {
if (rsi[AOM_PLANE_U].frame_restoration_type != RESTORE_NONE) {
cm->rst_internal.ntiles = av1_get_rest_ntiles(
ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x),
ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y),
cm->rst_info[AOM_PLANE_U].restoration_tilesize,
uvwidth, uvheight, cm->rst_info[AOM_PLANE_U].restoration_tilesize,
&cm->rst_internal.tile_width, &cm->rst_internal.tile_height,
&cm->rst_internal.nhtiles, &cm->rst_internal.nvtiles);
cm->rst_internal.rsi = &rsi[AOM_PLANE_U];
@ -1363,9 +1363,7 @@ static void loop_restoration_rows(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
if ((components_pattern >> AOM_PLANE_V) & 1) {
if (rsi[AOM_PLANE_V].frame_restoration_type != RESTORE_NONE) {
cm->rst_internal.ntiles = av1_get_rest_ntiles(
ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x),
ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y),
cm->rst_info[AOM_PLANE_V].restoration_tilesize,
uvwidth, uvheight, cm->rst_info[AOM_PLANE_V].restoration_tilesize,
&cm->rst_internal.tile_width, &cm->rst_internal.tile_height,
&cm->rst_internal.nhtiles, &cm->rst_internal.nvtiles);
cm->rst_internal.rsi = &rsi[AOM_PLANE_V];
@ -1402,11 +1400,16 @@ void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
int partial_frame, YV12_BUFFER_CONFIG *dst) {
int start_mi_row, end_mi_row, mi_rows_to_filter;
start_mi_row = 0;
#if CONFIG_FRAME_SUPERRES
mi_rows_to_filter =
ALIGN_POWER_OF_TWO(cm->superres_upscaled_height, 3) >> MI_SIZE_LOG2;
#else
mi_rows_to_filter = cm->mi_rows;
if (partial_frame && cm->mi_rows > 8) {
start_mi_row = cm->mi_rows >> 1;
#endif // CONFIG_FRAME_SUPERRES
if (partial_frame && mi_rows_to_filter > 8) {
start_mi_row = mi_rows_to_filter >> 1;
start_mi_row &= 0xfffffff8;
mi_rows_to_filter = AOMMAX(cm->mi_rows / 8, 8);
mi_rows_to_filter = AOMMAX(mi_rows_to_filter / 8, 8);
}
end_mi_row = start_mi_row + mi_rows_to_filter;
loop_restoration_init(&cm->rst_internal, cm->frame_type == KEY_FRAME);

View file

@ -14,17 +14,28 @@
#include "av1/common/scale.h"
#include "aom_dsp/aom_filter.h"
// Note: Expect val to be in q4 precision
static INLINE int scaled_x(int val, const struct scale_factors *sf) {
return (int)((int64_t)val * sf->x_scale_fp >> REF_SCALE_SHIFT);
const int off =
(sf->x_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
const int64_t tval = (int64_t)val * sf->x_scale_fp + off;
return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
}
// Note: Expect val to be in q4 precision
static INLINE int scaled_y(int val, const struct scale_factors *sf) {
return (int)((int64_t)val * sf->y_scale_fp >> REF_SCALE_SHIFT);
const int off =
(sf->y_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
const int64_t tval = (int64_t)val * sf->y_scale_fp + off;
return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
}
// Note: Expect val to be in q4 precision
static int unscaled_value(int val, const struct scale_factors *sf) {
(void)sf;
return val;
return val << SCALE_EXTRA_BITS;
}
static int get_fixed_point_scale_factor(int other_size, int this_size) {
@ -32,14 +43,24 @@ static int get_fixed_point_scale_factor(int other_size, int this_size) {
// and use fixed point scaling factors in decoding and encoding routines.
// Hardware implementations can calculate scale factor in device driver
// and use multiplication and shifting on hardware instead of division.
return (other_size << REF_SCALE_SHIFT) / this_size;
return ((other_size << REF_SCALE_SHIFT) + this_size / 2) / this_size;
}
MV32 av1_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) {
const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK;
const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK;
const MV32 res = { scaled_y(mv->row, sf) + y_off_q4,
scaled_x(mv->col, sf) + x_off_q4 };
static int get_coarse_point_scale_factor(int other_size, int this_size) {
// Calculate scaling factor once for each reference frame
// and use fixed point scaling factors in decoding and encoding routines.
// Hardware implementations can calculate scale factor in device driver
// and use multiplication and shifting on hardware instead of division.
return ((other_size << SCALE_SUBPEL_BITS) + this_size / 2) / this_size;
}
// Note: x and y are integer precision, mvq4 is q4 precision.
MV32 av1_scale_mv(const MV *mvq4, int x, int y,
const struct scale_factors *sf) {
const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf);
const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf);
const MV32 res = { scaled_y((y << SUBPEL_BITS) + mvq4->row, sf) - y_off_q4,
scaled_x((x << SUBPEL_BITS) + mvq4->col, sf) - x_off_q4 };
return res;
}
@ -59,8 +80,9 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
sf->x_step_q4 = scaled_x(16, sf);
sf->y_step_q4 = scaled_y(16, sf);
sf->x_step_q4 = get_coarse_point_scale_factor(other_w, this_w);
sf->y_step_q4 = get_coarse_point_scale_factor(other_h, this_h);
if (av1_is_scaled(sf)) {
sf->scale_value_x = scaled_x;
@ -76,8 +98,8 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
// applied in one direction only, and not at all for 0,0, seems to give the
// best quality, but it may be worth trying an additional mode that does
// do the filtering on full-pel.
if (sf->x_step_q4 == 16) {
if (sf->y_step_q4 == 16) {
if (sf->x_step_q4 == SCALE_SUBPEL_SHIFTS) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in either direction.
sf->predict[0][0][0] = aom_convolve_copy;
sf->predict[0][0][1] = aom_convolve_avg;
@ -95,7 +117,7 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->predict[1][0][1] = aom_convolve8_avg;
}
} else {
if (sf->y_step_q4 == 16) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in the y direction. Must always scale in the x direction.
sf->predict[0][0][0] = aom_convolve8_horiz;
sf->predict[0][0][1] = aom_convolve8_avg_horiz;
@ -119,8 +141,8 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
#if CONFIG_HIGHBITDEPTH
if (use_highbd) {
if (sf->x_step_q4 == 16) {
if (sf->y_step_q4 == 16) {
if (sf->x_step_q4 == SCALE_SUBPEL_SHIFTS) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in either direction.
sf->highbd_predict[0][0][0] = aom_highbd_convolve_copy;
sf->highbd_predict[0][0][1] = aom_highbd_convolve_avg;
@ -138,7 +160,7 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
sf->highbd_predict[1][0][1] = aom_highbd_convolve8_avg;
}
} else {
if (sf->y_step_q4 == 16) {
if (sf->y_step_q4 == SCALE_SUBPEL_SHIFTS) {
// No scaling in the y direction. Must always scale in the x direction.
sf->highbd_predict[0][0][0] = aom_highbd_convolve8_horiz;
sf->highbd_predict[0][0][1] = aom_highbd_convolve8_avg_horiz;

View file

@ -19,6 +19,8 @@
extern "C" {
#endif
#define SCALE_DENOMINATOR 16
#define REF_SCALE_SHIFT 14
#define REF_NO_SCALE (1 << REF_SCALE_SHIFT)
#define REF_INVALID_SCALE -1

View file

@ -6605,7 +6605,7 @@ static INLINE int clamp_64(int64_t value, int low, int high) {
}
static void update_scan_prob(AV1_COMMON *cm, TX_SIZE tx_size, TX_TYPE tx_type,
int rate_16) {
int rate) {
FRAME_CONTEXT *pre_fc = cm->pre_fc;
uint32_t *prev_non_zero_prob = get_non_zero_prob(pre_fc, tx_size, tx_type);
uint32_t *non_zero_prob = get_non_zero_prob(cm->fc, tx_size, tx_type);
@ -6615,13 +6615,18 @@ static void update_scan_prob(AV1_COMMON *cm, TX_SIZE tx_size, TX_TYPE tx_type,
int i;
for (i = 0; i < tx2d_size; i++) {
int64_t curr_prob =
block_num == 0 ? 0 : (non_zero_count[i] << 16) / block_num;
block_num == 0
? 0
: (non_zero_count[i] << ADAPT_SCAN_PROB_PRECISION) / block_num;
int64_t prev_prob = prev_non_zero_prob[i];
int64_t pred_prob =
(curr_prob * rate_16 + prev_prob * ((1 << 16) - rate_16)) >> 16;
(curr_prob * rate +
prev_prob * ((1 << ADAPT_SCAN_PROB_PRECISION) - rate)) >>
ADAPT_SCAN_PROB_PRECISION;
// TODO(angiebird): reduce the bit usage of probabilities and remove
// clamp_64()
non_zero_prob[i] = clamp_64(pred_prob, 0, UINT16_MAX);
non_zero_prob[i] =
clamp_64(pred_prob, 0, (1 << ADAPT_SCAN_PROB_PRECISION) - 1);
}
}
@ -6819,7 +6824,8 @@ void av1_init_scan_order(AV1_COMMON *cm) {
int i;
SCAN_ORDER *sc = &cm->fc->sc[tx_size][tx_type];
for (i = 0; i < tx2d_size; ++i) {
non_zero_prob[i] = (1 << 16) / 2; // init non_zero_prob to 0.5
non_zero_prob[i] =
(1 << ADAPT_SCAN_PROB_PRECISION) / 2; // init non_zero_prob to 0.5
}
update_scan_order_facade(cm, tx_size, tx_type);
sc->scan = get_adapt_scan(cm->fc, tx_size, tx_type);
@ -6840,7 +6846,7 @@ void av1_adapt_scan_order(AV1_COMMON *cm) {
#endif // CONFIG_RECT_TX && (CONFIG_EXT_TX || CONFIG_VAR_TX)
TX_TYPE tx_type;
for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
update_scan_prob(cm, tx_size, tx_type, ADAPT_SCAN_UPDATE_RATE_16);
update_scan_prob(cm, tx_size, tx_type, ADAPT_SCAN_UPDATE_RATE);
update_scan_order_facade(cm, tx_size, tx_type);
update_eob_threshold(cm, tx_size, tx_type);
}

View file

@ -78,10 +78,22 @@ static INLINE const SCAN_ORDER *get_default_scan(TX_SIZE tx_size,
}
static INLINE const SCAN_ORDER *get_scan(const AV1_COMMON *cm, TX_SIZE tx_size,
TX_TYPE tx_type, int is_inter) {
TX_TYPE tx_type,
const MB_MODE_INFO *mbmi) {
#if CONFIG_MRC_TX
// use the DCT_DCT scan order for MRC_DCT for now
if (tx_type == MRC_DCT) tx_type = DCT_DCT;
#endif // CONFIG_MRC_TX
const int is_inter = is_inter_block(mbmi);
#if CONFIG_ADAPT_SCAN
(void)mbmi;
(void)is_inter;
return &cm->fc->sc[tx_size][tx_type];
#if CONFIG_EXT_TX
if (tx_type >= IDTX)
return get_default_scan(tx_size, tx_type, is_inter);
else
#endif // CONFIG_EXT_TX
return &cm->fc->sc[tx_size][tx_type];
#else // CONFIG_ADAPT_SCAN
(void)cm;
return get_default_scan(tx_size, tx_type, is_inter);

View file

@ -50,6 +50,9 @@ struct segmentation_probs {
aom_prob tree_probs[SEG_TREE_PROBS];
aom_cdf_prob tree_cdf[CDF_SIZE(MAX_SEGMENTS)];
aom_prob pred_probs[PREDICTION_PROBS];
#if CONFIG_NEW_MULTISYMBOL
aom_cdf_prob pred_cdf[PREDICTION_PROBS][CDF_SIZE(2)];
#endif
};
static INLINE int segfeature_active(const struct segmentation *seg,

View file

@ -23,7 +23,7 @@ void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) {
tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols);
}
#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS
#if CONFIG_DEPENDENT_HORZTILES
void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm,
int row, int col) {
if (row < cm->tile_rows - 1) {
@ -41,13 +41,11 @@ void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm,
void av1_tile_init(TileInfo *tile, const AV1_COMMON *cm, int row, int col) {
av1_tile_set_row(tile, cm, row);
av1_tile_set_col(tile, cm, col);
#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS
#if CONFIG_DEPENDENT_HORZTILES
av1_tile_set_tg_boundary(tile, cm, row, col);
#endif
}
#if !CONFIG_EXT_TILE
#if CONFIG_EXT_PARTITION
#define MIN_TILE_WIDTH_MAX_SB 2
#define MAX_TILE_WIDTH_MAX_SB 32
@ -76,56 +74,79 @@ void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols,
*max_log2_tile_cols = get_max_log2_tile_cols(max_sb_cols);
assert(*min_log2_tile_cols <= *max_log2_tile_cols);
}
#endif // !CONFIG_EXT_TILE
void av1_update_boundary_info(const struct AV1Common *cm,
const TileInfo *const tile_info, int mi_row,
int mi_col) {
int row, col;
for (row = mi_row; row < (mi_row + cm->mib_size); row++)
for (col = mi_col; col < (mi_col + cm->mib_size); col++) {
MODE_INFO *const mi = cm->mi + row * cm->mi_stride + col;
mi->mbmi.boundary_info = 0;
void av1_setup_frame_boundary_info(const AV1_COMMON *const cm) {
MODE_INFO *mi = cm->mi;
int col;
for (col = 0; col < cm->mi_cols; ++col) {
mi->mbmi.boundary_info |= FRAME_ABOVE_BOUNDARY | TILE_ABOVE_BOUNDARY;
mi += 1;
}
// If horizontal dependent tile is enabled, then the horizontal
// tile boundary is not treated as real tile boundary for loop
// filtering, only the horizontal tile group boundary is treated
// as tile boundary.
// Otherwise, tile group boundary is treated the same as tile boundary.
// Loop filtering operation is done based on the
// loopfilter_across_tiles_enabled flag for both tile boundary and tile
// group boundary.
mi = cm->mi;
int row;
for (row = 0; row < cm->mi_rows; ++row) {
mi->mbmi.boundary_info |= FRAME_LEFT_BOUNDARY | TILE_LEFT_BOUNDARY;
mi += cm->mi_stride;
}
mi = cm->mi + (cm->mi_rows - 1) * cm->mi_stride;
for (col = 0; col < cm->mi_cols; ++col) {
mi->mbmi.boundary_info |= FRAME_BOTTOM_BOUNDARY | TILE_BOTTOM_BOUNDARY;
mi += 1;
}
mi = cm->mi + cm->mi_cols - 1;
for (row = 0; row < cm->mi_rows; ++row) {
mi->mbmi.boundary_info |= FRAME_RIGHT_BOUNDARY | TILE_RIGHT_BOUNDARY;
mi += cm->mi_stride;
}
}
void av1_setup_across_tile_boundary_info(const AV1_COMMON *const cm,
const TileInfo *const tile_info) {
int lpf_across_tiles_enabled = 1;
#if CONFIG_LOOPFILTERING_ACROSS_TILES
lpf_across_tiles_enabled = cm->loop_filter_across_tiles_enabled;
#endif
if ((cm->tile_cols * cm->tile_rows > 1) && (!lpf_across_tiles_enabled)) {
const int mi_row = tile_info->mi_row_start;
const int mi_col = tile_info->mi_col_start;
MODE_INFO *const mi_start = cm->mi + mi_row * cm->mi_stride + mi_col;
MODE_INFO *mi = 0;
const int row_diff = tile_info->mi_row_end - tile_info->mi_row_start;
const int col_diff = tile_info->mi_col_end - tile_info->mi_col_start;
int row, col;
if (cm->tile_cols * cm->tile_rows > 1) {
#if CONFIG_DEPENDENT_HORZTILES
#if CONFIG_TILE_GROUPS
if (row == tile_info->mi_row_start &&
(!cm->dependent_horz_tiles || tile_info->tg_horz_boundary))
#else
if (row == tile_info->mi_row_start && !cm->dependent_horz_tiles)
#endif // CONFIG_TILE_GROUPS
#else
if (row == tile_info->mi_row_start)
if (!cm->dependent_horz_tiles || tile_info->tg_horz_boundary)
#endif // CONFIG_DEPENDENT_HORZTILES
mi->mbmi.boundary_info |= TILE_ABOVE_BOUNDARY;
if (col == tile_info->mi_col_start)
mi->mbmi.boundary_info |= TILE_LEFT_BOUNDARY;
if ((row + 1) >= tile_info->mi_row_end)
mi->mbmi.boundary_info |= TILE_BOTTOM_BOUNDARY;
if ((col + 1) >= tile_info->mi_col_end)
mi->mbmi.boundary_info |= TILE_RIGHT_BOUNDARY;
{
mi = mi_start;
for (col = 0; col < col_diff; ++col) {
mi->mbmi.boundary_info |= TILE_ABOVE_BOUNDARY;
mi += 1;
}
// Frame boundary is treated as tile boundary
if (row == 0)
mi->mbmi.boundary_info |= FRAME_ABOVE_BOUNDARY | TILE_ABOVE_BOUNDARY;
if (col == 0)
mi->mbmi.boundary_info |= FRAME_LEFT_BOUNDARY | TILE_LEFT_BOUNDARY;
if ((row + 1) >= cm->mi_rows)
mi->mbmi.boundary_info |= FRAME_BOTTOM_BOUNDARY | TILE_BOTTOM_BOUNDARY;
if ((col + 1) >= cm->mi_cols)
mi->mbmi.boundary_info |= FRAME_RIGHT_BOUNDARY | TILE_RIGHT_BOUNDARY;
}
mi = mi_start;
for (row = 0; row < row_diff; ++row) {
mi->mbmi.boundary_info |= TILE_LEFT_BOUNDARY;
mi += cm->mi_stride;
}
mi = mi_start + (row_diff - 1) * cm->mi_stride;
for (col = 0; col < col_diff; ++col) {
mi->mbmi.boundary_info |= TILE_BOTTOM_BOUNDARY;
mi += 1;
}
mi = mi_start + col_diff - 1;
for (row = 0; row < row_diff; ++row) {
mi->mbmi.boundary_info |= TILE_RIGHT_BOUNDARY;
mi += cm->mi_stride;
}
}
}
#if CONFIG_LOOPFILTERING_ACROSS_TILES

View file

@ -20,9 +20,7 @@ extern "C" {
struct AV1Common;
#if CONFIG_TILE_GROUPS
#define DEFAULT_MAX_NUM_TG 1
#endif
typedef struct TileInfo {
int mi_row_start, mi_row_end;
@ -37,16 +35,16 @@ void av1_tile_init(TileInfo *tile, const struct AV1Common *cm, int row,
void av1_tile_set_row(TileInfo *tile, const struct AV1Common *cm, int row);
void av1_tile_set_col(TileInfo *tile, const struct AV1Common *cm, int col);
#if CONFIG_DEPENDENT_HORZTILES && CONFIG_TILE_GROUPS
#if CONFIG_DEPENDENT_HORZTILES
void av1_tile_set_tg_boundary(TileInfo *tile, const struct AV1Common *const cm,
int row, int col);
#endif
void av1_get_tile_n_bits(int mi_cols, int *min_log2_tile_cols,
int *max_log2_tile_cols);
void av1_update_boundary_info(const struct AV1Common *cm,
const TileInfo *const tile_info, int mi_row,
int mi_col);
void av1_setup_frame_boundary_info(const struct AV1Common *const cm);
void av1_setup_across_tile_boundary_info(const struct AV1Common *const cm,
const TileInfo *const tile_info);
#if CONFIG_LOOPFILTERING_ACROSS_TILES
int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm);

View file

@ -113,10 +113,11 @@ void av1_adapt_txb_probs(AV1_COMMON *cm, unsigned int count_sat,
for (ctx = 0; ctx < DC_SIGN_CONTEXTS; ++ctx)
fc->dc_sign[plane][ctx] = mode_mv_merge_probs(
pre_fc->dc_sign[plane][ctx], counts->dc_sign[plane][ctx]);
// Update probability models for non-zero coefficient map and eob flag.
for (level = 0; level < NUM_BASE_LEVELS; ++level)
for (tx_size = 0; tx_size < TX_SIZES; ++tx_size)
for (plane = 0; plane < PLANE_TYPES; ++plane)
for (tx_size = 0; tx_size < TX_SIZES; ++tx_size)
for (plane = 0; plane < PLANE_TYPES; ++plane)
for (level = 0; level < NUM_BASE_LEVELS; ++level)
for (ctx = 0; ctx < COEFF_BASE_CONTEXTS; ++ctx)
fc->coeff_base[tx_size][plane][level][ctx] =
merge_probs(pre_fc->coeff_base[tx_size][plane][level][ctx],

View file

@ -24,6 +24,10 @@ typedef struct txb_ctx {
int dc_sign_ctx;
} TXB_CTX;
static INLINE TX_SIZE get_txsize_context(TX_SIZE tx_size) {
return txsize_sqr_up_map[tx_size];
}
#define BASE_CONTEXT_POSITION_NUM 12
static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
/* clang-format off*/
@ -33,14 +37,14 @@ static int base_ref_offset[BASE_CONTEXT_POSITION_NUM][2] = {
};
static INLINE int get_level_count(const tran_low_t *tcoeffs, int stride,
int row, int col, int level,
int height, int row, int col, int level,
int (*nb_offset)[2], int nb_num) {
int count = 0;
for (int idx = 0; idx < nb_num; ++idx) {
const int ref_row = row + nb_offset[idx][0];
const int ref_col = col + nb_offset[idx][1];
const int pos = ref_row * stride + ref_col;
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
continue;
tran_low_t abs_coeff = abs(tcoeffs[pos]);
count += abs_coeff > level;
@ -49,14 +53,15 @@ static INLINE int get_level_count(const tran_low_t *tcoeffs, int stride,
}
static INLINE void get_mag(int *mag, const tran_low_t *tcoeffs, int stride,
int row, int col, int (*nb_offset)[2], int nb_num) {
int height, int row, int col, int (*nb_offset)[2],
int nb_num) {
mag[0] = 0;
mag[1] = 0;
for (int idx = 0; idx < nb_num; ++idx) {
const int ref_row = row + nb_offset[idx][0];
const int ref_col = col + nb_offset[idx][1];
const int pos = ref_row * stride + ref_col;
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
continue;
tran_low_t abs_coeff = abs(tcoeffs[pos]);
if (nb_offset[idx][0] >= 0 && nb_offset[idx][1] >= 0) {
@ -70,15 +75,16 @@ static INLINE void get_mag(int *mag, const tran_low_t *tcoeffs, int stride,
}
}
static INLINE int get_level_count_mag(int *mag, const tran_low_t *tcoeffs,
int stride, int row, int col, int level,
int (*nb_offset)[2], int nb_num) {
int stride, int height, int row, int col,
int level, int (*nb_offset)[2],
int nb_num) {
int count = 0;
*mag = 0;
for (int idx = 0; idx < nb_num; ++idx) {
const int ref_row = row + nb_offset[idx][0];
const int ref_col = col + nb_offset[idx][1];
const int pos = ref_row * stride + ref_col;
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
continue;
tran_low_t abs_coeff = abs(tcoeffs[pos]);
count += abs_coeff > level;
@ -111,15 +117,16 @@ static INLINE int get_base_ctx_from_count_mag(int row, int col, int count,
static INLINE int get_base_ctx(const tran_low_t *tcoeffs,
int c, // raster order
const int bwl, const int level) {
const int bwl, const int height,
const int level) {
const int stride = 1 << bwl;
const int row = c >> bwl;
const int col = c - (row << bwl);
const int level_minus_1 = level - 1;
int mag;
int count =
get_level_count_mag(&mag, tcoeffs, stride, row, col, level_minus_1,
base_ref_offset, BASE_CONTEXT_POSITION_NUM);
int count = get_level_count_mag(&mag, tcoeffs, stride, height, row, col,
level_minus_1, base_ref_offset,
BASE_CONTEXT_POSITION_NUM);
int ctx_idx = get_base_ctx_from_count_mag(row, col, count, mag, level);
return ctx_idx;
}
@ -169,15 +176,15 @@ static INLINE int get_br_ctx_from_count_mag(int row, int col, int count,
static INLINE int get_br_ctx(const tran_low_t *tcoeffs,
const int c, // raster order
const int bwl) {
const int bwl, const int height) {
const int stride = 1 << bwl;
const int row = c >> bwl;
const int col = c - (row << bwl);
const int level_minus_1 = NUM_BASE_LEVELS;
int mag;
const int count =
get_level_count_mag(&mag, tcoeffs, stride, row, col, level_minus_1,
br_ref_offset, BR_CONTEXT_POSITION_NUM);
const int count = get_level_count_mag(&mag, tcoeffs, stride, height, row, col,
level_minus_1, br_ref_offset,
BR_CONTEXT_POSITION_NUM);
const int ctx = get_br_ctx_from_count_mag(row, col, count, mag);
return ctx;
}
@ -188,79 +195,15 @@ static int sig_ref_offset[SIG_REF_OFFSET_NUM][2] = {
{ -1, 1 }, { 0, -2 }, { 0, -1 }, { 1, -2 }, { 1, -1 },
};
static INLINE int get_nz_map_ctx(const tran_low_t *tcoeffs,
const uint8_t *txb_mask,
const int coeff_idx, // raster order
const int bwl) {
const int row = coeff_idx >> bwl;
const int col = coeff_idx - (row << bwl);
int ctx = 0;
int idx;
int stride = 1 << bwl;
if (row == 0 && col == 0) return 0;
if (row == 0 && col == 1) return 1 + (tcoeffs[0] != 0);
if (row == 1 && col == 0) return 3 + (tcoeffs[0] != 0);
if (row == 1 && col == 1) {
int pos;
ctx = (tcoeffs[0] != 0);
if (txb_mask[1]) ctx += (tcoeffs[1] != 0);
pos = 1 << bwl;
if (txb_mask[pos]) ctx += (tcoeffs[pos] != 0);
ctx = (ctx + 1) >> 1;
assert(5 + ctx <= 7);
return 5 + ctx;
}
for (idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
int ref_row = row + sig_ref_offset[idx][0];
int ref_col = col + sig_ref_offset[idx][1];
int pos;
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
continue;
pos = (ref_row << bwl) + ref_col;
if (txb_mask[pos]) ctx += (tcoeffs[pos] != 0);
}
if (row == 0) {
ctx = (ctx + 1) >> 1;
assert(ctx < 3);
return 8 + ctx;
}
if (col == 0) {
ctx = (ctx + 1) >> 1;
assert(ctx < 3);
return 11 + ctx;
}
ctx >>= 1;
assert(14 + ctx < 20);
return 14 + ctx;
}
static INLINE int get_nz_count(const tran_low_t *tcoeffs, int stride, int row,
int col, const int16_t *iscan) {
static INLINE int get_nz_count(const tran_low_t *tcoeffs, int stride,
int height, int row, int col,
const int16_t *iscan) {
int count = 0;
const int pos = row * stride + col;
for (int idx = 0; idx < SIG_REF_OFFSET_NUM; ++idx) {
const int ref_row = row + sig_ref_offset[idx][0];
const int ref_col = col + sig_ref_offset[idx][1];
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
if (ref_row < 0 || ref_col < 0 || ref_row >= height || ref_col >= stride)
continue;
const int nb_pos = ref_row * stride + ref_col;
if (iscan[nb_pos] < iscan[pos]) count += (tcoeffs[nb_pos] != 0);
@ -320,26 +263,25 @@ static INLINE int get_nz_map_ctx_from_count(int count,
return 14 + ctx;
}
// TODO(angiebird): merge this function with get_nz_map_ctx() after proper
// testing
static INLINE int get_nz_map_ctx2(const tran_low_t *tcoeffs,
const int coeff_idx, // raster order
const int bwl, const int16_t *iscan) {
static INLINE int get_nz_map_ctx(const tran_low_t *tcoeffs,
const int coeff_idx, // raster order
const int bwl, const int height,
const int16_t *iscan) {
int stride = 1 << bwl;
const int row = coeff_idx >> bwl;
const int col = coeff_idx - (row << bwl);
int count = get_nz_count(tcoeffs, stride, row, col, iscan);
int count = get_nz_count(tcoeffs, stride, height, row, col, iscan);
return get_nz_map_ctx_from_count(count, tcoeffs, coeff_idx, bwl, iscan);
}
static INLINE int get_eob_ctx(const tran_low_t *tcoeffs,
const int coeff_idx, // raster order
const int bwl) {
const TX_SIZE txs_ctx) {
(void)tcoeffs;
if (bwl == 2) return av1_coeff_band_4x4[coeff_idx];
if (bwl == 3) return av1_coeff_band_8x8[coeff_idx];
if (bwl == 4) return av1_coeff_band_16x16[coeff_idx];
if (bwl == 5) return av1_coeff_band_32x32[coeff_idx];
if (txs_ctx == TX_4X4) return av1_coeff_band_4x4[coeff_idx];
if (txs_ctx == TX_8X8) return av1_coeff_band_8x8[coeff_idx];
if (txs_ctx == TX_16X16) return av1_coeff_band_16x16[coeff_idx];
if (txs_ctx == TX_32X32) return av1_coeff_band_32x32[coeff_idx];
assert(0);
return 0;

View file

@ -17,6 +17,9 @@
#include "./av1_rtcd.h"
#include "av1/common/warped_motion.h"
#include "av1/common/scale.h"
#define WARP_ERROR_BLOCK 32
/* clang-format off */
static const int error_measure_lut[512] = {
@ -90,6 +93,8 @@ static const int error_measure_lut[512] = {
static ProjectPointsFunc get_project_points_type(TransformationType type) {
switch (type) {
case VERTRAPEZOID: return project_points_vertrapezoid;
case HORTRAPEZOID: return project_points_hortrapezoid;
case HOMOGRAPHY: return project_points_homography;
case AFFINE: return project_points_affine;
case ROTZOOM: return project_points_rotzoom;
@ -279,29 +284,6 @@ void project_points_homography(const int32_t *mat, int *points, int *proj,
}
}
// 'points' are at original scale, output 'proj's are scaled up by
// 1 << WARPEDPIXEL_PREC_BITS
void project_points(const WarpedMotionParams *wm_params, int *points, int *proj,
const int n, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y) {
switch (wm_params->wmtype) {
case AFFINE:
project_points_affine(wm_params->wmmat, points, proj, n, stride_points,
stride_proj, subsampling_x, subsampling_y);
break;
case ROTZOOM:
project_points_rotzoom(wm_params->wmmat, points, proj, n, stride_points,
stride_proj, subsampling_x, subsampling_y);
break;
case HOMOGRAPHY:
project_points_homography(wm_params->wmmat, points, proj, n,
stride_points, stride_proj, subsampling_x,
subsampling_y);
break;
default: assert(0 && "Invalid warped motion type!"); return;
}
}
static const int16_t
filter_ntap[WARPEDPIXEL_PREC_SHIFTS][WARPEDPIXEL_FILTER_TAPS] = {
#if WARPEDPIXEL_PREC_BITS == 6
@ -911,11 +893,14 @@ static INLINE int highbd_error_measure(int err, int bd) {
error_measure_lut[256 + e1] * e2;
}
static void highbd_warp_plane_old(
const WarpedMotionParams *const wm, const uint8_t *const ref8, int width,
int height, int stride, const uint8_t *const pred8, int p_col, int p_row,
int p_width, int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale, int bd, int comp_avg) {
static void highbd_warp_plane_old(const WarpedMotionParams *const wm,
const uint8_t *const ref8, int width,
int height, int stride,
const uint8_t *const pred8, int p_col,
int p_row, int p_width, int p_height,
int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale,
int bd, ConvolveParams *conv_params) {
int i, j;
ProjectPointsFunc projectpoints = get_project_points_type(wm->wmtype);
uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
@ -929,7 +914,7 @@ static void highbd_warp_plane_old(
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
if (comp_avg)
if (conv_params->do_average)
pred[(j - p_col) + (i - p_row) * p_stride] = ROUND_POWER_OF_TWO(
pred[(j - p_col) + (i - p_row) * p_stride] +
highbd_warp_interpolate(ref, out[0], out[1], width, height,
@ -949,10 +934,10 @@ void av1_highbd_warp_affine_c(const int32_t *mat, const uint16_t *ref,
int width, int height, int stride, uint16_t *pred,
int p_col, int p_row, int p_width, int p_height,
int p_stride, int subsampling_x,
int subsampling_y, int bd, int comp_avg,
int16_t alpha, int16_t beta, int16_t gamma,
int16_t delta) {
uint32_t tmp[15 * 8];
int subsampling_y, int bd,
ConvolveParams *conv_params, int16_t alpha,
int16_t beta, int16_t gamma, int16_t delta) {
int32_t tmp[15 * 8];
int i, j, k, l, m;
for (i = p_row; i < p_row + p_height; i += 8) {
@ -1037,7 +1022,7 @@ void av1_highbd_warp_affine_c(const int32_t *mat, const uint16_t *ref,
assert(0 <= sum && sum < (1 << (bd + 2)));
uint16_t px =
clip_pixel_highbd(sum - (1 << (bd - 1)) - (1 << bd), bd);
if (comp_avg)
if (conv_params->do_average)
*p = ROUND_POWER_OF_TWO(*p + px, 1);
else
*p = px;
@ -1048,18 +1033,125 @@ void av1_highbd_warp_affine_c(const int32_t *mat, const uint16_t *ref,
}
}
#if CONFIG_CONVOLVE_ROUND
void av1_highbd_warp_affine_post_round_c(
const int32_t *mat, const uint16_t *ref, int width, int height, int stride,
uint16_t *pred, int p_col, int p_row, int p_width, int p_height,
int p_stride, int subsampling_x, int subsampling_y, int bd,
ConvolveParams *conv_params, int16_t alpha, int16_t beta, int16_t gamma,
int16_t delta) {
(void)pred;
(void)p_stride;
int32_t tmp[15 * 8];
int i, j, k, l, m;
const int offset_bits_horiz = bd + FILTER_BITS - 1;
const int offset_bits_vert = bd + 2 * FILTER_BITS - conv_params->round_0;
assert(FILTER_BITS == WARPEDPIXEL_FILTER_BITS);
for (i = p_row; i < p_row + p_height; i += 8) {
for (j = p_col; j < p_col + p_width; j += 8) {
int32_t x4, y4, ix4, sx4, iy4, sy4;
if (subsampling_x)
x4 = (mat[2] * 4 * (j + 4) + mat[3] * 4 * (i + 4) + mat[0] * 2 +
(mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS))) /
4;
else
x4 = mat[2] * (j + 4) + mat[3] * (i + 4) + mat[0];
if (subsampling_y)
y4 = (mat[4] * 4 * (j + 4) + mat[5] * 4 * (i + 4) + mat[1] * 2 +
(mat[4] + mat[5] - (1 << WARPEDMODEL_PREC_BITS))) /
4;
else
y4 = mat[4] * (j + 4) + mat[5] * (i + 4) + mat[1];
ix4 = x4 >> WARPEDMODEL_PREC_BITS;
sx4 = x4 & ((1 << WARPEDMODEL_PREC_BITS) - 1);
iy4 = y4 >> WARPEDMODEL_PREC_BITS;
sy4 = y4 & ((1 << WARPEDMODEL_PREC_BITS) - 1);
sx4 += alpha * (-4) + beta * (-4);
sy4 += gamma * (-4) + delta * (-4);
sx4 &= ~((1 << WARP_PARAM_REDUCE_BITS) - 1);
sy4 &= ~((1 << WARP_PARAM_REDUCE_BITS) - 1);
// Horizontal filter
for (k = -7; k < 8; ++k) {
int iy = iy4 + k;
if (iy < 0)
iy = 0;
else if (iy > height - 1)
iy = height - 1;
int sx = sx4 + beta * (k + 4);
for (l = -4; l < 4; ++l) {
int ix = ix4 + l - 3;
const int offs = ROUND_POWER_OF_TWO(sx, WARPEDDIFF_PREC_BITS) +
WARPEDPIXEL_PREC_SHIFTS;
assert(offs >= 0 && offs <= WARPEDPIXEL_PREC_SHIFTS * 3);
const int16_t *coeffs = warped_filter[offs];
int32_t sum = 1 << offset_bits_horiz;
for (m = 0; m < 8; ++m) {
int sample_x = ix + m;
if (sample_x < 0)
sample_x = 0;
else if (sample_x > width - 1)
sample_x = width - 1;
sum += ref[iy * stride + sample_x] * coeffs[m];
}
sum = ROUND_POWER_OF_TWO(sum, conv_params->round_0);
assert(0 <= sum &&
sum < (1 << (bd + FILTER_BITS + 1 - conv_params->round_0)));
tmp[(k + 7) * 8 + (l + 4)] = sum;
sx += alpha;
}
}
// Vertical filter
for (k = -4; k < AOMMIN(4, p_row + p_height - i - 4); ++k) {
int sy = sy4 + delta * (k + 4);
for (l = -4; l < 4; ++l) {
const int offs = ROUND_POWER_OF_TWO(sy, WARPEDDIFF_PREC_BITS) +
WARPEDPIXEL_PREC_SHIFTS;
assert(offs >= 0 && offs <= WARPEDPIXEL_PREC_SHIFTS * 3);
const int16_t *coeffs = warped_filter[offs];
int32_t sum = 1 << offset_bits_vert;
for (m = 0; m < 8; ++m) {
sum += tmp[(k + m + 4) * 8 + (l + 4)] * coeffs[m];
}
sum = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
(1 << (offset_bits_horiz + FILTER_BITS - conv_params->round_0 -
conv_params->round_1)) -
(1 << (offset_bits_vert - conv_params->round_1));
CONV_BUF_TYPE *p =
&conv_params->dst[(i - p_row + k + 4) * conv_params->dst_stride +
(j - p_col + l + 4)];
*p += sum;
sy += gamma;
}
}
}
}
}
#endif
static void highbd_warp_plane(WarpedMotionParams *wm, const uint8_t *const ref8,
int width, int height, int stride,
const uint8_t *const pred8, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int x_scale,
int y_scale, int bd, int comp_avg) {
int y_scale, int bd,
ConvolveParams *conv_params) {
if (wm->wmtype == ROTZOOM) {
wm->wmmat[5] = wm->wmmat[2];
wm->wmmat[4] = -wm->wmmat[3];
}
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) && x_scale == 16 &&
y_scale == 16) {
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) &&
x_scale == SCALE_SUBPEL_SHIFTS && y_scale == SCALE_SUBPEL_SHIFTS) {
const int32_t *const mat = wm->wmmat;
const int16_t alpha = wm->alpha;
const int16_t beta = wm->beta;
@ -1068,26 +1160,40 @@ static void highbd_warp_plane(WarpedMotionParams *wm, const uint8_t *const ref8,
const uint16_t *const ref = CONVERT_TO_SHORTPTR(ref8);
uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
#if CONFIG_CONVOLVE_ROUND
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
conv_params->do_post_rounding = 1;
av1_highbd_warp_affine_post_round(
mat, ref, width, height, stride, pred, p_col, p_row, p_width,
p_height, p_stride, subsampling_x, subsampling_y, bd, conv_params,
alpha, beta, gamma, delta);
} else {
av1_highbd_warp_affine(mat, ref, width, height, stride, pred, p_col,
p_row, p_width, p_height, p_stride, subsampling_x,
subsampling_y, bd, conv_params, alpha, beta, gamma,
delta);
}
#else
av1_highbd_warp_affine(mat, ref, width, height, stride, pred, p_col, p_row,
p_width, p_height, p_stride, subsampling_x,
subsampling_y, bd, comp_avg, alpha, beta, gamma,
subsampling_y, bd, conv_params, alpha, beta, gamma,
delta);
#endif
} else {
highbd_warp_plane_old(wm, ref8, width, height, stride, pred8, p_col, p_row,
p_width, p_height, p_stride, subsampling_x,
subsampling_y, x_scale, y_scale, bd, comp_avg);
subsampling_y, x_scale, y_scale, bd, conv_params);
}
}
static int64_t highbd_frame_error(const uint16_t *const ref, int stride,
const uint16_t *const dst, int p_col,
int p_row, int p_width, int p_height,
int p_stride, int bd) {
const uint16_t *const dst, int p_width,
int p_height, int p_stride, int bd) {
int64_t sum_error = 0;
for (int i = 0; i < p_height; ++i) {
for (int j = 0; j < p_width; ++j) {
sum_error += highbd_error_measure(
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride], bd);
sum_error +=
highbd_error_measure(dst[j + i * p_stride] - ref[j + i * stride], bd);
}
}
return sum_error;
@ -1097,19 +1203,31 @@ static int64_t highbd_warp_error(
WarpedMotionParams *wm, const uint8_t *const ref8, int width, int height,
int stride, const uint8_t *const dst8, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x, int subsampling_y,
int x_scale, int y_scale, int bd) {
int x_scale, int y_scale, int bd, int64_t best_error) {
int64_t gm_sumerr = 0;
uint16_t *tmp = aom_malloc(p_width * p_height * sizeof(*tmp));
if (!tmp) return INT64_MAX;
int warp_w, warp_h;
int error_bsize_w = AOMMIN(p_width, WARP_ERROR_BLOCK);
int error_bsize_h = AOMMIN(p_height, WARP_ERROR_BLOCK);
uint16_t tmp[WARP_ERROR_BLOCK * WARP_ERROR_BLOCK];
highbd_warp_plane(wm, ref8, width, height, stride, CONVERT_TO_BYTEPTR(tmp),
p_col, p_row, p_width, p_height, p_width, subsampling_x,
subsampling_y, x_scale, y_scale, bd, 0);
ConvolveParams conv_params = get_conv_params(0, 0, 0);
for (int i = p_row; i < p_row + p_height; i += WARP_ERROR_BLOCK) {
for (int j = p_col; j < p_col + p_width; j += WARP_ERROR_BLOCK) {
// avoid warping extra 8x8 blocks in the padded region of the frame
// when p_width and p_height are not multiples of WARP_ERROR_BLOCK
warp_w = AOMMIN(error_bsize_w, p_col + p_width - j);
warp_h = AOMMIN(error_bsize_h, p_row + p_height - i);
highbd_warp_plane(wm, ref8, width, height, stride,
CONVERT_TO_BYTEPTR(tmp), j, i, warp_w, warp_h,
WARP_ERROR_BLOCK, subsampling_x, subsampling_y, x_scale,
y_scale, bd, &conv_params);
gm_sumerr = highbd_frame_error(tmp, p_width, CONVERT_TO_SHORTPTR(dst8), p_col,
p_row, p_width, p_height, p_stride, bd);
aom_free(tmp);
gm_sumerr += highbd_frame_error(
tmp, WARP_ERROR_BLOCK, CONVERT_TO_SHORTPTR(dst8) + j + i * p_stride,
warp_w, warp_h, p_stride, bd);
if (gm_sumerr > best_error) return gm_sumerr;
}
}
return gm_sumerr;
}
#endif // CONFIG_HIGHBITDEPTH
@ -1123,7 +1241,7 @@ static void warp_plane_old(const WarpedMotionParams *const wm,
int stride, uint8_t *pred, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int x_scale,
int y_scale, int comp_avg) {
int y_scale, ConvolveParams *conv_params) {
int i, j;
ProjectPointsFunc projectpoints = get_project_points_type(wm->wmtype);
if (projectpoints == NULL) return;
@ -1135,7 +1253,7 @@ static void warp_plane_old(const WarpedMotionParams *const wm,
projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
if (comp_avg)
if (conv_params->do_average)
pred[(j - p_col) + (i - p_row) * p_stride] = ROUND_POWER_OF_TWO(
pred[(j - p_col) + (i - p_row) * p_stride] +
warp_interpolate(ref, out[0], out[1], width, height, stride),
@ -1235,10 +1353,10 @@ static void warp_plane_old(const WarpedMotionParams *const wm,
void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width,
int height, int stride, uint8_t *pred, int p_col,
int p_row, int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int comp_avg,
int16_t alpha, int16_t beta, int16_t gamma,
int16_t delta) {
uint16_t tmp[15 * 8];
int subsampling_x, int subsampling_y,
ConvolveParams *conv_params, int16_t alpha, int16_t beta,
int16_t gamma, int16_t delta) {
int32_t tmp[15 * 8];
int i, j, k, l, m;
const int bd = 8;
@ -1329,7 +1447,7 @@ void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width,
sum = ROUND_POWER_OF_TWO(sum, VERSHEAR_REDUCE_PREC_BITS);
assert(0 <= sum && sum < (1 << (bd + 2)));
uint8_t px = clip_pixel(sum - (1 << (bd - 1)) - (1 << bd));
if (comp_avg)
if (conv_params->do_average)
*p = ROUND_POWER_OF_TWO(*p + px, 1);
else
*p = px;
@ -1340,41 +1458,170 @@ void av1_warp_affine_c(const int32_t *mat, const uint8_t *ref, int width,
}
}
#if CONFIG_CONVOLVE_ROUND
void av1_warp_affine_post_round_c(const int32_t *mat, const uint8_t *ref,
int width, int height, int stride,
uint8_t *pred, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y,
ConvolveParams *conv_params, int16_t alpha,
int16_t beta, int16_t gamma, int16_t delta) {
(void)pred;
(void)p_stride;
int32_t tmp[15 * 8];
int i, j, k, l, m;
const int bd = 8;
const int offset_bits_horiz = bd + FILTER_BITS - 1;
const int offset_bits_vert = bd + 2 * FILTER_BITS - conv_params->round_0;
assert(FILTER_BITS == WARPEDPIXEL_FILTER_BITS);
for (i = p_row; i < p_row + p_height; i += 8) {
for (j = p_col; j < p_col + p_width; j += 8) {
int32_t x4, y4, ix4, sx4, iy4, sy4;
if (subsampling_x)
x4 = (mat[2] * 4 * (j + 4) + mat[3] * 4 * (i + 4) + mat[0] * 2 +
(mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS))) /
4;
else
x4 = mat[2] * (j + 4) + mat[3] * (i + 4) + mat[0];
if (subsampling_y)
y4 = (mat[4] * 4 * (j + 4) + mat[5] * 4 * (i + 4) + mat[1] * 2 +
(mat[4] + mat[5] - (1 << WARPEDMODEL_PREC_BITS))) /
4;
else
y4 = mat[4] * (j + 4) + mat[5] * (i + 4) + mat[1];
ix4 = x4 >> WARPEDMODEL_PREC_BITS;
sx4 = x4 & ((1 << WARPEDMODEL_PREC_BITS) - 1);
iy4 = y4 >> WARPEDMODEL_PREC_BITS;
sy4 = y4 & ((1 << WARPEDMODEL_PREC_BITS) - 1);
sx4 += alpha * (-4) + beta * (-4);
sy4 += gamma * (-4) + delta * (-4);
sx4 &= ~((1 << WARP_PARAM_REDUCE_BITS) - 1);
sy4 &= ~((1 << WARP_PARAM_REDUCE_BITS) - 1);
// Horizontal filter
for (k = -7; k < 8; ++k) {
// Clamp to top/bottom edge of the frame
int iy = iy4 + k;
if (iy < 0)
iy = 0;
else if (iy > height - 1)
iy = height - 1;
int sx = sx4 + beta * (k + 4);
for (l = -4; l < 4; ++l) {
int ix = ix4 + l - 3;
// At this point, sx = sx4 + alpha * l + beta * k
const int offs = ROUND_POWER_OF_TWO(sx, WARPEDDIFF_PREC_BITS) +
WARPEDPIXEL_PREC_SHIFTS;
assert(offs >= 0 && offs <= WARPEDPIXEL_PREC_SHIFTS * 3);
const int16_t *coeffs = warped_filter[offs];
int32_t sum = 1 << offset_bits_horiz;
for (m = 0; m < 8; ++m) {
// Clamp to left/right edge of the frame
int sample_x = ix + m;
if (sample_x < 0)
sample_x = 0;
else if (sample_x > width - 1)
sample_x = width - 1;
sum += ref[iy * stride + sample_x] * coeffs[m];
}
sum = ROUND_POWER_OF_TWO(sum, conv_params->round_0);
assert(0 <= sum &&
sum < (1 << (bd + FILTER_BITS + 1 - conv_params->round_0)));
tmp[(k + 7) * 8 + (l + 4)] = sum;
sx += alpha;
}
}
// Vertical filter
for (k = -4; k < AOMMIN(4, p_row + p_height - i - 4); ++k) {
int sy = sy4 + delta * (k + 4);
for (l = -4; l < AOMMIN(4, p_col + p_width - j - 4); ++l) {
// At this point, sy = sy4 + gamma * l + delta * k
const int offs = ROUND_POWER_OF_TWO(sy, WARPEDDIFF_PREC_BITS) +
WARPEDPIXEL_PREC_SHIFTS;
assert(offs >= 0 && offs <= WARPEDPIXEL_PREC_SHIFTS * 3);
const int16_t *coeffs = warped_filter[offs];
int32_t sum = 1 << offset_bits_vert;
for (m = 0; m < 8; ++m) {
sum += tmp[(k + m + 4) * 8 + (l + 4)] * coeffs[m];
}
sum = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
(1 << (offset_bits_horiz + FILTER_BITS - conv_params->round_0 -
conv_params->round_1)) -
(1 << (offset_bits_vert - conv_params->round_1));
CONV_BUF_TYPE *p =
&conv_params->dst[(i - p_row + k + 4) * conv_params->dst_stride +
(j - p_col + l + 4)];
*p += sum;
sy += gamma;
}
}
}
}
}
#endif // CONFIG_CONVOLVE_ROUND
static void warp_plane(WarpedMotionParams *wm, const uint8_t *const ref,
int width, int height, int stride, uint8_t *pred,
int p_col, int p_row, int p_width, int p_height,
int p_stride, int subsampling_x, int subsampling_y,
int x_scale, int y_scale, int comp_avg) {
int x_scale, int y_scale, ConvolveParams *conv_params) {
if (wm->wmtype == ROTZOOM) {
wm->wmmat[5] = wm->wmmat[2];
wm->wmmat[4] = -wm->wmmat[3];
}
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) && x_scale == 16 &&
y_scale == 16) {
if ((wm->wmtype == ROTZOOM || wm->wmtype == AFFINE) &&
x_scale == SCALE_SUBPEL_SHIFTS && y_scale == SCALE_SUBPEL_SHIFTS) {
const int32_t *const mat = wm->wmmat;
const int16_t alpha = wm->alpha;
const int16_t beta = wm->beta;
const int16_t gamma = wm->gamma;
const int16_t delta = wm->delta;
#if CONFIG_CONVOLVE_ROUND
if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
conv_params->do_post_rounding = 1;
av1_warp_affine_post_round(mat, ref, width, height, stride, pred, p_col,
p_row, p_width, p_height, p_stride,
subsampling_x, subsampling_y, conv_params,
alpha, beta, gamma, delta);
} else {
av1_warp_affine(mat, ref, width, height, stride, pred, p_col, p_row,
p_width, p_height, p_stride, subsampling_x, subsampling_y,
conv_params, alpha, beta, gamma, delta);
}
#else
av1_warp_affine(mat, ref, width, height, stride, pred, p_col, p_row,
p_width, p_height, p_stride, subsampling_x, subsampling_y,
comp_avg, alpha, beta, gamma, delta);
conv_params, alpha, beta, gamma, delta);
#endif
} else {
warp_plane_old(wm, ref, width, height, stride, pred, p_col, p_row, p_width,
p_height, p_stride, subsampling_x, subsampling_y, x_scale,
y_scale, comp_avg);
y_scale, conv_params);
}
}
static int64_t frame_error(const uint8_t *const ref, int stride,
const uint8_t *const dst, int p_col, int p_row,
int p_width, int p_height, int p_stride) {
const uint8_t *const dst, int p_width, int p_height,
int p_stride) {
int64_t sum_error = 0;
for (int i = 0; i < p_height; ++i) {
for (int j = 0; j < p_width; ++j) {
sum_error += (int64_t)error_measure(
dst[j + i * p_stride] - ref[(j + p_col) + (i + p_row) * stride]);
sum_error +=
(int64_t)error_measure(dst[j + i * p_stride] - ref[j + i * stride]);
}
}
return sum_error;
@ -1385,19 +1632,29 @@ static int64_t warp_error(WarpedMotionParams *wm, const uint8_t *const ref,
const uint8_t *const dst, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int x_scale,
int y_scale) {
int y_scale, int64_t best_error) {
int64_t gm_sumerr = 0;
uint8_t *tmp = aom_malloc(p_width * p_height);
if (!tmp) return INT64_MAX;
int warp_w, warp_h;
int error_bsize_w = AOMMIN(p_width, WARP_ERROR_BLOCK);
int error_bsize_h = AOMMIN(p_height, WARP_ERROR_BLOCK);
uint8_t tmp[WARP_ERROR_BLOCK * WARP_ERROR_BLOCK];
ConvolveParams conv_params = get_conv_params(0, 0, 0);
warp_plane(wm, ref, width, height, stride, tmp, p_col, p_row, p_width,
p_height, p_width, subsampling_x, subsampling_y, x_scale, y_scale,
0);
for (int i = p_row; i < p_row + p_height; i += WARP_ERROR_BLOCK) {
for (int j = p_col; j < p_col + p_width; j += WARP_ERROR_BLOCK) {
// avoid warping extra 8x8 blocks in the padded region of the frame
// when p_width and p_height are not multiples of WARP_ERROR_BLOCK
warp_w = AOMMIN(error_bsize_w, p_col + p_width - j);
warp_h = AOMMIN(error_bsize_h, p_row + p_height - i);
warp_plane(wm, ref, width, height, stride, tmp, j, i, warp_w, warp_h,
WARP_ERROR_BLOCK, subsampling_x, subsampling_y, x_scale,
y_scale, &conv_params);
gm_sumerr =
frame_error(tmp, p_width, dst, p_col, p_row, p_width, p_height, p_stride);
aom_free(tmp);
gm_sumerr += frame_error(tmp, WARP_ERROR_BLOCK, dst + j + i * p_stride,
warp_w, warp_h, p_stride);
if (gm_sumerr > best_error) return gm_sumerr;
}
}
return gm_sumerr;
}
@ -1405,17 +1662,16 @@ int64_t av1_frame_error(
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int stride, uint8_t *dst, int p_col, int p_row,
int p_width, int p_height, int p_stride) {
const uint8_t *ref, int stride, uint8_t *dst, int p_width, int p_height,
int p_stride) {
#if CONFIG_HIGHBITDEPTH
if (use_hbd) {
return highbd_frame_error(CONVERT_TO_SHORTPTR(ref), stride,
CONVERT_TO_SHORTPTR(dst), p_col, p_row, p_width,
p_height, p_stride, bd);
CONVERT_TO_SHORTPTR(dst), p_width, p_height,
p_stride, bd);
}
#endif // CONFIG_HIGHBITDEPTH
return frame_error(ref, stride, dst, p_col, p_row, p_width, p_height,
p_stride);
return frame_error(ref, stride, dst, p_width, p_height, p_stride);
}
int64_t av1_warp_error(WarpedMotionParams *wm,
@ -1425,18 +1681,19 @@ int64_t av1_warp_error(WarpedMotionParams *wm,
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale) {
int subsampling_y, int x_scale, int y_scale,
int64_t best_error) {
if (wm->wmtype <= AFFINE)
if (!get_shear_params(wm)) return 1;
#if CONFIG_HIGHBITDEPTH
if (use_hbd)
return highbd_warp_error(wm, ref, width, height, stride, dst, p_col, p_row,
p_width, p_height, p_stride, subsampling_x,
subsampling_y, x_scale, y_scale, bd);
subsampling_y, x_scale, y_scale, bd, best_error);
#endif // CONFIG_HIGHBITDEPTH
return warp_error(wm, ref, width, height, stride, dst, p_col, p_row, p_width,
p_height, p_stride, subsampling_x, subsampling_y, x_scale,
y_scale);
y_scale, best_error);
}
void av1_warp_plane(WarpedMotionParams *wm,
@ -1446,17 +1703,18 @@ void av1_warp_plane(WarpedMotionParams *wm,
const uint8_t *ref, int width, int height, int stride,
uint8_t *pred, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale, int comp_avg) {
int subsampling_y, int x_scale, int y_scale,
ConvolveParams *conv_params) {
#if CONFIG_HIGHBITDEPTH
if (use_hbd)
highbd_warp_plane(wm, ref, width, height, stride, pred, p_col, p_row,
p_width, p_height, p_stride, subsampling_x, subsampling_y,
x_scale, y_scale, bd, comp_avg);
x_scale, y_scale, bd, conv_params);
else
#endif // CONFIG_HIGHBITDEPTH
warp_plane(wm, ref, width, height, stride, pred, p_col, p_row, p_width,
p_height, p_stride, subsampling_x, subsampling_y, x_scale,
y_scale, comp_avg);
y_scale, conv_params);
}
#if CONFIG_WARPED_MOTION
@ -1492,6 +1750,83 @@ void av1_warp_plane(WarpedMotionParams *wm,
#define LS_PRODUCT2(a, b) \
(((a) * (b)*4 + ((a) + (b)) * 2 * LS_STEP + LS_STEP * LS_STEP * 2) >> 2)
#define USE_LIMITED_PREC_MULT 0
#if USE_LIMITED_PREC_MULT
#define MUL_PREC_BITS 16
static uint16_t resolve_multiplier_64(uint64_t D, int16_t *shift) {
int msb = 0;
uint16_t mult = 0;
*shift = 0;
if (D != 0) {
msb = (int16_t)((D >> 32) ? get_msb((unsigned int)(D >> 32)) + 32
: get_msb((unsigned int)D));
if (msb >= MUL_PREC_BITS) {
mult = (uint16_t)ROUND_POWER_OF_TWO_64(D, msb + 1 - MUL_PREC_BITS);
*shift = msb + 1 - MUL_PREC_BITS;
} else {
mult = (uint16_t)D;
*shift = 0;
}
}
return mult;
}
static int32_t get_mult_shift_ndiag(int64_t Px, int16_t iDet, int shift) {
int32_t ret;
int16_t mshift;
uint16_t Mul = resolve_multiplier_64(llabs(Px), &mshift);
int32_t v = (int32_t)Mul * (int32_t)iDet * (Px < 0 ? -1 : 1);
shift -= mshift;
if (shift > 0) {
return (int32_t)clamp(ROUND_POWER_OF_TWO_SIGNED(v, shift),
-WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
} else {
return (int32_t)clamp(v * (1 << (-shift)),
-WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
}
return ret;
}
static int32_t get_mult_shift_diag(int64_t Px, int16_t iDet, int shift) {
int16_t mshift;
uint16_t Mul = resolve_multiplier_64(llabs(Px), &mshift);
int32_t v = (int32_t)Mul * (int32_t)iDet * (Px < 0 ? -1 : 1);
shift -= mshift;
if (shift > 0) {
return (int32_t)clamp(
ROUND_POWER_OF_TWO_SIGNED(v, shift),
(1 << WARPEDMODEL_PREC_BITS) - WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
(1 << WARPEDMODEL_PREC_BITS) + WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
} else {
return (int32_t)clamp(
v * (1 << (-shift)),
(1 << WARPEDMODEL_PREC_BITS) - WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
(1 << WARPEDMODEL_PREC_BITS) + WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
}
}
#else
static int32_t get_mult_shift_ndiag(int64_t Px, int16_t iDet, int shift) {
int64_t v = Px * (int64_t)iDet;
return (int32_t)clamp64(ROUND_POWER_OF_TWO_SIGNED_64(v, shift),
-WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
}
static int32_t get_mult_shift_diag(int64_t Px, int16_t iDet, int shift) {
int64_t v = Px * (int64_t)iDet;
return (int32_t)clamp64(
ROUND_POWER_OF_TWO_SIGNED_64(v, shift),
(1 << WARPEDMODEL_PREC_BITS) - WARPEDMODEL_NONDIAGAFFINE_CLAMP + 1,
(1 << WARPEDMODEL_PREC_BITS) + WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
}
#endif // USE_LIMITED_PREC_MULT
static int find_affine_int(int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
int mvy, int mvx, WarpedMotionParams *wm, int mi_row,
int mi_col) {
@ -1502,8 +1837,10 @@ static int find_affine_int(int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
const int suy = (mi_row * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2 - 1) * 8;
const int sux = (mi_col * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2 - 1) * 8;
const int isuy = (mi_row * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2 - 1);
const int isux = (mi_col * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2 - 1);
const int suy = isuy * 8;
const int sux = isux * 8;
const int duy = suy + mvy;
const int dux = sux + mvx;
@ -1590,61 +1927,39 @@ static int find_affine_int(int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
shift = 0;
}
int64_t v;
v = Px[0] * (int64_t)iDet;
wm->wmmat[2] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED_64(v, shift));
v = Px[1] * (int64_t)iDet;
wm->wmmat[3] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED_64(v, shift));
v = ((int64_t)dux * (1 << WARPEDMODEL_PREC_BITS)) -
(int64_t)sux * wm->wmmat[2] - (int64_t)suy * wm->wmmat[3];
wm->wmmat[0] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED(v, 3));
wm->wmmat[2] = get_mult_shift_diag(Px[0], iDet, shift);
wm->wmmat[3] = get_mult_shift_ndiag(Px[1], iDet, shift);
wm->wmmat[4] = get_mult_shift_ndiag(Py[0], iDet, shift);
wm->wmmat[5] = get_mult_shift_diag(Py[1], iDet, shift);
v = Py[0] * (int64_t)iDet;
wm->wmmat[4] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED_64(v, shift));
v = Py[1] * (int64_t)iDet;
wm->wmmat[5] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED_64(v, shift));
v = ((int64_t)duy * (1 << WARPEDMODEL_PREC_BITS)) -
(int64_t)sux * wm->wmmat[4] - (int64_t)suy * wm->wmmat[5];
wm->wmmat[1] = (int32_t)(ROUND_POWER_OF_TWO_SIGNED(v, 3));
// Note: In the vx, vy expressions below, the max value of each of the
// 2nd and 3rd terms are (2^16 - 1) * (2^13 - 1). That leaves enough room
// for the first term so that the overall sum in the worst case fits
// within 32 bits overall.
int32_t vx = mvx * (1 << (WARPEDMODEL_PREC_BITS - 3)) -
(isux * (wm->wmmat[2] - (1 << WARPEDMODEL_PREC_BITS)) +
isuy * wm->wmmat[3]);
int32_t vy = mvy * (1 << (WARPEDMODEL_PREC_BITS - 3)) -
(isux * wm->wmmat[4] +
isuy * (wm->wmmat[5] - (1 << WARPEDMODEL_PREC_BITS)));
wm->wmmat[0] =
clamp(vx, -WARPEDMODEL_TRANS_CLAMP, WARPEDMODEL_TRANS_CLAMP - 1);
wm->wmmat[1] =
clamp(vy, -WARPEDMODEL_TRANS_CLAMP, WARPEDMODEL_TRANS_CLAMP - 1);
wm->wmmat[6] = wm->wmmat[7] = 0;
// Clamp values
wm->wmmat[0] = clamp(wm->wmmat[0], -WARPEDMODEL_TRANS_CLAMP,
WARPEDMODEL_TRANS_CLAMP - 1);
wm->wmmat[1] = clamp(wm->wmmat[1], -WARPEDMODEL_TRANS_CLAMP,
WARPEDMODEL_TRANS_CLAMP - 1);
wm->wmmat[2] = clamp(wm->wmmat[2], -WARPEDMODEL_DIAGAFFINE_CLAMP,
WARPEDMODEL_DIAGAFFINE_CLAMP - 1);
wm->wmmat[5] = clamp(wm->wmmat[5], -WARPEDMODEL_DIAGAFFINE_CLAMP,
WARPEDMODEL_DIAGAFFINE_CLAMP - 1);
wm->wmmat[3] = clamp(wm->wmmat[3], -WARPEDMODEL_NONDIAGAFFINE_CLAMP,
WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
wm->wmmat[4] = clamp(wm->wmmat[4], -WARPEDMODEL_NONDIAGAFFINE_CLAMP,
WARPEDMODEL_NONDIAGAFFINE_CLAMP - 1);
return 0;
}
int find_projection(int np, int *pts1, int *pts2, BLOCK_SIZE bsize, int mvy,
int mvx, WarpedMotionParams *wm_params, int mi_row,
int mi_col) {
int result = 1;
switch (wm_params->wmtype) {
case AFFINE:
result = find_affine_int(np, pts1, pts2, bsize, mvy, mvx, wm_params,
mi_row, mi_col);
break;
default: assert(0 && "Invalid warped motion type!"); return 1;
}
assert(wm_params->wmtype == AFFINE);
const int result = find_affine_int(np, pts1, pts2, bsize, mvy, mvx, wm_params,
mi_row, mi_col);
if (result == 0) {
if (wm_params->wmtype == ROTZOOM) {
wm_params->wmmat[5] = wm_params->wmmat[2];
wm_params->wmmat[4] = -wm_params->wmmat[3];
}
if (wm_params->wmtype == AFFINE || wm_params->wmtype == ROTZOOM) {
// check compatibility with the fast warp filter
if (!get_shear_params(wm_params)) return 1;
}
// check compatibility with the fast warp filter
if (!get_shear_params(wm_params)) return 1;
}
return result;

View file

@ -22,14 +22,22 @@
#include "aom_ports/mem.h"
#include "aom_dsp/aom_dsp_common.h"
#include "av1/common/mv.h"
#include "av1/common/convolve.h"
#define MAX_PARAMDIM 9
#if CONFIG_WARPED_MOTION
#define SAMPLES_ARRAY_SIZE ((2 * MAX_MIB_SIZE + 2) * 2)
#define LEAST_SQUARES_SAMPLES_MAX_BITS 3
#define LEAST_SQUARES_SAMPLES_MAX (1 << LEAST_SQUARES_SAMPLES_MAX_BITS)
#if WARPED_MOTION_SORT_SAMPLES
// #define SAMPLES_ARRAY_SIZE (LEAST_SQUARES_SAMPLES_MAX * 2)
// Search half bsize on the top and half bsize on the left, 1 upper-left block,
// 1 upper-right block.
#define SAMPLES_ARRAY_SIZE ((MAX_MIB_SIZE * MAX_MIB_SIZE + 2) * 2)
#else
#define SAMPLES_ARRAY_SIZE (LEAST_SQUARES_SAMPLES_MAX * 2)
#endif // WARPED_MOTION_SORT_SAMPLES
#define DEFAULT_WMTYPE AFFINE
#endif // CONFIG_WARPED_MOTION
@ -69,10 +77,6 @@ void project_points_homography(const int32_t *mat, int *points, int *proj,
const int stride_proj, const int subsampling_x,
const int subsampling_y);
void project_points(const WarpedMotionParams *wm_params, int *points, int *proj,
const int n, const int stride_points, const int stride_proj,
const int subsampling_x, const int subsampling_y);
// Returns the error between the result of applying motion 'wm' to the frame
// described by 'ref' and the frame described by 'dst'.
int64_t av1_warp_error(WarpedMotionParams *wm,
@ -82,7 +86,8 @@ int64_t av1_warp_error(WarpedMotionParams *wm,
const uint8_t *ref, int width, int height, int stride,
uint8_t *dst, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale);
int subsampling_y, int x_scale, int y_scale,
int64_t best_error);
// Returns the error between the frame described by 'ref' and the frame
// described by 'dst'.
@ -90,8 +95,8 @@ int64_t av1_frame_error(
#if CONFIG_HIGHBITDEPTH
int use_hbd, int bd,
#endif // CONFIG_HIGHBITDEPTH
const uint8_t *ref, int stride, uint8_t *dst, int p_col, int p_row,
int p_width, int p_height, int p_stride);
const uint8_t *ref, int stride, uint8_t *dst, int p_width, int p_height,
int p_stride);
void av1_warp_plane(WarpedMotionParams *wm,
#if CONFIG_HIGHBITDEPTH
@ -100,7 +105,8 @@ void av1_warp_plane(WarpedMotionParams *wm,
const uint8_t *ref, int width, int height, int stride,
uint8_t *pred, int p_col, int p_row, int p_width,
int p_height, int p_stride, int subsampling_x,
int subsampling_y, int x_scale, int y_scale, int comp_avg);
int subsampling_y, int x_scale, int y_scale,
ConvolveParams *conv_params);
int find_projection(int np, int *pts1, int *pts2, BLOCK_SIZE bsize, int mvy,
int mvx, WarpedMotionParams *wm_params, int mi_row,

View file

@ -676,11 +676,12 @@ void av1_convolve_horiz_ssse3(const uint8_t *src, int src_stride, uint8_t *dst,
__m128i verf[6];
__m128i horf[2];
SubpelFilterCoeffs hCoeffs, vCoeffs;
assert(conv_params->do_average == 0 || conv_params->do_average == 1);
const uint8_t *src_ptr;
store_pixel_t store2p = store2pixelTab[conv_params->ref];
store_pixel_t store4p = store4pixelTab[conv_params->ref];
transpose_to_dst_t transpose_4x4 = trans4x4Tab[conv_params->ref];
transpose_to_dst_t transpose_8x8 = trans8x8Tab[conv_params->ref];
store_pixel_t store2p = store2pixelTab[conv_params->do_average];
store_pixel_t store4p = store4pixelTab[conv_params->do_average];
transpose_to_dst_t transpose_4x4 = trans4x4Tab[conv_params->do_average];
transpose_to_dst_t transpose_8x8 = trans8x8Tab[conv_params->do_average];
const int tapsNum = filter_params.taps;
int block_height, block_residu;
@ -890,10 +891,11 @@ void av1_convolve_vert_ssse3(const uint8_t *src, int src_stride, uint8_t *dst,
__m128i verf[6];
SubpelFilterCoeffs vCoeffs;
const uint8_t *src_ptr;
assert(conv_params->do_average == 0 || conv_params->do_average == 1);
uint8_t *dst_ptr = dst;
store_pixel_t store2p = store2pixelTab[conv_params->ref];
store_pixel_t store4p = store4pixelTab[conv_params->ref];
store_pixel_t store8p = store8pixelTab[conv_params->ref];
store_pixel_t store2p = store2pixelTab[conv_params->do_average];
store_pixel_t store4p = store4pixelTab[conv_params->do_average];
store_pixel_t store8p = store8pixelTab[conv_params->do_average];
const int tapsNum = filter_params.taps;
if (0 == subpel_y_q4 || 16 != y_step_q4) {

View file

@ -40,7 +40,12 @@ static INLINE void fwd_txfm2d_sse4_1(const int16_t *input, int32_t *output,
const int stride,
const TXFM_2D_FLIP_CFG *cfg,
int32_t *txfm_buf) {
// TODO(sarahparker) must correct for rectangular transforms in follow up
// TODO(sarahparker) This does not currently support rectangular transforms
// and will break without splitting txfm_size out into row and col size.
// Rectangular transforms use c code only, so it should be ok for now.
// It will be corrected when there are sse implementations for rectangular
// transforms.
assert(cfg->row_cfg->txfm_size == cfg->col_cfg->txfm_size);
const int txfm_size = cfg->row_cfg->txfm_size;
const int8_t *shift = cfg->row_cfg->shift;
const int8_t *stage_range_col = cfg->col_cfg->stage_range;

View file

@ -64,7 +64,7 @@ static INLINE void transpose_32_4x4(int stride, const __m128i *input,
// the entire input block can be represent by a grid of 4x4 blocks
// each 4x4 blocks can be represent by 4 vertical __m128i
// we first transpose each 4x4 block internally
// than transpose the grid
// then transpose the grid
static INLINE void transpose_32(int txfm_size, const __m128i *input,
__m128i *output) {
const int num_per_128 = 4;

View file

@ -0,0 +1,367 @@
/*
* 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 <emmintrin.h>
#include "./aom_dsp_rtcd.h"
#include "aom_dsp/aom_convolve.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
#include "av1/common/convolve.h"
#if CONFIG_COMPOUND_ROUND
void av1_convolve_2d_sse2(const uint8_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params) {
DECLARE_ALIGNED(16, uint8_t,
im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE]);
int im_h = h + filter_params_y->taps - 1;
int im_stride = MAX_SB_SIZE;
int i, j;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
const __m128i zero = _mm_setzero_si128();
/* Horizontal filter */
{
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)x_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const =
_mm_set1_epi32((1 << conv_params->round_0) >> 1);
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_0);
for (i = 0; i < im_h; ++i) {
for (j = 0; j < w; j += 8) {
const __m128i data =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j]);
// Filter even-index pixels
const __m128i src_0 = _mm_unpacklo_epi8(data, zero);
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i src_2 = _mm_unpacklo_epi8(_mm_srli_si128(data, 2), zero);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i src_4 = _mm_unpacklo_epi8(_mm_srli_si128(data, 4), zero);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i src_6 = _mm_unpacklo_epi8(_mm_srli_si128(data, 6), zero);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
__m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_4),
_mm_add_epi32(res_2, res_6));
res_even =
_mm_sra_epi32(_mm_add_epi32(res_even, round_const), round_shift);
// Filter odd-index pixels
const __m128i src_1 = _mm_unpacklo_epi8(_mm_srli_si128(data, 1), zero);
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i src_3 = _mm_unpacklo_epi8(_mm_srli_si128(data, 3), zero);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i src_5 = _mm_unpacklo_epi8(_mm_srli_si128(data, 5), zero);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i src_7 = _mm_unpacklo_epi8(_mm_srli_si128(data, 7), zero);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
__m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_5),
_mm_add_epi32(res_3, res_7));
res_odd =
_mm_sra_epi32(_mm_add_epi32(res_odd, round_const), round_shift);
// Pack in the column order 0, 2, 4, 6, 1, 3, 5, 7
__m128i res = _mm_packs_epi32(res_even, res_odd);
res = _mm_packus_epi16(res, res);
_mm_storel_epi64((__m128i *)&im_block[i * im_stride + j], res);
}
}
}
/* Vertical filter */
{
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
const __m128i coeffs_y = _mm_loadu_si128((__m128i *)y_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const =
_mm_set1_epi32((1 << conv_params->round_1) >> 1);
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_1);
for (i = 0; i < h; ++i) {
for (j = 0; j < w; j += 8) {
// Filter even-index pixels
const uint8_t *data = &im_block[i * im_stride + j];
const __m128i src_01 = _mm_unpacklo_epi8(
_mm_loadl_epi64((__m128i *)(data + 0 * im_stride)),
_mm_loadl_epi64((__m128i *)(data + 1 * im_stride)));
const __m128i src_23 = _mm_unpacklo_epi8(
_mm_loadl_epi64((__m128i *)(data + 2 * im_stride)),
_mm_loadl_epi64((__m128i *)(data + 3 * im_stride)));
const __m128i src_45 = _mm_unpacklo_epi8(
_mm_loadl_epi64((__m128i *)(data + 4 * im_stride)),
_mm_loadl_epi64((__m128i *)(data + 5 * im_stride)));
const __m128i src_67 = _mm_unpacklo_epi8(
_mm_loadl_epi64((__m128i *)(data + 6 * im_stride)),
_mm_loadl_epi64((__m128i *)(data + 7 * im_stride)));
const __m128i src_0 = _mm_unpacklo_epi8(src_01, zero);
const __m128i src_2 = _mm_unpacklo_epi8(src_23, zero);
const __m128i src_4 = _mm_unpacklo_epi8(src_45, zero);
const __m128i src_6 = _mm_unpacklo_epi8(src_67, zero);
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
const __m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_2),
_mm_add_epi32(res_4, res_6));
// Filter odd-index pixels
const __m128i src_1 = _mm_unpackhi_epi8(src_01, zero);
const __m128i src_3 = _mm_unpackhi_epi8(src_23, zero);
const __m128i src_5 = _mm_unpackhi_epi8(src_45, zero);
const __m128i src_7 = _mm_unpackhi_epi8(src_67, zero);
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
const __m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_3),
_mm_add_epi32(res_5, res_7));
// Rearrange pixels back into the order 0 ... 7
const __m128i res_lo = _mm_unpacklo_epi32(res_even, res_odd);
const __m128i res_hi = _mm_unpackhi_epi32(res_even, res_odd);
const __m128i res_lo_round =
_mm_sra_epi32(_mm_add_epi32(res_lo, round_const), round_shift);
const __m128i res_hi_round =
_mm_sra_epi32(_mm_add_epi32(res_hi, round_const), round_shift);
// Accumulate values into the destination buffer
__m128i *const p = (__m128i *)&dst[i * dst_stride + j];
_mm_storeu_si128(p, _mm_add_epi32(_mm_loadu_si128(p), res_lo_round));
_mm_storeu_si128(p + 1,
_mm_add_epi32(_mm_loadu_si128(p + 1), res_hi_round));
}
}
}
}
#else
void av1_convolve_2d_sse2(const uint8_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w, int h,
InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params) {
const int bd = 8;
DECLARE_ALIGNED(16, int16_t,
im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE]);
int im_h = h + filter_params_y->taps - 1;
int im_stride = MAX_SB_SIZE;
int i, j;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
const __m128i zero = _mm_setzero_si128();
/* Horizontal filter */
{
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)x_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const = _mm_set1_epi32(
((1 << conv_params->round_0) >> 1) + (1 << (bd + FILTER_BITS - 1)));
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_0);
for (i = 0; i < im_h; ++i) {
for (j = 0; j < w; j += 8) {
const __m128i data =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j]);
// Filter even-index pixels
const __m128i src_0 = _mm_unpacklo_epi8(data, zero);
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i src_2 = _mm_unpacklo_epi8(_mm_srli_si128(data, 2), zero);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i src_4 = _mm_unpacklo_epi8(_mm_srli_si128(data, 4), zero);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i src_6 = _mm_unpacklo_epi8(_mm_srli_si128(data, 6), zero);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
__m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_4),
_mm_add_epi32(res_2, res_6));
res_even =
_mm_sra_epi32(_mm_add_epi32(res_even, round_const), round_shift);
// Filter odd-index pixels
const __m128i src_1 = _mm_unpacklo_epi8(_mm_srli_si128(data, 1), zero);
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i src_3 = _mm_unpacklo_epi8(_mm_srli_si128(data, 3), zero);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i src_5 = _mm_unpacklo_epi8(_mm_srli_si128(data, 5), zero);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i src_7 = _mm_unpacklo_epi8(_mm_srli_si128(data, 7), zero);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
__m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_5),
_mm_add_epi32(res_3, res_7));
res_odd =
_mm_sra_epi32(_mm_add_epi32(res_odd, round_const), round_shift);
// Pack in the column order 0, 2, 4, 6, 1, 3, 5, 7
__m128i res = _mm_packs_epi32(res_even, res_odd);
_mm_storeu_si128((__m128i *)&im_block[i * im_stride + j], res);
}
}
}
/* Vertical filter */
{
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
const __m128i coeffs_y = _mm_loadu_si128((__m128i *)y_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const = _mm_set1_epi32(
((1 << conv_params->round_1) >> 1) -
(1 << (bd + 2 * FILTER_BITS - conv_params->round_0 - 1)));
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_1);
for (i = 0; i < h; ++i) {
for (j = 0; j < w; j += 8) {
// Filter even-index pixels
const int16_t *data = &im_block[i * im_stride + j];
const __m128i src_0 =
_mm_unpacklo_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_2 =
_mm_unpacklo_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_4 =
_mm_unpacklo_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_6 =
_mm_unpacklo_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
const __m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_2),
_mm_add_epi32(res_4, res_6));
// Filter odd-index pixels
const __m128i src_1 =
_mm_unpackhi_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_3 =
_mm_unpackhi_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_5 =
_mm_unpackhi_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_7 =
_mm_unpackhi_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
const __m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_3),
_mm_add_epi32(res_5, res_7));
// Rearrange pixels back into the order 0 ... 7
const __m128i res_lo = _mm_unpacklo_epi32(res_even, res_odd);
const __m128i res_hi = _mm_unpackhi_epi32(res_even, res_odd);
const __m128i res_lo_round =
_mm_sra_epi32(_mm_add_epi32(res_lo, round_const), round_shift);
const __m128i res_hi_round =
_mm_sra_epi32(_mm_add_epi32(res_hi, round_const), round_shift);
// Accumulate values into the destination buffer
__m128i *const p = (__m128i *)&dst[i * dst_stride + j];
_mm_storeu_si128(p, _mm_add_epi32(_mm_loadu_si128(p), res_lo_round));
_mm_storeu_si128(p + 1,
_mm_add_epi32(_mm_loadu_si128(p + 1), res_hi_round));
}
}
}
}
#endif

View file

@ -0,0 +1,342 @@
/*
* 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.
*/
#include <immintrin.h>
#include "aom_dsp/aom_dsp_common.h"
#include "./av1_rtcd.h"
#if CONFIG_CONVOLVE_ROUND
static const uint32_t sindex[8] = { 0, 4, 1, 5, 2, 6, 3, 7 };
// 16 epi16 pixels
static INLINE void pixel_clamp_avx2(__m256i *u, int bd) {
const __m256i one = _mm256_set1_epi16(1);
const __m256i max = _mm256_sub_epi16(_mm256_slli_epi16(one, bd), one);
__m256i clamped, mask;
mask = _mm256_cmpgt_epi16(*u, max);
clamped = _mm256_andnot_si256(mask, *u);
mask = _mm256_and_si256(mask, max);
clamped = _mm256_or_si256(mask, clamped);
const __m256i zero = _mm256_setzero_si256();
mask = _mm256_cmpgt_epi16(clamped, zero);
*u = _mm256_and_si256(clamped, mask);
}
// 8 epi16 pixels
static INLINE void pixel_clamp_sse2(__m128i *u, int bd) {
const __m128i one = _mm_set1_epi16(1);
const __m128i max = _mm_sub_epi16(_mm_slli_epi16(one, bd), one);
__m128i clamped, mask;
mask = _mm_cmpgt_epi16(*u, max);
clamped = _mm_andnot_si128(mask, *u);
mask = _mm_and_si128(mask, max);
clamped = _mm_or_si128(mask, clamped);
const __m128i zero = _mm_setzero_si128();
mask = _mm_cmpgt_epi16(clamped, zero);
*u = _mm_and_si128(clamped, mask);
}
// Work on multiple of 32 pixels
static INLINE void cal_rounding_32xn_avx2(const int32_t *src, uint8_t *dst,
const __m256i *rnd, int shift,
int num) {
do {
__m256i x0 = _mm256_loadu_si256((const __m256i *)src);
__m256i x1 = _mm256_loadu_si256((const __m256i *)src + 1);
__m256i x2 = _mm256_loadu_si256((const __m256i *)src + 2);
__m256i x3 = _mm256_loadu_si256((const __m256i *)src + 3);
x0 = _mm256_add_epi32(x0, *rnd);
x1 = _mm256_add_epi32(x1, *rnd);
x2 = _mm256_add_epi32(x2, *rnd);
x3 = _mm256_add_epi32(x3, *rnd);
x0 = _mm256_srai_epi32(x0, shift);
x1 = _mm256_srai_epi32(x1, shift);
x2 = _mm256_srai_epi32(x2, shift);
x3 = _mm256_srai_epi32(x3, shift);
x0 = _mm256_packs_epi32(x0, x1);
x2 = _mm256_packs_epi32(x2, x3);
pixel_clamp_avx2(&x0, 8);
pixel_clamp_avx2(&x2, 8);
x0 = _mm256_packus_epi16(x0, x2);
x1 = _mm256_loadu_si256((const __m256i *)sindex);
x2 = _mm256_permutevar8x32_epi32(x0, x1);
_mm256_storeu_si256((__m256i *)dst, x2);
src += 32;
dst += 32;
num--;
} while (num > 0);
}
static INLINE void cal_rounding_16_avx2(const int32_t *src, uint8_t *dst,
const __m256i *rnd, int shift) {
__m256i x0 = _mm256_loadu_si256((const __m256i *)src);
__m256i x1 = _mm256_loadu_si256((const __m256i *)src + 1);
x0 = _mm256_add_epi32(x0, *rnd);
x1 = _mm256_add_epi32(x1, *rnd);
x0 = _mm256_srai_epi32(x0, shift);
x1 = _mm256_srai_epi32(x1, shift);
x0 = _mm256_packs_epi32(x0, x1);
pixel_clamp_avx2(&x0, 8);
const __m256i x2 = _mm256_packus_epi16(x0, x0);
x1 = _mm256_loadu_si256((const __m256i *)sindex);
x0 = _mm256_permutevar8x32_epi32(x2, x1);
_mm_storeu_si128((__m128i *)dst, _mm256_castsi256_si128(x0));
}
static INLINE void cal_rounding_8_avx2(const int32_t *src, uint8_t *dst,
const __m256i *rnd, int shift) {
__m256i x0 = _mm256_loadu_si256((const __m256i *)src);
x0 = _mm256_add_epi32(x0, *rnd);
x0 = _mm256_srai_epi32(x0, shift);
x0 = _mm256_packs_epi32(x0, x0);
pixel_clamp_avx2(&x0, 8);
x0 = _mm256_packus_epi16(x0, x0);
const __m256i x1 = _mm256_loadu_si256((const __m256i *)sindex);
x0 = _mm256_permutevar8x32_epi32(x0, x1);
_mm_storel_epi64((__m128i *)dst, _mm256_castsi256_si128(x0));
}
static INLINE void cal_rounding_4_sse2(const int32_t *src, uint8_t *dst,
const __m128i *rnd, int shift) {
__m128i x = _mm_loadu_si128((const __m128i *)src);
x = _mm_add_epi32(x, *rnd);
x = _mm_srai_epi32(x, shift);
x = _mm_packs_epi32(x, x);
pixel_clamp_sse2(&x, 8);
x = _mm_packus_epi16(x, x);
*(uint32_t *)dst = _mm_cvtsi128_si32(x);
}
void av1_convolve_rounding_avx2(const int32_t *src, int src_stride,
uint8_t *dst, int dst_stride, int w, int h,
int bits) {
const __m256i rnd_num = _mm256_set1_epi32((int32_t)(1 << (bits - 1)));
const __m128i rnd_num_sse2 = _mm256_castsi256_si128(rnd_num);
if (w > 64) { // width = 128
do {
cal_rounding_32xn_avx2(src, dst, &rnd_num, bits, 4);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 32) { // width = 64
do {
cal_rounding_32xn_avx2(src, dst, &rnd_num, bits, 2);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 16) { // width = 32
do {
cal_rounding_32xn_avx2(src, dst, &rnd_num, bits, 1);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 8) { // width = 16
do {
cal_rounding_16_avx2(src, dst, &rnd_num, bits);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 4) { // width = 8
do {
cal_rounding_8_avx2(src, dst, &rnd_num, bits);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 2) { // width = 4
do {
cal_rounding_4_sse2(src, dst, &rnd_num_sse2, bits);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else { // width = 2
do {
dst[0] = clip_pixel(ROUND_POWER_OF_TWO(src[0], bits));
dst[1] = clip_pixel(ROUND_POWER_OF_TWO(src[1], bits));
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
}
}
#if CONFIG_HIGHBITDEPTH
static INLINE void cal_highbd_rounding_32xn_avx2(const int32_t *src,
uint16_t *dst,
const __m256i *rnd, int shift,
int num, int bd) {
do {
__m256i x0 = _mm256_loadu_si256((const __m256i *)src);
__m256i x1 = _mm256_loadu_si256((const __m256i *)src + 1);
__m256i x2 = _mm256_loadu_si256((const __m256i *)src + 2);
__m256i x3 = _mm256_loadu_si256((const __m256i *)src + 3);
x0 = _mm256_add_epi32(x0, *rnd);
x1 = _mm256_add_epi32(x1, *rnd);
x2 = _mm256_add_epi32(x2, *rnd);
x3 = _mm256_add_epi32(x3, *rnd);
x0 = _mm256_srai_epi32(x0, shift);
x1 = _mm256_srai_epi32(x1, shift);
x2 = _mm256_srai_epi32(x2, shift);
x3 = _mm256_srai_epi32(x3, shift);
x0 = _mm256_packs_epi32(x0, x1);
x2 = _mm256_packs_epi32(x2, x3);
pixel_clamp_avx2(&x0, bd);
pixel_clamp_avx2(&x2, bd);
x0 = _mm256_permute4x64_epi64(x0, 0xD8);
x2 = _mm256_permute4x64_epi64(x2, 0xD8);
_mm256_storeu_si256((__m256i *)dst, x0);
_mm256_storeu_si256((__m256i *)(dst + 16), x2);
src += 32;
dst += 32;
num--;
} while (num > 0);
}
static INLINE void cal_highbd_rounding_16_avx2(const int32_t *src,
uint16_t *dst,
const __m256i *rnd, int shift,
int bd) {
__m256i x0 = _mm256_loadu_si256((const __m256i *)src);
__m256i x1 = _mm256_loadu_si256((const __m256i *)src + 1);
x0 = _mm256_add_epi32(x0, *rnd);
x1 = _mm256_add_epi32(x1, *rnd);
x0 = _mm256_srai_epi32(x0, shift);
x1 = _mm256_srai_epi32(x1, shift);
x0 = _mm256_packs_epi32(x0, x1);
pixel_clamp_avx2(&x0, bd);
x0 = _mm256_permute4x64_epi64(x0, 0xD8);
_mm256_storeu_si256((__m256i *)dst, x0);
}
static INLINE void cal_highbd_rounding_8_avx2(const int32_t *src, uint16_t *dst,
const __m256i *rnd, int shift,
int bd) {
__m256i x = _mm256_loadu_si256((const __m256i *)src);
x = _mm256_add_epi32(x, *rnd);
x = _mm256_srai_epi32(x, shift);
x = _mm256_packs_epi32(x, x);
pixel_clamp_avx2(&x, bd);
x = _mm256_permute4x64_epi64(x, 0xD8);
_mm_storeu_si128((__m128i *)dst, _mm256_castsi256_si128(x));
}
static INLINE void cal_highbd_rounding_4_sse2(const int32_t *src, uint16_t *dst,
const __m128i *rnd, int shift,
int bd) {
__m128i x = _mm_loadu_si128((const __m128i *)src);
x = _mm_add_epi32(x, *rnd);
x = _mm_srai_epi32(x, shift);
x = _mm_packs_epi32(x, x);
pixel_clamp_sse2(&x, bd);
_mm_storel_epi64((__m128i *)dst, x);
}
void av1_highbd_convolve_rounding_avx2(const int32_t *src, int src_stride,
uint8_t *dst8, int dst_stride, int w,
int h, int bits, int bd) {
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
const __m256i rnd_num = _mm256_set1_epi32((int32_t)(1 << (bits - 1)));
const __m128i rnd_num_sse2 = _mm256_castsi256_si128(rnd_num);
if (w > 64) { // width = 128
do {
cal_highbd_rounding_32xn_avx2(src, dst, &rnd_num, bits, 4, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 32) { // width = 64
do {
cal_highbd_rounding_32xn_avx2(src, dst, &rnd_num, bits, 2, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 16) { // width = 32
do {
cal_highbd_rounding_32xn_avx2(src, dst, &rnd_num, bits, 1, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 8) { // width = 16
do {
cal_highbd_rounding_16_avx2(src, dst, &rnd_num, bits, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 4) { // width = 8
do {
cal_highbd_rounding_8_avx2(src, dst, &rnd_num, bits, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else if (w > 2) { // width = 4
do {
cal_highbd_rounding_4_sse2(src, dst, &rnd_num_sse2, bits, bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
} else { // width = 2
do {
dst[0] = clip_pixel_highbd(ROUND_POWER_OF_TWO(src[0], bits), bd);
dst[1] = clip_pixel_highbd(ROUND_POWER_OF_TWO(src[1], bits), bd);
src += src_stride;
dst += dst_stride;
h--;
} while (h > 0);
}
}
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_CONVOLVE_ROUND

View file

@ -0,0 +1,372 @@
/*
* 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 <tmmintrin.h>
#include <assert.h>
#include "./aom_dsp_rtcd.h"
#include "aom_dsp/aom_convolve.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
#include "av1/common/convolve.h"
#if CONFIG_COMPOUND_ROUND
void av1_highbd_convolve_2d_ssse3(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w,
int h, InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd) {
DECLARE_ALIGNED(16, int16_t,
im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE]);
int im_h = h + filter_params_y->taps - 1;
int im_stride = MAX_SB_SIZE;
int i, j;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const uint16_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
/* Horizontal filter */
{
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)x_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const =
_mm_set1_epi32((1 << conv_params->round_0) >> 1);
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_0);
for (i = 0; i < im_h; ++i) {
for (j = 0; j < w; j += 8) {
const __m128i data =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j]);
const __m128i data2 =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j + 8]);
// Filter even-index pixels
const __m128i res_0 = _mm_madd_epi16(data, coeff_01);
const __m128i res_2 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 4), coeff_23);
const __m128i res_4 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 8), coeff_45);
const __m128i res_6 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 12), coeff_67);
__m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_4),
_mm_add_epi32(res_2, res_6));
res_even =
_mm_sra_epi32(_mm_add_epi32(res_even, round_const), round_shift);
// Filter odd-index pixels
const __m128i res_1 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 2), coeff_01);
const __m128i res_3 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 6), coeff_23);
const __m128i res_5 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 10), coeff_45);
const __m128i res_7 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 14), coeff_67);
__m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_5),
_mm_add_epi32(res_3, res_7));
res_odd =
_mm_sra_epi32(_mm_add_epi32(res_odd, round_const), round_shift);
// Pack in the column order 0, 2, 4, 6, 1, 3, 5, 7
const __m128i maxval = _mm_set1_epi16((1 << bd) - 1);
__m128i res = _mm_packs_epi32(res_even, res_odd);
res = _mm_max_epi16(_mm_min_epi16(res, maxval), _mm_setzero_si128());
_mm_storeu_si128((__m128i *)&im_block[i * im_stride + j], res);
}
}
}
/* Vertical filter */
{
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
const __m128i coeffs_y = _mm_loadu_si128((__m128i *)y_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const =
_mm_set1_epi32((1 << conv_params->round_1) >> 1);
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_1);
for (i = 0; i < h; ++i) {
for (j = 0; j < w; j += 8) {
// Filter even-index pixels
const int16_t *data = &im_block[i * im_stride + j];
const __m128i src_0 =
_mm_unpacklo_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_2 =
_mm_unpacklo_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_4 =
_mm_unpacklo_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_6 =
_mm_unpacklo_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
const __m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_2),
_mm_add_epi32(res_4, res_6));
// Filter odd-index pixels
const __m128i src_1 =
_mm_unpackhi_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_3 =
_mm_unpackhi_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_5 =
_mm_unpackhi_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_7 =
_mm_unpackhi_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
const __m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_3),
_mm_add_epi32(res_5, res_7));
// Rearrange pixels back into the order 0 ... 7
const __m128i res_lo = _mm_unpacklo_epi32(res_even, res_odd);
const __m128i res_hi = _mm_unpackhi_epi32(res_even, res_odd);
const __m128i res_lo_round =
_mm_sra_epi32(_mm_add_epi32(res_lo, round_const), round_shift);
const __m128i res_hi_round =
_mm_sra_epi32(_mm_add_epi32(res_hi, round_const), round_shift);
// Accumulate values into the destination buffer
__m128i *const p = (__m128i *)&dst[i * dst_stride + j];
_mm_storeu_si128(p, _mm_add_epi32(_mm_loadu_si128(p), res_lo_round));
_mm_storeu_si128(p + 1,
_mm_add_epi32(_mm_loadu_si128(p + 1), res_hi_round));
}
}
}
}
#else
void av1_highbd_convolve_2d_ssse3(const uint16_t *src, int src_stride,
CONV_BUF_TYPE *dst, int dst_stride, int w,
int h, InterpFilterParams *filter_params_x,
InterpFilterParams *filter_params_y,
const int subpel_x_q4, const int subpel_y_q4,
ConvolveParams *conv_params, int bd) {
DECLARE_ALIGNED(16, int16_t,
im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE]);
int im_h = h + filter_params_y->taps - 1;
int im_stride = MAX_SB_SIZE;
int i, j;
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const uint16_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
// Check that, even with 12-bit input, the intermediate values will fit
// into an unsigned 15-bit intermediate array.
assert(conv_params->round_0 >= 5);
/* Horizontal filter */
{
const int16_t *x_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_x, subpel_x_q4 & SUBPEL_MASK);
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)x_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const = _mm_set1_epi32(
((1 << conv_params->round_0) >> 1) + (1 << (bd + FILTER_BITS - 1)));
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_0);
for (i = 0; i < im_h; ++i) {
for (j = 0; j < w; j += 8) {
const __m128i data =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j]);
const __m128i data2 =
_mm_loadu_si128((__m128i *)&src_ptr[i * src_stride + j + 8]);
// Filter even-index pixels
const __m128i res_0 = _mm_madd_epi16(data, coeff_01);
const __m128i res_2 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 4), coeff_23);
const __m128i res_4 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 8), coeff_45);
const __m128i res_6 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 12), coeff_67);
__m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_4),
_mm_add_epi32(res_2, res_6));
res_even =
_mm_sra_epi32(_mm_add_epi32(res_even, round_const), round_shift);
// Filter odd-index pixels
const __m128i res_1 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 2), coeff_01);
const __m128i res_3 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 6), coeff_23);
const __m128i res_5 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 10), coeff_45);
const __m128i res_7 =
_mm_madd_epi16(_mm_alignr_epi8(data2, data, 14), coeff_67);
__m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_5),
_mm_add_epi32(res_3, res_7));
res_odd =
_mm_sra_epi32(_mm_add_epi32(res_odd, round_const), round_shift);
// Pack in the column order 0, 2, 4, 6, 1, 3, 5, 7
__m128i res = _mm_packs_epi32(res_even, res_odd);
_mm_storeu_si128((__m128i *)&im_block[i * im_stride + j], res);
}
}
}
/* Vertical filter */
{
const int16_t *y_filter = av1_get_interp_filter_subpel_kernel(
*filter_params_y, subpel_y_q4 & SUBPEL_MASK);
const __m128i coeffs_y = _mm_loadu_si128((__m128i *)y_filter);
// coeffs 0 1 0 1 2 3 2 3
const __m128i tmp_0 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
// coeffs 4 5 4 5 6 7 6 7
const __m128i tmp_1 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
// coeffs 0 1 0 1 0 1 0 1
const __m128i coeff_01 = _mm_unpacklo_epi64(tmp_0, tmp_0);
// coeffs 2 3 2 3 2 3 2 3
const __m128i coeff_23 = _mm_unpackhi_epi64(tmp_0, tmp_0);
// coeffs 4 5 4 5 4 5 4 5
const __m128i coeff_45 = _mm_unpacklo_epi64(tmp_1, tmp_1);
// coeffs 6 7 6 7 6 7 6 7
const __m128i coeff_67 = _mm_unpackhi_epi64(tmp_1, tmp_1);
const __m128i round_const = _mm_set1_epi32(
((1 << conv_params->round_1) >> 1) -
(1 << (bd + 2 * FILTER_BITS - conv_params->round_0 - 1)));
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_1);
for (i = 0; i < h; ++i) {
for (j = 0; j < w; j += 8) {
// Filter even-index pixels
const int16_t *data = &im_block[i * im_stride + j];
const __m128i src_0 =
_mm_unpacklo_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_2 =
_mm_unpacklo_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_4 =
_mm_unpacklo_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_6 =
_mm_unpacklo_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_0 = _mm_madd_epi16(src_0, coeff_01);
const __m128i res_2 = _mm_madd_epi16(src_2, coeff_23);
const __m128i res_4 = _mm_madd_epi16(src_4, coeff_45);
const __m128i res_6 = _mm_madd_epi16(src_6, coeff_67);
const __m128i res_even = _mm_add_epi32(_mm_add_epi32(res_0, res_2),
_mm_add_epi32(res_4, res_6));
// Filter odd-index pixels
const __m128i src_1 =
_mm_unpackhi_epi16(*(__m128i *)(data + 0 * im_stride),
*(__m128i *)(data + 1 * im_stride));
const __m128i src_3 =
_mm_unpackhi_epi16(*(__m128i *)(data + 2 * im_stride),
*(__m128i *)(data + 3 * im_stride));
const __m128i src_5 =
_mm_unpackhi_epi16(*(__m128i *)(data + 4 * im_stride),
*(__m128i *)(data + 5 * im_stride));
const __m128i src_7 =
_mm_unpackhi_epi16(*(__m128i *)(data + 6 * im_stride),
*(__m128i *)(data + 7 * im_stride));
const __m128i res_1 = _mm_madd_epi16(src_1, coeff_01);
const __m128i res_3 = _mm_madd_epi16(src_3, coeff_23);
const __m128i res_5 = _mm_madd_epi16(src_5, coeff_45);
const __m128i res_7 = _mm_madd_epi16(src_7, coeff_67);
const __m128i res_odd = _mm_add_epi32(_mm_add_epi32(res_1, res_3),
_mm_add_epi32(res_5, res_7));
// Rearrange pixels back into the order 0 ... 7
const __m128i res_lo = _mm_unpacklo_epi32(res_even, res_odd);
const __m128i res_hi = _mm_unpackhi_epi32(res_even, res_odd);
const __m128i res_lo_round =
_mm_sra_epi32(_mm_add_epi32(res_lo, round_const), round_shift);
const __m128i res_hi_round =
_mm_sra_epi32(_mm_add_epi32(res_hi, round_const), round_shift);
// Accumulate values into the destination buffer
__m128i *const p = (__m128i *)&dst[i * dst_stride + j];
_mm_storeu_si128(p, _mm_add_epi32(_mm_loadu_si128(p), res_lo_round));
_mm_storeu_si128(p + 1,
_mm_add_epi32(_mm_loadu_si128(p + 1), res_hi_round));
}
}
}
}
#endif

View file

@ -19,8 +19,9 @@ void av1_highbd_warp_affine_ssse3(const int32_t *mat, const uint16_t *ref,
uint16_t *pred, int p_col, int p_row,
int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int bd,
int comp_avg, int16_t alpha, int16_t beta,
int16_t gamma, int16_t delta) {
ConvolveParams *conv_params, int16_t alpha,
int16_t beta, int16_t gamma, int16_t delta) {
int comp_avg = conv_params->do_average;
#if HORSHEAR_REDUCE_PREC_BITS >= 5
__m128i tmp[15];
#else

View file

@ -364,8 +364,9 @@ static void iidtx16(__m256i *in) {
#endif
void av1_iht16x16_256_add_avx2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m256i in[16];
int tx_type = txfm_param->tx_type;
load_buffer_16x16(input, in);
switch (tx_type) {

View file

@ -59,10 +59,11 @@ static INLINE void fliplr_16x8(__m128i *in /*in[16]*/) {
#endif
void av1_iht4x4_16_add_sse2(const tran_low_t *input, uint8_t *dest, int stride,
int tx_type) {
const TxfmParam *txfm_param) {
__m128i in[2];
const __m128i zero = _mm_setzero_si128();
const __m128i eight = _mm_set1_epi16(8);
int tx_type = txfm_param->tx_type;
in[0] = load_input_data(input);
in[1] = load_input_data(input + 8);
@ -150,10 +151,11 @@ void av1_iht4x4_16_add_sse2(const tran_low_t *input, uint8_t *dest, int stride,
}
void av1_iht8x8_64_add_sse2(const tran_low_t *input, uint8_t *dest, int stride,
int tx_type) {
const TxfmParam *txfm_param) {
__m128i in[8];
const __m128i zero = _mm_setzero_si128();
const __m128i final_rounding = _mm_set1_epi16(1 << 4);
int tx_type = txfm_param->tx_type;
// load input data
in[0] = load_input_data(input);
@ -251,10 +253,11 @@ static void iidtx16_sse2(__m128i *in0, __m128i *in1) {
#endif // CONFIG_EXT_TX
void av1_iht16x16_256_add_sse2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m128i in[32];
__m128i *in0 = &in[0];
__m128i *in1 = &in[16];
int tx_type = txfm_param->tx_type;
load_buffer_8x16(input, in0);
input += 8;
@ -388,8 +391,9 @@ static INLINE void flip_buffer_lr_8x8(__m128i *in) {
#endif // CONFIG_EXT_TX
void av1_iht8x16_128_add_sse2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m128i in[16];
int tx_type = txfm_param->tx_type;
in[0] = load_input_data(input + 0 * 8);
in[1] = load_input_data(input + 1 * 8);
@ -553,8 +557,9 @@ static INLINE void write_buffer_8x8_round6(uint8_t *dest, __m128i *in,
}
void av1_iht16x8_128_add_sse2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m128i in[16];
int tx_type = txfm_param->tx_type;
// Transpose 16x8 input into in[]
in[0] = load_input_data(input + 0 * 16);
@ -713,8 +718,9 @@ static INLINE void write_buffer_8x4_round5(uint8_t *dest, __m128i *in,
}
void av1_iht8x4_32_add_sse2(const tran_low_t *input, uint8_t *dest, int stride,
int tx_type) {
const TxfmParam *txfm_param) {
__m128i in[8];
int tx_type = txfm_param->tx_type;
in[0] = load_input_data(input + 0 * 8);
in[1] = load_input_data(input + 1 * 8);
@ -897,8 +903,9 @@ static INLINE void write_buffer_4x8_round5(uint8_t *dest, __m128i *in,
}
void av1_iht4x8_32_add_sse2(const tran_low_t *input, uint8_t *dest, int stride,
int tx_type) {
const TxfmParam *txfm_param) {
__m128i in[8];
int tx_type = txfm_param->tx_type;
// Load rows, packed two per element of 'in'.
// We pack into the bottom half of 'in' so that the
@ -1119,8 +1126,9 @@ static INLINE void write_buffer_16x32_round6(uint8_t *dest, __m128i *intl,
}
void av1_iht16x32_512_add_sse2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m128i intl[16], intr[16], inbl[16], inbr[16];
int tx_type = txfm_param->tx_type;
int i;
for (i = 0; i < 16; ++i) {
@ -1272,8 +1280,9 @@ static INLINE void write_buffer_32x16_round6(uint8_t *dest, __m128i *in0,
}
void av1_iht32x16_512_add_sse2(const tran_low_t *input, uint8_t *dest,
int stride, int tx_type) {
int stride, const TxfmParam *txfm_param) {
__m128i in0[16], in1[16], in2[16], in3[16];
int tx_type = txfm_param->tx_type;
int i;
for (i = 0; i < 16; ++i) {

View file

@ -16,8 +16,8 @@ static void calc_block(__m128i sum, __m128i sum_sq, __m128i n,
if (bit_depth > 8) {
__m128i rounding_a = _mm_set1_epi32((1 << (2 * (bit_depth - 8))) >> 1);
__m128i rounding_b = _mm_set1_epi32((1 << (bit_depth - 8)) >> 1);
__m128i shift_a = _mm_set_epi64x(0, 2 * (bit_depth - 8));
__m128i shift_b = _mm_set_epi64x(0, bit_depth - 8);
__m128i shift_a = _mm_cvtsi32_si128(2 * (bit_depth - 8));
__m128i shift_b = _mm_cvtsi32_si128(bit_depth - 8);
a = _mm_srl_epi32(_mm_add_epi32(sum_sq, rounding_a), shift_a);
b = _mm_srl_epi32(_mm_add_epi32(sum, rounding_b), shift_b);
a = _mm_mullo_epi32(a, n);

View file

@ -17,9 +17,10 @@
void av1_warp_affine_sse2(const int32_t *mat, const uint8_t *ref, int width,
int height, int stride, uint8_t *pred, int p_col,
int p_row, int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int comp_avg,
int16_t alpha, int16_t beta, int16_t gamma,
int16_t delta) {
int subsampling_x, int subsampling_y,
ConvolveParams *conv_params, int16_t alpha,
int16_t beta, int16_t gamma, int16_t delta) {
int comp_avg = conv_params->do_average;
__m128i tmp[15];
int i, j, k;
const int bd = 8;

View file

@ -204,9 +204,10 @@ static const uint8_t odd_mask[16] = { 1, 3, 3, 5, 5, 7, 7, 9,
void av1_warp_affine_ssse3(const int32_t *mat, const uint8_t *ref, int width,
int height, int stride, uint8_t *pred, int p_col,
int p_row, int p_width, int p_height, int p_stride,
int subsampling_x, int subsampling_y, int comp_avg,
int16_t alpha, int16_t beta, int16_t gamma,
int16_t delta) {
int subsampling_x, int subsampling_y,
ConvolveParams *conv_params, int16_t alpha,
int16_t beta, int16_t gamma, int16_t delta) {
int comp_avg = conv_params->do_average;
__m128i tmp[15];
int i, j, k;
const int bd = 8;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,8 @@ void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
int supertx_enabled,
#endif
#if CONFIG_TXK_SEL
int block, int plane,
int blk_row, int blk_col, int block, int plane,
TX_SIZE tx_size,
#endif
aom_reader *r);

View file

@ -50,8 +50,6 @@ static void initialize_dec(void) {
av1_init_wedge_masks();
#endif // CONFIG_EXT_INTER
init_done = 1;
av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv,
av1_intra_mode_tree);
av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
av1_switchable_interp_tree);
#if CONFIG_EXT_TX
@ -65,8 +63,6 @@ static void initialize_dec(void) {
#else
av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, av1_ext_tx_tree);
#endif
av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv,
av1_inter_mode_tree);
}
}
@ -236,7 +232,12 @@ aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm,
// cpi->lst3_fb_idx = 2;
// cpi->gld_fb_idx = 3;
// cpi->bwd_fb_idx = 4;
// #if CONFIG_ALTREF2
// cpi->alt2_fb_idx = 5;
// cpi->alt_fb_idx = 6;
// #else // !CONFIG_ALTREF2
// cpi->alt_fb_idx = 5;
// #endif // CONFIG_ALTREF2
// #else // CONFIG_EXT_REFS
// cpi->gld_fb_idx = 1;
// cpi->alt_fb_idx = 2;
@ -255,9 +256,16 @@ aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm,
idx = cm->ref_frame_map[3];
} else if (ref_frame_flag == AOM_BWD_FLAG) {
idx = cm->ref_frame_map[4];
#if CONFIG_ALTREF2
} else if (ref_frame_flag == AOM_ALT2_FLAG) {
idx = cm->ref_frame_map[5];
} else if (ref_frame_flag == AOM_ALT_FLAG) {
idx = cm->ref_frame_map[6];
#else // !CONFIG_ALTREF2
} else if (ref_frame_flag == AOM_ALT_FLAG) {
idx = cm->ref_frame_map[5];
#else
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
} else if (ref_frame_flag == AOM_GOLD_FLAG) {
idx = cm->ref_frame_map[1];
} else if (ref_frame_flag == AOM_ALT_FLAG) {
@ -446,7 +454,10 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size,
// border.
if (pbi->dec_tile_row == -1 && pbi->dec_tile_col == -1)
#endif // CONFIG_EXT_TILE
aom_extend_frame_inner_borders(cm->frame_to_show);
// TODO(debargha): Fix encoder side mv range, so that we can use the
// inner border extension. As of now use the larger extension.
// aom_extend_frame_inner_borders(cm->frame_to_show);
aom_extend_frame_borders(cm->frame_to_show);
aom_clear_system_state();
@ -500,7 +511,6 @@ int av1_get_raw_frame(AV1Decoder *pbi, YV12_BUFFER_CONFIG *sd) {
/* no raw frame to show!!! */
if (!cm->show_frame) return ret;
pbi->ready_for_new_data = 1;
*sd = *cm->frame_to_show;
ret = 0;
aom_clear_system_state();
@ -518,6 +528,7 @@ int av1_get_frame_to_show(AV1Decoder *pbi, YV12_BUFFER_CONFIG *frame) {
aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
uint32_t sizes[8], int *count,
int *index_size,
aom_decrypt_cb decrypt_cb,
void *decrypt_state) {
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
@ -530,13 +541,14 @@ aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
size_t frame_sz_sum = 0;
assert(data_sz);
marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1);
marker = read_marker(decrypt_cb, decrypt_state, data);
*count = 0;
if ((marker & 0xe0) == 0xc0) {
const uint32_t frames = (marker & 0x7) + 1;
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
const size_t index_sz = 2 + mag * (frames - 1);
*index_size = (int)index_sz;
// This chunk is marked as having a superframe index but doesn't have
// enough data for it, thus it's an invalid superframe index.
@ -544,7 +556,7 @@ aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
{
const uint8_t marker2 =
read_marker(decrypt_cb, decrypt_state, data + data_sz - index_sz);
read_marker(decrypt_cb, decrypt_state, data + index_sz - 1);
// This chunk is marked as having a superframe index but doesn't have
// the matching marker byte at the front of the index therefore it's an
@ -555,7 +567,7 @@ aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
{
// Found a valid superframe index.
uint32_t i, j;
const uint8_t *x = &data[data_sz - index_sz + 1];
const uint8_t *x = &data[1];
// Frames has a maximum of 8 and mag has a maximum of 4.
uint8_t clear_buffer[28];

View file

@ -53,9 +53,7 @@ typedef struct TileData {
#if CONFIG_CFL
CFL_CTX cfl;
#endif
#if CONFIG_EC_ADAPT
DECLARE_ALIGNED(16, FRAME_CONTEXT, tctx);
#endif
#if CONFIG_PALETTE
DECLARE_ALIGNED(16, uint8_t, color_index_map[2][MAX_SB_SQUARE]);
#endif // CONFIG_PALETTE
@ -75,9 +73,7 @@ typedef struct TileWorkerData {
#if CONFIG_CFL
CFL_CTX cfl;
#endif
#if CONFIG_EC_ADAPT
FRAME_CONTEXT tctx;
#endif
#if CONFIG_PALETTE
DECLARE_ALIGNED(16, uint8_t, color_index_map[2][MAX_SB_SQUARE]);
#endif // CONFIG_PALETTE
@ -122,6 +118,7 @@ typedef struct AV1Decoder {
aom_decrypt_cb decrypt_cb;
void *decrypt_state;
int allow_lowbitdepth;
int max_threads;
int inv_tile_order;
int need_resync; // wait for key/intra-only frame.
@ -130,19 +127,17 @@ typedef struct AV1Decoder {
int tile_size_bytes;
#if CONFIG_EXT_TILE
int tile_col_size_bytes;
int dec_tile_row, dec_tile_col;
#endif // CONFIG_EXT_TILE
int dec_tile_row, dec_tile_col; // always -1 for non-VR tile encoding
#endif // CONFIG_EXT_TILE
#if CONFIG_ACCOUNTING
int acct_enabled;
Accounting accounting;
#endif
size_t uncomp_hdr_size; // Size of the uncompressed header
size_t first_partition_size; // Size of the compressed header
#if CONFIG_TILE_GROUPS
int tg_size; // Number of tiles in the current tilegroup
int tg_start; // First tile in the current tilegroup
int tg_size; // Number of tiles in the current tilegroup
int tg_start; // First tile in the current tilegroup
int tg_size_bit_offset;
#endif
#if CONFIG_REFERENCE_BUFFER
SequenceHeader seq_params;
#endif
@ -181,6 +176,7 @@ static INLINE uint8_t read_marker(aom_decrypt_cb decrypt_cb,
// "read_marker".
aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
uint32_t sizes[8], int *count,
int *index_size,
aom_decrypt_cb decrypt_cb,
void *decrypt_state);
@ -217,6 +213,20 @@ static INLINE int dec_is_ref_frame_buf(AV1Decoder *const pbi,
}
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
#define ACCT_STR __func__
static INLINE int av1_read_uniform(aom_reader *r, int n) {
const int l = get_unsigned_bits(n);
const int m = (1 << l) - n;
const int v = aom_read_literal(r, l - 1, ACCT_STR);
assert(l != 0);
if (v < m)
return v;
else
return (v << 1) - m + aom_read_literal(r, 1, ACCT_STR);
}
#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -42,14 +42,14 @@ static int read_golomb(MACROBLOCKD *xd, aom_reader *r) {
}
uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
aom_reader *r, int block, int plane,
tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
int16_t *max_scan_line, int *eob) {
aom_reader *r, int blk_row, int blk_col, int block,
int plane, tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
TX_SIZE tx_size, int16_t *max_scan_line, int *eob) {
FRAME_COUNTS *counts = xd->counts;
TX_SIZE tx_size = get_tx_size(plane, xd);
TX_SIZE txs_ctx = get_txsize_context(tx_size);
PLANE_TYPE plane_type = get_plane_type(plane);
aom_prob *nz_map = cm->fc->nz_map[tx_size][plane_type];
aom_prob *eob_flag = cm->fc->eob_flag[tx_size][plane_type];
aom_prob *nz_map = cm->fc->nz_map[txs_ctx][plane_type];
aom_prob *eob_flag = cm->fc->eob_flag[txs_ctx][plane_type];
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const int seg_eob = tx_size_2d[tx_size];
int c = 0;
@ -57,40 +57,47 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
const int16_t *const dequant = xd->plane[plane].seg_dequant[mbmi->segment_id];
const int shift = av1_get_tx_scale(tx_size);
const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2;
const int height = tx_size_high[tx_size];
int cul_level = 0;
unsigned int(*nz_map_count)[SIG_COEF_CONTEXTS][2];
uint8_t txb_mask[32 * 32] = { 0 };
nz_map_count = (counts) ? &counts->nz_map[tx_size][plane_type] : NULL;
nz_map_count = (counts) ? &counts->nz_map[txs_ctx][plane_type] : NULL;
memset(tcoeffs, 0, sizeof(*tcoeffs) * seg_eob);
int all_zero =
aom_read(r, cm->fc->txb_skip[tx_size][txb_ctx->txb_skip_ctx], ACCT_STR);
aom_read(r, cm->fc->txb_skip[txs_ctx][txb_ctx->txb_skip_ctx], ACCT_STR);
if (xd->counts)
++xd->counts->txb_skip[tx_size][txb_ctx->txb_skip_ctx][all_zero];
++xd->counts->txb_skip[txs_ctx][txb_ctx->txb_skip_ctx][all_zero];
*eob = 0;
if (all_zero) {
*max_scan_line = 0;
#if CONFIG_TXK_SEL
if (plane == 0) mbmi->txk_type[(blk_row << 4) + blk_col] = DCT_DCT;
#endif
return 0;
}
(void)blk_row;
(void)blk_col;
#if CONFIG_TXK_SEL
av1_read_tx_type(cm, xd, block, plane, r);
av1_read_tx_type(cm, xd, blk_row, blk_col, block, plane,
get_min_tx_size(tx_size), r);
#endif
TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
const SCAN_ORDER *const scan_order =
get_scan(cm, tx_size, tx_type, is_inter_block(mbmi));
const TX_TYPE tx_type =
av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
const int16_t *scan = scan_order->scan;
const int16_t *iscan = scan_order->iscan;
for (c = 0; c < seg_eob; ++c) {
int is_nz;
int coeff_ctx = get_nz_map_ctx(tcoeffs, txb_mask, scan[c], bwl);
int eob_ctx = get_eob_ctx(tcoeffs, scan[c], bwl);
int coeff_ctx = get_nz_map_ctx(tcoeffs, scan[c], bwl, height, iscan);
int eob_ctx = get_eob_ctx(tcoeffs, scan[c], txs_ctx);
if (c < seg_eob - 1)
is_nz = aom_read(r, nz_map[coeff_ctx], tx_size);
is_nz = aom_read(r, nz_map[coeff_ctx], ACCT_STR);
else
is_nz = 1;
@ -105,11 +112,10 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
if (counts) ++(*nz_map_count)[coeff_ctx][is_nz];
if (is_nz) {
int is_eob = aom_read(r, eob_flag[eob_ctx], tx_size);
if (counts) ++counts->eob_flag[tx_size][plane_type][eob_ctx][is_eob];
int is_eob = aom_read(r, eob_flag[eob_ctx], ACCT_STR);
if (counts) ++counts->eob_flag[txs_ctx][plane_type][eob_ctx][is_eob];
if (is_eob) break;
}
txb_mask[scan[c]] = 1;
}
*eob = AOMMIN(seg_eob, c + 1);
@ -117,7 +123,7 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
int i;
for (i = 0; i < NUM_BASE_LEVELS; ++i) {
aom_prob *coeff_base = cm->fc->coeff_base[tx_size][plane_type][i];
aom_prob *coeff_base = cm->fc->coeff_base[txs_ctx][plane_type][i];
update_eob = 0;
for (c = *eob - 1; c >= 0; --c) {
@ -127,17 +133,18 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
if (*v <= i) continue;
ctx = get_base_ctx(tcoeffs, scan[c], bwl, i + 1);
ctx = get_base_ctx(tcoeffs, scan[c], bwl, height, i + 1);
if (aom_read(r, coeff_base[ctx], tx_size)) {
if (aom_read(r, coeff_base[ctx], ACCT_STR)) {
*v = i + 1;
cul_level += i + 1;
if (counts) ++counts->coeff_base[tx_size][plane_type][i][ctx][1];
if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][1];
if (c == 0) {
int dc_sign_ctx = txb_ctx->dc_sign_ctx;
sign = aom_read(r, cm->fc->dc_sign[plane_type][dc_sign_ctx], tx_size);
sign =
aom_read(r, cm->fc->dc_sign[plane_type][dc_sign_ctx], ACCT_STR);
if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][sign];
} else {
sign = aom_read_bit(r, ACCT_STR);
@ -146,7 +153,7 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
continue;
}
*v = i + 2;
if (counts) ++counts->coeff_base[tx_size][plane_type][i][ctx][0];
if (counts) ++counts->coeff_base[txs_ctx][plane_type][i][ctx][0];
// update the eob flag for coefficients with magnitude above 1.
update_eob = AOMMAX(update_eob, c);
@ -163,26 +170,26 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
if (c == 0) {
int dc_sign_ctx = txb_ctx->dc_sign_ctx;
sign = aom_read(r, cm->fc->dc_sign[plane_type][dc_sign_ctx], tx_size);
sign = aom_read(r, cm->fc->dc_sign[plane_type][dc_sign_ctx], ACCT_STR);
if (counts) ++counts->dc_sign[plane_type][dc_sign_ctx][sign];
} else {
sign = aom_read_bit(r, ACCT_STR);
}
ctx = get_br_ctx(tcoeffs, scan[c], bwl);
ctx = get_br_ctx(tcoeffs, scan[c], bwl, height);
if (cm->fc->coeff_lps[tx_size][plane_type][ctx] == 0) exit(0);
if (cm->fc->coeff_lps[txs_ctx][plane_type][ctx] == 0) exit(0);
for (idx = 0; idx < COEFF_BASE_RANGE; ++idx) {
if (aom_read(r, cm->fc->coeff_lps[tx_size][plane_type][ctx], tx_size)) {
if (aom_read(r, cm->fc->coeff_lps[txs_ctx][plane_type][ctx], ACCT_STR)) {
*v = (idx + 1 + NUM_BASE_LEVELS);
if (sign) *v = -(*v);
cul_level += abs(*v);
if (counts) ++counts->coeff_lps[tx_size][plane_type][ctx][1];
if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][1];
break;
}
if (counts) ++counts->coeff_lps[tx_size][plane_type][ctx][0];
if (counts) ++counts->coeff_lps[txs_ctx][plane_type][ctx][0];
}
if (idx < COEFF_BASE_RANGE) continue;
@ -211,32 +218,31 @@ uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
uint8_t av1_read_coeffs_txb_facade(AV1_COMMON *cm, MACROBLOCKD *xd,
aom_reader *r, int row, int col, int block,
int plane, tran_low_t *tcoeffs,
int16_t *max_scan_line, int *eob) {
TX_SIZE tx_size, int16_t *max_scan_line,
int *eob) {
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
struct macroblockd_plane *pd = &xd->plane[plane];
const BLOCK_SIZE bsize = mbmi->sb_type;
#if CONFIG_CB4X4
#if CONFIG_CHROMA_2X2
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#else
#if CONFIG_CHROMA_SUB8X8
const BLOCK_SIZE plane_bsize =
AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
#endif // CONFIG_CHROMA_2X2
#elif CONFIG_CB4X4
const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#else // CONFIG_CB4X4
const BLOCK_SIZE plane_bsize =
get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
#endif // CONFIG_CB4X4
TX_SIZE tx_size = get_tx_size(plane, xd);
TXB_CTX txb_ctx;
get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + col,
pd->left_context + row, &txb_ctx);
uint8_t cul_level = av1_read_coeffs_txb(cm, xd, r, block, plane, tcoeffs,
&txb_ctx, max_scan_line, eob);
uint8_t cul_level =
av1_read_coeffs_txb(cm, xd, r, row, col, block, plane, tcoeffs, &txb_ctx,
tx_size, max_scan_line, eob);
#if CONFIG_ADAPT_SCAN
PLANE_TYPE plane_type = get_plane_type(plane);
TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, block, tx_size);
if (xd->counts && *eob > 0)
av1_update_scan_count_facade(cm, xd->counts, tx_size, tx_type, pd->dqcoeff,
*eob);

View file

@ -19,13 +19,14 @@
#include "aom_dsp/bitreader.h"
uint8_t av1_read_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
aom_reader *r, int block, int plane,
tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
int16_t *max_scan_line, int *eob);
aom_reader *r, int blk_row, int blk_col, int block,
int plane, tran_low_t *tcoeffs, TXB_CTX *txb_ctx,
TX_SIZE tx_size, int16_t *max_scan_line, int *eob);
uint8_t av1_read_coeffs_txb_facade(AV1_COMMON *cm, MACROBLOCKD *xd,
aom_reader *r, int row, int col, int block,
int plane, tran_low_t *tcoeffs,
int16_t *max_scan_line, int *eob);
TX_SIZE tx_size, int16_t *max_scan_line,
int *eob);
void av1_read_txb_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, aom_reader *r);
#endif // DECODETXB_H_

View file

@ -16,6 +16,7 @@
#endif // !CONFIG_PVQ
#include "av1/common/blockd.h"
#include "av1/decoder/detokenize.h"
#define ACCT_STR __func__
@ -23,7 +24,6 @@
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/idct.h"
#include "av1/decoder/detokenize.h"
#define EOB_CONTEXT_NODE 0
#define ZERO_CONTEXT_NODE 1
@ -110,16 +110,13 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
#endif // CONFIG_AOM_QM
int ctx, const int16_t *scan, const int16_t *nb,
int16_t *max_scan_line, aom_reader *r) {
FRAME_COUNTS *counts = xd->counts;
#if CONFIG_EC_ADAPT
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#else
FRAME_CONTEXT *const ec_ctx = xd->fc;
#endif
const int max_eob = tx_size_2d[tx_size];
const int ref = is_inter_block(&xd->mi[0]->mbmi);
#if CONFIG_AOM_QM
const qm_val_t *iqmatrix = iqm[!ref][tx_size];
#else
(void)tx_type;
#endif // CONFIG_AOM_QM
int band, c = 0;
const int tx_size_ctx = txsize_sqr_map[tx_size];
@ -129,11 +126,6 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
ec_ctx->coef_tail_cdfs[tx_size_ctx][type][ref];
int val = 0;
#if !CONFIG_EC_ADAPT
unsigned int *blockz_count;
unsigned int(*coef_counts)[COEFF_CONTEXTS][UNCONSTRAINED_NODES + 1] = NULL;
unsigned int(*eob_branch_count)[COEFF_CONTEXTS] = NULL;
#endif
uint8_t token_cache[MAX_TX_SQUARE];
const uint8_t *band_translate = get_band_translate(tx_size);
int dq_shift;
@ -142,15 +134,6 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
#if CONFIG_NEW_QUANT
const tran_low_t *dqv_val = &dq_val[0][0];
#endif // CONFIG_NEW_QUANT
(void)tx_type;
if (counts) {
#if !CONFIG_EC_ADAPT
coef_counts = counts->coef[tx_size_ctx][type][ref];
eob_branch_count = counts->eob_branch[tx_size_ctx][type][ref];
blockz_count = counts->blockz_count[tx_size_ctx][type][ref][ctx];
#endif
}
dq_shift = av1_get_tx_scale(tx_size);
@ -171,9 +154,6 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
HEAD_TOKENS + first_pos, ACCT_STR) +
!first_pos;
if (first_pos) {
#if !CONFIG_EC_ADAPT
if (counts) ++blockz_count[comb_token != 0];
#endif
if (comb_token == 0) return 0;
}
token = comb_token >> 1;
@ -181,11 +161,6 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
while (!token) {
*max_scan_line = AOMMAX(*max_scan_line, scan[c]);
token_cache[scan[c]] = 0;
#if !CONFIG_EC_ADAPT
if (counts && !last_pos) {
++coef_counts[band][ctx][ZERO_TOKEN];
}
#endif
++c;
dqv = dq[1];
ctx = get_coef_context(nb, token_cache, c);
@ -201,13 +176,6 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
}
more_data = comb_token & 1;
#if !CONFIG_EC_ADAPT
if (counts && !last_pos) {
++coef_counts[band][ctx][token];
++eob_branch_count[band][ctx];
if (!more_data) ++coef_counts[band][ctx][EOB_MODEL_TOKEN];
}
#endif
if (token > ONE_TOKEN)
token +=
@ -226,16 +194,15 @@ static int decode_coefs(MACROBLOCKD *xd, PLANE_TYPE type, tran_low_t *dqcoeff,
v = dq_shift ? ROUND_POWER_OF_TWO(v, dq_shift) : v;
#else
#if CONFIG_AOM_QM
dqv = ((iqmatrix[scan[c]] * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >>
AOM_QM_BITS;
// Apply quant matrix only for 2D transforms
if (IS_2D_TRANSFORM(tx_type))
dqv = ((iqmatrix[scan[c]] * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >>
AOM_QM_BITS;
#endif
v = (val * dqv) >> dq_shift;
#endif
v = aom_read_bit(r, ACCT_STR) ? -v : v;
#if CONFIG_COEFFICIENT_RANGE_CHECKING
check_range(v, xd->bd);
#endif // CONFIG_COEFFICIENT_RANGE_CHECKING
v = (int)check_range(aom_read_bit(r, ACCT_STR) ? -v : v, xd->bd);
dqcoeff[scan[c]] = v;
@ -258,46 +225,47 @@ void av1_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
const MB_MODE_INFO *const mbmi = &mi->mbmi;
uint8_t color_order[PALETTE_MAX_SIZE];
const int n = mbmi->palette_mode_info.palette_size[plane];
int i, j;
uint8_t *const color_map = xd->plane[plane].color_index_map;
const aom_prob(
*const prob)[PALETTE_COLOR_INDEX_CONTEXTS][PALETTE_COLORS - 1] =
plane ? av1_default_palette_uv_color_index_prob
: av1_default_palette_y_color_index_prob;
aom_cdf_prob(
*palette_cdf)[PALETTE_COLOR_INDEX_CONTEXTS][CDF_SIZE(PALETTE_COLORS)] =
plane ? xd->tile_ctx->palette_uv_color_index_cdf
: xd->tile_ctx->palette_y_color_index_cdf;
int plane_block_width, plane_block_height, rows, cols;
av1_get_block_dimensions(mbmi->sb_type, plane, xd, &plane_block_width,
&plane_block_height, &rows, &cols);
assert(plane == 0 || plane == 1);
// The first color index.
color_map[0] = av1_read_uniform(r, n);
assert(color_map[0] < n);
#if CONFIG_PALETTE_THROUGHPUT
// Run wavefront on the palette map index decoding.
for (i = 1; i < rows + cols - 1; ++i) {
for (j = AOMMIN(i, cols - 1); j >= AOMMAX(0, i - rows + 1); --j) {
for (int i = 1; i < rows + cols - 1; ++i) {
for (int j = AOMMIN(i, cols - 1); j >= AOMMAX(0, i - rows + 1); --j) {
const int color_ctx = av1_get_palette_color_index_context(
color_map, plane_block_width, (i - j), j, n, color_order, NULL);
const int color_idx =
aom_read_tree(r, av1_palette_color_index_tree[n - 2],
prob[n - 2][color_ctx], ACCT_STR);
const int color_idx = aom_read_symbol(
r, palette_cdf[n - PALETTE_MIN_SIZE][color_ctx], n, ACCT_STR);
assert(color_idx >= 0 && color_idx < n);
color_map[(i - j) * plane_block_width + j] = color_order[color_idx];
}
}
// Copy last column to extra columns.
if (cols < plane_block_width) {
for (i = 0; i < plane_block_height; ++i) {
for (int i = 0; i < plane_block_height; ++i) {
memset(color_map + i * plane_block_width + cols,
color_map[i * plane_block_width + cols - 1],
(plane_block_width - cols));
}
}
#else
for (i = 0; i < rows; ++i) {
for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
for (int i = 0; i < rows; ++i) {
for (int j = (i == 0 ? 1 : 0); j < cols; ++j) {
const int color_ctx = av1_get_palette_color_index_context(
color_map, plane_block_width, i, j, n, color_order, NULL);
const int color_idx =
aom_read_tree(r, av1_palette_color_index_tree[n - PALETTE_MIN_SIZE],
prob[n - PALETTE_MIN_SIZE][color_ctx], ACCT_STR);
const int color_idx = aom_read_symbol(
r, palette_cdf[n - PALETTE_MIN_SIZE][color_ctx], n, ACCT_STR);
assert(color_idx >= 0 && color_idx < n);
color_map[i * plane_block_width + j] = color_order[color_idx];
}
@ -307,7 +275,7 @@ void av1_decode_palette_tokens(MACROBLOCKD *const xd, int plane,
}
#endif // CONFIG_PALETTE_THROUGHPUT
// Copy last row to extra rows.
for (i = rows; i < plane_block_height; ++i) {
for (int i = rows; i < plane_block_height; ++i) {
memcpy(color_map + i * plane_block_width,
color_map + (rows - 1) * plane_block_width, plane_block_width);
}

View file

@ -14,9 +14,9 @@
#include "./aom_config.h"
#if !CONFIG_PVQ || CONFIG_VAR_TX
#include "av1/decoder/decoder.h"
#include "av1/common/scan.h"
#endif // !CONFIG_PVQ
#endif // !CONFIG_PVQ || CONFIG_VAR_TX
#include "av1/decoder/decoder.h"
#ifdef __cplusplus
extern "C" {

View file

@ -78,7 +78,7 @@ int ifd_inspect(insp_frame_data *fd, void *decoder) {
if (mi->mode < INTRA_MODES) {
mi->uv_mode = mbmi->uv_mode;
} else {
mi->uv_mode = INTRA_INVALID;
mi->uv_mode = UV_MODE_INVALID;
}
// Block Size
mi->sb_type = mbmi->sb_type;
@ -101,7 +101,7 @@ int ifd_inspect(insp_frame_data *fd, void *decoder) {
mi->cdef_strength += mi->cdef_strength == 3;
#endif
#if CONFIG_CFL
if (mbmi->uv_mode == DC_PRED) {
if (mbmi->uv_mode == UV_DC_PRED) {
mi->cfl_alpha_idx = mbmi->cfl_alpha_idx;
mi->cfl_alpha_sign = (mbmi->cfl_alpha_signs[CFL_PRED_V] << CFL_PRED_V) +
mbmi->cfl_alpha_signs[CFL_PRED_U];

View file

@ -352,10 +352,7 @@ void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) {
// For video conference clips, if the background has high motion in current
// frame because of the camera movement, set this frame as the golden frame.
// Use 70% and 5% as the thresholds for golden frame refreshing.
// Also, force this frame as a golden update frame if this frame will change
// the resolution (av1_resize_pending != 0).
if (av1_resize_pending(cpi) ||
(cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1)) {
if (cnt1 * 10 > (70 * rows * cols) && cnt2 * 20 < cnt1) {
av1_cyclic_refresh_set_golden_update(cpi);
rc->frames_till_gf_update_due = rc->baseline_gf_interval;

View file

@ -845,7 +845,6 @@ void av1_quantize_dc_nuq_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
}
#endif // CONFIG_NEW_QUANT
#if CONFIG_HIGHBITDEPTH
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,
@ -899,14 +898,29 @@ void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
switch (qparam->log_scale) {
case 0:
aom_highbd_quantize_b(coeff_ptr, n_coeffs, skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff_ptr, dqcoeff_ptr,
pd->dequant, eob_ptr, sc->scan, sc->iscan
if (LIKELY(n_coeffs >= 8)) {
aom_highbd_quantize_b(coeff_ptr, n_coeffs, skip_block, p->zbin,
p->round, p->quant, p->quant_shift, qcoeff_ptr,
dqcoeff_ptr, pd->dequant, eob_ptr, sc->scan,
sc->iscan
#if CONFIG_AOM_QM
,
qm_ptr, iqm_ptr
,
qm_ptr, iqm_ptr
#endif
);
);
} else {
// TODO(luoyi): Need SIMD (e.g. sse2) for smaller block size
// quantization
aom_highbd_quantize_b_c(coeff_ptr, n_coeffs, skip_block, p->zbin,
p->round, p->quant, p->quant_shift, qcoeff_ptr,
dqcoeff_ptr, pd->dequant, eob_ptr, sc->scan,
sc->iscan
#if CONFIG_AOM_QM
,
qm_ptr, iqm_ptr
#endif
);
}
break;
case 1:
aom_highbd_quantize_b_32x32(coeff_ptr, n_coeffs, skip_block, p->zbin,
@ -936,7 +950,6 @@ void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
}
}
#if CONFIG_HIGHBITDEPTH
static INLINE void highbd_quantize_dc(
const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
@ -958,14 +971,13 @@ static INLINE void highbd_quantize_dc(
const int coeff_sign = (coeff >> 31);
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
const int64_t tmp = abs_coeff + round_ptr[0];
const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> (16 - log_scale));
const int abs_qcoeff = (int)((tmp * quant) >> (16 - log_scale));
qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / (1 << log_scale);
if (abs_qcoeff) eob = 0;
}
*eob_ptr = eob + 1;
}
#endif // CONFIG_HIGHBITDEPTH
void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
@ -1504,9 +1516,7 @@ void av1_highbd_quantize_dc_nuq_facade(
}
}
#endif // CONFIG_NEW_QUANT
#endif // CONFIG_HIGHBITDEPTH
#if CONFIG_HIGHBITDEPTH
void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
int skip_block, const int16_t *zbin_ptr,
const int16_t *round_ptr,
@ -1547,15 +1557,14 @@ void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
#endif
const int coeff_sign = (coeff >> 31);
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
const int64_t tmp = abs_coeff + round_ptr[rc != 0];
const int64_t tmp = abs_coeff + (round_ptr[rc != 0] >> log_scale);
#if CONFIG_AOM_QM
const uint32_t abs_qcoeff =
(uint32_t)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
const int abs_qcoeff =
(int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / scale;
#else
const uint32_t abs_qcoeff =
(uint32_t)((tmp * quant_ptr[rc != 0]) >> shift);
const int abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> shift);
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / scale;
#endif
@ -1565,8 +1574,6 @@ void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
*eob_ptr = eob + 1;
}
#endif // CONFIG_HIGHBITDEPTH
static void invert_quant(int16_t *quant, int16_t *shift, int d) {
uint32_t t;
int l, m;

Some files were not shown because too many files have changed in this diff Show more