mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-09 16:57:30 +09:00
update libaom to rev 5bdd95475e07ac8641114cb139105b8d734a1b60 (without moz.build and aom_ports/aom_once.h)
This commit is contained in:
parent
402c27b560
commit
fb515ea77b
177 changed files with 21088 additions and 11681 deletions
5
third_party/aom/CMakeLists.txt
vendored
5
third_party/aom/CMakeLists.txt
vendored
|
|
@ -293,8 +293,11 @@ if(CONFIG_AV1_DECODER AND ENABLE_EXAMPLES)
|
|||
|
||||
if(EMSCRIPTEN)
|
||||
add_preproc_definition(_POSIX_SOURCE)
|
||||
append_link_flag_to_target("inspect" "-s TOTAL_MEMORY=402653184")
|
||||
append_link_flag_to_target("inspect" "--emrun")
|
||||
append_link_flag_to_target("inspect" "-s USE_PTHREADS=0")
|
||||
append_link_flag_to_target("inspect" "-s WASM=1")
|
||||
append_link_flag_to_target("inspect" "-s MODULARIZE=1")
|
||||
append_link_flag_to_target("inspect" "-s ALLOW_MEMORY_GROWTH=1")
|
||||
append_link_flag_to_target(
|
||||
"inspect" "-s \'EXTRA_EXPORTED_RUNTIME_METHODS=[\"UTF8ToString\"]\'")
|
||||
append_link_flag_to_target("inspect"
|
||||
|
|
|
|||
8
third_party/aom/aom/aom_encoder.h
vendored
8
third_party/aom/aom/aom_encoder.h
vendored
|
|
@ -406,8 +406,7 @@ typedef struct aom_codec_enc_cfg {
|
|||
* upscaling after the encode/decode process. Taking control of upscaling and
|
||||
* using restoration filters should allow it to outperform normal resizing.
|
||||
*
|
||||
* Mode 0 is SUPERRES_NONE, mode 1 is SUPERRES_FIXED, mode 2 is
|
||||
* SUPERRES_RANDOM and mode 3 is SUPERRES_QTHRESH.
|
||||
* Valid values are 0 to 4 as defined in enum SUPERRES_MODE.
|
||||
*/
|
||||
unsigned int rc_superres_mode;
|
||||
|
||||
|
|
@ -862,6 +861,11 @@ aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx,
|
|||
*/
|
||||
aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx);
|
||||
|
||||
/*!\brief usage parameter analogous to AV1 GOOD QUALITY mode. */
|
||||
#define AOM_USAGE_GOOD_QUALITY (0)
|
||||
/*!\brief usage parameter analogous to AV1 REALTIME mode. */
|
||||
#define AOM_USAGE_REALTIME (1)
|
||||
|
||||
/*!\brief Encode a frame
|
||||
*
|
||||
* Encodes a video frame at the given "presentation time." The presentation
|
||||
|
|
|
|||
248
third_party/aom/aom/aomcx.h
vendored
248
third_party/aom/aom/aomcx.h
vendored
|
|
@ -512,16 +512,25 @@ enum aome_enc_control_id {
|
|||
*/
|
||||
AV1E_SET_RENDER_SIZE,
|
||||
|
||||
/*!\brief Codec control function to set target level.
|
||||
*
|
||||
* 255: off (default); 0: only keep level stats; 10: target for level 1.0;
|
||||
* 11: target for level 1.1; ... 62: target for level 6.2
|
||||
/*!\brief Control to set target sequence level index for a certain operating
|
||||
* point(OP).
|
||||
* Possible values are in the form of "ABxy"(pad leading zeros if less than
|
||||
* 4 digits).
|
||||
* AB: OP index.
|
||||
* xy: Target level index for the OP. Can be values 0~23(corresponding to
|
||||
* level 2.0 ~ 7.3) or 31(maximum level parameter, no level-based
|
||||
* constraints).
|
||||
* E.g. "0" means target level index 0 for the 0th OP;
|
||||
* "111" means target level index 11 for the 1st OP;
|
||||
* "1021" means target level index 21 for the 10th OP.
|
||||
* If the target level is not specified for an OP, the maximum level parameter
|
||||
* of 31 is used as default.
|
||||
*/
|
||||
AV1E_SET_TARGET_LEVEL,
|
||||
AV1E_SET_TARGET_SEQ_LEVEL_IDX,
|
||||
|
||||
/*!\brief Codec control function to get bitstream level.
|
||||
/*!\brief Codec control function to get sequence level index.
|
||||
*/
|
||||
AV1E_GET_LEVEL,
|
||||
AV1E_GET_SEQ_LEVEL_IDX,
|
||||
|
||||
/*!\brief Codec control function to set intended superblock size.
|
||||
*
|
||||
|
|
@ -575,8 +584,9 @@ enum aome_enc_control_id {
|
|||
*
|
||||
* 0 = apply trellis quantization
|
||||
* 1 = do not apply trellis quantization
|
||||
* 2 = disable trellis quantization partially
|
||||
*
|
||||
* By default, the encoder applies trellis optimization on quantized
|
||||
* By default, the encoder applies optimization on quantized
|
||||
* coefficients.
|
||||
*
|
||||
*/
|
||||
|
|
@ -718,6 +728,43 @@ enum aome_enc_control_id {
|
|||
*/
|
||||
AV1E_SET_ENABLE_RECT_PARTITIONS,
|
||||
|
||||
/*!\brief Codec control function to enable/disable AB partitions.
|
||||
*
|
||||
* This will enable or disable usage of AB partitions. The default
|
||||
* value is 1.
|
||||
*
|
||||
*/
|
||||
AV1E_SET_ENABLE_AB_PARTITIONS,
|
||||
|
||||
/*!\brief Codec control function to enable/disable 1:4 and 4:1 partitions.
|
||||
*
|
||||
* This will enable or disable usage of 1:4 and 4:1 partitions. The default
|
||||
* value is 1.
|
||||
*
|
||||
*/
|
||||
AV1E_SET_ENABLE_1TO4_PARTITIONS,
|
||||
|
||||
/*!\brief Codec control function to set min partition size.
|
||||
*
|
||||
* This will set min partition size. The default value is 4 for 4x4.
|
||||
* valid values are [4, 8, 16, 32, 64, 128]
|
||||
* min_partition_size is applied to both width and height of the partition.
|
||||
* i.e, both width and height of a partition can not be smaller than
|
||||
* the min_partition_size, except the partition at the picture boundary.
|
||||
*
|
||||
*/
|
||||
AV1E_SET_MIN_PARTITION_SIZE,
|
||||
|
||||
/*!\brief Codec control function to set max partition size.
|
||||
*
|
||||
* This will set max partition size. The default value is 128 for 128x128.
|
||||
* valid values are [4, 8, 16, 32, 64, 128]
|
||||
* max_partition_size is applied to both width and height of the partition.
|
||||
* i.e, both width and height of a partition can not be larger than
|
||||
* the max_partition_size.
|
||||
*/
|
||||
AV1E_SET_MAX_PARTITION_SIZE,
|
||||
|
||||
/*!\brief Codec control function to turn on / off intra edge filter
|
||||
* at sequence level.
|
||||
*
|
||||
|
|
@ -747,6 +794,25 @@ enum aome_enc_control_id {
|
|||
*/
|
||||
AV1E_SET_ENABLE_TX64,
|
||||
|
||||
/*!\brief Codec control function to turn on / off flip and identity
|
||||
* transforms.
|
||||
*
|
||||
* This will enable or disable usage of flip and identity transform
|
||||
* types in any direction. The default value is 1. Including:
|
||||
* FLIPADST_DCT, DCT_FLIPADST, FLIPADST_FLIPADST, ADST_FLIPADST,
|
||||
* FLIPADST_ADST, IDTX, V_DCT, H_DCT, V_ADST, H_ADST, V_FLIPADST,
|
||||
* H_FLIPADST
|
||||
*/
|
||||
AV1E_SET_ENABLE_FLIP_IDTX,
|
||||
|
||||
/*!\brief Codec control function to set transform block size search method.
|
||||
*
|
||||
* This will set the transform block size search method.
|
||||
* 0: use Full RD search, 1: use Fast RD search, 2: always use largest
|
||||
* allowed transform block size based on partition size.
|
||||
*/
|
||||
AV1E_SET_TX_SIZE_SEARCH_METHOD,
|
||||
|
||||
/*!\brief Codec control function to turn on / off dist-wtd compound mode
|
||||
* at sequence level.
|
||||
*
|
||||
|
|
@ -793,6 +859,15 @@ enum aome_enc_control_id {
|
|||
*/
|
||||
AV1E_SET_ENABLE_MASKED_COMP,
|
||||
|
||||
/*!\brief Codec control function to turn on / off one sided compound usage
|
||||
* for a sequence.
|
||||
*
|
||||
* This will enable or disable usage of one sided compound
|
||||
* modes. The default value is 1.
|
||||
*
|
||||
*/
|
||||
AV1E_SET_ENABLE_ONESIDED_COMP,
|
||||
|
||||
/*!\brief Codec control function to turn on / off interintra compound
|
||||
* for a sequence.
|
||||
*
|
||||
|
|
@ -979,16 +1054,44 @@ enum aome_enc_control_id {
|
|||
/*!\brief Control to use dct only for inter modes */
|
||||
AV1E_SET_INTER_DCT_ONLY,
|
||||
|
||||
/*!\brief Control to use default tx type only for intra modes */
|
||||
AV1E_SET_INTRA_DEFAULT_TX_ONLY,
|
||||
|
||||
/*!\brief Control to use adaptive quantize_b */
|
||||
AV1E_SET_QUANT_B_ADAPT,
|
||||
|
||||
/*!\brief Control to select maximum height for the GF group pyramid structure
|
||||
* (valid values: 1 - 4) */
|
||||
* (valid values: 0 - 4) */
|
||||
AV1E_SET_GF_MAX_PYRAMID_HEIGHT,
|
||||
|
||||
/*!\brief Control to select maximum reference frames allowed per frame
|
||||
* (valid values: 3 - 7) */
|
||||
AV1E_SET_MAX_REFERENCE_FRAMES,
|
||||
|
||||
/*!\brief Control to use reduced set of single and compound references. */
|
||||
AV1E_SET_REDUCED_REFERENCE_SET,
|
||||
|
||||
/*!\brief Control to set frequency of the cost updates for coefficients
|
||||
* Possible values are:
|
||||
* 0: Update at SB level (default)
|
||||
* 1: Update at SB row level in tile
|
||||
* 2: Update at tile level
|
||||
*/
|
||||
AV1E_SET_COEFF_COST_UPD_FREQ,
|
||||
|
||||
/*!\brief Control to set frequency of the cost updates for mode
|
||||
* Possible values are:
|
||||
* 0: Update at SB level (default)
|
||||
* 1: Update at SB row level in tile
|
||||
* 2: Update at tile level
|
||||
*/
|
||||
AV1E_SET_MODE_COST_UPD_FREQ,
|
||||
|
||||
/*!\brief Control to set bit mask that specifies which tier each of the 32
|
||||
* possible operating points conforms to.
|
||||
* Bit value 0: Main Tier; 1: High Tier.
|
||||
*/
|
||||
AV1E_SET_TIER_MASK,
|
||||
};
|
||||
|
||||
/*!\brief aom 1-D scaling mode
|
||||
|
|
@ -1095,13 +1198,11 @@ AOM_CTRL_USE_TYPE(AOME_SET_ACTIVEMAP, aom_active_map_t *)
|
|||
AOM_CTRL_USE_TYPE(AOME_SET_SCALEMODE, aom_scaling_mode_t *)
|
||||
#define AOM_CTRL_AOME_SET_SCALEMODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_SPATIAL_LAYER_ID, int)
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_SPATIAL_LAYER_ID, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_SPATIAL_LAYER_ID
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_CPUUSED, int)
|
||||
#define AOM_CTRL_AOME_SET_CPUUSED
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_DEVSF, int)
|
||||
#define AOM_CTRL_AOME_SET_DEVSF
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ENABLEAUTOALTREF, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ENABLEAUTOALTREF
|
||||
|
||||
|
|
@ -1122,12 +1223,12 @@ AOM_CTRL_USE_TYPE(AOME_SET_TUNING, int) /* aom_tune_metric */
|
|||
AOM_CTRL_USE_TYPE(AOME_SET_CQ_LEVEL, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_CQ_LEVEL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ROW_MT, int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ROW_MT, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_ROW_MT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_COLUMNS, int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_COLUMNS, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TILE_COLUMNS
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TILE_ROWS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_TPL_MODEL, unsigned int)
|
||||
|
|
@ -1193,88 +1294,109 @@ AOM_CTRL_USE_TYPE(AV1E_SET_MTU, unsigned int)
|
|||
AOM_CTRL_USE_TYPE(AV1E_SET_TIMING_INFO_TYPE, int) /* aom_timing_info_type_t */
|
||||
#define AOM_CTRL_AV1E_SET_TIMING_INFO_TYPE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_RECT_PARTITIONS, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_RECT_PARTITIONS, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_RECT_PARTITIONS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_AB_PARTITIONS, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_AB_PARTITIONS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_1TO4_PARTITIONS, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_1TO4_PARTITIONS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MIN_PARTITION_SIZE, int)
|
||||
#define AOM_CTRL_AV1E_SET_MIN_PARTITION_SIZE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MAX_PARTITION_SIZE, int)
|
||||
#define AOM_CTRL_AV1E_SET_MAX_PARTITION_SIZE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_INTRA_EDGE_FILTER
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ORDER_HINT, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ORDER_HINT, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_ORDER_HINT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_TX64, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_TX64, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_TX64
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIST_WTD_COMP, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TX_SIZE_SEARCH_METHOD, int)
|
||||
#define AOM_CTRL_AV1E_SET_TXSIZE_SEARCH_METHOD
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_FLIP_IDTX, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_FLIP_IDTX
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIST_WTD_COMP, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_DIST_WTD_COMP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_REF_FRAME_MVS, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_REF_FRAME_MVS, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_REF_FRAME_MVS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_REF_FRAME_MVS, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_REF_FRAME_MVS, int)
|
||||
#define AOM_CTRL_AV1E_SET_ALLOW_REF_FRAME_MVS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DUAL_FILTER, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DUAL_FILTER, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_DUAL_FILTER
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_MASKED_COMP, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_MASKED_COMP, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_MASKED_COMP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_COMP, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ONESIDED_COMP, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_ONESIDED_COMP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_COMP, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTRA_COMP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_SMOOTH_INTERINTRA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIFF_WTD_COMP, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIFF_WTD_COMP, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_DIFF_WTD_COMP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTER_WEDGE, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTER_WEDGE, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTER_WEDGE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_WEDGE, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_WEDGE, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTRA_WEDGE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_GLOBAL_MOTION, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_GLOBAL_MOTION, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_WARPED_MOTION, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_WARPED_MOTION, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_WARPED_MOTION
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_WARPED_MOTION, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_WARPED_MOTION, int)
|
||||
#define AOM_CTRL_AV1E_SET_ALLOW_WARPED_MOTION
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_FILTER_INTRA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_FILTER_INTRA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_FILTER_INTRA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTRA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTRA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_SMOOTH_INTRA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PAETH_INTRA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PAETH_INTRA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_PAETH_INTRA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_CFL_INTRA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_CFL_INTRA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_CFL_INTRA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SUPERRES, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SUPERRES, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_SUPERRES
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PALETTE, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PALETTE, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_PALETTE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRABC, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRABC, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_INTRABC
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ANGLE_DELTA, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ANGLE_DELTA, int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_ANGLE_DELTA
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FRAME_PARALLEL_DECODING, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_FRAME_PARALLEL_DECODING
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ERROR_RESILIENT_MODE, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ERROR_RESILIENT_MODE, int)
|
||||
#define AOM_CTRL_AV1E_SET_ERROR_RESILIENT_MODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_S_FRAME_MODE, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_S_FRAME_MODE, int)
|
||||
#define AOM_CTRL_AV1E_SET_S_FRAME_MODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_AQ_MODE, unsigned int)
|
||||
|
|
@ -1322,14 +1444,8 @@ AOM_CTRL_USE_TYPE(AV1E_SET_RENDER_SIZE, int *)
|
|||
AOM_CTRL_USE_TYPE(AV1E_SET_SUPERBLOCK_SIZE, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_SUPERBLOCK_SIZE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TARGET_LEVEL, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TARGET_LEVEL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_GET_LEVEL, int *)
|
||||
#define AOM_CTRL_AV1E_GET_LEVEL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ANS_WINDOW_SIZE_LOG2, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_ANS_WINDOW_SIZE_LOG2
|
||||
AOM_CTRL_USE_TYPE(AV1E_GET_SEQ_LEVEL_IDX, int *)
|
||||
#define AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_SINGLE_TILE_DECODING, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_SINGLE_TILE_DECODING
|
||||
|
|
@ -1337,13 +1453,13 @@ AOM_CTRL_USE_TYPE(AV1E_SET_SINGLE_TILE_DECODING, unsigned int)
|
|||
AOM_CTRL_USE_TYPE(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
|
||||
#define AOM_CTRL_AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TEST_VECTOR, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TEST_VECTOR, int)
|
||||
#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TEST_VECTOR
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TABLE, const char *)
|
||||
#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TABLE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_CDF_UPDATE_MODE, int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_CDF_UPDATE_MODE, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_CDF_UPDATE_MODE
|
||||
|
||||
#ifdef CONFIG_DENOISE
|
||||
|
|
@ -1360,24 +1476,42 @@ AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_X, unsigned int)
|
|||
AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_Y, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_CHROMA_SUBSAMPLING_Y
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_REDUCED_TX_TYPE_SET, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_REDUCED_TX_TYPE_SET, int)
|
||||
#define AOM_CTRL_AV1E_SET_REDUCED_TX_TYPE_SET
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_INTRA_DCT_ONLY, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_INTRA_DCT_ONLY, int)
|
||||
#define AOM_CTRL_AV1E_SET_INTRA_DCT_ONLY
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_INTER_DCT_ONLY, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_INTER_DCT_ONLY, int)
|
||||
#define AOM_CTRL_AV1E_SET_INTER_DCT_ONLY
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_QUANT_B_ADAPT, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_INTRA_DEFAULT_TX_ONLY, int)
|
||||
#define AOM_CTRL_AV1E_SET_INTRA_DEFAULT_TX_ONLY
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_QUANT_B_ADAPT, int)
|
||||
#define AOM_CTRL_AV1E_SET_QUANT_B_ADAPT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_GF_MAX_PYRAMID_HEIGHT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MAX_REFERENCE_FRAMES, unsigned int)
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MAX_REFERENCE_FRAMES, int)
|
||||
#define AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_REDUCED_REFERENCE_SET, int)
|
||||
#define AOM_CTRL_AV1E_SET_REDUCED_REFERENCE_SET
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_COEFF_COST_UPD_FREQ, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_COEFF_COST_UPD_FREQ
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MODE_COST_UPD_FREQ, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_MODE_COST_UPD_FREQ
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TARGET_SEQ_LEVEL_IDX, int)
|
||||
#define AOM_CTRL_AV1E_SET_TARGET_SEQ_LEVEL_IDX
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TIER_MASK, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TIER_MASK
|
||||
|
||||
/*!\endcond */
|
||||
/*! @} - end defgroup aom_encoder */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
3
third_party/aom/aom_dsp/aom_dsp.cmake
vendored
3
third_party/aom/aom_dsp/aom_dsp.cmake
vendored
|
|
@ -194,6 +194,7 @@ if(CONFIG_AV1_ENCODER)
|
|||
"${AOM_ROOT}/aom_dsp/x86/highbd_subtract_sse2.c"
|
||||
"${AOM_ROOT}/aom_dsp/x86/highbd_variance_sse2.c"
|
||||
"${AOM_ROOT}/aom_dsp/x86/quantize_sse2.c"
|
||||
"${AOM_ROOT}/aom_dsp/x86/adaptive_quantize_sse2.c"
|
||||
"${AOM_ROOT}/aom_dsp/x86/quantize_x86.h"
|
||||
"${AOM_ROOT}/aom_dsp/x86/sum_squares_sse2.c"
|
||||
"${AOM_ROOT}/aom_dsp/x86/variance_sse2.c")
|
||||
|
|
@ -362,6 +363,8 @@ function(setup_aom_dsp_targets)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_dsp>)
|
||||
|
||||
# Pass the new lib targets up to the parent scope instance of
|
||||
# $AOM_LIB_TARGETS.
|
||||
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)
|
||||
|
|
|
|||
59
third_party/aom/aom_dsp/aom_dsp_rtcd_defs.pl
vendored
59
third_party/aom/aom_dsp/aom_dsp_rtcd_defs.pl
vendored
|
|
@ -518,9 +518,15 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
add_proto qw/void aom_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_quantize_b sse2/, "$ssse3_x86_64", "$avx_x86_64";
|
||||
|
||||
add_proto qw/void aom_quantize_b_adaptive/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_quantize_b_adaptive sse2/;
|
||||
|
||||
add_proto qw/void aom_quantize_b_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_quantize_b_32x32/, "$ssse3_x86_64", "$avx_x86_64";
|
||||
|
||||
add_proto qw/void aom_quantize_b_32x32_adaptive/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_quantize_b_32x32_adaptive sse2/;
|
||||
|
||||
add_proto qw/void aom_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_quantize_b_64x64 ssse3/;
|
||||
} # CONFIG_AV1_ENCODER
|
||||
|
|
@ -533,7 +539,7 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
specialize qw/aom_highbd_quantize_b_32x32 sse2/;
|
||||
|
||||
add_proto qw/void aom_highbd_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/aom_highbd_quantize_b_64x64 sse2/;
|
||||
} # CONFIG_AV1_ENCODER
|
||||
|
||||
#
|
||||
|
|
@ -835,6 +841,30 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
specialize qw/aom_highbd_sad16x64x4d sse2/;
|
||||
specialize qw/aom_highbd_sad64x16x4d sse2/;
|
||||
|
||||
#
|
||||
# Avg
|
||||
#
|
||||
add_proto qw/unsigned int aom_avg_8x8/, "const uint8_t *, int p";
|
||||
specialize qw/aom_avg_8x8 sse2/;
|
||||
|
||||
add_proto qw/unsigned int aom_avg_4x4/, "const uint8_t *, int p";
|
||||
specialize qw/aom_avg_4x4 sse2/;
|
||||
|
||||
add_proto qw/void aom_minmax_8x8/, "const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max";
|
||||
specialize qw/aom_minmax_8x8 sse2/;
|
||||
|
||||
add_proto qw/void aom_int_pro_row/, "int16_t *hbuf, const uint8_t *ref, const int ref_stride, const int height";
|
||||
# TODO(kyslov@) bring back SSE2 by extending it to 128 block size
|
||||
#specialize qw/aom_int_pro_row sse2/;
|
||||
|
||||
add_proto qw/int16_t aom_int_pro_col/, "const uint8_t *ref, const int width";
|
||||
# TODO(kyslov@) bring back SSE2 by extending it to 128 block size
|
||||
#specialize qw/aom_int_pro_col sse2/;
|
||||
|
||||
add_proto qw/int aom_vector_var/, "const int16_t *ref, const int16_t *src, const int bwl";
|
||||
# TODO(kyslov@) bring back SSE2 by extending it to 128 block size
|
||||
#specialize qw/aom_vector_var sse2/;
|
||||
|
||||
#
|
||||
# hamadard transform and satd for implmenting temporal dependency model
|
||||
#
|
||||
|
|
@ -1358,6 +1388,15 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
#
|
||||
# Subpixel Variance
|
||||
#
|
||||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance128x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_12_sub_pixel_variance128x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance128x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_12_sub_pixel_variance128x64 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance64x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_12_sub_pixel_variance64x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance64x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_12_sub_pixel_variance64x64 sse2/;
|
||||
|
||||
|
|
@ -1394,6 +1433,15 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance4x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
add_proto qw/uint32_t aom_highbd_12_sub_pixel_variance4x4/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance128x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_10_sub_pixel_variance128x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance128x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_10_sub_pixel_variance128x64 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance64x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_10_sub_pixel_variance64x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance64x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_10_sub_pixel_variance64x64 sse2/;
|
||||
|
||||
|
|
@ -1430,6 +1478,15 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance4x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
add_proto qw/uint32_t aom_highbd_10_sub_pixel_variance4x4/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_8_sub_pixel_variance128x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_8_sub_pixel_variance128x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_8_sub_pixel_variance128x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_8_sub_pixel_variance128x64 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_8_sub_pixel_variance64x128/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_8_sub_pixel_variance64x128 sse2/;
|
||||
|
||||
add_proto qw/uint32_t aom_highbd_8_sub_pixel_variance64x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse";
|
||||
specialize qw/aom_highbd_8_sub_pixel_variance64x64 sse2/;
|
||||
|
||||
|
|
|
|||
79
third_party/aom/aom_dsp/avg.c
vendored
79
third_party/aom/aom_dsp/avg.c
vendored
|
|
@ -14,6 +14,40 @@
|
|||
#include "config/aom_dsp_rtcd.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
void aom_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp,
|
||||
int *min, int *max) {
|
||||
int i, j;
|
||||
*min = 255;
|
||||
*max = 0;
|
||||
for (i = 0; i < 8; ++i, s += p, d += dp) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
int diff = abs(s[j] - d[j]);
|
||||
*min = diff < *min ? diff : *min;
|
||||
*max = diff > *max ? diff : *max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int aom_avg_4x4_c(const uint8_t *s, int p) {
|
||||
int i, j;
|
||||
int sum = 0;
|
||||
for (i = 0; i < 4; ++i, s += p)
|
||||
for (j = 0; j < 4; sum += s[j], ++j) {
|
||||
}
|
||||
|
||||
return (sum + 8) >> 4;
|
||||
}
|
||||
|
||||
unsigned int aom_avg_8x8_c(const uint8_t *s, int p) {
|
||||
int i, j;
|
||||
int sum = 0;
|
||||
for (i = 0; i < 8; ++i, s += p)
|
||||
for (j = 0; j < 8; sum += s[j], ++j) {
|
||||
}
|
||||
|
||||
return (sum + 32) >> 6;
|
||||
}
|
||||
|
||||
// src_diff: first pass, 9 bit, dynamic range [-255, 255]
|
||||
// second pass, 12 bit, dynamic range [-2040, 2040]
|
||||
static void hadamard_col8(const int16_t *src_diff, ptrdiff_t src_stride,
|
||||
|
|
@ -146,3 +180,48 @@ int aom_satd_c(const tran_low_t *coeff, int length) {
|
|||
// satd: 26 bits, dynamic range [-32640 * 1024, 32640 * 1024]
|
||||
return satd;
|
||||
}
|
||||
|
||||
// Integer projection onto row vectors.
|
||||
// height: value range {16, 32, 64, 128}.
|
||||
void aom_int_pro_row_c(int16_t hbuf[16], const uint8_t *ref,
|
||||
const int ref_stride, const int height) {
|
||||
int idx;
|
||||
const int norm_factor = height >> 1;
|
||||
for (idx = 0; idx < 16; ++idx) {
|
||||
int i;
|
||||
hbuf[idx] = 0;
|
||||
// hbuf[idx]: 14 bit, dynamic range [0, 32640].
|
||||
for (i = 0; i < height; ++i) hbuf[idx] += ref[i * ref_stride];
|
||||
// hbuf[idx]: 9 bit, dynamic range [0, 1020].
|
||||
hbuf[idx] /= norm_factor;
|
||||
++ref;
|
||||
}
|
||||
}
|
||||
|
||||
// width: value range {16, 32, 64, 128}.
|
||||
int16_t aom_int_pro_col_c(const uint8_t *ref, const int width) {
|
||||
int idx;
|
||||
int16_t sum = 0;
|
||||
// sum: 14 bit, dynamic range [0, 32640]
|
||||
for (idx = 0; idx < width; ++idx) sum += ref[idx];
|
||||
return sum;
|
||||
}
|
||||
|
||||
// ref: [0 - 510]
|
||||
// src: [0 - 510]
|
||||
// bwl: {2, 3, 4, 5}
|
||||
int aom_vector_var_c(const int16_t *ref, const int16_t *src, const int bwl) {
|
||||
int i;
|
||||
int width = 4 << bwl;
|
||||
int sse = 0, mean = 0, var;
|
||||
|
||||
for (i = 0; i < width; ++i) {
|
||||
int diff = ref[i] - src[i]; // diff: dynamic range [-510, 510], 10 bits.
|
||||
mean += diff; // mean: dynamic range 16 bits.
|
||||
sse += diff * diff; // sse: dynamic range 26 bits.
|
||||
}
|
||||
|
||||
// (mean * mean): dynamic range 31 bits.
|
||||
var = sse - ((mean * mean) >> (bwl + 2));
|
||||
return var;
|
||||
}
|
||||
|
|
|
|||
4
third_party/aom/aom_dsp/bitreader_buffer.c
vendored
4
third_party/aom/aom_dsp/bitreader_buffer.c
vendored
|
|
@ -60,9 +60,9 @@ int aom_rb_read_inv_signed_literal(struct aom_read_bit_buffer *rb, int bits) {
|
|||
|
||||
uint32_t aom_rb_read_uvlc(struct aom_read_bit_buffer *rb) {
|
||||
int leading_zeros = 0;
|
||||
while (!aom_rb_read_bit(rb)) ++leading_zeros;
|
||||
while (leading_zeros < 32 && !aom_rb_read_bit(rb)) ++leading_zeros;
|
||||
// Maximum 32 bits.
|
||||
if (leading_zeros >= 32) return UINT32_MAX;
|
||||
if (leading_zeros == 32) return UINT32_MAX;
|
||||
const uint32_t base = (1u << leading_zeros) - 1;
|
||||
const uint32_t value = aom_rb_read_literal(rb, leading_zeros);
|
||||
return base + value;
|
||||
|
|
|
|||
3
third_party/aom/aom_dsp/grain_synthesis.c
vendored
3
third_party/aom/aom_dsp/grain_synthesis.c
vendored
|
|
@ -232,7 +232,6 @@ static int scaling_lut_y[256];
|
|||
static int scaling_lut_cb[256];
|
||||
static int scaling_lut_cr[256];
|
||||
|
||||
static int grain_center;
|
||||
static int grain_min;
|
||||
static int grain_max;
|
||||
|
||||
|
|
@ -1077,7 +1076,7 @@ int av1_add_film_grain_run(const aom_film_grain_t *params, uint8_t *luma,
|
|||
int overlap = params->overlap_flag;
|
||||
int bit_depth = params->bit_depth;
|
||||
|
||||
grain_center = 128 << (bit_depth - 8);
|
||||
const int grain_center = 128 << (bit_depth - 8);
|
||||
grain_min = 0 - grain_center;
|
||||
grain_max = (256 << (bit_depth - 8)) - 1 - grain_center;
|
||||
|
||||
|
|
|
|||
78
third_party/aom/aom_dsp/quantize.c
vendored
78
third_party/aom/aom_dsp/quantize.c
vendored
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "aom_dsp/quantize.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
#include "av1/encoder/av1_quantize.h"
|
||||
|
||||
void quantize_b_adaptive_helper_c(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
|
||||
|
|
@ -28,15 +29,18 @@ void quantize_b_adaptive_helper_c(
|
|||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
int prescan_add[2];
|
||||
for (i = 0; i < 2; ++i)
|
||||
prescan_add[i] = ROUND_POWER_OF_TWO(dequant_ptr[i] * EOB_FACTOR, 7);
|
||||
|
||||
// Pre-scan pass
|
||||
for (i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
|
||||
int prescan_add = ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * 325, 7);
|
||||
if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add) &&
|
||||
coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add))
|
||||
const int prescan_add_val = prescan_add[rc != 0];
|
||||
if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val) &&
|
||||
coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add_val))
|
||||
non_zero_count--;
|
||||
else
|
||||
break;
|
||||
|
|
@ -44,6 +48,9 @@ void quantize_b_adaptive_helper_c(
|
|||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
int first = -1;
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
for (i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
|
@ -68,9 +75,32 @@ void quantize_b_adaptive_helper_c(
|
|||
const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
|
||||
dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
|
||||
|
||||
if (tmp32) eob = i;
|
||||
if (tmp32) {
|
||||
eob = i;
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
if (first == -1) first = i;
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
}
|
||||
}
|
||||
}
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
if (eob >= 0 && first == eob) {
|
||||
const int rc = scan[eob];
|
||||
if (qcoeff_ptr[rc] == 1 || qcoeff_ptr[rc] == -1) {
|
||||
const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int factor = EOB_FACTOR + SKIP_EOB_FACTOR_ADJUST;
|
||||
const int prescan_add_val =
|
||||
ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * factor, 7);
|
||||
if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val) &&
|
||||
coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add_val)) {
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
eob = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +185,10 @@ void highbd_quantize_b_adaptive_helper_c(
|
|||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
int prescan_add[2];
|
||||
for (i = 0; i < 2; ++i)
|
||||
prescan_add[i] = ROUND_POWER_OF_TWO(dequant_ptr[i] * EOB_FACTOR, 7);
|
||||
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
const int rc = scan[i];
|
||||
|
|
@ -163,14 +197,17 @@ void highbd_quantize_b_adaptive_helper_c(
|
|||
|
||||
// If the coefficient is out of the base ZBIN range, keep it for
|
||||
// quantization.
|
||||
int prescan_add = ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * 325, 7);
|
||||
if (coeff >= (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add) &&
|
||||
coeff <= (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add))
|
||||
const int prescan_add_val = prescan_add[rc != 0];
|
||||
if (coeff >= (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val) &&
|
||||
coeff <= (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add_val))
|
||||
idx_arr[idx++] = i;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
int first = -1;
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = scan[idx_arr[i]];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
|
@ -189,8 +226,31 @@ void highbd_quantize_b_adaptive_helper_c(
|
|||
(dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
|
||||
const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
|
||||
dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
|
||||
if (abs_qcoeff) eob = idx_arr[i];
|
||||
if (abs_qcoeff) {
|
||||
eob = idx_arr[i];
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
if (first == -1) first = eob;
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
}
|
||||
}
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
if (eob >= 0 && first == eob) {
|
||||
const int rc = scan[eob];
|
||||
if (qcoeff_ptr[rc] == 1 || qcoeff_ptr[rc] == -1) {
|
||||
const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int factor = EOB_FACTOR + SKIP_EOB_FACTOR_ADJUST;
|
||||
const int prescan_add_val =
|
||||
ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * factor, 7);
|
||||
if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val) &&
|
||||
coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS) - prescan_add_val)) {
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
eob = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SKIP_EOB_FACTOR_ADJUST
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
421
third_party/aom/aom_dsp/x86/adaptive_quantize_sse2.c
vendored
Normal file
421
third_party/aom/aom_dsp/x86/adaptive_quantize_sse2.c
vendored
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <emmintrin.h>
|
||||
#include "config/aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "av1/encoder/av1_quantize.h"
|
||||
#include "aom_dsp/x86/quantize_x86.h"
|
||||
|
||||
void aom_quantize_b_adaptive_sse2(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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 __m128i zero = _mm_setzero_si128();
|
||||
int index = 16;
|
||||
int non_zero_count = (int)n_coeffs;
|
||||
__m128i zbin, round, quant, dequant, shift;
|
||||
__m128i coeff0, coeff1, coeff0_sign, coeff1_sign;
|
||||
__m128i qcoeff0, qcoeff1;
|
||||
__m128i cmp_mask0, cmp_mask1;
|
||||
__m128i eob = zero, eob0, prescan0, prescan1, all_zero;
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 0),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], 0) };
|
||||
|
||||
int prescan_add[2];
|
||||
for (int i = 0; i < 2; ++i)
|
||||
prescan_add[i] = ROUND_POWER_OF_TWO(dequant_ptr[i] * EOB_FACTOR, 7);
|
||||
|
||||
// max buffer is of size 256 as this functions calls with
|
||||
// maximum n_coeffs as 256
|
||||
int16_t prescan[256];
|
||||
memset(prescan, -1, n_coeffs * sizeof(int16_t));
|
||||
|
||||
// TODO(Aniket): Experiment the following loop with intrinsic
|
||||
for (int i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = 1 << AOM_QM_BITS;
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int prescan_add_val = prescan_add[rc != 0];
|
||||
if (abs_coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val)) {
|
||||
prescan[rc] = 0;
|
||||
non_zero_count--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
int first = -1;
|
||||
#endif
|
||||
// Setup global values.
|
||||
load_b_values(zbin_ptr, &zbin, round_ptr, &round, quant_ptr, &quant,
|
||||
dequant_ptr, &dequant, quant_shift_ptr, &shift);
|
||||
|
||||
// Do DC and first 15 AC.
|
||||
coeff0 = load_coefficients(coeff_ptr);
|
||||
coeff1 = load_coefficients(coeff_ptr + 8);
|
||||
|
||||
// Poor man's abs().
|
||||
coeff0_sign = _mm_srai_epi16(coeff0, 15);
|
||||
coeff1_sign = _mm_srai_epi16(coeff1, 15);
|
||||
qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign);
|
||||
|
||||
prescan0 = _mm_loadu_si128((const __m128i *)prescan);
|
||||
prescan1 = _mm_loadu_si128((const __m128i *)(prescan + 8));
|
||||
|
||||
cmp_mask0 = _mm_and_si128(prescan0, _mm_cmpgt_epi16(qcoeff0, zbin));
|
||||
zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC
|
||||
cmp_mask1 = _mm_and_si128(prescan1, _mm_cmpgt_epi16(qcoeff1, zbin));
|
||||
|
||||
all_zero = _mm_or_si128(cmp_mask0, cmp_mask1);
|
||||
if (_mm_movemask_epi8(all_zero) == 0) {
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 4), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 8), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 12), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 4), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 8), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 12), zero);
|
||||
round = _mm_unpackhi_epi64(round, round);
|
||||
quant = _mm_unpackhi_epi64(quant, quant);
|
||||
shift = _mm_unpackhi_epi64(shift, shift);
|
||||
dequant = _mm_unpackhi_epi64(dequant, dequant);
|
||||
} else {
|
||||
calculate_qcoeff(&qcoeff0, round, quant, shift);
|
||||
|
||||
round = _mm_unpackhi_epi64(round, round);
|
||||
quant = _mm_unpackhi_epi64(quant, quant);
|
||||
shift = _mm_unpackhi_epi64(shift, shift);
|
||||
|
||||
calculate_qcoeff(&qcoeff1, round, quant, shift);
|
||||
|
||||
// Reinsert signs
|
||||
qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign);
|
||||
|
||||
// Mask out zbin threshold coeffs
|
||||
qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0);
|
||||
qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1);
|
||||
|
||||
store_coefficients(qcoeff0, qcoeff_ptr);
|
||||
store_coefficients(qcoeff1, qcoeff_ptr + 8);
|
||||
|
||||
coeff0 = calculate_dqcoeff(qcoeff0, dequant);
|
||||
dequant = _mm_unpackhi_epi64(dequant, dequant);
|
||||
coeff1 = calculate_dqcoeff(qcoeff1, dequant);
|
||||
|
||||
store_coefficients(coeff0, dqcoeff_ptr);
|
||||
store_coefficients(coeff1, dqcoeff_ptr + 8);
|
||||
|
||||
eob = scan_for_eob(&coeff0, &coeff1, cmp_mask0, cmp_mask1, iscan, 0, zero);
|
||||
}
|
||||
|
||||
// AC only loop.
|
||||
// TODO(Aniket): Reduce the processing of coeff quatization
|
||||
// based on eob logic
|
||||
while (index < n_coeffs) {
|
||||
coeff0 = load_coefficients(coeff_ptr + index);
|
||||
coeff1 = load_coefficients(coeff_ptr + index + 8);
|
||||
|
||||
coeff0_sign = _mm_srai_epi16(coeff0, 15);
|
||||
coeff1_sign = _mm_srai_epi16(coeff1, 15);
|
||||
qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign);
|
||||
|
||||
prescan0 = _mm_loadu_si128((const __m128i *)(prescan + index));
|
||||
prescan1 = _mm_loadu_si128((const __m128i *)(prescan + index + 8));
|
||||
|
||||
cmp_mask0 = _mm_and_si128(prescan0, _mm_cmpgt_epi16(qcoeff0, zbin));
|
||||
cmp_mask1 = _mm_and_si128(prescan1, _mm_cmpgt_epi16(qcoeff1, zbin));
|
||||
|
||||
all_zero = _mm_or_si128(cmp_mask0, cmp_mask1);
|
||||
if (_mm_movemask_epi8(all_zero) == 0) {
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 4), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 8), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 12), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 4), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 8), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 12), zero);
|
||||
index += 16;
|
||||
continue;
|
||||
}
|
||||
calculate_qcoeff(&qcoeff0, round, quant, shift);
|
||||
calculate_qcoeff(&qcoeff1, round, quant, shift);
|
||||
|
||||
qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign);
|
||||
|
||||
qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0);
|
||||
qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1);
|
||||
|
||||
store_coefficients(qcoeff0, qcoeff_ptr + index);
|
||||
store_coefficients(qcoeff1, qcoeff_ptr + index + 8);
|
||||
|
||||
coeff0 = calculate_dqcoeff(qcoeff0, dequant);
|
||||
coeff1 = calculate_dqcoeff(qcoeff1, dequant);
|
||||
|
||||
store_coefficients(coeff0, dqcoeff_ptr + index);
|
||||
store_coefficients(coeff1, dqcoeff_ptr + index + 8);
|
||||
|
||||
eob0 = scan_for_eob(&coeff0, &coeff1, cmp_mask0, cmp_mask1, iscan, index,
|
||||
zero);
|
||||
eob = _mm_max_epi16(eob, eob0);
|
||||
index += 16;
|
||||
}
|
||||
|
||||
*eob_ptr = accumulate_eob(eob);
|
||||
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
// TODO(Aniket): Experiment the following loop with intrinsic by combining
|
||||
// with the quantization loop above
|
||||
for (int i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int qcoeff = qcoeff_ptr[rc];
|
||||
if (qcoeff) {
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((*eob_ptr - 1) >= 0 && first == (*eob_ptr - 1)) {
|
||||
const int rc = scan[(*eob_ptr - 1)];
|
||||
if (qcoeff_ptr[rc] == 1 || qcoeff_ptr[rc] == -1) {
|
||||
const qm_val_t wt = (1 << AOM_QM_BITS);
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int factor = EOB_FACTOR + SKIP_EOB_FACTOR_ADJUST;
|
||||
const int prescan_add_val =
|
||||
ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * factor, 7);
|
||||
if (abs_coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val)) {
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
*eob_ptr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void aom_quantize_b_32x32_adaptive_sse2(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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 index = 16;
|
||||
int non_zero_count = (int)n_coeffs;
|
||||
const int log_scale = 1;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i one = _mm_set1_epi16(1);
|
||||
const __m128i log_scale_vec = _mm_set1_epi16(log_scale);
|
||||
__m128i zbin, round, quant, dequant, shift;
|
||||
__m128i coeff0, coeff1, coeff0_sign, coeff1_sign;
|
||||
__m128i qcoeff0, qcoeff1;
|
||||
__m128i cmp_mask0, cmp_mask1;
|
||||
__m128i eob = zero, eob0, prescan0, prescan1, all_zero;
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale) };
|
||||
|
||||
int prescan_add[2];
|
||||
for (int i = 0; i < 2; ++i)
|
||||
prescan_add[i] = ROUND_POWER_OF_TWO(dequant_ptr[i] * EOB_FACTOR, 7);
|
||||
|
||||
// max buffer is of size 1024 as this functions calls with
|
||||
// maximum n_coeffs as 1024
|
||||
int16_t prescan[1024];
|
||||
memset(prescan, -1, n_coeffs * sizeof(int16_t));
|
||||
|
||||
// TODO(Aniket): Experiment the following loop with intrinsic
|
||||
for (int i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = 1 << AOM_QM_BITS;
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int prescan_add_val = prescan_add[rc != 0];
|
||||
if (abs_coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val)) {
|
||||
prescan[rc] = 0;
|
||||
non_zero_count--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
int first = -1;
|
||||
#endif
|
||||
// Setup global values.
|
||||
zbin = _mm_load_si128((const __m128i *)zbin_ptr);
|
||||
round = _mm_load_si128((const __m128i *)round_ptr);
|
||||
quant = _mm_load_si128((const __m128i *)quant_ptr);
|
||||
dequant = _mm_load_si128((const __m128i *)dequant_ptr);
|
||||
shift = _mm_load_si128((const __m128i *)quant_shift_ptr);
|
||||
|
||||
// Shift with rounding.
|
||||
zbin = _mm_add_epi16(zbin, log_scale_vec);
|
||||
round = _mm_add_epi16(round, log_scale_vec);
|
||||
zbin = _mm_srli_epi16(zbin, log_scale);
|
||||
round = _mm_srli_epi16(round, log_scale);
|
||||
zbin = _mm_sub_epi16(zbin, one);
|
||||
// Do DC and first 15 AC.
|
||||
coeff0 = load_coefficients(coeff_ptr);
|
||||
coeff1 = load_coefficients(coeff_ptr + 8);
|
||||
|
||||
coeff0_sign = _mm_srai_epi16(coeff0, 15);
|
||||
coeff1_sign = _mm_srai_epi16(coeff1, 15);
|
||||
qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign);
|
||||
|
||||
prescan0 = _mm_loadu_si128((const __m128i *)prescan);
|
||||
prescan1 = _mm_loadu_si128((const __m128i *)(prescan + 8));
|
||||
|
||||
cmp_mask0 = _mm_and_si128(prescan0, _mm_cmpgt_epi16(qcoeff0, zbin));
|
||||
zbin = _mm_unpackhi_epi64(zbin, zbin); // Switch DC to AC
|
||||
cmp_mask1 = _mm_and_si128(prescan1, _mm_cmpgt_epi16(qcoeff1, zbin));
|
||||
|
||||
all_zero = _mm_or_si128(cmp_mask0, cmp_mask1);
|
||||
if (_mm_movemask_epi8(all_zero) == 0) {
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 4), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 8), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + 12), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 4), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 8), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + 12), zero);
|
||||
round = _mm_unpackhi_epi64(round, round);
|
||||
quant = _mm_unpackhi_epi64(quant, quant);
|
||||
shift = _mm_unpackhi_epi64(shift, shift);
|
||||
dequant = _mm_unpackhi_epi64(dequant, dequant);
|
||||
} else {
|
||||
calculate_qcoeff_log_scale(&qcoeff0, round, quant, &shift, &log_scale);
|
||||
|
||||
round = _mm_unpackhi_epi64(round, round);
|
||||
quant = _mm_unpackhi_epi64(quant, quant);
|
||||
shift = _mm_unpackhi_epi64(shift, shift);
|
||||
|
||||
calculate_qcoeff_log_scale(&qcoeff1, round, quant, &shift, &log_scale);
|
||||
|
||||
// Reinsert signs
|
||||
qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign);
|
||||
|
||||
// Mask out zbin threshold coeffs
|
||||
qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0);
|
||||
qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1);
|
||||
|
||||
store_coefficients(qcoeff0, qcoeff_ptr);
|
||||
store_coefficients(qcoeff1, qcoeff_ptr + 8);
|
||||
|
||||
calculate_dqcoeff_and_store_log_scale(qcoeff0, dequant, zero, dqcoeff_ptr,
|
||||
&log_scale);
|
||||
dequant = _mm_unpackhi_epi64(dequant, dequant);
|
||||
calculate_dqcoeff_and_store_log_scale(qcoeff1, dequant, zero,
|
||||
dqcoeff_ptr + 8, &log_scale);
|
||||
|
||||
eob =
|
||||
scan_for_eob(&qcoeff0, &qcoeff1, cmp_mask0, cmp_mask1, iscan, 0, zero);
|
||||
}
|
||||
|
||||
// AC only loop.
|
||||
// TODO(Aniket): Reduce the processing of coeff quatization
|
||||
// based on eob logic
|
||||
while (index < n_coeffs) {
|
||||
coeff0 = load_coefficients(coeff_ptr + index);
|
||||
coeff1 = load_coefficients(coeff_ptr + index + 8);
|
||||
|
||||
coeff0_sign = _mm_srai_epi16(coeff0, 15);
|
||||
coeff1_sign = _mm_srai_epi16(coeff1, 15);
|
||||
qcoeff0 = invert_sign_sse2(coeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(coeff1, coeff1_sign);
|
||||
|
||||
prescan0 = _mm_loadu_si128((const __m128i *)(prescan + index));
|
||||
prescan1 = _mm_loadu_si128((const __m128i *)(prescan + index + 8));
|
||||
|
||||
cmp_mask0 = _mm_and_si128(prescan0, _mm_cmpgt_epi16(qcoeff0, zbin));
|
||||
cmp_mask1 = _mm_and_si128(prescan1, _mm_cmpgt_epi16(qcoeff1, zbin));
|
||||
|
||||
all_zero = _mm_or_si128(cmp_mask0, cmp_mask1);
|
||||
if (_mm_movemask_epi8(all_zero) == 0) {
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 4), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 8), zero);
|
||||
_mm_store_si128((__m128i *)(qcoeff_ptr + index + 12), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 4), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 8), zero);
|
||||
_mm_store_si128((__m128i *)(dqcoeff_ptr + index + 12), zero);
|
||||
index += 16;
|
||||
continue;
|
||||
}
|
||||
calculate_qcoeff_log_scale(&qcoeff0, round, quant, &shift, &log_scale);
|
||||
calculate_qcoeff_log_scale(&qcoeff1, round, quant, &shift, &log_scale);
|
||||
|
||||
qcoeff0 = invert_sign_sse2(qcoeff0, coeff0_sign);
|
||||
qcoeff1 = invert_sign_sse2(qcoeff1, coeff1_sign);
|
||||
|
||||
qcoeff0 = _mm_and_si128(qcoeff0, cmp_mask0);
|
||||
qcoeff1 = _mm_and_si128(qcoeff1, cmp_mask1);
|
||||
|
||||
store_coefficients(qcoeff0, qcoeff_ptr + index);
|
||||
store_coefficients(qcoeff1, qcoeff_ptr + index + 8);
|
||||
|
||||
calculate_dqcoeff_and_store_log_scale(qcoeff0, dequant, zero,
|
||||
dqcoeff_ptr + index, &log_scale);
|
||||
calculate_dqcoeff_and_store_log_scale(qcoeff1, dequant, zero,
|
||||
dqcoeff_ptr + index + 8, &log_scale);
|
||||
|
||||
eob0 = scan_for_eob(&qcoeff0, &qcoeff1, cmp_mask0, cmp_mask1, iscan, index,
|
||||
zero);
|
||||
eob = _mm_max_epi16(eob, eob0);
|
||||
index += 16;
|
||||
}
|
||||
|
||||
*eob_ptr = accumulate_eob(eob);
|
||||
|
||||
#if SKIP_EOB_FACTOR_ADJUST
|
||||
// TODO(Aniket): Experiment the following loop with intrinsic by combining
|
||||
// with the quantization loop above
|
||||
for (int i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int qcoeff = qcoeff_ptr[rc];
|
||||
if (qcoeff) {
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((*eob_ptr - 1) >= 0 && first == (*eob_ptr - 1)) {
|
||||
const int rc = scan[(*eob_ptr - 1)];
|
||||
if (qcoeff_ptr[rc] == 1 || qcoeff_ptr[rc] == -1) {
|
||||
const qm_val_t wt = (1 << AOM_QM_BITS);
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int factor = EOB_FACTOR + SKIP_EOB_FACTOR_ADJUST;
|
||||
const int prescan_add_val =
|
||||
ROUND_POWER_OF_TWO(dequant_ptr[rc != 0] * factor, 7);
|
||||
if (abs_coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS) + prescan_add_val)) {
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
*eob_ptr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
123
third_party/aom/aom_dsp/x86/avg_intrin_sse2.c
vendored
123
third_party/aom/aom_dsp/x86/avg_intrin_sse2.c
vendored
|
|
@ -16,6 +16,129 @@
|
|||
#include "aom_dsp/x86/bitdepth_conversion_sse2.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
void aom_minmax_8x8_sse2(const uint8_t *s, int p, const uint8_t *d, int dp,
|
||||
int *min, int *max) {
|
||||
__m128i u0, s0, d0, diff, maxabsdiff, minabsdiff, negdiff, absdiff0, absdiff;
|
||||
u0 = _mm_setzero_si128();
|
||||
// Row 0
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff0 = _mm_max_epi16(diff, negdiff);
|
||||
// Row 1
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(absdiff0, absdiff);
|
||||
minabsdiff = _mm_min_epi16(absdiff0, absdiff);
|
||||
// Row 2
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 2 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
// Row 3
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 3 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
// Row 4
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 4 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 4 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
// Row 5
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 5 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 5 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
// Row 6
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 6 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 6 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
// Row 7
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 7 * p)), u0);
|
||||
d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(d + 7 * dp)), u0);
|
||||
diff = _mm_subs_epi16(s0, d0);
|
||||
negdiff = _mm_subs_epi16(u0, diff);
|
||||
absdiff = _mm_max_epi16(diff, negdiff);
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, absdiff);
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, absdiff);
|
||||
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_si128(maxabsdiff, 8));
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 32));
|
||||
maxabsdiff = _mm_max_epi16(maxabsdiff, _mm_srli_epi64(maxabsdiff, 16));
|
||||
*max = _mm_extract_epi16(maxabsdiff, 0);
|
||||
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_si128(minabsdiff, 8));
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 32));
|
||||
minabsdiff = _mm_min_epi16(minabsdiff, _mm_srli_epi64(minabsdiff, 16));
|
||||
*min = _mm_extract_epi16(minabsdiff, 0);
|
||||
}
|
||||
|
||||
unsigned int aom_avg_8x8_sse2(const uint8_t *s, int p) {
|
||||
__m128i s0, s1, u0;
|
||||
unsigned int avg = 0;
|
||||
u0 = _mm_setzero_si128();
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 4 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 5 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 6 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 7 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
|
||||
s0 = _mm_adds_epu16(s0, _mm_srli_si128(s0, 8));
|
||||
s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 32));
|
||||
s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 16));
|
||||
avg = _mm_extract_epi16(s0, 0);
|
||||
return (avg + 32) >> 6;
|
||||
}
|
||||
|
||||
unsigned int aom_avg_4x4_sse2(const uint8_t *s, int p) {
|
||||
__m128i s0, s1, u0;
|
||||
unsigned int avg = 0;
|
||||
u0 = _mm_setzero_si128();
|
||||
s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s)), u0);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 2 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i *)(s + 3 * p)), u0);
|
||||
s0 = _mm_adds_epu16(s0, s1);
|
||||
|
||||
s0 = _mm_adds_epu16(s0, _mm_srli_si128(s0, 4));
|
||||
s0 = _mm_adds_epu16(s0, _mm_srli_epi64(s0, 16));
|
||||
avg = _mm_extract_epi16(s0, 0);
|
||||
return (avg + 8) >> 4;
|
||||
}
|
||||
|
||||
static void hadamard_col8_sse2(__m128i *in, int iter) {
|
||||
__m128i a0 = in[0];
|
||||
__m128i a1 = in[1];
|
||||
|
|
|
|||
249
third_party/aom/aom_dsp/x86/convolve_avx2.h
vendored
249
third_party/aom/aom_dsp/x86/convolve_avx2.h
vendored
|
|
@ -34,31 +34,214 @@ DECLARE_ALIGNED(32, static const uint8_t, filt4_d4_global_avx2[]) = {
|
|||
2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8,
|
||||
};
|
||||
|
||||
DECLARE_ALIGNED(32, static const uint8_t, filt_center_global_avx2[32]) = {
|
||||
3, 255, 4, 255, 5, 255, 6, 255, 7, 255, 8, 255, 9, 255, 10, 255,
|
||||
3, 255, 4, 255, 5, 255, 6, 255, 7, 255, 8, 255, 9, 255, 10, 255
|
||||
};
|
||||
#define CONVOLVE_SR_HORIZONTAL_FILTER_8TAP \
|
||||
for (i = 0; i < (im_h - 2); i += 2) { \
|
||||
__m256i data = _mm256_castsi128_si256( \
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j])); \
|
||||
data = _mm256_inserti128_si256( \
|
||||
data, \
|
||||
_mm_loadu_si128( \
|
||||
(__m128i *)&src_ptr[(i * src_stride) + j + src_stride]), \
|
||||
1); \
|
||||
\
|
||||
__m256i res = convolve_lowbd_x(data, coeffs_h, filt); \
|
||||
res = \
|
||||
_mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h); \
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res); \
|
||||
} \
|
||||
\
|
||||
__m256i data_1 = _mm256_castsi128_si256( \
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j])); \
|
||||
\
|
||||
__m256i res = convolve_lowbd_x(data_1, coeffs_h, filt); \
|
||||
\
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h); \
|
||||
\
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res);
|
||||
|
||||
DECLARE_ALIGNED(32, static const uint8_t, filt1_global_avx2[32]) = {
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8
|
||||
};
|
||||
#define CONVOLVE_SR_VERTICAL_FILTER_8TAP \
|
||||
__m256i src_0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride)); \
|
||||
__m256i src_1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride)); \
|
||||
__m256i src_2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride)); \
|
||||
__m256i src_3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride)); \
|
||||
__m256i src_4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride)); \
|
||||
__m256i src_5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride)); \
|
||||
\
|
||||
__m256i s[8]; \
|
||||
s[0] = _mm256_unpacklo_epi16(src_0, src_1); \
|
||||
s[1] = _mm256_unpacklo_epi16(src_2, src_3); \
|
||||
s[2] = _mm256_unpacklo_epi16(src_4, src_5); \
|
||||
\
|
||||
s[4] = _mm256_unpackhi_epi16(src_0, src_1); \
|
||||
s[5] = _mm256_unpackhi_epi16(src_2, src_3); \
|
||||
s[6] = _mm256_unpackhi_epi16(src_4, src_5); \
|
||||
\
|
||||
for (i = 0; i < h; i += 2) { \
|
||||
const int16_t *data = &im_block[i * im_stride]; \
|
||||
\
|
||||
const __m256i s6 = _mm256_loadu_si256((__m256i *)(data + 6 * im_stride)); \
|
||||
const __m256i s7 = _mm256_loadu_si256((__m256i *)(data + 7 * im_stride)); \
|
||||
\
|
||||
s[3] = _mm256_unpacklo_epi16(s6, s7); \
|
||||
s[7] = _mm256_unpackhi_epi16(s6, s7); \
|
||||
\
|
||||
__m256i res_a = convolve(s, coeffs_v); \
|
||||
__m256i res_b = convolve(s + 4, coeffs_v); \
|
||||
\
|
||||
res_a = \
|
||||
_mm256_sra_epi32(_mm256_add_epi32(res_a, sum_round_v), sum_shift_v); \
|
||||
res_b = \
|
||||
_mm256_sra_epi32(_mm256_add_epi32(res_b, sum_round_v), sum_shift_v); \
|
||||
\
|
||||
const __m256i res_a_round = _mm256_sra_epi32( \
|
||||
_mm256_add_epi32(res_a, round_const_v), round_shift_v); \
|
||||
const __m256i res_b_round = _mm256_sra_epi32( \
|
||||
_mm256_add_epi32(res_b, round_const_v), round_shift_v); \
|
||||
\
|
||||
const __m256i res_16bit = _mm256_packs_epi32(res_a_round, res_b_round); \
|
||||
const __m256i res_8b = _mm256_packus_epi16(res_16bit, res_16bit); \
|
||||
\
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b); \
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1); \
|
||||
\
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j]; \
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + j + dst_stride]; \
|
||||
if (w - j > 4) { \
|
||||
_mm_storel_epi64(p_0, res_0); \
|
||||
_mm_storel_epi64(p_1, res_1); \
|
||||
} else if (w == 4) { \
|
||||
xx_storel_32(p_0, res_0); \
|
||||
xx_storel_32(p_1, res_1); \
|
||||
} else { \
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0); \
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1); \
|
||||
} \
|
||||
\
|
||||
s[0] = s[1]; \
|
||||
s[1] = s[2]; \
|
||||
s[2] = s[3]; \
|
||||
\
|
||||
s[4] = s[5]; \
|
||||
s[5] = s[6]; \
|
||||
s[6] = s[7]; \
|
||||
}
|
||||
|
||||
DECLARE_ALIGNED(32, static const uint8_t, filt2_global_avx2[32]) = {
|
||||
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
|
||||
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10
|
||||
};
|
||||
|
||||
DECLARE_ALIGNED(32, static const uint8_t, filt3_global_avx2[32]) = {
|
||||
4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
|
||||
4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12
|
||||
};
|
||||
|
||||
DECLARE_ALIGNED(32, static const uint8_t, filt4_global_avx2[32]) = {
|
||||
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14,
|
||||
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14
|
||||
};
|
||||
#define DIST_WTD_CONVOLVE_HORIZONTAL_FILTER_8TAP \
|
||||
for (i = 0; i < im_h; i += 2) { \
|
||||
__m256i data = _mm256_castsi128_si256(_mm_loadu_si128((__m128i *)src_h)); \
|
||||
if (i + 1 < im_h) \
|
||||
data = _mm256_inserti128_si256( \
|
||||
data, _mm_loadu_si128((__m128i *)(src_h + src_stride)), 1); \
|
||||
src_h += (src_stride << 1); \
|
||||
__m256i res = convolve_lowbd_x(data, coeffs_x, filt); \
|
||||
\
|
||||
res = \
|
||||
_mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h); \
|
||||
\
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res); \
|
||||
}
|
||||
|
||||
#define DIST_WTD_CONVOLVE_VERTICAL_FILTER_8TAP \
|
||||
__m256i s[8]; \
|
||||
__m256i s0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride)); \
|
||||
__m256i s1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride)); \
|
||||
__m256i s2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride)); \
|
||||
__m256i s3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride)); \
|
||||
__m256i s4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride)); \
|
||||
__m256i s5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride)); \
|
||||
\
|
||||
s[0] = _mm256_unpacklo_epi16(s0, s1); \
|
||||
s[1] = _mm256_unpacklo_epi16(s2, s3); \
|
||||
s[2] = _mm256_unpacklo_epi16(s4, s5); \
|
||||
\
|
||||
s[4] = _mm256_unpackhi_epi16(s0, s1); \
|
||||
s[5] = _mm256_unpackhi_epi16(s2, s3); \
|
||||
s[6] = _mm256_unpackhi_epi16(s4, s5); \
|
||||
\
|
||||
for (i = 0; i < h; i += 2) { \
|
||||
const int16_t *data = &im_block[i * im_stride]; \
|
||||
\
|
||||
const __m256i s6 = _mm256_loadu_si256((__m256i *)(data + 6 * im_stride)); \
|
||||
const __m256i s7 = _mm256_loadu_si256((__m256i *)(data + 7 * im_stride)); \
|
||||
\
|
||||
s[3] = _mm256_unpacklo_epi16(s6, s7); \
|
||||
s[7] = _mm256_unpackhi_epi16(s6, s7); \
|
||||
\
|
||||
const __m256i res_a = convolve(s, coeffs_y); \
|
||||
const __m256i res_a_round = _mm256_sra_epi32( \
|
||||
_mm256_add_epi32(res_a, round_const_v), round_shift_v); \
|
||||
\
|
||||
if (w - j > 4) { \
|
||||
const __m256i res_b = convolve(s + 4, coeffs_y); \
|
||||
const __m256i res_b_round = _mm256_sra_epi32( \
|
||||
_mm256_add_epi32(res_b, round_const_v), round_shift_v); \
|
||||
const __m256i res_16b = _mm256_packs_epi32(res_a_round, res_b_round); \
|
||||
const __m256i res_unsigned = _mm256_add_epi16(res_16b, offset_const); \
|
||||
\
|
||||
if (do_average) { \
|
||||
const __m256i data_ref_0 = load_line2_avx2( \
|
||||
&dst[i * dst_stride + j], &dst[i * dst_stride + j + dst_stride]); \
|
||||
const __m256i comp_avg_res = \
|
||||
comp_avg(&data_ref_0, &res_unsigned, &wt, use_dist_wtd_comp_avg); \
|
||||
\
|
||||
const __m256i round_result = convolve_rounding( \
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift); \
|
||||
\
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result); \
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8); \
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1); \
|
||||
\
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0); \
|
||||
_mm_storel_epi64( \
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1); \
|
||||
} else { \
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_unsigned); \
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0); \
|
||||
\
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_unsigned, 1); \
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]), \
|
||||
res_1); \
|
||||
} \
|
||||
} else { \
|
||||
const __m256i res_16b = _mm256_packs_epi32(res_a_round, res_a_round); \
|
||||
const __m256i res_unsigned = _mm256_add_epi16(res_16b, offset_const); \
|
||||
\
|
||||
if (do_average) { \
|
||||
const __m256i data_ref_0 = load_line2_avx2( \
|
||||
&dst[i * dst_stride + j], &dst[i * dst_stride + j + dst_stride]); \
|
||||
\
|
||||
const __m256i comp_avg_res = \
|
||||
comp_avg(&data_ref_0, &res_unsigned, &wt, use_dist_wtd_comp_avg); \
|
||||
\
|
||||
const __m256i round_result = convolve_rounding( \
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift); \
|
||||
\
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result); \
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8); \
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1); \
|
||||
\
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) = _mm_cvtsi128_si32(res_0); \
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) = \
|
||||
_mm_cvtsi128_si32(res_1); \
|
||||
\
|
||||
} else { \
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_unsigned); \
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0); \
|
||||
\
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_unsigned, 1); \
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]), \
|
||||
res_1); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
s[0] = s[1]; \
|
||||
s[1] = s[2]; \
|
||||
s[2] = s[3]; \
|
||||
\
|
||||
s[4] = s[5]; \
|
||||
s[5] = s[6]; \
|
||||
s[6] = s[7]; \
|
||||
}
|
||||
static INLINE void prepare_coeffs_lowbd(
|
||||
const InterpFilterParams *const filter_params, const int subpel_q4,
|
||||
__m256i *const coeffs /* [4] */) {
|
||||
|
|
@ -120,6 +303,17 @@ static INLINE __m256i convolve_lowbd(const __m256i *const s,
|
|||
return res;
|
||||
}
|
||||
|
||||
static INLINE __m256i convolve_lowbd_4tap(const __m256i *const s,
|
||||
const __m256i *const coeffs) {
|
||||
const __m256i res_23 = _mm256_maddubs_epi16(s[0], coeffs[0]);
|
||||
const __m256i res_45 = _mm256_maddubs_epi16(s[1], coeffs[1]);
|
||||
|
||||
// order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
const __m256i res = _mm256_add_epi16(res_45, res_23);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static INLINE __m256i convolve(const __m256i *const s,
|
||||
const __m256i *const coeffs) {
|
||||
const __m256i res_0 = _mm256_madd_epi16(s[0], coeffs[0]);
|
||||
|
|
@ -155,6 +349,17 @@ static INLINE __m256i convolve_lowbd_x(const __m256i data,
|
|||
return convolve_lowbd(s, coeffs);
|
||||
}
|
||||
|
||||
static INLINE __m256i convolve_lowbd_x_4tap(const __m256i data,
|
||||
const __m256i *const coeffs,
|
||||
const __m256i *const filt) {
|
||||
__m256i s[2];
|
||||
|
||||
s[0] = _mm256_shuffle_epi8(data, filt[0]);
|
||||
s[1] = _mm256_shuffle_epi8(data, filt[1]);
|
||||
|
||||
return convolve_lowbd_4tap(s, coeffs);
|
||||
}
|
||||
|
||||
static INLINE void add_store_aligned_256(CONV_BUF_TYPE *const dst,
|
||||
const __m256i *const res,
|
||||
const int do_average) {
|
||||
|
|
|
|||
|
|
@ -1,259 +0,0 @@
|
|||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
%include "third_party/x86inc/x86inc.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
pw_4: times 8 dw 4
|
||||
pw_8: times 8 dw 8
|
||||
pw_16: times 4 dd 16
|
||||
pw_32: times 4 dd 32
|
||||
|
||||
SECTION .text
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_dc_predictor_4x4, 4, 5, 4, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
movq m0, [aboveq]
|
||||
movq m2, [leftq]
|
||||
paddw m0, m2
|
||||
pshuflw m1, m0, 0xe
|
||||
paddw m0, m1
|
||||
pshuflw m1, m0, 0x1
|
||||
paddw m0, m1
|
||||
paddw m0, [GLOBAL(pw_4)]
|
||||
psraw m0, 3
|
||||
pshuflw m0, m0, 0x0
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_dc_predictor_8x8, 4, 5, 4, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
mova m2, [leftq]
|
||||
DEFINE_ARGS dst, stride, stride3, one
|
||||
mov oned, 0x00010001
|
||||
lea stride3q, [strideq*3]
|
||||
movd m3, oned
|
||||
pshufd m3, m3, 0x0
|
||||
paddw m0, m2
|
||||
pmaddwd m0, m3
|
||||
packssdw m0, m1
|
||||
pmaddwd m0, m3
|
||||
packssdw m0, m1
|
||||
pmaddwd m0, m3
|
||||
paddw m0, [GLOBAL(pw_8)]
|
||||
psrlw m0, 4
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+stride3q*2], m0
|
||||
lea dstq, [dstq+strideq*8]
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+stride3q*2], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_dc_predictor_16x16, 4, 5, 5, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
mova m3, [aboveq+16]
|
||||
mova m2, [leftq]
|
||||
mova m4, [leftq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 4
|
||||
paddw m0, m2
|
||||
paddw m0, m3
|
||||
paddw m0, m4
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
punpcklwd m0, m1
|
||||
movhlps m2, m0
|
||||
paddd m0, m2
|
||||
punpckldq m0, m1
|
||||
movhlps m2, m0
|
||||
paddd m0, m2
|
||||
paddd m0, [GLOBAL(pw_16)]
|
||||
psrad m0, 5
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2 +16], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+strideq*4 +16], m0
|
||||
mova [dstq+stride3q*2 ], m0
|
||||
mova [dstq+stride3q*2+16], m0
|
||||
lea dstq, [dstq+strideq*8]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_dc_predictor_32x32, 4, 5, 7, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
mova m0, [aboveq]
|
||||
mova m2, [aboveq+16]
|
||||
mova m3, [aboveq+32]
|
||||
mova m4, [aboveq+48]
|
||||
paddw m0, m2
|
||||
paddw m3, m4
|
||||
mova m2, [leftq]
|
||||
mova m4, [leftq+16]
|
||||
mova m5, [leftq+32]
|
||||
mova m6, [leftq+48]
|
||||
paddw m2, m4
|
||||
paddw m5, m6
|
||||
paddw m0, m3
|
||||
paddw m2, m5
|
||||
pxor m1, m1
|
||||
paddw m0, m2
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 8
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
punpcklwd m0, m1
|
||||
movhlps m2, m0
|
||||
paddd m0, m2
|
||||
punpckldq m0, m1
|
||||
movhlps m2, m0
|
||||
paddd m0, m2
|
||||
paddd m0, [GLOBAL(pw_32)]
|
||||
psrad m0, 6
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16 ], m0
|
||||
mova [dstq +32 ], m0
|
||||
mova [dstq +48 ], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16 ], m0
|
||||
mova [dstq+strideq*2+32 ], m0
|
||||
mova [dstq+strideq*2+48 ], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+strideq*4+16 ], m0
|
||||
mova [dstq+strideq*4+32 ], m0
|
||||
mova [dstq+strideq*4+48 ], m0
|
||||
mova [dstq+stride3q*2 ], m0
|
||||
mova [dstq+stride3q*2 +16], m0
|
||||
mova [dstq+stride3q*2 +32], m0
|
||||
mova [dstq+stride3q*2 +48], m0
|
||||
lea dstq, [dstq+strideq*8]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_v_predictor_4x4, 3, 3, 1, dst, stride, above
|
||||
movq m0, [aboveq]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_v_predictor_8x8, 3, 3, 1, dst, stride, above
|
||||
mova m0, [aboveq]
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+stride3q*2], m0
|
||||
lea dstq, [dstq+strideq*8]
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+stride3q*2], m0
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_v_predictor_16x16, 3, 4, 2, dst, stride, above
|
||||
mova m0, [aboveq]
|
||||
mova m1, [aboveq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, nlines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov nlines4d, 4
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m1
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2 +16], m1
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+strideq*4 +16], m1
|
||||
mova [dstq+stride3q*2 ], m0
|
||||
mova [dstq+stride3q*2+16], m1
|
||||
lea dstq, [dstq+strideq*8]
|
||||
dec nlines4d
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal highbd_v_predictor_32x32, 3, 4, 4, dst, stride, above
|
||||
mova m0, [aboveq]
|
||||
mova m1, [aboveq+16]
|
||||
mova m2, [aboveq+32]
|
||||
mova m3, [aboveq+48]
|
||||
DEFINE_ARGS dst, stride, stride3, nlines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov nlines4d, 8
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m1
|
||||
mova [dstq +32], m2
|
||||
mova [dstq +48], m3
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2 +16], m1
|
||||
mova [dstq+strideq*2 +32], m2
|
||||
mova [dstq+strideq*2 +48], m3
|
||||
mova [dstq+strideq*4 ], m0
|
||||
mova [dstq+strideq*4 +16], m1
|
||||
mova [dstq+strideq*4 +32], m2
|
||||
mova [dstq+strideq*4 +48], m3
|
||||
mova [dstq+stride3q*2 ], m0
|
||||
mova [dstq+stride3q*2 +16], m1
|
||||
mova [dstq+stride3q*2 +32], m2
|
||||
mova [dstq+stride3q*2 +48], m3
|
||||
lea dstq, [dstq+strideq*8]
|
||||
dec nlines4d
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
|
@ -146,3 +146,61 @@ void aom_highbd_quantize_b_32x32_sse2(
|
|||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
void aom_highbd_quantize_b_64x64_sse2(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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) {
|
||||
__m128i zbins[2];
|
||||
__m128i nzbins[2];
|
||||
int idx = 0;
|
||||
int idx_arr[1024];
|
||||
int i, eob = -1;
|
||||
const int zbin0_tmp = ROUND_POWER_OF_TWO(zbin_ptr[0], 2);
|
||||
const int zbin1_tmp = ROUND_POWER_OF_TWO(zbin_ptr[1], 2);
|
||||
(void)scan;
|
||||
zbins[0] = _mm_set_epi32(zbin1_tmp, zbin1_tmp, zbin1_tmp, zbin0_tmp);
|
||||
zbins[1] = _mm_set1_epi32(zbin1_tmp);
|
||||
|
||||
nzbins[0] = _mm_setzero_si128();
|
||||
nzbins[1] = _mm_setzero_si128();
|
||||
nzbins[0] = _mm_sub_epi32(nzbins[0], zbins[0]);
|
||||
nzbins[1] = _mm_sub_epi32(nzbins[1], zbins[1]);
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs / 4; i++) {
|
||||
__m128i coeffs, cmp1, cmp2;
|
||||
int test;
|
||||
coeffs = _mm_load_si128((const __m128i *)(coeff_ptr + i * 4));
|
||||
cmp1 = _mm_cmplt_epi32(coeffs, zbins[i != 0]);
|
||||
cmp2 = _mm_cmpgt_epi32(coeffs, nzbins[i != 0]);
|
||||
cmp1 = _mm_and_si128(cmp1, cmp2);
|
||||
test = _mm_movemask_epi8(cmp1);
|
||||
if (!(test & 0xf)) idx_arr[idx++] = i * 4;
|
||||
if (!(test & 0xf0)) idx_arr[idx++] = i * 4 + 1;
|
||||
if (!(test & 0xf00)) idx_arr[idx++] = i * 4 + 2;
|
||||
if (!(test & 0xf000)) idx_arr[idx++] = i * 4 + 3;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = idx_arr[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp1 = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 2);
|
||||
const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 14);
|
||||
qcoeff_ptr[rc] = (int)(abs_qcoeff ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 4;
|
||||
if (abs_qcoeff) eob = iscan[idx_arr[i]] > eob ? iscan[idx_arr[i]] : eob;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
|
|
|||
161
third_party/aom/aom_dsp/x86/highbd_variance_sse2.c
vendored
161
third_party/aom/aom_dsp/x86/highbd_variance_sse2.c
vendored
|
|
@ -287,30 +287,38 @@ DECLS(sse2);
|
|||
uint32_t aom_highbd_8_sub_pixel_variance##w##x##h##_##opt( \
|
||||
const uint8_t *src8, int src_stride, int x_offset, int y_offset, \
|
||||
const uint8_t *dst8, int dst_stride, uint32_t *sse_ptr) { \
|
||||
uint32_t sse; \
|
||||
uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); \
|
||||
int se = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src, src_stride, x_offset, y_offset, dst, dst_stride, h, &sse, NULL, \
|
||||
NULL); \
|
||||
if (w > wf) { \
|
||||
unsigned int sse2; \
|
||||
int se = 0; \
|
||||
unsigned int sse = 0; \
|
||||
unsigned int sse2; \
|
||||
int row_rep = (w > 64) ? 2 : 1; \
|
||||
for (int wd_64 = 0; wd_64 < row_rep; wd_64++) { \
|
||||
src += wd_64 * 64; \
|
||||
dst += wd_64 * 64; \
|
||||
int se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 16, src_stride, x_offset, y_offset, dst + 16, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
src, src_stride, x_offset, y_offset, dst, dst_stride, h, &sse2, \
|
||||
NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
if (w > wf) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 32, src_stride, x_offset, y_offset, dst + 32, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 48, src_stride, x_offset, y_offset, dst + 48, dst_stride, h, \
|
||||
src + 16, src_stride, x_offset, y_offset, dst + 16, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 32, src_stride, x_offset, y_offset, dst + 32, dst_stride, \
|
||||
h, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 48, src_stride, x_offset, y_offset, dst + 48, dst_stride, \
|
||||
h, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
*sse_ptr = sse; \
|
||||
|
|
@ -322,33 +330,42 @@ DECLS(sse2);
|
|||
const uint8_t *dst8, int dst_stride, uint32_t *sse_ptr) { \
|
||||
int64_t var; \
|
||||
uint32_t sse; \
|
||||
uint64_t long_sse = 0; \
|
||||
uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); \
|
||||
int se = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src, src_stride, x_offset, y_offset, dst, dst_stride, h, &sse, NULL, \
|
||||
NULL); \
|
||||
if (w > wf) { \
|
||||
uint32_t sse2; \
|
||||
int se = 0; \
|
||||
int row_rep = (w > 64) ? 2 : 1; \
|
||||
for (int wd_64 = 0; wd_64 < row_rep; wd_64++) { \
|
||||
src += wd_64 * 64; \
|
||||
dst += wd_64 * 64; \
|
||||
int se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 16, src_stride, x_offset, y_offset, dst + 16, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
src, src_stride, x_offset, y_offset, dst, dst_stride, h, &sse, NULL, \
|
||||
NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
long_sse += sse; \
|
||||
if (w > wf) { \
|
||||
uint32_t sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 32, src_stride, x_offset, y_offset, dst + 32, dst_stride, h, \
|
||||
src + 16, src_stride, x_offset, y_offset, dst + 16, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 48, src_stride, x_offset, y_offset, dst + 48, dst_stride, h, \
|
||||
&sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
sse += sse2; \
|
||||
long_sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 32, src_stride, x_offset, y_offset, dst + 32, dst_stride, \
|
||||
h, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 48, src_stride, x_offset, y_offset, dst + 48, dst_stride, \
|
||||
h, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
se = ROUND_POWER_OF_TWO(se, 2); \
|
||||
sse = ROUND_POWER_OF_TWO(sse, 4); \
|
||||
sse = (uint32_t)ROUND_POWER_OF_TWO(long_sse, 4); \
|
||||
*sse_ptr = sse; \
|
||||
var = (int64_t)(sse) - ((cast se * se) >> (wlog2 + hlog2)); \
|
||||
return (var >= 0) ? (uint32_t)var : 0; \
|
||||
|
|
@ -364,35 +381,38 @@ DECLS(sse2);
|
|||
uint64_t long_sse = 0; \
|
||||
uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8); \
|
||||
int row_rep = (w > 64) ? 2 : 1; \
|
||||
for (start_row = 0; start_row < h; start_row += 16) { \
|
||||
uint32_t sse2; \
|
||||
int height = h - start_row < 16 ? h - start_row : 16; \
|
||||
int se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + (start_row * src_stride), src_stride, x_offset, y_offset, \
|
||||
dst + (start_row * dst_stride), dst_stride, height, &sse2, NULL, \
|
||||
NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
if (w > wf) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 16 + (start_row * src_stride), src_stride, x_offset, \
|
||||
y_offset, dst + 16 + (start_row * dst_stride), dst_stride, height, \
|
||||
&sse2, NULL, NULL); \
|
||||
uint16_t *src_tmp = src + (start_row * src_stride); \
|
||||
uint16_t *dst_tmp = dst + (start_row * dst_stride); \
|
||||
for (int wd_64 = 0; wd_64 < row_rep; wd_64++) { \
|
||||
src_tmp += wd_64 * 64; \
|
||||
dst_tmp += wd_64 * 64; \
|
||||
int se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src_tmp, src_stride, x_offset, y_offset, dst_tmp, dst_stride, \
|
||||
height, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
if (w > wf) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 32 + (start_row * src_stride), src_stride, x_offset, \
|
||||
y_offset, dst + 32 + (start_row * dst_stride), dst_stride, \
|
||||
height, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src + 48 + (start_row * src_stride), src_stride, x_offset, \
|
||||
y_offset, dst + 48 + (start_row * dst_stride), dst_stride, \
|
||||
height, &sse2, NULL, NULL); \
|
||||
src_tmp + 16, src_stride, x_offset, y_offset, dst_tmp + 16, \
|
||||
dst_stride, height, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
if (w > wf * 2) { \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src_tmp + 32, src_stride, x_offset, y_offset, dst_tmp + 32, \
|
||||
dst_stride, height, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
se2 = aom_highbd_sub_pixel_variance##wf##xh_##opt( \
|
||||
src_tmp + 48, src_stride, x_offset, y_offset, dst_tmp + 48, \
|
||||
dst_stride, height, &sse2, NULL, NULL); \
|
||||
se += se2; \
|
||||
long_sse += sse2; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
|
@ -403,22 +423,25 @@ DECLS(sse2);
|
|||
return (var >= 0) ? (uint32_t)var : 0; \
|
||||
}
|
||||
|
||||
#define FNS(opt) \
|
||||
FN(64, 64, 16, 6, 6, opt, (int64_t)); \
|
||||
FN(64, 32, 16, 6, 5, opt, (int64_t)); \
|
||||
FN(32, 64, 16, 5, 6, opt, (int64_t)); \
|
||||
FN(32, 32, 16, 5, 5, opt, (int64_t)); \
|
||||
FN(32, 16, 16, 5, 4, opt, (int64_t)); \
|
||||
FN(16, 32, 16, 4, 5, opt, (int64_t)); \
|
||||
FN(16, 16, 16, 4, 4, opt, (int64_t)); \
|
||||
FN(16, 8, 16, 4, 3, opt, (int64_t)); \
|
||||
FN(8, 16, 8, 3, 4, opt, (int64_t)); \
|
||||
FN(8, 8, 8, 3, 3, opt, (int64_t)); \
|
||||
FN(8, 4, 8, 3, 2, opt, (int64_t)); \
|
||||
FN(16, 4, 16, 4, 2, opt, (int64_t)); \
|
||||
FN(8, 32, 8, 3, 5, opt, (int64_t)); \
|
||||
FN(32, 8, 16, 5, 3, opt, (int64_t)); \
|
||||
FN(16, 64, 16, 4, 6, opt, (int64_t)); \
|
||||
#define FNS(opt) \
|
||||
FN(128, 128, 16, 7, 7, opt, (int64_t)); \
|
||||
FN(128, 64, 16, 7, 6, opt, (int64_t)); \
|
||||
FN(64, 128, 16, 6, 7, opt, (int64_t)); \
|
||||
FN(64, 64, 16, 6, 6, opt, (int64_t)); \
|
||||
FN(64, 32, 16, 6, 5, opt, (int64_t)); \
|
||||
FN(32, 64, 16, 5, 6, opt, (int64_t)); \
|
||||
FN(32, 32, 16, 5, 5, opt, (int64_t)); \
|
||||
FN(32, 16, 16, 5, 4, opt, (int64_t)); \
|
||||
FN(16, 32, 16, 4, 5, opt, (int64_t)); \
|
||||
FN(16, 16, 16, 4, 4, opt, (int64_t)); \
|
||||
FN(16, 8, 16, 4, 3, opt, (int64_t)); \
|
||||
FN(8, 16, 8, 3, 4, opt, (int64_t)); \
|
||||
FN(8, 8, 8, 3, 3, opt, (int64_t)); \
|
||||
FN(8, 4, 8, 3, 2, opt, (int64_t)); \
|
||||
FN(16, 4, 16, 4, 2, opt, (int64_t)); \
|
||||
FN(8, 32, 8, 3, 5, opt, (int64_t)); \
|
||||
FN(32, 8, 16, 5, 3, opt, (int64_t)); \
|
||||
FN(16, 64, 16, 4, 6, opt, (int64_t)); \
|
||||
FN(64, 16, 16, 6, 4, opt, (int64_t))
|
||||
|
||||
FNS(sse2);
|
||||
|
|
|
|||
911
third_party/aom/aom_dsp/x86/intrapred_avx2.c
vendored
911
third_party/aom/aom_dsp/x86/intrapred_avx2.c
vendored
File diff suppressed because it is too large
Load diff
625
third_party/aom/aom_dsp/x86/intrapred_sse2_asm.asm
vendored
625
third_party/aom/aom_dsp/x86/intrapred_sse2_asm.asm
vendored
|
|
@ -1,625 +0,0 @@
|
|||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
%include "third_party/x86inc/x86inc.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
pb_1: times 16 db 1
|
||||
pw_4: times 8 dw 4
|
||||
pw_8: times 8 dw 8
|
||||
pw_16: times 8 dw 16
|
||||
pw_32: times 8 dw 32
|
||||
dc_128: times 16 db 128
|
||||
pw2_4: times 8 dw 2
|
||||
pw2_8: times 8 dw 4
|
||||
pw2_16: times 8 dw 8
|
||||
pw2_32: times 8 dw 16
|
||||
|
||||
SECTION .text
|
||||
|
||||
; ------------------------------------------
|
||||
; input: x, y, z, result
|
||||
;
|
||||
; trick from pascal
|
||||
; (x+2y+z+2)>>2 can be calculated as:
|
||||
; result = avg(x,z)
|
||||
; result -= xor(x,z) & 1
|
||||
; result = avg(result,y)
|
||||
; ------------------------------------------
|
||||
%macro X_PLUS_2Y_PLUS_Z_PLUS_2_RSH_2 4
|
||||
pavgb %4, %1, %3
|
||||
pxor %3, %1
|
||||
pand %3, [GLOBAL(pb_1)]
|
||||
psubb %4, %3
|
||||
pavgb %4, %2
|
||||
%endmacro
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_predictor_4x4, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
movd m2, [leftq]
|
||||
movd m0, [aboveq]
|
||||
pxor m1, m1
|
||||
punpckldq m0, m2
|
||||
psadbw m0, m1
|
||||
paddw m0, [GLOBAL(pw_4)]
|
||||
psraw m0, 3
|
||||
pshuflw m0, m0, 0x0
|
||||
packuswb m0, m0
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
lea dstq, [dstq+strideq*2]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_left_predictor_4x4, 2, 5, 2, dst, stride, above, left, goffset
|
||||
movifnidn leftq, leftmp
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
movd m0, [leftq]
|
||||
psadbw m0, m1
|
||||
paddw m0, [GLOBAL(pw2_4)]
|
||||
psraw m0, 2
|
||||
pshuflw m0, m0, 0x0
|
||||
packuswb m0, m0
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
lea dstq, [dstq+strideq*2]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_top_predictor_4x4, 3, 5, 2, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
movd m0, [aboveq]
|
||||
psadbw m0, m1
|
||||
paddw m0, [GLOBAL(pw2_4)]
|
||||
psraw m0, 2
|
||||
pshuflw m0, m0, 0x0
|
||||
packuswb m0, m0
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
lea dstq, [dstq+strideq*2]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_predictor_8x8, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
movq m0, [aboveq]
|
||||
movq m2, [leftq]
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
psadbw m0, m1
|
||||
psadbw m2, m1
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw_8)]
|
||||
psraw m0, 4
|
||||
punpcklbw m0, m0
|
||||
pshuflw m0, m0, 0x0
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_top_predictor_8x8, 3, 5, 2, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
movq m0, [aboveq]
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
psadbw m0, m1
|
||||
paddw m0, [GLOBAL(pw2_8)]
|
||||
psraw m0, 3
|
||||
punpcklbw m0, m0
|
||||
pshuflw m0, m0, 0x0
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_left_predictor_8x8, 2, 5, 2, dst, stride, above, left, goffset
|
||||
movifnidn leftq, leftmp
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
movq m0, [leftq]
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
psadbw m0, m1
|
||||
paddw m0, [GLOBAL(pw2_8)]
|
||||
psraw m0, 3
|
||||
punpcklbw m0, m0
|
||||
pshuflw m0, m0, 0x0
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_128_predictor_4x4, 2, 5, 1, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
movd m0, [GLOBAL(dc_128)]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq ], m0
|
||||
movd [dstq+strideq*2], m0
|
||||
movd [dstq+stride3q ], m0
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_128_predictor_8x8, 2, 5, 1, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
movq m0, [GLOBAL(dc_128)]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
mova m2, [leftq]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 4
|
||||
psadbw m0, m1
|
||||
psadbw m2, m1
|
||||
paddw m0, m2
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw_16)]
|
||||
psraw m0, 5
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq*2], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_top_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 4
|
||||
psadbw m0, m1
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw2_16)]
|
||||
psraw m0, 4
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq*2], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_left_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [leftq]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 4
|
||||
psadbw m0, m1
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw2_16)]
|
||||
psraw m0, 4
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq*2], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_128_predictor_16x16, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 4
|
||||
mova m0, [GLOBAL(dc_128)]
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq*2], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
mova m2, [aboveq+16]
|
||||
mova m3, [leftq]
|
||||
mova m4, [leftq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 8
|
||||
psadbw m0, m1
|
||||
psadbw m2, m1
|
||||
psadbw m3, m1
|
||||
psadbw m4, m1
|
||||
paddw m0, m2
|
||||
paddw m0, m3
|
||||
paddw m0, m4
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw_32)]
|
||||
psraw m0, 6
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq +16], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
mova [dstq+stride3q +16], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_top_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [aboveq]
|
||||
mova m2, [aboveq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 8
|
||||
psadbw m0, m1
|
||||
psadbw m2, m1
|
||||
paddw m0, m2
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw2_32)]
|
||||
psraw m0, 5
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq +16], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
mova [dstq+stride3q +16], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_left_predictor_32x32, 4, 5, 5, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
pxor m1, m1
|
||||
mova m0, [leftq]
|
||||
mova m2, [leftq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 8
|
||||
psadbw m0, m1
|
||||
psadbw m2, m1
|
||||
paddw m0, m2
|
||||
movhlps m2, m0
|
||||
paddw m0, m2
|
||||
paddw m0, [GLOBAL(pw2_32)]
|
||||
psraw m0, 5
|
||||
pshuflw m0, m0, 0x0
|
||||
punpcklqdq m0, m0
|
||||
packuswb m0, m0
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq +16], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
mova [dstq+stride3q +16], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
|
||||
RESTORE_GOT
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal dc_128_predictor_32x32, 4, 5, 3, dst, stride, above, left, goffset
|
||||
GET_GOT goffsetq
|
||||
|
||||
DEFINE_ARGS dst, stride, stride3, lines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov lines4d, 8
|
||||
mova m0, [GLOBAL(dc_128)]
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq +16], m0
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
mova [dstq+stride3q +16], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec lines4d
|
||||
jnz .loop
|
||||
RESTORE_GOT
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal v_predictor_4x4, 3, 3, 1, dst, stride, above
|
||||
movd m0, [aboveq]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
lea dstq, [dstq+strideq*2]
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m0
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal v_predictor_8x8, 3, 3, 1, dst, stride, above
|
||||
movq m0, [aboveq]
|
||||
DEFINE_ARGS dst, stride, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
movq [dstq ], m0
|
||||
movq [dstq+strideq ], m0
|
||||
movq [dstq+strideq*2], m0
|
||||
movq [dstq+stride3q ], m0
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal v_predictor_16x16, 3, 4, 1, dst, stride, above
|
||||
mova m0, [aboveq]
|
||||
DEFINE_ARGS dst, stride, stride3, nlines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov nlines4d, 4
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq*2], m0
|
||||
mova [dstq+stride3q ], m0
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec nlines4d
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal v_predictor_32x32, 3, 4, 2, dst, stride, above
|
||||
mova m0, [aboveq]
|
||||
mova m1, [aboveq+16]
|
||||
DEFINE_ARGS dst, stride, stride3, nlines4
|
||||
lea stride3q, [strideq*3]
|
||||
mov nlines4d, 8
|
||||
.loop:
|
||||
mova [dstq ], m0
|
||||
mova [dstq +16], m1
|
||||
mova [dstq+strideq ], m0
|
||||
mova [dstq+strideq +16], m1
|
||||
mova [dstq+strideq*2 ], m0
|
||||
mova [dstq+strideq*2+16], m1
|
||||
mova [dstq+stride3q ], m0
|
||||
mova [dstq+stride3q +16], m1
|
||||
lea dstq, [dstq+strideq*4]
|
||||
dec nlines4d
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal h_predictor_4x4, 2, 4, 4, dst, stride, line, left
|
||||
movifnidn leftq, leftmp
|
||||
movd m0, [leftq]
|
||||
punpcklbw m0, m0
|
||||
punpcklbw m0, m0
|
||||
pshufd m1, m0, 0x1
|
||||
movd [dstq ], m0
|
||||
movd [dstq+strideq], m1
|
||||
pshufd m2, m0, 0x2
|
||||
lea dstq, [dstq+strideq*2]
|
||||
pshufd m3, m0, 0x3
|
||||
movd [dstq ], m2
|
||||
movd [dstq+strideq], m3
|
||||
RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal h_predictor_8x8, 2, 5, 3, dst, stride, line, left
|
||||
movifnidn leftq, leftmp
|
||||
mov lineq, -2
|
||||
DEFINE_ARGS dst, stride, line, left, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
movq m0, [leftq ]
|
||||
punpcklbw m0, m0 ; l1 l1 l2 l2 ... l8 l8
|
||||
.loop:
|
||||
pshuflw m1, m0, 0x0 ; l1 l1 l1 l1 l1 l1 l1 l1
|
||||
pshuflw m2, m0, 0x55 ; l2 l2 l2 l2 l2 l2 l2 l2
|
||||
movq [dstq ], m1
|
||||
movq [dstq+strideq], m2
|
||||
pshuflw m1, m0, 0xaa
|
||||
pshuflw m2, m0, 0xff
|
||||
movq [dstq+strideq*2], m1
|
||||
movq [dstq+stride3q ], m2
|
||||
pshufd m0, m0, 0xe ; [63:0] l5 l5 l6 l6 l7 l7 l8 l8
|
||||
inc lineq
|
||||
lea dstq, [dstq+strideq*4]
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal h_predictor_16x16, 2, 5, 3, dst, stride, line, left
|
||||
movifnidn leftq, leftmp
|
||||
mov lineq, -4
|
||||
DEFINE_ARGS dst, stride, line, left, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
.loop:
|
||||
movd m0, [leftq]
|
||||
punpcklbw m0, m0
|
||||
punpcklbw m0, m0 ; l1 to l4 each repeated 4 times
|
||||
pshufd m1, m0, 0x0 ; l1 repeated 16 times
|
||||
pshufd m2, m0, 0x55 ; l2 repeated 16 times
|
||||
mova [dstq ], m1
|
||||
mova [dstq+strideq ], m2
|
||||
pshufd m1, m0, 0xaa
|
||||
pshufd m2, m0, 0xff
|
||||
mova [dstq+strideq*2], m1
|
||||
mova [dstq+stride3q ], m2
|
||||
inc lineq
|
||||
lea leftq, [leftq+4 ]
|
||||
lea dstq, [dstq+strideq*4]
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
||||
INIT_XMM sse2
|
||||
cglobal h_predictor_32x32, 2, 5, 3, dst, stride, line, left
|
||||
movifnidn leftq, leftmp
|
||||
mov lineq, -8
|
||||
DEFINE_ARGS dst, stride, line, left, stride3
|
||||
lea stride3q, [strideq*3]
|
||||
.loop:
|
||||
movd m0, [leftq]
|
||||
punpcklbw m0, m0
|
||||
punpcklbw m0, m0 ; l1 to l4 each repeated 4 times
|
||||
pshufd m1, m0, 0x0 ; l1 repeated 16 times
|
||||
pshufd m2, m0, 0x55 ; l2 repeated 16 times
|
||||
mova [dstq ], m1
|
||||
mova [dstq+16 ], m1
|
||||
mova [dstq+strideq ], m2
|
||||
mova [dstq+strideq+16 ], m2
|
||||
pshufd m1, m0, 0xaa
|
||||
pshufd m2, m0, 0xff
|
||||
mova [dstq+strideq*2 ], m1
|
||||
mova [dstq+strideq*2+16], m1
|
||||
mova [dstq+stride3q ], m2
|
||||
mova [dstq+stride3q+16 ], m2
|
||||
inc lineq
|
||||
lea leftq, [leftq+4 ]
|
||||
lea dstq, [dstq+strideq*4]
|
||||
jnz .loop
|
||||
REP_RET
|
||||
|
|
@ -23,8 +23,8 @@ static INLINE __m128i abs_diff(__m128i a, __m128i b) {
|
|||
}
|
||||
|
||||
// this function treats its input as 2 parallel 8x4 matrices, transposes each of
|
||||
// them to 4x8 independently while flipping the second matrix horizontaly. Used
|
||||
// for 14 taps pq pairs creation
|
||||
// them to 4x8 independently while flipping the second matrix horizontally.
|
||||
// Used for 14 taps pq pairs creation
|
||||
static INLINE void transpose_pq_14_sse2(__m128i *x0, __m128i *x1, __m128i *x2,
|
||||
__m128i *x3, __m128i *q0p0,
|
||||
__m128i *q1p1, __m128i *q2p2,
|
||||
|
|
|
|||
48
third_party/aom/aom_dsp/x86/quantize_x86.h
vendored
48
third_party/aom/aom_dsp/x86/quantize_x86.h
vendored
|
|
@ -32,6 +32,11 @@ static INLINE __m128i invert_sign_sse2(__m128i a, __m128i sign) {
|
|||
return _mm_sub_epi16(a, sign);
|
||||
}
|
||||
|
||||
static INLINE __m128i invert_sign_32_sse2(__m128i a, __m128i sign) {
|
||||
a = _mm_xor_si128(a, sign);
|
||||
return _mm_sub_epi32(a, sign);
|
||||
}
|
||||
|
||||
static INLINE void calculate_qcoeff(__m128i *coeff, const __m128i round,
|
||||
const __m128i quant, const __m128i shift) {
|
||||
__m128i tmp, qcoeff;
|
||||
|
|
@ -41,10 +46,53 @@ static INLINE void calculate_qcoeff(__m128i *coeff, const __m128i round,
|
|||
*coeff = _mm_mulhi_epi16(qcoeff, shift);
|
||||
}
|
||||
|
||||
static INLINE void calculate_qcoeff_log_scale(__m128i *coeff,
|
||||
const __m128i round,
|
||||
const __m128i quant,
|
||||
const __m128i *shift,
|
||||
const int *log_scale) {
|
||||
__m128i tmp, tmp1, qcoeff;
|
||||
qcoeff = _mm_adds_epi16(*coeff, round);
|
||||
tmp = _mm_mulhi_epi16(qcoeff, quant);
|
||||
qcoeff = _mm_add_epi16(tmp, qcoeff);
|
||||
tmp = _mm_mullo_epi16(qcoeff, *shift);
|
||||
tmp = _mm_srli_epi16(tmp, (16 - *log_scale));
|
||||
tmp1 = _mm_mulhi_epi16(qcoeff, *shift);
|
||||
tmp1 = _mm_slli_epi16(tmp1, *log_scale);
|
||||
*coeff = _mm_or_si128(tmp, tmp1);
|
||||
}
|
||||
|
||||
static INLINE __m128i calculate_dqcoeff(__m128i qcoeff, __m128i dequant) {
|
||||
return _mm_mullo_epi16(qcoeff, dequant);
|
||||
}
|
||||
|
||||
static INLINE void calculate_dqcoeff_and_store_log_scale(__m128i qcoeff,
|
||||
__m128i dequant,
|
||||
const __m128i zero,
|
||||
tran_low_t *dqcoeff,
|
||||
const int *log_scale) {
|
||||
// calculate abs
|
||||
__m128i coeff_sign = _mm_srai_epi16(qcoeff, 15);
|
||||
__m128i coeff = invert_sign_sse2(qcoeff, coeff_sign);
|
||||
|
||||
const __m128i sign_0 = _mm_unpacklo_epi16(coeff_sign, zero);
|
||||
const __m128i sign_1 = _mm_unpackhi_epi16(coeff_sign, zero);
|
||||
|
||||
const __m128i low = _mm_mullo_epi16(coeff, dequant);
|
||||
const __m128i high = _mm_mulhi_epi16(coeff, dequant);
|
||||
__m128i dqcoeff32_0 = _mm_unpacklo_epi16(low, high);
|
||||
__m128i dqcoeff32_1 = _mm_unpackhi_epi16(low, high);
|
||||
|
||||
dqcoeff32_0 = _mm_srli_epi32(dqcoeff32_0, *log_scale);
|
||||
dqcoeff32_1 = _mm_srli_epi32(dqcoeff32_1, *log_scale);
|
||||
|
||||
dqcoeff32_0 = invert_sign_32_sse2(dqcoeff32_0, sign_0);
|
||||
dqcoeff32_1 = invert_sign_32_sse2(dqcoeff32_1, sign_1);
|
||||
|
||||
_mm_store_si128((__m128i *)(dqcoeff), dqcoeff32_0);
|
||||
_mm_store_si128((__m128i *)(dqcoeff + 4), dqcoeff32_1);
|
||||
}
|
||||
|
||||
// Scan 16 values for eob reference in scan_ptr. Use masks (-1) from comparing
|
||||
// to zbin to add 1 to the index in 'scan'.
|
||||
static INLINE __m128i scan_for_eob(__m128i *coeff0, __m128i *coeff1,
|
||||
|
|
|
|||
222
third_party/aom/aom_dsp/x86/ssim_opt_x86_64.asm
vendored
222
third_party/aom/aom_dsp/x86/ssim_opt_x86_64.asm
vendored
|
|
@ -1,222 +0,0 @@
|
|||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
%include "aom_ports/x86_abi_support.asm"
|
||||
|
||||
; tabulate_ssim - sums sum_s,sum_r,sum_sq_s,sum_sq_r, sum_sxr
|
||||
%macro TABULATE_SSIM 0
|
||||
paddusw xmm15, xmm3 ; sum_s
|
||||
paddusw xmm14, xmm4 ; sum_r
|
||||
movdqa xmm1, xmm3
|
||||
pmaddwd xmm1, xmm1
|
||||
paddd xmm13, xmm1 ; sum_sq_s
|
||||
movdqa xmm2, xmm4
|
||||
pmaddwd xmm2, xmm2
|
||||
paddd xmm12, xmm2 ; sum_sq_r
|
||||
pmaddwd xmm3, xmm4
|
||||
paddd xmm11, xmm3 ; sum_sxr
|
||||
%endmacro
|
||||
|
||||
; Sum across the register %1 starting with q words
|
||||
%macro SUM_ACROSS_Q 1
|
||||
movdqa xmm2,%1
|
||||
punpckldq %1,xmm0
|
||||
punpckhdq xmm2,xmm0
|
||||
paddq %1,xmm2
|
||||
movdqa xmm2,%1
|
||||
punpcklqdq %1,xmm0
|
||||
punpckhqdq xmm2,xmm0
|
||||
paddq %1,xmm2
|
||||
%endmacro
|
||||
|
||||
; Sum across the register %1 starting with q words
|
||||
%macro SUM_ACROSS_W 1
|
||||
movdqa xmm1, %1
|
||||
punpcklwd %1,xmm0
|
||||
punpckhwd xmm1,xmm0
|
||||
paddd %1, xmm1
|
||||
SUM_ACROSS_Q %1
|
||||
%endmacro
|
||||
|
||||
SECTION .text
|
||||
|
||||
;void ssim_parms_sse2(
|
||||
; unsigned char *s,
|
||||
; int sp,
|
||||
; unsigned char *r,
|
||||
; int rp
|
||||
; uint32_t *sum_s,
|
||||
; uint32_t *sum_r,
|
||||
; uint32_t *sum_sq_s,
|
||||
; uint32_t *sum_sq_r,
|
||||
; uint32_t *sum_sxr);
|
||||
;
|
||||
; TODO: Use parm passing through structure, probably don't need the pxors
|
||||
; ( calling app will initialize to 0 ) could easily fit everything in sse2
|
||||
; without too much hastle, and can probably do better estimates with psadw
|
||||
; or pavgb At this point this is just meant to be first pass for calculating
|
||||
; all the parms needed for 16x16 ssim so we can play with dssim as distortion
|
||||
; in mode selection code.
|
||||
global sym(aom_ssim_parms_16x16_sse2) PRIVATE
|
||||
sym(aom_ssim_parms_16x16_sse2):
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
SHADOW_ARGS_TO_STACK 9
|
||||
SAVE_XMM 15
|
||||
push rsi
|
||||
push rdi
|
||||
; end prolog
|
||||
|
||||
mov rsi, arg(0) ;s
|
||||
mov rcx, arg(1) ;sp
|
||||
mov rdi, arg(2) ;r
|
||||
mov rax, arg(3) ;rp
|
||||
|
||||
pxor xmm0, xmm0
|
||||
pxor xmm15,xmm15 ;sum_s
|
||||
pxor xmm14,xmm14 ;sum_r
|
||||
pxor xmm13,xmm13 ;sum_sq_s
|
||||
pxor xmm12,xmm12 ;sum_sq_r
|
||||
pxor xmm11,xmm11 ;sum_sxr
|
||||
|
||||
mov rdx, 16 ;row counter
|
||||
.NextRow:
|
||||
|
||||
;grab source and reference pixels
|
||||
movdqu xmm5, [rsi]
|
||||
movdqu xmm6, [rdi]
|
||||
movdqa xmm3, xmm5
|
||||
movdqa xmm4, xmm6
|
||||
punpckhbw xmm3, xmm0 ; high_s
|
||||
punpckhbw xmm4, xmm0 ; high_r
|
||||
|
||||
TABULATE_SSIM
|
||||
|
||||
movdqa xmm3, xmm5
|
||||
movdqa xmm4, xmm6
|
||||
punpcklbw xmm3, xmm0 ; low_s
|
||||
punpcklbw xmm4, xmm0 ; low_r
|
||||
|
||||
TABULATE_SSIM
|
||||
|
||||
add rsi, rcx ; next s row
|
||||
add rdi, rax ; next r row
|
||||
|
||||
dec rdx ; counter
|
||||
jnz .NextRow
|
||||
|
||||
SUM_ACROSS_W xmm15
|
||||
SUM_ACROSS_W xmm14
|
||||
SUM_ACROSS_Q xmm13
|
||||
SUM_ACROSS_Q xmm12
|
||||
SUM_ACROSS_Q xmm11
|
||||
|
||||
mov rdi,arg(4)
|
||||
movd [rdi], xmm15;
|
||||
mov rdi,arg(5)
|
||||
movd [rdi], xmm14;
|
||||
mov rdi,arg(6)
|
||||
movd [rdi], xmm13;
|
||||
mov rdi,arg(7)
|
||||
movd [rdi], xmm12;
|
||||
mov rdi,arg(8)
|
||||
movd [rdi], xmm11;
|
||||
|
||||
; begin epilog
|
||||
pop rdi
|
||||
pop rsi
|
||||
RESTORE_XMM
|
||||
UNSHADOW_ARGS
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
;void ssim_parms_sse2(
|
||||
; unsigned char *s,
|
||||
; int sp,
|
||||
; unsigned char *r,
|
||||
; int rp
|
||||
; uint32_t *sum_s,
|
||||
; uint32_t *sum_r,
|
||||
; uint32_t *sum_sq_s,
|
||||
; uint32_t *sum_sq_r,
|
||||
; uint32_t *sum_sxr);
|
||||
;
|
||||
; TODO: Use parm passing through structure, probably don't need the pxors
|
||||
; ( calling app will initialize to 0 ) could easily fit everything in sse2
|
||||
; without too much hastle, and can probably do better estimates with psadw
|
||||
; or pavgb At this point this is just meant to be first pass for calculating
|
||||
; all the parms needed for 16x16 ssim so we can play with dssim as distortion
|
||||
; in mode selection code.
|
||||
global sym(aom_ssim_parms_8x8_sse2) PRIVATE
|
||||
sym(aom_ssim_parms_8x8_sse2):
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
SHADOW_ARGS_TO_STACK 9
|
||||
SAVE_XMM 15
|
||||
push rsi
|
||||
push rdi
|
||||
; end prolog
|
||||
|
||||
mov rsi, arg(0) ;s
|
||||
mov rcx, arg(1) ;sp
|
||||
mov rdi, arg(2) ;r
|
||||
mov rax, arg(3) ;rp
|
||||
|
||||
pxor xmm0, xmm0
|
||||
pxor xmm15,xmm15 ;sum_s
|
||||
pxor xmm14,xmm14 ;sum_r
|
||||
pxor xmm13,xmm13 ;sum_sq_s
|
||||
pxor xmm12,xmm12 ;sum_sq_r
|
||||
pxor xmm11,xmm11 ;sum_sxr
|
||||
|
||||
mov rdx, 8 ;row counter
|
||||
.NextRow:
|
||||
|
||||
;grab source and reference pixels
|
||||
movq xmm3, [rsi]
|
||||
movq xmm4, [rdi]
|
||||
punpcklbw xmm3, xmm0 ; low_s
|
||||
punpcklbw xmm4, xmm0 ; low_r
|
||||
|
||||
TABULATE_SSIM
|
||||
|
||||
add rsi, rcx ; next s row
|
||||
add rdi, rax ; next r row
|
||||
|
||||
dec rdx ; counter
|
||||
jnz .NextRow
|
||||
|
||||
SUM_ACROSS_W xmm15
|
||||
SUM_ACROSS_W xmm14
|
||||
SUM_ACROSS_Q xmm13
|
||||
SUM_ACROSS_Q xmm12
|
||||
SUM_ACROSS_Q xmm11
|
||||
|
||||
mov rdi,arg(4)
|
||||
movd [rdi], xmm15;
|
||||
mov rdi,arg(5)
|
||||
movd [rdi], xmm14;
|
||||
mov rdi,arg(6)
|
||||
movd [rdi], xmm13;
|
||||
mov rdi,arg(7)
|
||||
movd [rdi], xmm12;
|
||||
mov rdi,arg(8)
|
||||
movd [rdi], xmm11;
|
||||
|
||||
; begin epilog
|
||||
pop rdi
|
||||
pop rsi
|
||||
RESTORE_XMM
|
||||
UNSHADOW_ARGS
|
||||
pop rbp
|
||||
ret
|
||||
90
third_party/aom/aom_dsp/x86/txfm_common_avx2.h
vendored
90
third_party/aom/aom_dsp/x86/txfm_common_avx2.h
vendored
|
|
@ -168,6 +168,36 @@ static INLINE void transpose_16bit_16x16_avx2(const __m256i *const in,
|
|||
out[7 + 8] = _mm256_permute2x128_si256(c[12 + 2], c[13 + 2], 0x31);
|
||||
}
|
||||
|
||||
static INLINE void transpose_16bit_16x8_avx2(const __m256i *const in,
|
||||
__m256i *const out) {
|
||||
const __m256i a0 = _mm256_unpacklo_epi16(in[0], in[1]);
|
||||
const __m256i a1 = _mm256_unpacklo_epi16(in[2], in[3]);
|
||||
const __m256i a2 = _mm256_unpacklo_epi16(in[4], in[5]);
|
||||
const __m256i a3 = _mm256_unpacklo_epi16(in[6], in[7]);
|
||||
const __m256i a4 = _mm256_unpackhi_epi16(in[0], in[1]);
|
||||
const __m256i a5 = _mm256_unpackhi_epi16(in[2], in[3]);
|
||||
const __m256i a6 = _mm256_unpackhi_epi16(in[4], in[5]);
|
||||
const __m256i a7 = _mm256_unpackhi_epi16(in[6], in[7]);
|
||||
|
||||
const __m256i b0 = _mm256_unpacklo_epi32(a0, a1);
|
||||
const __m256i b1 = _mm256_unpacklo_epi32(a2, a3);
|
||||
const __m256i b2 = _mm256_unpacklo_epi32(a4, a5);
|
||||
const __m256i b3 = _mm256_unpacklo_epi32(a6, a7);
|
||||
const __m256i b4 = _mm256_unpackhi_epi32(a0, a1);
|
||||
const __m256i b5 = _mm256_unpackhi_epi32(a2, a3);
|
||||
const __m256i b6 = _mm256_unpackhi_epi32(a4, a5);
|
||||
const __m256i b7 = _mm256_unpackhi_epi32(a6, a7);
|
||||
|
||||
out[0] = _mm256_unpacklo_epi64(b0, b1);
|
||||
out[1] = _mm256_unpackhi_epi64(b0, b1);
|
||||
out[2] = _mm256_unpacklo_epi64(b4, b5);
|
||||
out[3] = _mm256_unpackhi_epi64(b4, b5);
|
||||
out[4] = _mm256_unpacklo_epi64(b2, b3);
|
||||
out[5] = _mm256_unpackhi_epi64(b2, b3);
|
||||
out[6] = _mm256_unpacklo_epi64(b6, b7);
|
||||
out[7] = _mm256_unpackhi_epi64(b6, b7);
|
||||
}
|
||||
|
||||
static INLINE void flip_buf_avx2(__m256i *in, __m256i *out, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
out[size - i - 1] = in[i];
|
||||
|
|
@ -236,6 +266,66 @@ static INLINE void av1_round_shift_rect_array_32_avx2(__m256i *input,
|
|||
}
|
||||
}
|
||||
|
||||
static INLINE __m256i scale_round_avx2(const __m256i a, const int scale) {
|
||||
const __m256i scale_rounding =
|
||||
pair_set_w16_epi16(scale, 1 << (NewSqrt2Bits - 1));
|
||||
const __m256i b = _mm256_madd_epi16(a, scale_rounding);
|
||||
return _mm256_srai_epi32(b, NewSqrt2Bits);
|
||||
}
|
||||
|
||||
static INLINE void store_rect_16bit_to_32bit_w8_avx2(const __m256i a,
|
||||
int32_t *const b) {
|
||||
const __m256i one = _mm256_set1_epi16(1);
|
||||
const __m256i a_lo = _mm256_unpacklo_epi16(a, one);
|
||||
const __m256i a_hi = _mm256_unpackhi_epi16(a, one);
|
||||
const __m256i b_lo = scale_round_avx2(a_lo, NewSqrt2);
|
||||
const __m256i b_hi = scale_round_avx2(a_hi, NewSqrt2);
|
||||
const __m256i temp = _mm256_permute2f128_si256(b_lo, b_hi, 0x31);
|
||||
_mm_store_si128((__m128i *)b, _mm256_castsi256_si128(b_lo));
|
||||
_mm_store_si128((__m128i *)(b + 4), _mm256_castsi256_si128(b_hi));
|
||||
_mm256_store_si256((__m256i *)(b + 64), temp);
|
||||
}
|
||||
|
||||
static INLINE void store_rect_buffer_16bit_to_32bit_w8_avx2(
|
||||
const __m256i *const in, int32_t *const out, const int stride,
|
||||
const int out_size) {
|
||||
for (int i = 0; i < out_size; ++i) {
|
||||
store_rect_16bit_to_32bit_w8_avx2(in[i], out + i * stride);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void pack_reg(const __m128i *in1, const __m128i *in2,
|
||||
__m256i *out) {
|
||||
out[0] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[0]), in2[0], 0x1);
|
||||
out[1] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[1]), in2[1], 0x1);
|
||||
out[2] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[2]), in2[2], 0x1);
|
||||
out[3] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[3]), in2[3], 0x1);
|
||||
out[4] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[4]), in2[4], 0x1);
|
||||
out[5] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[5]), in2[5], 0x1);
|
||||
out[6] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[6]), in2[6], 0x1);
|
||||
out[7] = _mm256_insertf128_si256(_mm256_castsi128_si256(in1[7]), in2[7], 0x1);
|
||||
}
|
||||
|
||||
static INLINE void extract_reg(const __m256i *in, __m128i *out1) {
|
||||
out1[0] = _mm256_castsi256_si128(in[0]);
|
||||
out1[1] = _mm256_castsi256_si128(in[1]);
|
||||
out1[2] = _mm256_castsi256_si128(in[2]);
|
||||
out1[3] = _mm256_castsi256_si128(in[3]);
|
||||
out1[4] = _mm256_castsi256_si128(in[4]);
|
||||
out1[5] = _mm256_castsi256_si128(in[5]);
|
||||
out1[6] = _mm256_castsi256_si128(in[6]);
|
||||
out1[7] = _mm256_castsi256_si128(in[7]);
|
||||
|
||||
out1[8] = _mm256_extracti128_si256(in[0], 0x01);
|
||||
out1[9] = _mm256_extracti128_si256(in[1], 0x01);
|
||||
out1[10] = _mm256_extracti128_si256(in[2], 0x01);
|
||||
out1[11] = _mm256_extracti128_si256(in[3], 0x01);
|
||||
out1[12] = _mm256_extracti128_si256(in[4], 0x01);
|
||||
out1[13] = _mm256_extracti128_si256(in[5], 0x01);
|
||||
out1[14] = _mm256_extracti128_si256(in[6], 0x01);
|
||||
out1[15] = _mm256_extracti128_si256(in[7], 0x01);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
4
third_party/aom/aom_scale/aom_scale.cmake
vendored
4
third_party/aom/aom_scale/aom_scale.cmake
vendored
|
|
@ -34,5 +34,9 @@ function(setup_aom_scale_targets)
|
|||
"AOM_SCALE_INTRIN_DSPR2" "aom")
|
||||
endif()
|
||||
|
||||
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} aom_scale PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
|
|
|||
2
third_party/aom/aom_scale/aom_scale_rtcd.pl
vendored
2
third_party/aom/aom_scale/aom_scale_rtcd.pl
vendored
|
|
@ -26,6 +26,8 @@ if (aom_config("CONFIG_SPATIAL_RESAMPLING") eq "yes") {
|
|||
add_proto qw/void aom_vertical_band_2_1_scale_i/, "unsigned char *source, int src_pitch, unsigned char *dest, int dest_pitch, unsigned int dest_width";
|
||||
}
|
||||
|
||||
add_proto qw/int aom_yv12_realloc_with_new_border/, "struct yv12_buffer_config *ybf, int new_border, int byte_alignment, int num_planes";
|
||||
|
||||
add_proto qw/void aom_yv12_extend_frame_borders/, "struct yv12_buffer_config *ybf, const int num_planes";
|
||||
|
||||
add_proto qw/void aom_yv12_copy_frame/, "const struct yv12_buffer_config *src_bc, struct yv12_buffer_config *dst_bc, const int num_planes";
|
||||
|
|
|
|||
142
third_party/aom/aom_scale/generic/yv12config.c
vendored
142
third_party/aom/aom_scale/generic/yv12config.c
vendored
|
|
@ -46,37 +46,16 @@ int aom_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int aom_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
||||
int ss_x, int ss_y, int use_highbitdepth,
|
||||
int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb,
|
||||
aom_get_frame_buffer_cb_fn_t cb, void *cb_priv) {
|
||||
#if CONFIG_SIZE_LIMIT
|
||||
if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT) return -1;
|
||||
#endif
|
||||
|
||||
/* Only support allocating buffers that have a border that's a multiple
|
||||
* of 32. The border restriction is required to get 16-byte alignment of
|
||||
* the start of the chroma rows without introducing an arbitrary gap
|
||||
* between planes, which would break the semantics of things like
|
||||
* aom_img_set_rect(). */
|
||||
if (border & 0x1f) return -3;
|
||||
|
||||
static int realloc_frame_buffer_aligned(
|
||||
YV12_BUFFER_CONFIG *ybf, int width, int height, int ss_x, int ss_y,
|
||||
int use_highbitdepth, int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb, aom_get_frame_buffer_cb_fn_t cb,
|
||||
void *cb_priv, const int y_stride, const uint64_t yplane_size,
|
||||
const uint64_t uvplane_size, const int aligned_width,
|
||||
const int aligned_height, const int uv_width, const int uv_height,
|
||||
const int uv_stride, const int uv_border_w, const int uv_border_h) {
|
||||
if (ybf) {
|
||||
const int aom_byte_align = (byte_alignment == 0) ? 1 : byte_alignment;
|
||||
const int aligned_width = (width + 7) & ~7;
|
||||
const int aligned_height = (height + 7) & ~7;
|
||||
const int y_stride = ((aligned_width + 2 * border) + 31) & ~31;
|
||||
const uint64_t yplane_size =
|
||||
(aligned_height + 2 * border) * (uint64_t)y_stride + byte_alignment;
|
||||
const int uv_width = aligned_width >> ss_x;
|
||||
const int uv_height = aligned_height >> ss_y;
|
||||
const int uv_stride = y_stride >> ss_x;
|
||||
const int uv_border_w = border >> ss_x;
|
||||
const int uv_border_h = border >> ss_y;
|
||||
const uint64_t uvplane_size =
|
||||
(uv_height + 2 * uv_border_h) * (uint64_t)uv_stride + byte_alignment;
|
||||
|
||||
const uint64_t frame_size =
|
||||
(1 + use_highbitdepth) * (yplane_size + 2 * uvplane_size);
|
||||
|
||||
|
|
@ -191,6 +170,111 @@ int aom_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
|||
return -2;
|
||||
}
|
||||
|
||||
static int calc_stride_and_planesize(const int ss_x, const int ss_y,
|
||||
const int aligned_width,
|
||||
const int aligned_height, const int border,
|
||||
const int byte_alignment, int *y_stride,
|
||||
int *uv_stride, uint64_t *yplane_size,
|
||||
uint64_t *uvplane_size,
|
||||
const int uv_height) {
|
||||
/* Only support allocating buffers that have a border that's a multiple
|
||||
* of 32. The border restriction is required to get 16-byte alignment of
|
||||
* the start of the chroma rows without introducing an arbitrary gap
|
||||
* between planes, which would break the semantics of things like
|
||||
* aom_img_set_rect(). */
|
||||
if (border & 0x1f) return -3;
|
||||
*y_stride = ((aligned_width + 2 * border) + 31) & ~31;
|
||||
*yplane_size =
|
||||
(aligned_height + 2 * border) * (uint64_t)(*y_stride) + byte_alignment;
|
||||
|
||||
*uv_stride = *y_stride >> ss_x;
|
||||
*uvplane_size = (uv_height + 2 * (border >> ss_y)) * (uint64_t)(*uv_stride) +
|
||||
byte_alignment;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aom_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
||||
int ss_x, int ss_y, int use_highbitdepth,
|
||||
int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb,
|
||||
aom_get_frame_buffer_cb_fn_t cb, void *cb_priv) {
|
||||
#if CONFIG_SIZE_LIMIT
|
||||
if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT) return -1;
|
||||
#endif
|
||||
|
||||
if (ybf) {
|
||||
int y_stride = 0;
|
||||
int uv_stride = 0;
|
||||
uint64_t yplane_size = 0;
|
||||
uint64_t uvplane_size = 0;
|
||||
const int aligned_width = (width + 7) & ~7;
|
||||
const int aligned_height = (height + 7) & ~7;
|
||||
const int uv_width = aligned_width >> ss_x;
|
||||
const int uv_height = aligned_height >> ss_y;
|
||||
const int uv_border_w = border >> ss_x;
|
||||
const int uv_border_h = border >> ss_y;
|
||||
|
||||
int error = calc_stride_and_planesize(
|
||||
ss_x, ss_y, aligned_width, aligned_height, border, byte_alignment,
|
||||
&y_stride, &uv_stride, &yplane_size, &uvplane_size, uv_height);
|
||||
if (error) return error;
|
||||
return realloc_frame_buffer_aligned(
|
||||
ybf, width, height, ss_x, ss_y, use_highbitdepth, border,
|
||||
byte_alignment, fb, cb, cb_priv, y_stride, yplane_size, uvplane_size,
|
||||
aligned_width, aligned_height, uv_width, uv_height, uv_stride,
|
||||
uv_border_w, uv_border_h);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
// TODO(anyone): This function allocates memory for
|
||||
// lookahead buffer considering height and width is
|
||||
// aligned to 128. Currently variance calculation of
|
||||
// simple_motion_search_get_best_ref() function is done
|
||||
// for full sb size (i.e integral multiple of max sb
|
||||
// size = 128 or 64). Hence partial sbs need up to 127
|
||||
// pixels beyond frame boundary. 128 aligned limitation of
|
||||
// lookahead buffer can be removed if variance calculation
|
||||
// is adjusted for partial sbs
|
||||
|
||||
// NOTE: Chroma width and height need not be aligned to
|
||||
// 128 since variance calculation happens only for luma plane
|
||||
int aom_realloc_lookahead_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
||||
int ss_x, int ss_y, int use_highbitdepth,
|
||||
int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb,
|
||||
aom_get_frame_buffer_cb_fn_t cb,
|
||||
void *cb_priv) {
|
||||
if (ybf) {
|
||||
int y_stride = 0;
|
||||
int uv_stride = 0;
|
||||
uint64_t yplane_size = 0;
|
||||
uint64_t uvplane_size = 0;
|
||||
const int aligned_128_width = (width + 127) & ~127;
|
||||
const int aligned_128_height = (height + 127) & ~127;
|
||||
const int aligned_width = (width + 7) & ~7;
|
||||
const int aligned_height = (height + 7) & ~7;
|
||||
const int uv_64_height = aligned_128_height >> ss_y;
|
||||
const int uv_width = aligned_width >> ss_x;
|
||||
const int uv_height = aligned_height >> ss_y;
|
||||
const int uv_border_w = border >> ss_x;
|
||||
const int uv_border_h = border >> ss_y;
|
||||
|
||||
int error = calc_stride_and_planesize(
|
||||
ss_x, ss_y, aligned_128_width, aligned_128_height, border,
|
||||
byte_alignment, &y_stride, &uv_stride, &yplane_size, &uvplane_size,
|
||||
uv_64_height);
|
||||
if (error) return error;
|
||||
|
||||
return realloc_frame_buffer_aligned(
|
||||
ybf, width, height, ss_x, ss_y, use_highbitdepth, border,
|
||||
byte_alignment, fb, cb, cb_priv, y_stride, yplane_size, uvplane_size,
|
||||
aligned_width, aligned_height, uv_width, uv_height, uv_stride,
|
||||
uv_border_w, uv_border_h);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
int aom_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
||||
int ss_x, int ss_y, int use_highbitdepth, int border,
|
||||
int byte_alignment) {
|
||||
|
|
|
|||
25
third_party/aom/aom_scale/generic/yv12extend.c
vendored
25
third_party/aom/aom_scale/generic/yv12extend.c
vendored
|
|
@ -434,3 +434,28 @@ void aom_yv12_partial_coloc_copy_v_c(const YV12_BUFFER_CONFIG *src_bc,
|
|||
aom_yv12_partial_copy_v_c(src_bc, hstart, hend, vstart, vend, dst_bc, hstart,
|
||||
vstart);
|
||||
}
|
||||
|
||||
int aom_yv12_realloc_with_new_border_c(YV12_BUFFER_CONFIG *ybf, int new_border,
|
||||
int byte_alignment, int num_planes) {
|
||||
if (ybf) {
|
||||
if (new_border == ybf->border) return 0;
|
||||
YV12_BUFFER_CONFIG new_buf;
|
||||
memset(&new_buf, 0, sizeof(new_buf));
|
||||
const int error = aom_alloc_frame_buffer(
|
||||
&new_buf, ybf->y_crop_width, ybf->y_crop_height, ybf->subsampling_x,
|
||||
ybf->subsampling_y, ybf->flags & YV12_FLAG_HIGHBITDEPTH, new_border,
|
||||
byte_alignment);
|
||||
if (error) return error;
|
||||
// Copy image buffer
|
||||
aom_yv12_copy_frame(ybf, &new_buf, num_planes);
|
||||
|
||||
// Extend up to new border
|
||||
aom_extend_frame_borders(&new_buf, num_planes);
|
||||
|
||||
// Now free the old buffer and replace with the new
|
||||
aom_free_frame_buffer(ybf);
|
||||
memcpy(ybf, &new_buf, sizeof(new_buf));
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
|
|
|||
9
third_party/aom/aom_scale/yv12config.h
vendored
9
third_party/aom/aom_scale/yv12config.h
vendored
|
|
@ -26,6 +26,7 @@ extern "C" {
|
|||
#define AOM_INTERP_EXTEND 4
|
||||
#define AOM_BORDER_IN_PIXELS 288
|
||||
#define AOM_ENC_NO_SCALE_BORDER 160
|
||||
#define AOM_ENC_LOOKAHEAD_BORDER 64
|
||||
#define AOM_DEC_BORDER_IN_PIXELS 64
|
||||
|
||||
typedef struct yv12_buffer_config {
|
||||
|
|
@ -124,6 +125,14 @@ int aom_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
|||
int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb,
|
||||
aom_get_frame_buffer_cb_fn_t cb, void *cb_priv);
|
||||
|
||||
int aom_realloc_lookahead_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height,
|
||||
int ss_x, int ss_y, int use_highbitdepth,
|
||||
int border, int byte_alignment,
|
||||
aom_codec_frame_buffer_t *fb,
|
||||
aom_get_frame_buffer_cb_fn_t cb,
|
||||
void *cb_priv);
|
||||
|
||||
int aom_free_frame_buffer(YV12_BUFFER_CONFIG *ybf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
2
third_party/aom/apps/aomdec.c
vendored
2
third_party/aom/apps/aomdec.c
vendored
|
|
@ -851,7 +851,7 @@ static int main_loop(int argc, const char **argv_) {
|
|||
}
|
||||
// Default to codec bit depth if output bit depth not set
|
||||
unsigned int output_bit_depth;
|
||||
if (!fixed_output_bit_depth && single_file && !do_md5) {
|
||||
if (!fixed_output_bit_depth && single_file) {
|
||||
output_bit_depth = img->bit_depth;
|
||||
} else {
|
||||
output_bit_depth = fixed_output_bit_depth;
|
||||
|
|
|
|||
176
third_party/aom/apps/aomenc.c
vendored
176
third_party/aom/apps/aomenc.c
vendored
|
|
@ -144,16 +144,14 @@ static const arg_def_t pass_arg =
|
|||
ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
|
||||
static const arg_def_t fpf_name =
|
||||
ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
|
||||
#if CONFIG_FP_MB_STATS
|
||||
static const arg_def_t fpmbf_name =
|
||||
ARG_DEF(NULL, "fpmbf", 1, "First pass block statistics file name");
|
||||
#endif
|
||||
static const arg_def_t limit =
|
||||
ARG_DEF(NULL, "limit", 1, "Stop encoding after n input frames");
|
||||
static const arg_def_t skip =
|
||||
ARG_DEF(NULL, "skip", 1, "Skip the first n input frames");
|
||||
static const arg_def_t good_dl =
|
||||
ARG_DEF(NULL, "good", 0, "Use Good Quality Deadline");
|
||||
static const arg_def_t rt_dl =
|
||||
ARG_DEF(NULL, "rt", 0, "Use Realtime Quality Deadline");
|
||||
static const arg_def_t quietarg =
|
||||
ARG_DEF("q", "quiet", 0, "Do not print encode progress");
|
||||
static const arg_def_t verbosearg =
|
||||
|
|
@ -219,6 +217,7 @@ static const arg_def_t *main_args[] = { &help,
|
|||
&limit,
|
||||
&skip,
|
||||
&good_dl,
|
||||
&rt_dl,
|
||||
&quietarg,
|
||||
&verbosearg,
|
||||
&psnrarg,
|
||||
|
|
@ -441,6 +440,21 @@ static const arg_def_t enable_rect_partitions =
|
|||
ARG_DEF(NULL, "enable-rect-partitions", 1,
|
||||
"Enable rectangular partitions "
|
||||
"(0: false, 1: true (default))");
|
||||
static const arg_def_t enable_ab_partitions =
|
||||
ARG_DEF(NULL, "enable-ab-partitions", 1,
|
||||
"Enable ab partitions (0: false, 1: true (default))");
|
||||
static const arg_def_t enable_1to4_partitions =
|
||||
ARG_DEF(NULL, "enable-1to4-partitions", 1,
|
||||
"Enable 1:4 and 4:1 partitions "
|
||||
"(0: false, 1: true (default))");
|
||||
static const arg_def_t min_partition_size =
|
||||
ARG_DEF(NULL, "min-partition-size", 4,
|
||||
"Set min partition size "
|
||||
"(4:4x4, 8:8x8, 16:16x16, 32:32x32, 64:64x64, 128:128x128)");
|
||||
static const arg_def_t max_partition_size =
|
||||
ARG_DEF(NULL, "max-partition-size", 128,
|
||||
"Set max partition size "
|
||||
"(4:4x4, 8:8x8, 16:16x16, 32:32x32, 64:64x64, 128:128x128)");
|
||||
static const arg_def_t enable_dual_filter =
|
||||
ARG_DEF(NULL, "enable-dual-filter", 1,
|
||||
"Enable dual filter "
|
||||
|
|
@ -456,6 +470,16 @@ static const arg_def_t enable_order_hint =
|
|||
static const arg_def_t enable_tx64 =
|
||||
ARG_DEF(NULL, "enable-tx64", 1,
|
||||
"Enable 64-pt transform (0: false, 1: true (default))");
|
||||
static const arg_def_t tx_size_search_method =
|
||||
ARG_DEF(NULL, "tx-size-search-method", 0,
|
||||
"Set transform block size search method "
|
||||
"(0: Full RD (default), 1: Fast RD, 2: use largest allowed)");
|
||||
static const arg_def_t enable_flip_idtx =
|
||||
ARG_DEF(NULL, "enable-flip-idtx", 1,
|
||||
"Enable extended transform type (0: false, 1: true (default)) "
|
||||
"including FLIPADST_DCT, DCT_FLIPADST, FLIPADST_FLIPADST, "
|
||||
"ADST_FLIPADST, FLIPADST_ADST, IDTX, V_DCT, H_DCT, V_ADST, "
|
||||
"H_ADST, V_FLIPADST, H_FLIPADST");
|
||||
static const arg_def_t enable_dist_wtd_comp =
|
||||
ARG_DEF(NULL, "enable-dist-wtd-comp", 1,
|
||||
"Enable distance-weighted compound "
|
||||
|
|
@ -464,6 +488,10 @@ static const arg_def_t enable_masked_comp =
|
|||
ARG_DEF(NULL, "enable-masked-comp", 1,
|
||||
"Enable masked (wedge/diff-wtd) compound "
|
||||
"(0: false, 1: true (default))");
|
||||
static const arg_def_t enable_onesided_comp =
|
||||
ARG_DEF(NULL, "enable-onesided-comp", 1,
|
||||
"Enable one sided compound "
|
||||
"(0: false, 1: true (default))");
|
||||
static const arg_def_t enable_interintra_comp =
|
||||
ARG_DEF(NULL, "enable-interintra-comp", 1,
|
||||
"Enable interintra compound "
|
||||
|
|
@ -522,7 +550,7 @@ static const arg_def_t enable_angle_delta =
|
|||
static const arg_def_t disable_trellis_quant =
|
||||
ARG_DEF(NULL, "disable-trellis-quant", 1,
|
||||
"Disable trellis optimization of quantized coefficients (0: false ("
|
||||
"default) 1: true)");
|
||||
"default) 1: true 2: partial true)");
|
||||
static const arg_def_t enable_qm =
|
||||
ARG_DEF(NULL, "enable-qm", 1,
|
||||
"Enable quantisation matrices (0: false (default), 1: true)");
|
||||
|
|
@ -536,8 +564,19 @@ static const arg_def_t use_intra_dct_only =
|
|||
ARG_DEF(NULL, "use-intra-dct-only", 1, "Use DCT only for INTRA modes");
|
||||
static const arg_def_t use_inter_dct_only =
|
||||
ARG_DEF(NULL, "use-inter-dct-only", 1, "Use DCT only for INTER modes");
|
||||
static const arg_def_t use_intra_default_tx_only =
|
||||
ARG_DEF(NULL, "use-intra-default-tx-only", 1,
|
||||
"Use Default-transform only for INTRA modes");
|
||||
static const arg_def_t quant_b_adapt =
|
||||
ARG_DEF(NULL, "quant-b-adapt", 1, "Use adaptive quantize_b");
|
||||
static const arg_def_t coeff_cost_upd_freq =
|
||||
ARG_DEF(NULL, "coeff-cost-upd-freq", 1,
|
||||
"Update freq for coeff costs"
|
||||
"0: SB, 1: SB Row per Tile, 2: Tile");
|
||||
static const arg_def_t mode_cost_upd_freq =
|
||||
ARG_DEF(NULL, "mode-cost-upd-freq", 1,
|
||||
"Update freq for mode costs"
|
||||
"0: SB, 1: SB Row per Tile, 2: Tile");
|
||||
#if CONFIG_DIST_8X8
|
||||
static const arg_def_t enable_dist_8x8 =
|
||||
ARG_DEF(NULL, "enable-dist-8x8", 1,
|
||||
|
|
@ -607,10 +646,23 @@ static const arg_def_t max_gf_interval = ARG_DEF(
|
|||
"max gf/arf frame interval (default 0, indicating in-built behavior)");
|
||||
static const arg_def_t gf_max_pyr_height =
|
||||
ARG_DEF(NULL, "gf-max-pyr-height", 1,
|
||||
"maximum height for GF group pyramid structure (1 to 4 (default))");
|
||||
"maximum height for GF group pyramid structure (0 to 4 (default))");
|
||||
static const arg_def_t max_reference_frames = ARG_DEF(
|
||||
NULL, "max-reference-frames", 1,
|
||||
"maximum number of reference frames allowed per frame (3 to 7 (default))");
|
||||
static const arg_def_t reduced_reference_set =
|
||||
ARG_DEF(NULL, "reduced-reference-set", 1,
|
||||
"Use reduced set of single and compound references (0: off "
|
||||
"(default), 1: on)");
|
||||
static const arg_def_t target_seq_level_idx =
|
||||
ARG_DEF(NULL, "target-seq-level-idx", 1,
|
||||
"Target sequence level index. "
|
||||
"Possible values are in the form of \"ABxy\"(pad leading zeros if "
|
||||
"less than 4 digits). "
|
||||
"AB: Operating point(OP) index; "
|
||||
"xy: Target level index for the OP. "
|
||||
"E.g. \"0\" means target level index 0 for the 0th OP; "
|
||||
"\"1021\" means target level index 21 for the 10th OP.");
|
||||
|
||||
static const struct arg_enum_list color_primaries_enum[] = {
|
||||
{ "bt709", AOM_CICP_CP_BT_709 },
|
||||
|
|
@ -716,6 +768,12 @@ static const struct arg_enum_list superblock_size_enum[] = {
|
|||
static const arg_def_t superblock_size = ARG_DEF_ENUM(
|
||||
NULL, "sb-size", 1, "Superblock size to use", superblock_size_enum);
|
||||
|
||||
static const arg_def_t set_tier_mask =
|
||||
ARG_DEF(NULL, "set-tier-mask", 1,
|
||||
"Set bit mask to specify which tier each of the 32 possible "
|
||||
"operating points conforms to. "
|
||||
"Bit value 0(defualt): Main Tier; 1: High Tier.");
|
||||
|
||||
static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
||||
&auto_altref,
|
||||
&sharpness,
|
||||
|
|
@ -735,12 +793,19 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
|||
&enable_cdef,
|
||||
&enable_restoration,
|
||||
&enable_rect_partitions,
|
||||
&enable_ab_partitions,
|
||||
&enable_1to4_partitions,
|
||||
&min_partition_size,
|
||||
&max_partition_size,
|
||||
&enable_dual_filter,
|
||||
&enable_intra_edge_filter,
|
||||
&enable_order_hint,
|
||||
&enable_tx64,
|
||||
&tx_size_search_method,
|
||||
&enable_flip_idtx,
|
||||
&enable_dist_wtd_comp,
|
||||
&enable_masked_comp,
|
||||
&enable_onesided_comp,
|
||||
&enable_interintra_comp,
|
||||
&enable_smooth_interintra,
|
||||
&enable_diff_wtd_comp,
|
||||
|
|
@ -763,7 +828,10 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
|||
&reduced_tx_type_set,
|
||||
&use_intra_dct_only,
|
||||
&use_inter_dct_only,
|
||||
&use_intra_default_tx_only,
|
||||
&quant_b_adapt,
|
||||
&coeff_cost_upd_freq,
|
||||
&mode_cost_upd_freq,
|
||||
#if CONFIG_DIST_8X8
|
||||
&enable_dist_8x8,
|
||||
#endif
|
||||
|
|
@ -793,7 +861,10 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
|
|||
&denoise_block_size,
|
||||
#endif // CONFIG_DENOISE
|
||||
&max_reference_frames,
|
||||
&reduced_reference_set,
|
||||
&enable_ref_frame_mvs,
|
||||
&target_seq_level_idx,
|
||||
&set_tier_mask,
|
||||
&bitdeptharg,
|
||||
&inbitdeptharg,
|
||||
&input_chroma_subsampling_x,
|
||||
|
|
@ -821,12 +892,19 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
|
|||
AV1E_SET_ENABLE_CDEF,
|
||||
AV1E_SET_ENABLE_RESTORATION,
|
||||
AV1E_SET_ENABLE_RECT_PARTITIONS,
|
||||
AV1E_SET_ENABLE_AB_PARTITIONS,
|
||||
AV1E_SET_ENABLE_1TO4_PARTITIONS,
|
||||
AV1E_SET_MIN_PARTITION_SIZE,
|
||||
AV1E_SET_MAX_PARTITION_SIZE,
|
||||
AV1E_SET_ENABLE_DUAL_FILTER,
|
||||
AV1E_SET_ENABLE_INTRA_EDGE_FILTER,
|
||||
AV1E_SET_ENABLE_ORDER_HINT,
|
||||
AV1E_SET_ENABLE_TX64,
|
||||
AV1E_SET_TX_SIZE_SEARCH_METHOD,
|
||||
AV1E_SET_ENABLE_FLIP_IDTX,
|
||||
AV1E_SET_ENABLE_DIST_WTD_COMP,
|
||||
AV1E_SET_ENABLE_MASKED_COMP,
|
||||
AV1E_SET_ENABLE_ONESIDED_COMP,
|
||||
AV1E_SET_ENABLE_INTERINTRA_COMP,
|
||||
AV1E_SET_ENABLE_SMOOTH_INTERINTRA,
|
||||
AV1E_SET_ENABLE_DIFF_WTD_COMP,
|
||||
|
|
@ -849,7 +927,10 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
|
|||
AV1E_SET_REDUCED_TX_TYPE_SET,
|
||||
AV1E_SET_INTRA_DCT_ONLY,
|
||||
AV1E_SET_INTER_DCT_ONLY,
|
||||
AV1E_SET_INTRA_DEFAULT_TX_ONLY,
|
||||
AV1E_SET_QUANT_B_ADAPT,
|
||||
AV1E_SET_COEFF_COST_UPD_FREQ,
|
||||
AV1E_SET_MODE_COST_UPD_FREQ,
|
||||
#if CONFIG_DIST_8X8
|
||||
AV1E_SET_ENABLE_DIST_8X8,
|
||||
#endif
|
||||
|
|
@ -879,7 +960,10 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
|
|||
AV1E_SET_DENOISE_BLOCK_SIZE,
|
||||
#endif // CONFIG_DENOISE
|
||||
AV1E_SET_MAX_REFERENCE_FRAMES,
|
||||
AV1E_SET_REDUCED_REFERENCE_SET,
|
||||
AV1E_SET_ENABLE_REF_FRAME_MVS,
|
||||
AV1E_SET_TARGET_SEQ_LEVEL_IDX,
|
||||
AV1E_SET_TIER_MASK,
|
||||
0 };
|
||||
#endif // CONFIG_AV1_ENCODER
|
||||
|
||||
|
|
@ -946,9 +1030,6 @@ struct stream_config {
|
|||
struct aom_codec_enc_cfg cfg;
|
||||
const char *out_fn;
|
||||
const char *stats_fn;
|
||||
#if CONFIG_FP_MB_STATS
|
||||
const char *fpmb_stats_fn;
|
||||
#endif
|
||||
stereo_format_t stereo_fmt;
|
||||
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
|
||||
int arg_ctrl_cnt;
|
||||
|
|
@ -976,9 +1057,6 @@ struct stream_state {
|
|||
uint64_t cx_time;
|
||||
size_t nbytes;
|
||||
stats_io_t stats;
|
||||
#if CONFIG_FP_MB_STATS
|
||||
stats_io_t fpmb_stats;
|
||||
#endif
|
||||
struct aom_image *img;
|
||||
aom_codec_ctx_t decoder;
|
||||
int mismatch_seen;
|
||||
|
|
@ -1064,7 +1142,9 @@ static void parse_global_config(struct AvxEncoderConfig *global, int argc,
|
|||
} else if (arg_match(&arg, &usage, argi))
|
||||
global->usage = arg_parse_uint(&arg);
|
||||
else if (arg_match(&arg, &good_dl, argi))
|
||||
warn("Deprecated --good option! Ignoring\n");
|
||||
global->usage = AOM_USAGE_GOOD_QUALITY; // Good quality usage
|
||||
else if (arg_match(&arg, &rt_dl, argi))
|
||||
global->usage = AOM_USAGE_REALTIME; // Real-time usage
|
||||
else if (arg_match(&arg, &use_yv12, argi))
|
||||
global->color_type = YV12;
|
||||
else if (arg_match(&arg, &use_i420, argi))
|
||||
|
|
@ -1117,11 +1197,19 @@ static void parse_global_config(struct AvxEncoderConfig *global, int argc,
|
|||
// Make default AV1 passes = 2 until there is a better quality 1-pass
|
||||
// encoder
|
||||
if (global->codec != NULL && global->codec->name != NULL)
|
||||
global->passes = (strcmp(global->codec->name, "av1") == 0) ? 2 : 1;
|
||||
global->passes = (strcmp(global->codec->name, "av1") == 0 &&
|
||||
global->usage != AOM_USAGE_REALTIME)
|
||||
? 2
|
||||
: 1;
|
||||
#else
|
||||
global->passes = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (global->usage == AOM_USAGE_REALTIME && global->passes > 1) {
|
||||
warn("Enforcing one-pass encoding in realtime mode\n");
|
||||
global->passes = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void open_input_file(struct AvxInputContext *input,
|
||||
|
|
@ -1238,6 +1326,17 @@ static void set_config_arg_ctrls(struct stream_config *config, int key,
|
|||
return;
|
||||
}
|
||||
|
||||
// For target level, the settings should accumulate rather than overwrite,
|
||||
// so we simply append it.
|
||||
if (key == AV1E_SET_TARGET_SEQ_LEVEL_IDX) {
|
||||
j = config->arg_ctrl_cnt;
|
||||
assert(j < (int)ARG_CTRL_CNT_MAX);
|
||||
config->arg_ctrls[j][0] = key;
|
||||
config->arg_ctrls[j][1] = arg_parse_enum_or_int(arg);
|
||||
++config->arg_ctrl_cnt;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Point either to the next free element or the first instance of this
|
||||
* control.
|
||||
*/
|
||||
|
|
@ -1307,10 +1406,6 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
|
|||
}
|
||||
} else if (arg_match(&arg, &fpf_name, argi)) {
|
||||
config->stats_fn = arg.val;
|
||||
#if CONFIG_FP_MB_STATS
|
||||
} else if (arg_match(&arg, &fpmbf_name, argi)) {
|
||||
config->fpmb_stats_fn = arg.val;
|
||||
#endif
|
||||
} else if (arg_match(&arg, &use_webm, argi)) {
|
||||
#if CONFIG_WEBM_IO
|
||||
config->write_webm = 1;
|
||||
|
|
@ -1355,6 +1450,12 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
|
|||
config->cfg.g_error_resilient = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &lag_in_frames, argi)) {
|
||||
config->cfg.g_lag_in_frames = arg_parse_uint(&arg);
|
||||
if (global->usage == AOM_USAGE_REALTIME &&
|
||||
config->cfg.rc_end_usage == AOM_CBR &&
|
||||
config->cfg.g_lag_in_frames != 0) {
|
||||
warn("non-zero %s option ignored in realtime CBR mode.\n", arg.name);
|
||||
config->cfg.g_lag_in_frames = 0;
|
||||
}
|
||||
} else if (arg_match(&arg, &large_scale_tile, argi)) {
|
||||
config->cfg.large_scale_tile = arg_parse_uint(&arg);
|
||||
if (config->cfg.large_scale_tile) global->codec = get_aom_lst_encoder();
|
||||
|
|
@ -1498,17 +1599,6 @@ static void validate_stream_config(const struct stream_state *stream,
|
|||
fatal("Stream %d: duplicate stats file (from stream %d)",
|
||||
streami->index, stream->index);
|
||||
}
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
/* Check for two streams sharing a mb stats file. */
|
||||
if (streami != stream) {
|
||||
const char *a = stream->config.fpmb_stats_fn;
|
||||
const char *b = streami->config.fpmb_stats_fn;
|
||||
if (a && b && !strcmp(a, b))
|
||||
fatal("Stream %d: duplicate mb stats file (from stream %d)",
|
||||
streami->index, stream->index);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1673,26 +1763,11 @@ static void setup_pass(struct stream_state *stream,
|
|||
fatal("Failed to open statistics store");
|
||||
}
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
if (stream->config.fpmb_stats_fn) {
|
||||
if (!stats_open_file(&stream->fpmb_stats, stream->config.fpmb_stats_fn,
|
||||
pass))
|
||||
fatal("Failed to open mb statistics store");
|
||||
} else {
|
||||
if (!stats_open_mem(&stream->fpmb_stats, pass))
|
||||
fatal("Failed to open mb statistics store");
|
||||
}
|
||||
#endif
|
||||
|
||||
stream->config.cfg.g_pass = global->passes == 2
|
||||
? pass ? AOM_RC_LAST_PASS : AOM_RC_FIRST_PASS
|
||||
: AOM_RC_ONE_PASS;
|
||||
if (pass) {
|
||||
stream->config.cfg.rc_twopass_stats_in = stats_get(&stream->stats);
|
||||
#if CONFIG_FP_MB_STATS
|
||||
stream->config.cfg.rc_firstpass_mb_stats_in =
|
||||
stats_get(&stream->fpmb_stats);
|
||||
#endif
|
||||
}
|
||||
|
||||
stream->cx_time = 0;
|
||||
|
|
@ -1921,13 +1996,6 @@ static void get_cx_data(struct stream_state *stream,
|
|||
pkt->data.twopass_stats.sz);
|
||||
stream->nbytes += pkt->data.raw.sz;
|
||||
break;
|
||||
#if CONFIG_FP_MB_STATS
|
||||
case AOM_CODEC_FPMB_STATS_PKT:
|
||||
stats_write(&stream->fpmb_stats, pkt->data.firstpass_mb_stats.buf,
|
||||
pkt->data.firstpass_mb_stats.sz);
|
||||
stream->nbytes += pkt->data.raw.sz;
|
||||
break;
|
||||
#endif
|
||||
case AOM_CODEC_PSNR_PKT:
|
||||
|
||||
if (global->show_psnr) {
|
||||
|
|
@ -2524,12 +2592,6 @@ int main(int argc, const char **argv_) {
|
|||
stats_close(&stream->stats, global.passes - 1);
|
||||
}
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
FOREACH_STREAM(stream, streams) {
|
||||
stats_close(&stream->fpmb_stats, global.passes - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (global.pass) break;
|
||||
}
|
||||
|
||||
|
|
|
|||
35
third_party/aom/av1/av1.cmake
vendored
35
third_party/aom/av1/av1.cmake
vendored
|
|
@ -151,6 +151,8 @@ list(APPEND AOM_AV1_ENCODER_SOURCES
|
|||
"${AOM_ROOT}/av1/encoder/firstpass.h"
|
||||
"${AOM_ROOT}/av1/encoder/global_motion.c"
|
||||
"${AOM_ROOT}/av1/encoder/global_motion.h"
|
||||
"${AOM_ROOT}/av1/encoder/gop_structure.c"
|
||||
"${AOM_ROOT}/av1/encoder/gop_structure.h"
|
||||
"${AOM_ROOT}/av1/encoder/grain_test_vectors.h"
|
||||
"${AOM_ROOT}/av1/encoder/hash.c"
|
||||
"${AOM_ROOT}/av1/encoder/hash.h"
|
||||
|
|
@ -158,6 +160,8 @@ list(APPEND AOM_AV1_ENCODER_SOURCES
|
|||
"${AOM_ROOT}/av1/encoder/hash_motion.h"
|
||||
"${AOM_ROOT}/av1/encoder/hybrid_fwd_txfm.c"
|
||||
"${AOM_ROOT}/av1/encoder/hybrid_fwd_txfm.h"
|
||||
"${AOM_ROOT}/av1/encoder/level.c"
|
||||
"${AOM_ROOT}/av1/encoder/level.h"
|
||||
"${AOM_ROOT}/av1/encoder/lookahead.c"
|
||||
"${AOM_ROOT}/av1/encoder/lookahead.h"
|
||||
"${AOM_ROOT}/av1/encoder/mbgraph.c"
|
||||
|
|
@ -168,6 +172,10 @@ list(APPEND AOM_AV1_ENCODER_SOURCES
|
|||
"${AOM_ROOT}/av1/encoder/ml.h"
|
||||
"${AOM_ROOT}/av1/encoder/palette.c"
|
||||
"${AOM_ROOT}/av1/encoder/palette.h"
|
||||
"${AOM_ROOT}/av1/encoder/partition_strategy.h"
|
||||
"${AOM_ROOT}/av1/encoder/partition_strategy.c"
|
||||
"${AOM_ROOT}/av1/encoder/pass2_strategy.h"
|
||||
"${AOM_ROOT}/av1/encoder/pass2_strategy.c"
|
||||
"${AOM_ROOT}/av1/encoder/pickcdef.c"
|
||||
"${AOM_ROOT}/av1/encoder/picklpf.c"
|
||||
"${AOM_ROOT}/av1/encoder/picklpf.h"
|
||||
|
|
@ -194,6 +202,8 @@ list(APPEND AOM_AV1_ENCODER_SOURCES
|
|||
"${AOM_ROOT}/av1/encoder/tpl_model.c"
|
||||
"${AOM_ROOT}/av1/encoder/tpl_model.h"
|
||||
"${AOM_ROOT}/av1/encoder/wedge_utils.c"
|
||||
"${AOM_ROOT}/av1/encoder/var_based_part.c"
|
||||
"${AOM_ROOT}/av1/encoder/var_based_part.h"
|
||||
"${AOM_ROOT}/third_party/fastfeat/fast.c"
|
||||
"${AOM_ROOT}/third_party/fastfeat/fast.h"
|
||||
"${AOM_ROOT}/third_party/fastfeat/fast_9.c"
|
||||
|
|
@ -257,8 +267,7 @@ list(APPEND AOM_AV1_COMMON_INTRIN_AVX2
|
|||
"${AOM_ROOT}/av1/common/x86/wiener_convolve_avx2.c")
|
||||
|
||||
list(APPEND AOM_AV1_ENCODER_ASM_SSE2 "${AOM_ROOT}/av1/encoder/x86/dct_sse2.asm"
|
||||
"${AOM_ROOT}/av1/encoder/x86/error_sse2.asm"
|
||||
"${AOM_ROOT}/av1/encoder/x86/temporal_filter_apply_sse2.asm")
|
||||
"${AOM_ROOT}/av1/encoder/x86/error_sse2.asm")
|
||||
|
||||
list(APPEND AOM_AV1_ENCODER_INTRIN_SSE2
|
||||
"${AOM_ROOT}/av1/encoder/x86/av1_fwd_txfm_sse2.c"
|
||||
|
|
@ -281,6 +290,9 @@ list(APPEND AOM_AV1_ENCODER_INTRIN_SSE4_1
|
|||
"${AOM_ROOT}/av1/encoder/x86/encodetxb_sse4.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/highbd_fwd_txfm_sse4.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/rdopt_sse4.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/temporal_filter_constants.h"
|
||||
"${AOM_ROOT}/av1/encoder/x86/temporal_filter_sse4.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/highbd_temporal_filter_sse4.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/pickrst_sse4.c")
|
||||
|
||||
list(APPEND AOM_AV1_ENCODER_INTRIN_AVX2
|
||||
|
|
@ -288,6 +300,7 @@ list(APPEND AOM_AV1_ENCODER_INTRIN_AVX2
|
|||
"${AOM_ROOT}/av1/encoder/x86/av1_highbd_quantize_avx2.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/corner_match_avx2.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/error_intrin_avx2.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/highbd_block_error_intrin_avx2.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/av1_fwd_txfm_avx2.h"
|
||||
"${AOM_ROOT}/av1/encoder/x86/av1_fwd_txfm2d_avx2.c"
|
||||
"${AOM_ROOT}/av1/encoder/x86/highbd_fwd_txfm_avx2.c"
|
||||
|
|
@ -346,15 +359,7 @@ endif()
|
|||
function(setup_av1_targets)
|
||||
add_library(aom_av1_common OBJECT ${AOM_AV1_COMMON_SOURCES})
|
||||
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})
|
||||
|
|
@ -452,13 +457,13 @@ function(setup_av1_targets)
|
|||
|
||||
if(HAVE_NEON)
|
||||
if(AOM_AV1_COMMON_INTRIN_NEON)
|
||||
add_intrinsics_object_library("${AOM_INTRIN_NEON_FLAG}" "neon"
|
||||
add_intrinsics_object_library("${AOM_NEON_INTRIN_FLAG}" "neon"
|
||||
"aom_av1_common"
|
||||
"AOM_AV1_COMMON_INTRIN_NEON" "aom")
|
||||
endif()
|
||||
|
||||
if(AOM_AV1_ENCODER_INTRIN_NEON)
|
||||
add_intrinsics_object_library("${AOM_INTRIN_NEON_FLAG}" "neon"
|
||||
add_intrinsics_object_library("${AOM_NEON_INTRIN_FLAG}" "neon"
|
||||
"aom_av1_encoder"
|
||||
"AOM_AV1_ENCODER_INTRIN_NEON" "aom")
|
||||
endif()
|
||||
|
|
@ -476,13 +481,7 @@ function(setup_av1_targets)
|
|||
"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)
|
||||
endfunction()
|
||||
|
||||
function(setup_av1_test_targets)
|
||||
endfunction()
|
||||
|
|
|
|||
312
third_party/aom/av1/av1_cx_iface.c
vendored
312
third_party/aom/av1/av1_cx_iface.c
vendored
|
|
@ -92,26 +92,34 @@ struct av1_extracfg {
|
|||
unsigned int motion_vector_unit_test;
|
||||
unsigned int cdf_update_mode;
|
||||
int enable_rect_partitions; // enable rectangular partitions for sequence
|
||||
int enable_ab_partitions; // enable AB partitions for sequence
|
||||
int enable_1to4_partitions; // enable 1:4 and 4:1 partitions for sequence
|
||||
int min_partition_size; // min partition size [4,8,16,32,64,128]
|
||||
int max_partition_size; // max partition size [4,8,16,32,64,128]
|
||||
int enable_intra_edge_filter; // enable intra-edge filter for sequence
|
||||
int enable_order_hint; // enable order hint for sequence
|
||||
int enable_tx64; // enable 64-pt transform usage for sequence
|
||||
int tx_size_search_method; // set transform block size search method
|
||||
int enable_flip_idtx; // enable flip and identity transform types
|
||||
int enable_dist_wtd_comp; // enable dist wtd compound for sequence
|
||||
int max_reference_frames; // maximum number of references per frame
|
||||
int enable_ref_frame_mvs; // sequence level
|
||||
int allow_ref_frame_mvs; // frame level
|
||||
int enable_masked_comp; // enable masked compound for sequence
|
||||
int enable_interintra_comp; // enable interintra compound for sequence
|
||||
int enable_smooth_interintra; // enable smooth interintra mode usage
|
||||
int enable_diff_wtd_comp; // enable diff-wtd compound usage
|
||||
int enable_interinter_wedge; // enable interinter-wedge compound usage
|
||||
int enable_interintra_wedge; // enable interintra-wedge compound usage
|
||||
int enable_global_motion; // enable global motion usage for sequence
|
||||
int enable_warped_motion; // sequence level
|
||||
int allow_warped_motion; // frame level
|
||||
int enable_filter_intra; // enable filter intra for sequence
|
||||
int enable_smooth_intra; // enable smooth intra modes for sequence
|
||||
int enable_paeth_intra; // enable Peeth intra mode for sequence
|
||||
int enable_cfl_intra; // enable CFL uv intra mode for sequence
|
||||
int enable_reduced_reference_set; // enable reduced set of references
|
||||
int enable_ref_frame_mvs; // sequence level
|
||||
int allow_ref_frame_mvs; // frame level
|
||||
int enable_masked_comp; // enable masked compound for sequence
|
||||
int enable_onesided_comp; // enable one sided compound for sequence
|
||||
int enable_interintra_comp; // enable interintra compound for sequence
|
||||
int enable_smooth_interintra; // enable smooth interintra mode usage
|
||||
int enable_diff_wtd_comp; // enable diff-wtd compound usage
|
||||
int enable_interinter_wedge; // enable interinter-wedge compound usage
|
||||
int enable_interintra_wedge; // enable interintra-wedge compound usage
|
||||
int enable_global_motion; // enable global motion usage for sequence
|
||||
int enable_warped_motion; // sequence level
|
||||
int allow_warped_motion; // frame level
|
||||
int enable_filter_intra; // enable filter intra for sequence
|
||||
int enable_smooth_intra; // enable smooth intra modes for sequence
|
||||
int enable_paeth_intra; // enable Paeth intra mode for sequence
|
||||
int enable_cfl_intra; // enable CFL uv intra mode for sequence
|
||||
int enable_superres;
|
||||
int enable_palette;
|
||||
int enable_intrabc;
|
||||
|
|
@ -126,7 +134,14 @@ struct av1_extracfg {
|
|||
int reduced_tx_type_set;
|
||||
int use_intra_dct_only;
|
||||
int use_inter_dct_only;
|
||||
int use_intra_default_tx_only;
|
||||
int quant_b_adapt;
|
||||
AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
|
||||
// Bit mask to specify which tier each of the 32 possible operating points
|
||||
// conforms to.
|
||||
unsigned int tier_mask;
|
||||
COST_UPDATE_TYPE coeff_cost_upd_freq;
|
||||
COST_UPDATE_TYPE mode_cost_upd_freq;
|
||||
};
|
||||
|
||||
static struct av1_extracfg default_extra_cfg = {
|
||||
|
|
@ -167,7 +182,7 @@ static struct av1_extracfg default_extra_cfg = {
|
|||
1, // max number of tile groups
|
||||
0, // mtu_size
|
||||
AOM_TIMING_UNSPECIFIED, // No picture timing signaling in bitstream
|
||||
1, // frame_parallel_decoding_mode
|
||||
0, // frame_parallel_decoding_mode
|
||||
1, // enable dual filter
|
||||
NO_AQ, // aq_mode
|
||||
NO_DELTA_Q, // deltaq_mode
|
||||
|
|
@ -190,14 +205,22 @@ static struct av1_extracfg default_extra_cfg = {
|
|||
0, // motion_vector_unit_test
|
||||
1, // CDF update mode
|
||||
1, // enable rectangular partitions
|
||||
1, // enable ab shape partitions
|
||||
1, // enable 1:4 and 4:1 partitions
|
||||
4, // min_partition_size
|
||||
128, // max_partition_size
|
||||
1, // enable intra edge filter
|
||||
1, // frame order hint
|
||||
1, // enable 64-pt transform usage
|
||||
0, // transform block size search method
|
||||
1, // enable flip and identity transform
|
||||
1, // dist-wtd compound
|
||||
7, // max_reference_frames
|
||||
0, // enable_reduced_reference_set
|
||||
1, // enable_ref_frame_mvs sequence level
|
||||
1, // allow ref_frame_mvs frame level
|
||||
1, // enable masked compound at sequence level
|
||||
1, // enable one sided compound at sequence level
|
||||
1, // enable interintra compound at sequence level
|
||||
1, // enable smooth interintra mode
|
||||
1, // enable difference-weighted compound
|
||||
|
|
@ -212,7 +235,7 @@ static struct av1_extracfg default_extra_cfg = {
|
|||
1, // enable CFL uv intra mode usage for sequence
|
||||
1, // superres
|
||||
1, // enable palette
|
||||
1, // enable intrabc
|
||||
!CONFIG_SHARP_SETTINGS, // enable intrabc
|
||||
1, // enable angle delta
|
||||
#if CONFIG_DENOISE
|
||||
0, // noise_level
|
||||
|
|
@ -223,7 +246,15 @@ static struct av1_extracfg default_extra_cfg = {
|
|||
0, // reduced_tx_type_set
|
||||
0, // use_intra_dct_only
|
||||
0, // use_inter_dct_only
|
||||
0, // use_intra_default_tx_only
|
||||
0, // quant_b_adapt
|
||||
{
|
||||
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
|
||||
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
|
||||
}, // target_seq_level_idx
|
||||
0, // tier_mask
|
||||
COST_UPD_SB, // coeff_cost_upd_freq
|
||||
COST_UPD_SB, // mode_cost_upd_freq
|
||||
};
|
||||
|
||||
struct aom_codec_alg_priv {
|
||||
|
|
@ -295,6 +326,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
|
|||
RANGE_CHECK_HI(extra_cfg, aq_mode, AQ_MODE_COUNT - 1);
|
||||
RANGE_CHECK_HI(extra_cfg, deltaq_mode, DELTAQ_MODE_COUNT - 1);
|
||||
RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
|
||||
RANGE_CHECK_HI(cfg, g_usage, 1);
|
||||
RANGE_CHECK_HI(cfg, g_threads, MAX_NUM_THREADS);
|
||||
RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
|
||||
RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
|
||||
|
|
@ -310,7 +342,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
|
|||
RANGE_CHECK(extra_cfg, max_gf_interval, MAX(2, extra_cfg->min_gf_interval),
|
||||
(MAX_LAG_BUFFERS - 1));
|
||||
}
|
||||
RANGE_CHECK(extra_cfg, gf_max_pyr_height, 1, 4);
|
||||
RANGE_CHECK_HI(extra_cfg, gf_max_pyr_height, 4);
|
||||
|
||||
RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
|
||||
RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
|
||||
|
|
@ -428,9 +460,25 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
|
|||
}
|
||||
|
||||
RANGE_CHECK(extra_cfg, max_reference_frames, 3, 7);
|
||||
RANGE_CHECK(extra_cfg, enable_reduced_reference_set, 0, 1);
|
||||
RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1);
|
||||
RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1);
|
||||
|
||||
RANGE_CHECK_HI(extra_cfg, disable_trellis_quant, 3);
|
||||
RANGE_CHECK(extra_cfg, coeff_cost_upd_freq, 0, 2);
|
||||
RANGE_CHECK(extra_cfg, mode_cost_upd_freq, 0, 2);
|
||||
|
||||
RANGE_CHECK(extra_cfg, min_partition_size, 4, 128);
|
||||
RANGE_CHECK(extra_cfg, max_partition_size, 4, 128);
|
||||
RANGE_CHECK_HI(extra_cfg, min_partition_size, extra_cfg->max_partition_size);
|
||||
|
||||
RANGE_CHECK(extra_cfg, tx_size_search_method, 0, 2);
|
||||
|
||||
for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
|
||||
if (!is_valid_seq_level_idx(extra_cfg->target_seq_level_idx[i]))
|
||||
ERROR("Target sequence level index is invalid");
|
||||
}
|
||||
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
|
|
@ -498,6 +546,7 @@ static aom_codec_err_t set_encoder_config(
|
|||
oxcf->profile = cfg->g_profile;
|
||||
oxcf->fwd_kf_enabled = cfg->fwd_kf_enabled;
|
||||
oxcf->max_threads = (int)cfg->g_threads;
|
||||
oxcf->mode = (cfg->g_usage == 1) ? REALTIME : GOOD;
|
||||
oxcf->width = cfg->g_w;
|
||||
oxcf->height = cfg->g_h;
|
||||
oxcf->forced_max_frame_width = cfg->g_forced_max_frame_width;
|
||||
|
|
@ -540,7 +589,6 @@ static aom_codec_err_t set_encoder_config(
|
|||
oxcf->init_framerate = 30;
|
||||
oxcf->timing_info_present = 0;
|
||||
}
|
||||
oxcf->mode = GOOD;
|
||||
oxcf->cfg = &cfg->cfg;
|
||||
|
||||
switch (cfg->g_pass) {
|
||||
|
|
@ -582,7 +630,10 @@ static aom_codec_err_t set_encoder_config(
|
|||
oxcf->reduced_tx_type_set = extra_cfg->reduced_tx_type_set;
|
||||
oxcf->use_intra_dct_only = extra_cfg->use_intra_dct_only;
|
||||
oxcf->use_inter_dct_only = extra_cfg->use_inter_dct_only;
|
||||
oxcf->use_intra_default_tx_only = extra_cfg->use_intra_default_tx_only;
|
||||
oxcf->quant_b_adapt = extra_cfg->quant_b_adapt;
|
||||
oxcf->coeff_cost_upd_freq = (COST_UPDATE_TYPE)extra_cfg->coeff_cost_upd_freq;
|
||||
oxcf->mode_cost_upd_freq = (COST_UPDATE_TYPE)extra_cfg->mode_cost_upd_freq;
|
||||
#if CONFIG_DIST_8X8
|
||||
oxcf->using_dist_8x8 = extra_cfg->enable_dist_8x8;
|
||||
if (extra_cfg->tuning == AOM_TUNE_CDEF_DIST ||
|
||||
|
|
@ -660,10 +711,6 @@ static aom_codec_err_t set_encoder_config(
|
|||
|
||||
oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in;
|
||||
#endif
|
||||
|
||||
oxcf->color_primaries = extra_cfg->color_primaries;
|
||||
oxcf->transfer_characteristics = extra_cfg->transfer_characteristics;
|
||||
oxcf->matrix_coefficients = extra_cfg->matrix_coefficients;
|
||||
|
|
@ -718,17 +765,21 @@ static aom_codec_err_t set_encoder_config(
|
|||
oxcf->full_still_picture_hdr = cfg->full_still_picture_hdr;
|
||||
oxcf->enable_dual_filter = extra_cfg->enable_dual_filter;
|
||||
oxcf->enable_rect_partitions = extra_cfg->enable_rect_partitions;
|
||||
oxcf->enable_ab_partitions = extra_cfg->enable_ab_partitions;
|
||||
oxcf->enable_1to4_partitions = extra_cfg->enable_1to4_partitions;
|
||||
oxcf->min_partition_size = extra_cfg->min_partition_size;
|
||||
oxcf->max_partition_size = extra_cfg->max_partition_size;
|
||||
oxcf->enable_intra_edge_filter = extra_cfg->enable_intra_edge_filter;
|
||||
oxcf->enable_tx64 = extra_cfg->enable_tx64;
|
||||
oxcf->tx_size_search_method = extra_cfg->tx_size_search_method;
|
||||
oxcf->enable_flip_idtx = extra_cfg->enable_flip_idtx;
|
||||
oxcf->enable_order_hint = extra_cfg->enable_order_hint;
|
||||
oxcf->enable_dist_wtd_comp =
|
||||
extra_cfg->enable_dist_wtd_comp & extra_cfg->enable_order_hint;
|
||||
oxcf->max_reference_frames = extra_cfg->max_reference_frames;
|
||||
if (oxcf->max_reference_frames > 3 && oxcf->max_reference_frames < 7) {
|
||||
// TODO(urvang): Enable all possible values, after they work properly.
|
||||
oxcf->max_reference_frames = 3;
|
||||
}
|
||||
oxcf->enable_reduced_reference_set = extra_cfg->enable_reduced_reference_set;
|
||||
oxcf->enable_masked_comp = extra_cfg->enable_masked_comp;
|
||||
oxcf->enable_onesided_comp = extra_cfg->enable_onesided_comp;
|
||||
oxcf->enable_diff_wtd_comp =
|
||||
extra_cfg->enable_masked_comp & extra_cfg->enable_diff_wtd_comp;
|
||||
oxcf->enable_interinter_wedge =
|
||||
|
|
@ -795,6 +846,9 @@ static aom_codec_err_t set_encoder_config(
|
|||
oxcf->border_in_pixels = (oxcf->resize_mode || oxcf->superres_mode)
|
||||
? AOM_BORDER_IN_PIXELS
|
||||
: AOM_ENC_NO_SCALE_BORDER;
|
||||
memcpy(oxcf->target_seq_level_idx, extra_cfg->target_seq_level_idx,
|
||||
sizeof(oxcf->target_seq_level_idx));
|
||||
oxcf->tier_mask = extra_cfg->tier_mask;
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1097,6 +1151,35 @@ static aom_codec_err_t ctrl_set_enable_rect_partitions(
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_ab_partitions(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.enable_ab_partitions = CAST(AV1E_SET_ENABLE_AB_PARTITIONS, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_1to4_partitions(
|
||||
aom_codec_alg_priv_t *ctx, va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.enable_1to4_partitions =
|
||||
CAST(AV1E_SET_ENABLE_1TO4_PARTITIONS, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_min_partition_size(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.min_partition_size = CAST(AV1E_SET_MIN_PARTITION_SIZE, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_max_partition_size(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.max_partition_size = CAST(AV1E_SET_MAX_PARTITION_SIZE, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_intra_edge_filter(
|
||||
aom_codec_alg_priv_t *ctx, va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1119,6 +1202,20 @@ static aom_codec_err_t ctrl_set_enable_tx64(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_tx_size_search_method(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.tx_size_search_method = CAST(AV1E_SET_TX_SIZE_SEARCH_METHOD, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_flip_idtx(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.enable_flip_idtx = CAST(AV1E_SET_ENABLE_FLIP_IDTX, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_dist_wtd_comp(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1133,6 +1230,14 @@ static aom_codec_err_t ctrl_set_max_reference_frames(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_reduced_reference_set(
|
||||
aom_codec_alg_priv_t *ctx, va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.enable_reduced_reference_set =
|
||||
CAST(AV1E_SET_REDUCED_REFERENCE_SET, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_ref_frame_mvs(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1154,6 +1259,13 @@ static aom_codec_err_t ctrl_set_enable_masked_comp(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_onesided_comp(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.enable_onesided_comp = CAST(AV1E_SET_ENABLE_ONESIDED_COMP, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_enable_interintra_comp(
|
||||
aom_codec_alg_priv_t *ctx, va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1327,6 +1439,14 @@ static aom_codec_err_t ctrl_set_inter_dct_only(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_intra_default_tx_only(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.use_intra_default_tx_only =
|
||||
CAST(AV1E_SET_INTRA_DEFAULT_TX_ONLY, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_quant_b_adapt(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1334,6 +1454,20 @@ static aom_codec_err_t ctrl_set_quant_b_adapt(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_coeff_cost_upd_freq(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.coeff_cost_upd_freq = CAST(AV1E_SET_COEFF_COST_UPD_FREQ, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_mode_cost_upd_freq(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.mode_cost_upd_freq = CAST(AV1E_SET_MODE_COST_UPD_FREQ, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_film_grain_test_vector(
|
||||
aom_codec_alg_priv_t *ctx, va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
|
|
@ -1409,6 +1543,26 @@ static aom_codec_err_t ctrl_enable_motion_vector_unit_test(
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_target_seq_level_idx(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
const int val = CAST(AV1E_SET_TARGET_SEQ_LEVEL_IDX, args);
|
||||
const int level = val % 100;
|
||||
const int operating_point_idx = val / 100;
|
||||
if (operating_point_idx >= 0 &&
|
||||
operating_point_idx < MAX_NUM_OPERATING_POINTS) {
|
||||
extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
|
||||
}
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_set_tier_mask(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
struct av1_extracfg extra_cfg = ctx->extra_cfg;
|
||||
extra_cfg.tier_mask = CAST(AV1E_SET_TIER_MASK, args);
|
||||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx,
|
||||
aom_codec_priv_enc_mr_cfg_t *data) {
|
||||
aom_codec_err_t res = AOM_CODEC_OK;
|
||||
|
|
@ -1511,8 +1665,7 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->oxcf.mode != GOOD) {
|
||||
if (ctx->oxcf.mode != GOOD && ctx->oxcf.mode != REALTIME) {
|
||||
ctx->oxcf.mode = GOOD;
|
||||
av1_change_config(ctx->cpi, &ctx->oxcf);
|
||||
}
|
||||
|
|
@ -1570,6 +1723,8 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
|
|||
unsigned char *cx_data = ctx->cx_data;
|
||||
size_t cx_data_sz = ctx->cx_data_sz;
|
||||
|
||||
assert(!(cx_data == NULL && cx_data_sz != 0));
|
||||
|
||||
/* Any pending invisible frames? */
|
||||
if (ctx->pending_cx_data) {
|
||||
memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
|
||||
|
|
@ -1616,8 +1771,8 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
|
|||
frame_size);
|
||||
}
|
||||
const uint32_t obu_header_offset = 0;
|
||||
obu_header_size = write_obu_header(
|
||||
OBU_TEMPORAL_DELIMITER, 0,
|
||||
obu_header_size = av1_write_obu_header(
|
||||
cpi, OBU_TEMPORAL_DELIMITER, 0,
|
||||
(uint8_t *)(ctx->pending_cx_data + obu_header_offset));
|
||||
|
||||
// OBUs are preceded/succeeded by an unsigned leb128 coded integer.
|
||||
|
|
@ -1978,6 +2133,13 @@ static aom_codec_err_t ctrl_set_chroma_subsampling_y(aom_codec_alg_priv_t *ctx,
|
|||
return update_extra_cfg(ctx, &extra_cfg);
|
||||
}
|
||||
|
||||
static aom_codec_err_t ctrl_get_seq_level_idx(aom_codec_alg_priv_t *ctx,
|
||||
va_list args) {
|
||||
int *const arg = va_arg(args, int *);
|
||||
if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
|
||||
return av1_get_seq_level_idx(ctx->cpi, arg);
|
||||
}
|
||||
|
||||
static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
||||
{ AV1_COPY_REFERENCE, ctrl_copy_reference },
|
||||
{ AOME_USE_REFERENCE, ctrl_use_reference },
|
||||
|
|
@ -2027,15 +2189,23 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
|||
{ AV1E_SET_ERROR_RESILIENT_MODE, ctrl_set_error_resilient_mode },
|
||||
{ AV1E_SET_S_FRAME_MODE, ctrl_set_s_frame_mode },
|
||||
{ AV1E_SET_ENABLE_RECT_PARTITIONS, ctrl_set_enable_rect_partitions },
|
||||
{ AV1E_SET_ENABLE_AB_PARTITIONS, ctrl_set_enable_ab_partitions },
|
||||
{ AV1E_SET_ENABLE_1TO4_PARTITIONS, ctrl_set_enable_1to4_partitions },
|
||||
{ AV1E_SET_MIN_PARTITION_SIZE, ctrl_set_min_partition_size },
|
||||
{ AV1E_SET_MAX_PARTITION_SIZE, ctrl_set_max_partition_size },
|
||||
{ AV1E_SET_ENABLE_DUAL_FILTER, ctrl_set_enable_dual_filter },
|
||||
{ AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctrl_set_enable_intra_edge_filter },
|
||||
{ AV1E_SET_ENABLE_ORDER_HINT, ctrl_set_enable_order_hint },
|
||||
{ AV1E_SET_ENABLE_TX64, ctrl_set_enable_tx64 },
|
||||
{ AV1E_SET_TX_SIZE_SEARCH_METHOD, ctrl_set_tx_size_search_method },
|
||||
{ AV1E_SET_ENABLE_FLIP_IDTX, ctrl_set_enable_flip_idtx },
|
||||
{ AV1E_SET_ENABLE_DIST_WTD_COMP, ctrl_set_enable_dist_wtd_comp },
|
||||
{ AV1E_SET_MAX_REFERENCE_FRAMES, ctrl_set_max_reference_frames },
|
||||
{ AV1E_SET_REDUCED_REFERENCE_SET, ctrl_set_enable_reduced_reference_set },
|
||||
{ AV1E_SET_ENABLE_REF_FRAME_MVS, ctrl_set_enable_ref_frame_mvs },
|
||||
{ AV1E_SET_ALLOW_REF_FRAME_MVS, ctrl_set_allow_ref_frame_mvs },
|
||||
{ AV1E_SET_ENABLE_MASKED_COMP, ctrl_set_enable_masked_comp },
|
||||
{ AV1E_SET_ENABLE_ONESIDED_COMP, ctrl_set_enable_onesided_comp },
|
||||
{ AV1E_SET_ENABLE_INTERINTRA_COMP, ctrl_set_enable_interintra_comp },
|
||||
{ AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctrl_set_enable_smooth_interintra },
|
||||
{ AV1E_SET_ENABLE_DIFF_WTD_COMP, ctrl_set_enable_diff_wtd_comp },
|
||||
|
|
@ -2056,7 +2226,10 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
|||
{ AV1E_SET_REDUCED_TX_TYPE_SET, ctrl_set_reduced_tx_type_set },
|
||||
{ AV1E_SET_INTRA_DCT_ONLY, ctrl_set_intra_dct_only },
|
||||
{ AV1E_SET_INTER_DCT_ONLY, ctrl_set_inter_dct_only },
|
||||
{ AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctrl_set_intra_default_tx_only },
|
||||
{ AV1E_SET_QUANT_B_ADAPT, ctrl_set_quant_b_adapt },
|
||||
{ AV1E_SET_COEFF_COST_UPD_FREQ, ctrl_set_coeff_cost_upd_freq },
|
||||
{ AV1E_SET_MODE_COST_UPD_FREQ, ctrl_set_mode_cost_upd_freq },
|
||||
{ AV1E_SET_DELTAQ_MODE, ctrl_set_deltaq_mode },
|
||||
{ AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
|
||||
{ AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
|
||||
|
|
@ -2080,6 +2253,8 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
|||
{ AV1E_SET_DENOISE_BLOCK_SIZE, ctrl_set_denoise_block_size },
|
||||
#endif // CONFIG_FILM_GRAIN
|
||||
{ AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
|
||||
{ AV1E_SET_TARGET_SEQ_LEVEL_IDX, ctrl_set_target_seq_level_idx },
|
||||
{ AV1E_SET_TIER_MASK, ctrl_set_tier_mask },
|
||||
|
||||
// Getters
|
||||
{ AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
|
||||
|
|
@ -2090,6 +2265,7 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
|
|||
{ AV1_COPY_NEW_FRAME_IMAGE, ctrl_copy_new_frame_image },
|
||||
{ AV1E_SET_CHROMA_SUBSAMPLING_X, ctrl_set_chroma_subsampling_x },
|
||||
{ AV1E_SET_CHROMA_SUBSAMPLING_Y, ctrl_set_chroma_subsampling_y },
|
||||
{ AV1E_GET_SEQ_LEVEL_IDX, ctrl_get_seq_level_idx },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
|
|
@ -2097,7 +2273,7 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
|
|||
{ 0,
|
||||
{
|
||||
// NOLINT
|
||||
0, // g_usage
|
||||
0, // g_usage - non-realtime usage
|
||||
0, // g_threads
|
||||
0, // g_profile
|
||||
|
||||
|
|
@ -2122,7 +2298,7 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
|
|||
SCALE_NUMERATOR, // rc_resize_denominator
|
||||
SCALE_NUMERATOR, // rc_resize_kf_denominator
|
||||
|
||||
0, // rc_superres_mode
|
||||
SUPERRES_NONE, // rc_superres_mode
|
||||
SCALE_NUMERATOR, // rc_superres_denominator
|
||||
SCALE_NUMERATOR, // rc_superres_kf_denominator
|
||||
63, // rc_superres_qthresh
|
||||
|
|
@ -2145,6 +2321,74 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
|
|||
0, // rc_two_pass_vbrmin_section
|
||||
2000, // rc_two_pass_vbrmax_section
|
||||
|
||||
// keyframing settings (kf)
|
||||
0, // fwd_kf_enabled
|
||||
AOM_KF_AUTO, // g_kfmode
|
||||
0, // kf_min_dist
|
||||
9999, // kf_max_dist
|
||||
0, // sframe_dist
|
||||
1, // sframe_mode
|
||||
0, // large_scale_tile
|
||||
0, // monochrome
|
||||
0, // full_still_picture_hdr
|
||||
0, // save_as_annexb
|
||||
0, // tile_width_count
|
||||
0, // tile_height_count
|
||||
{ 0 }, // tile_widths
|
||||
{ 0 }, // tile_heights
|
||||
{ 1 }, // config file
|
||||
} },
|
||||
{ 1,
|
||||
{
|
||||
// NOLINT
|
||||
1, // g_usage - real-time usage
|
||||
0, // g_threads
|
||||
0, // g_profile
|
||||
|
||||
320, // g_width
|
||||
240, // g_height
|
||||
0, // g_limit
|
||||
0, // g_forced_max_frame_width
|
||||
0, // g_forced_max_frame_height
|
||||
AOM_BITS_8, // g_bit_depth
|
||||
8, // g_input_bit_depth
|
||||
|
||||
{ 1, 30 }, // g_timebase
|
||||
|
||||
0, // g_error_resilient
|
||||
|
||||
AOM_RC_ONE_PASS, // g_pass
|
||||
|
||||
1, // g_lag_in_frames
|
||||
|
||||
0, // rc_dropframe_thresh
|
||||
RESIZE_NONE, // rc_resize_mode
|
||||
SCALE_NUMERATOR, // rc_resize_denominator
|
||||
SCALE_NUMERATOR, // rc_resize_kf_denominator
|
||||
|
||||
0, // rc_superres_mode
|
||||
SCALE_NUMERATOR, // rc_superres_denominator
|
||||
SCALE_NUMERATOR, // rc_superres_kf_denominator
|
||||
63, // rc_superres_qthresh
|
||||
32, // rc_superres_kf_qthresh
|
||||
|
||||
AOM_CBR, // rc_end_usage
|
||||
{ NULL, 0 }, // rc_twopass_stats_in
|
||||
{ NULL, 0 }, // rc_firstpass_mb_stats_in
|
||||
256, // rc_target_bandwidth
|
||||
0, // rc_min_quantizer
|
||||
63, // rc_max_quantizer
|
||||
25, // rc_undershoot_pct
|
||||
25, // rc_overshoot_pct
|
||||
|
||||
6000, // rc_max_buffer_size
|
||||
4000, // rc_buffer_initial_size
|
||||
5000, // rc_buffer_optimal_size
|
||||
|
||||
50, // rc_two_pass_vbrbias
|
||||
0, // rc_two_pass_vbrmin_section
|
||||
2000, // rc_two_pass_vbrmax_section
|
||||
|
||||
// keyframing settings (kf)
|
||||
0, // fwd_kf_enabled
|
||||
AOM_KF_AUTO, // g_kfmode
|
||||
|
|
@ -2185,7 +2429,7 @@ CODEC_INTERFACE(aom_codec_av1_cx) = {
|
|||
},
|
||||
{
|
||||
// NOLINT
|
||||
1, // 1 cfg map
|
||||
2, // 2 cfg map
|
||||
encoder_usage_cfg_map, // aom_codec_enc_cfg_map_t
|
||||
encoder_encode, // aom_codec_encode_fn_t
|
||||
encoder_get_cxdata, // aom_codec_get_cx_data_fn_t
|
||||
|
|
|
|||
72
third_party/aom/av1/av1_dx_iface.c
vendored
72
third_party/aom/av1/av1_dx_iface.c
vendored
|
|
@ -154,6 +154,49 @@ static aom_codec_err_t decoder_destroy(aom_codec_alg_priv_t *ctx) {
|
|||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
static aom_codec_err_t parse_timing_info(struct aom_read_bit_buffer *rb) {
|
||||
const uint32_t num_units_in_display_tick =
|
||||
aom_rb_read_unsigned_literal(rb, 32);
|
||||
const uint32_t time_scale = aom_rb_read_unsigned_literal(rb, 32);
|
||||
if (num_units_in_display_tick == 0 || time_scale == 0)
|
||||
return AOM_CODEC_UNSUP_BITSTREAM;
|
||||
const uint8_t equal_picture_interval = aom_rb_read_bit(rb);
|
||||
if (equal_picture_interval) {
|
||||
const uint32_t num_ticks_per_picture_minus_1 = aom_rb_read_uvlc(rb);
|
||||
if (num_ticks_per_picture_minus_1 == UINT32_MAX) {
|
||||
// num_ticks_per_picture_minus_1 cannot be (1 << 32) − 1.
|
||||
return AOM_CODEC_UNSUP_BITSTREAM;
|
||||
}
|
||||
}
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
static aom_codec_err_t parse_decoder_model_info(
|
||||
struct aom_read_bit_buffer *rb, int *buffer_delay_length_minus_1) {
|
||||
*buffer_delay_length_minus_1 = aom_rb_read_literal(rb, 5);
|
||||
const uint32_t num_units_in_decoding_tick =
|
||||
aom_rb_read_unsigned_literal(rb, 32);
|
||||
const uint8_t buffer_removal_time_length_minus_1 = aom_rb_read_literal(rb, 5);
|
||||
const uint8_t frame_presentation_time_length_minus_1 =
|
||||
aom_rb_read_literal(rb, 5);
|
||||
(void)num_units_in_decoding_tick;
|
||||
(void)buffer_removal_time_length_minus_1;
|
||||
(void)frame_presentation_time_length_minus_1;
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
static aom_codec_err_t parse_op_parameters_info(
|
||||
struct aom_read_bit_buffer *rb, int buffer_delay_length_minus_1) {
|
||||
const int n = buffer_delay_length_minus_1 + 1;
|
||||
const uint32_t decoder_buffer_delay = aom_rb_read_unsigned_literal(rb, n);
|
||||
const uint32_t encoder_buffer_delay = aom_rb_read_unsigned_literal(rb, n);
|
||||
const uint8_t low_delay_mode_flag = aom_rb_read_bit(rb);
|
||||
(void)decoder_buffer_delay;
|
||||
(void)encoder_buffer_delay;
|
||||
(void)low_delay_mode_flag;
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
// Parses the operating points (including operating_point_idc, seq_level_idx,
|
||||
// and seq_tier) and then sets si->number_spatial_layers and
|
||||
// si->number_temporal_layers based on operating_point_idc[0].
|
||||
|
|
@ -161,10 +204,23 @@ static aom_codec_err_t parse_operating_points(struct aom_read_bit_buffer *rb,
|
|||
int is_reduced_header,
|
||||
aom_codec_stream_info_t *si) {
|
||||
int operating_point_idc0 = 0;
|
||||
|
||||
if (is_reduced_header) {
|
||||
aom_rb_read_literal(rb, LEVEL_BITS); // level
|
||||
} else {
|
||||
uint8_t decoder_model_info_present_flag = 0;
|
||||
int buffer_delay_length_minus_1 = 0;
|
||||
aom_codec_err_t status;
|
||||
const uint8_t timing_info_present_flag = aom_rb_read_bit(rb);
|
||||
if (timing_info_present_flag) {
|
||||
if ((status = parse_timing_info(rb)) != AOM_CODEC_OK) return status;
|
||||
decoder_model_info_present_flag = aom_rb_read_bit(rb);
|
||||
if (decoder_model_info_present_flag) {
|
||||
if ((status = parse_decoder_model_info(
|
||||
rb, &buffer_delay_length_minus_1)) != AOM_CODEC_OK)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
const uint8_t initial_display_delay_present_flag = aom_rb_read_bit(rb);
|
||||
const uint8_t operating_points_cnt_minus_1 =
|
||||
aom_rb_read_literal(rb, OP_POINTS_CNT_MINUS_1_BITS);
|
||||
for (int i = 0; i < operating_points_cnt_minus_1 + 1; i++) {
|
||||
|
|
@ -173,6 +229,20 @@ static aom_codec_err_t parse_operating_points(struct aom_read_bit_buffer *rb,
|
|||
if (i == 0) operating_point_idc0 = operating_point_idc;
|
||||
int seq_level_idx = aom_rb_read_literal(rb, LEVEL_BITS); // level
|
||||
if (seq_level_idx > 7) aom_rb_read_bit(rb); // tier
|
||||
if (decoder_model_info_present_flag) {
|
||||
const uint8_t decoder_model_present_for_this_op = aom_rb_read_bit(rb);
|
||||
if (decoder_model_present_for_this_op) {
|
||||
if ((status = parse_op_parameters_info(
|
||||
rb, buffer_delay_length_minus_1)) != AOM_CODEC_OK)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
if (initial_display_delay_present_flag) {
|
||||
const uint8_t initial_display_delay_present_for_this_op =
|
||||
aom_rb_read_bit(rb);
|
||||
if (initial_display_delay_present_for_this_op)
|
||||
aom_rb_read_literal(rb, 4); // initial_display_delay_minus_1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
4
third_party/aom/av1/common/av1_inv_txfm2d.c
vendored
4
third_party/aom/av1/common/av1_inv_txfm2d.c
vendored
|
|
@ -228,7 +228,7 @@ void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
|
|||
(void)real_range_row;
|
||||
if (cfg->txfm_type_row == TXFM_TYPE_ADST4 && i == 1) {
|
||||
// the adst4 may use 1 extra bit on top of opt_range_row at stage 1
|
||||
// so opt_range_col >= real_range_col will not hold
|
||||
// so opt_range_row >= real_range_row will not hold
|
||||
stage_range_row[i] = opt_range_row;
|
||||
} else {
|
||||
assert(opt_range_row >= real_range_row);
|
||||
|
|
@ -241,7 +241,7 @@ void av1_gen_inv_stage_range(int8_t *stage_range_col, int8_t *stage_range_row,
|
|||
cfg->stage_range_col[i] + fwd_shift + shift[0] + bd + 1;
|
||||
(void)real_range_col;
|
||||
if (cfg->txfm_type_col == TXFM_TYPE_ADST4 && i == 1) {
|
||||
// the adst4 may use 1 extra bit on top of opt_range_row at stage 1
|
||||
// the adst4 may use 1 extra bit on top of opt_range_col at stage 1
|
||||
// so opt_range_col >= real_range_col will not hold
|
||||
stage_range_col[i] = opt_range_col;
|
||||
} else {
|
||||
|
|
|
|||
23
third_party/aom/av1/common/av1_rtcd_defs.pl
vendored
23
third_party/aom/av1/common/av1_rtcd_defs.pl
vendored
|
|
@ -111,10 +111,14 @@ specialize qw/av1_highbd_convolve8_vert/, "$sse2_x86_64";
|
|||
|
||||
#inv txfm
|
||||
add_proto qw/void av1_inv_txfm_add/, "const tran_low_t *dqcoeff, uint8_t *dst, int stride, const TxfmParam *txfm_param";
|
||||
specialize qw/av1_inv_txfm_add ssse3 avx2 neon/;
|
||||
# TODO(http://crbug.com/aomedia/2350): avx2 is disabled due to test vector
|
||||
# mismatches.
|
||||
specialize qw/av1_inv_txfm_add ssse3 neon/;
|
||||
|
||||
add_proto qw/void av1_highbd_inv_txfm_add/, "const tran_low_t *dqcoeff, uint8_t *dst, int stride, const TxfmParam *txfm_param";
|
||||
specialize qw/av1_highbd_inv_txfm_add sse4_1 avx2/;
|
||||
# TODO(http://crbug.com/aomedia/2350): avx2 is disabled due to test vector
|
||||
# mismatches.
|
||||
specialize qw/av1_highbd_inv_txfm_add sse4_1/;
|
||||
|
||||
add_proto qw/void av1_highbd_inv_txfm_add_4x4/, "const tran_low_t *dqcoeff, uint8_t *dst, int stride, const TxfmParam *txfm_param";
|
||||
specialize qw/av1_highbd_inv_txfm_add_4x4 sse4_1/;
|
||||
|
|
@ -160,8 +164,9 @@ add_proto qw/void av1_inv_txfm2d_add_32x8/, "const int32_t *input, uint16_t *out
|
|||
add_proto qw/void av1_highbd_dr_prediction_z1/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_above, int dx, int dy, int bd";
|
||||
specialize qw/av1_highbd_dr_prediction_z1 avx2/;
|
||||
add_proto qw/void av1_highbd_dr_prediction_z2/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_above, int upsample_left, int dx, int dy, int bd";
|
||||
# TODO(https://crbug.com/aomedia/2288)
|
||||
#specialize qw/av1_highbd_dr_prediction_z2 avx2/;
|
||||
# TODO(niva213@gmail.com): Re-enable avx2 after fixing valgrind issue
|
||||
# https://crbug.com/aomedia/2316
|
||||
# specialize qw/av1_highbd_dr_prediction_z2 avx2/;
|
||||
add_proto qw/void av1_highbd_dr_prediction_z3/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_left, int dx, int dy, int bd";
|
||||
specialize qw/av1_highbd_dr_prediction_z3 avx2/;
|
||||
|
||||
|
|
@ -255,18 +260,18 @@ if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
|
|||
|
||||
add_proto qw/int av1_full_range_search/, "const struct macroblock *x, const struct search_site_config *cfg, MV *ref_mv, MV *best_mv, int search_param, int sad_per_bit, int *num00, const struct aom_variance_vtable *fn_ptr, const MV *center_mv";
|
||||
|
||||
# TODO(yunqing): Add back the optimizations.
|
||||
# add_proto qw/void av1_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";
|
||||
# specialize qw/av1_temporal_filter_apply sse2 msa/;
|
||||
add_proto qw/void av1_apply_temporal_filter/, "const uint8_t *y_frame1, int y_stride, const uint8_t *y_pred, int y_buf_stride, const uint8_t *u_frame1, const uint8_t *v_frame1, int uv_stride, const uint8_t *u_pred, const uint8_t *v_pred, int uv_buf_stride, unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32, uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator, uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count";
|
||||
specialize qw/av1_apply_temporal_filter sse4_1/;
|
||||
|
||||
add_proto qw/void av1_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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";
|
||||
|
||||
# ENCODEMB INVOKE
|
||||
|
||||
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/;
|
||||
specialize qw/av1_highbd_block_error sse2 avx2/;
|
||||
|
||||
# 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";
|
||||
add_proto qw/void av1_highbd_apply_temporal_filter/, "const uint8_t *yf, int y_stride, const uint8_t *yp, int y_buf_stride, const uint8_t *uf, const uint8_t *vf, int uv_stride, const uint8_t *up, const uint8_t *vp, int uv_buf_stride, unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, int strength, const int *blk_fw, int use_32x32, uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator, uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count";
|
||||
specialize qw/av1_highbd_apply_temporal_filter sse4_1/;
|
||||
|
||||
add_proto qw/void av1_highbd_quantize_fp/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, 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/;
|
||||
|
|
|
|||
2
third_party/aom/av1/common/av1_txfm.h
vendored
2
third_party/aom/av1/common/av1_txfm.h
vendored
|
|
@ -59,7 +59,9 @@ static INLINE int32_t range_check_value(int32_t value, int8_t bit) {
|
|||
const int64_t min_value = -(1LL << (bit - 1));
|
||||
if (value < min_value || value > max_value) {
|
||||
fprintf(stderr, "coeff out of bit range, value: %d bit %d\n", value, bit);
|
||||
#if !CONFIG_AV1_ENCODER
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
#endif // CONFIG_COEFFICIENT_RANGE_CHECKING
|
||||
#if DO_RANGE_CHECK_CLAMP
|
||||
|
|
|
|||
5
third_party/aom/av1/common/blockd.h
vendored
5
third_party/aom/av1/common/blockd.h
vendored
|
|
@ -190,11 +190,6 @@ typedef struct RD_STATS {
|
|||
int64_t ref_rdcost;
|
||||
int zero_rate;
|
||||
uint8_t invalid_rate;
|
||||
#if CONFIG_ONE_PASS_SVM
|
||||
int eob, eob_0, eob_1, eob_2, eob_3;
|
||||
int64_t rd, rd_0, rd_1, rd_2, rd_3;
|
||||
int64_t y_sse, sse_0, sse_1, sse_2, sse_3;
|
||||
#endif
|
||||
#if CONFIG_RD_DEBUG
|
||||
int txb_coeff_cost[MAX_MB_PLANE];
|
||||
int txb_coeff_cost_map[MAX_MB_PLANE][TXB_COEFF_COST_MAP_SIZE]
|
||||
|
|
|
|||
1
third_party/aom/av1/common/cdef.c
vendored
1
third_party/aom/av1/common/cdef.c
vendored
|
|
@ -80,7 +80,6 @@ int sb_compute_cdef_list(const AV1_COMMON *const cm, int mi_row, int mi_col,
|
|||
if (!is_8x8_block_skip(grid, mi_row + r, mi_col + c, cm->mi_stride)) {
|
||||
dlist[count].by = r >> r_shift;
|
||||
dlist[count].bx = c >> c_shift;
|
||||
dlist[count].skip = 0;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
third_party/aom/av1/common/cdef_block.c
vendored
4
third_party/aom/av1/common/cdef_block.c
vendored
|
|
@ -232,8 +232,8 @@ void cdef_filter_fb(uint8_t *dst8, uint16_t *dst16, int dstride, uint16_t *in,
|
|||
}
|
||||
|
||||
for (bi = 0; bi < cdef_count; bi++) {
|
||||
int t = dlist[bi].skip ? 0 : pri_strength;
|
||||
int s = dlist[bi].skip ? 0 : sec_strength;
|
||||
int t = pri_strength;
|
||||
int s = sec_strength;
|
||||
by = dlist[bi].by;
|
||||
bx = dlist[bi].bx;
|
||||
if (dst8)
|
||||
|
|
|
|||
1
third_party/aom/av1/common/cdef_block.h
vendored
1
third_party/aom/av1/common/cdef_block.h
vendored
|
|
@ -38,7 +38,6 @@ DECLARE_ALIGNED(16, extern const int, cdef_directions[8][2]);
|
|||
typedef struct {
|
||||
uint8_t by;
|
||||
uint8_t bx;
|
||||
uint8_t skip;
|
||||
} cdef_list;
|
||||
|
||||
typedef void (*cdef_filter_block_func)(uint8_t *dst8, uint16_t *dst16,
|
||||
|
|
|
|||
2
third_party/aom/av1/common/entropy.c
vendored
2
third_party/aom/av1/common/entropy.c
vendored
|
|
@ -101,7 +101,7 @@ void av1_reset_cdf_symbol_counters(FRAME_CONTEXT *fc) {
|
|||
RESET_CDF_COUNTER(fc->refmv_cdf, 2);
|
||||
RESET_CDF_COUNTER(fc->drl_cdf, 2);
|
||||
RESET_CDF_COUNTER(fc->inter_compound_mode_cdf, INTER_COMPOUND_MODES);
|
||||
RESET_CDF_COUNTER(fc->compound_type_cdf, COMPOUND_TYPES - 1);
|
||||
RESET_CDF_COUNTER(fc->compound_type_cdf, MASKED_COMPOUND_TYPES);
|
||||
RESET_CDF_COUNTER(fc->wedge_idx_cdf, 16);
|
||||
RESET_CDF_COUNTER(fc->interintra_cdf, 2);
|
||||
RESET_CDF_COUNTER(fc->wedge_interintra_cdf, 2);
|
||||
|
|
|
|||
22
third_party/aom/av1/common/entropymode.c
vendored
22
third_party/aom/av1/common/entropymode.c
vendored
|
|
@ -488,17 +488,17 @@ static const aom_cdf_prob
|
|||
{ AOM_CDF2(16384) }
|
||||
};
|
||||
|
||||
static const aom_cdf_prob
|
||||
default_compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(COMPOUND_TYPES - 1)] = {
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(23431) }, { AOM_CDF2(13171) }, { AOM_CDF2(11470) },
|
||||
{ AOM_CDF2(9770) }, { AOM_CDF2(9100) }, { AOM_CDF2(8233) },
|
||||
{ AOM_CDF2(6172) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(11820) }, { AOM_CDF2(7701) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }
|
||||
};
|
||||
static const aom_cdf_prob default_compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(
|
||||
MASKED_COMPOUND_TYPES)] = {
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(23431) }, { AOM_CDF2(13171) }, { AOM_CDF2(11470) },
|
||||
{ AOM_CDF2(9770) }, { AOM_CDF2(9100) }, { AOM_CDF2(8233) },
|
||||
{ AOM_CDF2(6172) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }, { AOM_CDF2(16384) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(11820) }, { AOM_CDF2(7701) }, { AOM_CDF2(16384) },
|
||||
{ AOM_CDF2(16384) }
|
||||
};
|
||||
|
||||
static const aom_cdf_prob default_wedge_idx_cdf[BLOCK_SIZES_ALL][CDF_SIZE(16)] =
|
||||
{ { AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
|
||||
|
|
|
|||
3
third_party/aom/av1/common/entropymode.h
vendored
3
third_party/aom/av1/common/entropymode.h
vendored
|
|
@ -92,7 +92,8 @@ typedef struct frame_contexts {
|
|||
|
||||
aom_cdf_prob inter_compound_mode_cdf[INTER_MODE_CONTEXTS]
|
||||
[CDF_SIZE(INTER_COMPOUND_MODES)];
|
||||
aom_cdf_prob compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(COMPOUND_TYPES - 1)];
|
||||
aom_cdf_prob compound_type_cdf[BLOCK_SIZES_ALL]
|
||||
[CDF_SIZE(MASKED_COMPOUND_TYPES)];
|
||||
aom_cdf_prob wedge_idx_cdf[BLOCK_SIZES_ALL][CDF_SIZE(16)];
|
||||
aom_cdf_prob interintra_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(2)];
|
||||
aom_cdf_prob wedge_interintra_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)];
|
||||
|
|
|
|||
42
third_party/aom/av1/common/enums.h
vendored
42
third_party/aom/av1/common/enums.h
vendored
|
|
@ -92,15 +92,6 @@ enum {
|
|||
MAX_PROFILES,
|
||||
} SENUM1BYTE(BITSTREAM_PROFILE);
|
||||
|
||||
#define LEVEL_MAJOR_BITS 3
|
||||
#define LEVEL_MINOR_BITS 2
|
||||
#define LEVEL_BITS (LEVEL_MAJOR_BITS + LEVEL_MINOR_BITS)
|
||||
|
||||
#define LEVEL_MAJOR_MIN 2
|
||||
#define LEVEL_MAJOR_MAX ((1 << LEVEL_MAJOR_BITS) - 1 + LEVEL_MAJOR_MIN)
|
||||
#define LEVEL_MINOR_MIN 0
|
||||
#define LEVEL_MINOR_MAX ((1 << LEVEL_MINOR_BITS) - 1)
|
||||
|
||||
#define OP_POINTS_CNT_MINUS_1_BITS 5
|
||||
#define OP_POINTS_IDC_BITS 12
|
||||
|
||||
|
|
@ -455,9 +446,11 @@ enum {
|
|||
|
||||
enum {
|
||||
COMPOUND_AVERAGE,
|
||||
COMPOUND_DISTWTD,
|
||||
COMPOUND_WEDGE,
|
||||
COMPOUND_DIFFWTD,
|
||||
COMPOUND_TYPES,
|
||||
MASKED_COMPOUND_TYPES = 2,
|
||||
} UENUM1BYTE(COMPOUND_TYPE);
|
||||
|
||||
enum {
|
||||
|
|
@ -469,6 +462,37 @@ enum {
|
|||
FILTER_INTRA_MODES,
|
||||
} UENUM1BYTE(FILTER_INTRA_MODE);
|
||||
|
||||
enum {
|
||||
SEQ_LEVEL_2_0,
|
||||
SEQ_LEVEL_2_1,
|
||||
SEQ_LEVEL_2_2,
|
||||
SEQ_LEVEL_2_3,
|
||||
SEQ_LEVEL_3_0,
|
||||
SEQ_LEVEL_3_1,
|
||||
SEQ_LEVEL_3_2,
|
||||
SEQ_LEVEL_3_3,
|
||||
SEQ_LEVEL_4_0,
|
||||
SEQ_LEVEL_4_1,
|
||||
SEQ_LEVEL_4_2,
|
||||
SEQ_LEVEL_4_3,
|
||||
SEQ_LEVEL_5_0,
|
||||
SEQ_LEVEL_5_1,
|
||||
SEQ_LEVEL_5_2,
|
||||
SEQ_LEVEL_5_3,
|
||||
SEQ_LEVEL_6_0,
|
||||
SEQ_LEVEL_6_1,
|
||||
SEQ_LEVEL_6_2,
|
||||
SEQ_LEVEL_6_3,
|
||||
SEQ_LEVEL_7_0,
|
||||
SEQ_LEVEL_7_1,
|
||||
SEQ_LEVEL_7_2,
|
||||
SEQ_LEVEL_7_3,
|
||||
SEQ_LEVELS,
|
||||
SEQ_LEVEL_MAX = 31
|
||||
} UENUM1BYTE(AV1_LEVEL);
|
||||
|
||||
#define LEVEL_BITS 5
|
||||
|
||||
#define DIRECTIONAL_MODES 8
|
||||
#define MAX_ANGLE_DELTA 3
|
||||
#define ANGLE_STEP 3
|
||||
|
|
|
|||
28
third_party/aom/av1/common/mvref_common.c
vendored
28
third_party/aom/av1/common/mvref_common.c
vendored
|
|
@ -821,7 +821,7 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
|
|||
MV_REFERENCE_FRAME rf[2];
|
||||
av1_set_ref_frame(rf, ref_frame);
|
||||
|
||||
if (ref_frame < REF_FRAMES) {
|
||||
if (global_mvs != NULL && ref_frame < REF_FRAMES) {
|
||||
if (ref_frame != INTRA_FRAME) {
|
||||
global_mvs[ref_frame] = gm_get_motion_vector(
|
||||
&cm->global_motion[ref_frame], cm->allow_high_precision_mv, bsize,
|
||||
|
|
@ -1362,15 +1362,15 @@ static int compare_ref_frame_info(const void *arg_a, const void *arg_b) {
|
|||
return info_a->map_idx - info_b->map_idx;
|
||||
}
|
||||
|
||||
static void set_ref_frame_info(AV1_COMMON *const cm, int frame_idx,
|
||||
static void set_ref_frame_info(int *remapped_ref_idx, int frame_idx,
|
||||
REF_FRAME_INFO *ref_info) {
|
||||
assert(frame_idx >= 0 && frame_idx < INTER_REFS_PER_FRAME);
|
||||
|
||||
cm->remapped_ref_idx[frame_idx] = ref_info->map_idx;
|
||||
remapped_ref_idx[frame_idx] = ref_info->map_idx;
|
||||
}
|
||||
|
||||
void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
||||
int gld_map_idx) {
|
||||
void av1_set_frame_refs(AV1_COMMON *const cm, int *remapped_ref_idx,
|
||||
int lst_map_idx, int gld_map_idx) {
|
||||
int lst_frame_sort_idx = -1;
|
||||
int gld_frame_sort_idx = -1;
|
||||
|
||||
|
|
@ -1395,8 +1395,6 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
if (buf == NULL) continue;
|
||||
// If this assertion fails, there is a reference leak.
|
||||
assert(buf->ref_count > 0);
|
||||
// TODO(wtc@google.com): Remove the checking on ref_count after 2019-03-01.
|
||||
if (buf->ref_count <= 0) continue;
|
||||
|
||||
const int offset = (int)buf->order_hint;
|
||||
ref_frame_info[i].sort_idx =
|
||||
|
|
@ -1449,7 +1447,7 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
|
||||
// == ALTREF_FRAME ==
|
||||
if (bwd_start_idx <= bwd_end_idx) {
|
||||
set_ref_frame_info(cm, ALTREF_FRAME - LAST_FRAME,
|
||||
set_ref_frame_info(remapped_ref_idx, ALTREF_FRAME - LAST_FRAME,
|
||||
&ref_frame_info[bwd_end_idx]);
|
||||
ref_flag_list[ALTREF_FRAME - LAST_FRAME] = 1;
|
||||
bwd_end_idx--;
|
||||
|
|
@ -1457,7 +1455,7 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
|
||||
// == BWDREF_FRAME ==
|
||||
if (bwd_start_idx <= bwd_end_idx) {
|
||||
set_ref_frame_info(cm, BWDREF_FRAME - LAST_FRAME,
|
||||
set_ref_frame_info(remapped_ref_idx, BWDREF_FRAME - LAST_FRAME,
|
||||
&ref_frame_info[bwd_start_idx]);
|
||||
ref_flag_list[BWDREF_FRAME - LAST_FRAME] = 1;
|
||||
bwd_start_idx++;
|
||||
|
|
@ -1465,7 +1463,7 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
|
||||
// == ALTREF2_FRAME ==
|
||||
if (bwd_start_idx <= bwd_end_idx) {
|
||||
set_ref_frame_info(cm, ALTREF2_FRAME - LAST_FRAME,
|
||||
set_ref_frame_info(remapped_ref_idx, ALTREF2_FRAME - LAST_FRAME,
|
||||
&ref_frame_info[bwd_start_idx]);
|
||||
ref_flag_list[ALTREF2_FRAME - LAST_FRAME] = 1;
|
||||
}
|
||||
|
|
@ -1475,13 +1473,15 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
for (int i = fwd_start_idx; i <= fwd_end_idx; ++i) {
|
||||
// == LAST_FRAME ==
|
||||
if (ref_frame_info[i].map_idx == lst_map_idx) {
|
||||
set_ref_frame_info(cm, LAST_FRAME - LAST_FRAME, &ref_frame_info[i]);
|
||||
set_ref_frame_info(remapped_ref_idx, LAST_FRAME - LAST_FRAME,
|
||||
&ref_frame_info[i]);
|
||||
ref_flag_list[LAST_FRAME - LAST_FRAME] = 1;
|
||||
}
|
||||
|
||||
// == GOLDEN_FRAME ==
|
||||
if (ref_frame_info[i].map_idx == gld_map_idx) {
|
||||
set_ref_frame_info(cm, GOLDEN_FRAME - LAST_FRAME, &ref_frame_info[i]);
|
||||
set_ref_frame_info(remapped_ref_idx, GOLDEN_FRAME - LAST_FRAME,
|
||||
&ref_frame_info[i]);
|
||||
ref_flag_list[GOLDEN_FRAME - LAST_FRAME] = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1513,7 +1513,7 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
}
|
||||
if (fwd_start_idx > fwd_end_idx) break;
|
||||
|
||||
set_ref_frame_info(cm, ref_frame - LAST_FRAME,
|
||||
set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME,
|
||||
&ref_frame_info[fwd_end_idx]);
|
||||
ref_flag_list[ref_frame - LAST_FRAME] = 1;
|
||||
|
||||
|
|
@ -1524,7 +1524,7 @@ void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx,
|
|||
for (; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) {
|
||||
const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx];
|
||||
if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue;
|
||||
set_ref_frame_info(cm, ref_frame - LAST_FRAME,
|
||||
set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME,
|
||||
&ref_frame_info[fwd_start_idx]);
|
||||
ref_flag_list[ref_frame - LAST_FRAME] = 1;
|
||||
}
|
||||
|
|
|
|||
6
third_party/aom/av1/common/mvref_common.h
vendored
6
third_party/aom/av1/common/mvref_common.h
vendored
|
|
@ -210,7 +210,8 @@ void av1_setup_frame_buf_refs(AV1_COMMON *cm);
|
|||
void av1_setup_frame_sign_bias(AV1_COMMON *cm);
|
||||
void av1_setup_skip_mode_allowed(AV1_COMMON *cm);
|
||||
void av1_setup_motion_field(AV1_COMMON *cm);
|
||||
void av1_set_frame_refs(AV1_COMMON *const cm, int lst_map_idx, int gld_map_idx);
|
||||
void av1_set_frame_refs(AV1_COMMON *const cm, int *remapped_ref_idx,
|
||||
int lst_map_idx, int gld_map_idx);
|
||||
|
||||
static INLINE void av1_collect_neighbors_ref_counts(MACROBLOCKD *const xd) {
|
||||
av1_zero(xd->neighbors_ref_counts);
|
||||
|
|
@ -243,6 +244,9 @@ void av1_copy_frame_mvs(const AV1_COMMON *const cm,
|
|||
const MB_MODE_INFO *const mi, int mi_row, int mi_col,
|
||||
int x_mis, int y_mis);
|
||||
|
||||
// The global_mvs output parameter points to an array of REF_FRAMES elements.
|
||||
// The caller may pass a null global_mvs if it does not need the global_mvs
|
||||
// output.
|
||||
void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
|
||||
MB_MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
|
||||
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES],
|
||||
|
|
|
|||
52
third_party/aom/av1/common/onyxc_int.h
vendored
52
third_party/aom/av1/common/onyxc_int.h
vendored
|
|
@ -109,18 +109,6 @@ typedef struct {
|
|||
MV_REFERENCE_FRAME ref_frame;
|
||||
} MV_REF;
|
||||
|
||||
// FIXME(jack.haughton@argondesign.com): This enum was originally in
|
||||
// encoder/ratectrl.h, and is encoder specific. When we move to C++, this
|
||||
// should go back there and BufferPool should be templatized.
|
||||
enum {
|
||||
INTER_NORMAL = 0,
|
||||
INTER_LOW = 1,
|
||||
INTER_HIGH = 2,
|
||||
GF_ARF_LOW = 3,
|
||||
GF_ARF_STD = 4,
|
||||
KF_STD = 5,
|
||||
RATE_FACTOR_LEVELS = 6
|
||||
} UENUM1BYTE(RATE_FACTOR_LEVEL);
|
||||
|
||||
typedef struct RefCntBuffer {
|
||||
// For a RefCntBuffer, the following are reference-holding variables:
|
||||
|
|
@ -136,8 +124,6 @@ typedef struct RefCntBuffer {
|
|||
// - Total 'n' of the variables / array elements above have value 'k' (that
|
||||
// is, they are pointing to buffer at index 'k').
|
||||
// Then, pool->frame_bufs[k].ref_count = n.
|
||||
// TODO(david.turner@argondesign.com) Check whether this helpful comment is
|
||||
// still correct after we finish restructuring
|
||||
int ref_count;
|
||||
|
||||
unsigned int order_hint;
|
||||
|
|
@ -161,6 +147,10 @@ typedef struct RefCntBuffer {
|
|||
hash_table hash_table;
|
||||
FRAME_TYPE frame_type;
|
||||
|
||||
// This is only used in the encoder but needs to be indexed per ref frame
|
||||
// so it's extremely convenient to keep it here.
|
||||
int interp_filter_selected[SWITCHABLE];
|
||||
|
||||
// Inter frame reference frame delta for loop filter
|
||||
int8_t ref_deltas[REF_FRAMES];
|
||||
|
||||
|
|
@ -168,7 +158,6 @@ typedef struct RefCntBuffer {
|
|||
int8_t mode_deltas[MAX_MODE_LF_DELTAS];
|
||||
|
||||
FRAME_CONTEXT frame_context;
|
||||
RATE_FACTOR_LEVEL frame_rf_level;
|
||||
} RefCntBuffer;
|
||||
|
||||
typedef struct BufferPool {
|
||||
|
|
@ -193,11 +182,6 @@ typedef struct BufferPool {
|
|||
InternalFrameBufferList int_frame_buffers;
|
||||
} BufferPool;
|
||||
|
||||
typedef struct BitstreamLevel {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
} BitstreamLevel;
|
||||
|
||||
typedef struct {
|
||||
int cdef_pri_damping;
|
||||
int cdef_sec_damping;
|
||||
|
|
@ -279,7 +263,7 @@ typedef struct SequenceHeader {
|
|||
int operating_point_idc[MAX_NUM_OPERATING_POINTS];
|
||||
uint8_t display_model_info_present_flag;
|
||||
uint8_t decoder_model_info_present_flag;
|
||||
BitstreamLevel level[MAX_NUM_OPERATING_POINTS];
|
||||
AV1_LEVEL seq_level_idx[MAX_NUM_OPERATING_POINTS];
|
||||
uint8_t tier[MAX_NUM_OPERATING_POINTS]; // seq_tier in the spec. One bit: 0
|
||||
// or 1.
|
||||
|
||||
|
|
@ -314,6 +298,7 @@ typedef struct {
|
|||
unsigned int frame_number;
|
||||
SkipModeInfo skip_mode_info;
|
||||
int refresh_frame_flags; // Which ref frames are overwritten by this frame
|
||||
int frame_refs_short_signaling;
|
||||
} CurrentFrame;
|
||||
|
||||
typedef struct AV1Common {
|
||||
|
|
@ -343,9 +328,9 @@ typedef struct AV1Common {
|
|||
|
||||
// For encoder, we have a two-level mapping from reference frame type to the
|
||||
// corresponding buffer in the buffer pool:
|
||||
// * 'remapped_ref_idx[i - 1]' maps reference type ‘i’ (range: LAST_FRAME ...
|
||||
// EXTREF_FRAME) to a remapped index ‘j’ (in range: 0 ... REF_FRAMES - 1)
|
||||
// * Later, 'cm->ref_frame_map[j]' maps the remapped index ‘j’ to a pointer to
|
||||
// * 'remapped_ref_idx[i - 1]' maps reference type 'i' (range: LAST_FRAME ...
|
||||
// EXTREF_FRAME) to a remapped index 'j' (in range: 0 ... REF_FRAMES - 1)
|
||||
// * Later, 'cm->ref_frame_map[j]' maps the remapped index 'j' to a pointer to
|
||||
// the reference counted buffer structure RefCntBuffer, taken from the buffer
|
||||
// pool cm->buffer_pool->frame_bufs.
|
||||
//
|
||||
|
|
@ -364,10 +349,10 @@ typedef struct AV1Common {
|
|||
struct scale_factors ref_scale_factors[REF_FRAMES];
|
||||
|
||||
// For decoder, ref_frame_map[i] maps reference type 'i' to a pointer to
|
||||
// the buffer in the buffer pool ‘cm->buffer_pool.frame_bufs’.
|
||||
// the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'.
|
||||
// For encoder, ref_frame_map[j] (where j = remapped_ref_idx[i]) maps
|
||||
// remapped reference index 'j' (that is, original reference type 'i') to
|
||||
// a pointer to the buffer in the buffer pool ‘cm->buffer_pool.frame_bufs’.
|
||||
// a pointer to the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'.
|
||||
RefCntBuffer *ref_frame_map[REF_FRAMES];
|
||||
|
||||
// Prepare ref_frame_map for the next frame.
|
||||
|
|
@ -517,6 +502,7 @@ typedef struct AV1Common {
|
|||
int tile_col_start_sb[MAX_TILE_COLS + 1]; // valid for 0 <= i <= tile_cols
|
||||
int tile_row_start_sb[MAX_TILE_ROWS + 1]; // valid for 0 <= i <= tile_rows
|
||||
int tile_width, tile_height; // In MI units
|
||||
int min_inner_tile_width; // min width of non-rightmost tile
|
||||
|
||||
unsigned int large_scale_tile;
|
||||
unsigned int single_tile_decoding;
|
||||
|
|
@ -642,6 +628,7 @@ static INLINE RefCntBuffer *assign_cur_frame_new_fb(AV1_COMMON *const cm) {
|
|||
|
||||
cm->cur_frame = &cm->buffer_pool->frame_bufs[new_fb_idx];
|
||||
cm->cur_frame->buf.buf_8bit_valid = 0;
|
||||
av1_zero(cm->cur_frame->interp_filter_selected);
|
||||
return cm->cur_frame;
|
||||
}
|
||||
|
||||
|
|
@ -1385,17 +1372,8 @@ static INLINE int is_coded_lossless(const AV1_COMMON *cm,
|
|||
return coded_lossless;
|
||||
}
|
||||
|
||||
static INLINE int is_valid_seq_level_idx(uint8_t seq_level_idx) {
|
||||
return seq_level_idx < 24 || seq_level_idx == 31;
|
||||
}
|
||||
|
||||
static INLINE uint8_t major_minor_to_seq_level_idx(BitstreamLevel bl) {
|
||||
assert(bl.major >= LEVEL_MAJOR_MIN && bl.major <= LEVEL_MAJOR_MAX);
|
||||
// Since bl.minor is unsigned a comparison will return a warning:
|
||||
// comparison is always true due to limited range of data type
|
||||
assert(LEVEL_MINOR_MIN == 0);
|
||||
assert(bl.minor <= LEVEL_MINOR_MAX);
|
||||
return ((bl.major - LEVEL_MAJOR_MIN) << LEVEL_MINOR_BITS) + bl.minor;
|
||||
static INLINE int is_valid_seq_level_idx(AV1_LEVEL seq_level_idx) {
|
||||
return seq_level_idx < SEQ_LEVELS || seq_level_idx == SEQ_LEVEL_MAX;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
6
third_party/aom/av1/common/pred_common.h
vendored
6
third_party/aom/av1/common/pred_common.h
vendored
|
|
@ -59,9 +59,13 @@ static INLINE int av1_get_spatial_seg_pred(const AV1_COMMON *const cm,
|
|||
prev_l = get_segment_id(cm, cm->cur_frame->seg_map, BLOCK_4X4, mi_row - 0,
|
||||
mi_col - 1);
|
||||
}
|
||||
// This property follows from the fact that get_segment_id() returns a
|
||||
// nonnegative value. This allows us to test for all edge cases with a simple
|
||||
// prev_ul < 0 check.
|
||||
assert(IMPLIES(prev_ul >= 0, prev_u >= 0 && prev_l >= 0));
|
||||
|
||||
// Pick CDF index based on number of matching/out-of-bounds segment IDs.
|
||||
if (prev_ul < 0 || prev_u < 0 || prev_l < 0) /* Edge case */
|
||||
if (prev_ul < 0) /* Edge cases */
|
||||
*cdf_index = 0;
|
||||
else if ((prev_ul == prev_u) && (prev_ul == prev_l))
|
||||
*cdf_index = 2;
|
||||
|
|
|
|||
8
third_party/aom/av1/common/reconinter.h
vendored
8
third_party/aom/av1/common/reconinter.h
vendored
|
|
@ -167,6 +167,7 @@ static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
|
|||
const int comp_allowed = is_comp_ref_allowed(sb_type);
|
||||
switch (type) {
|
||||
case COMPOUND_AVERAGE:
|
||||
case COMPOUND_DISTWTD:
|
||||
case COMPOUND_DIFFWTD: return comp_allowed;
|
||||
case COMPOUND_WEDGE:
|
||||
return comp_allowed && wedge_params_lookup[sb_type].bits > 0;
|
||||
|
|
@ -245,13 +246,14 @@ static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
|
|||
return clamped_mv;
|
||||
}
|
||||
|
||||
static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
|
||||
const struct scale_factors *sf) {
|
||||
static INLINE int64_t 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) >> 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;
|
||||
return (int64_t)y * stride + x;
|
||||
}
|
||||
|
||||
static INLINE void setup_pred_plane(struct buf_2d *dst, BLOCK_SIZE bsize,
|
||||
|
|
|
|||
2
third_party/aom/av1/common/restoration.h
vendored
2
third_party/aom/av1/common/restoration.h
vendored
|
|
@ -22,7 +22,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Boarder for Loop restoration buffer
|
||||
// Border for Loop restoration buffer
|
||||
#define AOM_RESTORATION_FRAME_BORDER 32
|
||||
#define CLIP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
|
||||
#define RINT(x) ((x) < 0 ? (int)((x)-0.5) : (int)((x) + 0.5))
|
||||
|
|
|
|||
23
third_party/aom/av1/common/tile_common.c
vendored
23
third_party/aom/av1/common/tile_common.c
vendored
|
|
@ -51,6 +51,10 @@ void av1_calculate_tile_cols(AV1_COMMON *const cm) {
|
|||
int sb_rows = mi_rows >> cm->seq_params.mib_size_log2;
|
||||
int i;
|
||||
|
||||
// This will be overridden if there is at least two columns of tiles
|
||||
// (otherwise there is no inner tile width)
|
||||
cm->min_inner_tile_width = -1;
|
||||
|
||||
if (cm->uniform_tile_spacing_flag) {
|
||||
int start_sb;
|
||||
int size_sb = ALIGN_POWER_OF_TWO(sb_cols, cm->log2_tile_cols);
|
||||
|
|
@ -67,18 +71,29 @@ void av1_calculate_tile_cols(AV1_COMMON *const cm) {
|
|||
|
||||
cm->tile_width = size_sb << cm->seq_params.mib_size_log2;
|
||||
cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
|
||||
if (cm->tile_cols > 1) {
|
||||
cm->min_inner_tile_width = cm->tile_width;
|
||||
}
|
||||
} else {
|
||||
int max_tile_area_sb = (sb_rows * sb_cols);
|
||||
int widest_tile_sb = 1;
|
||||
int narrowest_inner_tile_sb = 65536;
|
||||
cm->log2_tile_cols = tile_log2(1, cm->tile_cols);
|
||||
for (i = 0; i < cm->tile_cols; i++) {
|
||||
int size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i];
|
||||
widest_tile_sb = AOMMAX(widest_tile_sb, size_sb);
|
||||
// ignore the rightmost tile in frame for determining the narrowest
|
||||
if (i < cm->tile_cols - 1)
|
||||
narrowest_inner_tile_sb = AOMMIN(narrowest_inner_tile_sb, size_sb);
|
||||
}
|
||||
if (cm->min_log2_tiles) {
|
||||
max_tile_area_sb >>= (cm->min_log2_tiles + 1);
|
||||
}
|
||||
cm->max_tile_height_sb = AOMMAX(max_tile_area_sb / widest_tile_sb, 1);
|
||||
if (cm->tile_cols > 1) {
|
||||
cm->min_inner_tile_width = narrowest_inner_tile_sb
|
||||
<< cm->seq_params.mib_size_log2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,3 +219,11 @@ void av1_get_uniform_tile_size(const AV1_COMMON *cm, int *w, int *h) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int is_min_tile_width_satisfied(const AV1_COMMON *cm) {
|
||||
// Disable check if there is a single tile col in the frame
|
||||
if (cm->tile_cols == 1) return 1;
|
||||
|
||||
return ((cm->min_inner_tile_width << MI_SIZE_LOG2) >=
|
||||
(64 << av1_superres_scaled(cm)));
|
||||
}
|
||||
|
|
|
|||
3
third_party/aom/av1/common/tile_common.h
vendored
3
third_party/aom/av1/common/tile_common.h
vendored
|
|
@ -59,6 +59,9 @@ void av1_get_tile_limits(struct AV1Common *const cm);
|
|||
void av1_calculate_tile_cols(struct AV1Common *const cm);
|
||||
void av1_calculate_tile_rows(struct AV1Common *const cm);
|
||||
|
||||
// Checks if the minimum tile_width requirement is satisfied
|
||||
int is_min_tile_width_satisfied(const struct AV1Common *cm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2920,8 +2920,18 @@ void av1_inv_txfm_add_ssse3(const tran_low_t *dqcoeff, uint8_t *dst, int stride,
|
|||
const TxfmParam *txfm_param) {
|
||||
const TX_TYPE tx_type = txfm_param->tx_type;
|
||||
if (!txfm_param->lossless) {
|
||||
av1_lowbd_inv_txfm2d_add_ssse3(dqcoeff, dst, stride, tx_type,
|
||||
txfm_param->tx_size, txfm_param->eob);
|
||||
switch (txfm_param->tx_size) {
|
||||
case TX_4X16:
|
||||
case TX_16X4:
|
||||
// TODO(http://crbug.com/aomedia/2350): the ssse3 versions cause test
|
||||
// vector mismatches.
|
||||
av1_inv_txfm_add_c(dqcoeff, dst, stride, txfm_param);
|
||||
break;
|
||||
default:
|
||||
av1_lowbd_inv_txfm2d_add_ssse3(dqcoeff, dst, stride, tx_type,
|
||||
txfm_param->tx_size, txfm_param->eob);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
av1_inv_txfm_add_c(dqcoeff, dst, stride, txfm_param);
|
||||
}
|
||||
|
|
|
|||
132
third_party/aom/av1/common/x86/convolve_2d_avx2.c
vendored
132
third_party/aom/av1/common/x86/convolve_2d_avx2.c
vendored
|
|
@ -27,31 +27,15 @@ void av1_convolve_2d_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
const int subpel_x_q4, const int subpel_y_q4,
|
||||
ConvolveParams *conv_params) {
|
||||
const int bd = 8;
|
||||
|
||||
DECLARE_ALIGNED(32, int16_t, im_block[(MAX_SB_SIZE + MAX_FILTER_TAP) * 8]);
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
int im_stride = 8;
|
||||
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;
|
||||
|
||||
int i, is_horiz_4tap = 0, is_vert_4tap = 0;
|
||||
DECLARE_ALIGNED(32, int16_t, im_block[(MAX_SB_SIZE + MAX_FILTER_TAP) * 8]);
|
||||
const int bits =
|
||||
FILTER_BITS * 2 - conv_params->round_0 - conv_params->round_1;
|
||||
const int offset_bits = bd + 2 * FILTER_BITS - conv_params->round_0;
|
||||
|
||||
__m256i filt[4], coeffs_h[4], coeffs_v[4];
|
||||
|
||||
assert(conv_params->round_0 > 0);
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs_h);
|
||||
prepare_coeffs(filter_params_y, subpel_y_q4, coeffs_v);
|
||||
|
||||
const __m256i round_const_h = _mm256_set1_epi16(
|
||||
((1 << (conv_params->round_0 - 1)) >> 1) + (1 << (bd + FILTER_BITS - 2)));
|
||||
const __m128i round_shift_h = _mm_cvtsi32_si128(conv_params->round_0 - 1);
|
||||
|
|
@ -65,58 +49,96 @@ void av1_convolve_2d_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
((1 << (offset_bits - conv_params->round_1)) >> 1));
|
||||
const __m128i round_shift_v = _mm_cvtsi32_si128(bits);
|
||||
|
||||
for (j = 0; j < w; j += 8) {
|
||||
for (i = 0; i < im_h; i += 2) {
|
||||
__m256i data = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j]));
|
||||
__m256i filt[4], coeffs_h[4], coeffs_v[4];
|
||||
|
||||
// Load the next line
|
||||
if (i + 1 < im_h)
|
||||
filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs_h);
|
||||
prepare_coeffs(filter_params_y, subpel_y_q4, coeffs_v);
|
||||
|
||||
// Condition for checking valid horz_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs_h[0], coeffs_h[3]), 0)))
|
||||
is_horiz_4tap = 1;
|
||||
|
||||
// Condition for checking valid vert_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs_v[0], coeffs_v[3]), 0)))
|
||||
is_vert_4tap = 1;
|
||||
|
||||
// horz_filt as 4 tap and vert_filt as 8 tap
|
||||
if (is_horiz_4tap) {
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const int fo_horiz = 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
|
||||
|
||||
// horz-filter
|
||||
for (int j = 0; j < w; j += 8) {
|
||||
for (i = 0; i < (im_h - 2); i += 2) {
|
||||
__m256i data = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j]));
|
||||
|
||||
// Load the next line
|
||||
data = _mm256_inserti128_si256(
|
||||
data,
|
||||
_mm_loadu_si128(
|
||||
(__m128i *)&src_ptr[(i * src_stride) + j + src_stride]),
|
||||
1);
|
||||
__m256i res = convolve_lowbd_x_4tap(data, coeffs_h + 1, filt);
|
||||
|
||||
__m256i res = convolve_lowbd_x(data, coeffs_h, filt);
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const_h),
|
||||
round_shift_h);
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res);
|
||||
}
|
||||
|
||||
__m256i data_1 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j]));
|
||||
|
||||
__m256i res = convolve_lowbd_x_4tap(data_1, coeffs_h + 1, filt);
|
||||
res =
|
||||
_mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h);
|
||||
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res);
|
||||
}
|
||||
|
||||
/* Vertical filter */
|
||||
{
|
||||
// vert filter
|
||||
CONVOLVE_SR_VERTICAL_FILTER_8TAP;
|
||||
}
|
||||
} else if (is_vert_4tap) {
|
||||
int im_h = h + 3;
|
||||
const int fo_vert = 1;
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
|
||||
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
for (int j = 0; j < w; j += 8) {
|
||||
// horz_filter
|
||||
CONVOLVE_SR_HORIZONTAL_FILTER_8TAP;
|
||||
// vert_filter
|
||||
__m256i s[6];
|
||||
__m256i src_0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride));
|
||||
__m256i src_1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride));
|
||||
__m256i src_2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride));
|
||||
__m256i src_3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride));
|
||||
__m256i src_4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride));
|
||||
__m256i src_5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride));
|
||||
|
||||
__m256i s[8];
|
||||
s[0] = _mm256_unpacklo_epi16(src_0, src_1);
|
||||
s[1] = _mm256_unpacklo_epi16(src_2, src_3);
|
||||
s[2] = _mm256_unpacklo_epi16(src_4, src_5);
|
||||
|
||||
s[4] = _mm256_unpackhi_epi16(src_0, src_1);
|
||||
s[5] = _mm256_unpackhi_epi16(src_2, src_3);
|
||||
s[6] = _mm256_unpackhi_epi16(src_4, src_5);
|
||||
s[3] = _mm256_unpackhi_epi16(src_0, src_1);
|
||||
s[4] = _mm256_unpackhi_epi16(src_2, src_3);
|
||||
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const int16_t *data = &im_block[i * im_stride];
|
||||
|
||||
const __m256i s6 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 6 * im_stride));
|
||||
const __m256i s7 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 7 * im_stride));
|
||||
const __m256i s4 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 4 * im_stride));
|
||||
const __m256i s5 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 5 * im_stride));
|
||||
|
||||
s[3] = _mm256_unpacklo_epi16(s6, s7);
|
||||
s[7] = _mm256_unpackhi_epi16(s6, s7);
|
||||
s[2] = _mm256_unpacklo_epi16(s4, s5);
|
||||
s[5] = _mm256_unpackhi_epi16(s4, s5);
|
||||
|
||||
__m256i res_a = convolve(s, coeffs_v);
|
||||
__m256i res_b = convolve(s + 4, coeffs_v);
|
||||
__m256i res_a = convolve_4tap(s, coeffs_v + 1);
|
||||
__m256i res_b = convolve_4tap(s + 3, coeffs_v + 1);
|
||||
|
||||
// Combine V round and 2F-H-V round into a single rounding
|
||||
res_a =
|
||||
|
|
@ -154,13 +176,25 @@ void av1_convolve_2d_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[3] = s[4];
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
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;
|
||||
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
for (j = 0; j < w; j += 8) {
|
||||
CONVOLVE_SR_HORIZONTAL_FILTER_8TAP;
|
||||
|
||||
CONVOLVE_SR_VERTICAL_FILTER_8TAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
484
third_party/aom/av1/common/x86/convolve_avx2.c
vendored
484
third_party/aom/av1/common/x86/convolve_avx2.c
vendored
|
|
@ -23,153 +23,239 @@ void av1_convolve_y_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
const InterpFilterParams *filter_params_y,
|
||||
const int subpel_x_q4, const int subpel_y_q4,
|
||||
ConvolveParams *conv_params) {
|
||||
int i, j;
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
|
||||
int i, j, is_vert_4tap = 0;
|
||||
// right shift is F-1 because we are already dividing
|
||||
// filter co-efficients by 2
|
||||
const int right_shift_bits = (FILTER_BITS - 1);
|
||||
const __m128i right_shift = _mm_cvtsi32_si128(right_shift_bits);
|
||||
const __m256i right_shift_const =
|
||||
_mm256_set1_epi16((1 << right_shift_bits) >> 1);
|
||||
__m256i coeffs[4], s[8];
|
||||
|
||||
assert(conv_params->round_0 <= FILTER_BITS);
|
||||
assert(((conv_params->round_0 + conv_params->round_1) <= (FILTER_BITS + 1)) ||
|
||||
((conv_params->round_0 + conv_params->round_1) == (2 * FILTER_BITS)));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_y, subpel_y_q4, coeffs);
|
||||
|
||||
(void)filter_params_x;
|
||||
(void)subpel_x_q4;
|
||||
(void)conv_params;
|
||||
__m256i coeffs[4], s[8];
|
||||
__m128i d[6];
|
||||
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
__m256i src6;
|
||||
prepare_coeffs_lowbd(filter_params_y, subpel_y_q4, coeffs);
|
||||
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
const __m256i src_01a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 0 * src_stride))),
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 1 * src_stride))),
|
||||
0x20);
|
||||
// Condition for checking valid vert_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs[0], coeffs[3]), 0)))
|
||||
is_vert_4tap = 1;
|
||||
|
||||
const __m256i src_12a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 1 * src_stride))),
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 2 * src_stride))),
|
||||
0x20);
|
||||
// vert_filt as 4 tap
|
||||
if (is_vert_4tap) {
|
||||
const int fo_vert = 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
d[0] = _mm_loadu_si128((__m128i *)(data + 0 * src_stride));
|
||||
d[1] = _mm_loadu_si128((__m128i *)(data + 1 * src_stride));
|
||||
d[2] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
|
||||
d[3] = _mm_loadu_si128((__m128i *)(data + 3 * src_stride));
|
||||
d[4] = _mm_loadu_si128((__m128i *)(data + 4 * src_stride));
|
||||
|
||||
const __m256i src_23a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 2 * src_stride))),
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 3 * src_stride))),
|
||||
0x20);
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
const __m256i src_01a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[0]), _mm256_castsi128_si256(d[1]), 0x20);
|
||||
|
||||
const __m256i src_34a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 3 * src_stride))),
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 4 * src_stride))),
|
||||
0x20);
|
||||
const __m256i src_12a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[1]), _mm256_castsi128_si256(d[2]), 0x20);
|
||||
|
||||
const __m256i src_45a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 4 * src_stride))),
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 5 * src_stride))),
|
||||
0x20);
|
||||
const __m256i src_23a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[2]), _mm256_castsi128_si256(d[3]), 0x20);
|
||||
|
||||
src6 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 6 * src_stride)));
|
||||
const __m256i src_56a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 5 * src_stride))),
|
||||
src6, 0x20);
|
||||
const __m256i src_34a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[3]), _mm256_castsi128_si256(d[4]), 0x20);
|
||||
|
||||
s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
|
||||
s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
|
||||
s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
|
||||
s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
|
||||
s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
|
||||
|
||||
s[4] = _mm256_unpackhi_epi8(src_01a, src_12a);
|
||||
s[5] = _mm256_unpackhi_epi8(src_23a, src_34a);
|
||||
s[6] = _mm256_unpackhi_epi8(src_45a, src_56a);
|
||||
s[3] = _mm256_unpackhi_epi8(src_01a, src_12a);
|
||||
s[4] = _mm256_unpackhi_epi8(src_23a, src_34a);
|
||||
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[i * src_stride + j];
|
||||
const __m256i src_67a = _mm256_permute2x128_si256(
|
||||
src6,
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 7 * src_stride))),
|
||||
0x20);
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[i * src_stride + j];
|
||||
d[5] = _mm_loadu_si128((__m128i *)(data + 5 * src_stride));
|
||||
const __m256i src_45a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[4]), _mm256_castsi128_si256(d[5]), 0x20);
|
||||
|
||||
d[4] = _mm_loadu_si128((__m128i *)(data + 6 * src_stride));
|
||||
const __m256i src_56a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[5]), _mm256_castsi128_si256(d[4]), 0x20);
|
||||
|
||||
s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
|
||||
s[5] = _mm256_unpackhi_epi8(src_45a, src_56a);
|
||||
|
||||
const __m256i res_lo = convolve_lowbd_4tap(s, coeffs + 1);
|
||||
/* rounding code */
|
||||
// shift by F - 1
|
||||
const __m256i res_16b_lo = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_lo, right_shift_const), right_shift);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
|
||||
|
||||
if (w - j > 8) {
|
||||
const __m256i res_hi = convolve_lowbd_4tap(s + 3, coeffs + 1);
|
||||
|
||||
/* rounding code */
|
||||
// shift by F - 1
|
||||
const __m256i res_16b_hi = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_hi, right_shift_const), right_shift);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b_hi = _mm256_packus_epi16(res_16b_hi, res_16b_hi);
|
||||
|
||||
__m256i res_a = _mm256_unpacklo_epi64(res_8b_lo, res_8b_hi);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_a);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_a, 1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
res_1);
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b_lo);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
res_1);
|
||||
} else if (w - j > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride + j], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + j + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
|
||||
__m128i *const p_1 =
|
||||
(__m128i *)&dst[i * dst_stride + j + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
}
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
|
||||
s[3] = s[4];
|
||||
s[4] = s[5];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
__m256i src6;
|
||||
|
||||
d[0] = _mm_loadu_si128((__m128i *)(data + 0 * src_stride));
|
||||
d[1] = _mm_loadu_si128((__m128i *)(data + 1 * src_stride));
|
||||
d[2] = _mm_loadu_si128((__m128i *)(data + 2 * src_stride));
|
||||
d[3] = _mm_loadu_si128((__m128i *)(data + 3 * src_stride));
|
||||
d[4] = _mm_loadu_si128((__m128i *)(data + 4 * src_stride));
|
||||
d[5] = _mm_loadu_si128((__m128i *)(data + 5 * src_stride));
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
const __m256i src_01a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[0]), _mm256_castsi128_si256(d[1]), 0x20);
|
||||
|
||||
const __m256i src_12a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[1]), _mm256_castsi128_si256(d[2]), 0x20);
|
||||
|
||||
const __m256i src_23a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[2]), _mm256_castsi128_si256(d[3]), 0x20);
|
||||
|
||||
const __m256i src_34a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[3]), _mm256_castsi128_si256(d[4]), 0x20);
|
||||
|
||||
const __m256i src_45a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(d[4]), _mm256_castsi128_si256(d[5]), 0x20);
|
||||
|
||||
src6 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 8 * src_stride)));
|
||||
const __m256i src_78a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 7 * src_stride))),
|
||||
src6, 0x20);
|
||||
_mm_loadu_si128((__m128i *)(data + 6 * src_stride)));
|
||||
const __m256i src_56a =
|
||||
_mm256_permute2x128_si256(_mm256_castsi128_si256(d[5]), src6, 0x20);
|
||||
|
||||
s[3] = _mm256_unpacklo_epi8(src_67a, src_78a);
|
||||
s[7] = _mm256_unpackhi_epi8(src_67a, src_78a);
|
||||
s[0] = _mm256_unpacklo_epi8(src_01a, src_12a);
|
||||
s[1] = _mm256_unpacklo_epi8(src_23a, src_34a);
|
||||
s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
|
||||
|
||||
const __m256i res_lo = convolve_lowbd(s, coeffs);
|
||||
s[4] = _mm256_unpackhi_epi8(src_01a, src_12a);
|
||||
s[5] = _mm256_unpackhi_epi8(src_23a, src_34a);
|
||||
s[6] = _mm256_unpackhi_epi8(src_45a, src_56a);
|
||||
|
||||
/* rounding code */
|
||||
// shift by F - 1
|
||||
const __m256i res_16b_lo = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_lo, right_shift_const), right_shift);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[i * src_stride + j];
|
||||
const __m256i src_67a = _mm256_permute2x128_si256(
|
||||
src6,
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 7 * src_stride))),
|
||||
0x20);
|
||||
|
||||
if (w - j > 8) {
|
||||
const __m256i res_hi = convolve_lowbd(s + 4, coeffs);
|
||||
src6 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 8 * src_stride)));
|
||||
const __m256i src_78a = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + 7 * src_stride))),
|
||||
src6, 0x20);
|
||||
|
||||
s[3] = _mm256_unpacklo_epi8(src_67a, src_78a);
|
||||
s[7] = _mm256_unpackhi_epi8(src_67a, src_78a);
|
||||
|
||||
const __m256i res_lo = convolve_lowbd(s, coeffs);
|
||||
|
||||
/* rounding code */
|
||||
// shift by F - 1
|
||||
const __m256i res_16b_hi = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_hi, right_shift_const), right_shift);
|
||||
const __m256i res_16b_lo = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_lo, right_shift_const), right_shift);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b_hi = _mm256_packus_epi16(res_16b_hi, res_16b_hi);
|
||||
__m256i res_8b_lo = _mm256_packus_epi16(res_16b_lo, res_16b_lo);
|
||||
|
||||
__m256i res_a = _mm256_unpacklo_epi64(res_8b_lo, res_8b_hi);
|
||||
if (w - j > 8) {
|
||||
const __m256i res_hi = convolve_lowbd(s + 4, coeffs);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_a);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_a, 1);
|
||||
/* rounding code */
|
||||
// shift by F - 1
|
||||
const __m256i res_16b_hi = _mm256_sra_epi16(
|
||||
_mm256_add_epi16(res_hi, right_shift_const), right_shift);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b_hi = _mm256_packus_epi16(res_16b_hi, res_16b_hi);
|
||||
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
res_1);
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b_lo);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
__m256i res_a = _mm256_unpacklo_epi64(res_8b_lo, res_8b_hi);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_a);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_a, 1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
res_1);
|
||||
} else if (w - j > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride + j], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + j + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + j + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b_lo);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b_lo, 1);
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + j + dst_stride],
|
||||
res_1);
|
||||
} else if (w - j > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride + j], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + j + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
|
||||
__m128i *const p_1 =
|
||||
(__m128i *)&dst[i * dst_stride + j + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
}
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
}
|
||||
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -180,26 +266,14 @@ void av1_convolve_x_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
const InterpFilterParams *filter_params_y,
|
||||
const int subpel_x_q4, const int subpel_y_q4,
|
||||
ConvolveParams *conv_params) {
|
||||
int i, j;
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
const int bits = FILTER_BITS - conv_params->round_0;
|
||||
|
||||
__m256i filt[4], coeffs[4];
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs);
|
||||
|
||||
const __m256i round_0_const =
|
||||
_mm256_set1_epi16((1 << (conv_params->round_0 - 1)) >> 1);
|
||||
const __m128i round_0_shift = _mm_cvtsi32_si128(conv_params->round_0 - 1);
|
||||
const __m256i round_const = _mm256_set1_epi16((1 << bits) >> 1);
|
||||
const __m128i round_shift = _mm_cvtsi32_si128(bits);
|
||||
|
||||
int i, is_horiz_4tap = 0;
|
||||
(void)filter_params_y;
|
||||
(void)subpel_y_q4;
|
||||
|
||||
|
|
@ -208,51 +282,101 @@ void av1_convolve_x_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
((conv_params->round_0 + conv_params->round_1) == 2 * FILTER_BITS));
|
||||
assert(conv_params->round_0 > 0);
|
||||
|
||||
if (w <= 8) {
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const __m256i data = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride]))),
|
||||
_mm256_castsi128_si256(_mm_loadu_si128(
|
||||
(__m128i *)(&src_ptr[i * src_stride + src_stride]))),
|
||||
0x20);
|
||||
__m256i coeffs[4], filt[4];
|
||||
filt[0] = _mm256_load_si256((__m256i const *)(filt_global_avx2));
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
|
||||
__m256i res_16b = convolve_lowbd_x(data, coeffs, filt);
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_0_const),
|
||||
round_0_shift);
|
||||
// Condition for checking valid horz_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs[0], coeffs[3]), 0)))
|
||||
is_horiz_4tap = 1;
|
||||
|
||||
res_16b =
|
||||
_mm256_sra_epi16(_mm256_add_epi16(res_16b, round_const), round_shift);
|
||||
// horz_filt as 4 tap
|
||||
if (is_horiz_4tap) {
|
||||
const int fo_horiz = 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
if (w <= 8) {
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const __m256i data = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride]))),
|
||||
_mm256_castsi128_si256(_mm_loadu_si128(
|
||||
(__m128i *)(&src_ptr[i * src_stride + src_stride]))),
|
||||
0x20);
|
||||
|
||||
/* rounding code */
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
|
||||
__m256i res_16b = convolve_lowbd_x_4tap(data, coeffs + 1, filt);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else if (w > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride];
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_0_const),
|
||||
round_0_shift);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_const),
|
||||
round_shift);
|
||||
|
||||
/* rounding code */
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
|
||||
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else if (w > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride];
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (int j = 0; j < w; j += 16) {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 8 9 10 11 12 13 14 15 16 17
|
||||
// 18 19 20 21 22 23
|
||||
const __m256i data = _mm256_inserti128_si256(
|
||||
_mm256_loadu_si256((__m256i *)&src_ptr[(i * src_stride) + j]),
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + (j + 8)]),
|
||||
1);
|
||||
|
||||
__m256i res_16b = convolve_lowbd_x_4tap(data, coeffs + 1, filt);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_0_const),
|
||||
round_0_shift);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_const),
|
||||
round_shift);
|
||||
|
||||
/* rounding code */
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
|
||||
|
||||
// Store values into the destination buffer
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
res_8b = _mm256_permute4x64_epi64(res_8b, 216);
|
||||
__m128i res = _mm256_castsi256_si128(res_8b);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; j += 16) {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 8 9 10 11 12 13 14 15 16 17 18
|
||||
// 19 20 21 22 23
|
||||
const __m256i data = _mm256_inserti128_si256(
|
||||
_mm256_loadu_si256((__m256i *)&src_ptr[(i * src_stride) + j]),
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + (j + 8)]),
|
||||
1);
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
if (w <= 8) {
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const __m256i data = _mm256_permute2x128_si256(
|
||||
_mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(&src_ptr[i * src_stride]))),
|
||||
_mm256_castsi128_si256(_mm_loadu_si128(
|
||||
(__m128i *)(&src_ptr[i * src_stride + src_stride]))),
|
||||
0x20);
|
||||
|
||||
__m256i res_16b = convolve_lowbd_x(data, coeffs, filt);
|
||||
|
||||
|
|
@ -266,11 +390,49 @@ void av1_convolve_x_sr_avx2(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
|
||||
|
||||
// Store values into the destination buffer
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
res_8b = _mm256_permute4x64_epi64(res_8b, 216);
|
||||
__m128i res = _mm256_castsi256_si128(res_8b);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride], res_0);
|
||||
_mm_storel_epi64((__m128i *)&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else if (w > 2) {
|
||||
xx_storel_32(&dst[i * dst_stride], res_0);
|
||||
xx_storel_32(&dst[i * dst_stride + dst_stride], res_1);
|
||||
} else {
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride];
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + dst_stride];
|
||||
*(uint16_t *)p_0 = _mm_cvtsi128_si32(res_0);
|
||||
*(uint16_t *)p_1 = _mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (int j = 0; j < w; j += 16) {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 8 9 10 11 12 13 14 15 16 17
|
||||
// 18 19 20 21 22 23
|
||||
const __m256i data = _mm256_inserti128_si256(
|
||||
_mm256_loadu_si256((__m256i *)&src_ptr[(i * src_stride) + j]),
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + (j + 8)]),
|
||||
1);
|
||||
|
||||
__m256i res_16b = convolve_lowbd_x(data, coeffs, filt);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_0_const),
|
||||
round_0_shift);
|
||||
|
||||
res_16b = _mm256_sra_epi16(_mm256_add_epi16(res_16b, round_const),
|
||||
round_shift);
|
||||
|
||||
/* rounding code */
|
||||
// 8 bit conversion and saturation to uint8
|
||||
__m256i res_8b = _mm256_packus_epi16(res_16b, res_16b);
|
||||
|
||||
// Store values into the destination buffer
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
res_8b = _mm256_permute4x64_epi64(res_8b, 216);
|
||||
__m128i res = _mm256_castsi256_si128(res_8b);
|
||||
_mm_storeu_si128((__m128i *)&dst[i * dst_stride + j], res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5926,28 +5926,16 @@ void av1_highbd_inv_txfm_add_sse4_1(const tran_low_t *input, uint8_t *dest,
|
|||
assert(av1_ext_tx_used[txfm_param->tx_set_type][txfm_param->tx_type]);
|
||||
const TX_SIZE tx_size = txfm_param->tx_size;
|
||||
switch (tx_size) {
|
||||
case TX_8X8:
|
||||
av1_highbd_inv_txfm_add_8x8_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
case TX_4X8:
|
||||
av1_highbd_inv_txfm_add_4x8_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
case TX_8X4:
|
||||
av1_highbd_inv_txfm_add_8x4_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
case TX_4X4:
|
||||
av1_highbd_inv_txfm_add_4x4_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
case TX_16X4:
|
||||
av1_highbd_inv_txfm_add_16x4_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
case TX_4X16:
|
||||
av1_highbd_inv_txfm_add_4x16_sse4_1(input, dest, stride, txfm_param);
|
||||
break;
|
||||
default:
|
||||
av1_highbd_inv_txfm2d_add_universe_sse4_1(
|
||||
input, dest, stride, txfm_param->tx_type, tx_size, txfm_param->eob,
|
||||
txfm_param->bd);
|
||||
// TODO(http://crbug.com/aomedia/2350): the remaining sse4_1 versions
|
||||
// cause test vector mismatches.
|
||||
av1_highbd_inv_txfm_add_c(input, dest, stride, txfm_param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
747
third_party/aom/av1/common/x86/jnt_convolve_avx2.c
vendored
747
third_party/aom/av1/common/x86/jnt_convolve_avx2.c
vendored
|
|
@ -44,9 +44,7 @@ void av1_dist_wtd_convolve_x_avx2(const uint8_t *src, int src_stride,
|
|||
CONV_BUF_TYPE *dst = conv_params->dst;
|
||||
int dst_stride = conv_params->dst_stride;
|
||||
const int bd = 8;
|
||||
int i, j;
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
int i, j, is_horiz_4tap = 0;
|
||||
const int bits = FILTER_BITS - conv_params->round_1;
|
||||
const __m256i wt = unpack_weights_avx2(conv_params);
|
||||
const int do_average = conv_params->do_average;
|
||||
|
|
@ -58,18 +56,10 @@ void av1_dist_wtd_convolve_x_avx2(const uint8_t *src, int src_stride,
|
|||
const int rounding_shift =
|
||||
2 * FILTER_BITS - conv_params->round_0 - conv_params->round_1;
|
||||
const __m256i rounding_const = _mm256_set1_epi16((1 << rounding_shift) >> 1);
|
||||
__m256i filt[4], coeffs[4];
|
||||
|
||||
assert(bits >= 0);
|
||||
assert(conv_params->round_0 > 0);
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs);
|
||||
|
||||
const __m256i round_const =
|
||||
_mm256_set1_epi16((1 << (conv_params->round_0 - 1)) >> 1);
|
||||
const __m128i round_shift = _mm_cvtsi32_si128(conv_params->round_0 - 1);
|
||||
|
|
@ -77,51 +67,121 @@ void av1_dist_wtd_convolve_x_avx2(const uint8_t *src, int src_stride,
|
|||
(void)filter_params_y;
|
||||
(void)subpel_y_q4;
|
||||
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const uint8_t *src_data = src_ptr + i * src_stride;
|
||||
CONV_BUF_TYPE *dst_data = dst + i * dst_stride;
|
||||
for (j = 0; j < w; j += 8) {
|
||||
const __m256i data =
|
||||
load_line2_avx2(&src_data[j], &src_data[j + src_stride]);
|
||||
__m256i filt[4], coeffs[4];
|
||||
|
||||
__m256i res = convolve_lowbd_x(data, coeffs, filt);
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const), round_shift);
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs);
|
||||
|
||||
res = _mm256_slli_epi16(res, bits);
|
||||
// Condition for checking valid horz_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs[0], coeffs[3]), 0)))
|
||||
is_horiz_4tap = 1;
|
||||
|
||||
const __m256i res_unsigned = _mm256_add_epi16(res, offset_const);
|
||||
// horz_filt as 4 tap
|
||||
if (is_horiz_4tap) {
|
||||
const int fo_horiz = 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const uint8_t *src_data = src_ptr + i * src_stride;
|
||||
CONV_BUF_TYPE *dst_data = dst + i * dst_stride;
|
||||
for (j = 0; j < w; j += 8) {
|
||||
const __m256i data =
|
||||
load_line2_avx2(&src_data[j], &src_data[j + src_stride]);
|
||||
|
||||
// Accumulate values into the destination buffer
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 =
|
||||
load_line2_avx2(&dst_data[j], &dst_data[j + dst_stride]);
|
||||
const __m256i comp_avg_res =
|
||||
comp_avg(&data_ref_0, &res_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
__m256i res = convolve_lowbd_x_4tap(data, coeffs + 1, filt);
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const), round_shift);
|
||||
res = _mm256_slli_epi16(res, bits);
|
||||
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
const __m256i res_unsigned = _mm256_add_epi16(res, offset_const);
|
||||
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
// Accumulate values into the destination buffer
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 =
|
||||
load_line2_avx2(&dst_data[j], &dst_data[j + dst_stride]);
|
||||
const __m256i comp_avg_res =
|
||||
comp_avg(&data_ref_0, &res_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) =
|
||||
_mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) = _mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_horiz;
|
||||
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const uint8_t *src_data = src_ptr + i * src_stride;
|
||||
CONV_BUF_TYPE *dst_data = dst + i * dst_stride;
|
||||
for (j = 0; j < w; j += 8) {
|
||||
const __m256i data =
|
||||
load_line2_avx2(&src_data[j], &src_data[j + src_stride]);
|
||||
|
||||
__m256i res = convolve_lowbd_x(data, coeffs, filt);
|
||||
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const), round_shift);
|
||||
|
||||
res = _mm256_slli_epi16(res, bits);
|
||||
|
||||
const __m256i res_unsigned = _mm256_add_epi16(res, offset_const);
|
||||
|
||||
// Accumulate values into the destination buffer
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 =
|
||||
load_line2_avx2(&dst_data[j], &dst_data[j + dst_stride]);
|
||||
const __m256i comp_avg_res =
|
||||
comp_avg(&data_ref_0, &res_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
if (w > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) =
|
||||
_mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -136,9 +196,7 @@ void av1_dist_wtd_convolve_y_avx2(const uint8_t *src, int src_stride,
|
|||
CONV_BUF_TYPE *dst = conv_params->dst;
|
||||
int dst_stride = conv_params->dst_stride;
|
||||
const int bd = 8;
|
||||
int i, j;
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
int i, j, is_vert_4tap = 0;
|
||||
// +1 to compensate for dividing the filter coeffs by 2
|
||||
const int left_shift = FILTER_BITS - conv_params->round_0 + 1;
|
||||
const __m256i round_const =
|
||||
|
|
@ -168,171 +226,368 @@ void av1_dist_wtd_convolve_y_avx2(const uint8_t *src, int src_stride,
|
|||
(void)filter_params_x;
|
||||
(void)subpel_x_q4;
|
||||
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
__m256i src6;
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
{
|
||||
__m256i src_ab[7];
|
||||
__m256i src_a[7];
|
||||
src_a[0] = _mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
for (int kk = 0; kk < 6; ++kk) {
|
||||
data += src_stride;
|
||||
src_a[kk + 1] =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
src_ab[kk] = _mm256_permute2x128_si256(src_a[kk], src_a[kk + 1], 0x20);
|
||||
// Condition for checking valid vert_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs[0], coeffs[3]), 0)))
|
||||
is_vert_4tap = 1;
|
||||
|
||||
if (is_vert_4tap) {
|
||||
const int fo_vert = 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
__m256i src4;
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
{
|
||||
__m256i src_ab[4];
|
||||
__m256i src_a[5];
|
||||
src_a[0] = _mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
for (int kk = 0; kk < 4; ++kk) {
|
||||
data += src_stride;
|
||||
src_a[kk + 1] =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
src_ab[kk] =
|
||||
_mm256_permute2x128_si256(src_a[kk], src_a[kk + 1], 0x20);
|
||||
}
|
||||
src4 = src_a[4];
|
||||
s[0] = _mm256_unpacklo_epi8(src_ab[0], src_ab[1]);
|
||||
s[1] = _mm256_unpacklo_epi8(src_ab[2], src_ab[3]);
|
||||
|
||||
s[3] = _mm256_unpackhi_epi8(src_ab[0], src_ab[1]);
|
||||
s[4] = _mm256_unpackhi_epi8(src_ab[2], src_ab[3]);
|
||||
}
|
||||
src6 = src_a[6];
|
||||
s[0] = _mm256_unpacklo_epi8(src_ab[0], src_ab[1]);
|
||||
s[1] = _mm256_unpacklo_epi8(src_ab[2], src_ab[3]);
|
||||
s[2] = _mm256_unpacklo_epi8(src_ab[4], src_ab[5]);
|
||||
s[4] = _mm256_unpackhi_epi8(src_ab[0], src_ab[1]);
|
||||
s[5] = _mm256_unpackhi_epi8(src_ab[2], src_ab[3]);
|
||||
s[6] = _mm256_unpackhi_epi8(src_ab[4], src_ab[5]);
|
||||
}
|
||||
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[(i + 7) * src_stride + j];
|
||||
const __m256i src7 =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
const __m256i src_67a = _mm256_permute2x128_si256(src6, src7, 0x20);
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[(i + 5) * src_stride + j];
|
||||
const __m256i src5 =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
const __m256i src_45a = _mm256_permute2x128_si256(src4, src5, 0x20);
|
||||
|
||||
src6 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + src_stride)));
|
||||
const __m256i src_78a = _mm256_permute2x128_si256(src7, src6, 0x20);
|
||||
src4 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + src_stride)));
|
||||
const __m256i src_56a = _mm256_permute2x128_si256(src5, src4, 0x20);
|
||||
|
||||
s[3] = _mm256_unpacklo_epi8(src_67a, src_78a);
|
||||
s[7] = _mm256_unpackhi_epi8(src_67a, src_78a);
|
||||
s[2] = _mm256_unpacklo_epi8(src_45a, src_56a);
|
||||
s[5] = _mm256_unpackhi_epi8(src_45a, src_56a);
|
||||
|
||||
__m256i res_lo = convolve_lowbd(s, coeffs);
|
||||
__m256i res_lo = convolve_lowbd_4tap(s, coeffs + 1);
|
||||
|
||||
res_lo = _mm256_add_epi16(res_lo, offset_const_1);
|
||||
res_lo = _mm256_add_epi16(res_lo, offset_const_1);
|
||||
|
||||
const __m256i res_lo_0_32b = _mm256_unpacklo_epi16(res_lo, zero);
|
||||
const __m256i res_lo_0_shift =
|
||||
_mm256_slli_epi32(res_lo_0_32b, left_shift);
|
||||
const __m256i res_lo_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_0_shift, round_const), round_shift);
|
||||
const __m256i res_lo_0_32b = _mm256_unpacklo_epi16(res_lo, zero);
|
||||
const __m256i res_lo_0_shift =
|
||||
_mm256_slli_epi32(res_lo_0_32b, left_shift);
|
||||
const __m256i res_lo_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_0_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_lo_1_32b = _mm256_unpackhi_epi16(res_lo, zero);
|
||||
const __m256i res_lo_1_shift =
|
||||
_mm256_slli_epi32(res_lo_1_32b, left_shift);
|
||||
const __m256i res_lo_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_1_shift, round_const), round_shift);
|
||||
const __m256i res_lo_1_32b = _mm256_unpackhi_epi16(res_lo, zero);
|
||||
const __m256i res_lo_1_shift =
|
||||
_mm256_slli_epi32(res_lo_1_32b, left_shift);
|
||||
const __m256i res_lo_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_1_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_lo_round =
|
||||
_mm256_packs_epi32(res_lo_0_round, res_lo_1_round);
|
||||
const __m256i res_lo_round =
|
||||
_mm256_packs_epi32(res_lo_0_round, res_lo_1_round);
|
||||
|
||||
const __m256i res_lo_unsigned =
|
||||
_mm256_add_epi16(res_lo_round, offset_const_2);
|
||||
const __m256i res_lo_unsigned =
|
||||
_mm256_add_epi16(res_lo_round, offset_const_2);
|
||||
|
||||
if (w - j < 16) {
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 = load_line2_avx2(
|
||||
&dst[i * dst_stride + j], &dst[i * dst_stride + j + dst_stride]);
|
||||
const __m256i comp_avg_res = comp_avg(&data_ref_0, &res_lo_unsigned,
|
||||
&wt, use_dist_wtd_comp_avg);
|
||||
if (w - j < 16) {
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 =
|
||||
load_line2_avx2(&dst[i * dst_stride + j],
|
||||
&dst[i * dst_stride + j + dst_stride]);
|
||||
const __m256i comp_avg_res = comp_avg(&data_ref_0, &res_lo_unsigned,
|
||||
&wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 = _mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
const __m256i res_8 =
|
||||
_mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])),
|
||||
res_1);
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) =
|
||||
_mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) =
|
||||
_mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
}
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
__m256i res_hi = convolve_lowbd_4tap(s + 3, coeffs + 1);
|
||||
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
res_hi = _mm256_add_epi16(res_hi, offset_const_1);
|
||||
|
||||
const __m256i res_hi_0_32b = _mm256_unpacklo_epi16(res_hi, zero);
|
||||
const __m256i res_hi_0_shift =
|
||||
_mm256_slli_epi32(res_hi_0_32b, left_shift);
|
||||
const __m256i res_hi_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_0_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_1_32b = _mm256_unpackhi_epi16(res_hi, zero);
|
||||
const __m256i res_hi_1_shift =
|
||||
_mm256_slli_epi32(res_hi_1_32b, left_shift);
|
||||
const __m256i res_hi_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_1_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_round =
|
||||
_mm256_packs_epi32(res_hi_0_round, res_hi_1_round);
|
||||
|
||||
const __m256i res_hi_unsigned =
|
||||
_mm256_add_epi16(res_hi_round, offset_const_2);
|
||||
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0_lo =
|
||||
load_line2_avx2(&dst[i * dst_stride + j],
|
||||
&dst[i * dst_stride + j + dst_stride]);
|
||||
|
||||
const __m256i data_ref_0_hi =
|
||||
load_line2_avx2(&dst[i * dst_stride + j + 8],
|
||||
&dst[i * dst_stride + j + 8 + dst_stride]);
|
||||
|
||||
const __m256i comp_avg_res_lo = comp_avg(
|
||||
&data_ref_0_lo, &res_lo_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i comp_avg_res_hi = comp_avg(
|
||||
&data_ref_0_hi, &res_hi_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result_lo =
|
||||
convolve_rounding(&comp_avg_res_lo, &offset_const,
|
||||
&rounding_const, rounding_shift);
|
||||
|
||||
const __m256i round_result_hi =
|
||||
convolve_rounding(&comp_avg_res_hi, &offset_const,
|
||||
&rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 =
|
||||
_mm256_packus_epi16(round_result_lo, round_result_hi);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
_mm_store_si128((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_store_si128(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
|
||||
} else {
|
||||
const __m128i res_lo_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_lo_0);
|
||||
|
||||
const __m128i res_lo_1 =
|
||||
_mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_lo_1);
|
||||
|
||||
const __m128i res_hi_0 = _mm256_castsi256_si128(res_hi_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + 8]),
|
||||
res_hi_0);
|
||||
|
||||
const __m128i res_hi_1 =
|
||||
_mm256_extracti128_si256(res_hi_unsigned, 1);
|
||||
_mm_store_si128(
|
||||
(__m128i *)(&dst[i * dst_stride + j + 8 + dst_stride]),
|
||||
res_hi_1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__m256i res_hi = convolve_lowbd(s + 4, coeffs);
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
|
||||
res_hi = _mm256_add_epi16(res_hi, offset_const_1);
|
||||
|
||||
const __m256i res_hi_0_32b = _mm256_unpacklo_epi16(res_hi, zero);
|
||||
const __m256i res_hi_0_shift =
|
||||
_mm256_slli_epi32(res_hi_0_32b, left_shift);
|
||||
const __m256i res_hi_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_0_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_1_32b = _mm256_unpackhi_epi16(res_hi, zero);
|
||||
const __m256i res_hi_1_shift =
|
||||
_mm256_slli_epi32(res_hi_1_32b, left_shift);
|
||||
const __m256i res_hi_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_1_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_round =
|
||||
_mm256_packs_epi32(res_hi_0_round, res_hi_1_round);
|
||||
|
||||
const __m256i res_hi_unsigned =
|
||||
_mm256_add_epi16(res_hi_round, offset_const_2);
|
||||
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0_lo = load_line2_avx2(
|
||||
&dst[i * dst_stride + j], &dst[i * dst_stride + j + dst_stride]);
|
||||
|
||||
const __m256i data_ref_0_hi =
|
||||
load_line2_avx2(&dst[i * dst_stride + j + 8],
|
||||
&dst[i * dst_stride + j + 8 + dst_stride]);
|
||||
|
||||
const __m256i comp_avg_res_lo = comp_avg(
|
||||
&data_ref_0_lo, &res_lo_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i comp_avg_res_hi = comp_avg(
|
||||
&data_ref_0_hi, &res_hi_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result_lo = convolve_rounding(
|
||||
&comp_avg_res_lo, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i round_result_hi = convolve_rounding(
|
||||
&comp_avg_res_hi, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 =
|
||||
_mm256_packus_epi16(round_result_lo, round_result_hi);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
_mm_store_si128((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_store_si128(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
|
||||
} else {
|
||||
const __m128i res_lo_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_lo_0);
|
||||
|
||||
const __m128i res_lo_1 = _mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_lo_1);
|
||||
|
||||
const __m128i res_hi_0 = _mm256_castsi256_si128(res_hi_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + 8]), res_hi_0);
|
||||
|
||||
const __m128i res_hi_1 = _mm256_extracti128_si256(res_hi_unsigned, 1);
|
||||
_mm_store_si128(
|
||||
(__m128i *)(&dst[i * dst_stride + j + 8 + dst_stride]), res_hi_1);
|
||||
}
|
||||
s[3] = s[4];
|
||||
s[4] = s[5];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride;
|
||||
for (j = 0; j < w; j += 16) {
|
||||
const uint8_t *data = &src_ptr[j];
|
||||
__m256i src6;
|
||||
// Load lines a and b. Line a to lower 128, line b to upper 128
|
||||
{
|
||||
__m256i src_ab[7];
|
||||
__m256i src_a[7];
|
||||
src_a[0] = _mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
for (int kk = 0; kk < 6; ++kk) {
|
||||
data += src_stride;
|
||||
src_a[kk + 1] =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
src_ab[kk] =
|
||||
_mm256_permute2x128_si256(src_a[kk], src_a[kk + 1], 0x20);
|
||||
}
|
||||
src6 = src_a[6];
|
||||
s[0] = _mm256_unpacklo_epi8(src_ab[0], src_ab[1]);
|
||||
s[1] = _mm256_unpacklo_epi8(src_ab[2], src_ab[3]);
|
||||
s[2] = _mm256_unpacklo_epi8(src_ab[4], src_ab[5]);
|
||||
s[4] = _mm256_unpackhi_epi8(src_ab[0], src_ab[1]);
|
||||
s[5] = _mm256_unpackhi_epi8(src_ab[2], src_ab[3]);
|
||||
s[6] = _mm256_unpackhi_epi8(src_ab[4], src_ab[5]);
|
||||
}
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
for (i = 0; i < h; i += 2) {
|
||||
data = &src_ptr[(i + 7) * src_stride + j];
|
||||
const __m256i src7 =
|
||||
_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)data));
|
||||
const __m256i src_67a = _mm256_permute2x128_si256(src6, src7, 0x20);
|
||||
|
||||
src6 = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)(data + src_stride)));
|
||||
const __m256i src_78a = _mm256_permute2x128_si256(src7, src6, 0x20);
|
||||
|
||||
s[3] = _mm256_unpacklo_epi8(src_67a, src_78a);
|
||||
s[7] = _mm256_unpackhi_epi8(src_67a, src_78a);
|
||||
|
||||
__m256i res_lo = convolve_lowbd(s, coeffs);
|
||||
|
||||
res_lo = _mm256_add_epi16(res_lo, offset_const_1);
|
||||
|
||||
const __m256i res_lo_0_32b = _mm256_unpacklo_epi16(res_lo, zero);
|
||||
const __m256i res_lo_0_shift =
|
||||
_mm256_slli_epi32(res_lo_0_32b, left_shift);
|
||||
const __m256i res_lo_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_0_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_lo_1_32b = _mm256_unpackhi_epi16(res_lo, zero);
|
||||
const __m256i res_lo_1_shift =
|
||||
_mm256_slli_epi32(res_lo_1_32b, left_shift);
|
||||
const __m256i res_lo_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_lo_1_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_lo_round =
|
||||
_mm256_packs_epi32(res_lo_0_round, res_lo_1_round);
|
||||
|
||||
const __m256i res_lo_unsigned =
|
||||
_mm256_add_epi16(res_lo_round, offset_const_2);
|
||||
|
||||
if (w - j < 16) {
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0 =
|
||||
load_line2_avx2(&dst[i * dst_stride + j],
|
||||
&dst[i * dst_stride + j + dst_stride]);
|
||||
const __m256i comp_avg_res = comp_avg(&data_ref_0, &res_lo_unsigned,
|
||||
&wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result = convolve_rounding(
|
||||
&comp_avg_res, &offset_const, &rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 =
|
||||
_mm256_packus_epi16(round_result, round_result);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
if (w - j > 4) {
|
||||
_mm_storel_epi64((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_storel_epi64(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])),
|
||||
res_1);
|
||||
} else {
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j]) =
|
||||
_mm_cvtsi128_si32(res_0);
|
||||
*(uint32_t *)(&dst0[i * dst_stride0 + j + dst_stride0]) =
|
||||
_mm_cvtsi128_si32(res_1);
|
||||
}
|
||||
} else {
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_0);
|
||||
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_1);
|
||||
}
|
||||
} else {
|
||||
__m256i res_hi = convolve_lowbd(s + 4, coeffs);
|
||||
|
||||
res_hi = _mm256_add_epi16(res_hi, offset_const_1);
|
||||
|
||||
const __m256i res_hi_0_32b = _mm256_unpacklo_epi16(res_hi, zero);
|
||||
const __m256i res_hi_0_shift =
|
||||
_mm256_slli_epi32(res_hi_0_32b, left_shift);
|
||||
const __m256i res_hi_0_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_0_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_1_32b = _mm256_unpackhi_epi16(res_hi, zero);
|
||||
const __m256i res_hi_1_shift =
|
||||
_mm256_slli_epi32(res_hi_1_32b, left_shift);
|
||||
const __m256i res_hi_1_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_hi_1_shift, round_const), round_shift);
|
||||
|
||||
const __m256i res_hi_round =
|
||||
_mm256_packs_epi32(res_hi_0_round, res_hi_1_round);
|
||||
|
||||
const __m256i res_hi_unsigned =
|
||||
_mm256_add_epi16(res_hi_round, offset_const_2);
|
||||
|
||||
if (do_average) {
|
||||
const __m256i data_ref_0_lo =
|
||||
load_line2_avx2(&dst[i * dst_stride + j],
|
||||
&dst[i * dst_stride + j + dst_stride]);
|
||||
|
||||
const __m256i data_ref_0_hi =
|
||||
load_line2_avx2(&dst[i * dst_stride + j + 8],
|
||||
&dst[i * dst_stride + j + 8 + dst_stride]);
|
||||
|
||||
const __m256i comp_avg_res_lo = comp_avg(
|
||||
&data_ref_0_lo, &res_lo_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i comp_avg_res_hi = comp_avg(
|
||||
&data_ref_0_hi, &res_hi_unsigned, &wt, use_dist_wtd_comp_avg);
|
||||
|
||||
const __m256i round_result_lo =
|
||||
convolve_rounding(&comp_avg_res_lo, &offset_const,
|
||||
&rounding_const, rounding_shift);
|
||||
|
||||
const __m256i round_result_hi =
|
||||
convolve_rounding(&comp_avg_res_hi, &offset_const,
|
||||
&rounding_const, rounding_shift);
|
||||
|
||||
const __m256i res_8 =
|
||||
_mm256_packus_epi16(round_result_lo, round_result_hi);
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8, 1);
|
||||
|
||||
_mm_store_si128((__m128i *)(&dst0[i * dst_stride0 + j]), res_0);
|
||||
_mm_store_si128(
|
||||
(__m128i *)((&dst0[i * dst_stride0 + j + dst_stride0])), res_1);
|
||||
|
||||
} else {
|
||||
const __m128i res_lo_0 = _mm256_castsi256_si128(res_lo_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j]), res_lo_0);
|
||||
|
||||
const __m128i res_lo_1 =
|
||||
_mm256_extracti128_si256(res_lo_unsigned, 1);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + dst_stride]),
|
||||
res_lo_1);
|
||||
|
||||
const __m128i res_hi_0 = _mm256_castsi256_si128(res_hi_unsigned);
|
||||
_mm_store_si128((__m128i *)(&dst[i * dst_stride + j + 8]),
|
||||
res_hi_0);
|
||||
|
||||
const __m128i res_hi_1 =
|
||||
_mm256_extracti128_si256(res_hi_unsigned, 1);
|
||||
_mm_store_si128(
|
||||
(__m128i *)(&dst[i * dst_stride + j + 8 + dst_stride]),
|
||||
res_hi_1);
|
||||
}
|
||||
}
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -348,12 +603,9 @@ void av1_dist_wtd_convolve_2d_avx2(const uint8_t *src, int src_stride,
|
|||
const int bd = 8;
|
||||
|
||||
DECLARE_ALIGNED(32, int16_t, im_block[(MAX_SB_SIZE + MAX_FILTER_TAP) * 8]);
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
|
||||
int im_stride = 8;
|
||||
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;
|
||||
int i, is_horiz_4tap = 0, is_vert_4tap = 0;
|
||||
const __m256i wt = unpack_weights_avx2(conv_params);
|
||||
const int do_average = conv_params->do_average;
|
||||
const int use_dist_wtd_comp_avg = conv_params->use_dist_wtd_comp_avg;
|
||||
|
|
@ -364,18 +616,9 @@ void av1_dist_wtd_convolve_2d_avx2(const uint8_t *src, int src_stride,
|
|||
const int rounding_shift =
|
||||
2 * FILTER_BITS - conv_params->round_0 - conv_params->round_1;
|
||||
const __m256i rounding_const = _mm256_set1_epi16((1 << rounding_shift) >> 1);
|
||||
__m256i filt[4], s[8], coeffs_x[4], coeffs_y[4];
|
||||
|
||||
assert(conv_params->round_0 > 0);
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs_x);
|
||||
prepare_coeffs(filter_params_y, subpel_y_q4, coeffs_y);
|
||||
|
||||
const __m256i round_const_h = _mm256_set1_epi16(
|
||||
((1 << (conv_params->round_0 - 1)) >> 1) + (1 << (bd + FILTER_BITS - 2)));
|
||||
const __m128i round_shift_h = _mm_cvtsi32_si128(conv_params->round_0 - 1);
|
||||
|
|
@ -385,9 +628,29 @@ void av1_dist_wtd_convolve_2d_avx2(const uint8_t *src, int src_stride,
|
|||
(1 << (bd + 2 * FILTER_BITS - conv_params->round_0 - 1)));
|
||||
const __m128i round_shift_v = _mm_cvtsi32_si128(conv_params->round_1);
|
||||
|
||||
for (j = 0; j < w; j += 8) {
|
||||
/* Horizontal filter */
|
||||
{
|
||||
__m256i filt[4], coeffs_x[4], coeffs_y[4];
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32));
|
||||
|
||||
prepare_coeffs_lowbd(filter_params_x, subpel_x_q4, coeffs_x);
|
||||
prepare_coeffs(filter_params_y, subpel_y_q4, coeffs_y);
|
||||
|
||||
// Condition for checking valid horz_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs_x[0], coeffs_x[3]), 0)))
|
||||
is_horiz_4tap = 1;
|
||||
|
||||
// Condition for checking valid vert_filt taps
|
||||
if (!(_mm256_extract_epi32(_mm256_or_si256(coeffs_y[0], coeffs_y[3]), 0)))
|
||||
is_vert_4tap = 1;
|
||||
|
||||
if (is_horiz_4tap) {
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
const int fo_vert = filter_params_y->taps / 2 - 1;
|
||||
const int fo_horiz = 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
|
||||
for (int j = 0; j < w; j += 8) {
|
||||
/* Horizontal filter */
|
||||
const uint8_t *src_h = src_ptr + j;
|
||||
for (i = 0; i < im_h; i += 2) {
|
||||
__m256i data =
|
||||
|
|
@ -396,49 +659,59 @@ void av1_dist_wtd_convolve_2d_avx2(const uint8_t *src, int src_stride,
|
|||
data = _mm256_inserti128_si256(
|
||||
data, _mm_loadu_si128((__m128i *)(src_h + src_stride)), 1);
|
||||
src_h += (src_stride << 1);
|
||||
__m256i res = convolve_lowbd_x(data, coeffs_x, filt);
|
||||
__m256i res = convolve_lowbd_x_4tap(data, coeffs_x + 1, filt);
|
||||
|
||||
res = _mm256_sra_epi16(_mm256_add_epi16(res, round_const_h),
|
||||
round_shift_h);
|
||||
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res);
|
||||
}
|
||||
DIST_WTD_CONVOLVE_VERTICAL_FILTER_8TAP;
|
||||
}
|
||||
} else if (is_vert_4tap) {
|
||||
int im_h = h + 3;
|
||||
const int fo_vert = 1;
|
||||
const int fo_horiz = filter_params_x->taps / 2 - 1;
|
||||
const uint8_t *const src_ptr = src - fo_vert * src_stride - fo_horiz;
|
||||
|
||||
/* Vertical filter */
|
||||
{
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
for (int j = 0; j < w; j += 8) {
|
||||
/* Horizontal filter */
|
||||
const uint8_t *src_h = src_ptr + j;
|
||||
DIST_WTD_CONVOLVE_HORIZONTAL_FILTER_8TAP;
|
||||
|
||||
/* Vertical filter */
|
||||
__m256i s[6];
|
||||
__m256i s0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride));
|
||||
__m256i s1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride));
|
||||
__m256i s2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride));
|
||||
__m256i s3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride));
|
||||
__m256i s4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride));
|
||||
__m256i s5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride));
|
||||
|
||||
s[0] = _mm256_unpacklo_epi16(s0, s1);
|
||||
s[1] = _mm256_unpacklo_epi16(s2, s3);
|
||||
s[2] = _mm256_unpacklo_epi16(s4, s5);
|
||||
|
||||
s[4] = _mm256_unpackhi_epi16(s0, s1);
|
||||
s[5] = _mm256_unpackhi_epi16(s2, s3);
|
||||
s[6] = _mm256_unpackhi_epi16(s4, s5);
|
||||
s[3] = _mm256_unpackhi_epi16(s0, s1);
|
||||
s[4] = _mm256_unpackhi_epi16(s2, s3);
|
||||
|
||||
for (i = 0; i < h; i += 2) {
|
||||
const int16_t *data = &im_block[i * im_stride];
|
||||
|
||||
const __m256i s6 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 6 * im_stride));
|
||||
const __m256i s7 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 7 * im_stride));
|
||||
const __m256i s4 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 4 * im_stride));
|
||||
const __m256i s5 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 5 * im_stride));
|
||||
|
||||
s[3] = _mm256_unpacklo_epi16(s6, s7);
|
||||
s[7] = _mm256_unpackhi_epi16(s6, s7);
|
||||
s[2] = _mm256_unpacklo_epi16(s4, s5);
|
||||
s[5] = _mm256_unpackhi_epi16(s4, s5);
|
||||
|
||||
const __m256i res_a = convolve(s, coeffs_y);
|
||||
const __m256i res_a = convolve_4tap(s, coeffs_y + 1);
|
||||
const __m256i res_a_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_a, round_const_v), round_shift_v);
|
||||
|
||||
if (w - j > 4) {
|
||||
const __m256i res_b = convolve(s + 4, coeffs_y);
|
||||
const __m256i res_b = convolve_4tap(s + 3, coeffs_y + 1);
|
||||
const __m256i res_b_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_b, round_const_v), round_shift_v);
|
||||
const __m256i res_16b = _mm256_packs_epi32(res_a_round, res_b_round);
|
||||
|
|
@ -504,16 +777,28 @@ void av1_dist_wtd_convolve_2d_avx2(const uint8_t *src, int src_stride,
|
|||
res_1);
|
||||
}
|
||||
}
|
||||
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[3] = s[4];
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int im_h = h + filter_params_y->taps - 1;
|
||||
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;
|
||||
|
||||
filt[2] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 2));
|
||||
filt[3] = _mm256_load_si256((__m256i const *)(filt_global_avx2 + 32 * 3));
|
||||
|
||||
for (int j = 0; j < w; j += 8) {
|
||||
/* Horizontal filter */
|
||||
const uint8_t *src_h = src_ptr + j;
|
||||
DIST_WTD_CONVOLVE_HORIZONTAL_FILTER_8TAP;
|
||||
|
||||
DIST_WTD_CONVOLVE_VERTICAL_FILTER_8TAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include "av1/common/convolve.h"
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_dsp/aom_filter.h"
|
||||
#include "aom_dsp/x86/convolve_avx2.h"
|
||||
#include "aom_dsp/x86/synonyms.h"
|
||||
#include "aom_dsp/x86/synonyms_avx2.h"
|
||||
|
||||
|
|
@ -26,207 +25,236 @@
|
|||
// on the left.
|
||||
// A row of, say, 8-bit pixels with values p0, p1, p2, ..., p30, p31 will be
|
||||
// loaded and stored as [ p31 ... p17 p16 ][ p15 ... p1 p0 ].
|
||||
|
||||
// Exploiting the range of wiener filter coefficients,
|
||||
// horizontal filtering can be done in 16 bit intermediate precision.
|
||||
// The details are as follows :
|
||||
// Consider the horizontal wiener filter coefficients of the following form :
|
||||
// [C0, C1, C2, 2^(FILTER_BITS) -2 * (C0 + C1 + C2), C2, C1, C0]
|
||||
// Subtracting 2^(FILTER_BITS) from the centre tap we get the following :
|
||||
// [C0, C1, C2, -2 * (C0 + C1 + C2), C2, C1, C0]
|
||||
// The sum of the product "C0 * p0 + C1 * p1 + C2 * p2 -2 * (C0 + C1 + C2) * p3
|
||||
// + C2 * p4 + C1 * p5 + C0 * p6" would be in the range of signed 16 bit
|
||||
// precision. Finally, after rounding the above result by round_0, we multiply
|
||||
// the centre pixel by 2^(FILTER_BITS - round_0) and add it to get the
|
||||
// horizontal filter output.
|
||||
|
||||
void av1_wiener_convolve_add_src_avx2(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int x_step_q4,
|
||||
const int16_t *filter_y, int y_step_q4,
|
||||
int w, int h,
|
||||
const ConvolveParams *conv_params) {
|
||||
const int bd = 8;
|
||||
assert(x_step_q4 == 16 && y_step_q4 == 16);
|
||||
assert(!(w & 7));
|
||||
(void)x_step_q4;
|
||||
(void)y_step_q4;
|
||||
|
||||
DECLARE_ALIGNED(32, int16_t, im_block[(MAX_SB_SIZE + SUBPEL_TAPS) * 8]);
|
||||
int im_h = h + SUBPEL_TAPS - 2;
|
||||
int im_stride = 8;
|
||||
memset(im_block + (im_h * im_stride), 0, MAX_SB_SIZE);
|
||||
int i, j;
|
||||
const int center_tap = (SUBPEL_TAPS - 1) / 2;
|
||||
DECLARE_ALIGNED(32, uint16_t,
|
||||
temp[(MAX_SB_SIZE + SUBPEL_TAPS - 1) * MAX_SB_SIZE]);
|
||||
int intermediate_height = h + SUBPEL_TAPS - 2;
|
||||
memset(temp + (intermediate_height * MAX_SB_SIZE), 0, MAX_SB_SIZE);
|
||||
const int center_tap = ((SUBPEL_TAPS - 1) / 2);
|
||||
const uint8_t *const src_ptr = src - center_tap * src_stride - center_tap;
|
||||
|
||||
__m256i filt[4], coeffs_h[4], coeffs_v[4], filt_center;
|
||||
|
||||
assert(conv_params->round_0 > 0);
|
||||
|
||||
filt[0] = _mm256_load_si256((__m256i const *)filt1_global_avx2);
|
||||
filt[1] = _mm256_load_si256((__m256i const *)filt2_global_avx2);
|
||||
filt[2] = _mm256_load_si256((__m256i const *)filt3_global_avx2);
|
||||
filt[3] = _mm256_load_si256((__m256i const *)filt4_global_avx2);
|
||||
|
||||
filt_center = _mm256_load_si256((__m256i const *)filt_center_global_avx2);
|
||||
|
||||
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)filter_x);
|
||||
const __m256i filter_coeffs_x = _mm256_broadcastsi128_si256(coeffs_x);
|
||||
|
||||
// coeffs 0 1 0 1 0 1 0 1
|
||||
coeffs_h[0] =
|
||||
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0200u));
|
||||
// coeffs 2 3 2 3 2 3 2 3
|
||||
coeffs_h[1] =
|
||||
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0604u));
|
||||
// coeffs 4 5 4 5 4 5 4 5
|
||||
coeffs_h[2] =
|
||||
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0a08u));
|
||||
// coeffs 6 7 6 7 6 7 6 7
|
||||
coeffs_h[3] =
|
||||
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0e0cu));
|
||||
|
||||
const __m256i round_const_h =
|
||||
_mm256_set1_epi16((1 << (conv_params->round_0 - 1)));
|
||||
const __m128i round_shift_h = _mm_cvtsi32_si128(conv_params->round_0);
|
||||
const __m128i zero_128 = _mm_setzero_si128();
|
||||
const __m256i zero_256 = _mm256_setzero_si256();
|
||||
|
||||
// Add an offset to account for the "add_src" part of the convolve function.
|
||||
const __m128i zero_128 = _mm_setzero_si128();
|
||||
const __m128i offset_0 = _mm_insert_epi16(zero_128, 1 << FILTER_BITS, 3);
|
||||
const __m128i coeffs_y = _mm_add_epi16(xx_loadu_128(filter_y), offset_0);
|
||||
const __m128i offset = _mm_insert_epi16(zero_128, 1 << FILTER_BITS, 3);
|
||||
|
||||
const __m256i filter_coeffs_y = _mm256_broadcastsi128_si256(coeffs_y);
|
||||
const __m256i clamp_low = zero_256;
|
||||
const __m256i clamp_high =
|
||||
_mm256_set1_epi16(WIENER_CLAMP_LIMIT(conv_params->round_0, bd) - 1);
|
||||
|
||||
// coeffs 0 1 0 1 0 1 0 1
|
||||
coeffs_v[0] = _mm256_shuffle_epi32(filter_coeffs_y, 0x00);
|
||||
// coeffs 2 3 2 3 2 3 2 3
|
||||
coeffs_v[1] = _mm256_shuffle_epi32(filter_coeffs_y, 0x55);
|
||||
// coeffs 4 5 4 5 4 5 4 5
|
||||
coeffs_v[2] = _mm256_shuffle_epi32(filter_coeffs_y, 0xaa);
|
||||
// coeffs 6 7 6 7 6 7 6 7
|
||||
coeffs_v[3] = _mm256_shuffle_epi32(filter_coeffs_y, 0xff);
|
||||
/* Horizontal filter */
|
||||
{
|
||||
// coeffs [ f7 f6 f5 f4 f3 f2 f1 f0 ]
|
||||
const __m128i coeffs_x = _mm_add_epi16(xx_loadu_128(filter_x), offset);
|
||||
|
||||
const __m256i round_const_v =
|
||||
_mm256_set1_epi32((1 << (conv_params->round_1 - 1)));
|
||||
const __m128i round_shift_v = _mm_cvtsi32_si128(conv_params->round_1);
|
||||
// coeffs [ f3 f2 f3 f2 f1 f0 f1 f0 ]
|
||||
const __m128i coeffs_0123 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
|
||||
// coeffs [ f7 f6 f7 f6 f5 f4 f5 f4 ]
|
||||
const __m128i coeffs_4567 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
|
||||
|
||||
for (j = 0; j < w; j += 8) {
|
||||
for (i = 0; i < im_h; i += 2) {
|
||||
__m256i data = _mm256_castsi128_si256(
|
||||
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j]));
|
||||
// coeffs [ f1 f0 f1 f0 f1 f0 f1 f0 ]
|
||||
const __m128i coeffs_01_128 = _mm_unpacklo_epi64(coeffs_0123, coeffs_0123);
|
||||
// coeffs [ f3 f2 f3 f2 f3 f2 f3 f2 ]
|
||||
const __m128i coeffs_23_128 = _mm_unpackhi_epi64(coeffs_0123, coeffs_0123);
|
||||
// coeffs [ f5 f4 f5 f4 f5 f4 f5 f4 ]
|
||||
const __m128i coeffs_45_128 = _mm_unpacklo_epi64(coeffs_4567, coeffs_4567);
|
||||
// coeffs [ f7 f6 f7 f6 f7 f6 f7 f6 ]
|
||||
const __m128i coeffs_67_128 = _mm_unpackhi_epi64(coeffs_4567, coeffs_4567);
|
||||
|
||||
// Load the next line
|
||||
if (i + 1 < im_h)
|
||||
data = _mm256_inserti128_si256(
|
||||
data,
|
||||
_mm_loadu_si128(
|
||||
(__m128i *)&src_ptr[(i * src_stride) + j + src_stride]),
|
||||
1);
|
||||
// coeffs [ f1 f0 f1 f0 f1 f0 f1 f0 ][ f1 f0 f1 f0 f1 f0 f1 f0 ]
|
||||
const __m256i coeffs_01 = yy_set_m128i(coeffs_01_128, coeffs_01_128);
|
||||
// coeffs [ f3 f2 f3 f2 f3 f2 f3 f2 ][ f3 f2 f3 f2 f3 f2 f3 f2 ]
|
||||
const __m256i coeffs_23 = yy_set_m128i(coeffs_23_128, coeffs_23_128);
|
||||
// coeffs [ f5 f4 f5 f4 f5 f4 f5 f4 ][ f5 f4 f5 f4 f5 f4 f5 f4 ]
|
||||
const __m256i coeffs_45 = yy_set_m128i(coeffs_45_128, coeffs_45_128);
|
||||
// coeffs [ f7 f6 f7 f6 f7 f6 f7 f6 ][ f7 f6 f7 f6 f7 f6 f7 f6 ]
|
||||
const __m256i coeffs_67 = yy_set_m128i(coeffs_67_128, coeffs_67_128);
|
||||
|
||||
__m256i res = convolve_lowbd_x(data, coeffs_h, filt);
|
||||
const __m256i round_const = _mm256_set1_epi32(
|
||||
(1 << (conv_params->round_0 - 1)) + (1 << (bd + FILTER_BITS - 1)));
|
||||
|
||||
res =
|
||||
_mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h);
|
||||
for (int i = 0; i < intermediate_height; ++i) {
|
||||
for (int j = 0; j < w; j += 16) {
|
||||
const uint8_t *data_ij = src_ptr + i * src_stride + j;
|
||||
|
||||
__m256i data_0 = _mm256_shuffle_epi8(data, filt_center);
|
||||
// Load 8-bit src data
|
||||
const __m128i data_0 = xx_loadu_128(data_ij + 0);
|
||||
const __m128i data_1 = xx_loadu_128(data_ij + 1);
|
||||
const __m128i data_2 = xx_loadu_128(data_ij + 2);
|
||||
const __m128i data_3 = xx_loadu_128(data_ij + 3);
|
||||
const __m128i data_4 = xx_loadu_128(data_ij + 4);
|
||||
const __m128i data_5 = xx_loadu_128(data_ij + 5);
|
||||
const __m128i data_6 = xx_loadu_128(data_ij + 6);
|
||||
const __m128i data_7 = xx_loadu_128(data_ij + 7);
|
||||
|
||||
// multiply the center pixel by 2^(FILTER_BITS - round_0) and add it to
|
||||
// the result
|
||||
data_0 = _mm256_slli_epi16(data_0, FILTER_BITS - conv_params->round_0);
|
||||
res = _mm256_add_epi16(res, data_0);
|
||||
// (Zero-)Extend 8-bit data to 16-bit data
|
||||
const __m256i src_0 = _mm256_cvtepu8_epi16(data_0);
|
||||
const __m256i src_1 = _mm256_cvtepu8_epi16(data_1);
|
||||
const __m256i src_2 = _mm256_cvtepu8_epi16(data_2);
|
||||
const __m256i src_3 = _mm256_cvtepu8_epi16(data_3);
|
||||
const __m256i src_4 = _mm256_cvtepu8_epi16(data_4);
|
||||
const __m256i src_5 = _mm256_cvtepu8_epi16(data_5);
|
||||
const __m256i src_6 = _mm256_cvtepu8_epi16(data_6);
|
||||
const __m256i src_7 = _mm256_cvtepu8_epi16(data_7);
|
||||
|
||||
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res);
|
||||
}
|
||||
// Multiply src data by filter coeffs and sum pairs
|
||||
const __m256i res_0 = _mm256_madd_epi16(src_0, coeffs_01);
|
||||
const __m256i res_1 = _mm256_madd_epi16(src_1, coeffs_01);
|
||||
const __m256i res_2 = _mm256_madd_epi16(src_2, coeffs_23);
|
||||
const __m256i res_3 = _mm256_madd_epi16(src_3, coeffs_23);
|
||||
const __m256i res_4 = _mm256_madd_epi16(src_4, coeffs_45);
|
||||
const __m256i res_5 = _mm256_madd_epi16(src_5, coeffs_45);
|
||||
const __m256i res_6 = _mm256_madd_epi16(src_6, coeffs_67);
|
||||
const __m256i res_7 = _mm256_madd_epi16(src_7, coeffs_67);
|
||||
|
||||
/* Vertical filter */
|
||||
{
|
||||
__m256i src_0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride));
|
||||
__m256i src_1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride));
|
||||
__m256i src_2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride));
|
||||
__m256i src_3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride));
|
||||
__m256i src_4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride));
|
||||
__m256i src_5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride));
|
||||
// Calculate scalar product for even- and odd-indices separately,
|
||||
// increasing to 32-bit precision
|
||||
const __m256i res_even_sum = _mm256_add_epi32(
|
||||
_mm256_add_epi32(res_0, res_4), _mm256_add_epi32(res_2, res_6));
|
||||
const __m256i res_odd_sum = _mm256_add_epi32(
|
||||
_mm256_add_epi32(res_1, res_5), _mm256_add_epi32(res_3, res_7));
|
||||
|
||||
__m256i s[8];
|
||||
s[0] = _mm256_unpacklo_epi16(src_0, src_1);
|
||||
s[1] = _mm256_unpacklo_epi16(src_2, src_3);
|
||||
s[2] = _mm256_unpacklo_epi16(src_4, src_5);
|
||||
const __m256i res_even = _mm256_srai_epi32(
|
||||
_mm256_add_epi32(res_even_sum, round_const), conv_params->round_0);
|
||||
const __m256i res_odd = _mm256_srai_epi32(
|
||||
_mm256_add_epi32(res_odd_sum, round_const), conv_params->round_0);
|
||||
|
||||
s[4] = _mm256_unpackhi_epi16(src_0, src_1);
|
||||
s[5] = _mm256_unpackhi_epi16(src_2, src_3);
|
||||
s[6] = _mm256_unpackhi_epi16(src_4, src_5);
|
||||
// Reduce to 16-bit precision and pack even- and odd-index results
|
||||
// back into one register. The _mm256_packs_epi32 intrinsic returns
|
||||
// a register with the pixels ordered as follows:
|
||||
// [ 15 13 11 9 14 12 10 8 ] [ 7 5 3 1 6 4 2 0 ]
|
||||
const __m256i res = _mm256_packs_epi32(res_even, res_odd);
|
||||
const __m256i res_clamped =
|
||||
_mm256_min_epi16(_mm256_max_epi16(res, clamp_low), clamp_high);
|
||||
|
||||
for (i = 0; i < h - 1; i += 2) {
|
||||
const int16_t *data = &im_block[i * im_stride];
|
||||
|
||||
const __m256i s6 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 6 * im_stride));
|
||||
const __m256i s7 =
|
||||
_mm256_loadu_si256((__m256i *)(data + 7 * im_stride));
|
||||
|
||||
s[3] = _mm256_unpacklo_epi16(s6, s7);
|
||||
s[7] = _mm256_unpackhi_epi16(s6, s7);
|
||||
|
||||
__m256i res_a = convolve(s, coeffs_v);
|
||||
__m256i res_b = convolve(s + 4, coeffs_v);
|
||||
|
||||
const __m256i res_a_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_a, round_const_v), round_shift_v);
|
||||
const __m256i res_b_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(res_b, round_const_v), round_shift_v);
|
||||
|
||||
/* rounding code */
|
||||
// 16 bit conversion
|
||||
const __m256i res_16bit = _mm256_packs_epi32(res_a_round, res_b_round);
|
||||
// 8 bit conversion and saturation to uint8
|
||||
const __m256i res_8b = _mm256_packus_epi16(res_16bit, res_16bit);
|
||||
|
||||
const __m128i res_0 = _mm256_castsi256_si128(res_8b);
|
||||
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
|
||||
|
||||
// Store values into the destination buffer
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
|
||||
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + j + dst_stride];
|
||||
|
||||
_mm_storel_epi64(p_0, res_0);
|
||||
_mm_storel_epi64(p_1, res_1);
|
||||
|
||||
s[0] = s[1];
|
||||
s[1] = s[2];
|
||||
s[2] = s[3];
|
||||
|
||||
s[4] = s[5];
|
||||
s[5] = s[6];
|
||||
s[6] = s[7];
|
||||
// Store in a temporary array
|
||||
yy_storeu_256(temp + i * MAX_SB_SIZE + j, res_clamped);
|
||||
}
|
||||
if (h - i) {
|
||||
s[0] = _mm256_permute2x128_si256(s[0], s[4], 0x20);
|
||||
s[1] = _mm256_permute2x128_si256(s[1], s[5], 0x20);
|
||||
s[2] = _mm256_permute2x128_si256(s[2], s[6], 0x20);
|
||||
}
|
||||
}
|
||||
|
||||
const int16_t *data = &im_block[i * im_stride];
|
||||
const __m128i s6_ = _mm_loadu_si128((__m128i *)(data + 6 * im_stride));
|
||||
const __m128i s7_ = _mm_loadu_si128((__m128i *)(data + 7 * im_stride));
|
||||
/* Vertical filter */
|
||||
{
|
||||
// coeffs [ g7 g6 g5 g4 g3 g2 g1 g0 ]
|
||||
const __m128i coeffs_y = _mm_add_epi16(xx_loadu_128(filter_y), offset);
|
||||
|
||||
__m128i s3 = _mm_unpacklo_epi16(s6_, s7_);
|
||||
__m128i s7 = _mm_unpackhi_epi16(s6_, s7_);
|
||||
// coeffs [ g3 g2 g3 g2 g1 g0 g1 g0 ]
|
||||
const __m128i coeffs_0123 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
|
||||
// coeffs [ g7 g6 g7 g6 g5 g4 g5 g4 ]
|
||||
const __m128i coeffs_4567 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
|
||||
|
||||
s[3] = _mm256_inserti128_si256(_mm256_castsi128_si256(s3), s7, 1);
|
||||
__m256i convolveres = convolve(s, coeffs_v);
|
||||
// coeffs [ g1 g0 g1 g0 g1 g0 g1 g0 ]
|
||||
const __m128i coeffs_01_128 = _mm_unpacklo_epi64(coeffs_0123, coeffs_0123);
|
||||
// coeffs [ g3 g2 g3 g2 g3 g2 g3 g2 ]
|
||||
const __m128i coeffs_23_128 = _mm_unpackhi_epi64(coeffs_0123, coeffs_0123);
|
||||
// coeffs [ g5 g4 g5 g4 g5 g4 g5 g4 ]
|
||||
const __m128i coeffs_45_128 = _mm_unpacklo_epi64(coeffs_4567, coeffs_4567);
|
||||
// coeffs [ g7 g6 g7 g6 g7 g6 g7 g6 ]
|
||||
const __m128i coeffs_67_128 = _mm_unpackhi_epi64(coeffs_4567, coeffs_4567);
|
||||
|
||||
const __m256i res_round = _mm256_sra_epi32(
|
||||
_mm256_add_epi32(convolveres, round_const_v), round_shift_v);
|
||||
// coeffs [ g1 g0 g1 g0 g1 g0 g1 g0 ][ g1 g0 g1 g0 g1 g0 g1 g0 ]
|
||||
const __m256i coeffs_01 = yy_set_m128i(coeffs_01_128, coeffs_01_128);
|
||||
// coeffs [ g3 g2 g3 g2 g3 g2 g3 g2 ][ g3 g2 g3 g2 g3 g2 g3 g2 ]
|
||||
const __m256i coeffs_23 = yy_set_m128i(coeffs_23_128, coeffs_23_128);
|
||||
// coeffs [ g5 g4 g5 g4 g5 g4 g5 g4 ][ g5 g4 g5 g4 g5 g4 g5 g4 ]
|
||||
const __m256i coeffs_45 = yy_set_m128i(coeffs_45_128, coeffs_45_128);
|
||||
// coeffs [ g7 g6 g7 g6 g7 g6 g7 g6 ][ g7 g6 g7 g6 g7 g6 g7 g6 ]
|
||||
const __m256i coeffs_67 = yy_set_m128i(coeffs_67_128, coeffs_67_128);
|
||||
|
||||
/* rounding code */
|
||||
// 16 bit conversion
|
||||
__m128i reslo = _mm256_castsi256_si128(res_round);
|
||||
__m128i reshi = _mm256_extracti128_si256(res_round, 1);
|
||||
const __m128i res_16bit = _mm_packus_epi32(reslo, reshi);
|
||||
const __m256i round_const =
|
||||
_mm256_set1_epi32((1 << (conv_params->round_1 - 1)) -
|
||||
(1 << (bd + conv_params->round_1 - 1)));
|
||||
|
||||
// 8 bit conversion and saturation to uint8
|
||||
const __m128i res_8b = _mm_packus_epi16(res_16bit, res_16bit);
|
||||
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
|
||||
_mm_storel_epi64(p_0, res_8b);
|
||||
for (int i = 0; i < h; ++i) {
|
||||
for (int j = 0; j < w; j += 16) {
|
||||
const uint16_t *data_ij = temp + i * MAX_SB_SIZE + j;
|
||||
|
||||
// Load 16-bit data from the output of the horizontal filter in
|
||||
// which the pixels are ordered as follows:
|
||||
// [ 15 13 11 9 14 12 10 8 ] [ 7 5 3 1 6 4 2 0 ]
|
||||
const __m256i data_0 = yy_loadu_256(data_ij + 0 * MAX_SB_SIZE);
|
||||
const __m256i data_1 = yy_loadu_256(data_ij + 1 * MAX_SB_SIZE);
|
||||
const __m256i data_2 = yy_loadu_256(data_ij + 2 * MAX_SB_SIZE);
|
||||
const __m256i data_3 = yy_loadu_256(data_ij + 3 * MAX_SB_SIZE);
|
||||
const __m256i data_4 = yy_loadu_256(data_ij + 4 * MAX_SB_SIZE);
|
||||
const __m256i data_5 = yy_loadu_256(data_ij + 5 * MAX_SB_SIZE);
|
||||
const __m256i data_6 = yy_loadu_256(data_ij + 6 * MAX_SB_SIZE);
|
||||
const __m256i data_7 = yy_loadu_256(data_ij + 7 * MAX_SB_SIZE);
|
||||
|
||||
// Filter the even-indices, increasing to 32-bit precision
|
||||
const __m256i src_0 = _mm256_unpacklo_epi16(data_0, data_1);
|
||||
const __m256i src_2 = _mm256_unpacklo_epi16(data_2, data_3);
|
||||
const __m256i src_4 = _mm256_unpacklo_epi16(data_4, data_5);
|
||||
const __m256i src_6 = _mm256_unpacklo_epi16(data_6, data_7);
|
||||
|
||||
const __m256i res_0 = _mm256_madd_epi16(src_0, coeffs_01);
|
||||
const __m256i res_2 = _mm256_madd_epi16(src_2, coeffs_23);
|
||||
const __m256i res_4 = _mm256_madd_epi16(src_4, coeffs_45);
|
||||
const __m256i res_6 = _mm256_madd_epi16(src_6, coeffs_67);
|
||||
|
||||
const __m256i res_even = _mm256_add_epi32(
|
||||
_mm256_add_epi32(res_0, res_2), _mm256_add_epi32(res_4, res_6));
|
||||
|
||||
// Filter the odd-indices, increasing to 32-bit precision
|
||||
const __m256i src_1 = _mm256_unpackhi_epi16(data_0, data_1);
|
||||
const __m256i src_3 = _mm256_unpackhi_epi16(data_2, data_3);
|
||||
const __m256i src_5 = _mm256_unpackhi_epi16(data_4, data_5);
|
||||
const __m256i src_7 = _mm256_unpackhi_epi16(data_6, data_7);
|
||||
|
||||
const __m256i res_1 = _mm256_madd_epi16(src_1, coeffs_01);
|
||||
const __m256i res_3 = _mm256_madd_epi16(src_3, coeffs_23);
|
||||
const __m256i res_5 = _mm256_madd_epi16(src_5, coeffs_45);
|
||||
const __m256i res_7 = _mm256_madd_epi16(src_7, coeffs_67);
|
||||
|
||||
const __m256i res_odd = _mm256_add_epi32(
|
||||
_mm256_add_epi32(res_1, res_3), _mm256_add_epi32(res_5, res_7));
|
||||
|
||||
// Pixels are currently in the following order:
|
||||
// res_even order: [ 14 12 10 8 ] [ 6 4 2 0 ]
|
||||
// res_odd order: [ 15 13 11 9 ] [ 7 5 3 1 ]
|
||||
//
|
||||
// Rearrange the pixels into the following order:
|
||||
// res_lo order: [ 11 10 9 8 ] [ 3 2 1 0 ]
|
||||
// res_hi order: [ 15 14 13 12 ] [ 7 6 5 4 ]
|
||||
const __m256i res_lo = _mm256_unpacklo_epi32(res_even, res_odd);
|
||||
const __m256i res_hi = _mm256_unpackhi_epi32(res_even, res_odd);
|
||||
|
||||
const __m256i res_lo_round = _mm256_srai_epi32(
|
||||
_mm256_add_epi32(res_lo, round_const), conv_params->round_1);
|
||||
const __m256i res_hi_round = _mm256_srai_epi32(
|
||||
_mm256_add_epi32(res_hi, round_const), conv_params->round_1);
|
||||
|
||||
// Reduce to 16-bit precision and pack into the correct order:
|
||||
// [ 15 14 13 12 11 10 9 8 ][ 7 6 5 4 3 2 1 0 ]
|
||||
const __m256i res_16bit =
|
||||
_mm256_packs_epi32(res_lo_round, res_hi_round);
|
||||
|
||||
// Reduce to 8-bit precision. This messes up the order:
|
||||
// [ - - - - - - - - 15 14 13 12 11 10 9 8 ]
|
||||
// [ - - - - - - - - 7 6 5 4 3 2 1 0 ]
|
||||
const __m256i res_8bit =
|
||||
_mm256_packus_epi16(res_16bit, zero_256 /* don't care value */);
|
||||
|
||||
// Swap the two central 32-bit values to get the order:
|
||||
// [ - - - - - - - - - - - - - - - - ]
|
||||
// [ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ]
|
||||
const __m256i res_8bit2 = _mm256_permute4x64_epi64(res_8bit, 0xd8);
|
||||
|
||||
// Store the lower 128-bit lane in the dst array
|
||||
xx_storeu_128(dst + i * dst_stride + j,
|
||||
_mm256_castsi256_si128(res_8bit2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
third_party/aom/av1/decoder/decodeframe.c
vendored
36
third_party/aom/av1/decoder/decodeframe.c
vendored
|
|
@ -781,7 +781,7 @@ static INLINE void dec_build_inter_predictors(const AV1_COMMON *cm,
|
|||
dec_calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, 0, 0, pre_buf,
|
||||
&subpel_params[ref], bw, bh, &block, mi_x, mi_y,
|
||||
&scaled_mv, &subpel_x_mv, &subpel_y_mv);
|
||||
pre[ref] = pre_buf->buf0 + block.y0 * pre_buf->stride + block.x0;
|
||||
pre[ref] = pre_buf->buf0 + (int64_t)block.y0 * pre_buf->stride + block.x0;
|
||||
src_stride[ref] = pre_buf->stride;
|
||||
highbd = is_cur_buf_hbd(xd);
|
||||
|
||||
|
|
@ -4240,6 +4240,25 @@ void av1_read_film_grain_params(AV1_COMMON *cm,
|
|||
if (!pars->update_parameters) {
|
||||
// inherit parameters from a previous reference frame
|
||||
int film_grain_params_ref_idx = aom_rb_read_literal(rb, 3);
|
||||
// Section 6.8.20: It is a requirement of bitstream conformance that
|
||||
// film_grain_params_ref_idx is equal to ref_frame_idx[ j ] for some value
|
||||
// of j in the range 0 to REFS_PER_FRAME - 1.
|
||||
int found = 0;
|
||||
for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
||||
if (film_grain_params_ref_idx == cm->remapped_ref_idx[i]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
||||
"Invalid film grain reference idx %d. ref_frame_idx = "
|
||||
"{%d, %d, %d, %d, %d, %d, %d}",
|
||||
film_grain_params_ref_idx, cm->remapped_ref_idx[0],
|
||||
cm->remapped_ref_idx[1], cm->remapped_ref_idx[2],
|
||||
cm->remapped_ref_idx[3], cm->remapped_ref_idx[4],
|
||||
cm->remapped_ref_idx[5], cm->remapped_ref_idx[6]);
|
||||
}
|
||||
RefCntBuffer *const buf = cm->ref_frame_map[film_grain_params_ref_idx];
|
||||
if (buf == NULL) {
|
||||
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
||||
|
|
@ -4468,13 +4487,13 @@ void av1_read_timing_info_header(AV1_COMMON *cm,
|
|||
cm->timing_info.equal_picture_interval =
|
||||
aom_rb_read_bit(rb); // Equal picture interval bit
|
||||
if (cm->timing_info.equal_picture_interval) {
|
||||
cm->timing_info.num_ticks_per_picture =
|
||||
aom_rb_read_uvlc(rb) + 1; // ticks per picture
|
||||
if (cm->timing_info.num_ticks_per_picture == 0) {
|
||||
const uint32_t num_ticks_per_picture_minus_1 = aom_rb_read_uvlc(rb);
|
||||
if (num_ticks_per_picture_minus_1 == UINT32_MAX) {
|
||||
aom_internal_error(
|
||||
&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
||||
"num_ticks_per_picture_minus_1 cannot be (1 << 32) − 1.");
|
||||
}
|
||||
cm->timing_info.num_ticks_per_picture = num_ticks_per_picture_minus_1 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5179,7 +5198,7 @@ static int read_uncompressed_header(AV1Decoder *pbi,
|
|||
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
||||
"Inter frame requests nonexistent reference");
|
||||
|
||||
av1_set_frame_refs(cm, lst_ref, gld_ref);
|
||||
av1_set_frame_refs(cm, cm->remapped_ref_idx, lst_ref, gld_ref);
|
||||
}
|
||||
|
||||
for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
|
||||
|
|
@ -5189,7 +5208,7 @@ static int read_uncompressed_header(AV1Decoder *pbi,
|
|||
|
||||
// Most of the time, streams start with a keyframe. In that case,
|
||||
// ref_frame_map will have been filled in at that point and will not
|
||||
// contain any -1's. However, streams are explicitly allowed to start
|
||||
// contain any NULLs. However, streams are explicitly allowed to start
|
||||
// with an intra-only frame, so long as they don't then signal a
|
||||
// reference to a slot that hasn't been set yet. That's what we are
|
||||
// checking here.
|
||||
|
|
@ -5319,6 +5338,11 @@ static int read_uncompressed_header(AV1Decoder *pbi,
|
|||
}
|
||||
|
||||
read_tile_info(pbi, rb);
|
||||
if (!is_min_tile_width_satisfied(cm)) {
|
||||
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
|
||||
"Minimum tile width requirement not satisfied");
|
||||
}
|
||||
|
||||
setup_quantization(cm, rb);
|
||||
xd->bd = (int)seq_params->bit_depth;
|
||||
|
||||
|
|
|
|||
17
third_party/aom/av1/decoder/decodemv.c
vendored
17
third_party/aom/av1/decoder/decodemv.c
vendored
|
|
@ -678,11 +678,10 @@ static void read_intrabc_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
|
|||
|
||||
int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
|
||||
int_mv ref_mvs[INTRA_FRAME + 1][MAX_MV_REF_CANDIDATES];
|
||||
int_mv global_mvs[REF_FRAMES];
|
||||
|
||||
av1_find_mv_refs(cm, xd, mbmi, INTRA_FRAME, xd->ref_mv_count,
|
||||
xd->ref_mv_stack, ref_mvs, global_mvs, mi_row, mi_col,
|
||||
inter_mode_ctx);
|
||||
xd->ref_mv_stack, ref_mvs, /*global_mvs=*/NULL, mi_row,
|
||||
mi_col, inter_mode_ctx);
|
||||
|
||||
int_mv nearestmv, nearmv;
|
||||
|
||||
|
|
@ -1271,9 +1270,9 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
|
|||
const int is_compound = has_second_ref(mbmi);
|
||||
|
||||
MV_REFERENCE_FRAME ref_frame = av1_ref_frame_type(mbmi->ref_frame);
|
||||
int_mv global_mvs[REF_FRAMES];
|
||||
av1_find_mv_refs(cm, xd, mbmi, ref_frame, xd->ref_mv_count, xd->ref_mv_stack,
|
||||
ref_mvs, global_mvs, mi_row, mi_col, inter_mode_ctx);
|
||||
ref_mvs, /*global_mvs=*/NULL, mi_row, mi_col,
|
||||
inter_mode_ctx);
|
||||
|
||||
int mode_ctx = av1_mode_context_analyzer(inter_mode_ctx, mbmi->ref_frame);
|
||||
mbmi->ref_mv_idx = 0;
|
||||
|
|
@ -1421,9 +1420,12 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
|
|||
const int comp_index_ctx = get_comp_index_context(cm, xd);
|
||||
mbmi->compound_idx = aom_read_symbol(
|
||||
r, ec_ctx->compound_index_cdf[comp_index_ctx], 2, ACCT_STR);
|
||||
mbmi->interinter_comp.type =
|
||||
mbmi->compound_idx ? COMPOUND_AVERAGE : COMPOUND_DISTWTD;
|
||||
} else {
|
||||
// Distance-weighted compound is disabled, so always use average
|
||||
mbmi->compound_idx = 1;
|
||||
mbmi->interinter_comp.type = COMPOUND_AVERAGE;
|
||||
}
|
||||
} else {
|
||||
assert(cm->current_frame.reference_mode != SINGLE_REFERENCE &&
|
||||
|
|
@ -1434,8 +1436,9 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
|
|||
// compound_diffwtd, wedge
|
||||
if (is_interinter_compound_used(COMPOUND_WEDGE, bsize))
|
||||
mbmi->interinter_comp.type =
|
||||
1 + aom_read_symbol(r, ec_ctx->compound_type_cdf[bsize],
|
||||
COMPOUND_TYPES - 1, ACCT_STR);
|
||||
COMPOUND_WEDGE + aom_read_symbol(r,
|
||||
ec_ctx->compound_type_cdf[bsize],
|
||||
MASKED_COMPOUND_TYPES, ACCT_STR);
|
||||
else
|
||||
mbmi->interinter_comp.type = COMPOUND_DIFFWTD;
|
||||
|
||||
|
|
|
|||
2
third_party/aom/av1/decoder/decoder.h
vendored
2
third_party/aom/av1/decoder/decoder.h
vendored
|
|
@ -48,9 +48,9 @@ typedef void (*cfl_store_inter_block_visitor_fn_t)(AV1_COMMON *const cm,
|
|||
MACROBLOCKD *const xd);
|
||||
|
||||
typedef struct ThreadData {
|
||||
aom_reader *bit_reader;
|
||||
DECLARE_ALIGNED(32, MACROBLOCKD, xd);
|
||||
CB_BUFFER cb_buffer_base;
|
||||
aom_reader *bit_reader;
|
||||
uint8_t *mc_buf[2];
|
||||
int32_t mc_buf_size;
|
||||
int mc_buf_use_highbd; // Boolean: whether the byte pointers stored in
|
||||
|
|
|
|||
192
third_party/aom/av1/decoder/dthread.c
vendored
192
third_party/aom/av1/decoder/dthread.c
vendored
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "config/aom_config.h"
|
||||
|
||||
#include "aom_mem/aom_mem.h"
|
||||
#include "av1/common/reconinter.h"
|
||||
#include "av1/decoder/dthread.h"
|
||||
#include "av1/decoder/decoder.h"
|
||||
|
||||
// #define DEBUG_THREAD
|
||||
|
||||
// TODO(hkuang): Clean up all the #ifdef in this file.
|
||||
void av1_frameworker_lock_stats(AVxWorker *const worker) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
FrameWorkerData *const worker_data = worker->data1;
|
||||
pthread_mutex_lock(&worker_data->stats_mutex);
|
||||
#else
|
||||
(void)worker;
|
||||
#endif
|
||||
}
|
||||
|
||||
void av1_frameworker_unlock_stats(AVxWorker *const worker) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
FrameWorkerData *const worker_data = worker->data1;
|
||||
pthread_mutex_unlock(&worker_data->stats_mutex);
|
||||
#else
|
||||
(void)worker;
|
||||
#endif
|
||||
}
|
||||
|
||||
void av1_frameworker_signal_stats(AVxWorker *const worker) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
FrameWorkerData *const worker_data = worker->data1;
|
||||
|
||||
// TODO(hkuang): Fix the pthread_cond_broadcast in windows wrapper.
|
||||
#if defined(_WIN32) && !HAVE_PTHREAD_H
|
||||
pthread_cond_signal(&worker_data->stats_cond);
|
||||
#else
|
||||
pthread_cond_broadcast(&worker_data->stats_cond);
|
||||
#endif
|
||||
|
||||
#else
|
||||
(void)worker;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This macro prevents thread_sanitizer from reporting known concurrent writes.
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#define BUILDING_WITH_TSAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// TODO(hkuang): Remove worker parameter as it is only used in debug code.
|
||||
void av1_frameworker_wait(AVxWorker *const worker, RefCntBuffer *const ref_buf,
|
||||
int row) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
if (!ref_buf) return;
|
||||
|
||||
#ifndef BUILDING_WITH_TSAN
|
||||
// The following line of code will get harmless tsan error but it is the key
|
||||
// to get best performance.
|
||||
if (ref_buf->row >= row && ref_buf->buf.corrupted != 1) return;
|
||||
#endif
|
||||
|
||||
{
|
||||
// Find the worker thread that owns the reference frame. If the reference
|
||||
// frame has been fully decoded, it may not have owner.
|
||||
AVxWorker *const ref_worker = ref_buf->frame_worker_owner;
|
||||
FrameWorkerData *const ref_worker_data =
|
||||
(FrameWorkerData *)ref_worker->data1;
|
||||
const AV1Decoder *const pbi = ref_worker_data->pbi;
|
||||
|
||||
#ifdef DEBUG_THREAD
|
||||
{
|
||||
FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
|
||||
printf("%d %p worker is waiting for %d %p worker (%d) ref %d \r\n",
|
||||
worker_data->worker_id, worker, ref_worker_data->worker_id,
|
||||
ref_buf->frame_worker_owner, row, ref_buf->row);
|
||||
}
|
||||
#endif
|
||||
|
||||
av1_frameworker_lock_stats(ref_worker);
|
||||
while (ref_buf->row < row && pbi->cur_buf == ref_buf &&
|
||||
ref_buf->buf.corrupted != 1) {
|
||||
pthread_cond_wait(&ref_worker_data->stats_cond,
|
||||
&ref_worker_data->stats_mutex);
|
||||
}
|
||||
|
||||
if (ref_buf->buf.corrupted == 1) {
|
||||
FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
|
||||
av1_frameworker_unlock_stats(ref_worker);
|
||||
aom_internal_error(&worker_data->pbi->common.error,
|
||||
AOM_CODEC_CORRUPT_FRAME,
|
||||
"Worker %p failed to decode frame", worker);
|
||||
}
|
||||
av1_frameworker_unlock_stats(ref_worker);
|
||||
}
|
||||
#else
|
||||
(void)worker;
|
||||
(void)ref_buf;
|
||||
(void)row;
|
||||
(void)ref_buf;
|
||||
#endif // CONFIG_MULTITHREAD
|
||||
}
|
||||
|
||||
void av1_frameworker_broadcast(RefCntBuffer *const buf, int row) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
AVxWorker *worker = buf->frame_worker_owner;
|
||||
|
||||
#ifdef DEBUG_THREAD
|
||||
{
|
||||
FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
|
||||
printf("%d %p worker decode to (%d) \r\n", worker_data->worker_id,
|
||||
buf->frame_worker_owner, row);
|
||||
}
|
||||
#endif
|
||||
|
||||
av1_frameworker_lock_stats(worker);
|
||||
buf->row = row;
|
||||
av1_frameworker_signal_stats(worker);
|
||||
av1_frameworker_unlock_stats(worker);
|
||||
#else
|
||||
(void)buf;
|
||||
(void)row;
|
||||
#endif // CONFIG_MULTITHREAD
|
||||
}
|
||||
|
||||
void av1_frameworker_copy_context(AVxWorker *const dst_worker,
|
||||
AVxWorker *const src_worker) {
|
||||
#if CONFIG_MULTITHREAD
|
||||
FrameWorkerData *const src_worker_data = (FrameWorkerData *)src_worker->data1;
|
||||
FrameWorkerData *const dst_worker_data = (FrameWorkerData *)dst_worker->data1;
|
||||
AV1_COMMON *const src_cm = &src_worker_data->pbi->common;
|
||||
AV1_COMMON *const dst_cm = &dst_worker_data->pbi->common;
|
||||
int i;
|
||||
|
||||
// Wait until source frame's context is ready.
|
||||
av1_frameworker_lock_stats(src_worker);
|
||||
while (!src_worker_data->frame_context_ready) {
|
||||
pthread_cond_wait(&src_worker_data->stats_cond,
|
||||
&src_worker_data->stats_mutex);
|
||||
}
|
||||
|
||||
dst_cm->last_frame_seg_map = src_cm->seg.enabled
|
||||
? src_cm->current_frame_seg_map
|
||||
: src_cm->last_frame_seg_map;
|
||||
dst_worker_data->pbi->need_resync = src_worker_data->pbi->need_resync;
|
||||
av1_frameworker_unlock_stats(src_worker);
|
||||
|
||||
dst_cm->seq_params.bit_depth = src_cm->seq_params.bit_depth;
|
||||
dst_cm->seq_params.use_highbitdepth = src_cm->seq_params.use_highbitdepth;
|
||||
// TODO(zoeliu): To handle parallel decoding
|
||||
dst_cm->prev_frame =
|
||||
src_cm->show_existing_frame ? src_cm->prev_frame : src_cm->cur_frame;
|
||||
dst_cm->last_width =
|
||||
!src_cm->show_existing_frame ? src_cm->width : src_cm->last_width;
|
||||
dst_cm->last_height =
|
||||
!src_cm->show_existing_frame ? src_cm->height : src_cm->last_height;
|
||||
dst_cm->seq_params.subsampling_x = src_cm->seq_params.subsampling_x;
|
||||
dst_cm->seq_params.subsampling_y = src_cm->seq_params.subsampling_y;
|
||||
dst_cm->frame_type = src_cm->frame_type;
|
||||
dst_cm->last_show_frame = !src_cm->show_existing_frame
|
||||
? src_cm->show_frame
|
||||
: src_cm->last_show_frame;
|
||||
for (i = 0; i < REF_FRAMES; ++i)
|
||||
dst_cm->ref_frame_map[i] = src_cm->next_ref_frame_map[i];
|
||||
|
||||
memcpy(dst_cm->lf_info.lfthr, src_cm->lf_info.lfthr,
|
||||
(MAX_LOOP_FILTER + 1) * sizeof(loop_filter_thresh));
|
||||
dst_cm->lf.sharpness_level = src_cm->lf.sharpness_level;
|
||||
dst_cm->lf.filter_level[0] = src_cm->lf.filter_level[0];
|
||||
dst_cm->lf.filter_level[1] = src_cm->lf.filter_level[1];
|
||||
memcpy(dst_cm->lf.ref_deltas, src_cm->lf.ref_deltas, REF_FRAMES);
|
||||
memcpy(dst_cm->lf.mode_deltas, src_cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
|
||||
dst_cm->seg = src_cm->seg;
|
||||
memcpy(dst_cm->frame_contexts, src_cm->frame_contexts,
|
||||
FRAME_CONTEXTS * sizeof(dst_cm->frame_contexts[0]));
|
||||
#else
|
||||
(void)dst_worker;
|
||||
(void)src_worker;
|
||||
#endif // CONFIG_MULTITHREAD
|
||||
}
|
||||
3
third_party/aom/av1/decoder/inspection.c
vendored
3
third_party/aom/av1/decoder/inspection.c
vendored
|
|
@ -82,6 +82,9 @@ int ifd_inspect(insp_frame_data *fd, void *decoder, int skip_not_transform) {
|
|||
mi->ref_frame[1] = mbmi->ref_frame[1];
|
||||
// Prediction Mode
|
||||
mi->mode = mbmi->mode;
|
||||
mi->intrabc = (int16_t)mbmi->use_intrabc;
|
||||
mi->palette = (int16_t)mbmi->palette_mode_info.palette_size[0];
|
||||
mi->uv_palette = (int16_t)mbmi->palette_mode_info.palette_size[1];
|
||||
// Prediction Mode for Chromatic planes
|
||||
if (mi->mode < INTRA_MODES) {
|
||||
mi->uv_mode = mbmi->uv_mode;
|
||||
|
|
|
|||
3
third_party/aom/av1/decoder/inspection.h
vendored
3
third_party/aom/av1/decoder/inspection.h
vendored
|
|
@ -52,6 +52,9 @@ struct insp_mi_data {
|
|||
int16_t current_qindex;
|
||||
int16_t compound_type;
|
||||
int16_t motion_mode;
|
||||
int16_t intrabc;
|
||||
int16_t palette;
|
||||
int16_t uv_palette;
|
||||
};
|
||||
|
||||
typedef struct insp_frame_data insp_frame_data;
|
||||
|
|
|
|||
21
third_party/aom/av1/decoder/obu.c
vendored
21
third_party/aom/av1/decoder/obu.c
vendored
|
|
@ -98,12 +98,10 @@ static int byte_alignment(AV1_COMMON *const cm,
|
|||
static uint32_t read_temporal_delimiter_obu() { return 0; }
|
||||
|
||||
// Returns a boolean that indicates success.
|
||||
static int read_bitstream_level(BitstreamLevel *bl,
|
||||
static int read_bitstream_level(AV1_LEVEL *seq_level_idx,
|
||||
struct aom_read_bit_buffer *rb) {
|
||||
const uint8_t seq_level_idx = aom_rb_read_literal(rb, LEVEL_BITS);
|
||||
if (!is_valid_seq_level_idx(seq_level_idx)) return 0;
|
||||
bl->major = (seq_level_idx >> LEVEL_MINOR_BITS) + LEVEL_MAJOR_MIN;
|
||||
bl->minor = seq_level_idx & ((1 << LEVEL_MINOR_BITS) - 1);
|
||||
*seq_level_idx = aom_rb_read_literal(rb, LEVEL_BITS);
|
||||
if (!is_valid_seq_level_idx(*seq_level_idx)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +149,7 @@ static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
|
|||
seq_params->display_model_info_present_flag = 0;
|
||||
seq_params->operating_points_cnt_minus_1 = 0;
|
||||
seq_params->operating_point_idc[0] = 0;
|
||||
if (!read_bitstream_level(&seq_params->level[0], rb)) {
|
||||
if (!read_bitstream_level(&seq_params->seq_level_idx[0], rb)) {
|
||||
cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -175,13 +173,13 @@ static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
|
|||
for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) {
|
||||
seq_params->operating_point_idc[i] =
|
||||
aom_rb_read_literal(rb, OP_POINTS_IDC_BITS);
|
||||
if (!read_bitstream_level(&seq_params->level[i], rb)) {
|
||||
if (!read_bitstream_level(&seq_params->seq_level_idx[i], rb)) {
|
||||
cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
|
||||
return 0;
|
||||
}
|
||||
// This is the seq_level_idx[i] > 7 check in the spec. seq_level_idx 7
|
||||
// is equivalent to level 3.3.
|
||||
if (seq_params->level[i].major > 3)
|
||||
if (seq_params->seq_level_idx[i] >= SEQ_LEVEL_4_0)
|
||||
seq_params->tier[i] = aom_rb_read_bit(rb);
|
||||
else
|
||||
seq_params->tier[i] = 0;
|
||||
|
|
@ -195,10 +193,9 @@ static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
|
|||
if (cm->timing_info_present &&
|
||||
(cm->timing_info.equal_picture_interval ||
|
||||
cm->op_params[i].decoder_model_param_present_flag)) {
|
||||
cm->op_params[i].bitrate = max_level_bitrate(
|
||||
seq_params->profile,
|
||||
major_minor_to_seq_level_idx(seq_params->level[i]),
|
||||
seq_params->tier[i]);
|
||||
cm->op_params[i].bitrate =
|
||||
max_level_bitrate(seq_params->profile, seq_params->seq_level_idx[i],
|
||||
seq_params->tier[i]);
|
||||
// Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass
|
||||
// the check
|
||||
if (cm->op_params[i].bitrate == 0)
|
||||
|
|
|
|||
189
third_party/aom/av1/encoder/aq_cyclicrefresh.c
vendored
189
third_party/aom/av1/encoder/aq_cyclicrefresh.c
vendored
|
|
@ -31,9 +31,9 @@ struct CYCLIC_REFRESH {
|
|||
// excess of the cycle time, i.e., in the case of all zero motion, block
|
||||
// will be refreshed every (100/percent_refresh + time_for_refresh) frames.
|
||||
int time_for_refresh;
|
||||
// Target number of (8x8) blocks that are set for delta-q.
|
||||
// Target number of (4x4) blocks that are set for delta-q.
|
||||
int target_num_seg_blocks;
|
||||
// Actual number of (8x8) blocks that were applied delta-q.
|
||||
// Actual number of (4x4) blocks that were applied delta-q.
|
||||
int actual_num_seg1_blocks;
|
||||
int actual_num_seg2_blocks;
|
||||
// RD mult. parameters for segment 1.
|
||||
|
|
@ -55,6 +55,8 @@ struct CYCLIC_REFRESH {
|
|||
int rate_boost_fac;
|
||||
double low_content_avg;
|
||||
int qindex_delta[3];
|
||||
double weight_segment;
|
||||
int apply_cyclic_refresh;
|
||||
};
|
||||
|
||||
CYCLIC_REFRESH *av1_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
|
||||
|
|
@ -87,27 +89,6 @@ void av1_cyclic_refresh_free(CYCLIC_REFRESH *cr) {
|
|||
}
|
||||
}
|
||||
|
||||
// Check if we should turn off cyclic refresh based on bitrate condition.
|
||||
static int apply_cyclic_refresh_bitrate(const AV1_COMMON *cm,
|
||||
const RATE_CONTROL *rc) {
|
||||
// Turn off cyclic refresh if bits available per frame is not sufficiently
|
||||
// larger than bit cost of segmentation. Segment map bit cost should scale
|
||||
// with number of seg blocks, so compare available bits to number of blocks.
|
||||
// Average bits available per frame = avg_frame_bandwidth
|
||||
// Number of (8x8) blocks in frame = mi_rows * mi_cols;
|
||||
const float factor = 0.25;
|
||||
const int number_blocks = cm->mi_rows * cm->mi_cols;
|
||||
// The condition below corresponds to turning off at target bitrates:
|
||||
// (at 30fps), ~12kbps for CIF, 36kbps for VGA, 100kps for HD/720p.
|
||||
// Also turn off at very small frame sizes, to avoid too large fraction of
|
||||
// superblocks to be refreshed per frame. Threshold below is less than QCIF.
|
||||
if (rc->avg_frame_bandwidth < factor * number_blocks ||
|
||||
number_blocks / 64 < 5)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if this coding block, of size bsize, should be considered for refresh
|
||||
// (lower-qp coding). Decision can be based on various factors, such as
|
||||
// size of the coding block (i.e., below min_block size rejected), coding
|
||||
|
|
@ -158,11 +139,11 @@ int av1_cyclic_refresh_estimate_bits_at_q(const AV1_COMP *cpi,
|
|||
const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
int estimated_bits;
|
||||
int mbs = cm->MBs;
|
||||
int num8x8bl = mbs << 2;
|
||||
int num4x4bl = mbs << 4;
|
||||
// Weight for non-base segments: use actual number of blocks refreshed in
|
||||
// previous/just encoded frame. Note number of blocks here is in 8x8 units.
|
||||
double weight_segment1 = (double)cr->actual_num_seg1_blocks / num8x8bl;
|
||||
double weight_segment2 = (double)cr->actual_num_seg2_blocks / num8x8bl;
|
||||
// previous/just encoded frame. Note number of blocks here is in 4x4 units.
|
||||
double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
|
||||
double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
|
||||
// Take segment weighted average for estimated bits.
|
||||
estimated_bits =
|
||||
(int)((1.0 - weight_segment1 - weight_segment2) *
|
||||
|
|
@ -190,14 +171,14 @@ int av1_cyclic_refresh_rc_bits_per_mb(const AV1_COMP *cpi, int i,
|
|||
const AV1_COMMON *const cm = &cpi->common;
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
int bits_per_mb;
|
||||
int num8x8bl = cm->MBs << 2;
|
||||
int num4x4bl = cm->MBs << 4;
|
||||
// Weight for segment prior to encoding: take the average of the target
|
||||
// number for the frame to be encoded and the actual from the previous frame.
|
||||
double weight_segment =
|
||||
(double)((cr->target_num_seg_blocks + cr->actual_num_seg1_blocks +
|
||||
cr->actual_num_seg2_blocks) >>
|
||||
1) /
|
||||
num8x8bl;
|
||||
num4x4bl;
|
||||
// Compute delta-q corresponding to qindex i.
|
||||
int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta);
|
||||
// Take segment weighted average for bits per mb.
|
||||
|
|
@ -264,21 +245,6 @@ void av1_cyclic_refresh_update_segment(const AV1_COMP *cpi,
|
|||
int map_offset = block_index + y * cm->mi_cols + x;
|
||||
cr->map[map_offset] = new_map_value;
|
||||
cpi->segmentation_map[map_offset] = mbmi->segment_id;
|
||||
// Inter skip blocks were clearly not coded at the current qindex, so
|
||||
// don't update the map for them. For cases where motion is non-zero or
|
||||
// the reference frame isn't the previous frame, the previous value in
|
||||
// the map for this spatial location is not entirely correct.
|
||||
if ((!is_inter_block(mbmi) || !skip) &&
|
||||
mbmi->segment_id <= CR_SEGMENT_ID_BOOST2) {
|
||||
cr->last_coded_q_map[map_offset] = clamp(
|
||||
cm->base_qindex + cr->qindex_delta[mbmi->segment_id], 0, MAXQ);
|
||||
} else if (is_inter_block(mbmi) && skip &&
|
||||
mbmi->segment_id <= CR_SEGMENT_ID_BOOST2) {
|
||||
cr->last_coded_q_map[map_offset] =
|
||||
AOMMIN(clamp(cm->base_qindex + cr->qindex_delta[mbmi->segment_id],
|
||||
0, MAXQ),
|
||||
cr->last_coded_q_map[map_offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,73 +281,6 @@ void av1_cyclic_refresh_set_golden_update(AV1_COMP *const cpi) {
|
|||
rc->baseline_gf_interval = 40;
|
||||
}
|
||||
|
||||
// Update some encoding stats (from the just encoded frame). If this frame's
|
||||
// background has high motion, refresh the golden frame. Otherwise, if the
|
||||
// golden reference is to be updated check if we should NOT update the golden
|
||||
// ref.
|
||||
void av1_cyclic_refresh_check_golden_update(AV1_COMP *const cpi) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
int mi_row, mi_col;
|
||||
double fraction_low = 0.0;
|
||||
int low_content_frame = 0;
|
||||
|
||||
MB_MODE_INFO **mi;
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
const int rows = cm->mi_rows, cols = cm->mi_cols;
|
||||
int cnt1 = 0, cnt2 = 0;
|
||||
int force_gf_refresh = 0;
|
||||
|
||||
for (mi_row = 0; mi_row < rows; mi_row++) {
|
||||
mi = cm->mi_grid_visible + mi_row * cm->mi_stride;
|
||||
|
||||
for (mi_col = 0; mi_col < cols; mi_col++) {
|
||||
int16_t abs_mvr = mi[0]->mv[0].as_mv.row >= 0
|
||||
? mi[0]->mv[0].as_mv.row
|
||||
: -1 * mi[0]->mv[0].as_mv.row;
|
||||
int16_t abs_mvc = mi[0]->mv[0].as_mv.col >= 0
|
||||
? mi[0]->mv[0].as_mv.col
|
||||
: -1 * mi[0]->mv[0].as_mv.col;
|
||||
|
||||
// Calculate the motion of the background.
|
||||
if (abs_mvr <= 16 && abs_mvc <= 16) {
|
||||
cnt1++;
|
||||
if (abs_mvr == 0 && abs_mvc == 0) cnt2++;
|
||||
}
|
||||
mi++;
|
||||
|
||||
// Accumulate low_content_frame.
|
||||
if (cr->map[mi_row * cols + mi_col] < 1) low_content_frame++;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
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;
|
||||
|
||||
if (rc->frames_till_gf_update_due > rc->frames_to_key)
|
||||
rc->frames_till_gf_update_due = rc->frames_to_key;
|
||||
cpi->refresh_golden_frame = 1;
|
||||
force_gf_refresh = 1;
|
||||
}
|
||||
|
||||
fraction_low = (double)low_content_frame / (rows * cols);
|
||||
// Update average.
|
||||
cr->low_content_avg = (fraction_low + 3 * cr->low_content_avg) / 4;
|
||||
if (!force_gf_refresh && cpi->refresh_golden_frame == 1) {
|
||||
// Don't update golden reference if the amount of low_content for the
|
||||
// current encoded frame is small, or if the recursive average of the
|
||||
// low_content over the update interval window falls below threshold.
|
||||
if (fraction_low < 0.8 || cr->low_content_avg < 0.7)
|
||||
cpi->refresh_golden_frame = 0;
|
||||
// Reset for next internal.
|
||||
cr->low_content_avg = fraction_low;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the segmentation map, and related quantities: cyclic refresh map,
|
||||
// refresh sb_index, and target number of blocks to be refreshed.
|
||||
// The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
|
||||
|
|
@ -458,26 +357,70 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
|
|||
|
||||
// Set cyclic refresh parameters.
|
||||
void av1_cyclic_refresh_update_parameters(AV1_COMP *const cpi) {
|
||||
// TODO(marpan): Parameters need to be tuned.
|
||||
const RATE_CONTROL *const rc = &cpi->rc;
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
int num4x4bl = cm->MBs << 4;
|
||||
int target_refresh = 0;
|
||||
double weight_segment_target = 0;
|
||||
double weight_segment = 0;
|
||||
int qp_thresh = AOMMIN(20, rc->best_quality << 1);
|
||||
cr->apply_cyclic_refresh = 1;
|
||||
if (frame_is_intra_only(cm) || is_lossless_requested(&cpi->oxcf) ||
|
||||
rc->avg_frame_qindex[INTER_FRAME] < qp_thresh) {
|
||||
cr->apply_cyclic_refresh = 0;
|
||||
return;
|
||||
}
|
||||
cr->percent_refresh = 10;
|
||||
cr->max_qdelta_perc = 50;
|
||||
cr->max_qdelta_perc = 60;
|
||||
cr->time_for_refresh = 0;
|
||||
cr->motion_thresh = 32;
|
||||
cr->rate_boost_fac = 15;
|
||||
// Use larger delta-qp (increase rate_ratio_qdelta) for first few (~4)
|
||||
// periods of the refresh cycle, after a key frame.
|
||||
if (rc->frames_since_key < 4 * cr->percent_refresh)
|
||||
// Account for larger interval on base layer for temporal layers.
|
||||
if (cr->percent_refresh > 0 &&
|
||||
rc->frames_since_key < 400 / cr->percent_refresh) {
|
||||
cr->rate_ratio_qdelta = 3.0;
|
||||
else
|
||||
cr->rate_ratio_qdelta = 2.0;
|
||||
// Adjust some parameters for low resolutions at low bitrates.
|
||||
if (cm->width <= 352 && cm->height <= 288 && rc->avg_frame_bandwidth < 3400) {
|
||||
cr->motion_thresh = 4;
|
||||
cr->rate_boost_fac = 10;
|
||||
} else {
|
||||
cr->motion_thresh = 32;
|
||||
cr->rate_boost_fac = 17;
|
||||
cr->rate_ratio_qdelta = 2.0;
|
||||
}
|
||||
// Adjust some parameters for low resolutions.
|
||||
if (cm->width <= 352 && cm->height <= 288) {
|
||||
if (rc->avg_frame_bandwidth < 3000) {
|
||||
cr->motion_thresh = 16;
|
||||
cr->rate_boost_fac = 13;
|
||||
} else {
|
||||
cr->max_qdelta_perc = 70;
|
||||
cr->rate_ratio_qdelta = AOMMAX(cr->rate_ratio_qdelta, 2.5);
|
||||
}
|
||||
}
|
||||
if (cpi->oxcf.rc_mode == AOM_VBR) {
|
||||
// To be adjusted for VBR mode, e.g., based on gf period and boost.
|
||||
// For now use smaller qp-delta (than CBR), no second boosted seg, and
|
||||
// turn-off (no refresh) on golden refresh (since it's already boosted).
|
||||
cr->percent_refresh = 10;
|
||||
cr->rate_ratio_qdelta = 1.5;
|
||||
cr->rate_boost_fac = 10;
|
||||
if (cpi->refresh_golden_frame == 1) {
|
||||
cr->percent_refresh = 0;
|
||||
cr->rate_ratio_qdelta = 1.0;
|
||||
}
|
||||
}
|
||||
// Weight for segment prior to encoding: take the average of the target
|
||||
// number for the frame to be encoded and the actual from the previous frame.
|
||||
// Use the target if its less. To be used for setting the base qp for the
|
||||
// frame in vp9_rc_regulate_q.
|
||||
target_refresh = cr->percent_refresh * cm->mi_rows * cm->mi_cols / 100;
|
||||
weight_segment_target = (double)(target_refresh) / num4x4bl;
|
||||
weight_segment = (double)((target_refresh + cr->actual_num_seg1_blocks +
|
||||
cr->actual_num_seg2_blocks) >>
|
||||
1) /
|
||||
num4x4bl;
|
||||
if (weight_segment_target < 7 * weight_segment / 8)
|
||||
weight_segment = weight_segment_target;
|
||||
cr->weight_segment = weight_segment;
|
||||
}
|
||||
|
||||
// Setup cyclic background refresh: set delta q and segmentation map.
|
||||
|
|
@ -486,7 +429,6 @@ void av1_cyclic_refresh_setup(AV1_COMP *const cpi) {
|
|||
const RATE_CONTROL *const rc = &cpi->rc;
|
||||
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
|
||||
struct segmentation *const seg = &cm->seg;
|
||||
const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
|
||||
int resolution_change =
|
||||
cm->prev_frame && (cm->width != cm->prev_frame->width ||
|
||||
cm->height != cm->prev_frame->height);
|
||||
|
|
@ -498,8 +440,7 @@ void av1_cyclic_refresh_setup(AV1_COMP *const cpi) {
|
|||
return;
|
||||
}
|
||||
if (cm->current_frame.frame_number == 0) cr->low_content_avg = 0.0;
|
||||
// Don't apply refresh on key frame or enhancement layer frames.
|
||||
if (!apply_cyclic_refresh || cm->current_frame.frame_type == KEY_FRAME) {
|
||||
if (!cr->apply_cyclic_refresh) {
|
||||
// Set segmentation map to 0 and disable.
|
||||
unsigned char *const seg_map = cpi->segmentation_map;
|
||||
memset(seg_map, 0, cm->mi_rows * cm->mi_cols);
|
||||
|
|
|
|||
|
|
@ -54,19 +54,12 @@ void av1_cyclic_refresh_update_segment(const struct AV1_COMP *cpi,
|
|||
int mi_col, BLOCK_SIZE bsize,
|
||||
int64_t rate, int64_t dist, int skip);
|
||||
|
||||
// Update the segmentation map, and related quantities: cyclic refresh map,
|
||||
// refresh sb_index, and target number of blocks to be refreshed.
|
||||
void av1_cyclic_refresh_update__map(struct AV1_COMP *const cpi);
|
||||
|
||||
// Update the actual number of blocks that were applied the segment delta q.
|
||||
void av1_cyclic_refresh_postencode(struct AV1_COMP *const cpi);
|
||||
|
||||
// Set golden frame update interval, for 1 pass CBR mode.
|
||||
void av1_cyclic_refresh_set_golden_update(struct AV1_COMP *const cpi);
|
||||
|
||||
// Check if we should not update golden reference, based on past refresh stats.
|
||||
void av1_cyclic_refresh_check_golden_update(struct AV1_COMP *const cpi);
|
||||
|
||||
// Set/update global/frame level refresh parameters.
|
||||
void av1_cyclic_refresh_update_parameters(struct AV1_COMP *const cpi);
|
||||
|
||||
|
|
|
|||
10
third_party/aom/av1/encoder/av1_quantize.c
vendored
10
third_party/aom/av1/encoder/av1_quantize.c
vendored
|
|
@ -276,13 +276,13 @@ void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
|||
} else {
|
||||
switch (qparam->log_scale) {
|
||||
case 0:
|
||||
aom_quantize_b_adaptive_c(
|
||||
coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
|
||||
p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
|
||||
eob_ptr, sc->scan, sc->iscan);
|
||||
aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX,
|
||||
p->round_QTX, p->quant_QTX,
|
||||
p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
|
||||
p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
|
||||
break;
|
||||
case 1:
|
||||
aom_quantize_b_32x32_adaptive_c(
|
||||
aom_quantize_b_32x32_adaptive(
|
||||
coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
|
||||
p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
|
||||
eob_ptr, sc->scan, sc->iscan);
|
||||
|
|
|
|||
3
third_party/aom/av1/encoder/av1_quantize.h
vendored
3
third_party/aom/av1/encoder/av1_quantize.h
vendored
|
|
@ -22,6 +22,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EOB_FACTOR 325
|
||||
#define SKIP_EOB_FACTOR_ADJUST 200
|
||||
|
||||
typedef struct QUANT_PARAM {
|
||||
int log_scale;
|
||||
TX_SIZE tx_size;
|
||||
|
|
|
|||
114
third_party/aom/av1/encoder/bitstream.c
vendored
114
third_party/aom/av1/encoder/bitstream.c
vendored
|
|
@ -369,10 +369,18 @@ static void pack_txb_tokens(aom_writer *w, AV1_COMMON *cm, MACROBLOCK *const x,
|
|||
blk_col)];
|
||||
|
||||
if (tx_size == plane_tx_size || plane) {
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
|
||||
const uint16_t eob = x->mbmi_ext->eobs[plane][block];
|
||||
TXB_CTX txb_ctx = { x->mbmi_ext->txb_skip_ctx[plane][block],
|
||||
x->mbmi_ext->dc_sign_ctx[plane][block] };
|
||||
const int txb_offset =
|
||||
x->mbmi_ext->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
|
||||
tran_low_t *tcoeff_txb =
|
||||
x->mbmi_ext->cb_coef_buff->tcoeff[plane] + x->mbmi_ext->cb_offset;
|
||||
uint16_t *eob_txb = x->mbmi_ext->cb_coef_buff->eobs[plane] + txb_offset;
|
||||
uint8_t *txb_skip_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->txb_skip_ctx[plane] + txb_offset;
|
||||
int *dc_sign_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->dc_sign_ctx[plane] + txb_offset;
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(tcoeff_txb, block);
|
||||
const uint16_t eob = eob_txb[block];
|
||||
TXB_CTX txb_ctx = { txb_skip_ctx_txb[block], dc_sign_ctx_txb[block] };
|
||||
av1_write_coeffs_txb(cm, xd, w, blk_row, blk_col, plane, tx_size, tcoeff,
|
||||
eob, &txb_ctx);
|
||||
#if CONFIG_RD_DEBUG
|
||||
|
|
@ -627,7 +635,7 @@ static void write_mb_interp_filter(AV1_COMP *cpi, const MACROBLOCKD *xd,
|
|||
av1_extract_interp_filter(mbmi->interp_filters, dir);
|
||||
aom_write_symbol(w, filter, ec_ctx->switchable_interp_cdf[ctx],
|
||||
SWITCHABLE_FILTERS);
|
||||
++cpi->interp_filter_selected[0][filter];
|
||||
++cm->cur_frame->interp_filter_selected[filter];
|
||||
if (cm->seq_params.enable_dual_filter == 0) return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1162,9 +1170,9 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
|
|||
mbmi->interinter_comp.type == COMPOUND_DIFFWTD);
|
||||
|
||||
if (is_interinter_compound_used(COMPOUND_WEDGE, bsize))
|
||||
aom_write_symbol(w, mbmi->interinter_comp.type - 1,
|
||||
aom_write_symbol(w, mbmi->interinter_comp.type - COMPOUND_WEDGE,
|
||||
ec_ctx->compound_type_cdf[bsize],
|
||||
COMPOUND_TYPES - 1);
|
||||
MASKED_COMPOUND_TYPES);
|
||||
|
||||
if (mbmi->interinter_comp.type == COMPOUND_WEDGE) {
|
||||
assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
|
||||
|
|
@ -1288,7 +1296,7 @@ static void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) {
|
|||
}
|
||||
|
||||
const int16_t mode_ctx =
|
||||
is_comp_ref ? mbmi_ext->compound_mode_context[mbmi->ref_frame[0]]
|
||||
is_comp_ref ? 0
|
||||
: av1_mode_context_analyzer(mbmi_ext->mode_context,
|
||||
mbmi->ref_frame);
|
||||
|
||||
|
|
@ -2743,21 +2751,14 @@ static int check_frame_refs_short_signaling(AV1_COMMON *const cm) {
|
|||
|
||||
// Check whether the encoder side ref frame choices are aligned with that to
|
||||
// be derived at the decoder side.
|
||||
int remapped_ref_idx_copy[REF_FRAMES];
|
||||
struct scale_factors ref_scale_factors_copy[REF_FRAMES];
|
||||
|
||||
// Backup the frame refs info
|
||||
memcpy(remapped_ref_idx_copy, cm->remapped_ref_idx,
|
||||
REF_FRAMES * sizeof(*remapped_ref_idx_copy));
|
||||
memcpy(ref_scale_factors_copy, cm->ref_scale_factors,
|
||||
REF_FRAMES * sizeof(*ref_scale_factors_copy));
|
||||
int remapped_ref_idx_decoder[REF_FRAMES];
|
||||
|
||||
const int lst_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
|
||||
const int gld_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
|
||||
|
||||
// Set up the frame refs mapping indexes according to the
|
||||
// frame_refs_short_signaling policy.
|
||||
av1_set_frame_refs(cm, lst_map_idx, gld_map_idx);
|
||||
av1_set_frame_refs(cm, remapped_ref_idx_decoder, lst_map_idx, gld_map_idx);
|
||||
|
||||
// We only turn on frame_refs_short_signaling when the encoder side decision
|
||||
// on ref frames is identical to that at the decoder side.
|
||||
|
|
@ -2765,10 +2766,11 @@ static int check_frame_refs_short_signaling(AV1_COMMON *const cm) {
|
|||
for (int ref_idx = 0; ref_idx < INTER_REFS_PER_FRAME; ++ref_idx) {
|
||||
// Compare the buffer index between two reference frames indexed
|
||||
// respectively by the encoder and the decoder side decisions.
|
||||
RefCntBuffer *ref_frame_buf_copy = NULL;
|
||||
if (remapped_ref_idx_copy[ref_idx] != INVALID_IDX)
|
||||
ref_frame_buf_copy = cm->ref_frame_map[remapped_ref_idx_copy[ref_idx]];
|
||||
if (get_ref_frame_buf(cm, LAST_FRAME + ref_idx) != ref_frame_buf_copy) {
|
||||
RefCntBuffer *ref_frame_buf_new = NULL;
|
||||
if (remapped_ref_idx_decoder[ref_idx] != INVALID_IDX) {
|
||||
ref_frame_buf_new = cm->ref_frame_map[remapped_ref_idx_decoder[ref_idx]];
|
||||
}
|
||||
if (get_ref_frame_buf(cm, LAST_FRAME + ref_idx) != ref_frame_buf_new) {
|
||||
frame_refs_short_signaling = 0;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2786,13 +2788,6 @@ static int check_frame_refs_short_signaling(AV1_COMMON *const cm) {
|
|||
}
|
||||
#endif // 0
|
||||
|
||||
// Restore the frame refs info if frame_refs_short_signaling is off.
|
||||
if (!frame_refs_short_signaling) {
|
||||
memcpy(cm->remapped_ref_idx, remapped_ref_idx_copy,
|
||||
REF_FRAMES * sizeof(*remapped_ref_idx_copy));
|
||||
memcpy(cm->ref_scale_factors, ref_scale_factors_copy,
|
||||
REF_FRAMES * sizeof(*ref_scale_factors_copy));
|
||||
}
|
||||
return frame_refs_short_signaling;
|
||||
}
|
||||
|
||||
|
|
@ -2805,6 +2800,8 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
|
|||
MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
|
||||
CurrentFrame *const current_frame = &cm->current_frame;
|
||||
|
||||
current_frame->frame_refs_short_signaling = 0;
|
||||
|
||||
if (seq_params->still_picture) {
|
||||
assert(cm->show_existing_frame == 0);
|
||||
assert(cm->show_frame == 1);
|
||||
|
|
@ -2867,24 +2864,25 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
|
|||
int frame_size_override_flag = 0;
|
||||
|
||||
if (seq_params->reduced_still_picture_hdr) {
|
||||
assert(cm->width == seq_params->max_frame_width &&
|
||||
cm->height == seq_params->max_frame_height);
|
||||
assert(cm->superres_upscaled_width == seq_params->max_frame_width &&
|
||||
cm->superres_upscaled_height == seq_params->max_frame_height);
|
||||
} else {
|
||||
if (seq_params->frame_id_numbers_present_flag) {
|
||||
int frame_id_len = seq_params->frame_id_length;
|
||||
aom_wb_write_literal(wb, cm->current_frame_id, frame_id_len);
|
||||
}
|
||||
|
||||
if (cm->width > seq_params->max_frame_width ||
|
||||
cm->height > seq_params->max_frame_height) {
|
||||
if (cm->superres_upscaled_width > seq_params->max_frame_width ||
|
||||
cm->superres_upscaled_height > seq_params->max_frame_height) {
|
||||
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
|
||||
"Frame dimensions are larger than the maximum values");
|
||||
}
|
||||
|
||||
frame_size_override_flag =
|
||||
frame_is_sframe(cm) ? 1
|
||||
: (cm->width != seq_params->max_frame_width ||
|
||||
cm->height != seq_params->max_frame_height);
|
||||
frame_is_sframe(cm)
|
||||
? 1
|
||||
: (cm->superres_upscaled_width != seq_params->max_frame_width ||
|
||||
cm->superres_upscaled_height != seq_params->max_frame_height);
|
||||
if (!frame_is_sframe(cm)) aom_wb_write_bit(wb, frame_size_override_flag);
|
||||
|
||||
if (seq_params->order_hint_info.enable_order_hint)
|
||||
|
|
@ -2960,25 +2958,25 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
|
|||
|
||||
// NOTE: Error resilient mode turns off frame_refs_short_signaling
|
||||
// automatically.
|
||||
int frame_refs_short_signaling = 0;
|
||||
#define FRAME_REFS_SHORT_SIGNALING 0
|
||||
#if FRAME_REFS_SHORT_SIGNALING
|
||||
frame_refs_short_signaling =
|
||||
current_frame->frame_refs_short_signaling =
|
||||
seq_params->order_hint_info.enable_order_hint;
|
||||
#endif // FRAME_REFS_SHORT_SIGNALING
|
||||
|
||||
if (frame_refs_short_signaling) {
|
||||
if (current_frame->frame_refs_short_signaling) {
|
||||
// NOTE(zoeliu@google.com):
|
||||
// An example solution for encoder-side implementation on frame refs
|
||||
// short signaling, which is only turned on when the encoder side
|
||||
// decision on ref frames is identical to that at the decoder side.
|
||||
frame_refs_short_signaling = check_frame_refs_short_signaling(cm);
|
||||
current_frame->frame_refs_short_signaling =
|
||||
check_frame_refs_short_signaling(cm);
|
||||
}
|
||||
|
||||
if (seq_params->order_hint_info.enable_order_hint)
|
||||
aom_wb_write_bit(wb, frame_refs_short_signaling);
|
||||
aom_wb_write_bit(wb, current_frame->frame_refs_short_signaling);
|
||||
|
||||
if (frame_refs_short_signaling) {
|
||||
if (current_frame->frame_refs_short_signaling) {
|
||||
const int lst_ref = get_ref_frame_map_idx(cm, LAST_FRAME);
|
||||
aom_wb_write_literal(wb, lst_ref, REF_FRAMES_LOG2);
|
||||
|
||||
|
|
@ -2988,7 +2986,7 @@ static void write_uncompressed_header_obu(AV1_COMP *cpi,
|
|||
|
||||
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
||||
assert(get_ref_frame_map_idx(cm, ref_frame) != INVALID_IDX);
|
||||
if (!frame_refs_short_signaling)
|
||||
if (!current_frame->frame_refs_short_signaling)
|
||||
aom_wb_write_literal(wb, get_ref_frame_map_idx(cm, ref_frame),
|
||||
REF_FRAMES_LOG2);
|
||||
if (seq_params->frame_id_numbers_present_flag) {
|
||||
|
|
@ -3236,8 +3234,12 @@ static int remux_tiles(const AV1_COMMON *const cm, uint8_t *dst,
|
|||
return wpos;
|
||||
}
|
||||
|
||||
uint32_t write_obu_header(OBU_TYPE obu_type, int obu_extension,
|
||||
uint8_t *const dst) {
|
||||
uint32_t av1_write_obu_header(AV1_COMP *const cpi, OBU_TYPE obu_type,
|
||||
int obu_extension, uint8_t *const dst) {
|
||||
if (cpi->keep_level_stats &&
|
||||
(obu_type == OBU_FRAME || obu_type == OBU_FRAME_HEADER))
|
||||
++cpi->frame_header_count;
|
||||
|
||||
struct aom_write_bit_buffer wb = { dst, 0 };
|
||||
uint32_t size = 0;
|
||||
|
||||
|
|
@ -3289,9 +3291,8 @@ static void add_trailing_bits(struct aom_write_bit_buffer *wb) {
|
|||
}
|
||||
}
|
||||
|
||||
static void write_bitstream_level(BitstreamLevel bl,
|
||||
static void write_bitstream_level(AV1_LEVEL seq_level_idx,
|
||||
struct aom_write_bit_buffer *wb) {
|
||||
uint8_t seq_level_idx = major_minor_to_seq_level_idx(bl);
|
||||
assert(is_valid_seq_level_idx(seq_level_idx));
|
||||
aom_wb_write_literal(wb, seq_level_idx, LEVEL_BITS);
|
||||
}
|
||||
|
|
@ -3314,7 +3315,7 @@ uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
|
|||
assert(cm->timing_info_present == 0);
|
||||
assert(cm->seq_params.decoder_model_info_present_flag == 0);
|
||||
assert(cm->seq_params.display_model_info_present_flag == 0);
|
||||
write_bitstream_level(cm->seq_params.level[0], &wb);
|
||||
write_bitstream_level(cm->seq_params.seq_level_idx[0], &wb);
|
||||
} else {
|
||||
aom_wb_write_bit(&wb, cm->timing_info_present); // timing info present flag
|
||||
|
||||
|
|
@ -3333,8 +3334,8 @@ uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
|
|||
for (i = 0; i < cm->seq_params.operating_points_cnt_minus_1 + 1; i++) {
|
||||
aom_wb_write_literal(&wb, cm->seq_params.operating_point_idc[i],
|
||||
OP_POINTS_IDC_BITS);
|
||||
write_bitstream_level(cm->seq_params.level[i], &wb);
|
||||
if (cm->seq_params.level[i].major > 3)
|
||||
write_bitstream_level(cm->seq_params.seq_level_idx[i], &wb);
|
||||
if (cm->seq_params.seq_level_idx[i] >= SEQ_LEVEL_4_0)
|
||||
aom_wb_write_bit(&wb, cm->seq_params.tier[i]);
|
||||
if (cm->seq_params.decoder_model_info_present_flag) {
|
||||
aom_wb_write_bit(&wb,
|
||||
|
|
@ -3436,7 +3437,7 @@ static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst,
|
|||
// For large_scale_tile case, we always have only one tile group, so it can
|
||||
// be written as an OBU_FRAME.
|
||||
const OBU_TYPE obu_type = OBU_FRAME;
|
||||
const uint32_t tg_hdr_size = write_obu_header(obu_type, 0, data);
|
||||
const uint32_t tg_hdr_size = av1_write_obu_header(cpi, obu_type, 0, data);
|
||||
data += tg_hdr_size;
|
||||
|
||||
const uint32_t frame_header_size =
|
||||
|
|
@ -3591,7 +3592,7 @@ static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst,
|
|||
const OBU_TYPE obu_type =
|
||||
(num_tg_hdrs == 1) ? OBU_FRAME : OBU_TILE_GROUP;
|
||||
curr_tg_data_size =
|
||||
write_obu_header(obu_type, obu_extension_header, data);
|
||||
av1_write_obu_header(cpi, obu_type, obu_extension_header, data);
|
||||
obu_header_size = curr_tg_data_size;
|
||||
|
||||
if (num_tg_hdrs == 1) {
|
||||
|
|
@ -3677,8 +3678,9 @@ static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst,
|
|||
|
||||
// Rewrite the OBU header to change the OBU type to Redundant Frame
|
||||
// Header.
|
||||
write_obu_header(OBU_REDUNDANT_FRAME_HEADER, obu_extension_header,
|
||||
&data[fh_info->obu_header_byte_offset]);
|
||||
av1_write_obu_header(cpi, OBU_REDUNDANT_FRAME_HEADER,
|
||||
obu_extension_header,
|
||||
&data[fh_info->obu_header_byte_offset]);
|
||||
|
||||
data += fh_info->total_length;
|
||||
|
||||
|
|
@ -3757,11 +3759,13 @@ int av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size,
|
|||
bitstream_queue_reset_write();
|
||||
#endif
|
||||
|
||||
cpi->frame_header_count = 0;
|
||||
|
||||
// The TD is now written outside the frame encode loop
|
||||
|
||||
// write sequence header obu if KEY_FRAME, preceded by 4-byte size
|
||||
if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
|
||||
obu_header_size = write_obu_header(OBU_SEQUENCE_HEADER, 0, data);
|
||||
obu_header_size = av1_write_obu_header(cpi, OBU_SEQUENCE_HEADER, 0, data);
|
||||
|
||||
obu_payload_size = write_sequence_header_obu(cpi, data + obu_header_size);
|
||||
const size_t length_field_size =
|
||||
|
|
@ -3781,7 +3785,7 @@ int av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size,
|
|||
// Write Frame Header OBU.
|
||||
fh_info.frame_header = data;
|
||||
obu_header_size =
|
||||
write_obu_header(OBU_FRAME_HEADER, obu_extension_header, data);
|
||||
av1_write_obu_header(cpi, OBU_FRAME_HEADER, obu_extension_header, data);
|
||||
obu_payload_size =
|
||||
write_frame_header_obu(cpi, &saved_wb, data + obu_header_size, 1);
|
||||
|
||||
|
|
|
|||
9
third_party/aom/av1/encoder/bitstream.h
vendored
9
third_party/aom/av1/encoder/bitstream.h
vendored
|
|
@ -27,8 +27,8 @@ uint32_t write_sequence_header_obu(AV1_COMP *cpi, uint8_t *const dst);
|
|||
|
||||
// Writes the OBU header byte, and the OBU header extension byte when
|
||||
// 'obu_extension' is non-zero. Returns number of bytes written to 'dst'.
|
||||
uint32_t write_obu_header(OBU_TYPE obu_type, int obu_extension,
|
||||
uint8_t *const dst);
|
||||
uint32_t av1_write_obu_header(AV1_COMP *const cpi, OBU_TYPE obu_type,
|
||||
int obu_extension, uint8_t *const dst);
|
||||
|
||||
int write_uleb_obu_size(uint32_t obu_header_size, uint32_t obu_payload_size,
|
||||
uint8_t *dest);
|
||||
|
|
@ -36,11 +36,6 @@ int write_uleb_obu_size(uint32_t obu_header_size, uint32_t obu_payload_size,
|
|||
int av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size,
|
||||
int *const largest_tile_id);
|
||||
|
||||
static INLINE int av1_preserve_existing_gf(const AV1_COMP *const cpi) {
|
||||
// Do not swap gf and arf indices for internal overlay frames
|
||||
return cpi->rc.is_src_frame_alt_ref && !cpi->rc.is_src_frame_ext_arf;
|
||||
}
|
||||
|
||||
void av1_write_tx_type(const AV1_COMMON *const cm, const MACROBLOCKD *xd,
|
||||
int blk_row, int blk_col, int plane, TX_SIZE tx_size,
|
||||
aom_writer *w);
|
||||
|
|
|
|||
27
third_party/aom/av1/encoder/block.h
vendored
27
third_party/aom/av1/encoder/block.h
vendored
|
|
@ -75,13 +75,10 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
// TODO(angiebird): Reduce the buffer size according to sb_type
|
||||
tran_low_t *tcoeff[MAX_MB_PLANE];
|
||||
uint16_t *eobs[MAX_MB_PLANE];
|
||||
uint8_t *txb_skip_ctx[MAX_MB_PLANE];
|
||||
int *dc_sign_ctx[MAX_MB_PLANE];
|
||||
CB_COEFF_BUFFER *cb_coef_buff;
|
||||
CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
|
||||
int_mv global_mvs[REF_FRAMES];
|
||||
int16_t compound_mode_context[MODE_CTX_REF_FRAMES];
|
||||
int cb_offset;
|
||||
int16_t mode_context[MODE_CTX_REF_FRAMES];
|
||||
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
|
||||
} MB_MODE_INFO_EXT;
|
||||
|
|
@ -156,7 +153,7 @@ typedef struct {
|
|||
|
||||
// Region size for mode decision sampling in the first pass of partition
|
||||
// search(two_pass_partition_search speed feature), in units of mi size(4).
|
||||
// Used by the mode_pruning_based_on_two_pass_partition_search speed feature.
|
||||
// Used by the mode pruning in two_pass_partition_search feature.
|
||||
#define FIRST_PARTITION_PASS_SAMPLE_REGION 8
|
||||
#define FIRST_PARTITION_PASS_SAMPLE_REGION_LOG2 3
|
||||
#define FIRST_PARTITION_PASS_STATS_TABLES \
|
||||
|
|
@ -177,6 +174,8 @@ typedef struct {
|
|||
uint8_t ref0_counts[REF_FRAMES]; // Counters for ref_frame[0].
|
||||
uint8_t ref1_counts[REF_FRAMES]; // Counters for ref_frame[1].
|
||||
int sample_counts; // Number of samples collected.
|
||||
uint8_t interintra_motion_mode_count[REF_FRAMES]; // Counter for interintra
|
||||
// motion mode
|
||||
} FIRST_PARTITION_PASS_STATS;
|
||||
|
||||
#define MAX_INTERP_FILTER_STATS 64
|
||||
|
|
@ -185,12 +184,17 @@ typedef struct {
|
|||
int_mv mv[2];
|
||||
int8_t ref_frames[2];
|
||||
COMPOUND_TYPE comp_type;
|
||||
int64_t rd;
|
||||
int skip_txfm_sb;
|
||||
int64_t skip_sse_sb;
|
||||
unsigned int pred_sse;
|
||||
} INTERPOLATION_FILTER_STATS;
|
||||
|
||||
#define MAX_COMP_RD_STATS 64
|
||||
typedef struct {
|
||||
int32_t rate[COMPOUND_TYPES];
|
||||
int64_t dist[COMPOUND_TYPES];
|
||||
int64_t comp_model_rd[COMPOUND_TYPES];
|
||||
int_mv mv[2];
|
||||
MV_REFERENCE_FRAME ref_frames[2];
|
||||
PREDICTION_MODE mode;
|
||||
|
|
@ -272,6 +276,7 @@ struct macroblock {
|
|||
|
||||
unsigned int max_mv_context[REF_FRAMES];
|
||||
unsigned int source_variance;
|
||||
unsigned int simple_motion_pred_sse;
|
||||
unsigned int pred_sse[REF_FRAMES];
|
||||
int pred_mv_sad[REF_FRAMES];
|
||||
|
||||
|
|
@ -351,7 +356,7 @@ struct macroblock {
|
|||
// BWDREF_FRAME) in bidir-comp mode.
|
||||
int comp_bwdref_cost[REF_CONTEXTS][BWD_REFS - 1][2];
|
||||
int inter_compound_mode_cost[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
|
||||
int compound_type_cost[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
|
||||
int compound_type_cost[BLOCK_SIZES_ALL][MASKED_COMPOUND_TYPES];
|
||||
int wedge_idx_cost[BLOCK_SIZES_ALL][16];
|
||||
int interintra_cost[BLOCK_SIZE_GROUPS][2];
|
||||
int wedge_interintra_cost[BLOCK_SIZES_ALL][2];
|
||||
|
|
@ -396,6 +401,11 @@ struct macroblock {
|
|||
// Store the fractional best motion vector during sub/Qpel-pixel motion search
|
||||
int_mv fractional_best_mv[3];
|
||||
|
||||
// Ref frames that are selected by square partition blocks within a super-
|
||||
// block, in MI resolution. They can be used to prune ref frames for
|
||||
// rectangular blocks.
|
||||
int picked_ref_frames_mask[32 * 32];
|
||||
|
||||
// use default transform and skip transform type search for intra modes
|
||||
int use_default_intra_tx_type;
|
||||
// use default transform and skip transform type search for inter modes
|
||||
|
|
@ -416,6 +426,9 @@ struct macroblock {
|
|||
// detection). For reference, 556 is the value returned for a solid
|
||||
// vertical black/white edge.
|
||||
uint16_t edge_strength;
|
||||
// The strongest edge strength seen along the x/y axis.
|
||||
uint16_t edge_strength_x;
|
||||
uint16_t edge_strength_y;
|
||||
|
||||
// [Saved stat index]
|
||||
COMP_RD_STATS comp_rd_stats[MAX_COMP_RD_STATS];
|
||||
|
|
|
|||
16
third_party/aom/av1/encoder/context_tree.h
vendored
16
third_party/aom/av1/encoder/context_tree.h
vendored
|
|
@ -58,8 +58,6 @@ typedef struct {
|
|||
int hybrid_pred_diff;
|
||||
int comp_pred_diff;
|
||||
int single_pred_diff;
|
||||
// Skip certain ref frames during RD search of rectangular partitions.
|
||||
int skip_ref_frame_mask;
|
||||
|
||||
// TODO(jingning) Use RD_COST struct here instead. This involves a boarder
|
||||
// scope of refactoring.
|
||||
|
|
@ -67,26 +65,12 @@ typedef struct {
|
|||
|
||||
int rd_mode_is_ready; // Flag to indicate whether rd pick mode decision has
|
||||
// been made.
|
||||
int mode_selected;
|
||||
#if CONFIG_ONE_PASS_SVM
|
||||
// Features for one pass svm early term
|
||||
int seg_feat;
|
||||
#endif
|
||||
|
||||
// motion vector cache for adaptive motion search control in partition
|
||||
// search loop
|
||||
MV pred_mv[REF_FRAMES];
|
||||
InterpFilter pred_interp_filter;
|
||||
PARTITION_TYPE partition;
|
||||
|
||||
// Reference and prediction mode cache for ref/mode speedup
|
||||
// TODO(zoeliu@gmail.com): The values of ref_selected and mode_selected will
|
||||
// be explored for further encoder speedup, to differentiate this approach for
|
||||
// setting skip_ref_frame_mask from others. For instance, it is possible that
|
||||
// the underlying square block(s) share the same SIMPLE_TRANSLATION motion
|
||||
// mode as well as the mode of GLOBALMV, more ref/mode combos could be
|
||||
// skipped.
|
||||
MV_REFERENCE_FRAME ref_selected[2];
|
||||
} PICK_MODE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
827
third_party/aom/av1/encoder/encode_strategy.c
vendored
827
third_party/aom/av1/encoder/encode_strategy.c
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -31,9 +31,13 @@ int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
|
|||
int64_t *const time_stamp, int64_t *const time_end,
|
||||
const aom_rational_t *const timebase, int flush);
|
||||
|
||||
// Set individual buffer update flags based on frame reference type
|
||||
// Set individual buffer update flags based on frame reference type.
|
||||
// force_refresh_all is used when we have a KEY_FRAME or S_FRAME. It forces all
|
||||
// refresh_*_frame flags to be set, because we refresh all buffers in this case.
|
||||
void av1_configure_buffer_updates(AV1_COMP *const cpi,
|
||||
const FRAME_UPDATE_TYPE type);
|
||||
EncodeFrameParams *const frame_params,
|
||||
const FRAME_UPDATE_TYPE type,
|
||||
int force_refresh_all);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
2397
third_party/aom/av1/encoder/encodeframe.c
vendored
2397
third_party/aom/av1/encoder/encodeframe.c
vendored
File diff suppressed because it is too large
Load diff
49
third_party/aom/av1/encoder/encodemb.c
vendored
49
third_party/aom/av1/encoder/encodemb.c
vendored
|
|
@ -111,9 +111,8 @@ int av1_optimize_b(const struct AV1_COMP *cpi, MACROBLOCK *mb, int plane,
|
|||
return eob;
|
||||
}
|
||||
|
||||
(void)fast_mode;
|
||||
return av1_optimize_txb_new(cpi, mb, plane, block, tx_size, tx_type, txb_ctx,
|
||||
rate_cost, cpi->oxcf.sharpness);
|
||||
rate_cost, cpi->oxcf.sharpness, fast_mode);
|
||||
}
|
||||
|
||||
enum {
|
||||
|
|
@ -185,7 +184,7 @@ void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
|
|||
av1_quantize_skip(n_coeffs, qcoeff, dqcoeff, eob);
|
||||
}
|
||||
}
|
||||
// NOTE: optimize_b_following is ture means av1_optimze_b will be called
|
||||
// NOTE: optimize_b_following is true means av1_optimze_b will be called
|
||||
// When the condition of doing optimize_b is changed,
|
||||
// this flag need update simultaneously
|
||||
const int optimize_b_following =
|
||||
|
|
@ -228,12 +227,16 @@ static void encode_block(int plane, int block, int blk_row, int blk_col,
|
|||
TX_TYPE tx_type = av1_get_tx_type(pd->plane_type, xd, blk_row, blk_col,
|
||||
tx_size, cm->reduced_tx_set_used);
|
||||
if (args->enable_optimize_b != NO_TRELLIS_OPT) {
|
||||
av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize,
|
||||
tx_size, tx_type, AV1_XFORM_QUANT_FP);
|
||||
av1_xform_quant(
|
||||
cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size, tx_type,
|
||||
USE_B_QUANT_NO_TRELLIS &&
|
||||
(args->enable_optimize_b == FINAL_PASS_TRELLIS_OPT)
|
||||
? AV1_XFORM_QUANT_B
|
||||
: AV1_XFORM_QUANT_FP);
|
||||
TXB_CTX txb_ctx;
|
||||
get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
|
||||
av1_optimize_b(args->cpi, x, plane, block, tx_size, tx_type, &txb_ctx, 1,
|
||||
&dummy_rate_cost);
|
||||
av1_optimize_b(args->cpi, x, plane, block, tx_size, tx_type, &txb_ctx,
|
||||
args->cpi->sf.trellis_eob_fast, &dummy_rate_cost);
|
||||
} else {
|
||||
av1_xform_quant(
|
||||
cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size, tx_type,
|
||||
|
|
@ -256,12 +259,12 @@ static void encode_block(int plane, int block, int blk_row, int blk_col,
|
|||
cm->reduced_tx_set_used);
|
||||
}
|
||||
|
||||
// TODO(debargha, jingning): Temporarily disable txk_type check for eob=0
|
||||
// case. It is possible that certain collision in hash index would cause
|
||||
// the assertion failure. To further optimize the rate-distortion
|
||||
// performance, we need to re-visit this part and enable this assert
|
||||
// again.
|
||||
if (p->eobs[block] == 0 && plane == 0) {
|
||||
// TODO(debargha, jingning): Temporarily disable txk_type check for eob=0
|
||||
// case. It is possible that certain collision in hash index would cause
|
||||
// the assertion failure. To further optimize the rate-distortion
|
||||
// performance, we need to re-visit this part and enable this assert
|
||||
// again.
|
||||
#if 0
|
||||
if (args->cpi->oxcf.aq_mode == NO_AQ &&
|
||||
args->cpi->oxcf.deltaq_mode == NO_DELTA_Q) {
|
||||
|
|
@ -580,12 +583,16 @@ void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
|
|||
const ENTROPY_CONTEXT *a = &args->ta[blk_col];
|
||||
const ENTROPY_CONTEXT *l = &args->tl[blk_row];
|
||||
if (args->enable_optimize_b != NO_TRELLIS_OPT) {
|
||||
av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize,
|
||||
tx_size, tx_type, AV1_XFORM_QUANT_FP);
|
||||
av1_xform_quant(
|
||||
cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size, tx_type,
|
||||
USE_B_QUANT_NO_TRELLIS &&
|
||||
(args->enable_optimize_b == FINAL_PASS_TRELLIS_OPT)
|
||||
? AV1_XFORM_QUANT_B
|
||||
: AV1_XFORM_QUANT_FP);
|
||||
TXB_CTX txb_ctx;
|
||||
get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
|
||||
av1_optimize_b(args->cpi, x, plane, block, tx_size, tx_type, &txb_ctx, 1,
|
||||
&dummy_rate_cost);
|
||||
av1_optimize_b(args->cpi, x, plane, block, tx_size, tx_type, &txb_ctx,
|
||||
args->cpi->sf.trellis_eob_fast, &dummy_rate_cost);
|
||||
} else {
|
||||
av1_xform_quant(
|
||||
cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size, tx_type,
|
||||
|
|
@ -598,12 +605,12 @@ void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
|
|||
dst_stride, *eob, cm->reduced_tx_set_used);
|
||||
}
|
||||
|
||||
// TODO(jingning): Temporarily disable txk_type check for eob=0 case.
|
||||
// It is possible that certain collision in hash index would cause
|
||||
// the assertion failure. To further optimize the rate-distortion
|
||||
// performance, we need to re-visit this part and enable this assert
|
||||
// again.
|
||||
if (*eob == 0 && plane == 0) {
|
||||
// TODO(jingning): Temporarily disable txk_type check for eob=0 case.
|
||||
// It is possible that certain collision in hash index would cause
|
||||
// the assertion failure. To further optimize the rate-distortion
|
||||
// performance, we need to re-visit this part and enable this assert
|
||||
// again.
|
||||
#if 0
|
||||
if (args->cpi->oxcf.aq_mode == NO_AQ
|
||||
&& args->cpi->oxcf.deltaq_mode == NO_DELTA_Q) {
|
||||
|
|
|
|||
1133
third_party/aom/av1/encoder/encoder.c
vendored
1133
third_party/aom/av1/encoder/encoder.c
vendored
File diff suppressed because it is too large
Load diff
321
third_party/aom/av1/encoder/encoder.h
vendored
321
third_party/aom/av1/encoder/encoder.h
vendored
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef AOM_AV1_ENCODER_ENCODER_H_
|
||||
#define AOM_AV1_ENCODER_ENCODER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config/aom_config.h"
|
||||
|
|
@ -24,11 +25,14 @@
|
|||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/common/resize.h"
|
||||
#include "av1/common/timing.h"
|
||||
#include "av1/common/blockd.h"
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/encoder/aq_cyclicrefresh.h"
|
||||
#include "av1/encoder/av1_quantize.h"
|
||||
#include "av1/encoder/context_tree.h"
|
||||
#include "av1/encoder/encodemb.h"
|
||||
#include "av1/encoder/firstpass.h"
|
||||
#include "av1/encoder/level.h"
|
||||
#include "av1/encoder/lookahead.h"
|
||||
#include "av1/encoder/mbgraph.h"
|
||||
#include "av1/encoder/mcomp.h"
|
||||
|
|
@ -36,6 +40,7 @@
|
|||
#include "av1/encoder/rd.h"
|
||||
#include "av1/encoder/speed_features.h"
|
||||
#include "av1/encoder/tokenize.h"
|
||||
#include "av1/encoder/block.h"
|
||||
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
#include "aom_dsp/ssim.h"
|
||||
|
|
@ -60,18 +65,12 @@ typedef struct {
|
|||
} CODING_CONTEXT;
|
||||
|
||||
enum {
|
||||
// regular inter frame
|
||||
REGULAR_FRAME = 0,
|
||||
// alternate reference frame
|
||||
ARF_FRAME = 1,
|
||||
// overlay frame
|
||||
OVERLAY_FRAME = 2,
|
||||
// golden frame
|
||||
GLD_FRAME = 3,
|
||||
// backward reference frame
|
||||
BRF_FRAME = 4,
|
||||
// extra alternate reference frame
|
||||
EXT_ARF_FRAME = 5,
|
||||
REGULAR_FRAME, // regular inter frame
|
||||
ARF_FRAME, // alternate reference frame
|
||||
OVERLAY_FRAME, // overlay frame
|
||||
GLD_FRAME, // golden frame
|
||||
BRF_FRAME, // backward reference frame
|
||||
INTERNAL_ARF_FRAME, // internal alternate reference frame
|
||||
FRAME_CONTEXT_INDEXES
|
||||
} UENUM1BYTE(FRAME_CONTEXT_INDEX);
|
||||
|
||||
|
|
@ -85,7 +84,10 @@ enum {
|
|||
enum {
|
||||
// Good Quality Fast Encoding. The encoder balances quality with the amount of
|
||||
// time it takes to encode the output. Speed setting controls how fast.
|
||||
GOOD
|
||||
GOOD,
|
||||
// Realtime Fast Encoding. Will force some restrictions on bitrate
|
||||
// constraints.
|
||||
REALTIME
|
||||
} UENUM1BYTE(MODE);
|
||||
|
||||
enum {
|
||||
|
|
@ -121,22 +123,38 @@ enum {
|
|||
} UENUM1BYTE(RESIZE_MODE);
|
||||
|
||||
enum {
|
||||
SUPERRES_NONE = 0, // No frame superres allowed
|
||||
SUPERRES_FIXED = 1, // All frames are coded at the specified scale,
|
||||
// and super-resolved.
|
||||
SUPERRES_RANDOM = 2, // All frames are coded at a random scale,
|
||||
// and super-resolved.
|
||||
SUPERRES_QTHRESH = 3, // Superres scale for a frame is determined based on
|
||||
// q_index
|
||||
SUPERRES_NONE, // No frame superres allowed.
|
||||
SUPERRES_FIXED, // All frames are coded at the specified scale,
|
||||
// and super-resolved.
|
||||
SUPERRES_RANDOM, // All frames are coded at a random scale,
|
||||
// and super-resolved.
|
||||
SUPERRES_QTHRESH, // Superres scale for a frame is determined based on
|
||||
// q_index.
|
||||
SUPERRES_AUTO, // Automatically select superres for appropriate frames.
|
||||
SUPERRES_MODES
|
||||
} UENUM1BYTE(SUPERRES_MODE);
|
||||
|
||||
typedef enum {
|
||||
kInvalid = 0,
|
||||
kLowSadLowSumdiff = 1,
|
||||
kLowSadHighSumdiff = 2,
|
||||
kHighSadLowSumdiff = 3,
|
||||
kHighSadHighSumdiff = 4,
|
||||
kLowVarHighSumdiff = 5,
|
||||
kVeryHighSad = 6,
|
||||
} CONTENT_STATE_SB;
|
||||
|
||||
enum {
|
||||
SS_CFG_SRC = 0,
|
||||
SS_CFG_LOOKAHEAD = 1,
|
||||
SS_CFG_TOTAL = 2
|
||||
} UENUM1BYTE(SS_CFG_OFFSET);
|
||||
|
||||
typedef struct TplDepStats {
|
||||
int64_t intra_cost;
|
||||
int64_t inter_cost;
|
||||
int64_t mc_flow;
|
||||
int64_t mc_dep_cost;
|
||||
int64_t mc_ref_cost;
|
||||
|
||||
int ref_frame_index;
|
||||
int_mv mv;
|
||||
|
|
@ -153,6 +171,12 @@ typedef struct TplDepFrame {
|
|||
int base_qindex;
|
||||
} TplDepFrame;
|
||||
|
||||
typedef enum {
|
||||
COST_UPD_SB,
|
||||
COST_UPD_SBROW,
|
||||
COST_UPD_TILE,
|
||||
} COST_UPDATE_TYPE;
|
||||
|
||||
#define TPL_DEP_COST_SCALE_LOG2 4
|
||||
|
||||
typedef struct AV1EncoderConfig {
|
||||
|
|
@ -291,10 +315,6 @@ typedef struct AV1EncoderConfig {
|
|||
|
||||
aom_fixed_buf_t two_pass_stats_in;
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
aom_fixed_buf_t firstpass_mb_stats_in;
|
||||
#endif
|
||||
|
||||
aom_tune_metric tuning;
|
||||
aom_tune_content content;
|
||||
int use_highbitdepth;
|
||||
|
|
@ -324,14 +344,22 @@ typedef struct AV1EncoderConfig {
|
|||
unsigned int motion_vector_unit_test;
|
||||
const cfg_options_t *cfg;
|
||||
int enable_rect_partitions;
|
||||
int enable_ab_partitions;
|
||||
int enable_1to4_partitions;
|
||||
int min_partition_size;
|
||||
int max_partition_size;
|
||||
int enable_intra_edge_filter;
|
||||
int enable_tx64;
|
||||
int tx_size_search_method;
|
||||
int enable_flip_idtx;
|
||||
int enable_order_hint;
|
||||
int enable_dist_wtd_comp;
|
||||
int enable_ref_frame_mvs;
|
||||
unsigned int max_reference_frames;
|
||||
int enable_reduced_reference_set;
|
||||
unsigned int allow_ref_frame_mvs;
|
||||
int enable_masked_comp;
|
||||
int enable_onesided_comp;
|
||||
int enable_interintra_comp;
|
||||
int enable_smooth_interintra;
|
||||
int enable_diff_wtd_comp;
|
||||
|
|
@ -360,8 +388,15 @@ typedef struct AV1EncoderConfig {
|
|||
int reduced_tx_type_set;
|
||||
int use_intra_dct_only;
|
||||
int use_inter_dct_only;
|
||||
int use_intra_default_tx_only;
|
||||
int quant_b_adapt;
|
||||
COST_UPDATE_TYPE coeff_cost_upd_freq;
|
||||
COST_UPDATE_TYPE mode_cost_upd_freq;
|
||||
int border_in_pixels;
|
||||
AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
|
||||
// Bit mask to specify which tier each of the 32 possible operating points
|
||||
// conforms to.
|
||||
unsigned int tier_mask;
|
||||
} AV1EncoderConfig;
|
||||
|
||||
static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {
|
||||
|
|
@ -418,7 +453,7 @@ typedef struct FRAME_COUNTS {
|
|||
unsigned int interintra[BLOCK_SIZE_GROUPS][2];
|
||||
unsigned int interintra_mode[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
|
||||
unsigned int wedge_interintra[BLOCK_SIZES_ALL][2];
|
||||
unsigned int compound_type[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
|
||||
unsigned int compound_type[BLOCK_SIZES_ALL][MASKED_COMPOUND_TYPES];
|
||||
unsigned int motion_mode[BLOCK_SIZES_ALL][MOTION_MODES];
|
||||
unsigned int obmc[BLOCK_SIZES_ALL][2];
|
||||
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
|
||||
|
|
@ -487,6 +522,11 @@ typedef struct inter_modes_info {
|
|||
int64_t sse_arr[MAX_INTER_MODES];
|
||||
int64_t est_rd_arr[MAX_INTER_MODES];
|
||||
RdIdxPair rd_idx_pair_arr[MAX_INTER_MODES];
|
||||
bool true_rd_arr[MAX_INTER_MODES];
|
||||
uint8_t blk_skip_arr[MAX_INTER_MODES][MAX_MIB_SIZE * MAX_MIB_SIZE];
|
||||
RD_STATS rd_cost_arr[MAX_INTER_MODES];
|
||||
RD_STATS rd_cost_y_arr[MAX_INTER_MODES];
|
||||
RD_STATS rd_cost_uv_arr[MAX_INTER_MODES];
|
||||
} InterModesInfo;
|
||||
|
||||
// Encoder row synchronization
|
||||
|
|
@ -593,15 +633,84 @@ typedef struct {
|
|||
YV12_BUFFER_CONFIG buf;
|
||||
} EncRefCntBuffer;
|
||||
|
||||
#if CONFIG_COLLECT_PARTITION_STATS
|
||||
#if CONFIG_COLLECT_PARTITION_STATS == 2
|
||||
typedef struct PartitionStats {
|
||||
int partition_decisions[6][EXT_PARTITION_TYPES];
|
||||
int partition_attempts[6][EXT_PARTITION_TYPES];
|
||||
int64_t partition_times[6][EXT_PARTITION_TYPES];
|
||||
|
||||
int partition_redo;
|
||||
} PartitionStats;
|
||||
#endif
|
||||
|
||||
#if CONFIG_COLLECT_COMPONENT_TIMING
|
||||
#include "aom_ports/aom_timer.h"
|
||||
// Adjust the following to add new components.
|
||||
enum {
|
||||
encode_frame_to_data_rate_time,
|
||||
encode_with_recode_loop_time,
|
||||
loop_filter_time,
|
||||
cdef_time,
|
||||
loop_restoration_time,
|
||||
av1_pack_bitstream_final_time,
|
||||
av1_encode_frame_time,
|
||||
av1_compute_global_motion_time,
|
||||
av1_setup_motion_field_time,
|
||||
encode_sb_time,
|
||||
first_partition_search_pass_time,
|
||||
rd_pick_partition_time,
|
||||
rd_pick_sb_modes_time,
|
||||
av1_rd_pick_intra_mode_sb_time,
|
||||
av1_rd_pick_inter_mode_sb_time,
|
||||
handle_intra_mode_time,
|
||||
handle_inter_mode_time,
|
||||
do_tx_search_time,
|
||||
handle_newmv_time,
|
||||
compound_type_rd_time,
|
||||
interpolation_filter_search_time,
|
||||
motion_mode_rd_time,
|
||||
kTimingComponents,
|
||||
} UENUM1BYTE(TIMING_COMPONENT);
|
||||
|
||||
static INLINE char const *get_component_name(int index) {
|
||||
switch (index) {
|
||||
case encode_frame_to_data_rate_time:
|
||||
return "encode_frame_to_data_rate_time";
|
||||
case encode_with_recode_loop_time: return "encode_with_recode_loop_time";
|
||||
case loop_filter_time: return "loop_filter_time";
|
||||
case cdef_time: return "cdef_time";
|
||||
case loop_restoration_time: return "loop_restoration_time";
|
||||
case av1_pack_bitstream_final_time: return "av1_pack_bitstream_final_time";
|
||||
case av1_encode_frame_time: return "av1_encode_frame_time";
|
||||
case av1_compute_global_motion_time:
|
||||
return "av1_compute_global_motion_time";
|
||||
case av1_setup_motion_field_time: return "av1_setup_motion_field_time";
|
||||
case encode_sb_time: return "encode_sb_time";
|
||||
case first_partition_search_pass_time:
|
||||
return "first_partition_search_pass_time";
|
||||
case rd_pick_partition_time: return "rd_pick_partition_time";
|
||||
case rd_pick_sb_modes_time: return "rd_pick_sb_modes_time";
|
||||
case av1_rd_pick_intra_mode_sb_time:
|
||||
return "av1_rd_pick_intra_mode_sb_time";
|
||||
case av1_rd_pick_inter_mode_sb_time:
|
||||
return "av1_rd_pick_inter_mode_sb_time";
|
||||
case handle_intra_mode_time: return "handle_intra_mode_time";
|
||||
case handle_inter_mode_time: return "handle_inter_mode_time";
|
||||
case do_tx_search_time: return "do_tx_search_time";
|
||||
case handle_newmv_time: return "handle_newmv_time";
|
||||
case compound_type_rd_time: return "compound_type_rd_time";
|
||||
case interpolation_filter_search_time:
|
||||
return "interpolation_filter_search_time";
|
||||
case motion_mode_rd_time: return "motion_mode_rd_time";
|
||||
default: assert(0);
|
||||
}
|
||||
return "error";
|
||||
}
|
||||
#endif
|
||||
|
||||
// The maximum number of internal ARFs except ALTREF_FRAME
|
||||
#define MAX_INTERNAL_ARFS (REF_FRAMES - BWDREF_FRAME - 1)
|
||||
|
||||
typedef struct AV1_COMP {
|
||||
QUANTS quants;
|
||||
ThreadData td;
|
||||
|
|
@ -615,7 +724,6 @@ typedef struct AV1_COMP {
|
|||
struct lookahead_entry *alt_ref_source;
|
||||
int no_show_kf;
|
||||
|
||||
int optimize_speed_feature;
|
||||
int optimize_seg_arr[MAX_SEGMENTS];
|
||||
|
||||
YV12_BUFFER_CONFIG *source;
|
||||
|
|
@ -630,6 +738,9 @@ typedef struct AV1_COMP {
|
|||
|
||||
// For a still frame, this flag is set to 1 to skip partition search.
|
||||
int partition_search_skippable_frame;
|
||||
// The following item corresponds to two_pass_partition_search speed features.
|
||||
int two_pass_partition_search;
|
||||
|
||||
double csm_rate_array[32];
|
||||
double m_rate_array[32];
|
||||
int rate_size;
|
||||
|
|
@ -665,13 +776,6 @@ typedef struct AV1_COMP {
|
|||
// frame of the same type as the current frame).
|
||||
int fb_of_context_type[REF_FRAMES];
|
||||
|
||||
// When true, a new rule for backward (future) reference frames is in effect:
|
||||
// - BWDREF_FRAME is always the closest future frame available
|
||||
// - ALTREF2_FRAME is always the 2nd closest future frame available
|
||||
// - 'refresh_bwd_ref_frame' flag is used for updating both the BWDREF_FRAME
|
||||
// and ALTREF2_FRAME. ('refresh_alt2_ref_frame' flag is irrelevant).
|
||||
int new_bwdref_update_rule;
|
||||
|
||||
int ext_refresh_frame_flags_pending;
|
||||
int ext_refresh_last_frame;
|
||||
int ext_refresh_golden_frame;
|
||||
|
|
@ -709,12 +813,6 @@ typedef struct AV1_COMP {
|
|||
RATE_CONTROL rc;
|
||||
double framerate;
|
||||
|
||||
// Relevant for an inter frame.
|
||||
// - Index '0' corresponds to the values for the currently coded frame.
|
||||
// - Indices LAST_FRAME ... EXTREF_FRAMES are used to store values for all the
|
||||
// possible inter reference frames.
|
||||
int interp_filter_selected[REF_FRAMES + 1][SWITCHABLE];
|
||||
|
||||
struct aom_codec_pkt_list *output_pkt_list;
|
||||
|
||||
MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS];
|
||||
|
|
@ -741,12 +839,10 @@ typedef struct AV1_COMP {
|
|||
fractional_mv_step_fp *find_fractional_mv_step;
|
||||
av1_diamond_search_fn_t diamond_search_sad;
|
||||
aom_variance_fn_ptr_t fn_ptr[BLOCK_SIZES_ALL];
|
||||
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
uint64_t time_receive_data;
|
||||
uint64_t time_compress_data;
|
||||
uint64_t time_pick_lpf;
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
int use_fp_mb_stats;
|
||||
#endif
|
||||
|
||||
TWO_PASS twopass;
|
||||
|
|
@ -802,9 +898,11 @@ typedef struct AV1_COMP {
|
|||
int resize_pending_width;
|
||||
int resize_pending_height;
|
||||
|
||||
int frame_flags;
|
||||
|
||||
search_site_config ss_cfg;
|
||||
// ss_cfg[SS_CFG_LOOKAHEAD] : used in following cases
|
||||
// -> temporal filtering
|
||||
// -> intrabc
|
||||
// ss_cfg[SS_CFG_SRC] : used everywhere except above mentioned cases
|
||||
search_site_config ss_cfg[SS_CFG_TOTAL];
|
||||
|
||||
TileDataEnc *tile_data;
|
||||
int allocated_tiles; // Keep track of memory allocated for tiles.
|
||||
|
|
@ -824,17 +922,24 @@ typedef struct AV1_COMP {
|
|||
// VARIANCE_AQ segment map refresh
|
||||
int vaq_refresh;
|
||||
|
||||
// VAR_BASED_PARTITION thresholds
|
||||
// 0 - threshold_128x128; 1 - threshold_64x64;
|
||||
// 2 - threshold_32x32; 3 - threshold_16x16;
|
||||
// 4 - vbp_threshold_8x8;
|
||||
int64_t vbp_thresholds[5];
|
||||
int64_t vbp_threshold_minmax;
|
||||
int64_t vbp_threshold_sad;
|
||||
int64_t vbp_threshold_copy;
|
||||
BLOCK_SIZE vbp_bsize_min;
|
||||
|
||||
// Multi-threading
|
||||
int num_workers;
|
||||
AVxWorker *workers;
|
||||
struct EncWorkerData *tile_thr_data;
|
||||
int existing_fb_idx_to_show;
|
||||
int is_arf_filter_off[MAX_EXT_ARFS + 1];
|
||||
int num_extra_arfs;
|
||||
int arf_pos_in_gf[MAX_EXT_ARFS + 1];
|
||||
int arf_pos_for_ovrly[MAX_EXT_ARFS + 1];
|
||||
int is_arf_filter_off[MAX_INTERNAL_ARFS + 1];
|
||||
int global_motion_search_done;
|
||||
int extra_arf_allowed;
|
||||
int internal_altref_allowed;
|
||||
// A flag to indicate if intrabc is ever used in current frame.
|
||||
int intrabc_used;
|
||||
int dv_cost[2][MV_VALS];
|
||||
|
|
@ -873,9 +978,25 @@ typedef struct AV1_COMP {
|
|||
#endif
|
||||
// Set if screen content is set or relevant tools are enabled
|
||||
int is_screen_content_type;
|
||||
#if CONFIG_COLLECT_PARTITION_STATS
|
||||
#if CONFIG_COLLECT_PARTITION_STATS == 2
|
||||
PartitionStats partition_stats;
|
||||
#endif
|
||||
|
||||
#if CONFIG_COLLECT_COMPONENT_TIMING
|
||||
// component_time[] are initialized to zero while encoder starts.
|
||||
uint64_t component_time[kTimingComponents];
|
||||
struct aom_usec_timer component_timer[kTimingComponents];
|
||||
// frame_component_time[] are initialized to zero at beginning of each frame.
|
||||
uint64_t frame_component_time[kTimingComponents];
|
||||
#endif
|
||||
|
||||
// The following data are for AV1 bitstream levels.
|
||||
AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
|
||||
int keep_level_stats;
|
||||
AV1LevelInfo level_info[MAX_NUM_OPERATING_POINTS];
|
||||
// Count the number of OBU_FRAME and OBU_FRAME_HEADER for level calculation.
|
||||
int frame_header_count;
|
||||
FrameWindowBuffer frame_window_buffer;
|
||||
} AV1_COMP;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -892,14 +1013,26 @@ struct EncodeFrameParams {
|
|||
int primary_ref_frame;
|
||||
int order_offset;
|
||||
int show_frame;
|
||||
int refresh_frame_flags;
|
||||
|
||||
// This is a bitmask of which reference slots can be used in this frame
|
||||
int show_existing_frame;
|
||||
int existing_fb_idx_to_show;
|
||||
|
||||
// Bitmask of which reference buffers may be referenced by this frame
|
||||
int ref_frame_flags;
|
||||
|
||||
// Reference buffer assignment for this frame.
|
||||
int remapped_ref_idx[REF_FRAMES];
|
||||
|
||||
// Flags which determine which reference buffers are refreshed by this frame
|
||||
int refresh_last_frame;
|
||||
int refresh_golden_frame;
|
||||
int refresh_bwd_ref_frame;
|
||||
int refresh_alt2_ref_frame;
|
||||
int refresh_alt_ref_frame;
|
||||
|
||||
// Speed level to use for this frame: Bigger number means faster.
|
||||
int speed;
|
||||
|
||||
unsigned int *frame_flags;
|
||||
};
|
||||
typedef struct EncodeFrameParams EncodeFrameParams;
|
||||
|
||||
|
|
@ -1112,6 +1245,48 @@ static INLINE int encode_show_existing_frame(const AV1_COMMON *cm) {
|
|||
cm->current_frame.frame_type == KEY_FRAME);
|
||||
}
|
||||
|
||||
// Lighter version of set_offsets that only sets the mode info
|
||||
// pointers.
|
||||
static INLINE void set_mode_info_offsets(const AV1_COMP *const cpi,
|
||||
MACROBLOCK *const x,
|
||||
MACROBLOCKD *const xd, int mi_row,
|
||||
int mi_col) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int idx_str = xd->mi_stride * mi_row + mi_col;
|
||||
xd->mi = cm->mi_grid_visible + idx_str;
|
||||
xd->mi[0] = cm->mi + idx_str;
|
||||
x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
|
||||
}
|
||||
|
||||
// Check to see if the given partition size is allowed for a specified number
|
||||
// of mi block rows and columns remaining in the image.
|
||||
// If not then return the largest allowed partition size
|
||||
static INLINE BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
|
||||
int cols_left, int *bh, int *bw) {
|
||||
int int_size = (int)bsize;
|
||||
if (rows_left <= 0 || cols_left <= 0) {
|
||||
return AOMMIN(bsize, BLOCK_8X8);
|
||||
} else {
|
||||
for (; int_size > 0; int_size -= 3) {
|
||||
*bh = mi_size_high[int_size];
|
||||
*bw = mi_size_wide[int_size];
|
||||
if ((*bh <= rows_left) && (*bw <= cols_left)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (BLOCK_SIZE)int_size;
|
||||
}
|
||||
|
||||
static const uint8_t av1_ref_frame_flag_list[REF_FRAMES] = { 0,
|
||||
AOM_LAST_FLAG,
|
||||
AOM_LAST2_FLAG,
|
||||
AOM_LAST3_FLAG,
|
||||
AOM_GOLD_FLAG,
|
||||
AOM_BWD_FLAG,
|
||||
AOM_ALT2_FLAG,
|
||||
AOM_ALT_FLAG };
|
||||
|
||||
// Returns a Sequence Header OBU stored in an aom_fixed_buf_t, or NULL upon
|
||||
// failure. When a non-NULL aom_fixed_buf_t pointer is returned by this
|
||||
// function, the memory must be freed by the caller. Both the buf member of the
|
||||
|
|
@ -1123,7 +1298,7 @@ static INLINE int encode_show_existing_frame(const AV1_COMMON *cm) {
|
|||
// field.
|
||||
aom_fixed_buf_t *av1_get_global_headers(AV1_COMP *cpi);
|
||||
|
||||
#if CONFIG_COLLECT_PARTITION_STATS
|
||||
#if CONFIG_COLLECT_PARTITION_STATS == 2
|
||||
static INLINE void av1_print_partition_stats(PartitionStats *part_stats) {
|
||||
FILE *f = fopen("partition_stats.csv", "w");
|
||||
if (!f) {
|
||||
|
|
@ -1137,6 +1312,9 @@ static INLINE void av1_print_partition_stats(PartitionStats *part_stats) {
|
|||
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
|
||||
fprintf(f, "attempt_%d,", part);
|
||||
}
|
||||
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
|
||||
fprintf(f, "time_%d,", part);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
|
||||
const int bsizes[6] = { 128, 64, 32, 16, 8, 4 };
|
||||
|
|
@ -1149,6 +1327,9 @@ static INLINE void av1_print_partition_stats(PartitionStats *part_stats) {
|
|||
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
|
||||
fprintf(f, "%d,", part_stats->partition_attempts[bsize_idx][part]);
|
||||
}
|
||||
for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
|
||||
fprintf(f, "%ld,", part_stats->partition_times[bsize_idx][part]);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fclose(f);
|
||||
|
|
@ -1156,7 +1337,8 @@ static INLINE void av1_print_partition_stats(PartitionStats *part_stats) {
|
|||
|
||||
static INLINE int av1_get_bsize_idx_for_part_stats(BLOCK_SIZE bsize) {
|
||||
assert(bsize == BLOCK_128X128 || bsize == BLOCK_64X64 ||
|
||||
bsize == BLOCK_32X32 || bsize == BLOCK_16X16 || bsize == BLOCK_8X8);
|
||||
bsize == BLOCK_32X32 || bsize == BLOCK_16X16 || bsize == BLOCK_8X8 ||
|
||||
bsize == BLOCK_4X4);
|
||||
switch (bsize) {
|
||||
case BLOCK_128X128: return 0;
|
||||
case BLOCK_64X64: return 1;
|
||||
|
|
@ -1169,6 +1351,27 @@ static INLINE int av1_get_bsize_idx_for_part_stats(BLOCK_SIZE bsize) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_COLLECT_COMPONENT_TIMING
|
||||
static INLINE void start_timing(AV1_COMP *cpi, int component) {
|
||||
aom_usec_timer_start(&cpi->component_timer[component]);
|
||||
}
|
||||
static INLINE void end_timing(AV1_COMP *cpi, int component) {
|
||||
aom_usec_timer_mark(&cpi->component_timer[component]);
|
||||
cpi->frame_component_time[component] +=
|
||||
aom_usec_timer_elapsed(&cpi->component_timer[component]);
|
||||
}
|
||||
static INLINE char const *get_frame_type_enum(int type) {
|
||||
switch (type) {
|
||||
case 0: return "KEY_FRAME";
|
||||
case 1: return "INTER_FRAME";
|
||||
case 2: return "INTRA_ONLY_FRAME";
|
||||
case 3: return "S_FRAME";
|
||||
default: assert(0);
|
||||
}
|
||||
return "error";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
124
third_party/aom/av1/encoder/encodetxb.c
vendored
124
third_party/aom/av1/encoder/encodetxb.c
vendored
|
|
@ -76,21 +76,12 @@ void av1_free_txb_buf(AV1_COMP *cpi) { aom_free(cpi->coeff_buffer_base); }
|
|||
void av1_set_coeff_buffer(const AV1_COMP *const cpi, MACROBLOCK *const x,
|
||||
int mi_row, int mi_col) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
int mib_size_log2 = cm->seq_params.mib_size_log2;
|
||||
int stride = (cm->mi_cols >> mib_size_log2) + 1;
|
||||
int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
|
||||
CB_COEFF_BUFFER *coeff_buf = &cpi->coeff_buffer_base[offset];
|
||||
const int txb_offset = x->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
|
||||
x->mbmi_ext->cb_coef_buff = &cpi->coeff_buffer_base[offset];
|
||||
x->mbmi_ext->cb_offset = x->cb_offset;
|
||||
assert(x->cb_offset < (1 << num_pels_log2_lookup[cm->seq_params.sb_size]));
|
||||
for (int plane = 0; plane < num_planes; ++plane) {
|
||||
x->mbmi_ext->tcoeff[plane] = coeff_buf->tcoeff[plane] + x->cb_offset;
|
||||
x->mbmi_ext->eobs[plane] = coeff_buf->eobs[plane] + txb_offset;
|
||||
x->mbmi_ext->txb_skip_ctx[plane] =
|
||||
coeff_buf->txb_skip_ctx[plane] + txb_offset;
|
||||
x->mbmi_ext->dc_sign_ctx[plane] =
|
||||
coeff_buf->dc_sign_ctx[plane] + txb_offset;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_golomb(aom_writer *w, int level) {
|
||||
|
|
@ -647,10 +638,18 @@ static void write_coeffs_txb_wrap(const AV1_COMMON *cm, MACROBLOCK *x,
|
|||
aom_writer *w, int plane, int block,
|
||||
int blk_row, int blk_col, TX_SIZE tx_size) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
|
||||
uint16_t eob = x->mbmi_ext->eobs[plane][block];
|
||||
TXB_CTX txb_ctx = { x->mbmi_ext->txb_skip_ctx[plane][block],
|
||||
x->mbmi_ext->dc_sign_ctx[plane][block] };
|
||||
const int txb_offset =
|
||||
x->mbmi_ext->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
|
||||
tran_low_t *tcoeff_txb =
|
||||
x->mbmi_ext->cb_coef_buff->tcoeff[plane] + x->mbmi_ext->cb_offset;
|
||||
uint16_t *eob_txb = x->mbmi_ext->cb_coef_buff->eobs[plane] + txb_offset;
|
||||
uint8_t *txb_skip_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->txb_skip_ctx[plane] + txb_offset;
|
||||
int *dc_sign_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->dc_sign_ctx[plane] + txb_offset;
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(tcoeff_txb, block);
|
||||
uint16_t eob = eob_txb[block];
|
||||
TXB_CTX txb_ctx = { txb_skip_ctx_txb[block], dc_sign_ctx_txb[block] };
|
||||
av1_write_coeffs_txb(cm, xd, w, blk_row, blk_col, plane, tx_size, tcoeff, eob,
|
||||
&txb_ctx);
|
||||
}
|
||||
|
|
@ -1489,6 +1488,36 @@ static AOM_FORCE_INLINE void update_coeff_simple(
|
|||
}
|
||||
}
|
||||
|
||||
static INLINE void update_coeff_eob_fast(int *eob, int shift,
|
||||
const int16_t *dequant_ptr,
|
||||
const int16_t *scan,
|
||||
const tran_low_t *coeff_ptr,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr) {
|
||||
// TODO(sarahparker) make this work for aomqm
|
||||
int eob_out = *eob;
|
||||
int zbin[2] = { dequant_ptr[0] + ROUND_POWER_OF_TWO(dequant_ptr[0] * 70, 7),
|
||||
dequant_ptr[1] + ROUND_POWER_OF_TWO(dequant_ptr[1] * 70, 7) };
|
||||
|
||||
for (int i = *eob - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const int qcoeff = qcoeff_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
|
||||
if (((abs_coeff << (1 + shift)) < zbin[rc != 0]) || (qcoeff == 0)) {
|
||||
eob_out--;
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*eob = eob_out;
|
||||
}
|
||||
|
||||
static AOM_FORCE_INLINE void update_coeff_eob(
|
||||
int *accu_rate, int64_t *accu_dist, int *eob, int *nz_num, int *nz_ci,
|
||||
int si, TX_SIZE tx_size, TX_CLASS tx_class, int bwl, int height,
|
||||
|
|
@ -1624,35 +1653,44 @@ static INLINE void update_skip(int *accu_rate, int64_t accu_dist, int *eob,
|
|||
int av1_optimize_txb_new(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
||||
int block, TX_SIZE tx_size, TX_TYPE tx_type,
|
||||
const TXB_CTX *const txb_ctx, int *rate_cost,
|
||||
int sharpness) {
|
||||
const AV1_COMMON *cm = &cpi->common;
|
||||
int sharpness, int fast_mode) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
const struct macroblock_plane *p = &x->plane[plane];
|
||||
const SCAN_ORDER *scan_order = get_scan(tx_size, tx_type);
|
||||
const int16_t *scan = scan_order->scan;
|
||||
const int shift = av1_get_tx_scale(tx_size);
|
||||
int eob = p->eobs[block];
|
||||
const int16_t *dequant = p->dequant_QTX;
|
||||
tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
|
||||
const tran_low_t *tcoeff = BLOCK_OFFSET(p->coeff, block);
|
||||
|
||||
if (fast_mode) {
|
||||
update_coeff_eob_fast(&eob, shift, dequant, scan, tcoeff, qcoeff, dqcoeff);
|
||||
p->eobs[block] = eob;
|
||||
if (eob == 0) {
|
||||
*rate_cost = av1_cost_skip_txb(x, txb_ctx, plane, tx_size);
|
||||
return eob;
|
||||
}
|
||||
}
|
||||
|
||||
const AV1_COMMON *cm = &cpi->common;
|
||||
const PLANE_TYPE plane_type = get_plane_type(plane);
|
||||
const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
|
||||
const TX_CLASS tx_class = tx_type_to_class[tx_type];
|
||||
const MB_MODE_INFO *mbmi = xd->mi[0];
|
||||
const struct macroblock_plane *p = &x->plane[plane];
|
||||
struct macroblockd_plane *pd = &xd->plane[plane];
|
||||
tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
|
||||
const tran_low_t *tcoeff = BLOCK_OFFSET(p->coeff, block);
|
||||
const int16_t *dequant = p->dequant_QTX;
|
||||
const int bwl = get_txb_bwl(tx_size);
|
||||
const int width = get_txb_wide(tx_size);
|
||||
const int height = get_txb_high(tx_size);
|
||||
assert(width == (1 << bwl));
|
||||
const int is_inter = is_inter_block(mbmi);
|
||||
const SCAN_ORDER *scan_order = get_scan(tx_size, tx_type);
|
||||
const int16_t *scan = scan_order->scan;
|
||||
const LV_MAP_COEFF_COST *txb_costs = &x->coeff_costs[txs_ctx][plane_type];
|
||||
const int eob_multi_size = txsize_log2_minus4[tx_size];
|
||||
const LV_MAP_EOB_COST *txb_eob_costs =
|
||||
&x->eob_costs[eob_multi_size][plane_type];
|
||||
|
||||
const int shift = av1_get_tx_scale(tx_size);
|
||||
const int64_t rdmult =
|
||||
((x->rdmult * plane_rd_mult[is_inter][plane_type] << (2 * (xd->bd - 8))) +
|
||||
2) >>
|
||||
const int rshift =
|
||||
(sharpness +
|
||||
(cpi->oxcf.aq_mode == VARIANCE_AQ && mbmi->segment_id < 4
|
||||
? 7 - mbmi->segment_id
|
||||
|
|
@ -1661,10 +1699,14 @@ int av1_optimize_txb_new(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
|||
cpi->oxcf.deltaq_mode > NO_DELTA_Q && x->sb_energy_level < 0
|
||||
? (3 - x->sb_energy_level)
|
||||
: 0));
|
||||
const int64_t rdmult =
|
||||
(((int64_t)x->rdmult *
|
||||
(plane_rd_mult[is_inter][plane_type] << (2 * (xd->bd - 8)))) +
|
||||
2) >>
|
||||
rshift;
|
||||
|
||||
uint8_t levels_buf[TX_PAD_2D];
|
||||
uint8_t *const levels = set_levels(levels_buf, width);
|
||||
int eob = p->eobs[block];
|
||||
|
||||
if (eob > 1) av1_txb_init_levels(qcoeff, width, height, levels);
|
||||
|
||||
|
|
@ -1705,7 +1747,7 @@ int av1_optimize_txb_new(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
|||
|
||||
#define UPDATE_COEFF_EOB_CASE(tx_class_literal) \
|
||||
case tx_class_literal: \
|
||||
for (; si >= 0 && nz_num <= max_nz_num; --si) { \
|
||||
for (; si >= 0 && nz_num <= max_nz_num && !fast_mode; --si) { \
|
||||
update_coeff_eob(&accu_rate, &accu_dist, &eob, &nz_num, nz_ci, si, \
|
||||
tx_size, tx_class_literal, bwl, height, \
|
||||
txb_ctx->dc_sign_ctx, rdmult, shift, dequant, scan, \
|
||||
|
|
@ -1798,7 +1840,8 @@ int av1_optimize_txb(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
|||
|
||||
const int shift = av1_get_tx_scale(tx_size);
|
||||
const int64_t rdmult =
|
||||
((x->rdmult * plane_rd_mult[is_inter][plane_type] << (2 * (xd->bd - 8))) +
|
||||
(((int64_t)x->rdmult * plane_rd_mult[is_inter][plane_type]
|
||||
<< (2 * (xd->bd - 8))) +
|
||||
2) >>
|
||||
2;
|
||||
uint8_t levels_buf[TX_PAD_2D];
|
||||
|
|
@ -1965,15 +2008,22 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row,
|
|||
2);
|
||||
}
|
||||
|
||||
x->mbmi_ext->txb_skip_ctx[plane][block] = txb_ctx.txb_skip_ctx;
|
||||
x->mbmi_ext->eobs[plane][block] = eob;
|
||||
const int txb_offset =
|
||||
x->mbmi_ext->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
|
||||
uint16_t *eob_txb = x->mbmi_ext->cb_coef_buff->eobs[plane] + txb_offset;
|
||||
uint8_t *txb_skip_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->txb_skip_ctx[plane] + txb_offset;
|
||||
txb_skip_ctx_txb[block] = txb_ctx.txb_skip_ctx;
|
||||
eob_txb[block] = eob;
|
||||
|
||||
if (eob == 0) {
|
||||
av1_set_contexts(xd, pd, plane, plane_bsize, tx_size, 0, blk_col, blk_row);
|
||||
return;
|
||||
}
|
||||
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
|
||||
tran_low_t *tcoeff_txb =
|
||||
x->mbmi_ext->cb_coef_buff->tcoeff[plane] + x->mbmi_ext->cb_offset;
|
||||
tran_low_t *tcoeff = BLOCK_OFFSET(tcoeff_txb, block);
|
||||
const int segment_id = mbmi->segment_id;
|
||||
const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
|
||||
const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
|
||||
|
|
@ -2066,7 +2116,9 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row,
|
|||
#endif // CONFIG_ENTROPY_STATS
|
||||
if (allow_update_cdf)
|
||||
update_cdf(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], dc_sign, 2);
|
||||
x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx;
|
||||
int *dc_sign_ctx_txb =
|
||||
x->mbmi_ext->cb_coef_buff->dc_sign_ctx[plane] + txb_offset;
|
||||
dc_sign_ctx_txb[block] = dc_sign_ctx;
|
||||
}
|
||||
|
||||
const int cul_level = av1_get_txb_entropy_context(tcoeff, scan_order, eob);
|
||||
|
|
|
|||
2
third_party/aom/av1/encoder/encodetxb.h
vendored
2
third_party/aom/av1/encoder/encodetxb.h
vendored
|
|
@ -78,7 +78,7 @@ void hbt_destroy();
|
|||
int av1_optimize_txb_new(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
|
||||
int block, TX_SIZE tx_size, TX_TYPE tx_type,
|
||||
const TXB_CTX *const txb_ctx, int *rate_cost,
|
||||
int sharpness);
|
||||
int sharpness, int fast_mode);
|
||||
|
||||
// These numbers are empirically obtained.
|
||||
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
|
||||
|
|
|
|||
60
third_party/aom/av1/encoder/ethread.c
vendored
60
third_party/aom/av1/encoder/ethread.c
vendored
|
|
@ -236,26 +236,34 @@ static void switch_tile_and_get_next_job(AV1_COMP *const cpi, int *cur_tile_id,
|
|||
int tile_index = tile_row * tile_cols + tile_col;
|
||||
TileDataEnc *this_tile = &cpi->tile_data[tile_index];
|
||||
AV1RowMTInfo *row_mt_info = &this_tile->row_mt_info;
|
||||
int num_mis_to_encode =
|
||||
this_tile->tile_info.mi_row_end - row_mt_info->current_mi_row;
|
||||
int num_sb_rows_in_tile =
|
||||
av1_get_sb_rows_in_tile(cm, this_tile->tile_info);
|
||||
int num_sb_cols_in_tile =
|
||||
av1_get_sb_cols_in_tile(cm, this_tile->tile_info);
|
||||
int theoretical_limit_on_threads =
|
||||
AOMMIN((num_sb_cols_in_tile + 1) >> 1, num_sb_rows_in_tile);
|
||||
int num_threads_working = row_mt_info->num_threads_working;
|
||||
if (num_threads_working < theoretical_limit_on_threads) {
|
||||
int num_mis_to_encode =
|
||||
this_tile->tile_info.mi_row_end - row_mt_info->current_mi_row;
|
||||
|
||||
// Tile to be processed by this thread is selected on the basis of
|
||||
// availability of jobs:
|
||||
// 1) If jobs are available, tile to be processed is chosen on the
|
||||
// basis of minimum number of threads working for that tile. If two or
|
||||
// more tiles have same number of threads working for them, then the tile
|
||||
// with maximum number of jobs available will be chosen.
|
||||
// 2) If no jobs are available, then end_of_frame is reached.
|
||||
if (num_mis_to_encode > 0) {
|
||||
int num_threads_working = row_mt_info->num_threads_working;
|
||||
if (num_threads_working < min_num_threads_working) {
|
||||
min_num_threads_working = num_threads_working;
|
||||
max_mis_to_encode = 0;
|
||||
}
|
||||
if (num_threads_working == min_num_threads_working &&
|
||||
num_mis_to_encode > max_mis_to_encode) {
|
||||
tile_id = tile_index;
|
||||
max_mis_to_encode = num_mis_to_encode;
|
||||
// Tile to be processed by this thread is selected on the basis of
|
||||
// availability of jobs:
|
||||
// 1) If jobs are available, tile to be processed is chosen on the
|
||||
// basis of minimum number of threads working for that tile. If two or
|
||||
// more tiles have same number of threads working for them, then the
|
||||
// tile with maximum number of jobs available will be chosen.
|
||||
// 2) If no jobs are available, then end_of_frame is reached.
|
||||
if (num_mis_to_encode > 0) {
|
||||
if (num_threads_working < min_num_threads_working) {
|
||||
min_num_threads_working = num_threads_working;
|
||||
max_mis_to_encode = 0;
|
||||
}
|
||||
if (num_threads_working == min_num_threads_working &&
|
||||
num_mis_to_encode > max_mis_to_encode) {
|
||||
tile_id = tile_index;
|
||||
max_mis_to_encode = num_mis_to_encode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -616,7 +624,7 @@ void av1_encode_tiles_row_mt(AV1_COMP *cpi) {
|
|||
const int tile_rows = cm->tile_rows;
|
||||
MultiThreadHandle *multi_thread_ctxt = &cpi->multi_thread_ctxt;
|
||||
int num_workers = 0;
|
||||
int total_num_sb_rows = 0;
|
||||
int total_num_threads_row_mt = 0;
|
||||
int max_sb_rows = 0;
|
||||
|
||||
if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
|
||||
|
|
@ -631,11 +639,19 @@ void av1_encode_tiles_row_mt(AV1_COMP *cpi) {
|
|||
TileDataEnc *tile_data = &cpi->tile_data[row * cm->tile_cols + col];
|
||||
int num_sb_rows_in_tile =
|
||||
av1_get_sb_rows_in_tile(cm, tile_data->tile_info);
|
||||
total_num_sb_rows += num_sb_rows_in_tile;
|
||||
int num_sb_cols_in_tile =
|
||||
av1_get_sb_cols_in_tile(cm, tile_data->tile_info);
|
||||
total_num_threads_row_mt +=
|
||||
AOMMIN((num_sb_cols_in_tile + 1) >> 1, num_sb_rows_in_tile);
|
||||
max_sb_rows = AOMMAX(max_sb_rows, num_sb_rows_in_tile);
|
||||
}
|
||||
}
|
||||
num_workers = AOMMIN(cpi->oxcf.max_threads, total_num_sb_rows);
|
||||
// TODO(ravi.chaudhary@ittiam.com): Currently the percentage of
|
||||
// post-processing stages in encoder is quiet low, so limiting the number of
|
||||
// threads to the theoretical limit in row-mt does not have much impact on
|
||||
// post-processing multi-threading stage. Need to revisit this when
|
||||
// post-processing time starts shooting up.
|
||||
num_workers = AOMMIN(cpi->oxcf.max_threads, total_num_threads_row_mt);
|
||||
|
||||
if (multi_thread_ctxt->allocated_tile_cols != tile_cols ||
|
||||
multi_thread_ctxt->allocated_tile_rows != tile_rows ||
|
||||
|
|
|
|||
2364
third_party/aom/av1/encoder/firstpass.c
vendored
2364
third_party/aom/av1/encoder/firstpass.c
vendored
File diff suppressed because it is too large
Load diff
128
third_party/aom/av1/encoder/firstpass.h
vendored
128
third_party/aom/av1/encoder/firstpass.h
vendored
|
|
@ -21,35 +21,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
|
||||
#define FPMB_DCINTRA_MASK 0x01
|
||||
|
||||
#define FPMB_MOTION_ZERO_MASK 0x02
|
||||
#define FPMB_MOTION_LEFT_MASK 0x04
|
||||
#define FPMB_MOTION_RIGHT_MASK 0x08
|
||||
#define FPMB_MOTION_UP_MASK 0x10
|
||||
#define FPMB_MOTION_DOWN_MASK 0x20
|
||||
|
||||
#define FPMB_ERROR_SMALL_MASK 0x40
|
||||
#define FPMB_ERROR_LARGE_MASK 0x80
|
||||
#define FPMB_ERROR_SMALL_TH 2000
|
||||
#define FPMB_ERROR_LARGE_TH 48000
|
||||
|
||||
typedef struct {
|
||||
uint8_t *mb_stats_start;
|
||||
uint8_t *mb_stats_end;
|
||||
} FIRSTPASS_MB_STATS;
|
||||
#endif
|
||||
|
||||
// Length of the bi-predictive frame group (BFG)
|
||||
// NOTE: Currently each BFG contains one backward ref (BWF) frame plus a certain
|
||||
// number of bi-predictive frames.
|
||||
#define BFG_INTERVAL 2
|
||||
// The maximum number of extra ALTREF's except ALTREF_FRAME
|
||||
#define MAX_EXT_ARFS (REF_FRAMES - BWDREF_FRAME - 1)
|
||||
|
||||
#define MIN_EXT_ARF_INTERVAL 4
|
||||
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x)-0.000001 : (x) + 0.000001)
|
||||
|
||||
#define MIN_ZERO_MOTION 0.95
|
||||
#define MAX_SR_CODED_ERROR 40
|
||||
|
|
@ -59,45 +31,79 @@ typedef struct {
|
|||
#define VLOW_MOTION_THRESHOLD 950
|
||||
|
||||
typedef struct {
|
||||
// Frame number in display order, if stats are for a single frame.
|
||||
// No real meaning for a collection of frames.
|
||||
double frame;
|
||||
// Weight assigned to this frame (or total weight for the collection of
|
||||
// frames) currently based on intra factor and brightness factor. This is used
|
||||
// to distribute bits betweeen easier and harder frames.
|
||||
double weight;
|
||||
// Intra prediction error.
|
||||
double intra_error;
|
||||
// Average wavelet energy computed using Discrete Wavelet Transform (DWT).
|
||||
double frame_avg_wavelet_energy;
|
||||
// Best of intra pred error and inter pred error using last frame as ref.
|
||||
double coded_error;
|
||||
// Best of intra pred error and inter pred error using golden frame as ref.
|
||||
double sr_coded_error;
|
||||
// Percentage of blocks with inter pred error < intra pred error.
|
||||
double pcnt_inter;
|
||||
// Percentage of blocks using (inter prediction and) non-zero motion vectors.
|
||||
double pcnt_motion;
|
||||
// Percentage of blocks where golden frame was the best reference. That is:
|
||||
// inter pred error using golden frame < inter pred error using last frame and
|
||||
// inter pred error using golden frame < intra pred error
|
||||
double pcnt_second_ref;
|
||||
// Percentage of blocks where intra and inter prediction errors were very
|
||||
// close. Note that this is a 'weighted count', that is, the so blocks may be
|
||||
// weighted by how close the two errors were.
|
||||
double pcnt_neutral;
|
||||
// Percentage of blocks that have almost no intra error residual
|
||||
// (i.e. are in effect completely flat and untextured in the intra
|
||||
// domain). In natural videos this is uncommon, but it is much more
|
||||
// common in animations, graphics and screen content, so may be used
|
||||
// as a signal to detect these types of content.
|
||||
double intra_skip_pct;
|
||||
double inactive_zone_rows; // Image mask rows top and bottom.
|
||||
double inactive_zone_cols; // Image mask columns at left and right edges.
|
||||
// Image mask rows top and bottom.
|
||||
double inactive_zone_rows;
|
||||
// Image mask columns at left and right edges.
|
||||
double inactive_zone_cols;
|
||||
// Average of row motion vectors.
|
||||
double MVr;
|
||||
// Mean of absolute value of row motion vectors.
|
||||
double mvr_abs;
|
||||
// Mean of column motion vectors.
|
||||
double MVc;
|
||||
// Mean of absolute value of column motion vectors.
|
||||
double mvc_abs;
|
||||
// Variance of row motion vectors.
|
||||
double MVrv;
|
||||
// Variance of column motion vectors.
|
||||
double MVcv;
|
||||
// Value in range [-1,1] indicating fraction of row and column motion vectors
|
||||
// that point inwards (negative MV value) or outwards (positive MV value).
|
||||
// For example, value of 1 indicates, all row/column MVs are inwards.
|
||||
double mv_in_out_count;
|
||||
// Count of unique non-zero motion vectors.
|
||||
double new_mv_count;
|
||||
// Duration of the frame / collection of frames.
|
||||
double duration;
|
||||
// 1.0 if stats are for a single frame, OR
|
||||
// Number of frames in this collection for which the stats are accumulated.
|
||||
double count;
|
||||
// standard deviation for (0, 0) motion prediction error
|
||||
double raw_error_stdev;
|
||||
} FIRSTPASS_STATS;
|
||||
|
||||
enum {
|
||||
KF_UPDATE = 0,
|
||||
LF_UPDATE = 1,
|
||||
GF_UPDATE = 2,
|
||||
ARF_UPDATE = 3,
|
||||
OVERLAY_UPDATE = 4,
|
||||
BRF_UPDATE = 5, // Backward Reference Frame
|
||||
LAST_BIPRED_UPDATE = 6, // Last Bi-predictive Frame
|
||||
BIPRED_UPDATE = 7, // Bi-predictive Frame, but not the last one
|
||||
INTNL_OVERLAY_UPDATE = 8, // Internal Overlay Frame
|
||||
INTNL_ARF_UPDATE = 9, // Internal Altref Frame (candidate for ALTREF2)
|
||||
FRAME_UPDATE_TYPES = 10
|
||||
KF_UPDATE,
|
||||
LF_UPDATE,
|
||||
GF_UPDATE,
|
||||
ARF_UPDATE,
|
||||
OVERLAY_UPDATE,
|
||||
INTNL_OVERLAY_UPDATE, // Internal Overlay Frame
|
||||
INTNL_ARF_UPDATE, // Internal Altref Frame
|
||||
FRAME_UPDATE_TYPES
|
||||
} UENUM1BYTE(FRAME_UPDATE_TYPE);
|
||||
|
||||
#define FC_ANIMATION_THRESH 0.15
|
||||
|
|
@ -109,18 +115,15 @@ enum {
|
|||
|
||||
typedef struct {
|
||||
unsigned char index;
|
||||
RATE_FACTOR_LEVEL rf_level[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
FRAME_UPDATE_TYPE update_type[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char arf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char arf_update_idx[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char arf_ref_idx[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char arf_pos_in_gf[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char pyramid_level[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char pyramid_height;
|
||||
unsigned char pyramid_lvl_nodes[MAX_PYRAMID_LVL];
|
||||
unsigned char brf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
unsigned char bidir_pred_enabled[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 1];
|
||||
int size;
|
||||
} GF_GROUP;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -139,11 +142,6 @@ typedef struct {
|
|||
double mb_av_energy;
|
||||
double frame_avg_haar_energy;
|
||||
|
||||
#if CONFIG_FP_MB_STATS
|
||||
uint8_t *frame_mb_stats_buf;
|
||||
uint8_t *this_frame_mb_stats;
|
||||
FIRSTPASS_MB_STATS firstpass_mb_stats;
|
||||
#endif
|
||||
// An indication of the content type of the current frame
|
||||
FRAME_CONTENT_TYPE fr_content_type;
|
||||
|
||||
|
|
@ -160,7 +158,6 @@ typedef struct {
|
|||
|
||||
int kf_zeromotion_pct;
|
||||
int last_kfgroup_zeromotion_pct;
|
||||
int gf_zeromotion_pct;
|
||||
int active_worst_quality;
|
||||
int baseline_active_worst_quality;
|
||||
int extend_minq;
|
||||
|
|
@ -172,37 +169,14 @@ typedef struct {
|
|||
|
||||
struct AV1_COMP;
|
||||
struct EncodeFrameParams;
|
||||
struct AV1EncoderConfig;
|
||||
|
||||
void av1_init_first_pass(struct AV1_COMP *cpi);
|
||||
void av1_rc_get_first_pass_params(struct AV1_COMP *cpi);
|
||||
void av1_first_pass(struct AV1_COMP *cpi, const int64_t ts_duration);
|
||||
void av1_end_first_pass(struct AV1_COMP *cpi);
|
||||
|
||||
void av1_init_second_pass(struct AV1_COMP *cpi);
|
||||
void av1_rc_get_second_pass_params(
|
||||
struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
|
||||
|
||||
// Post encode update of the rate control parameters for 2-pass
|
||||
void av1_twopass_postencode_update(struct AV1_COMP *cpi);
|
||||
|
||||
static INLINE int get_number_of_extra_arfs(int interval, int arf_pending,
|
||||
int max_pyr_height) {
|
||||
// Max extra (internal) alt-refs allowed based on interval.
|
||||
int extra_arfs_from_interval = 0;
|
||||
if (arf_pending && MAX_EXT_ARFS > 0) {
|
||||
extra_arfs_from_interval =
|
||||
(interval >= MIN_EXT_ARF_INTERVAL * (MAX_EXT_ARFS + 1))
|
||||
? MAX_EXT_ARFS
|
||||
: (interval >= MIN_EXT_ARF_INTERVAL * MAX_EXT_ARFS)
|
||||
? MAX_EXT_ARFS - 1
|
||||
: 0;
|
||||
}
|
||||
// Max extra (internal) alt-refs allowed based on max pyramid height.
|
||||
assert(max_pyr_height >= 1);
|
||||
const int ext_arfs_from_max_height = max_pyr_height - 1;
|
||||
// Finally, min of the two above is our actual max allowance.
|
||||
return AOMMIN(extra_arfs_from_interval, ext_arfs_from_max_height);
|
||||
}
|
||||
void av1_twopass_zero_stats(FIRSTPASS_STATS *section);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
29
third_party/aom/av1/encoder/global_motion.c
vendored
29
third_party/aom/av1/encoder/global_motion.c
vendored
|
|
@ -32,7 +32,6 @@
|
|||
#define MIN_INLIER_PROB 0.1
|
||||
|
||||
#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
|
||||
#define USE_GM_FEATURE_BASED 1
|
||||
|
||||
// Border over which to compute the global motion
|
||||
#define ERRORADV_BORDER 0
|
||||
|
|
@ -276,7 +275,6 @@ static unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm,
|
|||
return buf_8bit;
|
||||
}
|
||||
|
||||
#if USE_GM_FEATURE_BASED
|
||||
static int compute_global_motion_feature_based(
|
||||
TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
|
||||
int bit_depth, int *num_inliers_by_motion, double *params_by_motion,
|
||||
|
|
@ -331,7 +329,7 @@ static int compute_global_motion_feature_based(
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static INLINE RansacFuncDouble
|
||||
get_ransac_double_prec_type(TransformationType type) {
|
||||
switch (type) {
|
||||
|
|
@ -543,6 +541,7 @@ static INLINE void solve_2x2_system(const double *M, const double *b,
|
|||
output_vec[1] = -M[2] * mult_b0 + M_0 * mult_b1;
|
||||
}
|
||||
|
||||
/*
|
||||
static INLINE void image_difference(const uint8_t *src, int src_stride,
|
||||
const uint8_t *ref, int ref_stride,
|
||||
int16_t *dst, int dst_stride, int height,
|
||||
|
|
@ -557,6 +556,7 @@ static INLINE void image_difference(const uint8_t *src, int src_stride,
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Compute an image gradient using a sobel filter.
|
||||
// If dir == 1, compute the x gradient. If dir == 0, compute y. This function
|
||||
|
|
@ -869,19 +869,22 @@ static int compute_global_motion_disflow_based(
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int av1_compute_global_motion(TransformationType type, YV12_BUFFER_CONFIG *frm,
|
||||
YV12_BUFFER_CONFIG *ref, int bit_depth,
|
||||
GlobalMotionEstimationType gm_estimation_type,
|
||||
int *num_inliers_by_motion,
|
||||
double *params_by_motion, int num_motions) {
|
||||
#if USE_GM_FEATURE_BASED
|
||||
return compute_global_motion_feature_based(type, frm, ref, bit_depth,
|
||||
num_inliers_by_motion,
|
||||
params_by_motion, num_motions);
|
||||
#else
|
||||
return compute_global_motion_disflow_based(type, frm, ref, bit_depth,
|
||||
num_inliers_by_motion,
|
||||
params_by_motion, num_motions);
|
||||
#endif
|
||||
switch (gm_estimation_type) {
|
||||
case GLOBAL_MOTION_FEATURE_BASED:
|
||||
return compute_global_motion_feature_based(type, frm, ref, bit_depth,
|
||||
num_inliers_by_motion,
|
||||
params_by_motion, num_motions);
|
||||
case GLOBAL_MOTION_DISFLOW_BASED:
|
||||
return compute_global_motion_disflow_based(type, frm, ref, bit_depth,
|
||||
num_inliers_by_motion,
|
||||
params_by_motion, num_motions);
|
||||
default: assert(0 && "Unknown global motion estimation type");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
6
third_party/aom/av1/encoder/global_motion.h
vendored
6
third_party/aom/av1/encoder/global_motion.h
vendored
|
|
@ -22,6 +22,11 @@ extern "C" {
|
|||
|
||||
#define RANSAC_NUM_MOTIONS 1
|
||||
|
||||
typedef enum {
|
||||
GLOBAL_MOTION_FEATURE_BASED,
|
||||
GLOBAL_MOTION_DISFLOW_BASED,
|
||||
} GlobalMotionEstimationType;
|
||||
|
||||
void av1_convert_model_to_params(const double *params,
|
||||
WarpedMotionParams *model);
|
||||
|
||||
|
|
@ -56,6 +61,7 @@ int64_t av1_refine_integerized_param(WarpedMotionParams *wm,
|
|||
*/
|
||||
int av1_compute_global_motion(TransformationType type, YV12_BUFFER_CONFIG *frm,
|
||||
YV12_BUFFER_CONFIG *ref, int bit_depth,
|
||||
GlobalMotionEstimationType gm_estimation_type,
|
||||
int *num_inliers_by_motion,
|
||||
double *params_by_motion, int num_motions);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
192
third_party/aom/av1/encoder/gop_structure.c
vendored
Normal file
192
third_party/aom/av1/encoder/gop_structure.c
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 <stdint.h>
|
||||
|
||||
#include "config/aom_config.h"
|
||||
#include "config/aom_scale_rtcd.h"
|
||||
|
||||
#include "aom/aom_codec.h"
|
||||
#include "aom/aom_encoder.h"
|
||||
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
#include "av1/common/onyxc_int.h"
|
||||
|
||||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/firstpass.h"
|
||||
#include "av1/encoder/gop_structure.h"
|
||||
|
||||
// Set parameters for frames between 'start' and 'end' (excluding both).
|
||||
static void set_multi_layer_params(GF_GROUP *const gf_group, int start, int end,
|
||||
int *frame_ind, int arf_ind, int level) {
|
||||
assert(level >= MIN_PYRAMID_LVL);
|
||||
const int num_frames_to_process = end - start - 1;
|
||||
assert(num_frames_to_process >= 0);
|
||||
if (num_frames_to_process == 0) return;
|
||||
|
||||
// Either we are at the last level of the pyramid, or we don't have enough
|
||||
// frames between 'l' and 'r' to create one more level.
|
||||
if (level == MIN_PYRAMID_LVL || num_frames_to_process < 3) {
|
||||
// Leaf nodes.
|
||||
while (++start < end) {
|
||||
gf_group->update_type[*frame_ind] = LF_UPDATE;
|
||||
gf_group->arf_src_offset[*frame_ind] = 0;
|
||||
gf_group->arf_pos_in_gf[*frame_ind] = 0;
|
||||
gf_group->arf_update_idx[*frame_ind] = arf_ind;
|
||||
gf_group->pyramid_level[*frame_ind] = MIN_PYRAMID_LVL;
|
||||
++gf_group->pyramid_lvl_nodes[MIN_PYRAMID_LVL];
|
||||
++(*frame_ind);
|
||||
}
|
||||
} else {
|
||||
const int m = (start + end) / 2;
|
||||
const int arf_pos_in_gf = *frame_ind;
|
||||
|
||||
// Internal ARF.
|
||||
gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
|
||||
gf_group->arf_src_offset[*frame_ind] = m - start - 1;
|
||||
gf_group->arf_pos_in_gf[*frame_ind] = 0;
|
||||
gf_group->arf_update_idx[*frame_ind] = 1; // mark all internal ARF 1
|
||||
gf_group->pyramid_level[*frame_ind] = level;
|
||||
++gf_group->pyramid_lvl_nodes[level];
|
||||
++(*frame_ind);
|
||||
|
||||
// Frames displayed before this internal ARF.
|
||||
set_multi_layer_params(gf_group, start, m, frame_ind, 1, level - 1);
|
||||
|
||||
// Overlay for internal ARF.
|
||||
gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE;
|
||||
gf_group->arf_src_offset[*frame_ind] = 0;
|
||||
gf_group->arf_pos_in_gf[*frame_ind] = arf_pos_in_gf; // For bit allocation.
|
||||
gf_group->arf_update_idx[*frame_ind] = 1;
|
||||
gf_group->pyramid_level[*frame_ind] = MIN_PYRAMID_LVL;
|
||||
++(*frame_ind);
|
||||
|
||||
// Frames displayed after this internal ARF.
|
||||
set_multi_layer_params(gf_group, m, end, frame_ind, arf_ind, level - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int construct_multi_layer_gf_structure(
|
||||
GF_GROUP *const gf_group, int gf_interval, int pyr_height,
|
||||
FRAME_UPDATE_TYPE first_frame_update_type) {
|
||||
gf_group->pyramid_height = pyr_height;
|
||||
av1_zero_array(gf_group->pyramid_lvl_nodes, MAX_PYRAMID_LVL);
|
||||
int frame_index = 0;
|
||||
|
||||
// Keyframe / Overlay frame / Golden frame.
|
||||
assert(gf_interval >= 1);
|
||||
assert(first_frame_update_type == KF_UPDATE ||
|
||||
first_frame_update_type == OVERLAY_UPDATE ||
|
||||
first_frame_update_type == GF_UPDATE);
|
||||
gf_group->update_type[frame_index] = first_frame_update_type;
|
||||
gf_group->arf_src_offset[frame_index] = 0;
|
||||
gf_group->arf_pos_in_gf[frame_index] = 0;
|
||||
gf_group->arf_update_idx[frame_index] = 0;
|
||||
gf_group->pyramid_level[frame_index] = MIN_PYRAMID_LVL;
|
||||
++frame_index;
|
||||
|
||||
// ALTREF.
|
||||
const int use_altref = (gf_group->pyramid_height > 0);
|
||||
if (use_altref) {
|
||||
gf_group->update_type[frame_index] = ARF_UPDATE;
|
||||
gf_group->arf_src_offset[frame_index] = gf_interval - 1;
|
||||
gf_group->arf_pos_in_gf[frame_index] = 0;
|
||||
gf_group->arf_update_idx[frame_index] = 0;
|
||||
gf_group->pyramid_level[frame_index] = gf_group->pyramid_height;
|
||||
++frame_index;
|
||||
}
|
||||
|
||||
// Rest of the frames.
|
||||
const int next_height =
|
||||
use_altref ? gf_group->pyramid_height - 1 : gf_group->pyramid_height;
|
||||
assert(next_height >= MIN_PYRAMID_LVL);
|
||||
set_multi_layer_params(gf_group, 0, gf_interval, &frame_index, 0,
|
||||
next_height);
|
||||
return frame_index;
|
||||
}
|
||||
|
||||
#define CHECK_GF_PARAMETER 0
|
||||
#if CHECK_GF_PARAMETER
|
||||
void check_frame_params(GF_GROUP *const gf_group, int gf_interval) {
|
||||
static const char *update_type_strings[FRAME_UPDATE_TYPES] = {
|
||||
"KF_UPDATE", "LF_UPDATE", "GF_UPDATE",
|
||||
"ARF_UPDATE", "OVERLAY_UPDATE", "INTNL_OVERLAY_UPDATE",
|
||||
"INTNL_ARF_UPDATE"
|
||||
};
|
||||
FILE *fid = fopen("GF_PARAMS.txt", "a");
|
||||
|
||||
fprintf(fid, "\ngf_interval = {%d}\n", gf_interval);
|
||||
for (int i = 0; i <= gf_group->size; ++i) {
|
||||
fprintf(fid, "#%2d : %s %d %d %d %d\n", i,
|
||||
update_type_strings[gf_group->update_type[i]],
|
||||
gf_group->arf_src_offset[i], gf_group->arf_pos_in_gf[i],
|
||||
gf_group->arf_update_idx[i], gf_group->pyramid_level[i]);
|
||||
}
|
||||
|
||||
fprintf(fid, "number of nodes in each level: \n");
|
||||
for (int i = 0; i < gf_group->pyramid_height; ++i) {
|
||||
fprintf(fid, "lvl %d: %d ", i, gf_group->pyramid_lvl_nodes[i]);
|
||||
}
|
||||
fprintf(fid, "\n");
|
||||
fclose(fid);
|
||||
}
|
||||
#endif // CHECK_GF_PARAMETER
|
||||
|
||||
static INLINE int max_pyramid_height_from_width(int pyramid_width) {
|
||||
if (pyramid_width > 12) return 4;
|
||||
if (pyramid_width > 6) return 3;
|
||||
if (pyramid_width > 3) return 2;
|
||||
if (pyramid_width > 1) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_pyramid_height(const AV1_COMP *const cpi) {
|
||||
const RATE_CONTROL *const rc = &cpi->rc;
|
||||
assert(IMPLIES(cpi->oxcf.gf_max_pyr_height == MIN_PYRAMID_LVL,
|
||||
!rc->source_alt_ref_pending)); // define_gf_group() enforced.
|
||||
if (!rc->source_alt_ref_pending) {
|
||||
return MIN_PYRAMID_LVL;
|
||||
}
|
||||
assert(cpi->oxcf.gf_max_pyr_height > MIN_PYRAMID_LVL);
|
||||
if (!cpi->internal_altref_allowed) {
|
||||
assert(MIN_PYRAMID_LVL + 1 <= cpi->oxcf.gf_max_pyr_height);
|
||||
return MIN_PYRAMID_LVL + 1;
|
||||
}
|
||||
return AOMMIN(max_pyramid_height_from_width(rc->baseline_gf_interval),
|
||||
cpi->oxcf.gf_max_pyr_height);
|
||||
}
|
||||
|
||||
void av1_gop_setup_structure(AV1_COMP *cpi,
|
||||
const EncodeFrameParams *const frame_params) {
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
TWO_PASS *const twopass = &cpi->twopass;
|
||||
GF_GROUP *const gf_group = &twopass->gf_group;
|
||||
const int key_frame = (frame_params->frame_type == KEY_FRAME);
|
||||
const FRAME_UPDATE_TYPE first_frame_update_type =
|
||||
key_frame ? KF_UPDATE
|
||||
: rc->source_alt_ref_active ? OVERLAY_UPDATE : GF_UPDATE;
|
||||
gf_group->size = construct_multi_layer_gf_structure(
|
||||
gf_group, rc->baseline_gf_interval, get_pyramid_height(cpi),
|
||||
first_frame_update_type);
|
||||
|
||||
// We need to configure the frame at the end of the sequence + 1 that
|
||||
// will be the start frame for the next group. Otherwise prior to the
|
||||
// call to av1_get_second_pass_params(), the data will be undefined.
|
||||
gf_group->update_type[gf_group->size] =
|
||||
(rc->source_alt_ref_pending) ? OVERLAY_UPDATE : GF_UPDATE;
|
||||
gf_group->arf_update_idx[gf_group->size] = 0;
|
||||
gf_group->arf_pos_in_gf[gf_group->size] = 0;
|
||||
|
||||
#if CHECK_GF_PARAMETER
|
||||
check_frame_params(gf_group, rc->baseline_gf_interval);
|
||||
#endif
|
||||
}
|
||||
36
third_party/aom/av1/encoder/gop_structure.h
vendored
Normal file
36
third_party/aom/av1/encoder/gop_structure.h
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 AOM_AV1_ENCODER_GOP_STRUCTURE_H_
|
||||
#define AOM_AV1_ENCODER_GOP_STRUCTURE_H_
|
||||
|
||||
#include "av1/common/onyxc_int.h"
|
||||
#include "av1/encoder/ratectrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct AV1_COMP;
|
||||
struct EncodeFrameParams;
|
||||
|
||||
// Set up the Group-Of-Pictures structure for this GF_GROUP. This involves
|
||||
// deciding where to place the various FRAME_UPDATE_TYPEs in the group. It does
|
||||
// this primarily by setting the contents of
|
||||
// cpi->twopass.gf_group.update_type[].
|
||||
void av1_gop_setup_structure(
|
||||
struct AV1_COMP *cpi, const struct EncodeFrameParams *const frame_params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_AV1_ENCODER_GOP_STRUCTURE_H_
|
||||
3
third_party/aom/av1/encoder/hash_motion.c
vendored
3
third_party/aom/av1/encoder/hash_motion.c
vendored
|
|
@ -393,8 +393,9 @@ void av1_get_block_hash_value(uint8_t *y_src, int stride, int block_size,
|
|||
uint32_t *hash_value1, uint32_t *hash_value2,
|
||||
int use_highbitdepth, MACROBLOCK *x) {
|
||||
uint32_t to_hash[4];
|
||||
const int add_value = hash_block_size_to_index(block_size) << crc_bits;
|
||||
int add_value = hash_block_size_to_index(block_size);
|
||||
assert(add_value >= 0);
|
||||
add_value <<= crc_bits;
|
||||
const int crc_mask = (1 << crc_bits) - 1;
|
||||
|
||||
// 2x2 subblock hash values in current CU
|
||||
|
|
|
|||
599
third_party/aom/av1/encoder/level.c
vendored
Normal file
599
third_party/aom/av1/encoder/level.c
vendored
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/level.h"
|
||||
|
||||
#define UNDEFINED_LEVEL \
|
||||
{ \
|
||||
.level = SEQ_LEVEL_MAX, .max_picture_size = 0, .max_h_size = 0, \
|
||||
.max_v_size = 0, .max_display_rate = 0, .max_decode_rate = 0, \
|
||||
.max_header_rate = 0, .main_mbps = 0, .high_mbps = 0, .main_cr = 0, \
|
||||
.high_cr = 0, .max_tiles = 0, .max_tile_cols = 0 \
|
||||
}
|
||||
|
||||
static const AV1LevelSpec av1_level_defs[SEQ_LEVELS] = {
|
||||
{ .level = SEQ_LEVEL_2_0,
|
||||
.max_picture_size = 147456,
|
||||
.max_h_size = 2048,
|
||||
.max_v_size = 1152,
|
||||
.max_display_rate = 4423680L,
|
||||
.max_decode_rate = 5529600L,
|
||||
.max_header_rate = 150,
|
||||
.main_mbps = 1.5,
|
||||
.high_mbps = 0,
|
||||
.main_cr = 2.0,
|
||||
.high_cr = 0,
|
||||
.max_tiles = 8,
|
||||
.max_tile_cols = 4 },
|
||||
{ .level = SEQ_LEVEL_2_1,
|
||||
.max_picture_size = 278784,
|
||||
.max_h_size = 2816,
|
||||
.max_v_size = 1584,
|
||||
.max_display_rate = 8363520L,
|
||||
.max_decode_rate = 10454400L,
|
||||
.max_header_rate = 150,
|
||||
.main_mbps = 3.0,
|
||||
.high_mbps = 0,
|
||||
.main_cr = 2.0,
|
||||
.high_cr = 0,
|
||||
.max_tiles = 8,
|
||||
.max_tile_cols = 4 },
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
{ .level = SEQ_LEVEL_3_0,
|
||||
.max_picture_size = 665856,
|
||||
.max_h_size = 4352,
|
||||
.max_v_size = 2448,
|
||||
.max_display_rate = 19975680L,
|
||||
.max_decode_rate = 24969600L,
|
||||
.max_header_rate = 150,
|
||||
.main_mbps = 6.0,
|
||||
.high_mbps = 0,
|
||||
.main_cr = 2.0,
|
||||
.high_cr = 0,
|
||||
.max_tiles = 16,
|
||||
.max_tile_cols = 6 },
|
||||
{ .level = SEQ_LEVEL_3_1,
|
||||
.max_picture_size = 1065024,
|
||||
.max_h_size = 5504,
|
||||
.max_v_size = 3096,
|
||||
.max_display_rate = 31950720L,
|
||||
.max_decode_rate = 39938400L,
|
||||
.max_header_rate = 150,
|
||||
.main_mbps = 10.0,
|
||||
.high_mbps = 0,
|
||||
.main_cr = 2.0,
|
||||
.high_cr = 0,
|
||||
.max_tiles = 16,
|
||||
.max_tile_cols = 6 },
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
{ .level = SEQ_LEVEL_4_0,
|
||||
.max_picture_size = 2359296,
|
||||
.max_h_size = 6144,
|
||||
.max_v_size = 3456,
|
||||
.max_display_rate = 70778880L,
|
||||
.max_decode_rate = 77856768L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 12.0,
|
||||
.high_mbps = 30.0,
|
||||
.main_cr = 4.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 32,
|
||||
.max_tile_cols = 8 },
|
||||
{ .level = SEQ_LEVEL_4_1,
|
||||
.max_picture_size = 2359296,
|
||||
.max_h_size = 6144,
|
||||
.max_v_size = 3456,
|
||||
.max_display_rate = 141557760L,
|
||||
.max_decode_rate = 155713536L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 20.0,
|
||||
.high_mbps = 50.0,
|
||||
.main_cr = 4.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 32,
|
||||
.max_tile_cols = 8 },
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
{ .level = SEQ_LEVEL_5_0,
|
||||
.max_picture_size = 8912896,
|
||||
.max_h_size = 8192,
|
||||
.max_v_size = 4352,
|
||||
.max_display_rate = 267386880L,
|
||||
.max_decode_rate = 273715200L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 30.0,
|
||||
.high_mbps = 100.0,
|
||||
.main_cr = 6.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 64,
|
||||
.max_tile_cols = 8 },
|
||||
{ .level = SEQ_LEVEL_5_1,
|
||||
.max_picture_size = 8912896,
|
||||
.max_h_size = 8192,
|
||||
.max_v_size = 4352,
|
||||
.max_display_rate = 534773760L,
|
||||
.max_decode_rate = 547430400L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 40.0,
|
||||
.high_mbps = 160.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 64,
|
||||
.max_tile_cols = 8 },
|
||||
{ .level = SEQ_LEVEL_5_2,
|
||||
.max_picture_size = 8912896,
|
||||
.max_h_size = 8192,
|
||||
.max_v_size = 4352,
|
||||
.max_display_rate = 1069547520L,
|
||||
.max_decode_rate = 1094860800L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 60.0,
|
||||
.high_mbps = 240.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 64,
|
||||
.max_tile_cols = 8 },
|
||||
{ .level = SEQ_LEVEL_5_3,
|
||||
.max_picture_size = 8912896,
|
||||
.max_h_size = 8192,
|
||||
.max_v_size = 4352,
|
||||
.max_display_rate = 1069547520L,
|
||||
.max_decode_rate = 1176502272L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 60.0,
|
||||
.high_mbps = 240.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 64,
|
||||
.max_tile_cols = 8 },
|
||||
{ .level = SEQ_LEVEL_6_0,
|
||||
.max_picture_size = 35651584,
|
||||
.max_h_size = 16384,
|
||||
.max_v_size = 8704,
|
||||
.max_display_rate = 1069547520L,
|
||||
.max_decode_rate = 1176502272L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 60.0,
|
||||
.high_mbps = 240.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 128,
|
||||
.max_tile_cols = 16 },
|
||||
{ .level = SEQ_LEVEL_6_1,
|
||||
.max_picture_size = 35651584,
|
||||
.max_h_size = 16384,
|
||||
.max_v_size = 8704,
|
||||
.max_display_rate = 2139095040L,
|
||||
.max_decode_rate = 2189721600L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 100.0,
|
||||
.high_mbps = 480.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 128,
|
||||
.max_tile_cols = 16 },
|
||||
{ .level = SEQ_LEVEL_6_2,
|
||||
.max_picture_size = 35651584,
|
||||
.max_h_size = 16384,
|
||||
.max_v_size = 8704,
|
||||
.max_display_rate = 4278190080L,
|
||||
.max_decode_rate = 4379443200L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 160.0,
|
||||
.high_mbps = 800.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 128,
|
||||
.max_tile_cols = 16 },
|
||||
{ .level = SEQ_LEVEL_6_3,
|
||||
.max_picture_size = 35651584,
|
||||
.max_h_size = 16384,
|
||||
.max_v_size = 8704,
|
||||
.max_display_rate = 4278190080L,
|
||||
.max_decode_rate = 4706009088L,
|
||||
.max_header_rate = 300,
|
||||
.main_mbps = 160.0,
|
||||
.high_mbps = 800.0,
|
||||
.main_cr = 8.0,
|
||||
.high_cr = 4.0,
|
||||
.max_tiles = 128,
|
||||
.max_tile_cols = 16 },
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
UNDEFINED_LEVEL,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
LUMA_PIC_SIZE_TOO_LARGE,
|
||||
LUMA_PIC_H_SIZE_TOO_LARGE,
|
||||
LUMA_PIC_V_SIZE_TOO_LARGE,
|
||||
TOO_MANY_TILE_COLUMNS,
|
||||
TOO_MANY_TILES,
|
||||
TILE_TOO_LARGE,
|
||||
CROPPED_TILE_WIDTH_TOO_SMALL,
|
||||
CROPPED_TILE_HEIGHT_TOO_SMALL,
|
||||
TILE_WIDTH_INVALID,
|
||||
FRAME_HEADER_RATE_TOO_HIGH,
|
||||
DISPLAY_RATE_TOO_HIGH,
|
||||
DECODE_RATE_TOO_HIGH,
|
||||
CR_TOO_SMALL,
|
||||
|
||||
TARGET_LEVEL_FAIL_IDS,
|
||||
TARGET_LEVEL_OK,
|
||||
} TARGET_LEVEL_FAIL_ID;
|
||||
|
||||
static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = {
|
||||
"The picture size is too large.",
|
||||
"The picture width is too large.",
|
||||
"The picture height is too large.",
|
||||
"Too many tile columns are used.",
|
||||
"Too many tiles are used.",
|
||||
"The tile size is too large.",
|
||||
"The cropped tile width is less than 8",
|
||||
"The cropped tile height is less than 8",
|
||||
"The tile width is invalid",
|
||||
"The frame header rate is too high",
|
||||
"The display luma sample rate is too high",
|
||||
"The decoded luma sample rate is too high",
|
||||
"The compression ratio is too small",
|
||||
};
|
||||
|
||||
static double get_min_cr(const AV1LevelSpec *const level_spec, int tier,
|
||||
int is_still_picture, int64_t decoded_sample_rate) {
|
||||
if (is_still_picture) return 0.8;
|
||||
const double min_cr_basis = tier ? level_spec->high_cr : level_spec->main_cr;
|
||||
const double speed_adj =
|
||||
(double)decoded_sample_rate / level_spec->max_display_rate;
|
||||
return AOMMAX(min_cr_basis * speed_adj, 0.8);
|
||||
}
|
||||
|
||||
static TARGET_LEVEL_FAIL_ID check_level_constraints(
|
||||
const AV1LevelSpec *const target_level_spec,
|
||||
const AV1LevelSpec *const level_spec,
|
||||
const AV1LevelStats *const level_stats, int tier, int is_still_picture) {
|
||||
const double min_cr = get_min_cr(target_level_spec, tier, is_still_picture,
|
||||
level_spec->max_decode_rate);
|
||||
TARGET_LEVEL_FAIL_ID fail_id = TARGET_LEVEL_OK;
|
||||
|
||||
do {
|
||||
if (level_spec->max_picture_size > target_level_spec->max_picture_size) {
|
||||
fail_id = LUMA_PIC_SIZE_TOO_LARGE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_h_size > target_level_spec->max_h_size) {
|
||||
fail_id = LUMA_PIC_H_SIZE_TOO_LARGE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_v_size > target_level_spec->max_v_size) {
|
||||
fail_id = LUMA_PIC_V_SIZE_TOO_LARGE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_tile_cols > target_level_spec->max_tile_cols) {
|
||||
fail_id = TOO_MANY_TILE_COLUMNS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_tiles > target_level_spec->max_tiles) {
|
||||
fail_id = TOO_MANY_TILES;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_header_rate > target_level_spec->max_header_rate) {
|
||||
fail_id = FRAME_HEADER_RATE_TOO_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_display_rate > target_level_spec->max_display_rate) {
|
||||
fail_id = DISPLAY_RATE_TOO_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_spec->max_decode_rate > target_level_spec->max_decode_rate) {
|
||||
fail_id = DECODE_RATE_TOO_HIGH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_stats->max_tile_size > 4096 * 2304) {
|
||||
fail_id = TILE_TOO_LARGE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_stats->min_cropped_tile_width < 8) {
|
||||
fail_id = CROPPED_TILE_WIDTH_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_stats->min_cropped_tile_height < 8) {
|
||||
fail_id = CROPPED_TILE_HEIGHT_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!level_stats->tile_width_is_valid) {
|
||||
fail_id = TILE_WIDTH_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
if (level_stats->min_cr < min_cr) {
|
||||
fail_id = CR_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
return fail_id;
|
||||
}
|
||||
|
||||
static INLINE int is_in_operating_point(int operating_point,
|
||||
int temporal_layer_id,
|
||||
int spatial_layer_id) {
|
||||
if (!operating_point) return 1;
|
||||
|
||||
return ((operating_point >> temporal_layer_id) & 1) &&
|
||||
((operating_point >> (spatial_layer_id + 8)) & 1);
|
||||
}
|
||||
|
||||
static void get_tile_stats(const AV1_COMP *const cpi, int *max_tile_size,
|
||||
int *min_cropped_tile_width,
|
||||
int *min_cropped_tile_height,
|
||||
int *tile_width_valid) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int tile_cols = cm->tile_cols;
|
||||
const int tile_rows = cm->tile_rows;
|
||||
|
||||
*max_tile_size = 0;
|
||||
*min_cropped_tile_width = INT_MAX;
|
||||
*min_cropped_tile_height = INT_MAX;
|
||||
*tile_width_valid = 1;
|
||||
|
||||
for (int tile_row = 0; tile_row < tile_rows; ++tile_row) {
|
||||
for (int tile_col = 0; tile_col < tile_cols; ++tile_col) {
|
||||
const TileInfo *const tile_info =
|
||||
&cpi->tile_data[tile_row * cm->tile_cols + tile_col].tile_info;
|
||||
const int tile_width =
|
||||
(tile_info->mi_col_end - tile_info->mi_col_start) * MI_SIZE;
|
||||
const int tile_height =
|
||||
(tile_info->mi_row_end - tile_info->mi_row_start) * MI_SIZE;
|
||||
const int tile_size = tile_width * tile_height;
|
||||
*max_tile_size = AOMMAX(*max_tile_size, tile_size);
|
||||
|
||||
const int cropped_tile_width =
|
||||
cm->width - tile_info->mi_col_start * MI_SIZE;
|
||||
const int cropped_tile_height =
|
||||
cm->height - tile_info->mi_row_start * MI_SIZE;
|
||||
*min_cropped_tile_width =
|
||||
AOMMIN(*min_cropped_tile_width, cropped_tile_width);
|
||||
*min_cropped_tile_height =
|
||||
AOMMIN(*min_cropped_tile_height, cropped_tile_height);
|
||||
|
||||
const int is_right_most_tile = tile_info->mi_col_end == cm->mi_cols;
|
||||
if (!is_right_most_tile) {
|
||||
if (av1_superres_scaled(cm))
|
||||
*tile_width_valid &= tile_width >= 128;
|
||||
else
|
||||
*tile_width_valid &= tile_width >= 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int store_frame_record(int64_t ts_start, int64_t ts_end, int pic_size,
|
||||
int frame_header_count, int show_frame,
|
||||
int show_existing_frame,
|
||||
FrameWindowBuffer *const buffer) {
|
||||
if (buffer->num < FRAME_WINDOW_SIZE) {
|
||||
++buffer->num;
|
||||
} else {
|
||||
buffer->start = (buffer->start + 1) % FRAME_WINDOW_SIZE;
|
||||
}
|
||||
const int new_idx = (buffer->start + buffer->num - 1) % FRAME_WINDOW_SIZE;
|
||||
FrameRecord *const record = &buffer->buf[new_idx];
|
||||
record->ts_start = ts_start;
|
||||
record->ts_end = ts_end;
|
||||
record->pic_size = pic_size;
|
||||
record->frame_header_count = frame_header_count;
|
||||
record->show_frame = show_frame;
|
||||
record->show_existing_frame = show_existing_frame;
|
||||
|
||||
return new_idx;
|
||||
}
|
||||
|
||||
// Count the number of frames encoded in the last "duration" ticks, in display
|
||||
// time.
|
||||
static int count_frames(const FrameWindowBuffer *const buffer,
|
||||
int64_t duration) {
|
||||
const int current_idx = (buffer->start + buffer->num - 1) % FRAME_WINDOW_SIZE;
|
||||
// Assume current frame is shown frame.
|
||||
assert(buffer->buf[current_idx].show_frame);
|
||||
|
||||
const int64_t current_time = buffer->buf[current_idx].ts_end;
|
||||
const int64_t time_limit = AOMMAX(current_time - duration, 0);
|
||||
int num_frames = 1;
|
||||
int index = current_idx - 1;
|
||||
for (int i = buffer->num - 2; i >= 0; --i, --index, ++num_frames) {
|
||||
if (index < 0) index = FRAME_WINDOW_SIZE - 1;
|
||||
const FrameRecord *const record = &buffer->buf[index];
|
||||
if (!record->show_frame) continue;
|
||||
const int64_t ts_start = record->ts_start;
|
||||
if (ts_start < time_limit) break;
|
||||
}
|
||||
|
||||
return num_frames;
|
||||
}
|
||||
|
||||
// Scan previously encoded frames and update level metrics accordingly.
|
||||
static void scan_past_frames(const FrameWindowBuffer *const buffer,
|
||||
int num_frames_to_scan,
|
||||
AV1LevelSpec *const level_spec) {
|
||||
const int num_frames_in_buffer = buffer->num;
|
||||
int index = (buffer->start + num_frames_in_buffer - 1) % FRAME_WINDOW_SIZE;
|
||||
int frame_headers = 0;
|
||||
int64_t display_samples = 0;
|
||||
int64_t decoded_samples = 0;
|
||||
for (int i = 0; i < AOMMIN(num_frames_in_buffer, num_frames_to_scan); ++i) {
|
||||
const FrameRecord *const record = &buffer->buf[index];
|
||||
if (!record->show_existing_frame) {
|
||||
frame_headers += record->frame_header_count;
|
||||
decoded_samples += record->pic_size;
|
||||
}
|
||||
if (record->show_frame) {
|
||||
display_samples += record->pic_size;
|
||||
}
|
||||
--index;
|
||||
if (index < 0) index = FRAME_WINDOW_SIZE - 1;
|
||||
}
|
||||
level_spec->max_header_rate =
|
||||
AOMMAX(level_spec->max_header_rate, frame_headers);
|
||||
level_spec->max_display_rate =
|
||||
AOMMAX(level_spec->max_display_rate, display_samples);
|
||||
level_spec->max_decode_rate =
|
||||
AOMMAX(level_spec->max_decode_rate, decoded_samples);
|
||||
}
|
||||
|
||||
void av1_update_level_info(AV1_COMP *cpi, size_t size, int64_t ts_start,
|
||||
int64_t ts_end) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
const int upscaled_width = cm->superres_upscaled_width;
|
||||
const int height = cm->height;
|
||||
const int tile_cols = cm->tile_cols;
|
||||
const int tile_rows = cm->tile_rows;
|
||||
const int tiles = tile_cols * tile_rows;
|
||||
const int luma_pic_size = upscaled_width * height;
|
||||
const int frame_header_count = cpi->frame_header_count;
|
||||
const int show_frame = cm->show_frame;
|
||||
const int show_existing_frame = cm->show_existing_frame;
|
||||
|
||||
// Store info. of current frame into FrameWindowBuffer.
|
||||
FrameWindowBuffer *const buffer = &cpi->frame_window_buffer;
|
||||
store_frame_record(ts_start, ts_end, luma_pic_size, frame_header_count,
|
||||
show_frame, show_existing_frame, buffer);
|
||||
// Count the number of frames encoded in the past 1 second.
|
||||
const int encoded_frames_in_last_second =
|
||||
show_frame ? count_frames(buffer, TICKS_PER_SEC) : 0;
|
||||
|
||||
int max_tile_size;
|
||||
int min_cropped_tile_width;
|
||||
int min_cropped_tile_height;
|
||||
int tile_width_is_valid;
|
||||
get_tile_stats(cpi, &max_tile_size, &min_cropped_tile_width,
|
||||
&min_cropped_tile_height, &tile_width_is_valid);
|
||||
|
||||
const SequenceHeader *const seq_params = &cm->seq_params;
|
||||
const BITSTREAM_PROFILE profile = seq_params->profile;
|
||||
const int pic_size_profile_factor =
|
||||
profile == PROFILE_0 ? 15 : (profile == PROFILE_1 ? 30 : 36);
|
||||
const size_t frame_compressed_size = (size > 129 ? size - 128 : 1);
|
||||
const size_t frame_uncompressed_size =
|
||||
(luma_pic_size * pic_size_profile_factor) >> 3;
|
||||
|
||||
aom_clear_system_state();
|
||||
const double compression_ratio =
|
||||
frame_uncompressed_size / (double)frame_compressed_size;
|
||||
const double total_time_encoded =
|
||||
(cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
|
||||
(double)TICKS_PER_SEC;
|
||||
|
||||
const int temporal_layer_id = cm->temporal_layer_id;
|
||||
const int spatial_layer_id = cm->spatial_layer_id;
|
||||
const int is_still_picture = seq_params->still_picture;
|
||||
// update level_stats
|
||||
// TODO(kyslov@) fix the implementation according to buffer model
|
||||
for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; ++i) {
|
||||
if (!is_in_operating_point(seq_params->operating_point_idc[i],
|
||||
temporal_layer_id, spatial_layer_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AV1LevelInfo *const level_info = &cpi->level_info[i];
|
||||
AV1LevelStats *const level_stats = &level_info->level_stats;
|
||||
|
||||
level_stats->max_tile_size =
|
||||
AOMMAX(level_stats->max_tile_size, max_tile_size);
|
||||
level_stats->min_cropped_tile_width =
|
||||
AOMMIN(level_stats->min_cropped_tile_width, min_cropped_tile_width);
|
||||
level_stats->min_cropped_tile_height =
|
||||
AOMMIN(level_stats->min_cropped_tile_height, min_cropped_tile_height);
|
||||
level_stats->tile_width_is_valid &= tile_width_is_valid;
|
||||
level_stats->total_compressed_size += frame_compressed_size;
|
||||
if (show_frame) level_stats->total_time_encoded = total_time_encoded;
|
||||
level_stats->min_cr = AOMMIN(level_stats->min_cr, compression_ratio);
|
||||
|
||||
// update level_spec
|
||||
// TODO(kyslov@) update all spec fields
|
||||
AV1LevelSpec *const level_spec = &level_info->level_spec;
|
||||
level_spec->max_picture_size =
|
||||
AOMMAX(level_spec->max_picture_size, luma_pic_size);
|
||||
level_spec->max_h_size =
|
||||
AOMMAX(level_spec->max_h_size, cm->superres_upscaled_width);
|
||||
level_spec->max_v_size = AOMMAX(level_spec->max_v_size, height);
|
||||
level_spec->max_tile_cols = AOMMAX(level_spec->max_tile_cols, tile_cols);
|
||||
level_spec->max_tiles = AOMMAX(level_spec->max_tiles, tiles);
|
||||
|
||||
if (show_frame) {
|
||||
scan_past_frames(buffer, encoded_frames_in_last_second, level_spec);
|
||||
}
|
||||
|
||||
// Check whether target level is met.
|
||||
const AV1_LEVEL target_seq_level_idx = cpi->target_seq_level_idx[i];
|
||||
if (target_seq_level_idx < SEQ_LEVELS) {
|
||||
const AV1LevelSpec *const target_level_spec =
|
||||
av1_level_defs + target_seq_level_idx;
|
||||
const int tier = seq_params->tier[i];
|
||||
const TARGET_LEVEL_FAIL_ID fail_id = check_level_constraints(
|
||||
target_level_spec, level_spec, level_stats, tier, is_still_picture);
|
||||
if (fail_id != TARGET_LEVEL_OK) {
|
||||
const int target_level_major = 2 + (target_seq_level_idx >> 2);
|
||||
const int target_level_minor = target_seq_level_idx & 3;
|
||||
aom_internal_error(&cm->error, AOM_CODEC_ERROR,
|
||||
"Failed to encode to the target level %d_%d. %s",
|
||||
target_level_major, target_level_minor,
|
||||
level_fail_messages[fail_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aom_codec_err_t av1_get_seq_level_idx(const AV1_COMP *cpi, int *seq_level_idx) {
|
||||
const SequenceHeader *const seq_params = &cpi->common.seq_params;
|
||||
if (!cpi->keep_level_stats) {
|
||||
for (int op = 0; op < seq_params->operating_points_cnt_minus_1 + 1; ++op) {
|
||||
seq_level_idx[op] = (int)SEQ_LEVEL_MAX;
|
||||
}
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
const int is_still_picture = seq_params->still_picture;
|
||||
for (int op = 0; op < seq_params->operating_points_cnt_minus_1 + 1; ++op) {
|
||||
seq_level_idx[op] = (int)SEQ_LEVEL_MAX;
|
||||
const int tier = seq_params->tier[op];
|
||||
const AV1LevelInfo *const level_info = &cpi->level_info[op];
|
||||
const AV1LevelStats *const level_stats = &level_info->level_stats;
|
||||
const AV1LevelSpec *const level_spec = &level_info->level_spec;
|
||||
for (int level = 0; level < SEQ_LEVELS; ++level) {
|
||||
const AV1LevelSpec *const target_level_spec = av1_level_defs + level;
|
||||
const TARGET_LEVEL_FAIL_ID fail_id = check_level_constraints(
|
||||
target_level_spec, level_spec, level_stats, tier, is_still_picture);
|
||||
if (fail_id == TARGET_LEVEL_OK) {
|
||||
seq_level_idx[op] = level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AOM_CODEC_OK;
|
||||
}
|
||||
76
third_party/aom/av1/encoder/level.h
vendored
Normal file
76
third_party/aom/av1/encoder/level.h
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 AOM_AV1_ENCODER_LEVEL_H_
|
||||
#define AOM_AV1_ENCODER_LEVEL_H_
|
||||
|
||||
#include "av1/common/enums.h"
|
||||
|
||||
struct AV1_COMP;
|
||||
|
||||
// AV1 Level Specifications
|
||||
typedef struct {
|
||||
AV1_LEVEL level;
|
||||
int max_picture_size;
|
||||
int max_h_size;
|
||||
int max_v_size;
|
||||
int max_header_rate;
|
||||
int max_tiles;
|
||||
int max_tile_cols;
|
||||
int64_t max_display_rate;
|
||||
int64_t max_decode_rate;
|
||||
double main_mbps;
|
||||
double high_mbps;
|
||||
double main_cr;
|
||||
double high_cr;
|
||||
} AV1LevelSpec;
|
||||
|
||||
typedef struct {
|
||||
int64_t ts_start;
|
||||
int64_t ts_end;
|
||||
int pic_size;
|
||||
int frame_header_count;
|
||||
int show_frame;
|
||||
int show_existing_frame;
|
||||
} FrameRecord;
|
||||
|
||||
// Record frame info. in a rolling window.
|
||||
#define FRAME_WINDOW_SIZE 256
|
||||
typedef struct {
|
||||
FrameRecord buf[FRAME_WINDOW_SIZE];
|
||||
int num; // Number of FrameRecord stored in the buffer.
|
||||
int start; // Buffer index of the first FrameRecord.
|
||||
} FrameWindowBuffer;
|
||||
|
||||
// Used to keep track of AV1 Level Stats. Currently unimplemented.
|
||||
typedef struct {
|
||||
uint64_t total_compressed_size;
|
||||
int max_tile_size;
|
||||
int min_cropped_tile_width;
|
||||
int min_cropped_tile_height;
|
||||
int tile_width_is_valid;
|
||||
double total_time_encoded;
|
||||
double min_cr;
|
||||
} AV1LevelStats;
|
||||
|
||||
typedef struct {
|
||||
AV1LevelStats level_stats;
|
||||
AV1LevelSpec level_spec;
|
||||
} AV1LevelInfo;
|
||||
|
||||
void av1_update_level_info(struct AV1_COMP *cpi, size_t size, int64_t ts_start,
|
||||
int64_t ts_end);
|
||||
|
||||
// Return sequence level indices in seq_level_idx[MAX_NUM_OPERATING_POINTS].
|
||||
aom_codec_err_t av1_get_seq_level_idx(const struct AV1_COMP *cpi,
|
||||
int *seq_level_idx);
|
||||
|
||||
#endif // AOM_AV1_ENCODER_LEVEL_H_
|
||||
19
third_party/aom/av1/encoder/lookahead.c
vendored
19
third_party/aom/av1/encoder/lookahead.c
vendored
|
|
@ -44,7 +44,7 @@ void av1_lookahead_destroy(struct lookahead_ctx *ctx) {
|
|||
struct lookahead_ctx *av1_lookahead_init(
|
||||
unsigned int width, unsigned int height, unsigned int subsampling_x,
|
||||
unsigned int subsampling_y, int use_highbitdepth, unsigned int depth,
|
||||
const int border_in_pixels) {
|
||||
const int border_in_pixels, int is_scale) {
|
||||
struct lookahead_ctx *ctx = NULL;
|
||||
|
||||
// Clamp the lookahead queue depth
|
||||
|
|
@ -62,10 +62,19 @@ struct lookahead_ctx *av1_lookahead_init(
|
|||
ctx->buf = calloc(depth, sizeof(*ctx->buf));
|
||||
if (!ctx->buf) goto bail;
|
||||
for (i = 0; i < depth; i++)
|
||||
if (aom_alloc_frame_buffer(&ctx->buf[i].img, width, height, subsampling_x,
|
||||
subsampling_y, use_highbitdepth,
|
||||
border_in_pixels, legacy_byte_alignment))
|
||||
goto bail;
|
||||
if (is_scale) {
|
||||
if (aom_alloc_frame_buffer(
|
||||
&ctx->buf[i].img, width, height, subsampling_x, subsampling_y,
|
||||
use_highbitdepth, border_in_pixels, legacy_byte_alignment))
|
||||
goto bail;
|
||||
} else {
|
||||
aom_free_frame_buffer(&ctx->buf[i].img);
|
||||
if (aom_realloc_lookahead_buffer(
|
||||
&ctx->buf[i].img, width, height, subsampling_x, subsampling_y,
|
||||
use_highbitdepth, AOM_ENC_LOOKAHEAD_BORDER,
|
||||
legacy_byte_alignment, NULL, NULL, NULL))
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
bail:
|
||||
|
|
|
|||
2
third_party/aom/av1/encoder/lookahead.h
vendored
2
third_party/aom/av1/encoder/lookahead.h
vendored
|
|
@ -47,7 +47,7 @@ struct lookahead_ctx {
|
|||
struct lookahead_ctx *av1_lookahead_init(
|
||||
unsigned int width, unsigned int height, unsigned int subsampling_x,
|
||||
unsigned int subsampling_y, int use_highbitdepth, unsigned int depth,
|
||||
const int border_in_pixels);
|
||||
const int border_in_pixels, int is_scale);
|
||||
|
||||
/**\brief Destroys the lookahead stage
|
||||
*/
|
||||
|
|
|
|||
361
third_party/aom/av1/encoder/mcomp.c
vendored
361
third_party/aom/av1/encoder/mcomp.c
vendored
|
|
@ -19,6 +19,7 @@
|
|||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
#include "aom_ports/mem.h"
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
#include "av1/common/common.h"
|
||||
#include "av1/common/mvref_common.h"
|
||||
|
|
@ -28,6 +29,7 @@
|
|||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/encodemv.h"
|
||||
#include "av1/encoder/mcomp.h"
|
||||
#include "av1/encoder/partition_strategy.h"
|
||||
#include "av1/encoder/rdopt.h"
|
||||
#include "av1/encoder/reconinter_enc.h"
|
||||
|
||||
|
|
@ -1798,11 +1800,11 @@ static int full_pixel_diamond(const AV1_COMP *const cpi, MACROBLOCK *x,
|
|||
MV *mvp_full, int step_param, int sadpb,
|
||||
int further_steps, int do_refine, int *cost_list,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv) {
|
||||
const MV *ref_mv, const search_site_config *cfg) {
|
||||
MV temp_mv;
|
||||
int thissme, n, num00 = 0;
|
||||
int bestsme = cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, &temp_mv,
|
||||
step_param, sadpb, &n, fn_ptr, ref_mv);
|
||||
int bestsme = cpi->diamond_search_sad(x, cfg, mvp_full, &temp_mv, step_param,
|
||||
sadpb, &n, fn_ptr, ref_mv);
|
||||
if (bestsme < INT_MAX)
|
||||
bestsme = av1_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1);
|
||||
x->best_mv.as_mv = temp_mv;
|
||||
|
|
@ -1817,9 +1819,9 @@ static int full_pixel_diamond(const AV1_COMP *const cpi, MACROBLOCK *x,
|
|||
if (num00) {
|
||||
num00--;
|
||||
} else {
|
||||
thissme = cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, &temp_mv,
|
||||
step_param + n, sadpb, &num00, fn_ptr,
|
||||
ref_mv);
|
||||
thissme =
|
||||
cpi->diamond_search_sad(x, cfg, mvp_full, &temp_mv, step_param + n,
|
||||
sadpb, &num00, fn_ptr, ref_mv);
|
||||
if (thissme < INT_MAX)
|
||||
thissme = av1_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1);
|
||||
|
||||
|
|
@ -2095,11 +2097,222 @@ static int is_exhaustive_allowed(const AV1_COMP *const cpi, MACROBLOCK *x) {
|
|||
return is_allowed;
|
||||
}
|
||||
|
||||
static int vector_match(int16_t *ref, int16_t *src, int bwl) {
|
||||
int best_sad = INT_MAX;
|
||||
int this_sad;
|
||||
int d;
|
||||
int center, offset = 0;
|
||||
int bw = 4 << bwl; // redundant variable, to be changed in the experiments.
|
||||
for (d = 0; d <= bw; d += 16) {
|
||||
this_sad = aom_vector_var(&ref[d], src, bwl);
|
||||
if (this_sad < best_sad) {
|
||||
best_sad = this_sad;
|
||||
offset = d;
|
||||
}
|
||||
}
|
||||
center = offset;
|
||||
|
||||
for (d = -8; d <= 8; d += 16) {
|
||||
int this_pos = offset + d;
|
||||
// check limit
|
||||
if (this_pos < 0 || this_pos > bw) continue;
|
||||
this_sad = aom_vector_var(&ref[this_pos], src, bwl);
|
||||
if (this_sad < best_sad) {
|
||||
best_sad = this_sad;
|
||||
center = this_pos;
|
||||
}
|
||||
}
|
||||
offset = center;
|
||||
|
||||
for (d = -4; d <= 4; d += 8) {
|
||||
int this_pos = offset + d;
|
||||
// check limit
|
||||
if (this_pos < 0 || this_pos > bw) continue;
|
||||
this_sad = aom_vector_var(&ref[this_pos], src, bwl);
|
||||
if (this_sad < best_sad) {
|
||||
best_sad = this_sad;
|
||||
center = this_pos;
|
||||
}
|
||||
}
|
||||
offset = center;
|
||||
|
||||
for (d = -2; d <= 2; d += 4) {
|
||||
int this_pos = offset + d;
|
||||
// check limit
|
||||
if (this_pos < 0 || this_pos > bw) continue;
|
||||
this_sad = aom_vector_var(&ref[this_pos], src, bwl);
|
||||
if (this_sad < best_sad) {
|
||||
best_sad = this_sad;
|
||||
center = this_pos;
|
||||
}
|
||||
}
|
||||
offset = center;
|
||||
|
||||
for (d = -1; d <= 1; d += 2) {
|
||||
int this_pos = offset + d;
|
||||
// check limit
|
||||
if (this_pos < 0 || this_pos > bw) continue;
|
||||
this_sad = aom_vector_var(&ref[this_pos], src, bwl);
|
||||
if (this_sad < best_sad) {
|
||||
best_sad = this_sad;
|
||||
center = this_pos;
|
||||
}
|
||||
}
|
||||
|
||||
return (center - (bw >> 1));
|
||||
}
|
||||
|
||||
static const MV search_pos[4] = {
|
||||
{ -1, 0 },
|
||||
{ 0, -1 },
|
||||
{ 0, 1 },
|
||||
{ 1, 0 },
|
||||
};
|
||||
|
||||
unsigned int av1_int_pro_motion_estimation(const AV1_COMP *cpi, MACROBLOCK *x,
|
||||
BLOCK_SIZE bsize, int mi_row,
|
||||
int mi_col, const MV *ref_mv) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
MB_MODE_INFO *mi = xd->mi[0];
|
||||
struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
|
||||
DECLARE_ALIGNED(16, int16_t, hbuf[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, vbuf[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, src_hbuf[128]);
|
||||
DECLARE_ALIGNED(16, int16_t, src_vbuf[128]);
|
||||
int idx;
|
||||
const int bw = 4 << mi_size_wide_log2[bsize];
|
||||
const int bh = 4 << mi_size_high_log2[bsize];
|
||||
const int search_width = bw << 1;
|
||||
const int search_height = bh << 1;
|
||||
const int src_stride = x->plane[0].src.stride;
|
||||
const int ref_stride = xd->plane[0].pre[0].stride;
|
||||
uint8_t const *ref_buf, *src_buf;
|
||||
MV *tmp_mv = &xd->mi[0]->mv[0].as_mv;
|
||||
unsigned int best_sad, tmp_sad, this_sad[4];
|
||||
MV this_mv;
|
||||
const int norm_factor = 3 + (bw >> 5);
|
||||
const YV12_BUFFER_CONFIG *scaled_ref_frame =
|
||||
av1_get_scaled_ref_frame(cpi, mi->ref_frame[0]);
|
||||
MvLimits subpel_mv_limits;
|
||||
|
||||
if (scaled_ref_frame) {
|
||||
int i;
|
||||
// Swap out the reference frame for a version that's been scaled to
|
||||
// match the resolution of the current frame, allowing the existing
|
||||
// motion search code to be used without additional modifications.
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0];
|
||||
av1_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL,
|
||||
MAX_MB_PLANE);
|
||||
}
|
||||
|
||||
if (xd->bd != 8) {
|
||||
unsigned int sad;
|
||||
tmp_mv->row = 0;
|
||||
tmp_mv->col = 0;
|
||||
sad = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, src_stride,
|
||||
xd->plane[0].pre[0].buf, ref_stride);
|
||||
|
||||
if (scaled_ref_frame) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i];
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
// Set up prediction 1-D reference set
|
||||
ref_buf = xd->plane[0].pre[0].buf - (bw >> 1);
|
||||
for (idx = 0; idx < search_width; idx += 16) {
|
||||
aom_int_pro_row(&hbuf[idx], ref_buf, ref_stride, bh);
|
||||
ref_buf += 16;
|
||||
}
|
||||
|
||||
ref_buf = xd->plane[0].pre[0].buf - (bh >> 1) * ref_stride;
|
||||
for (idx = 0; idx < search_height; ++idx) {
|
||||
vbuf[idx] = aom_int_pro_col(ref_buf, bw) >> norm_factor;
|
||||
ref_buf += ref_stride;
|
||||
}
|
||||
|
||||
// Set up src 1-D reference set
|
||||
for (idx = 0; idx < bw; idx += 16) {
|
||||
src_buf = x->plane[0].src.buf + idx;
|
||||
aom_int_pro_row(&src_hbuf[idx], src_buf, src_stride, bh);
|
||||
}
|
||||
|
||||
src_buf = x->plane[0].src.buf;
|
||||
for (idx = 0; idx < bh; ++idx) {
|
||||
src_vbuf[idx] = aom_int_pro_col(src_buf, bw) >> norm_factor;
|
||||
src_buf += src_stride;
|
||||
}
|
||||
|
||||
// Find the best match per 1-D search
|
||||
tmp_mv->col = vector_match(hbuf, src_hbuf, mi_size_wide_log2[bsize]);
|
||||
tmp_mv->row = vector_match(vbuf, src_vbuf, mi_size_high_log2[bsize]);
|
||||
|
||||
this_mv = *tmp_mv;
|
||||
src_buf = x->plane[0].src.buf;
|
||||
ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
|
||||
best_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride);
|
||||
|
||||
{
|
||||
const uint8_t *const pos[4] = {
|
||||
ref_buf - ref_stride,
|
||||
ref_buf - 1,
|
||||
ref_buf + 1,
|
||||
ref_buf + ref_stride,
|
||||
};
|
||||
|
||||
cpi->fn_ptr[bsize].sdx4df(src_buf, src_stride, pos, ref_stride, this_sad);
|
||||
}
|
||||
|
||||
for (idx = 0; idx < 4; ++idx) {
|
||||
if (this_sad[idx] < best_sad) {
|
||||
best_sad = this_sad[idx];
|
||||
tmp_mv->row = search_pos[idx].row + this_mv.row;
|
||||
tmp_mv->col = search_pos[idx].col + this_mv.col;
|
||||
}
|
||||
}
|
||||
|
||||
if (this_sad[0] < this_sad[3])
|
||||
this_mv.row -= 1;
|
||||
else
|
||||
this_mv.row += 1;
|
||||
|
||||
if (this_sad[1] < this_sad[2])
|
||||
this_mv.col -= 1;
|
||||
else
|
||||
this_mv.col += 1;
|
||||
|
||||
ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
|
||||
|
||||
tmp_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride);
|
||||
if (best_sad > tmp_sad) {
|
||||
*tmp_mv = this_mv;
|
||||
best_sad = tmp_sad;
|
||||
}
|
||||
|
||||
tmp_mv->row *= 8;
|
||||
tmp_mv->col *= 8;
|
||||
|
||||
set_subpel_mv_search_range(
|
||||
&x->mv_limits, &subpel_mv_limits.col_min, &subpel_mv_limits.col_max,
|
||||
&subpel_mv_limits.row_min, &subpel_mv_limits.row_max, ref_mv);
|
||||
clamp_mv(tmp_mv, subpel_mv_limits.col_min, subpel_mv_limits.col_max,
|
||||
subpel_mv_limits.row_min, subpel_mv_limits.row_max);
|
||||
|
||||
if (scaled_ref_frame) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i];
|
||||
}
|
||||
|
||||
return best_sad;
|
||||
}
|
||||
|
||||
int av1_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
|
||||
MV *mvp_full, int step_param, int method,
|
||||
int run_mesh_search, int error_per_bit,
|
||||
int *cost_list, const MV *ref_mv, int var_max, int rd,
|
||||
int x_pos, int y_pos, int intra) {
|
||||
int x_pos, int y_pos, int intra,
|
||||
const search_site_config *cfg) {
|
||||
const SPEED_FEATURES *const sf = &cpi->sf;
|
||||
const aom_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize];
|
||||
int var = 0;
|
||||
|
|
@ -2139,7 +2352,7 @@ int av1_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
|
|||
case NSTEP:
|
||||
var = full_pixel_diamond(cpi, x, mvp_full, step_param, error_per_bit,
|
||||
MAX_MVSEARCH_STEPS - 1 - step_param, 1,
|
||||
cost_list, fn_ptr, ref_mv);
|
||||
cost_list, fn_ptr, ref_mv, cfg);
|
||||
|
||||
// Should we allow a follow on exhaustive search?
|
||||
if (is_exhaustive_allowed(cpi, x)) {
|
||||
|
|
@ -2676,14 +2889,15 @@ static int obmc_full_pixel_diamond(const AV1_COMP *cpi, MACROBLOCK *x,
|
|||
MV *mvp_full, int step_param, int sadpb,
|
||||
int further_steps, int do_refine,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv, MV *dst_mv,
|
||||
int is_second) {
|
||||
const MV *ref_mv, MV *dst_mv, int is_second,
|
||||
const search_site_config *cfg) {
|
||||
(void)cpi; // to silence compiler warning
|
||||
const int32_t *wsrc = x->wsrc_buf;
|
||||
const int32_t *mask = x->mask_buf;
|
||||
MV temp_mv;
|
||||
int thissme, n, num00 = 0;
|
||||
int bestsme =
|
||||
obmc_diamond_search_sad(x, &cpi->ss_cfg, wsrc, mask, mvp_full, &temp_mv,
|
||||
obmc_diamond_search_sad(x, cfg, wsrc, mask, mvp_full, &temp_mv,
|
||||
step_param, sadpb, &n, fn_ptr, ref_mv, is_second);
|
||||
if (bestsme < INT_MAX)
|
||||
bestsme = get_obmc_mvpred_var(x, wsrc, mask, &temp_mv, ref_mv, fn_ptr, 1,
|
||||
|
|
@ -2700,9 +2914,9 @@ static int obmc_full_pixel_diamond(const AV1_COMP *cpi, MACROBLOCK *x,
|
|||
if (num00) {
|
||||
num00--;
|
||||
} else {
|
||||
thissme = obmc_diamond_search_sad(x, &cpi->ss_cfg, wsrc, mask, mvp_full,
|
||||
&temp_mv, step_param + n, sadpb, &num00,
|
||||
fn_ptr, ref_mv, is_second);
|
||||
thissme = obmc_diamond_search_sad(x, cfg, wsrc, mask, mvp_full, &temp_mv,
|
||||
step_param + n, sadpb, &num00, fn_ptr,
|
||||
ref_mv, is_second);
|
||||
if (thissme < INT_MAX)
|
||||
thissme = get_obmc_mvpred_var(x, wsrc, mask, &temp_mv, ref_mv, fn_ptr,
|
||||
1, is_second);
|
||||
|
|
@ -2738,11 +2952,12 @@ int av1_obmc_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, MV *mvp_full,
|
|||
int step_param, int sadpb, int further_steps,
|
||||
int do_refine,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv, MV *dst_mv, int is_second) {
|
||||
const MV *ref_mv, MV *dst_mv, int is_second,
|
||||
const search_site_config *cfg) {
|
||||
if (cpi->sf.obmc_full_pixel_search_level == 0) {
|
||||
return obmc_full_pixel_diamond(cpi, x, mvp_full, step_param, sadpb,
|
||||
further_steps, do_refine, fn_ptr, ref_mv,
|
||||
dst_mv, is_second);
|
||||
dst_mv, is_second, cfg);
|
||||
} else {
|
||||
const int32_t *wsrc = x->wsrc_buf;
|
||||
const int32_t *mask = x->mask_buf;
|
||||
|
|
@ -2851,3 +3066,117 @@ int av1_return_min_sub_pixel_mv(
|
|||
lower_mv_precision(bestmv, allow_hp, 0);
|
||||
return besterr;
|
||||
}
|
||||
|
||||
void av1_simple_motion_search(AV1_COMP *const cpi, MACROBLOCK *x, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int ref,
|
||||
MV ref_mv_full, int num_planes,
|
||||
int use_subpixel) {
|
||||
assert(num_planes == 1 &&
|
||||
"Currently simple_motion_search only supports luma plane");
|
||||
assert(!frame_is_intra_only(&cpi->common) &&
|
||||
"Simple motion search only enabled for non-key frames");
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
|
||||
set_offsets_for_motion_search(cpi, x, mi_row, mi_col, bsize);
|
||||
|
||||
MB_MODE_INFO *mbmi = xd->mi[0];
|
||||
mbmi->sb_type = bsize;
|
||||
mbmi->ref_frame[0] = ref;
|
||||
mbmi->ref_frame[1] = NONE_FRAME;
|
||||
mbmi->motion_mode = SIMPLE_TRANSLATION;
|
||||
|
||||
const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, ref);
|
||||
const YV12_BUFFER_CONFIG *scaled_ref_frame =
|
||||
av1_get_scaled_ref_frame(cpi, ref);
|
||||
struct buf_2d backup_yv12;
|
||||
// ref_mv is used to code the motion vector. ref_mv_full is the initial point.
|
||||
// ref_mv is in units of 1/8 pel whereas ref_mv_full is in units of pel.
|
||||
MV ref_mv = { 0, 0 };
|
||||
const int step_param = cpi->mv_step_param;
|
||||
const MvLimits tmp_mv_limits = x->mv_limits;
|
||||
const SEARCH_METHODS search_methods = NSTEP;
|
||||
const int do_mesh_search = 0;
|
||||
const int sadpb = x->sadperbit16;
|
||||
int cost_list[5];
|
||||
const int ref_idx = 0;
|
||||
int var;
|
||||
|
||||
if (scaled_ref_frame) {
|
||||
backup_yv12 = xd->plane[AOM_PLANE_Y].pre[ref_idx];
|
||||
av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL,
|
||||
num_planes);
|
||||
} else {
|
||||
av1_setup_pre_planes(xd, ref_idx, yv12, mi_row, mi_col,
|
||||
get_ref_scale_factors(cm, ref), num_planes);
|
||||
}
|
||||
|
||||
// This overwrites the mv_limits so we will need to restore it later.
|
||||
av1_set_mv_search_range(&x->mv_limits, &ref_mv);
|
||||
var = av1_full_pixel_search(
|
||||
cpi, x, bsize, &ref_mv_full, step_param, search_methods, do_mesh_search,
|
||||
sadpb, cond_cost_list(cpi, cost_list), &ref_mv, INT_MAX, 1,
|
||||
mi_col * MI_SIZE, mi_row * MI_SIZE, 0, &cpi->ss_cfg[SS_CFG_SRC]);
|
||||
// Restore
|
||||
x->mv_limits = tmp_mv_limits;
|
||||
|
||||
const int use_subpel_search =
|
||||
var < INT_MAX && !cpi->common.cur_frame_force_integer_mv && use_subpixel;
|
||||
if (use_subpel_search) {
|
||||
int not_used = 0;
|
||||
if (cpi->sf.use_accurate_subpel_search) {
|
||||
const int pw = block_size_wide[bsize];
|
||||
const int ph = block_size_high[bsize];
|
||||
cpi->find_fractional_mv_step(
|
||||
x, cm, mi_row, mi_col, &ref_mv, cm->allow_high_precision_mv,
|
||||
x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
|
||||
cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
|
||||
x->nmv_vec_cost, x->mv_cost_stack, ¬_used, &x->pred_sse[ref], NULL,
|
||||
NULL, 0, 0, pw, ph, cpi->sf.use_accurate_subpel_search, 1);
|
||||
} else {
|
||||
cpi->find_fractional_mv_step(
|
||||
x, cm, mi_row, mi_col, &ref_mv, cm->allow_high_precision_mv,
|
||||
x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
|
||||
cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
|
||||
x->nmv_vec_cost, x->mv_cost_stack, ¬_used, &x->pred_sse[ref], NULL,
|
||||
NULL, 0, 0, 0, 0, 0, 1);
|
||||
}
|
||||
} else {
|
||||
// Manually convert from units of pixel to 1/8-pixels if we are not doing
|
||||
// subpel search
|
||||
x->best_mv.as_mv.row *= 8;
|
||||
x->best_mv.as_mv.col *= 8;
|
||||
}
|
||||
|
||||
mbmi->mv[0].as_mv = x->best_mv.as_mv;
|
||||
|
||||
// Get a copy of the prediction output
|
||||
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
||||
av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize,
|
||||
AOM_PLANE_Y, AOM_PLANE_Y);
|
||||
|
||||
aom_clear_system_state();
|
||||
|
||||
if (scaled_ref_frame) {
|
||||
xd->plane[AOM_PLANE_Y].pre[ref_idx] = backup_yv12;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_simple_motion_sse_var(AV1_COMP *cpi, MACROBLOCK *x, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize,
|
||||
const MV ref_mv_full, int use_subpixel,
|
||||
unsigned int *sse, unsigned int *var) {
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
const MV_REFERENCE_FRAME ref =
|
||||
cpi->rc.is_src_frame_alt_ref ? ALTREF_FRAME : LAST_FRAME;
|
||||
|
||||
av1_simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref, ref_mv_full, 1,
|
||||
use_subpixel);
|
||||
|
||||
const uint8_t *src = x->plane[0].src.buf;
|
||||
const int src_stride = x->plane[0].src.stride;
|
||||
const uint8_t *dst = xd->plane[0].dst.buf;
|
||||
const int dst_stride = xd->plane[0].dst.stride;
|
||||
|
||||
*var = cpi->fn_ptr[bsize].vf(src, src_stride, dst, dst_stride, sse);
|
||||
}
|
||||
|
|
|
|||
25
third_party/aom/av1/encoder/mcomp.h
vendored
25
third_party/aom/av1/encoder/mcomp.h
vendored
|
|
@ -13,6 +13,7 @@
|
|||
#define AOM_AV1_ENCODER_MCOMP_H_
|
||||
|
||||
#include "av1/encoder/block.h"
|
||||
|
||||
#include "aom_dsp/variance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -83,6 +84,11 @@ int av1_refining_search_sad(struct macroblock *x, MV *ref_mv, int sad_per_bit,
|
|||
int distance, const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *center_mv);
|
||||
|
||||
unsigned int av1_int_pro_motion_estimation(const struct AV1_COMP *cpi,
|
||||
MACROBLOCK *x, BLOCK_SIZE bsize,
|
||||
int mi_row, int mi_col,
|
||||
const MV *ref_mv);
|
||||
|
||||
// Runs sequence of diamond searches in smaller steps for RD.
|
||||
int av1_full_pixel_diamond(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
MV *mvp_full, int step_param, int sadpb,
|
||||
|
|
@ -132,13 +138,15 @@ int av1_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
|||
BLOCK_SIZE bsize, MV *mvp_full, int step_param,
|
||||
int method, int run_mesh_search, int error_per_bit,
|
||||
int *cost_list, const MV *ref_mv, int var_max, int rd,
|
||||
int x_pos, int y_pos, int intra);
|
||||
int x_pos, int y_pos, int intra,
|
||||
const search_site_config *cfg);
|
||||
|
||||
int av1_obmc_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
|
||||
MV *mvp_full, int step_param, int sadpb,
|
||||
int further_steps, int do_refine,
|
||||
const aom_variance_fn_ptr_t *fn_ptr,
|
||||
const MV *ref_mv, MV *dst_mv, int is_second);
|
||||
const MV *ref_mv, MV *dst_mv, int is_second,
|
||||
const search_site_config *cfg);
|
||||
int av1_find_best_obmc_sub_pixel_tree_up(
|
||||
MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col,
|
||||
MV *bestmv, const MV *ref_mv, int allow_hp, int error_per_bit,
|
||||
|
|
@ -154,6 +162,19 @@ unsigned int av1_refine_warped_mv(const struct AV1_COMP *cpi,
|
|||
int mi_row, int mi_col, int *pts0,
|
||||
int *pts_inref0, int total_samples);
|
||||
|
||||
// Performs a motion search in SIMPLE_TRANSLATION mode using reference frame
|
||||
// ref. Note that this sets the offset of mbmi, so we will need to reset it
|
||||
// after calling this function.
|
||||
void av1_simple_motion_search(struct AV1_COMP *const cpi, MACROBLOCK *x,
|
||||
int mi_row, int mi_col, BLOCK_SIZE bsize, int ref,
|
||||
MV ref_mv_full, int num_planes, int use_subpixel);
|
||||
|
||||
// Performs a simple motion search to calculate the sse and var of the residue
|
||||
void av1_simple_motion_sse_var(struct AV1_COMP *cpi, MACROBLOCK *x, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize,
|
||||
const MV ref_mv_full, int use_subpixel,
|
||||
unsigned int *sse, unsigned int *var);
|
||||
|
||||
static INLINE void av1_set_fractional_mv(int_mv *fractional_best_mv) {
|
||||
for (int z = 0; z < 3; z++) {
|
||||
fractional_best_mv[z].as_int = INVALID_MV;
|
||||
|
|
|
|||
2782
third_party/aom/av1/encoder/partition_model_weights.h
vendored
2782
third_party/aom/av1/encoder/partition_model_weights.h
vendored
File diff suppressed because it is too large
Load diff
722
third_party/aom/av1/encoder/partition_strategy.c
vendored
Normal file
722
third_party/aom/av1/encoder/partition_strategy.c
vendored
Normal file
|
|
@ -0,0 +1,722 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 <float.h>
|
||||
|
||||
#include "aom_ports/system_state.h"
|
||||
|
||||
#include "av1/common/enums.h"
|
||||
#include "av1/common/reconinter.h"
|
||||
|
||||
#include "av1/encoder/encoder.h"
|
||||
#include "av1/encoder/partition_model_weights.h"
|
||||
#include "av1/encoder/partition_strategy.h"
|
||||
#include "av1/encoder/rdopt.h"
|
||||
|
||||
// Performs a simple_motion_search with a single reference frame and extract
|
||||
// the variance of residues. Here features is assumed to be a length 6 array.
|
||||
// After this function is called, we will store the following in to features:
|
||||
// features[0] = log(1 + dc_q**2/256)
|
||||
// features[1] = log(1 + variance_of_residue)
|
||||
// for i in [2, 3, 4, 5]:
|
||||
// features[i] = log(1 + variance_of_residue_in_block[i]/variance_of_residue)
|
||||
static void get_res_var_features(AV1_COMP *const cpi, MACROBLOCK *x, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize,
|
||||
float *features) {
|
||||
// TODO(chiyotsai@google.com): The data this model trained on did not also use
|
||||
// SIMPLE_TRANSLATION to build the inter_predictor. Retraining and tuning the
|
||||
// model with the correct data should give better performance.
|
||||
assert(mi_size_wide[bsize] == mi_size_high[bsize]);
|
||||
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
|
||||
// Perform a single motion search in Y_PLANE to make a prediction
|
||||
const int use_subpixel = 0;
|
||||
|
||||
// Start getting the features
|
||||
int f_idx = 0;
|
||||
|
||||
// Q_INDEX
|
||||
const int dc_q = av1_dc_quant_QTX(x->qindex, 0, xd->bd) >> (xd->bd - 8);
|
||||
aom_clear_system_state();
|
||||
features[f_idx++] = logf(1.0f + (float)(dc_q * dc_q) / 256.0f);
|
||||
|
||||
// VARIANCE
|
||||
unsigned int sse = 0;
|
||||
unsigned int var = 0;
|
||||
const MV ref_mv_full = { .row = 0, .col = 0 };
|
||||
av1_simple_motion_sse_var(cpi, x, mi_row, mi_col, bsize, ref_mv_full,
|
||||
use_subpixel, &sse, &var);
|
||||
aom_clear_system_state();
|
||||
features[f_idx++] = logf(1.0f + (float)var);
|
||||
|
||||
// Regional
|
||||
const uint8_t *src = x->plane[0].src.buf;
|
||||
const int src_stride = x->plane[0].src.stride;
|
||||
const uint8_t *dst = xd->plane[0].dst.buf;
|
||||
const int dst_stride = xd->plane[0].dst.stride;
|
||||
const int bw = block_size_wide[bsize];
|
||||
const int bh = block_size_high[bsize];
|
||||
const BLOCK_SIZE subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
|
||||
int r_idx = 0;
|
||||
for (r_idx = 0; r_idx < 4; r_idx++) {
|
||||
const int x_idx = (r_idx & 1) * bw / 2;
|
||||
const int y_idx = (r_idx >> 1) * bh / 2;
|
||||
const int src_offset = y_idx * src_stride + x_idx;
|
||||
const int dst_offset = y_idx * dst_stride + x_idx;
|
||||
const unsigned int sub_var = cpi->fn_ptr[subsize].vf(
|
||||
src + src_offset, src_stride, dst + dst_offset, dst_stride, &sse);
|
||||
aom_clear_system_state();
|
||||
const float var_ratio = (1.0f + (float)sub_var) / (4.0f + (float)var);
|
||||
features[f_idx++] = var_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_simple_motion_search_based_split(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize, int *partition_none_allowed, int *partition_horz_allowed,
|
||||
int *partition_vert_allowed, int *do_rectangular_split,
|
||||
int *do_square_split) {
|
||||
const NN_CONFIG *nn_config = NULL;
|
||||
float split_only_thresh = 0.0f;
|
||||
if (bsize == BLOCK_128X128) {
|
||||
nn_config = &av1_simple_motion_search_based_split_nn_config_128;
|
||||
split_only_thresh = av1_simple_motion_search_based_split_thresh_128;
|
||||
} else if (bsize == BLOCK_64X64) {
|
||||
nn_config = &av1_simple_motion_search_based_split_nn_config_64;
|
||||
split_only_thresh = av1_simple_motion_search_based_split_thresh_64;
|
||||
} else if (bsize == BLOCK_32X32) {
|
||||
nn_config = &av1_simple_motion_search_based_split_nn_config_32;
|
||||
split_only_thresh = av1_simple_motion_search_based_split_thresh_32;
|
||||
} else if (bsize == BLOCK_16X16) {
|
||||
nn_config = &av1_simple_motion_search_based_split_nn_config_16;
|
||||
split_only_thresh = av1_simple_motion_search_based_split_thresh_16;
|
||||
} else if (bsize == BLOCK_8X8) {
|
||||
// Disable BLOCK_8X8 for now
|
||||
#if !CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8
|
||||
nn_config = &av1_simple_motion_search_based_split_nn_config_8;
|
||||
split_only_thresh = av1_simple_motion_search_based_split_thresh_8;
|
||||
#endif
|
||||
} else {
|
||||
assert(0 && "Unexpected block size in simple_motion_based_split");
|
||||
}
|
||||
if (nn_config) {
|
||||
float features[6] = { 0 };
|
||||
float score = 0;
|
||||
get_res_var_features(cpi, x, mi_row, mi_col, bsize, features);
|
||||
av1_nn_predict(features, nn_config, &score);
|
||||
|
||||
if (score > split_only_thresh) {
|
||||
*partition_none_allowed = 0;
|
||||
*partition_horz_allowed = 0;
|
||||
*partition_vert_allowed = 0;
|
||||
*do_rectangular_split = 0;
|
||||
}
|
||||
// TODO(Venkat): Experiment to skip only rectangular/extended parititions
|
||||
if (cpi->sf.simple_motion_search_split_only >= 2) {
|
||||
if (score < -split_only_thresh) *do_square_split = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given a list of ref frames in refs, performs simple_motion_search on each of
|
||||
// the refs and returns the ref with the smallest sse. Returns -1 if none of the
|
||||
// ref in the list is available. Also stores the best sse and var in best_sse,
|
||||
// best_var, respectively. If save_mv_code is -1, don't update mv_ref_fulls in
|
||||
// pc_tree. If save_mv_code is between 0 and 3, update mv_ref_fulls under
|
||||
// pc_tree->split[i]. If save_mv_code is 4, update mv_ref_fulls under pc_tree.
|
||||
static int simple_motion_search_get_best_ref(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, const int *const refs, int num_refs,
|
||||
int use_subpixel, int save_mv_code, unsigned int *best_sse,
|
||||
unsigned int *best_var) {
|
||||
// TODO(chiyotsai@google.com): The calculation of variance currently uses
|
||||
// bsize, so we might take area outside of the image into account. We need to
|
||||
// modify the SIMD functions to fix this later.
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
int best_ref = -1;
|
||||
|
||||
if (mi_col >= cm->mi_cols || mi_row >= cm->mi_rows) {
|
||||
// If the whole block is outside of the image, set the var and sse to 0.
|
||||
*best_var = 0;
|
||||
*best_sse = 0;
|
||||
|
||||
return best_ref;
|
||||
}
|
||||
|
||||
// Otherwise do loop through the reference frames and find the one with the
|
||||
// minimum SSE
|
||||
const MACROBLOCKD *xd = &x->e_mbd;
|
||||
const MV *mv_ref_fulls = pc_tree->mv_ref_fulls;
|
||||
|
||||
const int num_planes = 1;
|
||||
|
||||
*best_sse = INT_MAX;
|
||||
|
||||
for (int ref_idx = 0; ref_idx < num_refs; ref_idx++) {
|
||||
const int ref = refs[ref_idx];
|
||||
|
||||
if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref]) {
|
||||
unsigned int curr_sse = 0, curr_var = 0;
|
||||
av1_simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref,
|
||||
mv_ref_fulls[ref], num_planes, use_subpixel);
|
||||
curr_var = cpi->fn_ptr[bsize].vf(
|
||||
x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf,
|
||||
xd->plane[0].dst.stride, &curr_sse);
|
||||
if (curr_sse < *best_sse) {
|
||||
*best_sse = curr_sse;
|
||||
*best_var = curr_var;
|
||||
best_ref = ref;
|
||||
}
|
||||
|
||||
const int new_mv_row = x->best_mv.as_mv.row / 8;
|
||||
const int new_mv_col = x->best_mv.as_mv.col / 8;
|
||||
if (save_mv_code == 4) {
|
||||
pc_tree->mv_ref_fulls[ref].row = new_mv_row;
|
||||
pc_tree->mv_ref_fulls[ref].col = new_mv_col;
|
||||
} else if (save_mv_code >= 0 && save_mv_code < 4) {
|
||||
// Propagate the new motion vectors to a lower level
|
||||
pc_tree->split[save_mv_code]->mv_ref_fulls[ref].row = new_mv_row;
|
||||
pc_tree->split[save_mv_code]->mv_ref_fulls[ref].col = new_mv_col;
|
||||
} else {
|
||||
assert(save_mv_code == -1 &&
|
||||
"Unknown code in simple_motion_search_get_best_ref.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best_ref;
|
||||
}
|
||||
|
||||
// Performs fullpixel simple_motion_search with LAST_FRAME and ALTREF_FRAME on
|
||||
// each subblock and extract the variance and sse of residues. Then store the
|
||||
// var and sse from each partition subblock to features. The DC qindex is also
|
||||
// stored in features.
|
||||
// Here features is assumed to be a length 19 array.
|
||||
// After this function is called, we will store the following to features:
|
||||
// features[0:17] = var and sse from subblocks
|
||||
// features[18] = DC q_index
|
||||
static void simple_motion_search_prune_part_features(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, float *features) {
|
||||
// TODO(chiyotsai@google.com): Cache the result of the motion search from the
|
||||
// larger bsize.
|
||||
const int w_mi = mi_size_wide[bsize];
|
||||
const int h_mi = mi_size_high[bsize];
|
||||
int f_idx = 0;
|
||||
assert(mi_size_wide[bsize] == mi_size_high[bsize]);
|
||||
assert(cpi->ref_frame_flags & av1_ref_frame_flag_list[LAST_FRAME] ||
|
||||
cpi->ref_frame_flags & av1_ref_frame_flag_list[ALTREF_FRAME]);
|
||||
|
||||
// Setting up motion search
|
||||
const int ref_list[] = { LAST_FRAME, ALTREF_FRAME };
|
||||
const int num_refs = 2;
|
||||
const int use_subpixel = 1;
|
||||
|
||||
unsigned int int_features[FEATURE_SIZE_SMS_PRUNE_PART - 1];
|
||||
|
||||
// Doing whole block first to update the mv
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, mi_row, mi_col, bsize, ref_list, num_refs, use_subpixel,
|
||||
4, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
f_idx += 2;
|
||||
|
||||
// Split subblocks
|
||||
BLOCK_SIZE subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
|
||||
int r_idx = 0;
|
||||
for (r_idx = 0; r_idx < 4; r_idx++) {
|
||||
const int sub_mi_col = mi_col + (r_idx & 1) * w_mi / 2;
|
||||
const int sub_mi_row = mi_row + (r_idx >> 1) * h_mi / 2;
|
||||
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, sub_mi_row, sub_mi_col, subsize, ref_list, num_refs,
|
||||
use_subpixel, r_idx, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
f_idx += 2;
|
||||
}
|
||||
|
||||
// Horz subblocks
|
||||
subsize = get_partition_subsize(bsize, PARTITION_HORZ);
|
||||
for (r_idx = 0; r_idx < 2; r_idx++) {
|
||||
const int sub_mi_col = mi_col + 0;
|
||||
const int sub_mi_row = mi_row + r_idx * h_mi / 2;
|
||||
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, sub_mi_row, sub_mi_col, subsize, ref_list, num_refs,
|
||||
use_subpixel, -1, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
|
||||
f_idx += 2;
|
||||
}
|
||||
|
||||
// Vert subblock
|
||||
subsize = get_partition_subsize(bsize, PARTITION_VERT);
|
||||
for (r_idx = 0; r_idx < 2; r_idx++) {
|
||||
const int sub_mi_col = mi_col + r_idx * w_mi / 2;
|
||||
const int sub_mi_row = mi_row + 0;
|
||||
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, sub_mi_row, sub_mi_col, subsize, ref_list, num_refs,
|
||||
use_subpixel, -1, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
|
||||
f_idx += 2;
|
||||
}
|
||||
|
||||
aom_clear_system_state();
|
||||
for (int idx = 0; idx < f_idx; idx++) {
|
||||
features[idx] = logf(1.0f + (float)int_features[idx]);
|
||||
}
|
||||
|
||||
const MACROBLOCKD *xd = &x->e_mbd;
|
||||
set_offsets_for_motion_search(cpi, x, mi_row, mi_col, bsize);
|
||||
|
||||
// Q_INDEX
|
||||
const int dc_q = av1_dc_quant_QTX(x->qindex, 0, xd->bd) >> (xd->bd - 8);
|
||||
features[f_idx++] = logf(1.0f + (float)(dc_q * dc_q) / 256.0f);
|
||||
|
||||
// Neighbor stuff
|
||||
const int has_above = !!xd->above_mbmi;
|
||||
const int has_left = !!xd->left_mbmi;
|
||||
const BLOCK_SIZE above_bsize = has_above ? xd->above_mbmi->sb_type : bsize;
|
||||
const BLOCK_SIZE left_bsize = has_left ? xd->left_mbmi->sb_type : bsize;
|
||||
features[f_idx++] = (float)has_above;
|
||||
features[f_idx++] = (float)mi_size_wide_log2[above_bsize];
|
||||
features[f_idx++] = (float)mi_size_high_log2[above_bsize];
|
||||
features[f_idx++] = (float)has_left;
|
||||
features[f_idx++] = (float)mi_size_wide_log2[left_bsize];
|
||||
features[f_idx++] = (float)mi_size_high_log2[left_bsize];
|
||||
|
||||
assert(f_idx == FEATURE_SIZE_SMS_PRUNE_PART);
|
||||
}
|
||||
|
||||
void av1_simple_motion_search_prune_part(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int *partition_none_allowed,
|
||||
int *partition_horz_allowed, int *partition_vert_allowed,
|
||||
int *do_square_split, int *do_rectangular_split, int *prune_horz,
|
||||
int *prune_vert, float *features, int *valid) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
// Get model parameters
|
||||
const NN_CONFIG *nn_config = NULL;
|
||||
const float *prune_thresh = NULL, *only_thresh = NULL;
|
||||
const float *ml_mean = NULL, *ml_std = NULL;
|
||||
float normalized_features[FEATURE_SIZE_SMS_PRUNE_PART] = { 0.0f };
|
||||
|
||||
if (bsize == BLOCK_128X128) {
|
||||
nn_config = &av1_simple_motion_search_prune_part_nn_config_128;
|
||||
ml_mean = av1_simple_motion_search_prune_part_mean_128;
|
||||
ml_std = av1_simple_motion_search_prune_part_std_128;
|
||||
prune_thresh = av1_simple_motion_search_prune_part_prune_thresh_128;
|
||||
only_thresh = av1_simple_motion_search_prune_part_only_thresh_128;
|
||||
} else if (bsize == BLOCK_64X64) {
|
||||
nn_config = &av1_simple_motion_search_prune_part_nn_config_64;
|
||||
ml_mean = av1_simple_motion_search_prune_part_mean_64;
|
||||
ml_std = av1_simple_motion_search_prune_part_std_64;
|
||||
prune_thresh = av1_simple_motion_search_prune_part_prune_thresh_64;
|
||||
only_thresh = av1_simple_motion_search_prune_part_only_thresh_64;
|
||||
} else if (bsize == BLOCK_32X32) {
|
||||
nn_config = &av1_simple_motion_search_prune_part_nn_config_32;
|
||||
ml_mean = av1_simple_motion_search_prune_part_mean_32;
|
||||
ml_std = av1_simple_motion_search_prune_part_std_32;
|
||||
prune_thresh = av1_simple_motion_search_prune_part_prune_thresh_32;
|
||||
only_thresh = av1_simple_motion_search_prune_part_only_thresh_32;
|
||||
} else if (bsize == BLOCK_16X16) {
|
||||
nn_config = &av1_simple_motion_search_prune_part_nn_config_16;
|
||||
ml_mean = av1_simple_motion_search_prune_part_mean_16;
|
||||
ml_std = av1_simple_motion_search_prune_part_std_16;
|
||||
prune_thresh = av1_simple_motion_search_prune_part_prune_thresh_16;
|
||||
only_thresh = av1_simple_motion_search_prune_part_only_thresh_16;
|
||||
} else if (bsize == BLOCK_8X8) {
|
||||
nn_config = &av1_simple_motion_search_prune_part_nn_config_8;
|
||||
ml_mean = av1_simple_motion_search_prune_part_mean_8;
|
||||
ml_std = av1_simple_motion_search_prune_part_std_8;
|
||||
prune_thresh = av1_simple_motion_search_prune_part_prune_thresh_8;
|
||||
only_thresh = av1_simple_motion_search_prune_part_only_thresh_8;
|
||||
} else {
|
||||
assert(0 && "Unexpected block size in simple_motion_prune_part");
|
||||
}
|
||||
|
||||
// If there is no valid threshold, return immediately.
|
||||
if (!nn_config || (prune_thresh[PARTITION_HORZ] == 0.0f &&
|
||||
prune_thresh[PARTITION_VERT] == 0.0f)) {
|
||||
return;
|
||||
}
|
||||
if (bsize < BLOCK_8X8) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get features
|
||||
simple_motion_search_prune_part_features(cpi, x, pc_tree, mi_row, mi_col,
|
||||
bsize, features);
|
||||
*valid = 1;
|
||||
for (int f_idx = 0; f_idx < FEATURE_SIZE_SMS_PRUNE_PART; f_idx++) {
|
||||
normalized_features[f_idx] =
|
||||
(features[f_idx] - ml_mean[f_idx]) / ml_std[f_idx];
|
||||
}
|
||||
|
||||
// Get probabilities
|
||||
float scores[EXT_PARTITION_TYPES] = { 0.0f },
|
||||
probs[EXT_PARTITION_TYPES] = { 0.0f };
|
||||
const int num_classes = (bsize == BLOCK_128X128 || bsize == BLOCK_8X8)
|
||||
? PARTITION_TYPES
|
||||
: EXT_PARTITION_TYPES;
|
||||
|
||||
av1_nn_predict(normalized_features, nn_config, scores);
|
||||
aom_clear_system_state();
|
||||
|
||||
av1_nn_softmax(scores, probs, num_classes);
|
||||
|
||||
// Determine if we should prune rectangular partitions.
|
||||
if (cpi->sf.simple_motion_search_prune_rect && !frame_is_intra_only(cm) &&
|
||||
(*partition_horz_allowed || *partition_vert_allowed) &&
|
||||
bsize >= BLOCK_8X8 && !av1_superres_scaled(cm)) {
|
||||
*prune_horz = probs[PARTITION_HORZ] <= prune_thresh[PARTITION_HORZ];
|
||||
*prune_vert = probs[PARTITION_VERT] <= prune_thresh[PARTITION_VERT];
|
||||
}
|
||||
|
||||
// Silence compiler warnings
|
||||
(void)only_thresh;
|
||||
(void)partition_none_allowed;
|
||||
(void)do_square_split;
|
||||
(void)do_rectangular_split;
|
||||
}
|
||||
|
||||
// Early terminates PARTITION_NONE using simple_motion_search features and the
|
||||
// rate, distortion, and rdcost of PARTITION_NONE. This is only called when:
|
||||
// - The frame is a show frame
|
||||
// - The frame is not intra only
|
||||
// - The current bsize is > BLOCK_8X8
|
||||
// - blk_row + blk_height/2 < total_rows and blk_col + blk_width/2 < total_cols
|
||||
void av1_simple_motion_search_early_term_none(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, const RD_STATS *none_rdc,
|
||||
int *early_terminate, float *simple_motion_features,
|
||||
int *simple_motion_features_are_valid) {
|
||||
// TODO(chiyotsai@google.com): There are other features we can extract from
|
||||
// PARTITION_NONE. Play with this later.
|
||||
int f_idx = 0;
|
||||
if (!*simple_motion_features_are_valid) {
|
||||
simple_motion_search_prune_part_features(cpi, x, pc_tree, mi_row, mi_col,
|
||||
bsize, simple_motion_features);
|
||||
*simple_motion_features_are_valid = 1;
|
||||
}
|
||||
f_idx = 25;
|
||||
|
||||
simple_motion_features[f_idx++] = logf(1.0f + (float)none_rdc->rate);
|
||||
simple_motion_features[f_idx++] = logf(1.0f + (float)none_rdc->dist);
|
||||
simple_motion_features[f_idx++] = logf(1.0f + (float)none_rdc->rdcost);
|
||||
|
||||
assert(f_idx == FEATURE_SIZE_SMS_TERM_NONE);
|
||||
|
||||
const float *ml_mean = NULL;
|
||||
const float *ml_std = NULL;
|
||||
const float *ml_model = NULL;
|
||||
|
||||
if (bsize == BLOCK_128X128) {
|
||||
ml_mean = av1_simple_motion_search_term_none_mean_128;
|
||||
ml_std = av1_simple_motion_search_term_none_std_128;
|
||||
ml_model = av1_simple_motion_search_term_none_model_128;
|
||||
} else if (bsize == BLOCK_64X64) {
|
||||
ml_mean = av1_simple_motion_search_term_none_mean_64;
|
||||
ml_std = av1_simple_motion_search_term_none_std_64;
|
||||
ml_model = av1_simple_motion_search_term_none_model_64;
|
||||
} else if (bsize == BLOCK_32X32) {
|
||||
ml_mean = av1_simple_motion_search_term_none_mean_32;
|
||||
ml_std = av1_simple_motion_search_term_none_std_32;
|
||||
ml_model = av1_simple_motion_search_term_none_model_32;
|
||||
} else if (bsize == BLOCK_16X16) {
|
||||
ml_mean = av1_simple_motion_search_term_none_mean_16;
|
||||
ml_std = av1_simple_motion_search_term_none_std_16;
|
||||
ml_model = av1_simple_motion_search_term_none_model_16;
|
||||
} else {
|
||||
assert(0 && "Unexpected block size in simple_motion_term_none");
|
||||
}
|
||||
|
||||
if (ml_model) {
|
||||
float score = 0.0f;
|
||||
for (f_idx = 0; f_idx < FEATURE_SIZE_SMS_TERM_NONE; f_idx++) {
|
||||
score += ml_model[f_idx] *
|
||||
(simple_motion_features[f_idx] - ml_mean[f_idx]) / ml_std[f_idx];
|
||||
}
|
||||
score += ml_model[FEATURE_SIZE_SMS_TERM_NONE];
|
||||
|
||||
if (score >= 0.0f) {
|
||||
*early_terminate = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void firstpass_simple_motion_search_features(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, float *features) {
|
||||
assert(mi_size_wide[bsize] == mi_size_high[bsize]);
|
||||
assert(cpi->ref_frame_flags & av1_ref_frame_flag_list[LAST_FRAME] ||
|
||||
cpi->ref_frame_flags & av1_ref_frame_flag_list[ALTREF_FRAME]);
|
||||
|
||||
// Setting up motion search
|
||||
const int ref_list[] = { LAST_FRAME, ALTREF_FRAME };
|
||||
const int num_refs = 2;
|
||||
const int use_subpixel = 0;
|
||||
|
||||
unsigned int int_features[10] = { 0 };
|
||||
|
||||
int f_idx = 0;
|
||||
// Doing whole block first to update the mv
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, mi_row, mi_col, bsize, ref_list, num_refs, use_subpixel,
|
||||
4, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
f_idx += 2;
|
||||
|
||||
// Split subblocks
|
||||
const BLOCK_SIZE subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
|
||||
const int w_mi = mi_size_wide[bsize];
|
||||
const int h_mi = mi_size_high[bsize];
|
||||
for (int r_idx = 0; r_idx < 4; r_idx++) {
|
||||
const int sub_mi_col = mi_col + (r_idx & 1) * w_mi / 2;
|
||||
const int sub_mi_row = mi_row + (r_idx >> 1) * h_mi / 2;
|
||||
|
||||
simple_motion_search_get_best_ref(
|
||||
cpi, x, pc_tree, sub_mi_row, sub_mi_col, subsize, ref_list, num_refs,
|
||||
use_subpixel, r_idx, &int_features[f_idx], &int_features[f_idx + 1]);
|
||||
f_idx += 2;
|
||||
}
|
||||
|
||||
aom_clear_system_state();
|
||||
for (int idx = 0; idx < f_idx; idx++) {
|
||||
features[idx] = logf(1.0f + (float)int_features[idx]);
|
||||
}
|
||||
|
||||
const MACROBLOCKD *xd = &x->e_mbd;
|
||||
set_offsets_for_motion_search(cpi, x, mi_row, mi_col, bsize);
|
||||
|
||||
// Q_INDEX
|
||||
const int dc_q = av1_dc_quant_QTX(x->qindex, 0, xd->bd) >> (xd->bd - 8);
|
||||
features[f_idx++] = logf(1.0f + (float)(dc_q * dc_q) / 256.0f);
|
||||
|
||||
// Neighbor stuff
|
||||
const int has_above = !!xd->above_mbmi;
|
||||
const int has_left = !!xd->left_mbmi;
|
||||
const BLOCK_SIZE above_bsize = has_above ? xd->above_mbmi->sb_type : bsize;
|
||||
const BLOCK_SIZE left_bsize = has_left ? xd->left_mbmi->sb_type : bsize;
|
||||
features[f_idx++] = (float)has_above;
|
||||
features[f_idx++] = (float)mi_size_wide_log2[above_bsize];
|
||||
features[f_idx++] = (float)mi_size_high_log2[above_bsize];
|
||||
features[f_idx++] = (float)has_left;
|
||||
features[f_idx++] = (float)mi_size_wide_log2[left_bsize];
|
||||
features[f_idx++] = (float)mi_size_high_log2[left_bsize];
|
||||
}
|
||||
|
||||
void av1_firstpass_simple_motion_search_early_term(AV1_COMP *const cpi,
|
||||
MACROBLOCK *x,
|
||||
PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize,
|
||||
const RD_STATS *none_rdc,
|
||||
int *do_square_split) {
|
||||
const NN_CONFIG *nn_config = NULL;
|
||||
float thresh = 0.0f;
|
||||
const float *ml_mean = NULL, *ml_std = NULL;
|
||||
if (bsize == BLOCK_32X32) {
|
||||
nn_config = &av1_fp_simple_motion_search_term_none_nn_config_32;
|
||||
ml_mean = av1_fp_simple_motion_search_term_none_mean_32;
|
||||
ml_std = av1_fp_simple_motion_search_term_none_std_32;
|
||||
thresh = av1_fp_simple_motion_search_term_none_thresh_32;
|
||||
} else if (bsize == BLOCK_16X16) {
|
||||
nn_config = &av1_fp_simple_motion_search_term_none_nn_config_16;
|
||||
ml_mean = av1_fp_simple_motion_search_term_none_mean_16;
|
||||
ml_std = av1_fp_simple_motion_search_term_none_std_16;
|
||||
thresh = av1_fp_simple_motion_search_term_none_thresh_16;
|
||||
} else if (bsize == BLOCK_8X8) {
|
||||
nn_config = &av1_fp_simple_motion_search_term_none_nn_config_8;
|
||||
ml_mean = av1_fp_simple_motion_search_term_none_mean_8;
|
||||
ml_std = av1_fp_simple_motion_search_term_none_std_8;
|
||||
thresh = av1_fp_simple_motion_search_term_none_thresh_8;
|
||||
} else {
|
||||
assert(0 &&
|
||||
"Unexpected bsize in firstpass_simple_motion_search_early_term");
|
||||
return;
|
||||
}
|
||||
|
||||
float ml_features[FEATURE_SIZE_FP_SMS_TERM_NONE] = { 0.0f };
|
||||
|
||||
firstpass_simple_motion_search_features(cpi, x, pc_tree, mi_row, mi_col,
|
||||
bsize, ml_features);
|
||||
int f_idx = 17;
|
||||
|
||||
ml_features[f_idx++] = logf(1.0f + (float)none_rdc->rate);
|
||||
ml_features[f_idx++] = logf(1.0f + (float)none_rdc->dist);
|
||||
ml_features[f_idx++] = logf(1.0f + (float)none_rdc->rdcost);
|
||||
|
||||
for (f_idx = 0; f_idx < 20; f_idx++) {
|
||||
ml_features[f_idx] = (ml_features[f_idx] - ml_mean[f_idx]) / ml_std[f_idx];
|
||||
}
|
||||
|
||||
// Get probabilities
|
||||
float score = 0.0f;
|
||||
|
||||
av1_nn_predict(ml_features, nn_config, &score);
|
||||
aom_clear_system_state();
|
||||
|
||||
// Determine if we should prune square partitions.
|
||||
if (score < thresh) {
|
||||
*do_square_split = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void av1_get_max_min_partition_features(AV1_COMP *const cpi, MACROBLOCK *x,
|
||||
int mi_row, int mi_col,
|
||||
float *features) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
|
||||
|
||||
assert(sb_size == BLOCK_128X128);
|
||||
|
||||
int f_idx = 0;
|
||||
|
||||
const int dc_q = av1_dc_quant_QTX(x->qindex, 0, xd->bd) >> (xd->bd - 8);
|
||||
aom_clear_system_state();
|
||||
const float log_q_sq = logf(1.0f + (float)(dc_q * dc_q) / 256.0f);
|
||||
|
||||
// Perform full-pixel single motion search in Y plane of 16x16 mbs in the sb
|
||||
float sum_mv_row_sq = 0;
|
||||
float sum_mv_row = 0;
|
||||
float min_abs_mv_row = FLT_MAX;
|
||||
float max_abs_mv_row = 0;
|
||||
|
||||
float sum_mv_col_sq = 0;
|
||||
float sum_mv_col = 0;
|
||||
float min_abs_mv_col = FLT_MAX;
|
||||
float max_abs_mv_col = 0;
|
||||
|
||||
float sum_log_sse_sq = 0;
|
||||
float sum_log_sse = 0;
|
||||
float min_log_sse = FLT_MAX;
|
||||
float max_log_sse = 0;
|
||||
|
||||
const BLOCK_SIZE mb_size = BLOCK_16X16;
|
||||
const int mb_rows = block_size_high[sb_size] / block_size_high[mb_size];
|
||||
const int mb_cols = block_size_wide[sb_size] / block_size_wide[mb_size];
|
||||
const int mb_in_mi_size_high_log2 = mi_size_high_log2[mb_size];
|
||||
const int mb_in_mi_size_wide_log2 = mi_size_wide_log2[mb_size];
|
||||
|
||||
for (int mb_row = 0; mb_row < mb_rows; mb_row++)
|
||||
for (int mb_col = 0; mb_col < mb_cols; mb_col++) {
|
||||
const int this_mi_row = mi_row + (mb_row << mb_in_mi_size_high_log2);
|
||||
const int this_mi_col = mi_col + (mb_col << mb_in_mi_size_wide_log2);
|
||||
unsigned int sse = 0;
|
||||
unsigned int var = 0;
|
||||
const MV ref_mv_full = { .row = 0, .col = 0 };
|
||||
|
||||
av1_simple_motion_sse_var(cpi, x, this_mi_row, this_mi_col, mb_size,
|
||||
ref_mv_full, 0, &sse, &var);
|
||||
|
||||
aom_clear_system_state();
|
||||
const float mv_row = (float)(x->best_mv.as_mv.row / 8);
|
||||
const float mv_col = (float)(x->best_mv.as_mv.col / 8);
|
||||
const float log_sse = logf(1.0f + (float)sse);
|
||||
const float abs_mv_row = fabsf(mv_row);
|
||||
const float abs_mv_col = fabsf(mv_col);
|
||||
|
||||
sum_mv_row_sq += mv_row * mv_row;
|
||||
sum_mv_row += mv_row;
|
||||
sum_mv_col_sq += mv_col * mv_col;
|
||||
sum_mv_col += mv_col;
|
||||
|
||||
if (abs_mv_row < min_abs_mv_row) min_abs_mv_row = abs_mv_row;
|
||||
if (abs_mv_row > max_abs_mv_row) max_abs_mv_row = abs_mv_row;
|
||||
if (abs_mv_col < min_abs_mv_col) min_abs_mv_col = abs_mv_col;
|
||||
if (abs_mv_col > max_abs_mv_col) max_abs_mv_col = abs_mv_col;
|
||||
|
||||
sum_log_sse_sq += log_sse * log_sse;
|
||||
sum_log_sse += log_sse;
|
||||
if (log_sse < min_log_sse) min_log_sse = log_sse;
|
||||
if (log_sse > max_log_sse) max_log_sse = log_sse;
|
||||
}
|
||||
aom_clear_system_state();
|
||||
const float avg_mv_row = sum_mv_row / 64.0f;
|
||||
const float var_mv_row = sum_mv_row_sq / 64.0f - avg_mv_row * avg_mv_row;
|
||||
|
||||
const float avg_mv_col = sum_mv_col / 64.0f;
|
||||
const float var_mv_col = sum_mv_col_sq / 64.0f - avg_mv_col * avg_mv_col;
|
||||
|
||||
const float avg_log_sse = sum_log_sse / 64.0f;
|
||||
const float var_log_sse = sum_log_sse_sq / 64.0f - avg_log_sse * avg_log_sse;
|
||||
|
||||
features[f_idx++] = avg_log_sse;
|
||||
features[f_idx++] = avg_mv_col;
|
||||
features[f_idx++] = avg_mv_row;
|
||||
features[f_idx++] = log_q_sq;
|
||||
features[f_idx++] = max_abs_mv_col;
|
||||
features[f_idx++] = max_abs_mv_row;
|
||||
features[f_idx++] = max_log_sse;
|
||||
features[f_idx++] = min_abs_mv_col;
|
||||
features[f_idx++] = min_abs_mv_row;
|
||||
features[f_idx++] = min_log_sse;
|
||||
features[f_idx++] = var_log_sse;
|
||||
features[f_idx++] = var_mv_col;
|
||||
features[f_idx++] = var_mv_row;
|
||||
|
||||
assert(f_idx == FEATURE_SIZE_MAX_MIN_PART_PRED);
|
||||
}
|
||||
|
||||
BLOCK_SIZE av1_predict_max_partition(AV1_COMP *const cpi, MACROBLOCK *const x,
|
||||
const float *features) {
|
||||
float scores[MAX_NUM_CLASSES_MAX_MIN_PART_PRED] = { 0.0f },
|
||||
probs[MAX_NUM_CLASSES_MAX_MIN_PART_PRED] = { 0.0f };
|
||||
const NN_CONFIG *nn_config = &av1_max_part_pred_nn_config;
|
||||
|
||||
assert(cpi->sf.auto_max_partition_based_on_simple_motion != NOT_IN_USE);
|
||||
|
||||
aom_clear_system_state();
|
||||
av1_nn_predict(features, nn_config, scores);
|
||||
av1_nn_softmax(scores, probs, MAX_NUM_CLASSES_MAX_MIN_PART_PRED);
|
||||
|
||||
int result = MAX_NUM_CLASSES_MAX_MIN_PART_PRED - 1;
|
||||
if (cpi->sf.auto_max_partition_based_on_simple_motion == DIRECT_PRED) {
|
||||
result = 0;
|
||||
float max_prob = probs[0];
|
||||
for (int i = 1; i < MAX_NUM_CLASSES_MAX_MIN_PART_PRED; ++i) {
|
||||
if (probs[i] > max_prob) {
|
||||
max_prob = probs[i];
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
} else if (cpi->sf.auto_max_partition_based_on_simple_motion ==
|
||||
RELAXED_PRED) {
|
||||
for (result = MAX_NUM_CLASSES_MAX_MIN_PART_PRED - 1; result >= 0;
|
||||
--result) {
|
||||
if (result < MAX_NUM_CLASSES_MAX_MIN_PART_PRED - 1) {
|
||||
probs[result] += probs[result + 1];
|
||||
}
|
||||
if (probs[result] > 0.2) break;
|
||||
}
|
||||
} else if (cpi->sf.auto_max_partition_based_on_simple_motion == ADAPT_PRED) {
|
||||
const BLOCK_SIZE sb_size = cpi->common.seq_params.sb_size;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
// TODO(debargha): x->source_variance is unavailable at this point,
|
||||
// so compute. The redundant recomputation later can be removed.
|
||||
const unsigned int source_variance =
|
||||
is_cur_buf_hbd(xd)
|
||||
? av1_high_get_sby_perpixel_variance(cpi, &x->plane[0].src, sb_size,
|
||||
xd->bd)
|
||||
: av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, sb_size);
|
||||
if (source_variance > 16) {
|
||||
const double thresh = source_variance < 128 ? 0.05 : 0.1;
|
||||
for (result = MAX_NUM_CLASSES_MAX_MIN_PART_PRED - 1; result >= 0;
|
||||
--result) {
|
||||
if (result < MAX_NUM_CLASSES_MAX_MIN_PART_PRED - 1) {
|
||||
probs[result] += probs[result + 1];
|
||||
}
|
||||
if (probs[result] > thresh) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (BLOCK_SIZE)((result + 2) * 3);
|
||||
}
|
||||
154
third_party/aom/av1/encoder/partition_strategy.h
vendored
Normal file
154
third_party/aom/av1/encoder/partition_strategy.h
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 AOM_AV1_ENCODER_PARTITION_STRATEGY_H_
|
||||
#define AOM_AV1_ENCODER_PARTITION_STRATEGY_H_
|
||||
|
||||
#include "av1/encoder/encodeframe.h"
|
||||
#include "av1/encoder/encodemb.h"
|
||||
#include "av1/encoder/encoder.h"
|
||||
|
||||
#define FEATURE_SIZE_SMS_PRUNE_PART 25
|
||||
#define FEATURE_SIZE_SMS_TERM_NONE 28
|
||||
#define FEATURE_SIZE_FP_SMS_TERM_NONE 20
|
||||
#define FEATURE_SIZE_MAX_MIN_PART_PRED 13
|
||||
#define MAX_NUM_CLASSES_MAX_MIN_PART_PRED 4
|
||||
|
||||
// Performs a simple_motion_search with a single reference frame and extract
|
||||
// the variance of residues. Then use the features to determine whether we want
|
||||
// to go straight to splitting without trying PARTITION_NONE
|
||||
void av1_simple_motion_search_based_split(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize, int *partition_none_allowed, int *partition_horz_allowed,
|
||||
int *partition_vert_allowed, int *do_rectangular_split,
|
||||
int *do_square_split);
|
||||
|
||||
// Performs a simple_motion_search with two reference frames and extract
|
||||
// the variance of residues. Then use the features to determine whether we want
|
||||
// to prune some partitions.
|
||||
void av1_simple_motion_search_prune_part(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, int *partition_none_allowed,
|
||||
int *partition_horz_allowed, int *partition_vert_allowed,
|
||||
int *do_square_split, int *do_rectangular_split, int *prune_horz,
|
||||
int *prune_vert, float *features, int *valid);
|
||||
|
||||
// Early terminates PARTITION_NONE using simple_motion_search features and the
|
||||
// rate, distortion, and rdcost of PARTITION_NONE. This is only called when:
|
||||
// - The frame is a show frame
|
||||
// - The frame is not intra only
|
||||
// - The current bsize is > BLOCK_8X8
|
||||
// - blk_row + blk_height/2 < total_rows and blk_col + blk_width/2 < total_cols
|
||||
void av1_simple_motion_search_early_term_none(
|
||||
AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize, const RD_STATS *none_rdc,
|
||||
int *early_terminate, float *simple_motion_features,
|
||||
int *simple_motion_features_are_valid);
|
||||
|
||||
// Early terminates after PARTITION_NONE in firstpass of two pass partition
|
||||
// search.
|
||||
void av1_firstpass_simple_motion_search_early_term(AV1_COMP *const cpi,
|
||||
MACROBLOCK *x,
|
||||
PC_TREE *pc_tree, int mi_row,
|
||||
int mi_col, BLOCK_SIZE bsize,
|
||||
const RD_STATS *none_rdc,
|
||||
int *do_square_split);
|
||||
|
||||
// Get the features for selecting the max and min partition size. Currently this
|
||||
// performs simple_motion_search on 16X16 subblocks of the currnet superblock,
|
||||
// and then extract the statistics of sse and motion vectors as features.
|
||||
void av1_get_max_min_partition_features(AV1_COMP *const cpi, MACROBLOCK *x,
|
||||
int mi_row, int mi_col,
|
||||
float *features);
|
||||
|
||||
// Predict the maximum BLOCK_SIZE to be used to encoder the current superblock.
|
||||
BLOCK_SIZE av1_predict_max_partition(AV1_COMP *const cpi, MACROBLOCK *const x,
|
||||
const float *features);
|
||||
|
||||
// A simplified version of set_offsets meant to be used for
|
||||
// simple_motion_search.
|
||||
static INLINE void set_offsets_for_motion_search(const AV1_COMP *const cpi,
|
||||
MACROBLOCK *const x,
|
||||
int mi_row, int mi_col,
|
||||
BLOCK_SIZE bsize) {
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
const int num_planes = av1_num_planes(cm);
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const int mi_width = mi_size_wide[bsize];
|
||||
const int mi_height = mi_size_high[bsize];
|
||||
|
||||
set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
|
||||
|
||||
// Set up destination pointers.
|
||||
av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row, mi_col, 0,
|
||||
num_planes);
|
||||
|
||||
// Set up limit values for MV components.
|
||||
// Mv beyond the range do not produce new/different prediction block.
|
||||
x->mv_limits.row_min =
|
||||
-(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
|
||||
x->mv_limits.col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
|
||||
x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
|
||||
x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
|
||||
|
||||
set_plane_n4(xd, mi_width, mi_height, num_planes);
|
||||
|
||||
// Set up distance of MB to edge of frame in 1/8th pel units.
|
||||
assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
|
||||
xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
|
||||
xd->mb_to_bottom_edge = ((cm->mi_rows - mi_height - mi_row) * MI_SIZE) * 8;
|
||||
xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
|
||||
xd->mb_to_right_edge = ((cm->mi_cols - mi_width - mi_col) * MI_SIZE) * 8;
|
||||
|
||||
// Set up source buffers.
|
||||
av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, bsize);
|
||||
|
||||
// R/D setup.
|
||||
x->rdmult = cpi->rd.RDMULT;
|
||||
}
|
||||
|
||||
static INLINE void init_simple_motion_search_mvs(PC_TREE *pc_tree) {
|
||||
for (int idx = 0; idx < REF_FRAMES; idx++) {
|
||||
pc_tree->mv_ref_fulls[idx].row = 0;
|
||||
pc_tree->mv_ref_fulls[idx].col = 0;
|
||||
}
|
||||
if (pc_tree->block_size >= BLOCK_8X8) {
|
||||
init_simple_motion_search_mvs(pc_tree->split[0]);
|
||||
init_simple_motion_search_mvs(pc_tree->split[1]);
|
||||
init_simple_motion_search_mvs(pc_tree->split[2]);
|
||||
init_simple_motion_search_mvs(pc_tree->split[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE int is_full_sb(AV1_COMMON *const cm, int mi_row, int mi_col,
|
||||
BLOCK_SIZE sb_size) {
|
||||
const int sb_mi_wide = mi_size_wide[sb_size];
|
||||
const int sb_mi_high = mi_size_high[sb_size];
|
||||
|
||||
return (mi_row + sb_mi_high) <= cm->mi_rows &&
|
||||
(mi_col + sb_mi_wide) <= cm->mi_cols;
|
||||
}
|
||||
|
||||
static INLINE int use_auto_max_partition(AV1_COMP *const cpi,
|
||||
BLOCK_SIZE sb_size, int mi_row,
|
||||
int mi_col) {
|
||||
AV1_COMMON *const cm = &cpi->common;
|
||||
|
||||
return !frame_is_intra_only(cm) &&
|
||||
cpi->sf.auto_max_partition_based_on_simple_motion != NOT_IN_USE &&
|
||||
sb_size == BLOCK_128X128 && is_full_sb(cm, mi_row, mi_col, sb_size) &&
|
||||
cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index] !=
|
||||
OVERLAY_UPDATE &&
|
||||
cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index] !=
|
||||
INTNL_OVERLAY_UPDATE;
|
||||
}
|
||||
|
||||
#endif // AOM_AV1_ENCODER_PARTITION_STRATEGY_H_
|
||||
1787
third_party/aom/av1/encoder/pass2_strategy.c
vendored
Normal file
1787
third_party/aom/av1/encoder/pass2_strategy.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
34
third_party/aom/av1/encoder/pass2_strategy.h
vendored
Normal file
34
third_party/aom/av1/encoder/pass2_strategy.h
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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 AOM_AV1_ENCODER_PASS2_STRATEGY_H_
|
||||
#define AOM_AV1_ENCODER_PASS2_STRATEGY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct AV1_COMP;
|
||||
struct EncodeFrameParams;
|
||||
|
||||
void av1_init_second_pass(struct AV1_COMP *cpi);
|
||||
|
||||
void av1_get_second_pass_params(struct AV1_COMP *cpi,
|
||||
struct EncodeFrameParams *const frame_params,
|
||||
unsigned int frame_flags);
|
||||
|
||||
void av1_twopass_postencode_update(struct AV1_COMP *cpi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_AV1_ENCODER_PASS2_STRATEGY_H_
|
||||
14
third_party/aom/av1/encoder/picklpf.c
vendored
14
third_party/aom/av1/encoder/picklpf.c
vendored
|
|
@ -213,19 +213,25 @@ void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
|
|||
const int min_filter_level = 0;
|
||||
const int max_filter_level = av1_get_max_filter_level(cpi);
|
||||
const int q = av1_ac_quant_Q3(cm->base_qindex, 0, cm->seq_params.bit_depth);
|
||||
// based on tests result for rtc test set
|
||||
// 0.04590 boosted or 0.02295 non-booseted in 18-bit fixed point
|
||||
const int strength_boost_q_treshold = 700;
|
||||
const int inter_frame_multiplier =
|
||||
q > strength_boost_q_treshold ? 12034 : 6017;
|
||||
// These values were determined by linear fitting the result of the
|
||||
// searched level for 8 bit depth:
|
||||
// Keyframes: filt_guess = q * 0.06699 - 1.60817
|
||||
// Other frames: filt_guess = q * 0.02295 + 2.48225
|
||||
// Other frames: filt_guess = q * inter_frame_multiplier + 2.48225
|
||||
//
|
||||
// And high bit depth separately:
|
||||
// filt_guess = q * 0.316206 + 3.87252
|
||||
int filt_guess;
|
||||
switch (cm->seq_params.bit_depth) {
|
||||
case AOM_BITS_8:
|
||||
filt_guess = (cm->current_frame.frame_type == KEY_FRAME)
|
||||
? ROUND_POWER_OF_TWO(q * 17563 - 421574, 18)
|
||||
: ROUND_POWER_OF_TWO(q * 6017 + 650707, 18);
|
||||
filt_guess =
|
||||
(cm->current_frame.frame_type == KEY_FRAME)
|
||||
? ROUND_POWER_OF_TWO(q * 17563 - 421574, 18)
|
||||
: ROUND_POWER_OF_TWO(q * inter_frame_multiplier + 650707, 18);
|
||||
break;
|
||||
case AOM_BITS_10:
|
||||
filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 4060632, 20);
|
||||
|
|
|
|||
24
third_party/aom/av1/encoder/pickrst.c
vendored
24
third_party/aom/av1/encoder/pickrst.c
vendored
|
|
@ -1413,20 +1413,22 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) {
|
|||
RestorationType best_rtype = RESTORE_NONE;
|
||||
|
||||
const int highbd = rsc.cm->seq_params.use_highbitdepth;
|
||||
extend_frame(rsc.dgd_buffer, rsc.plane_width, rsc.plane_height,
|
||||
rsc.dgd_stride, RESTORATION_BORDER, RESTORATION_BORDER,
|
||||
highbd);
|
||||
if (!cpi->sf.disable_loop_restoration_chroma || !plane) {
|
||||
extend_frame(rsc.dgd_buffer, rsc.plane_width, rsc.plane_height,
|
||||
rsc.dgd_stride, RESTORATION_BORDER, RESTORATION_BORDER,
|
||||
highbd);
|
||||
|
||||
for (RestorationType r = 0; r < num_rtypes; ++r) {
|
||||
if ((force_restore_type != RESTORE_TYPES) && (r != RESTORE_NONE) &&
|
||||
(r != force_restore_type))
|
||||
continue;
|
||||
for (RestorationType r = 0; r < num_rtypes; ++r) {
|
||||
if ((force_restore_type != RESTORE_TYPES) && (r != RESTORE_NONE) &&
|
||||
(r != force_restore_type))
|
||||
continue;
|
||||
|
||||
double cost = search_rest_type(&rsc, r);
|
||||
double cost = search_rest_type(&rsc, r);
|
||||
|
||||
if (r == 0 || cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_rtype = r;
|
||||
if (r == 0 || cost < best_cost) {
|
||||
best_cost = cost;
|
||||
best_rtype = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue