Update aom to commit id f5bdeac22930ff4c6b219be49c843db35970b918

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

View file

@ -11,8 +11,9 @@
cmake_minimum_required(VERSION 3.5)
if (NOT EMSCRIPTEN)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE
"Build type: Debug, Release, RelWithDebInfo or MinSizeRel" STRING FORCE)
endif ()
endif ()
@ -20,6 +21,11 @@ option(ENABLE_CCACHE "Enable ccache support." OFF)
option(ENABLE_DISTCC "Enable distcc support." OFF)
option(ENABLE_DOCS "Enable documentation generation (doxygen required)." ON)
option(ENABLE_NASM "Use nasm instead of yasm for x86 assembly." OFF)
option(ENABLE_IDE_TEST_HOSTING
"Enables running tests within IDEs like Visual Studio and Xcode." OFF)
# $BUILD_SHARED_LIBS is a CMake built-in-- it's listed here for visibility.
option(BUILD_SHARED_LIBS "CMake should generate a shared library build." OFF)
project(AOM C CXX)
@ -34,7 +40,6 @@ if ("${AOM_ROOT}" STREQUAL "${AOM_CONFIG_DIR}")
endif ()
include("${AOM_ROOT}/build/cmake/aom_configure.cmake")
include("${AOM_ROOT}/build/cmake/aom_optimization.cmake")
include("${AOM_ROOT}/aom_dsp/aom_dsp.cmake")
include("${AOM_ROOT}/aom_mem/aom_mem.cmake")
include("${AOM_ROOT}/aom_ports/aom_ports.cmake")
@ -42,6 +47,7 @@ include("${AOM_ROOT}/aom_scale/aom_scale.cmake")
include("${AOM_ROOT}/aom_util/aom_util.cmake")
include("${AOM_ROOT}/av1/av1.cmake")
include("${AOM_ROOT}/test/test.cmake")
include("${AOM_ROOT}/build/cmake/util.cmake")
set(AOM_RTCD_SOURCES
"${AOM_CONFIG_DIR}/aom_dsp_rtcd.h"
@ -212,9 +218,9 @@ add_library(aom_common_app_util OBJECT ${AOM_COMMON_APP_UTIL_SOURCES})
if (CONFIG_AV1_DECODER)
add_library(aom_decoder_app_util OBJECT ${AOM_DECODER_APP_UTIL_SOURCES})
add_executable(aomdec
"${AOM_ROOT}/aomdec.c"
$<TARGET_OBJECTS:aom_common_app_util>
$<TARGET_OBJECTS:aom_decoder_app_util>)
"${AOM_ROOT}/aomdec.c"
$<TARGET_OBJECTS:aom_common_app_util>
$<TARGET_OBJECTS:aom_decoder_app_util>)
if (CONFIG_ANALYZER)
add_executable(analyzer
@ -223,6 +229,7 @@ if (CONFIG_AV1_DECODER)
$<TARGET_OBJECTS:aom_decoder_app_util>)
target_link_libraries(analyzer ${AOM_LIB_LINK_TYPE} ${wxWidgets_LIBRARIES})
set(AOM_APP_TARGETS ${AOM_APP_TARGETS} analyzer)
set(AOM_DECODER_EXAMPLE_TARGETS ${AOM_DECODER_EXAMPLE_TARGETS} analyzer)
endif ()
add_executable(decode_to_md5
@ -247,14 +254,17 @@ if (CONFIG_AV1_DECODER)
if (EMSCRIPTEN)
add_preproc_definition(_POSIX_SOURCE)
add_compiler_flag_if_supported("-s TOTAL_MEMORY=134217728")
add_compiler_flag_if_supported("-s MODULARIZE=1")
add_compiler_flag_if_supported("-s EXPORT_NAME=\"\'DecoderModule\'\"")
add_compiler_flag_if_supported("--memory-init-file 0")
append_link_flag_to_target("inspect" "-s TOTAL_MEMORY=134217728")
append_link_flag_to_target("inspect" "-s MODULARIZE=1")
append_link_flag_to_target("inspect"
"-s EXPORT_NAME=\"\'DecoderModule\'\"")
append_link_flag_to_target("inspect" "--memory-init-file 0")
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
# Default to -O3 when no build type specified.
add_compiler_flag_if_supported("-O3")
append_compiler_flag("-O3")
endif ()
em_link_post_js(inspect "${AOM_ROOT}/tools/inspect-post.js")
endif ()
endif ()
@ -324,7 +334,7 @@ if (CONFIG_LIBYUV)
# Add to existing targets.
foreach (aom_app ${AOM_APP_TARGETS})
target_sources(${aom_app} PUBLIC $<TARGET_OBJECTS:yuv>)
target_sources(${aom_app} PRIVATE $<TARGET_OBJECTS:yuv>)
set_property(TARGET ${aom_app} PROPERTY LINKER_LANGUAGE CXX)
endforeach ()
endif ()
@ -339,15 +349,15 @@ if (CONFIG_WEBM_IO)
# Add to existing targets.
if (CONFIG_AV1_DECODER)
target_sources(aom_decoder_app_util PUBLIC ${AOM_WEBM_DECODER_SOURCES})
target_sources(aom_decoder_app_util PRIVATE ${AOM_WEBM_DECODER_SOURCES})
endif ()
if (CONFIG_AV1_ENCODER)
target_sources(aom_encoder_app_util PUBLIC ${AOM_WEBM_ENCODER_SOURCES})
target_sources(aom_encoder_app_util PRIVATE ${AOM_WEBM_ENCODER_SOURCES})
endif ()
foreach (aom_app ${AOM_APP_TARGETS})
target_sources(${aom_app} PUBLIC $<TARGET_OBJECTS:webm>)
target_sources(${aom_app} PRIVATE $<TARGET_OBJECTS:webm>)
set_property(TARGET ${aom_app} PROPERTY LINKER_LANGUAGE CXX)
endforeach ()
endif ()
@ -374,11 +384,8 @@ if (XCODE)
# Note: LINKER_LANGUAGE is explicitly set to C++ for all targets touched
# here, it really is the Xcode generator's fault, or just a deficiency in
# Xcode itself.
set(XCODE_DUMMY_CXX_FILE "${AOM_CONFIG_DIR}/dummy.cc")
file(WRITE "${XCODE_DUMMY_CXX_FILE}"
"// Xcode needs a C++ file to link, ignore this file.")
foreach (aom_app ${AOM_APP_TARGETS})
target_sources(${aom_app} PUBLIC "${XCODE_DUMMY_CXX_FILE}")
add_dummy_source_file_to_target("${aom_app}" "cc")
endforeach ()
endif ()
endif ()
@ -391,6 +398,12 @@ if ("${CMAKE_GENERATOR}" MATCHES "Makefiles$" )
RUNTIME_OUTPUT_DIRECTORY "${AOM_CONFIG_DIR}/examples")
endif ()
if (BUILD_SHARED_LIBS)
include("${AOM_ROOT}/build/cmake/exports.cmake")
setup_exports_target()
set_target_properties(aom PROPERTIES SOVERSION 0)
endif ()
# Aomedia documentation rule.
if (ENABLE_DOCS)
include(FindDoxygen)

View file

@ -1,5 +1,9 @@
README - 9 March 2017
***************************
DEPRECATED -- SEE README.md
***************************
Welcome to the AV1 Codec SDK!
COMPILING THE APPLICATIONS/LIBRARIES:
@ -55,6 +59,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
armv7-none-rvct
armv7-win32-vs12
armv7-win32-vs14
armv7-win32-vs15
armv7s-darwin-gcc
mips32-linux-gcc
mips64-linux-gcc
@ -79,6 +84,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-win32-gcc
x86-win32-vs12
x86-win32-vs14
x86-win32-vs15
x86_64-android-gcc
x86_64-darwin9-gcc
x86_64-darwin10-gcc
@ -95,6 +101,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-win64-gcc
x86_64-win64-vs12
x86_64-win64-vs14
x86_64-win64-vs15
generic-gnu
The generic-gnu target, in conjunction with the CROSS environment variable,

307
third_party/aom/README.md vendored Normal file
View file

@ -0,0 +1,307 @@
# AV1 Codec Library
## Building the library and applications
### Prerequisites
1. [CMake](https://cmake.org) version 3.5 or higher.
2. [Git](https://git-scm.com/).
3. [Perl](https://www.perl.org/).
4. For x86 targets, [yasm](http://yasm.tortall.net/), which is preferred, or a
recent version of [nasm](http://www.nasm.us/).
5. Building the documentation requires [doxygen](http://doxygen.org).
6. Building the unit tests requires [Python](https://www.python.org/).
7. Emscripten builds require the portable
[EMSDK](https://kripken.github.io/emscripten-site/index.html).
### Basic build
CMake replaces the configure step typical of many projects. Running CMake will
produce configuration and build files for the currently selected CMake
generator. For most systems the default generator is Unix Makefiles. The basic
form of a makefile build is the following:
$ cmake path/to/aom
$ make
The above will generate a makefile build that produces the AV1 library and
applications for the current host system after the make step completes
successfully. The compiler chosen varies by host platform, but a general rule
applies: On systems where cc and c++ are present in $PATH at the time CMake is
run the generated build will use cc and c++ by default.
### Configuration options
The AV1 codec library has a great many configuration options. These come in two
varieties:
1. Build system configuration options. These have the form `ENABLE_FEATURE`.
2. AV1 codec configuration options. These have the form `CONFIG_FEATURE`.
Both types of options are set at the time CMake is run. The following example
enables ccache and disables high bit depth:
~~~
$ cmake path/to/aom -DENABLE_CCACHE=1 -DCONFIG_HIGHBITDEPTH=0
$ make
~~~
The available configuration options are too numerous to list here. Build system
configuration options can be found at the top of the CMakeLists.txt file found
in the root of the AV1 repository, and AV1 codec configuration options can
currently be found in the file `build/cmake/aom_config_defaults.cmake`.
### Dylib builds
A dylib (shared object) build of the AV1 codec library can be enabled via the
CMake built in variable `BUILD_SHARED_LIBS`:
~~~
$ cmake path/to/aom -DBUILD_SHARED_LIBS=1
$ make
~~~
This is currently only supported on non-Windows targets.
### Cross compiling
For the purposes of building the AV1 codec and applications and relative to the
scope of this guide, all builds for architectures differing from the native host
architecture will be considered cross compiles. The AV1 CMake build handles
cross compiling via the use of toolchain files included in the AV1 repository.
The toolchain files available at the time of this writing are:
- arm64-ios.cmake
- arm64-linux-gcc.cmake
- armv7-ios.cmake
- armv7-linux-gcc.cmake
- armv7s-ios.cmake
- mips32-linux-gcc.cmake
- mips64-linux-gcc.cmake
- x86-ios-simulator.cmake
- x86-linux.cmake
- x86-macos.cmake
- x86\_64-ios-simulator.cmake
The following example demonstrates use of the x86-macos.cmake toolchain file on
a x86\_64 MacOS host:
~~~
$ cmake path/to/aom \
-DCMAKE_TOOLCHAIN_FILE=path/to/aom/build/cmake/toolchains/x86-macos.cmake
$ make
~~~
To build for an unlisted target creation of a new toolchain file is the best
solution. The existing toolchain files can be used a starting point for a new
toolchain file since each one exposes the basic requirements for toolchain files
as used in the AV1 codec build.
As a temporary work around an unoptimized AV1 configuration that builds only C
and C++ sources can be produced using the following commands:
~~~
$ cmake path/to/aom -DAOM_TARGET_CPU=generic
$ make
~~~
In addition to the above it's important to note that the toolchain files
suffixed with gcc behave differently than the others. These toolchain files
attempt to obey the $CROSS environment variable.
### Microsoft Visual Studio builds
Building the AV1 codec library in Microsoft Visual Studio is supported. The
following example demonstrates generating projects and a solution for the
Microsoft IDE:
~~~
# This does not require a bash shell; command.exe is fine.
$ cmake path/to/aom -G "Visual Studio 15 2017"
~~~
### Xcode builds
Building the AV1 codec library in Xcode is supported. The following example
demonstrates generating an Xcode project:
~~~
$ cmake path/to/aom -G Xcode
~~~
### Emscripten builds
Building the AV1 codec library with Emscripten is supported. Typically this is
used to hook into the AOMAnalyzer GUI application. These instructions focus on
using the inspector with AOMAnalyzer, but all tools can be built with
Emscripten.
It is assumed here that you have already downloaded and installed the EMSDK,
installed and activated at least one toolchain, and setup your environment
appropriately using the emsdk\_env script.
1. Download [AOMAnalyzer](https://people.xiph.org/~mbebenita/analyzer/).
2. Configure the build:
~~~
$ cmake path/to/aom \
-DENABLE_CCACHE=1 \
-DAOM_TARGET_CPU=generic \
-DENABLE_DOCS=0 \
-DCONFIG_ACCOUNTING=1 \
-DCONFIG_INSPECTION=1 \
-DCONFIG_MULTITHREAD=0 \
-DCONFIG_RUNTIME_CPU_DETECT=0 \
-DCONFIG_UNIT_TESTS=0 \
-DCONFIG_WEBM_IO=0 \
-DCMAKE_TOOLCHAIN_FILE=path/to/emsdk-portable/.../Emscripten.cmake
~~~
3. Build it: run make if that's your generator of choice:
~~~
$ make inspect
~~~
4. Run the analyzer:
~~~
# inspect.js is in the examples sub directory of the directory in which you
# executed cmake.
$ path/to/AOMAnalyzer path/to/examples/inspect.js path/to/av1/input/file
~~~
## Testing the AV1 codec
### Testing basics
Currently there are two types of tests in the AV1 codec repository.
#### 1. Unit tests:
The unit tests can be run at build time:
~~~
# Before running the make command the LIBAOM_TEST_DATA_PATH environment
# variable should be set to avoid downloading the test files to the
# cmake build configuration directory.
$ cmake path/to/aom
# Note: The AV1 CMake build creates many test targets. Running make
# with multiple jobs will speed up the test run significantly.
$ make runtests
~~~
#### 2. Example tests:
The example tests require a bash shell and can be run in the following manner:
~~~
# See the note above about LIBAOM_TEST_DATA_PATH above.
$ cmake path/to/aom
$ make
# It's best to build the testdata target using many make jobs.
# Running it like this will verify and download (if necessary)
# one at a time, which takes a while.
$ make testdata
$ path/to/aom/test/examples.sh --bin-path examples
~~~
### IDE hosted tests
By default the generated projects files created by CMake will not include the
runtests and testdata rules when generating for IDEs like Microsoft Visual
Studio and Xcode. This is done to avoid intolerably long build cycles in the
IDEs-- IDE behavior is to build all targets when selecting the build project
options in MSVS and Xcode. To enable the test rules in IDEs the
`ENABLE_IDE_TEST_HOSTING` variable must be enabled at CMake generation time:
~~~
# This example uses Xcode. To get a list of the generators
# available, run cmake with the -G argument missing its
# value.
$ cmake path/to/aom -DENABLE_IDE_TEST_HOSTING=1 -G Xcode
~~~
### Downloading the test data
The fastest and easiest way to obtain the test data is to use CMake to generate
a build using the Unix Makefiles generator, and then to build only the testdata
rule:
~~~
$ cmake path/to/aom -G "Unix Makefiles"
# 28 is used because there are 28 test files as of this writing.
$ make -j28 testdata
~~~
The above make command will only download and verify the test data.
### Sharded testing
The AV1 codec library unit tests are built upon gtest which supports sharding of
test jobs. Sharded test runs can be achieved in a couple of ways.
#### 1. Running test\_libaom directly:
~~~
# Set the environment variable GTEST_TOTAL_SHARDS to 9 to run 10 test shards
# (GTEST shard indexing is 0 based).
$ export GTEST_TOTAL_SHARDS=9
$ for shard in $(seq 0 ${GTEST_TOTAL_SHARDS}); do \
[ ${shard} -lt ${GTEST_TOTAL_SHARDS} ] \
&& GTEST_SHARD_INDEX=${shard} ./test_libaom & \
done
~~~
To create a test shard for each CPU core available on the current system set
`GTEST_TOTAL_SHARDS` to the number of CPU cores on your system minus one.
#### 2. Running the tests via the CMake build:
~~~
# For IDE based builds, ENABLE_IDE_TEST_HOSTING must be enabled. See
# the IDE hosted tests section above for more information. If the IDE
# supports building targets concurrently tests will be sharded by default.
# For make and ninja builds the -j parameter controls the number of shards
# at test run time. This example will run the tests using 10 shards via
# make.
$ make -j10 runtests
~~~
The maximum number of test targets that can run concurrently is determined by
the number of CPUs on the system where the build is configured as detected by
CMake. A system with 24 cores can run 24 test shards using a value of 24 with
the `-j` parameter. When CMake is unable to detect the number of cores 10 shards
is the default maximum value.
## Coding style
The coding style used by this project is enforced with clang-format using the
configuration contained in the .clang-format file in the root of the repository.
Before pushing changes for review you can format your code with:
~~~
# Apply clang-format to modified .c, .h and .cc files
$ clang-format -i --style=file \
$(git diff --name-only --diff-filter=ACMR '*.[hc]' '*.cc')
~~~
Check the .clang-format file for the version used to generate it if there is any
difference between your local formatting and the review system.
See also: http://clang.llvm.org/docs/ClangFormat.html
## Support
This library is an open source project supported by its community. Please
please email aomediacodec@jointdevelopment.kavi.com for help.
## Bug reports
Bug reports can be filed in the Alliance for Open Media
[issue tracker](https://bugs.chromium.org/p/aomedia/issues/list).

View file

@ -107,7 +107,8 @@ typedef struct aom_codec_dec_cfg {
unsigned int threads; /**< Maximum number of threads to use, default 1 */
unsigned int w; /**< Width */
unsigned int h; /**< Height */
} aom_codec_dec_cfg_t; /**< alias for struct aom_codec_dec_cfg */
unsigned int allow_lowbitdepth; /**< Allow use of low-bitdepth coding path */
} aom_codec_dec_cfg_t; /**< alias for struct aom_codec_dec_cfg */
/*!\brief Initialize a decoder instance
*

View file

@ -363,44 +363,63 @@ typedef struct aom_codec_enc_cfg {
*/
unsigned int rc_dropframe_thresh;
/*!\brief Enable/disable spatial resampling, if supported by the codec.
/*!\brief Mode for spatial resampling, if supported by the codec.
*
* Spatial resampling allows the codec to compress a lower resolution
* version of the frame, which is then upscaled by the encoder to the
* version of the frame, which is then upscaled by the decoder to the
* correct presentation resolution. This increases visual quality at
* low data rates, at the expense of CPU time on the encoder/decoder.
*/
unsigned int rc_resize_allowed;
unsigned int rc_resize_mode;
/*!\brief Internal coded frame width.
/*!\brief Frame resize numerator.
*
* If spatial resampling is enabled this specifies the width of the
* encoded frame.
* The numerator for resize to use, assuming 16 as the denominator.
*
* Valid numerators are 8 - 16 for now.
*/
unsigned int rc_scaled_width;
unsigned int rc_resize_numerator;
/*!\brief Internal coded frame height.
/*!\brief Keyframe resize numerator.
*
* If spatial resampling is enabled this specifies the height of the
* encoded frame.
* The numerator for resize to use, assuming 16 as the denominator.
*
* Valid numerators are 8 - 16 for now.
*/
unsigned int rc_scaled_height;
unsigned int rc_resize_kf_numerator;
/*!\brief Spatial resampling up watermark.
/*!\brief Frame super-resolution scaling mode.
*
* This threshold is described as a percentage of the target data buffer.
* When the data buffer rises above this percentage of fullness, the
* encoder will step up to a higher resolution version of the frame.
* Similar to spatial resampling, frame super-resolution integrates
* 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, and mode 2 is
* SUPERRES_DYNAMIC.
*/
unsigned int rc_resize_up_thresh;
unsigned int rc_superres_mode;
/*!\brief Spatial resampling down watermark.
/*!\brief Frame super-resolution numerator.
*
* This threshold is described as a percentage of the target data buffer.
* When the data buffer falls below this percentage of fullness, the
* encoder will step down to a lower resolution version of the frame.
* The numerator for superres to use. If fixed it will only change if the
* cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling.
*
* Valid numerators are 8 to 16.
*
* Ignored by SUPERRES_DYNAMIC.
*/
unsigned int rc_resize_down_thresh;
unsigned int rc_superres_numerator;
/*!\brief Keyframe super-resolution numerator.
*
* The numerator for superres to use. If fixed it will only change if the
* cumulative scale change over resizing and superres is greater than 1/2;
* this forces superres to reduce scaling.
*
* Valid numerators are 8 - 16 for now.
*/
unsigned int rc_superres_kf_numerator;
/*!\brief Rate control algorithm to use.
*
@ -574,6 +593,14 @@ typedef struct aom_codec_enc_cfg {
* equal to kf_max_dist for a fixed interval.
*/
unsigned int kf_max_dist;
/*!\brief Tile coding mode
*
* This value indicates the tile coding mode.
* A value of 0 implies a normal non-large-scale tile coding. A value of 1
* implies a large-scale tile coding.
*/
unsigned int large_scale_tile;
} aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */
/*!\brief Initialize an encoder instance

View file

@ -35,6 +35,8 @@ extern "C" {
#define AOM_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel. */
#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
#include "./aom_config.h"
/*!\brief List of supported image formats */
typedef enum aom_img_fmt {
AOM_IMG_FMT_NONE,
@ -74,10 +76,28 @@ typedef enum aom_color_space {
AOM_CS_BT_709 = 2, /**< BT.709 */
AOM_CS_SMPTE_170 = 3, /**< SMPTE.170 */
AOM_CS_SMPTE_240 = 4, /**< SMPTE.240 */
AOM_CS_BT_2020 = 5, /**< BT.2020 */
AOM_CS_RESERVED = 6, /**< Reserved */
AOM_CS_SRGB = 7 /**< sRGB */
} aom_color_space_t; /**< alias for enum aom_color_space */
#if CONFIG_COLORSPACE_HEADERS
AOM_CS_BT_2020_NCL = 5, /**< BT.2020 non-constant luminance (BT.2100) */
AOM_CS_BT_2020_CL = 6, /**< BT.2020 constant luminance */
AOM_CS_SRGB = 7, /**< sRGB */
AOM_CS_ICTCP = 8, /**< ICtCp, ITU-R BT.2100 */
AOM_CS_RESERVED = 9 /**< Values 9..31 are reserved */
#else
AOM_CS_BT_2020 = 5, /**< BT.2020 */
AOM_CS_RESERVED = 6, /**< Reserved */
AOM_CS_SRGB = 7 /**< sRGB */
#endif
} aom_color_space_t; /**< alias for enum aom_color_space */
#if CONFIG_COLORSPACE_HEADERS
typedef enum aom_transfer_function {
AOM_TF_UNKNOWN = 0, /**< Unknown */
AOM_TF_BT_709 = 1, /**< BT.709 */
AOM_TF_PQ = 2, /**< PQ TF BT.2100 / ST.2084 */
AOM_TF_HLG = 3, /**< Hybrid Log-Gamma */
AOM_TF_RESERVED = 4 /**< Values 4..31 are reserved */
} aom_transfer_function_t; /**< alias for enum aom_transfer_function */
#endif
/*!\brief List of supported color range */
typedef enum aom_color_range {
@ -85,10 +105,24 @@ typedef enum aom_color_range {
AOM_CR_FULL_RANGE = 1 /**< YUV/RGB [0..255] */
} aom_color_range_t; /**< alias for enum aom_color_range */
#if CONFIG_COLORSPACE_HEADERS
typedef enum aom_chroma_sample_position {
AOM_CSP_UNKNOWN = 0, /**< Unknown */
AOM_CSP_VERTICAL = 1, /**< Horizontally co-located with luma(0, 0)*/
/**< sample, between two vertical samples */
AOM_CSP_COLOCATED = 2, /**< Co-located with luma(0, 0) sample */
AOM_CSP_RESERVED = 3 /**< Reserved value */
} aom_chroma_sample_position_t; /**< alias for enum aom_transfer_function */
#endif
/**\brief Image Descriptor */
typedef struct aom_image {
aom_img_fmt_t fmt; /**< Image Format */
aom_color_space_t cs; /**< Color Space */
aom_img_fmt_t fmt; /**< Image Format */
aom_color_space_t cs; /**< Color Space */
#if CONFIG_COLORSPACE_HEADERS
aom_transfer_function_t tf; /**< transfer function */
aom_chroma_sample_position_t csp; /**< chroma sample position */
#endif
aom_color_range_t range; /**< Color Range */
/* Image storage dimensions */

View file

@ -61,4 +61,6 @@ typedef size_t uintptr_t;
#include <inttypes.h>
#endif
#define NELEMENTS(x) (int)(sizeof(x) / sizeof(x[0]))
#endif // AOM_AOM_INTEGER_H_

View file

@ -327,18 +327,41 @@ enum aome_enc_control_id {
AV1E_SET_TUNE_CONTENT,
/*!\brief Codec control function to set color space info.
* \note Valid ranges: 0..7, default is "UNKNOWN".
* \note Valid ranges: 0..9, default is "UNKNOWN".
* 0 = UNKNOWN,
* 1 = BT_601
* 2 = BT_709
* 3 = SMPTE_170
* 4 = SMPTE_240
* 5 = BT_2020
* 6 = RESERVED
* 5 = BT_2020_NCL
* 6 = BT_2020_CL
* 7 = SRGB
* 8 = ICtCp
* 9 = RESERVED
*/
AV1E_SET_COLOR_SPACE,
#if CONFIG_COLORSPACE_HEADERS
/*!\brief Codec control function to set transfer function info.
* \note Valid ranges: 0..4, default is "UNKNOWN".
* 0 = UNKNOWN,
* 1 = BT_709
* 2 = PQ
* 3 = HLG
* 4 = RESERVED
*/
AV1E_SET_TRANSFER_FUNCTION,
/*!\brief Codec control function to set chroma 4:2:0 sample position info.
* \note Valid ranges: 0..3, default is "UNKNOWN".
* 0 = UNKNOWN,
* 1 = VERTICAL
* 2 = COLOCATED
* 3 = RESERVED
*/
AV1E_SET_CHROMA_SAMPLE_POSITION,
#endif
/*!\brief Codec control function to set minimum interval between GF/ARF frames
*
* By default the value is set as 4.
@ -515,14 +538,15 @@ enum aome_enc_control_id {
*/
AV1E_SET_DELTAQ_MODE,
/*!\brief Codec control function to set the tile encoding mode to 0 or 1.
/*!\brief Codec control function to set the single tile decoding mode to 0 or
* 1.
*
* 0 means that the tile encoding mode is TILE_NORMAL, and 1 means that the
* tile encoding mode is TILE_VR.
* 0 means that the single tile decoding is off, and 1 means that the single
* tile decoding is on.
*
* Experiment: EXT_TILE
*/
AV1E_SET_TILE_ENCODING_MODE,
AV1E_SET_SINGLE_TILE_DECODING,
/*!\brief Codec control function to enable the extreme motion vector unit test
* in AV1. Please note that this is only used in motion vector unit test.
@ -704,6 +728,14 @@ AOM_CTRL_USE_TYPE(AV1E_SET_TUNE_CONTENT, int) /* aom_tune_content */
AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_SPACE, int)
#define AOM_CTRL_AV1E_SET_COLOR_SPACE
#if CONFIG_COLORSPACE_HEADERS
AOM_CTRL_USE_TYPE(AV1E_SET_TRANSFER_FUNCTION, int)
#define AOM_CTRL_AV1E_SET_TRANSFER_FUNCTION
AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SAMPLE_POSITION, int)
#define AOM_CTRL_AV1E_SET_CHROMA_SAMPLE_POSITION
#endif
AOM_CTRL_USE_TYPE(AV1E_SET_MIN_GF_INTERVAL, unsigned int)
#define AOM_CTRL_AV1E_SET_MIN_GF_INTERVAL
@ -735,8 +767,8 @@ AOM_CTRL_USE_TYPE(AV1E_GET_LEVEL, int *)
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_SET_TILE_ENCODING_MODE, unsigned int)
#define AOM_CTRL_AV1E_SET_TILE_ENCODING_MODE
AOM_CTRL_USE_TYPE(AV1E_SET_SINGLE_TILE_DECODING, unsigned int)
#define AOM_CTRL_AV1E_SET_SINGLE_TILE_DECODING
AOM_CTRL_USE_TYPE(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
#define AOM_CTRL_AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST

View file

@ -41,6 +41,29 @@ static void convolve_horiz(const uint8_t *src, ptrdiff_t src_stride,
}
}
static void convolve_horiz_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *x_filters, int x0_qn,
int x_step_qn, int w, int h) {
int x, y;
src -= SUBPEL_TAPS / 2 - 1;
for (y = 0; y < h; ++y) {
int x_qn = x0_qn;
for (x = 0; x < w; ++x) {
const uint8_t *const src_x = &src[x_qn >> SCALE_SUBPEL_BITS]; // q8
const int x_filter_idx = (x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(x_filter_idx < SUBPEL_SHIFTS);
const int16_t *const x_filter = x_filters[x_filter_idx];
int k, sum = 0;
for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k];
dst[x] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
x_qn += x_step_qn;
}
src += src_stride;
dst += dst_stride;
}
}
static void convolve_avg_horiz(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *x_filters, int x0_q4,
@ -63,6 +86,30 @@ static void convolve_avg_horiz(const uint8_t *src, ptrdiff_t src_stride,
}
}
static void convolve_avg_horiz_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *x_filters, int x0_qn,
int x_step_qn, int w, int h) {
int x, y;
src -= SUBPEL_TAPS / 2 - 1;
for (y = 0; y < h; ++y) {
int x_qn = x0_qn;
for (x = 0; x < w; ++x) {
const uint8_t *const src_x = &src[x_qn >> SCALE_SUBPEL_BITS];
const int x_filter_idx = (x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS;
assert(x_filter_idx < SUBPEL_SHIFTS);
const int16_t *const x_filter = x_filters[x_filter_idx];
int k, sum = 0;
for (k = 0; k < SUBPEL_TAPS; ++k) sum += src_x[k] * x_filter[k];
dst[x] = ROUND_POWER_OF_TWO(
dst[x] + clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)), 1);
x_qn += x_step_qn;
}
src += src_stride;
dst += dst_stride;
}
}
static void convolve_vert(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *y_filters, int y0_q4,
@ -86,6 +133,31 @@ static void convolve_vert(const uint8_t *src, ptrdiff_t src_stride,
}
}
static void convolve_vert_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *y_filters, int y0_qn,
int y_step_qn, int w, int h) {
int x, y;
src -= src_stride * (SUBPEL_TAPS / 2 - 1);
for (x = 0; x < w; ++x) {
int y_qn = y0_qn;
for (y = 0; y < h; ++y) {
const unsigned char *src_y =
&src[(y_qn >> SCALE_SUBPEL_BITS) * src_stride];
const int16_t *const y_filter =
y_filters[(y_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS];
int k, sum = 0;
for (k = 0; k < SUBPEL_TAPS; ++k)
sum += src_y[k * src_stride] * y_filter[k];
dst[y * dst_stride] = clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS));
y_qn += y_step_qn;
}
++src;
++dst;
}
}
static void convolve_avg_vert(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *y_filters, int y0_q4,
@ -112,6 +184,34 @@ static void convolve_avg_vert(const uint8_t *src, ptrdiff_t src_stride,
}
}
static void convolve_avg_vert_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *y_filters, int y0_qn,
int y_step_qn, int w, int h) {
int x, y;
src -= src_stride * (SUBPEL_TAPS / 2 - 1);
for (x = 0; x < w; ++x) {
int y_qn = y0_qn;
for (y = 0; y < h; ++y) {
const unsigned char *src_y =
&src[(y_qn >> SCALE_SUBPEL_BITS) * src_stride];
const int16_t *const y_filter =
y_filters[(y_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS];
int k, sum = 0;
for (k = 0; k < SUBPEL_TAPS; ++k)
sum += src_y[k * src_stride] * y_filter[k];
dst[y * dst_stride] = ROUND_POWER_OF_TWO(
dst[y * dst_stride] +
clip_pixel(ROUND_POWER_OF_TWO(sum, FILTER_BITS)),
1);
y_qn += y_step_qn;
}
++src;
++dst;
}
}
static void convolve(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
ptrdiff_t dst_stride, const InterpKernel *const x_filters,
int x0_q4, int x_step_q4,
@ -146,6 +246,41 @@ static void convolve(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
dst_stride, y_filters, y0_q4, y_step_q4, w, h);
}
static void convolve_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const InterpKernel *const x_filters, int x0_qn,
int x_step_qn, const InterpKernel *const y_filters,
int y0_qn, int y_step_qn, int w, int h) {
// TODO(afergs): Update comment here
// Note: Fixed size intermediate buffer, temp, places limits on parameters.
// 2d filtering proceeds in 2 steps:
// (1) Interpolate horizontally into an intermediate buffer, temp.
// (2) Interpolate temp vertically to derive the sub-pixel result.
// Deriving the maximum number of rows in the temp buffer (135):
// --Smallest scaling factor is x1/2 ==> y_step_qn = 32 (Normative).
// --Largest block size is 64x64 pixels.
// --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the
// original frame (in 1/16th pixel units).
// --Must round-up because block may be located at sub-pixel position.
// --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails.
// --((64 - 1) * 32 + 15) >> 4 + 8 = 135.
uint8_t temp[MAX_EXT_SIZE * MAX_SB_SIZE];
int intermediate_height =
(((h - 1) * y_step_qn + y0_qn) >> SCALE_SUBPEL_BITS) + SUBPEL_TAPS;
assert(w <= MAX_SB_SIZE);
assert(h <= MAX_SB_SIZE);
assert(y_step_qn <= SCALE_SUBPEL_BITS * 2);
assert(x_step_qn <= SCALE_SUBPEL_BITS * 2);
convolve_horiz_scale_c(src - src_stride * (SUBPEL_TAPS / 2 - 1), src_stride,
temp, MAX_SB_SIZE, x_filters, x0_qn, x_step_qn, w,
intermediate_height);
convolve_vert_scale_c(temp + MAX_SB_SIZE * (SUBPEL_TAPS / 2 - 1), MAX_SB_SIZE,
dst, dst_stride, y_filters, y0_qn, y_step_qn, w, h);
}
static const InterpKernel *get_filter_base(const int16_t *filter) {
// NOTE: This assumes that the filter table is 256-byte aligned.
// TODO(agrange) Modify to make independent of table alignment.
@ -171,6 +306,21 @@ void aom_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
w, h);
}
void aom_convolve8_horiz_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x,
int x_step_qn, const int16_t *filter_y,
int subpel_y, int y_step_qn, int w, int h) {
const InterpKernel *const filters_x = get_filter_base(filter_x);
(void)subpel_y;
(void)filter_y;
(void)y_step_qn;
convolve_horiz_scale_c(src, src_stride, dst, dst_stride, filters_x, subpel_x,
x_step_qn, w, h);
}
void aom_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int x_step_q4,
@ -186,6 +336,22 @@ void aom_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride,
x_step_q4, w, h);
}
void aom_convolve8_avg_horiz_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x,
int x_step_qn, const int16_t *filter_y,
int subpel_y, int y_step_qn, int w,
int h) {
const InterpKernel *const filters_x = get_filter_base(filter_x);
(void)subpel_y;
(void)filter_y;
(void)y_step_qn;
convolve_avg_horiz_scale_c(src, src_stride, dst, dst_stride, filters_x,
subpel_x, x_step_qn, w, h);
}
void aom_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int x_step_q4,
@ -201,6 +367,21 @@ void aom_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride,
w, h);
}
void aom_convolve8_vert_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x,
int x_step_qn, const int16_t *filter_y,
int subpel_y, int y_step_qn, int w, int h) {
const InterpKernel *const filters_y = get_filter_base(filter_y);
(void)subpel_x;
(void)filter_x;
(void)x_step_qn;
convolve_vert_scale_c(src, src_stride, dst, dst_stride, filters_y, subpel_y,
y_step_qn, w, h);
}
void aom_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int x_step_q4,
@ -216,6 +397,21 @@ void aom_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride,
y_step_q4, w, h);
}
void aom_convolve8_avg_vert_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x,
int x_step_qn, const int16_t *filter_y,
int subpel_y, int y_step_qn, int w, int h) {
const InterpKernel *const filters_y = get_filter_base(filter_y);
(void)subpel_x;
(void)filter_x;
(void)x_step_qn;
convolve_avg_vert_scale_c(src, src_stride, dst, dst_stride, filters_y,
subpel_y, y_step_qn, w, h);
}
void aom_convolve8_c(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,
@ -230,6 +426,19 @@ void aom_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
filters_y, y0_q4, y_step_q4, w, h);
}
void aom_convolve8_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x, int x_step_qn,
const int16_t *filter_y, int subpel_y, int y_step_qn,
int w, int h) {
const InterpKernel *const filters_x = get_filter_base(filter_x);
const InterpKernel *const filters_y = get_filter_base(filter_y);
convolve_scale_c(src, src_stride, dst, dst_stride, filters_x, subpel_x,
x_step_qn, filters_y, subpel_y, y_step_qn, w, h);
}
void aom_convolve8_avg_c(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,
@ -245,6 +454,22 @@ void aom_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
h);
}
void aom_convolve8_avg_scale_c(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int subpel_x,
int x_step_qn, const int16_t *filter_y,
int subpel_y, int y_step_qn, int w, int h) {
/* Fixed size intermediate buffer places limits on parameters. */
DECLARE_ALIGNED(16, uint8_t, temp[MAX_SB_SIZE * MAX_SB_SIZE]);
assert(w <= MAX_SB_SIZE);
assert(h <= MAX_SB_SIZE);
aom_convolve8_scale_c(src, src_stride, temp, MAX_SB_SIZE, filter_x, subpel_x,
x_step_qn, filter_y, subpel_y, y_step_qn, w, h);
aom_convolve_avg_c(temp, MAX_SB_SIZE, dst, dst_stride, NULL, 0, NULL, 0, w,
h);
}
void aom_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
ptrdiff_t dst_stride, const int16_t *filter_x,
int filter_x_stride, const int16_t *filter_y,
@ -332,6 +557,7 @@ void aom_scaled_avg_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst,
filter_y, y_step_q4, w, h);
}
// TODO(afergs): Make sure this works too
#if CONFIG_LOOP_RESTORATION
static void convolve_add_src_horiz(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
@ -569,6 +795,7 @@ void aom_convolve8_add_src_hip_c(const uint8_t *src, ptrdiff_t src_stride,
}
#endif // CONFIG_LOOP_RESTORATION
// TODO(afergs): Make sure this works too
#if CONFIG_HIGHBITDEPTH
static void highbd_convolve_horiz(const uint8_t *src8, ptrdiff_t src_stride,
uint8_t *dst8, ptrdiff_t dst_stride,

View file

@ -287,6 +287,7 @@ if (CONFIG_AV1_ENCODER)
"${AOM_ROOT}/aom_dsp/x86/fwd_dct32x32_impl_avx2.h"
"${AOM_ROOT}/aom_dsp/x86/fwd_txfm_avx2.c"
"${AOM_ROOT}/aom_dsp/x86/fwd_txfm_avx2.h"
"${AOM_ROOT}/aom_dsp/x86/highbd_quantize_intrin_avx2.c"
"${AOM_ROOT}/aom_dsp/x86/sad4d_avx2.c"
"${AOM_ROOT}/aom_dsp/x86/sad_avx2.c"
"${AOM_ROOT}/aom_dsp/x86/sad_impl_avx2.c"
@ -312,6 +313,7 @@ if (CONFIG_AV1_ENCODER)
"${AOM_ROOT}/aom_dsp/x86/fwd_txfm_sse2.c"
"${AOM_ROOT}/aom_dsp/x86/fwd_txfm_sse2.h"
"${AOM_ROOT}/aom_dsp/x86/halfpix_variance_sse2.c"
"${AOM_ROOT}/aom_dsp/x86/highbd_quantize_intrin_sse2.c"
"${AOM_ROOT}/aom_dsp/x86/variance_sse2.c"
"${AOM_ROOT}/aom_dsp/x86/sum_squares_sse2.c")
@ -330,10 +332,16 @@ if (CONFIG_AV1_ENCODER)
"${AOM_ROOT}/aom_dsp/mips/variance_msa.c"
"${AOM_ROOT}/aom_dsp/mips/sub_pixel_variance_msa.c")
if (CONFIG_EXT_INTER)
set(AOM_DSP_ENCODER_INTRIN_SSSE3
${AOM_DSP_ENCODER_INTRIN_SSSE3}
"${AOM_ROOT}/aom_dsp/x86/masked_sad_intrin_ssse3.c"
"${AOM_ROOT}/aom_dsp/x86/masked_variance_intrin_ssse3.c")
endif ()
if (CONFIG_HIGHBITDEPTH)
set(AOM_DSP_ENCODER_INTRIN_SSE2
${AOM_DSP_ENCODER_INTRIN_SSE2}
"${AOM_ROOT}/aom_dsp/x86/highbd_quantize_intrin_sse2.c"
"${AOM_ROOT}/aom_dsp/x86/highbd_subtract_sse2.c")
endif ()
endif ()
@ -407,29 +415,38 @@ endif ()
# has been created.
function (setup_aom_dsp_targets)
add_library(aom_dsp_common OBJECT ${AOM_DSP_COMMON_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_dsp_common)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_dsp_common>)
list(APPEND AOM_LIB_TARGETS aom_dsp_common)
create_dummy_source_file("aom_av1" "c" "dummy_source_file")
add_library(aom_dsp OBJECT "${dummy_source_file}")
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_dsp_common>)
list(APPEND AOM_LIB_TARGETS aom_dsp)
# Not all generators support libraries consisting only of object files. Add a
# dummy source file to the aom_dsp target.
add_dummy_source_file_to_target("aom_dsp" "c")
if (CONFIG_AV1_DECODER)
add_library(aom_dsp_decoder OBJECT ${AOM_DSP_DECODER_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_dsp_decoder)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_dsp_decoder>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_dsp_decoder>)
endif ()
if (CONFIG_AV1_ENCODER)
add_library(aom_dsp_encoder OBJECT ${AOM_DSP_ENCODER_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_dsp_encoder)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_dsp_encoder>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_dsp_encoder>)
endif ()
if (HAVE_SSE2)
add_asm_library("aom_dsp_common_sse2" "AOM_DSP_COMMON_ASM_SSE2" "aom")
add_intrinsics_object_library("-msse2" "sse2" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_SSE2")
"AOM_DSP_COMMON_INTRIN_SSE2" "aom")
if (CONFIG_AV1_ENCODER)
add_asm_library("aom_dsp_encoder_sse2" "AOM_DSP_ENCODER_ASM_SSE2" "aom")
add_asm_library("aom_dsp_encoder_sse2" "AOM_DSP_ENCODER_ASM_SSE2"
"aom")
add_intrinsics_object_library("-msse2" "sse2" "aom_dsp_encoder"
"AOM_DSP_ENCODER_INTRIN_SSE2")
"AOM_DSP_ENCODER_INTRIN_SSE2" "aom")
endif()
endif ()
@ -440,7 +457,7 @@ function (setup_aom_dsp_targets)
if (HAVE_SSSE3)
add_asm_library("aom_dsp_common_ssse3" "AOM_DSP_COMMON_ASM_SSSE3" "aom")
add_intrinsics_object_library("-mssse3" "ssse3" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_SSSE3")
"AOM_DSP_COMMON_INTRIN_SSSE3" "aom")
if (CONFIG_AV1_ENCODER)
if ("${AOM_TARGET_CPU}" STREQUAL "x86_64")
@ -448,16 +465,20 @@ function (setup_aom_dsp_targets)
${AOM_DSP_ENCODER_ASM_SSSE3_X86_64})
endif ()
add_asm_library("aom_dsp_encoder_ssse3" "AOM_DSP_ENCODER_ASM_SSSE3" "aom")
if (AOM_DSP_ENCODER_INTRIN_SSSE3)
add_intrinsics_object_library("-mssse3" "ssse3" "aom_dsp_encoder"
"AOM_DSP_ENCODER_INTRIN_SSSE3" "aom")
endif ()
endif ()
endif ()
if (HAVE_SSE4_1)
add_intrinsics_object_library("-msse4.1" "sse4_1" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_SSE4_1")
"AOM_DSP_COMMON_INTRIN_SSE4_1" "aom")
if (CONFIG_AV1_ENCODER)
if (AOM_DSP_ENCODER_INTRIN_SSE4_1)
add_intrinsics_object_library("-msse4.1" "sse4_1" "aom_dsp_encoder"
"AOM_DSP_ENCODER_INTRIN_SSE4_1")
"AOM_DSP_ENCODER_INTRIN_SSE4_1" "aom")
endif ()
add_asm_library("aom_dsp_encoder_sse4_1" "AOM_DSP_ENCODER_ASM_SSE4_1"
"aom")
@ -473,10 +494,10 @@ function (setup_aom_dsp_targets)
if (HAVE_AVX2)
add_intrinsics_object_library("-mavx2" "avx2" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_AVX2")
"AOM_DSP_COMMON_INTRIN_AVX2" "aom")
if (CONFIG_AV1_ENCODER)
add_intrinsics_object_library("-mavx2" "avx2" "aom_dsp_encoder"
"AOM_DSP_ENCODER_INTRIN_AVX2")
"AOM_DSP_ENCODER_INTRIN_AVX2" "aom")
endif ()
endif ()
@ -490,20 +511,21 @@ function (setup_aom_dsp_targets)
if (HAVE_NEON)
add_intrinsics_object_library("${AOM_NEON_INTRIN_FLAG}" "neon"
"aom_dsp_common" "AOM_DSP_COMMON_INTRIN_NEON")
"aom_dsp_common" "AOM_DSP_COMMON_INTRIN_NEON"
"aom")
endif ()
if (HAVE_DSPR2)
add_intrinsics_object_library("" "dspr2" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_DSPR2")
"AOM_DSP_COMMON_INTRIN_DSPR2" "aom")
endif ()
if (HAVE_MSA)
add_intrinsics_object_library("" "msa" "aom_dsp_common"
"AOM_DSP_COMMON_INTRIN_MSA")
"AOM_DSP_COMMON_INTRIN_MSA" "aom")
if (CONFIG_AV1_ENCODER)
add_intrinsics_object_library("" "msa" "aom_dsp_encoder"
"AOM_DSP_ENCODER_INTRIN_MSA")
"AOM_DSP_ENCODER_INTRIN_MSA" "aom")
endif ()
endif ()

View file

@ -290,9 +290,10 @@ DSP_SRCS-yes += quantize.c
DSP_SRCS-yes += quantize.h
DSP_SRCS-$(HAVE_SSE2) += x86/quantize_sse2.c
ifeq ($(CONFIG_HIGHBITDEPTH),yes)
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_quantize_intrin_sse2.c
endif
DSP_SRCS-$(HAVE_AVX2) += x86/highbd_quantize_intrin_avx2.c
ifeq ($(ARCH_X86_64),yes)
DSP_SRCS-$(HAVE_SSSE3) += x86/quantize_ssse3_x86_64.asm
DSP_SRCS-$(HAVE_AVX) += x86/quantize_avx_x86_64.asm

View file

@ -31,8 +31,6 @@ extern "C" {
#define AOMMIN(x, y) (((x) < (y)) ? (x) : (y))
#define AOMMAX(x, y) (((x) > (y)) ? (x) : (y))
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
#define IMPLIES(a, b) (!(a) || (b)) // Logical 'a implies b' (or 'a -> b')
#define IS_POWER_OF_TWO(x) (((x) & ((x)-1)) == 0)
@ -54,16 +52,9 @@ extern "C" {
#define UNLIKELY(v) (v)
#endif
#define AOM_SWAP(type, a, b) \
do { \
type c = (b); \
b = a; \
a = c; \
} while (0)
#if CONFIG_AOM_QM
typedef uint16_t qm_val_t;
#define AOM_QM_BITS 6
#define AOM_QM_BITS 5
#endif
#if CONFIG_HIGHBITDEPTH
// Note:
@ -87,11 +78,14 @@ static INLINE int clamp(int value, int low, int high) {
return value < low ? low : (value > high ? high : value);
}
static INLINE int64_t clamp64(int64_t value, int64_t low, int64_t high) {
return value < low ? low : (value > high ? high : value);
}
static INLINE double fclamp(double value, double low, double high) {
return value < low ? low : (value > high ? high : value);
}
#if CONFIG_HIGHBITDEPTH
static INLINE uint16_t clip_pixel_highbd(int val, int bd) {
switch (bd) {
case 8:
@ -100,7 +94,6 @@ static INLINE uint16_t clip_pixel_highbd(int val, int bd) {
case 12: return (uint16_t)clamp(val, 0, 4095);
}
}
#endif // CONFIG_HIGHBITDEPTH
#ifdef __cplusplus
} // extern "C"

View file

@ -40,12 +40,26 @@ foreach $w (@block_widths) {
push @block_sizes, [$w, $h] if ($w <= 2*$h && $h <= 2*$w) ;
}
}
if (aom_config("CONFIG_EXT_PARTITION_TYPES")) {
push @block_sizes, [4, 16];
push @block_sizes, [16, 4];
push @block_sizes, [8, 32];
push @block_sizes, [32, 8];
}
@tx_dims = (2, 4, 8, 16, 32);
if (aom_config("CONFIG_TX64X64") eq "yes") {
push @tx_dims, '64';
}
@tx_sizes = ();
foreach $w (@tx_dims) {
push @tx_sizes, [$w, $w];
foreach $h (@tx_dims) {
push @tx_sizes, [$w, $h] if ($w >=4 && $h >=4 && ($w == 2*$h || $h == 2*$w));
}
}
@pred_names = qw/dc dc_top dc_left dc_128 v h d207e d63e d45e d117 d135 d153/;
if (aom_config("CONFIG_ALT_INTRA") eq "yes") {
push @pred_names, qw/paeth smooth/;
@ -60,9 +74,8 @@ if (aom_config("CONFIG_ALT_INTRA") eq "yes") {
# Intra prediction
#
foreach $dim (@tx_dims) {
$w = ${dim};
$h = ${dim};
foreach (@tx_sizes) {
($w, $h) = @$_;
foreach $pred_name (@pred_names) {
add_proto "void", "aom_${pred_name}_predictor_${w}x${h}",
"uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left";
@ -142,20 +155,27 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#
# Sub Pixel Filters
#
add_proto qw/void aom_convolve_copy/, "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";
add_proto qw/void aom_convolve_avg/, "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";
add_proto qw/void aom_convolve8/, "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";
add_proto qw/void aom_convolve8_horiz/, "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";
add_proto qw/void aom_convolve8_vert/, "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";
add_proto qw/void aom_convolve8_avg/, "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";
add_proto qw/void aom_convolve8_avg_horiz/, "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";
add_proto qw/void aom_convolve8_avg_vert/, "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";
add_proto qw/void aom_scaled_2d/, "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";
add_proto qw/void aom_scaled_horiz/, "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";
add_proto qw/void aom_scaled_vert/, "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";
add_proto qw/void aom_scaled_avg_2d/, "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";
add_proto qw/void aom_scaled_avg_horiz/, "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";
add_proto qw/void aom_scaled_avg_vert/, "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";
add_proto qw/void aom_convolve_copy/, "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";
add_proto qw/void aom_convolve_avg/, "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";
add_proto qw/void aom_convolve8/, "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";
add_proto qw/void aom_convolve8_horiz/, "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";
add_proto qw/void aom_convolve8_vert/, "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";
add_proto qw/void aom_convolve8_avg/, "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";
add_proto qw/void aom_convolve8_avg_horiz/, "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";
add_proto qw/void aom_convolve8_avg_vert/, "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";
add_proto qw/void aom_scaled_2d/, "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";
add_proto qw/void aom_scaled_horiz/, "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";
add_proto qw/void aom_scaled_vert/, "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";
add_proto qw/void aom_scaled_avg_2d/, "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";
add_proto qw/void aom_scaled_avg_horiz/, "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";
add_proto qw/void aom_scaled_avg_vert/, "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";
add_proto qw/void aom_convolve8_horiz_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
add_proto qw/void aom_convolve8_vert_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
add_proto qw/void aom_convolve8_avg_horiz_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
add_proto qw/void aom_convolve8_avg_vert_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
add_proto qw/void aom_convolve8_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
add_proto qw/void aom_convolve8_avg_scale/, "const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const int16_t *filter_x, int subpel_x, int x_step_q4, const int16_t *filter_y, int subpel_y, int y_step_q4, int w, int h";
specialize qw/aom_convolve_copy sse2 /;
specialize qw/aom_convolve_avg sse2 /;
@ -334,24 +354,15 @@ if ((aom_config("CONFIG_AV1_ENCODER") eq "yes") || (aom_config("CONFIG_PVQ") eq
add_proto qw/void aom_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct8x8 sse2/, "$ssse3_x86_64";
add_proto qw/void aom_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct8x8_1 sse2/;
add_proto qw/void aom_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct16x16 sse2/;
add_proto qw/void aom_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct16x16_1 sse2 avx2/;
add_proto qw/void aom_fdct32x32/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32 sse2 avx2/;
add_proto qw/void aom_fdct32x32_rd/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32_rd sse2 avx2/;
add_proto qw/void aom_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32_1 sse2 avx2/;
# High bit depth
add_proto qw/void aom_highbd_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_highbd_fdct4x4 sse2/;
@ -359,20 +370,15 @@ if ((aom_config("CONFIG_AV1_ENCODER") eq "yes") || (aom_config("CONFIG_PVQ") eq
add_proto qw/void aom_highbd_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_highbd_fdct8x8 sse2/;
add_proto qw/void aom_highbd_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
add_proto qw/void aom_highbd_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_highbd_fdct16x16 sse2/;
add_proto qw/void aom_highbd_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
add_proto qw/void aom_highbd_fdct32x32/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_highbd_fdct32x32 sse2/;
add_proto qw/void aom_highbd_fdct32x32_rd/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_highbd_fdct32x32_rd sse2/;
add_proto qw/void aom_highbd_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
} else {
add_proto qw/void aom_fdct4x4/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct4x4 sse2 msa/;
@ -383,47 +389,25 @@ if ((aom_config("CONFIG_AV1_ENCODER") eq "yes") || (aom_config("CONFIG_PVQ") eq
add_proto qw/void aom_fdct8x8/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct8x8 sse2 neon msa/, "$ssse3_x86_64";
add_proto qw/void aom_fdct8x8_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct8x8_1 sse2 neon msa/;
add_proto qw/void aom_fdct16x16/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct16x16 sse2 msa/;
add_proto qw/void aom_fdct16x16_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct16x16_1 sse2 avx2 msa/;
add_proto qw/void aom_fdct32x32/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32 sse2 avx2 msa/;
add_proto qw/void aom_fdct32x32_rd/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32_rd sse2 avx2 msa/;
add_proto qw/void aom_fdct32x32_1/, "const int16_t *input, tran_low_t *output, int stride";
specialize qw/aom_fdct32x32_1 sse2 avx2 msa/;
} # CONFIG_HIGHBITDEPTH
} # CONFIG_AV1_ENCODER
#
# Inverse transform
if (aom_config("CONFIG_AV1") eq "yes") {
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_iwht4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride";
add_proto qw/void aom_iwht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride";
specialize qw/aom_iwht4x4_16_add sse2/;
add_proto qw/void aom_highbd_idct4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_idct8x8_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_idct16x16_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_idct32x32_1024_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_idct32x32_34_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_idct32x32_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_iwht4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
add_proto qw/void aom_highbd_iwht4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
@ -469,10 +453,8 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_idct32x32_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride";
specialize qw/aom_idct32x32_1_add sse2 avx2/;
add_proto qw/void aom_highbd_idct4x4_16_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride, int bd";
specialize qw/aom_highbd_idct4x4_16_add sse2/;
}
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
} else {
{
add_proto qw/void aom_idct4x4_1_add/, "const tran_low_t *input, uint8_t *dest, int dest_stride";
@ -541,13 +523,12 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
add_proto qw/void aom_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
add_proto qw/void aom_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
add_proto qw/void aom_highbd_quantize_b_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
add_proto qw/void aom_highbd_quantize_b_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
add_proto qw/void aom_highbd_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
add_proto qw/void aom_highbd_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan, const qm_val_t * qm_ptr, const qm_val_t * iqm_ptr";
} # CONFIG_HIGHBITDEPTH
} # CONFIG_AV1_ENCODER
} else {
if (aom_config("CONFIG_AV1_ENCODER") eq "yes") {
@ -559,21 +540,23 @@ if (aom_config("CONFIG_AOM_QM") eq "yes") {
add_proto qw/void aom_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/aom_highbd_quantize_b sse2/;
add_proto qw/void aom_highbd_quantize_b/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/aom_highbd_quantize_b sse2 avx2/;
add_proto qw/void aom_highbd_quantize_b_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/aom_highbd_quantize_b_32x32 sse2/;
add_proto qw/void aom_highbd_quantize_b_32x32/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
specialize qw/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, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
add_proto qw/void aom_highbd_quantize_b_64x64/, "const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan";
} # CONFIG_HIGHBITDEPTH
} # CONFIG_AV1_ENCODER
} # CONFIG_AOM_QM
if (aom_config("CONFIG_AV1") eq "yes") {
#
# Alpha blending with mask
#
if (aom_config("CONFIG_CONVOLVE_ROUND") eq "yes") {
add_proto qw/void aom_blend_a64_d32_mask/, "int32_t *dst, uint32_t dst_stride, const int32_t *src0, uint32_t src0_stride, const int32_t *src1, uint32_t src1_stride, const uint8_t *mask, uint32_t mask_stride, int h, int w, int suby, int subx";
}
add_proto qw/void aom_blend_a64_mask/, "uint8_t *dst, uint32_t dst_stride, const uint8_t *src0, uint32_t src0_stride, const uint8_t *src1, uint32_t src1_stride, const uint8_t *mask, uint32_t mask_stride, int h, int w, int suby, int subx";
add_proto qw/void aom_blend_a64_hmask/, "uint8_t *dst, uint32_t dst_stride, const uint8_t *src0, uint32_t src0_stride, const uint8_t *src1, uint32_t src1_stride, const uint8_t *mask, int h, int w";
add_proto qw/void aom_blend_a64_vmask/, "uint8_t *dst, uint32_t dst_stride, const uint8_t *src0, uint32_t src0_stride, const uint8_t *src1, uint32_t src1_stride, const uint8_t *mask, int h, int w";
@ -927,15 +910,15 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
#
# ...
#
add_proto qw/void aom_upsampled_pred/, "uint8_t *comp_pred, int width, int height, const uint8_t *ref, int ref_stride";
add_proto qw/void aom_upsampled_pred/, "uint8_t *comp_pred, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref, int ref_stride";
specialize qw/aom_upsampled_pred sse2/;
add_proto qw/void aom_comp_avg_upsampled_pred/, "uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride";
add_proto qw/void aom_comp_avg_upsampled_pred/, "uint8_t *comp_pred, const uint8_t *pred, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref, int ref_stride";
specialize qw/aom_comp_avg_upsampled_pred sse2/;
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_highbd_upsampled_pred/, "uint16_t *comp_pred, int width, int height, const uint8_t *ref8, int ref_stride";
add_proto qw/void aom_highbd_upsampled_pred/, "uint16_t *comp_pred, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref8, int ref_stride, int bd";
specialize qw/aom_highbd_upsampled_pred sse2/;
add_proto qw/void aom_highbd_comp_avg_upsampled_pred/, "uint16_t *comp_pred, const uint8_t *pred8, int width, int height, const uint8_t *ref8, int ref_stride";
add_proto qw/void aom_highbd_comp_avg_upsampled_pred/, "uint16_t *comp_pred, const uint8_t *pred8, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref8, int ref_stride, int bd";
specialize qw/aom_highbd_comp_avg_upsampled_pred sse2/;
}
@ -1005,6 +988,22 @@ specialize qw/aom_sub_pixel_avg_variance8x8 msa sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance8x4 msa sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance4x8 msa sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance4x4 msa sse2 ssse3/;
if (aom_config("CONFIG_EXT_PARTITION_TYPES")) {
specialize qw/aom_variance4x16 sse2/;
specialize qw/aom_variance16x4 sse2/;
specialize qw/aom_variance8x32 sse2/;
specialize qw/aom_variance32x8 sse2/;
specialize qw/aom_sub_pixel_variance4x16 sse2 ssse3/;
specialize qw/aom_sub_pixel_variance16x4 sse2 ssse3/;
specialize qw/aom_sub_pixel_variance8x32 sse2 ssse3/;
specialize qw/aom_sub_pixel_variance32x8 sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance4x16 sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance16x4 sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance8x32 sse2 ssse3/;
specialize qw/aom_sub_pixel_avg_variance32x8 sse2 ssse3/;
}
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
foreach $bd (8, 10, 12) {
add_proto qw/unsigned int/, "aom_highbd_${bd}_variance2x2", "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse";
@ -1021,6 +1020,8 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
if ($w != 128 && $h != 128 && $w != 4 && $h != 4) {
specialize "aom_highbd_${bd}_variance${w}x${h}", "sse2";
}
# TODO(david.barker): When ext-partition-types is enabled, we currenly
# don't have vectorized 4x16 highbd variance functions
if ($w == 4 && $h == 4) {
specialize "aom_highbd_${bd}_variance${w}x${h}", "sse4_1";
}
@ -1496,10 +1497,10 @@ if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
if (aom_config("CONFIG_EXT_INTER") eq "yes") {
add_proto qw/void aom_comp_mask_pred/, "uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask";
add_proto qw/void aom_comp_mask_upsampled_pred/, "uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask";
add_proto qw/void aom_comp_mask_upsampled_pred/, "uint8_t *comp_pred, const uint8_t *pred, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask";
if (aom_config("CONFIG_HIGHBITDEPTH") eq "yes") {
add_proto qw/void aom_highbd_comp_mask_pred/, "uint16_t *comp_pred, const uint8_t *pred8, int width, int height, const uint8_t *ref8, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask";
add_proto qw/void aom_highbd_comp_mask_upsampled_pred/, "uint16_t *comp_pred, const uint8_t *pred8, int width, int height, const uint8_t *ref8, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask";
add_proto qw/void aom_highbd_comp_mask_upsampled_pred/, "uint16_t *comp_pred, const uint8_t *pred8, int width, int height, int subsample_x_q3, int subsample_y_q3, const uint8_t *ref8, int ref_stride, const uint8_t *mask, int mask_stride, int invert_mask, int bd";
}
}

View file

@ -25,6 +25,12 @@ extern "C" {
#define SUBPEL_SHIFTS (1 << SUBPEL_BITS)
#define SUBPEL_TAPS 8
#define SCALE_SUBPEL_BITS 10
#define SCALE_SUBPEL_SHIFTS (1 << SCALE_SUBPEL_BITS)
#define SCALE_SUBPEL_MASK (SCALE_SUBPEL_SHIFTS - 1)
#define SCALE_EXTRA_BITS (SCALE_SUBPEL_BITS - SUBPEL_BITS)
#define SCALE_EXTRA_OFF ((1 << SCALE_EXTRA_BITS) / 2)
typedef int16_t InterpKernel[SUBPEL_TAPS];
#define BIL_SUBPEL_BITS 3

View file

@ -194,9 +194,7 @@ static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
int nsymbs ACCT_STR_PARAM) {
int ret;
ret = aom_read_cdf(r, cdf, nsymbs, ACCT_STR_NAME);
#if CONFIG_EC_ADAPT
update_cdf(cdf, ret, nsymbs);
#endif
return ret;
}

View file

@ -140,9 +140,7 @@ static INLINE void aom_write_cdf(aom_writer *w, int symb,
static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf,
int nsymbs) {
aom_write_cdf(w, symb, cdf, nsymbs);
#if CONFIG_EC_ADAPT
update_cdf(cdf, symb, nsymbs);
#endif
}
static INLINE void aom_write_tree_as_cdf(aom_writer *w,

View file

@ -18,6 +18,69 @@
#include "./aom_dsp_rtcd.h"
#if CONFIG_CONVOLVE_ROUND
// Blending with alpha mask. Mask values come from the range [0, 64],
// as described for AOM_BLEND_A64 in aom_dsp/blend.h. src0 or src1 can
// be the same as dst, or dst can be different from both sources.
void aom_blend_a64_d32_mask_c(int32_t *dst, uint32_t dst_stride,
const int32_t *src0, uint32_t src0_stride,
const int32_t *src1, uint32_t src1_stride,
const uint8_t *mask, uint32_t mask_stride, int h,
int w, int subh, int subw) {
int i, j;
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
assert(h >= 1);
assert(w >= 1);
assert(IS_POWER_OF_TWO(h));
assert(IS_POWER_OF_TWO(w));
if (subw == 0 && subh == 0) {
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
const int m = mask[i * mask_stride + j];
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
src1[i * src1_stride + j]);
}
}
} else if (subw == 1 && subh == 1) {
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
const int m = ROUND_POWER_OF_TWO(
mask[(2 * i) * mask_stride + (2 * j)] +
mask[(2 * i + 1) * mask_stride + (2 * j)] +
mask[(2 * i) * mask_stride + (2 * j + 1)] +
mask[(2 * i + 1) * mask_stride + (2 * j + 1)],
2);
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
src1[i * src1_stride + j]);
}
}
} else if (subw == 1 && subh == 0) {
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
const int m = AOM_BLEND_AVG(mask[i * mask_stride + (2 * j)],
mask[i * mask_stride + (2 * j + 1)]);
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
src1[i * src1_stride + j]);
}
}
} else {
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
const int m = AOM_BLEND_AVG(mask[(2 * i) * mask_stride + j],
mask[(2 * i + 1) * mask_stride + j]);
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
src1[i * src1_stride + j]);
}
}
}
}
#endif // CONFIG_CONVOLVE_ROUND
// Blending with alpha mask. Mask values come from the range [0, 64],
// as described for AOM_BLEND_A64 in aom_dsp/blend.h. src0 or src1 can
// be the same as dst, or dst can be different from both sources.

View file

@ -172,15 +172,6 @@ void aom_fdct8x8_c(const int16_t *input, tran_low_t *final_output, int stride) {
}
}
void aom_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride) {
int r, c;
tran_low_t sum = 0;
for (r = 0; r < 8; ++r)
for (c = 0; c < 8; ++c) sum += input[r * stride + c];
output[0] = sum;
}
void aom_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
// The 2D transform is done with two passes which are actually pretty
// similar. In the first one, we transform the columns and transpose
@ -361,15 +352,6 @@ void aom_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
}
}
void aom_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride) {
int r, c;
int sum = 0;
for (r = 0; r < 16; ++r)
for (c = 0; c < 16; ++c) sum += input[r * stride + c];
output[0] = (tran_low_t)(sum >> 1);
}
static INLINE tran_high_t dct_32_round(tran_high_t input) {
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
// TODO(debargha, peter.derivaz): Find new bounds for this assert,
@ -758,15 +740,6 @@ void aom_fdct32x32_rd_c(const int16_t *input, tran_low_t *out, int stride) {
}
}
void aom_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride) {
int r, c;
int sum = 0;
for (r = 0; r < 32; ++r)
for (c = 0; c < 32; ++c) sum += input[r * stride + c];
output[0] = (tran_low_t)(sum >> 3);
}
#if CONFIG_HIGHBITDEPTH
void aom_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output,
int stride) {
@ -778,32 +751,17 @@ void aom_highbd_fdct8x8_c(const int16_t *input, tran_low_t *final_output,
aom_fdct8x8_c(input, final_output, stride);
}
void aom_highbd_fdct8x8_1_c(const int16_t *input, tran_low_t *final_output,
int stride) {
aom_fdct8x8_1_c(input, final_output, stride);
}
void aom_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output,
int stride) {
aom_fdct16x16_c(input, output, stride);
}
void aom_highbd_fdct16x16_1_c(const int16_t *input, tran_low_t *output,
int stride) {
aom_fdct16x16_1_c(input, output, stride);
}
void aom_highbd_fdct32x32_c(const int16_t *input, tran_low_t *out, int stride) {
aom_fdct32x32_c(input, out, stride);
}
void aom_highbd_fdct32x32_rd_c(const int16_t *input, tran_low_t *out,
int stride) {
aom_fdct32x32_rd_c(input, out, stride);
}
void aom_highbd_fdct32x32_1_c(const int16_t *input, tran_low_t *out,
int stride) {
aom_fdct32x32_1_c(input, out, stride);
}
#endif // CONFIG_HIGHBITDEPTH

View file

@ -20,10 +20,5 @@ static INLINE tran_high_t saturate_int16(tran_high_t value) {
return result < INT16_MIN ? INT16_MIN : result;
}
static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
return rv;
}
void aom_fdct32(const tran_high_t *input, tran_high_t *output, int round);
#endif // AOM_DSP_FWD_TXFM_H_

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -23,8 +23,7 @@ extern "C" {
#endif
static INLINE tran_high_t dct_const_round_shift(tran_high_t input) {
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
return rv;
return ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
}
static INLINE tran_high_t check_range(tran_high_t input, int bd) {
@ -51,9 +50,19 @@ static INLINE tran_high_t check_range(tran_high_t input, int bd) {
}
#define WRAPLOW(x) ((int32_t)check_range(x, 8))
#if CONFIG_HIGHBITDEPTH
#define HIGHBD_WRAPLOW(x, bd) ((int32_t)check_range((x), bd))
#endif // CONFIG_HIGHBITDEPTH
#if CONFIG_MRC_TX
// These each perform dct but add coefficients based on a mask
void aom_imrc32x32_1024_add_c(const tran_low_t *input, uint8_t *dest,
int stride, int *mask);
void aom_imrc32x32_135_add_c(const tran_low_t *input, uint8_t *dest, int stride,
int *mask);
void aom_imrc32x32_34_add_c(const tran_low_t *input, uint8_t *dest, int stride,
int *mask);
#endif // CONFIG_MRC_TX
void aom_idct4_c(const tran_low_t *input, tran_low_t *output);
void aom_idct8_c(const tran_low_t *input, tran_low_t *output);
@ -63,7 +72,6 @@ void aom_iadst4_c(const tran_low_t *input, tran_low_t *output);
void aom_iadst8_c(const tran_low_t *input, tran_low_t *output);
void aom_iadst16_c(const tran_low_t *input, tran_low_t *output);
#if CONFIG_HIGHBITDEPTH
void aom_highbd_idct4_c(const tran_low_t *input, tran_low_t *output, int bd);
void aom_highbd_idct8_c(const tran_low_t *input, tran_low_t *output, int bd);
void aom_highbd_idct16_c(const tran_low_t *input, tran_low_t *output, int bd);
@ -78,7 +86,6 @@ static INLINE uint16_t highbd_clip_pixel_add(uint16_t dest, tran_high_t trans,
trans = HIGHBD_WRAPLOW(trans, bd);
return clip_pixel_highbd(dest + (int)trans, bd);
}
#endif
static INLINE uint8_t clip_pixel_add(uint8_t dest, tran_high_t trans) {
trans = WRAPLOW(trans);

View file

@ -926,23 +926,3 @@ void aom_fdct32x32_rd_msa(const int16_t *input, int16_t *out,
out + (8 * i * 32));
}
}
void aom_fdct32x32_1_msa(const int16_t *input, int16_t *out, int32_t stride) {
int sum = LD_HADD(input, stride);
sum += LD_HADD(input + 8, stride);
sum += LD_HADD(input + 16, stride);
sum += LD_HADD(input + 24, stride);
sum += LD_HADD(input + 32 * 8, stride);
sum += LD_HADD(input + 32 * 8 + 8, stride);
sum += LD_HADD(input + 32 * 8 + 16, stride);
sum += LD_HADD(input + 32 * 8 + 24, stride);
sum += LD_HADD(input + 32 * 16, stride);
sum += LD_HADD(input + 32 * 16 + 8, stride);
sum += LD_HADD(input + 32 * 16 + 16, stride);
sum += LD_HADD(input + 32 * 16 + 24, stride);
sum += LD_HADD(input + 32 * 24, stride);
sum += LD_HADD(input + 32 * 24 + 8, stride);
sum += LD_HADD(input + 32 * 24 + 16, stride);
sum += LD_HADD(input + 32 * 24 + 24, stride);
out[0] = (int16_t)(sum >> 3);
}

View file

@ -236,11 +236,3 @@ void aom_fdct16x16_msa(const int16_t *input, int16_t *output,
fdct16x8_1d_row((&tmp_buf[0] + (128 * i)), (output + (128 * i)));
}
}
void aom_fdct16x16_1_msa(const int16_t *input, int16_t *out, int32_t stride) {
int sum = LD_HADD(input, stride);
sum += LD_HADD(input + 8, stride);
sum += LD_HADD(input + 16 * 8, stride);
sum += LD_HADD(input + 16 * 8 + 8, stride);
out[0] = (int16_t)(sum >> 1);
}

View file

@ -186,10 +186,8 @@ int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
for (i = 1; i < nsymbs; i++) {
cdf[i] = AOM_ICDF(AOM_ICDF(cdf[i - 1]) + cdf[i]);
}
// Store symbol count at the end of the CDF
#if CONFIG_EC_ADAPT
// Store symbol count at the end of the CDF
cdf[nsymbs] = 0;
#endif
return nsymbs;
}

View file

@ -148,7 +148,6 @@ static INLINE void av1_tree_to_cdf(const aom_tree_index *tree,
void av1_indices_from_tree(int *ind, int *inv, const aom_tree_index *tree);
#if CONFIG_EC_ADAPT
static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
const int rate = 4 + (cdf[nsymbs] > 31) + get_msb(nsymbs);
const int rate2 = 5;
@ -183,7 +182,6 @@ static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
#endif
cdf[nsymbs] += (cdf[nsymbs] < 32);
}
#endif
#ifdef __cplusplus
} // extern "C"

View file

@ -256,7 +256,6 @@ void aom_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
}
#endif // CONFIG_TX64X64
#if CONFIG_HIGHBITDEPTH
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
int skip_block, const int16_t *round_ptr,
const int16_t quant, tran_low_t *qcoeff_ptr,
@ -523,7 +522,6 @@ void aom_highbd_quantize_b_64x64_c(
*eob_ptr = eob + 1;
}
#endif // CONFIG_TX64X64
#endif // CONFIG_HIGHBITDEPTH
#else // CONFIG_AOM_QM
@ -602,7 +600,6 @@ void aom_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
}
#endif // CONFIG_TX64X64
#if CONFIG_HIGHBITDEPTH
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
int skip_block, const int16_t *round_ptr,
const int16_t quant, tran_low_t *qcoeff_ptr,
@ -716,8 +713,7 @@ void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
if (abs_coeff >= zbins[rc != 0]) {
const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
const uint32_t abs_qcoeff =
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
if (abs_qcoeff) eob = i;
@ -767,8 +763,7 @@ void aom_highbd_quantize_b_32x32_c(
const int64_t tmp1 =
abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
const uint32_t abs_qcoeff =
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
if (abs_qcoeff) eob = idx_arr[i];
@ -818,8 +813,7 @@ void aom_highbd_quantize_b_64x64_c(
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);
const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 14);
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 4;
if (abs_qcoeff) eob = idx_arr[i];
@ -828,5 +822,4 @@ void aom_highbd_quantize_b_64x64_c(
*eob_ptr = eob + 1;
}
#endif // CONFIG_TX64X64
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_AOM_QM

View file

@ -153,10 +153,21 @@ sadMxN(4, 4)
sadMxNxK(4, 4, 3)
sadMxNxK(4, 4, 8)
sadMxNx4D(4, 4)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
sadMxN(4, 16)
sadMxNx4D(4, 16)
sadMxN(16, 4)
sadMxNx4D(16, 4)
sadMxN(8, 32)
sadMxNx4D(8, 32)
sadMxN(32, 8)
sadMxNx4D(32, 8)
#endif
/* clang-format on */
#if CONFIG_HIGHBITDEPTH
static INLINE
static INLINE
unsigned int highbd_sad(const uint8_t *a8, int a_stride, const uint8_t *b8,
int b_stride, int width, int height) {
int y, x;
@ -307,11 +318,22 @@ highbd_sadMxN(4, 4)
highbd_sadMxNxK(4, 4, 3)
highbd_sadMxNxK(4, 4, 8)
highbd_sadMxNx4D(4, 4)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
highbd_sadMxN(4, 16)
highbd_sadMxNx4D(4, 16)
highbd_sadMxN(16, 4)
highbd_sadMxNx4D(16, 4)
highbd_sadMxN(8, 32)
highbd_sadMxNx4D(8, 32)
highbd_sadMxN(32, 8)
highbd_sadMxNx4D(32, 8)
#endif
/* clang-format on */
#endif // CONFIG_HIGHBITDEPTH
#if CONFIG_AV1 && CONFIG_EXT_INTER
static INLINE
static INLINE
unsigned int masked_sad(const uint8_t *src, int src_stride,
const uint8_t *a, int a_stride, const uint8_t *b,
int b_stride, const uint8_t *m, int m_stride,
@ -367,10 +389,17 @@ MASKSADMxN(8, 8)
MASKSADMxN(8, 4)
MASKSADMxN(4, 8)
MASKSADMxN(4, 4)
#if CONFIG_EXT_PARTITION_TYPES
MASKSADMxN(4, 16)
MASKSADMxN(16, 4)
MASKSADMxN(8, 32)
MASKSADMxN(32, 8)
#endif
/* clang-format on */
#if CONFIG_HIGHBITDEPTH
static INLINE
static INLINE
unsigned int highbd_masked_sad(const uint8_t *src8, int src_stride,
const uint8_t *a8, int a_stride,
const uint8_t *b8, int b_stride,
@ -429,6 +458,13 @@ HIGHBD_MASKSADMXN(8, 8)
HIGHBD_MASKSADMXN(8, 4)
HIGHBD_MASKSADMXN(4, 8)
HIGHBD_MASKSADMXN(4, 4)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
HIGHBD_MASKSADMXN(4, 16)
HIGHBD_MASKSADMXN(16, 4)
HIGHBD_MASKSADMXN(8, 32)
HIGHBD_MASKSADMXN(32, 8)
#endif
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_AV1 && CONFIG_EXT_INTER
@ -480,10 +516,17 @@ OBMCSADMxN(8, 8)
OBMCSADMxN(8, 4)
OBMCSADMxN(4, 8)
OBMCSADMxN(4, 4)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
OBMCSADMxN(4, 16)
OBMCSADMxN(16, 4)
OBMCSADMxN(8, 32)
OBMCSADMxN(32, 8)
#endif
/* clang-format on */
#if CONFIG_HIGHBITDEPTH
static INLINE
static INLINE
unsigned int highbd_obmc_sad(const uint8_t *pre8, int pre_stride,
const int32_t *wsrc, const int32_t *mask,
int width, int height) {
@ -529,6 +572,13 @@ HIGHBD_OBMCSADMXN(8, 8)
HIGHBD_OBMCSADMXN(8, 4)
HIGHBD_OBMCSADMXN(4, 8)
HIGHBD_OBMCSADMXN(4, 4)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
HIGHBD_OBMCSADMXN(4, 16)
HIGHBD_OBMCSADMXN(16, 4)
HIGHBD_OBMCSADMXN(8, 32)
HIGHBD_OBMCSADMXN(32, 8)
#endif
/* clang-format on */
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_AV1 && CONFIG_MOTION_VAR

View file

@ -508,17 +508,19 @@ SIMD_INLINE v256 v256_shr_s32(v256 a, unsigned int c) {
to enforce that. */
#define v256_shl_n_byte(a, n) \
((n) < 16 ? v256_from_v128(v128_or(v128_shl_n_byte(a.hi, n), \
v128_shr_n_byte(a.lo, 16 - (n))), \
v128_shr_n_byte(a.lo, (16 - (n)) & 31)), \
v128_shl_n_byte(a.lo, (n))) \
: v256_from_v128((n) > 16 ? v128_shl_n_byte(a.lo, (n)-16) : a.lo, \
v128_zero()))
: v256_from_v128( \
(n) > 16 ? v128_shl_n_byte(a.lo, ((n)-16) & 31) : a.lo, \
v128_zero()))
#define v256_shr_n_byte(a, n) \
((n) < 16 ? v256_from_v128(v128_shr_n_byte(a.hi, n), \
v128_or(v128_shr_n_byte(a.lo, n), \
v128_shl_n_byte(a.hi, 16 - (n)))) \
: v256_from_v128(v128_zero(), \
(n) > 16 ? v128_shr_n_byte(a.hi, (n)-16) : a.hi))
#define v256_shr_n_byte(a, n) \
((n) < 16 ? v256_from_v128(v128_shr_n_byte(a.hi, n), \
v128_or(v128_shr_n_byte(a.lo, n), \
v128_shl_n_byte(a.hi, (16 - (n)) & 31))) \
: v256_from_v128( \
v128_zero(), \
(n) > 16 ? v128_shr_n_byte(a.hi, ((n)-16) & 31) : a.hi))
#define v256_align(a, b, c) \
((c) ? v256_or(v256_shr_n_byte(b, c), v256_shl_n_byte(a, 32 - (c))) : b)

View file

@ -21,6 +21,27 @@
#define UNIT_QUANT_SHIFT 2
#define UNIT_QUANT_FACTOR (1 << UNIT_QUANT_SHIFT)
typedef struct txfm_param {
// for both forward and inverse transforms
int tx_type;
int tx_size;
int lossless;
int bd;
#if CONFIG_MRC_TX || CONFIG_LGT
int stride;
uint8_t *dst;
#endif // CONFIG_MRC_TX || CONFIG_LGT
#if CONFIG_LGT
int is_inter;
int mode;
#endif
// for inverse transforms only
#if CONFIG_ADAPT_SCAN
const int16_t *eob_threshold;
#endif
int eob;
} TxfmParam;
// Constants:
// for (int i = 1; i< 32; ++i)
// printf("static const int cospi_%d_64 = %.0f;\n", i,
@ -67,4 +88,62 @@ static const tran_high_t sinpi_4_9 = 15212;
// 16384 * sqrt(2)
static const tran_high_t Sqrt2 = 23170;
static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
return rv;
}
#if CONFIG_LGT
// The Line Graph Transforms (LGTs) matrices are written as follows.
// Each 2D array is 16384 times an LGT matrix, which is the matrix of
// eigenvectors of the graph Laplacian matrices for the line graph.
// LGT4 name: lgt4_140
// Self loops: 1.400, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000
static const tran_high_t lgt4_140[4][4] = {
{ 4206, 9518, 13524, 15674 },
{ 11552, 14833, 1560, -13453 },
{ 15391, -1906, -14393, 9445 },
{ 12201, -14921, 12016, -4581 },
};
// LGT4 name: lgt4_170
// Self loops: 1.700, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000
static const tran_high_t lgt4_170[4][4] = {
{ 3636, 9287, 13584, 15902 },
{ 10255, 15563, 2470, -13543 },
{ 14786, 711, -15249, 9231 },
{ 14138, -14420, 10663, -3920 },
};
// LGT8 name: lgt8_150
// Self loops: 1.500, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000
static const tran_high_t lgt8_150[8][8] = {
{ 2075, 5110, 7958, 10511, 12677, 14376, 15544, 16140 },
{ 6114, 13307, 16196, 13845, 7015, -2084, -10509, -15534 },
{ 9816, 16163, 8717, -6168, -15790, -11936, 2104, 14348 },
{ 12928, 12326, -7340, -15653, 242, 15763, 6905, -12632 },
{ 15124, 3038, -16033, 1758, 15507, -6397, -13593, 10463 },
{ 15895, -7947, -7947, 15895, -7947, -7947, 15895, -7947 },
{ 14325, -15057, 9030, 1050, -10659, 15483, -13358, 5236 },
{ 9054, -12580, 14714, -15220, 14043, -11312, 7330, -2537 },
};
// LGT8 name: lgt8_170
// Self loops: 1.700, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000
// Edges: 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000
static const tran_high_t lgt8_170[8][8] = {
{ 1858, 4947, 7850, 10458, 12672, 14411, 15607, 16217 },
{ 5494, 13022, 16256, 14129, 7343, -1864, -10456, -15601 },
{ 8887, 16266, 9500, -5529, -15749, -12273, 1876, 14394 },
{ 11870, 13351, -6199, -15984, -590, 15733, 7273, -12644 },
{ 14248, 5137, -15991, 291, 15893, -5685, -13963, 10425 },
{ 15716, -5450, -10010, 15929, -6665, -8952, 16036, -7835 },
{ 15533, -13869, 6559, 3421, -12009, 15707, -13011, 5018 },
{ 11357, -13726, 14841, -14600, 13025, -10259, 6556, -2254 },
};
#endif // CONFIG_LGT
#endif // AOM_DSP_TXFM_COMMON_H_

View file

@ -9,6 +9,8 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
@ -20,6 +22,9 @@
#include "aom_dsp/aom_filter.h"
#include "aom_dsp/blend.h"
#include "./av1_rtcd.h"
#include "av1/common/filter.h"
uint32_t aom_get4x4sse_cs_c(const uint8_t *a, int a_stride, const uint8_t *b,
int b_stride) {
int distortion = 0;
@ -246,6 +251,13 @@ VARIANCES(4, 2)
VARIANCES(2, 4)
VARIANCES(2, 2)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
VARIANCES(4, 16)
VARIANCES(16, 4)
VARIANCES(8, 32)
VARIANCES(32, 8)
#endif
GET_VAR(16, 16)
GET_VAR(8, 8)
@ -271,33 +283,66 @@ void aom_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width,
// Get pred block from up-sampled reference.
void aom_upsampled_pred_c(uint8_t *comp_pred, int width, int height,
const uint8_t *ref, int ref_stride) {
int i, j, k;
int stride = ref_stride << 3;
for (i = 0; i < height; i++) {
for (j = 0, k = 0; j < width; j++, k += 8) {
comp_pred[j] = ref[k];
int subpel_x_q3, int subpel_y_q3, const uint8_t *ref,
int ref_stride) {
if (!subpel_x_q3 && !subpel_y_q3) {
int i;
for (i = 0; i < height; i++) {
memcpy(comp_pred, ref, width * sizeof(*comp_pred));
comp_pred += width;
ref += ref_stride;
}
} else {
InterpFilterParams filter;
filter = av1_get_interp_filter_params(EIGHTTAP_REGULAR);
if (!subpel_y_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
/*Directly call C version to allow this to work for small (2x2) sizes.*/
aom_convolve8_horiz_c(ref, ref_stride, comp_pred, width, kernel, 16, NULL,
-1, width, height);
} else if (!subpel_x_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
/*Directly call C version to allow this to work for small (2x2) sizes.*/
aom_convolve8_vert_c(ref, ref_stride, comp_pred, width, NULL, -1, kernel,
16, width, height);
} else {
DECLARE_ALIGNED(16, uint8_t,
temp[((MAX_SB_SIZE * 2 + 16) + 16) * MAX_SB_SIZE]);
const int16_t *kernel_x;
const int16_t *kernel_y;
int intermediate_height;
kernel_x = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
kernel_y = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
intermediate_height =
(((height - 1) * 8 + subpel_y_q3) >> 3) + filter.taps;
assert(intermediate_height <= (MAX_SB_SIZE * 2 + 16) + 16);
/*Directly call C versions to allow this to work for small (2x2) sizes.*/
aom_convolve8_horiz_c(ref - ref_stride * ((filter.taps >> 1) - 1),
ref_stride, temp, MAX_SB_SIZE, kernel_x, 16, NULL,
-1, width, intermediate_height);
aom_convolve8_vert_c(temp + MAX_SB_SIZE * ((filter.taps >> 1) - 1),
MAX_SB_SIZE, comp_pred, width, NULL, -1, kernel_y,
16, width, height);
}
comp_pred += width;
ref += stride;
}
}
void aom_comp_avg_upsampled_pred_c(uint8_t *comp_pred, const uint8_t *pred,
int width, int height, const uint8_t *ref,
int width, int height, int subpel_x_q3,
int subpel_y_q3, const uint8_t *ref,
int ref_stride) {
int i, j;
int stride = ref_stride << 3;
aom_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3, ref,
ref_stride);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
const int tmp = ref[(j << 3)] + pred[j];
comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1);
comp_pred[j] = ROUND_POWER_OF_TWO(comp_pred[j] + pred[j], 1);
}
comp_pred += width;
pred += width;
ref += stride;
}
}
@ -611,6 +656,13 @@ HIGHBD_VARIANCES(4, 2)
HIGHBD_VARIANCES(2, 4)
HIGHBD_VARIANCES(2, 2)
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
HIGHBD_VARIANCES(4, 16)
HIGHBD_VARIANCES(16, 4)
HIGHBD_VARIANCES(8, 32)
HIGHBD_VARIANCES(32, 8)
#endif
HIGHBD_GET_VAR(8)
HIGHBD_GET_VAR(16)
@ -637,37 +689,74 @@ void aom_highbd_comp_avg_pred_c(uint16_t *comp_pred, const uint8_t *pred8,
}
void aom_highbd_upsampled_pred_c(uint16_t *comp_pred, int width, int height,
const uint8_t *ref8, int ref_stride) {
int i, j;
int stride = ref_stride << 3;
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
for (i = 0; i < height; ++i) {
for (j = 0; j < width; ++j) {
comp_pred[j] = ref[(j << 3)];
int subpel_x_q3, int subpel_y_q3,
const uint8_t *ref8, int ref_stride, int bd) {
if (!subpel_x_q3 && !subpel_y_q3) {
const uint16_t *ref;
int i;
ref = CONVERT_TO_SHORTPTR(ref8);
for (i = 0; i < height; i++) {
memcpy(comp_pred, ref, width * sizeof(*comp_pred));
comp_pred += width;
ref += ref_stride;
}
} else {
InterpFilterParams filter;
filter = av1_get_interp_filter_params(EIGHTTAP_REGULAR);
if (!subpel_y_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
/*Directly call C version to allow this to work for small (2x2) sizes.*/
aom_highbd_convolve8_horiz_c(ref8, ref_stride,
CONVERT_TO_BYTEPTR(comp_pred), width, kernel,
16, NULL, -1, width, height, bd);
} else if (!subpel_x_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
/*Directly call C version to allow this to work for small (2x2) sizes.*/
aom_highbd_convolve8_vert_c(ref8, ref_stride,
CONVERT_TO_BYTEPTR(comp_pred), width, NULL,
-1, kernel, 16, width, height, bd);
} else {
DECLARE_ALIGNED(16, uint16_t,
temp[((MAX_SB_SIZE + 16) + 16) * MAX_SB_SIZE]);
const int16_t *kernel_x;
const int16_t *kernel_y;
int intermediate_height;
kernel_x = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
kernel_y = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
intermediate_height =
(((height - 1) * 8 + subpel_y_q3) >> 3) + filter.taps;
assert(intermediate_height <= (MAX_SB_SIZE * 2 + 16) + 16);
/*Directly call C versions to allow this to work for small (2x2) sizes.*/
aom_highbd_convolve8_horiz_c(ref8 - ref_stride * ((filter.taps >> 1) - 1),
ref_stride, CONVERT_TO_BYTEPTR(temp),
MAX_SB_SIZE, kernel_x, 16, NULL, -1, width,
intermediate_height, bd);
aom_highbd_convolve8_vert_c(
CONVERT_TO_BYTEPTR(temp + MAX_SB_SIZE * ((filter.taps >> 1) - 1)),
MAX_SB_SIZE, CONVERT_TO_BYTEPTR(comp_pred), width, NULL, -1, kernel_y,
16, width, height, bd);
}
comp_pred += width;
ref += stride;
}
}
void aom_highbd_comp_avg_upsampled_pred_c(uint16_t *comp_pred,
const uint8_t *pred8, int width,
int height, const uint8_t *ref8,
int ref_stride) {
int height, int subpel_x_q3,
int subpel_y_q3, const uint8_t *ref8,
int ref_stride, int bd) {
int i, j;
int stride = ref_stride << 3;
uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
const uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
aom_highbd_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3,
ref8, ref_stride, bd);
for (i = 0; i < height; ++i) {
for (j = 0; j < width; ++j) {
const int tmp = pred[j] + ref[(j << 3)];
comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1);
comp_pred[j] = ROUND_POWER_OF_TWO(pred[j] + comp_pred[j], 1);
}
comp_pred += width;
pred += width;
ref += stride;
}
}
#endif // CONFIG_HIGHBITDEPTH
@ -694,22 +783,23 @@ void aom_comp_mask_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width,
}
void aom_comp_mask_upsampled_pred_c(uint8_t *comp_pred, const uint8_t *pred,
int width, int height, const uint8_t *ref,
int width, int height, int subpel_x_q3,
int subpel_y_q3, const uint8_t *ref,
int ref_stride, const uint8_t *mask,
int mask_stride, int invert_mask) {
int i, j;
int stride = ref_stride << 3;
aom_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3, ref,
ref_stride);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
if (!invert_mask)
comp_pred[j] = AOM_BLEND_A64(mask[j], ref[(j << 3)], pred[j]);
comp_pred[j] = AOM_BLEND_A64(mask[j], comp_pred[j], pred[j]);
else
comp_pred[j] = AOM_BLEND_A64(mask[j], pred[j], ref[(j << 3)]);
comp_pred[j] = AOM_BLEND_A64(mask[j], pred[j], comp_pred[j]);
}
comp_pred += width;
pred += width;
ref += stride;
mask += mask_stride;
}
}
@ -753,6 +843,13 @@ MASK_SUBPIX_VAR(128, 64)
MASK_SUBPIX_VAR(128, 128)
#endif // CONFIG_EXT_PARTITION
#if CONFIG_EXT_PARTITION_TYPES
MASK_SUBPIX_VAR(4, 16)
MASK_SUBPIX_VAR(16, 4)
MASK_SUBPIX_VAR(8, 32)
MASK_SUBPIX_VAR(32, 8)
#endif
#if CONFIG_HIGHBITDEPTH
void aom_highbd_comp_mask_pred_c(uint16_t *comp_pred, const uint8_t *pred8,
int width, int height, const uint8_t *ref8,
@ -775,26 +872,24 @@ void aom_highbd_comp_mask_pred_c(uint16_t *comp_pred, const uint8_t *pred8,
}
}
void aom_highbd_comp_mask_upsampled_pred_c(uint16_t *comp_pred,
const uint8_t *pred8, int width,
int height, const uint8_t *ref8,
int ref_stride, const uint8_t *mask,
int mask_stride, int invert_mask) {
void aom_highbd_comp_mask_upsampled_pred_c(
uint16_t *comp_pred, const uint8_t *pred8, int width, int height,
int subpel_x_q3, int subpel_y_q3, const uint8_t *ref8, int ref_stride,
const uint8_t *mask, int mask_stride, int invert_mask, int bd) {
int i, j;
int stride = ref_stride << 3;
uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
aom_highbd_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3,
ref8, ref_stride, bd);
for (i = 0; i < height; ++i) {
for (j = 0; j < width; ++j) {
if (!invert_mask)
comp_pred[j] = AOM_BLEND_A64(mask[j], ref[j << 3], pred[j]);
comp_pred[j] = AOM_BLEND_A64(mask[j], comp_pred[j], pred[j]);
else
comp_pred[j] = AOM_BLEND_A64(mask[j], pred[j], ref[j << 3]);
comp_pred[j] = AOM_BLEND_A64(mask[j], pred[j], comp_pred[j]);
}
comp_pred += width;
pred += width;
ref += stride;
mask += mask_stride;
}
}
@ -884,6 +979,13 @@ HIGHBD_MASK_SUBPIX_VAR(64, 128)
HIGHBD_MASK_SUBPIX_VAR(128, 64)
HIGHBD_MASK_SUBPIX_VAR(128, 128)
#endif // CONFIG_EXT_PARTITION
#if CONFIG_EXT_PARTITION_TYPES
HIGHBD_MASK_SUBPIX_VAR(4, 16)
HIGHBD_MASK_SUBPIX_VAR(16, 4)
HIGHBD_MASK_SUBPIX_VAR(8, 32)
HIGHBD_MASK_SUBPIX_VAR(32, 8)
#endif
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_AV1 && CONFIG_EXT_INTER
@ -983,6 +1085,17 @@ OBMC_VAR(128, 128)
OBMC_SUBPIX_VAR(128, 128)
#endif // CONFIG_EXT_PARTITION
#if CONFIG_EXT_PARTITION_TYPES
OBMC_VAR(4, 16)
OBMC_SUBPIX_VAR(4, 16)
OBMC_VAR(16, 4)
OBMC_SUBPIX_VAR(16, 4)
OBMC_VAR(8, 32)
OBMC_SUBPIX_VAR(8, 32)
OBMC_VAR(32, 8)
OBMC_SUBPIX_VAR(32, 8)
#endif
#if CONFIG_HIGHBITDEPTH
static INLINE void highbd_obmc_variance64(const uint8_t *pre8, int pre_stride,
const int32_t *wsrc,
@ -1164,5 +1277,16 @@ HIGHBD_OBMC_SUBPIX_VAR(128, 64)
HIGHBD_OBMC_VAR(128, 128)
HIGHBD_OBMC_SUBPIX_VAR(128, 128)
#endif // CONFIG_EXT_PARTITION
#if CONFIG_EXT_PARTITION_TYPES
HIGHBD_OBMC_VAR(4, 16)
HIGHBD_OBMC_SUBPIX_VAR(4, 16)
HIGHBD_OBMC_VAR(16, 4)
HIGHBD_OBMC_SUBPIX_VAR(16, 4)
HIGHBD_OBMC_VAR(8, 32)
HIGHBD_OBMC_SUBPIX_VAR(8, 32)
HIGHBD_OBMC_VAR(32, 8)
HIGHBD_OBMC_SUBPIX_VAR(32, 8)
#endif
#endif // CONFIG_HIGHBITDEPTH
#endif // CONFIG_AV1 && CONFIG_MOTION_VAR

View file

@ -85,147 +85,6 @@ void aom_fdct8x8_1_sse2(const int16_t *input, tran_low_t *output, int stride) {
output[0] = (tran_low_t)_mm_cvtsi128_si32(in1);
}
void aom_fdct16x16_1_sse2(const int16_t *input, tran_low_t *output,
int stride) {
__m128i in0, in1, in2, in3;
__m128i u0, u1;
__m128i sum = _mm_setzero_si128();
int i;
for (i = 0; i < 2; ++i) {
in0 = _mm_load_si128((const __m128i *)(input + 0 * stride + 0));
in1 = _mm_load_si128((const __m128i *)(input + 0 * stride + 8));
in2 = _mm_load_si128((const __m128i *)(input + 1 * stride + 0));
in3 = _mm_load_si128((const __m128i *)(input + 1 * stride + 8));
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 2 * stride + 0));
in1 = _mm_load_si128((const __m128i *)(input + 2 * stride + 8));
in2 = _mm_load_si128((const __m128i *)(input + 3 * stride + 0));
in3 = _mm_load_si128((const __m128i *)(input + 3 * stride + 8));
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 4 * stride + 0));
in1 = _mm_load_si128((const __m128i *)(input + 4 * stride + 8));
in2 = _mm_load_si128((const __m128i *)(input + 5 * stride + 0));
in3 = _mm_load_si128((const __m128i *)(input + 5 * stride + 8));
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 6 * stride + 0));
in1 = _mm_load_si128((const __m128i *)(input + 6 * stride + 8));
in2 = _mm_load_si128((const __m128i *)(input + 7 * stride + 0));
in3 = _mm_load_si128((const __m128i *)(input + 7 * stride + 8));
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
sum = _mm_add_epi16(sum, u1);
input += 8 * stride;
}
u0 = _mm_setzero_si128();
in0 = _mm_unpacklo_epi16(u0, sum);
in1 = _mm_unpackhi_epi16(u0, sum);
in0 = _mm_srai_epi32(in0, 16);
in1 = _mm_srai_epi32(in1, 16);
sum = _mm_add_epi32(in0, in1);
in0 = _mm_unpacklo_epi32(sum, u0);
in1 = _mm_unpackhi_epi32(sum, u0);
sum = _mm_add_epi32(in0, in1);
in0 = _mm_srli_si128(sum, 8);
in1 = _mm_add_epi32(sum, in0);
in1 = _mm_srai_epi32(in1, 1);
output[0] = (tran_low_t)_mm_cvtsi128_si32(in1);
}
void aom_fdct32x32_1_sse2(const int16_t *input, tran_low_t *output,
int stride) {
__m128i in0, in1, in2, in3;
__m128i u0, u1;
__m128i sum = _mm_setzero_si128();
int i;
for (i = 0; i < 8; ++i) {
in0 = _mm_load_si128((const __m128i *)(input + 0));
in1 = _mm_load_si128((const __m128i *)(input + 8));
in2 = _mm_load_si128((const __m128i *)(input + 16));
in3 = _mm_load_si128((const __m128i *)(input + 24));
input += stride;
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 0));
in1 = _mm_load_si128((const __m128i *)(input + 8));
in2 = _mm_load_si128((const __m128i *)(input + 16));
in3 = _mm_load_si128((const __m128i *)(input + 24));
input += stride;
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 0));
in1 = _mm_load_si128((const __m128i *)(input + 8));
in2 = _mm_load_si128((const __m128i *)(input + 16));
in3 = _mm_load_si128((const __m128i *)(input + 24));
input += stride;
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
in0 = _mm_load_si128((const __m128i *)(input + 0));
in1 = _mm_load_si128((const __m128i *)(input + 8));
in2 = _mm_load_si128((const __m128i *)(input + 16));
in3 = _mm_load_si128((const __m128i *)(input + 24));
input += stride;
sum = _mm_add_epi16(sum, u1);
u0 = _mm_add_epi16(in0, in1);
u1 = _mm_add_epi16(in2, in3);
sum = _mm_add_epi16(sum, u0);
sum = _mm_add_epi16(sum, u1);
}
u0 = _mm_setzero_si128();
in0 = _mm_unpacklo_epi16(u0, sum);
in1 = _mm_unpackhi_epi16(u0, sum);
in0 = _mm_srai_epi32(in0, 16);
in1 = _mm_srai_epi32(in1, 16);
sum = _mm_add_epi32(in0, in1);
in0 = _mm_unpacklo_epi32(sum, u0);
in1 = _mm_unpackhi_epi32(sum, u0);
sum = _mm_add_epi32(in0, in1);
in0 = _mm_srli_si128(sum, 8);
in1 = _mm_add_epi32(sum, in0);
in1 = _mm_srai_epi32(in1, 3);
output[0] = (tran_low_t)_mm_cvtsi128_si32(in1);
}
#define DCT_HIGH_BIT_DEPTH 0
#define FDCT4x4_2D aom_fdct4x4_sse2
#define FDCT8x8_2D aom_fdct8x8_sse2

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2017, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <immintrin.h>
#include "./aom_dsp_rtcd.h"
#include "aom/aom_integer.h"
static INLINE void init_one_qp(const __m128i *p, __m256i *qp) {
const __m128i sign = _mm_srai_epi16(*p, 15);
const __m128i dc = _mm_unpacklo_epi16(*p, sign);
const __m128i ac = _mm_unpackhi_epi16(*p, sign);
*qp = _mm256_insertf128_si256(_mm256_castsi128_si256(dc), ac, 1);
}
static INLINE void update_qp(__m256i *qp) {
int i;
for (i = 0; i < 5; ++i) {
qp[i] = _mm256_permute2x128_si256(qp[i], qp[i], 0x11);
}
}
static INLINE void init_qp(const int16_t *zbin_ptr, const int16_t *round_ptr,
const int16_t *quant_ptr, const int16_t *dequant_ptr,
const int16_t *quant_shift_ptr, __m256i *qp) {
const __m128i zbin = _mm_loadu_si128((const __m128i *)zbin_ptr);
const __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);
const __m128i quant_shift = _mm_loadu_si128((const __m128i *)quant_shift_ptr);
init_one_qp(&zbin, &qp[0]);
init_one_qp(&round, &qp[1]);
init_one_qp(&quant, &qp[2]);
init_one_qp(&dequant, &qp[3]);
init_one_qp(&quant_shift, &qp[4]);
}
// Note:
// *x is vector multiplied by *y which is 16 int32_t parallel multiplication
// and right shift 16. The output, 16 int32_t is save in *p.
static INLINE void mm256_mul_shift_epi32(const __m256i *x, const __m256i *y,
__m256i *p) {
__m256i prod_lo = _mm256_mul_epi32(*x, *y);
__m256i prod_hi = _mm256_srli_epi64(*x, 32);
const __m256i mult_hi = _mm256_srli_epi64(*y, 32);
prod_hi = _mm256_mul_epi32(prod_hi, mult_hi);
prod_lo = _mm256_srli_epi64(prod_lo, 16);
const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
prod_lo = _mm256_and_si256(prod_lo, mask);
prod_hi = _mm256_srli_epi64(prod_hi, 16);
prod_hi = _mm256_slli_epi64(prod_hi, 32);
*p = _mm256_or_si256(prod_lo, prod_hi);
}
static INLINE void quantize(const __m256i *qp, __m256i *c,
const int16_t *iscan_ptr, tran_low_t *qcoeff,
tran_low_t *dqcoeff, __m256i *eob) {
const __m256i abs = _mm256_abs_epi32(*c);
const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
__m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
flag2 = _mm256_or_si256(flag1, flag2);
const int32_t nzflag = _mm256_movemask_epi8(flag2);
if (LIKELY(nzflag)) {
__m256i q = _mm256_add_epi32(abs, qp[1]);
__m256i tmp;
mm256_mul_shift_epi32(&q, &qp[2], &tmp);
q = _mm256_add_epi32(tmp, q);
mm256_mul_shift_epi32(&q, &qp[4], &q);
__m256i dq = _mm256_mullo_epi32(q, qp[3]);
q = _mm256_sign_epi32(q, *c);
dq = _mm256_sign_epi32(dq, *c);
q = _mm256_and_si256(q, flag2);
dq = _mm256_and_si256(dq, flag2);
_mm256_storeu_si256((__m256i *)qcoeff, q);
_mm256_storeu_si256((__m256i *)dqcoeff, dq);
const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
const __m128i zr = _mm_setzero_si128();
const __m128i lo = _mm_unpacklo_epi16(isc, zr);
const __m128i hi = _mm_unpackhi_epi16(isc, zr);
const __m256i iscan =
_mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
const __m256i zero = _mm256_setzero_si256();
const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
__m256i cur_eob = _mm256_sub_epi32(iscan, nz);
cur_eob = _mm256_and_si256(cur_eob, nz);
*eob = _mm256_max_epi32(cur_eob, *eob);
} else {
const __m256i zero = _mm256_setzero_si256();
_mm256_storeu_si256((__m256i *)qcoeff, zero);
_mm256_storeu_si256((__m256i *)dqcoeff, zero);
}
}
void aom_highbd_quantize_b_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
int skip_block, const int16_t *zbin_ptr,
const int16_t *round_ptr,
const int16_t *quant_ptr,
const int16_t *quant_shift_ptr,
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
const int16_t *dequant_ptr, uint16_t *eob_ptr,
const int16_t *scan, const int16_t *iscan) {
(void)scan;
const unsigned int step = 8;
if (LIKELY(!skip_block)) {
__m256i qp[5], coeff;
init_qp(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
__m256i eob = _mm256_setzero_si256();
quantize(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
coeff_ptr += step;
qcoeff_ptr += step;
dqcoeff_ptr += step;
iscan += step;
n_coeffs -= step;
update_qp(qp);
while (n_coeffs > 0) {
coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
quantize(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
coeff_ptr += step;
qcoeff_ptr += step;
dqcoeff_ptr += step;
iscan += step;
n_coeffs -= step;
}
{
__m256i eob_s;
eob_s = _mm256_shuffle_epi32(eob, 0xe);
eob = _mm256_max_epi16(eob, eob_s);
eob_s = _mm256_shufflelo_epi16(eob, 0xe);
eob = _mm256_max_epi16(eob, eob_s);
eob_s = _mm256_shufflelo_epi16(eob, 1);
eob = _mm256_max_epi16(eob, eob_s);
const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
_mm256_extractf128_si256(eob, 1));
*eob_ptr = _mm_extract_epi16(final_eob, 0);
}
} else {
do {
const __m256i zero = _mm256_setzero_si256();
_mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
_mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
qcoeff_ptr += step;
dqcoeff_ptr += step;
n_coeffs -= step;
} while (n_coeffs > 0);
*eob_ptr = 0;
}
}

View file

@ -15,7 +15,6 @@
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"
#if CONFIG_HIGHBITDEPTH
void aom_highbd_quantize_b_sse2(const tran_low_t *coeff_ptr, intptr_t count,
int skip_block, const int16_t *zbin_ptr,
const int16_t *round_ptr,
@ -152,4 +151,3 @@ void aom_highbd_quantize_b_32x32_sse2(
}
*eob_ptr = eob + 1;
}
#endif

View file

@ -288,3 +288,9 @@ HIGH_SADNXN4D 8, 8
HIGH_SADNXN4D 8, 4
HIGH_SADNXN4D 4, 8
HIGH_SADNXN4D 4, 4
%if CONFIG_EXT_PARTITION_TYPES
HIGH_SADNXN4D 4, 16
HIGH_SADNXN4D 16, 4
HIGH_SADNXN4D 8, 32
HIGH_SADNXN4D 32, 8
%endif

View file

@ -227,6 +227,10 @@ HIGH_SAD32XN 16 ; highbd_sad32x16_sse2
HIGH_SAD32XN 64, 1 ; highbd_sad32x64_avg_sse2
HIGH_SAD32XN 32, 1 ; highbd_sad32x32_avg_sse2
HIGH_SAD32XN 16, 1 ; highbd_sad32x16_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
HIGH_SAD32XN 8 ; highbd_sad_32x8_sse2
HIGH_SAD32XN 8, 1 ; highbd_sad_32x8_avg_sse2
%endif
; unsigned int aom_highbd_sad16x{8,16,32}_sse2(uint8_t *src, int src_stride,
; uint8_t *ref, int ref_stride);
@ -295,7 +299,10 @@ HIGH_SAD16XN 8 ; highbd_sad16x8_sse2
HIGH_SAD16XN 32, 1 ; highbd_sad16x32_avg_sse2
HIGH_SAD16XN 16, 1 ; highbd_sad16x16_avg_sse2
HIGH_SAD16XN 8, 1 ; highbd_sad16x8_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
HIGH_SAD16XN 4 ; highbd_sad_16x4_sse2
HIGH_SAD16XN 4, 1 ; highbd_sad_16x4_avg_sse2
%endif
; unsigned int aom_highbd_sad8x{4,8,16}_sse2(uint8_t *src, int src_stride,
; uint8_t *ref, int ref_stride);
@ -364,3 +371,7 @@ HIGH_SAD8XN 4 ; highbd_sad8x4_sse2
HIGH_SAD8XN 16, 1 ; highbd_sad8x16_avg_sse2
HIGH_SAD8XN 8, 1 ; highbd_sad8x8_avg_sse2
HIGH_SAD8XN 4, 1 ; highbd_sad8x4_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
HIGH_SAD8XN 32 ; highbd_sad_8x32_sse2
HIGH_SAD8XN 32, 1 ; highbd_sad_8x32_avg_sse2
%endif

View file

@ -75,7 +75,7 @@ SECTION .text
paddd m6, m4
mov r1, ssem ; r1 = unsigned int *sse
movd [r1], m7 ; store sse
movd rax, m6 ; store sum as return value
movd eax, m6 ; store sum as return value
%endif
RET
%endmacro

View file

@ -9,6 +9,7 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <assert.h>
#include <emmintrin.h> // SSE2
#include "./aom_config.h"
@ -16,6 +17,9 @@
#include "aom_ports/mem.h"
#include "./av1_rtcd.h"
#include "av1/common/filter.h"
typedef uint32_t (*high_variance_fn_t)(const uint16_t *src, int src_stride,
const uint16_t *ref, int ref_stride,
uint32_t *sse, int *sum);
@ -181,6 +185,11 @@ VAR_FN(16, 16, 16, 8);
VAR_FN(16, 8, 8, 7);
VAR_FN(8, 16, 8, 7);
VAR_FN(8, 8, 8, 6);
#if CONFIG_EXT_PARTITION_TYPES
VAR_FN(16, 4, 16, 6);
VAR_FN(8, 32, 8, 8);
VAR_FN(32, 8, 16, 8);
#endif
#undef VAR_FN
@ -387,6 +396,7 @@ DECLS(sse2);
return (var >= 0) ? (uint32_t)var : 0; \
}
#if CONFIG_EXT_PARTITION_TYPES
#define FNS(opt) \
FN(64, 64, 16, 6, 6, opt, (int64_t)); \
FN(64, 32, 16, 6, 5, opt, (int64_t)); \
@ -398,7 +408,24 @@ DECLS(sse2);
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(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))
#else
#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))
#endif
FNS(sse2);
@ -412,9 +439,9 @@ FNS(sse2);
const uint16_t *dst, ptrdiff_t dst_stride, const uint16_t *sec, \
ptrdiff_t sec_stride, int height, unsigned int *sse, void *unused0, \
void *unused);
#define DECLS(opt1) \
DECL(16, opt1) \
DECL(8, opt1)
#define DECLS(opt) \
DECL(16, opt) \
DECL(8, opt)
DECLS(sse2);
#undef DECL
@ -546,18 +573,36 @@ DECLS(sse2);
return (var >= 0) ? (uint32_t)var : 0; \
}
#define FNS(opt1) \
FN(64, 64, 16, 6, 6, opt1, (int64_t)); \
FN(64, 32, 16, 6, 5, opt1, (int64_t)); \
FN(32, 64, 16, 5, 6, opt1, (int64_t)); \
FN(32, 32, 16, 5, 5, opt1, (int64_t)); \
FN(32, 16, 16, 5, 4, opt1, (int64_t)); \
FN(16, 32, 16, 4, 5, opt1, (int64_t)); \
FN(16, 16, 16, 4, 4, opt1, (int64_t)); \
FN(16, 8, 16, 4, 3, opt1, (int64_t)); \
FN(8, 16, 8, 4, 3, opt1, (int64_t)); \
FN(8, 8, 8, 3, 3, opt1, (int64_t)); \
FN(8, 4, 8, 3, 2, opt1, (int64_t));
#if CONFIG_EXT_PARTITION_TYPES
#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));
#else
#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));
#endif
FNS(sse2);
@ -565,131 +610,94 @@ FNS(sse2);
#undef FN
void aom_highbd_upsampled_pred_sse2(uint16_t *comp_pred, int width, int height,
const uint8_t *ref8, int ref_stride) {
int i, j;
int stride = ref_stride << 3;
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
if (width >= 8) {
// read 8 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 8) {
__m128i s0 = _mm_cvtsi32_si128(*(const uint32_t *)ref);
__m128i s1 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 8));
__m128i s2 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 16));
__m128i s3 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 24));
__m128i s4 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 32));
__m128i s5 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 40));
__m128i s6 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 48));
__m128i s7 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 56));
__m128i t0, t1, t2, t3;
t0 = _mm_unpacklo_epi16(s0, s1);
t1 = _mm_unpacklo_epi16(s2, s3);
t2 = _mm_unpacklo_epi16(s4, s5);
t3 = _mm_unpacklo_epi16(s6, s7);
t0 = _mm_unpacklo_epi32(t0, t1);
t2 = _mm_unpacklo_epi32(t2, t3);
t0 = _mm_unpacklo_epi64(t0, t2);
_mm_storeu_si128((__m128i *)(comp_pred), t0);
comp_pred += 8;
ref += 64; // 8 * 8;
int subpel_x_q3, int subpel_y_q3,
const uint8_t *ref8, int ref_stride,
int bd) {
if (!subpel_x_q3 && !subpel_y_q3) {
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
if (width >= 8) {
int i;
assert(!(width & 7));
/*Read 8 pixels one row at a time.*/
for (i = 0; i < height; i++) {
int j;
for (j = 0; j < width; j += 8) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
_mm_storeu_si128((__m128i *)comp_pred, s0);
comp_pred += 8;
ref += 8;
}
ref += ref_stride - width;
}
} else {
int i;
assert(!(width & 3));
/*Read 4 pixels two rows at a time.*/
for (i = 0; i < height; i += 2) {
__m128i s0 = _mm_loadl_epi64((const __m128i *)ref);
__m128i s1 = _mm_loadl_epi64((const __m128i *)(ref + ref_stride));
__m128i t0 = _mm_unpacklo_epi64(s0, s1);
_mm_storeu_si128((__m128i *)comp_pred, t0);
comp_pred += 8;
ref += 2 * ref_stride;
}
ref += stride - (width << 3);
}
} else {
// read 4 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 4) {
__m128i s0 = _mm_cvtsi32_si128(*(const uint32_t *)ref);
__m128i s1 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 8));
__m128i s2 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 16));
__m128i s3 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 24));
__m128i t0, t1;
t0 = _mm_unpacklo_epi16(s0, s1);
t1 = _mm_unpacklo_epi16(s2, s3);
t0 = _mm_unpacklo_epi32(t0, t1);
_mm_storel_epi64((__m128i *)(comp_pred), t0);
comp_pred += 4;
ref += 4 * 8;
}
ref += stride - (width << 3);
InterpFilterParams filter;
filter = av1_get_interp_filter_params(EIGHTTAP_REGULAR);
if (!subpel_y_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
aom_highbd_convolve8_horiz(ref8, ref_stride,
CONVERT_TO_BYTEPTR(comp_pred), width, kernel,
16, NULL, -1, width, height, bd);
} else if (!subpel_x_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
aom_highbd_convolve8_vert(ref8, ref_stride, CONVERT_TO_BYTEPTR(comp_pred),
width, NULL, -1, kernel, 16, width, height, bd);
} else {
DECLARE_ALIGNED(16, uint16_t,
temp[((MAX_SB_SIZE + 16) + 16) * MAX_SB_SIZE]);
const int16_t *kernel_x;
const int16_t *kernel_y;
int intermediate_height;
kernel_x = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
kernel_y = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
intermediate_height =
(((height - 1) * 8 + subpel_y_q3) >> 3) + filter.taps;
assert(intermediate_height <= (MAX_SB_SIZE * 2 + 16) + 16);
aom_highbd_convolve8_horiz(ref8 - ref_stride * ((filter.taps >> 1) - 1),
ref_stride, CONVERT_TO_BYTEPTR(temp),
MAX_SB_SIZE, kernel_x, 16, NULL, -1, width,
intermediate_height, bd);
aom_highbd_convolve8_vert(
CONVERT_TO_BYTEPTR(temp + MAX_SB_SIZE * ((filter.taps >> 1) - 1)),
MAX_SB_SIZE, CONVERT_TO_BYTEPTR(comp_pred), width, NULL, -1, kernel_y,
16, width, height, bd);
}
}
}
void aom_highbd_comp_avg_upsampled_pred_sse2(uint16_t *comp_pred,
const uint8_t *pred8, int width,
int height, const uint8_t *ref8,
int ref_stride) {
const __m128i one = _mm_set1_epi16(1);
int i, j;
int stride = ref_stride << 3;
int height, int subpel_x_q3,
int subpel_y_q3,
const uint8_t *ref8,
int ref_stride, int bd) {
uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
if (width >= 8) {
// read 8 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 8) {
__m128i s0 = _mm_cvtsi32_si128(*(const uint32_t *)ref);
__m128i s1 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 8));
__m128i s2 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 16));
__m128i s3 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 24));
__m128i s4 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 32));
__m128i s5 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 40));
__m128i s6 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 48));
__m128i s7 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 56));
__m128i p0 = _mm_loadu_si128((const __m128i *)pred);
__m128i t0, t1, t2, t3;
t0 = _mm_unpacklo_epi16(s0, s1);
t1 = _mm_unpacklo_epi16(s2, s3);
t2 = _mm_unpacklo_epi16(s4, s5);
t3 = _mm_unpacklo_epi16(s6, s7);
t0 = _mm_unpacklo_epi32(t0, t1);
t2 = _mm_unpacklo_epi32(t2, t3);
t0 = _mm_unpacklo_epi64(t0, t2);
p0 = _mm_adds_epu16(t0, p0);
p0 = _mm_adds_epu16(p0, one);
p0 = _mm_srli_epi16(p0, 1);
_mm_storeu_si128((__m128i *)(comp_pred), p0);
comp_pred += 8;
pred += 8;
ref += 8 * 8;
}
ref += stride - (width << 3);
}
} else {
// read 4 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 4) {
__m128i s0 = _mm_cvtsi32_si128(*(const uint32_t *)ref);
__m128i s1 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 8));
__m128i s2 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 16));
__m128i s3 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + 24));
__m128i p0 = _mm_loadl_epi64((const __m128i *)pred);
__m128i t0, t1;
t0 = _mm_unpacklo_epi16(s0, s1);
t1 = _mm_unpacklo_epi16(s2, s3);
t0 = _mm_unpacklo_epi32(t0, t1);
p0 = _mm_adds_epu16(t0, p0);
p0 = _mm_adds_epu16(p0, one);
p0 = _mm_srli_epi16(p0, 1);
_mm_storel_epi64((__m128i *)(comp_pred), p0);
comp_pred += 4;
pred += 4;
ref += 4 * 8;
}
ref += stride - (width << 3);
}
int n;
int i;
aom_highbd_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3,
ref8, ref_stride, bd);
/*The total number of pixels must be a multiple of 8 (e.g., 4x4).*/
assert(!(width * height & 7));
n = width * height >> 3;
for (i = 0; i < n; i++) {
__m128i s0 = _mm_loadu_si128((const __m128i *)comp_pred);
__m128i p0 = _mm_loadu_si128((const __m128i *)pred);
_mm_storeu_si128((__m128i *)comp_pred, _mm_avg_epu16(s0, p0));
comp_pred += 8;
pred += 8;
}
}

View file

@ -3498,237 +3498,3 @@ void idct32_8col(__m128i *in0, __m128i *in1) {
in1[14] = _mm_sub_epi16(stp1_1, stp1_30);
in1[15] = _mm_sub_epi16(stp1_0, stp1_31);
}
#if CONFIG_HIGHBITDEPTH
static INLINE __m128i clamp_high_sse2(__m128i value, int bd) {
__m128i ubounded, retval;
const __m128i zero = _mm_set1_epi16(0);
const __m128i one = _mm_set1_epi16(1);
const __m128i max = _mm_subs_epi16(_mm_slli_epi16(one, bd), one);
ubounded = _mm_cmpgt_epi16(value, max);
retval = _mm_andnot_si128(ubounded, value);
ubounded = _mm_and_si128(ubounded, max);
retval = _mm_or_si128(retval, ubounded);
retval = _mm_and_si128(retval, _mm_cmpgt_epi16(retval, zero));
return retval;
}
void aom_highbd_idct4x4_16_add_sse2(const tran_low_t *input, uint8_t *dest8,
int stride, int bd) {
tran_low_t out[4 * 4];
tran_low_t *outptr = out;
int i, j;
__m128i inptr[4];
__m128i sign_bits[2];
__m128i temp_mm, min_input, max_input;
int test;
uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
int optimised_cols = 0;
const __m128i zero = _mm_set1_epi16(0);
const __m128i eight = _mm_set1_epi16(8);
const __m128i max = _mm_set1_epi16(12043);
const __m128i min = _mm_set1_epi16(-12043);
// Load input into __m128i
inptr[0] = _mm_loadu_si128((const __m128i *)input);
inptr[1] = _mm_loadu_si128((const __m128i *)(input + 4));
inptr[2] = _mm_loadu_si128((const __m128i *)(input + 8));
inptr[3] = _mm_loadu_si128((const __m128i *)(input + 12));
// Pack to 16 bits
inptr[0] = _mm_packs_epi32(inptr[0], inptr[1]);
inptr[1] = _mm_packs_epi32(inptr[2], inptr[3]);
max_input = _mm_max_epi16(inptr[0], inptr[1]);
min_input = _mm_min_epi16(inptr[0], inptr[1]);
max_input = _mm_cmpgt_epi16(max_input, max);
min_input = _mm_cmplt_epi16(min_input, min);
temp_mm = _mm_or_si128(max_input, min_input);
test = _mm_movemask_epi8(temp_mm);
if (!test) {
// Do the row transform
aom_idct4_sse2(inptr);
// Check the min & max values
max_input = _mm_max_epi16(inptr[0], inptr[1]);
min_input = _mm_min_epi16(inptr[0], inptr[1]);
max_input = _mm_cmpgt_epi16(max_input, max);
min_input = _mm_cmplt_epi16(min_input, min);
temp_mm = _mm_or_si128(max_input, min_input);
test = _mm_movemask_epi8(temp_mm);
if (test) {
array_transpose_4x4(inptr);
sign_bits[0] = _mm_cmplt_epi16(inptr[0], zero);
sign_bits[1] = _mm_cmplt_epi16(inptr[1], zero);
inptr[3] = _mm_unpackhi_epi16(inptr[1], sign_bits[1]);
inptr[2] = _mm_unpacklo_epi16(inptr[1], sign_bits[1]);
inptr[1] = _mm_unpackhi_epi16(inptr[0], sign_bits[0]);
inptr[0] = _mm_unpacklo_epi16(inptr[0], sign_bits[0]);
_mm_storeu_si128((__m128i *)outptr, inptr[0]);
_mm_storeu_si128((__m128i *)(outptr + 4), inptr[1]);
_mm_storeu_si128((__m128i *)(outptr + 8), inptr[2]);
_mm_storeu_si128((__m128i *)(outptr + 12), inptr[3]);
} else {
// Set to use the optimised transform for the column
optimised_cols = 1;
}
} else {
// Run the un-optimised row transform
for (i = 0; i < 4; ++i) {
aom_highbd_idct4_c(input, outptr, bd);
input += 4;
outptr += 4;
}
}
if (optimised_cols) {
aom_idct4_sse2(inptr);
// Final round and shift
inptr[0] = _mm_add_epi16(inptr[0], eight);
inptr[1] = _mm_add_epi16(inptr[1], eight);
inptr[0] = _mm_srai_epi16(inptr[0], 4);
inptr[1] = _mm_srai_epi16(inptr[1], 4);
// Reconstruction and Store
{
__m128i d0 = _mm_loadl_epi64((const __m128i *)dest);
__m128i d2 = _mm_loadl_epi64((const __m128i *)(dest + stride * 2));
d0 = _mm_unpacklo_epi64(
d0, _mm_loadl_epi64((const __m128i *)(dest + stride)));
d2 = _mm_unpacklo_epi64(
d2, _mm_loadl_epi64((const __m128i *)(dest + stride * 3)));
d0 = clamp_high_sse2(_mm_adds_epi16(d0, inptr[0]), bd);
d2 = clamp_high_sse2(_mm_adds_epi16(d2, inptr[1]), bd);
// store input0
_mm_storel_epi64((__m128i *)dest, d0);
// store input1
d0 = _mm_srli_si128(d0, 8);
_mm_storel_epi64((__m128i *)(dest + stride), d0);
// store input2
_mm_storel_epi64((__m128i *)(dest + stride * 2), d2);
// store input3
d2 = _mm_srli_si128(d2, 8);
_mm_storel_epi64((__m128i *)(dest + stride * 3), d2);
}
} else {
// Run the un-optimised column transform
tran_low_t temp_in[4], temp_out[4];
// Columns
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) temp_in[j] = out[j * 4 + i];
aom_highbd_idct4_c(temp_in, temp_out, bd);
for (j = 0; j < 4; ++j) {
dest[j * stride + i] = highbd_clip_pixel_add(
dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 4), bd);
}
}
}
}
void aom_highbd_idct8x8_10_add_sse2(const tran_low_t *input, uint8_t *dest8,
int stride, int bd) {
tran_low_t out[8 * 8] = { 0 };
tran_low_t *outptr = out;
int i, j, test;
__m128i inptr[8];
__m128i min_input, max_input, temp1, temp2, sign_bits;
uint16_t *dest = CONVERT_TO_SHORTPTR(dest8);
const __m128i zero = _mm_set1_epi16(0);
const __m128i sixteen = _mm_set1_epi16(16);
const __m128i max = _mm_set1_epi16(6201);
const __m128i min = _mm_set1_epi16(-6201);
int optimised_cols = 0;
// Load input into __m128i & pack to 16 bits
for (i = 0; i < 8; i++) {
temp1 = _mm_loadu_si128((const __m128i *)(input + 8 * i));
temp2 = _mm_loadu_si128((const __m128i *)(input + 8 * i + 4));
inptr[i] = _mm_packs_epi32(temp1, temp2);
}
// Find the min & max for the row transform
// only first 4 row has non-zero coefs
max_input = _mm_max_epi16(inptr[0], inptr[1]);
min_input = _mm_min_epi16(inptr[0], inptr[1]);
for (i = 2; i < 4; i++) {
max_input = _mm_max_epi16(max_input, inptr[i]);
min_input = _mm_min_epi16(min_input, inptr[i]);
}
max_input = _mm_cmpgt_epi16(max_input, max);
min_input = _mm_cmplt_epi16(min_input, min);
temp1 = _mm_or_si128(max_input, min_input);
test = _mm_movemask_epi8(temp1);
if (!test) {
// Do the row transform
aom_idct8_sse2(inptr);
// Find the min & max for the column transform
// N.B. Only first 4 cols contain non-zero coeffs
max_input = _mm_max_epi16(inptr[0], inptr[1]);
min_input = _mm_min_epi16(inptr[0], inptr[1]);
for (i = 2; i < 8; i++) {
max_input = _mm_max_epi16(max_input, inptr[i]);
min_input = _mm_min_epi16(min_input, inptr[i]);
}
max_input = _mm_cmpgt_epi16(max_input, max);
min_input = _mm_cmplt_epi16(min_input, min);
temp1 = _mm_or_si128(max_input, min_input);
test = _mm_movemask_epi8(temp1);
if (test) {
// Use fact only first 4 rows contain non-zero coeffs
array_transpose_4X8(inptr, inptr);
for (i = 0; i < 4; i++) {
sign_bits = _mm_cmplt_epi16(inptr[i], zero);
temp1 = _mm_unpackhi_epi16(inptr[i], sign_bits);
temp2 = _mm_unpacklo_epi16(inptr[i], sign_bits);
_mm_storeu_si128((__m128i *)(outptr + 4 * (2 * i + 1)), temp1);
_mm_storeu_si128((__m128i *)(outptr + 4 * (2 * i)), temp2);
}
} else {
// Set to use the optimised transform for the column
optimised_cols = 1;
}
} else {
// Run the un-optimised row transform
for (i = 0; i < 4; ++i) {
aom_highbd_idct8_c(input, outptr, bd);
input += 8;
outptr += 8;
}
}
if (optimised_cols) {
aom_idct8_sse2(inptr);
// Final round & shift and Reconstruction and Store
{
__m128i d[8];
for (i = 0; i < 8; i++) {
inptr[i] = _mm_add_epi16(inptr[i], sixteen);
d[i] = _mm_loadu_si128((const __m128i *)(dest + stride * i));
inptr[i] = _mm_srai_epi16(inptr[i], 5);
d[i] = clamp_high_sse2(_mm_adds_epi16(d[i], inptr[i]), bd);
// Store
_mm_storeu_si128((__m128i *)(dest + stride * i), d[i]);
}
}
} else {
// Run the un-optimised column transform
tran_low_t temp_in[8], temp_out[8];
for (i = 0; i < 8; ++i) {
for (j = 0; j < 8; ++j) temp_in[j] = out[j * 8 + i];
aom_highbd_idct8_c(temp_in, temp_out, bd);
for (j = 0; j < 8; ++j) {
dest[j * stride + i] = highbd_clip_pixel_add(
dest[j * stride + i], ROUND_POWER_OF_TWO(temp_out[j], 5), bd);
}
}
}
}
#endif // CONFIG_HIGHBITDEPTH

View file

@ -93,6 +93,12 @@ MASKSAD8XN_SSSE3(8)
MASKSAD8XN_SSSE3(4)
MASKSAD4XN_SSSE3(8)
MASKSAD4XN_SSSE3(4)
#if CONFIG_EXT_PARTITION_TYPES
MASKSAD4XN_SSSE3(16)
MASKSADMXN_SSSE3(16, 4)
MASKSAD8XN_SSSE3(32)
MASKSADMXN_SSSE3(32, 8)
#endif
static INLINE unsigned int masked_sad_ssse3(const uint8_t *src_ptr,
int src_stride,
@ -283,6 +289,12 @@ HIGHBD_MASKSADMXN_SSSE3(8, 8)
HIGHBD_MASKSADMXN_SSSE3(8, 4)
HIGHBD_MASKSAD4XN_SSSE3(8)
HIGHBD_MASKSAD4XN_SSSE3(4)
#if CONFIG_EXT_PARTITION_TYPES
HIGHBD_MASKSAD4XN_SSSE3(16)
HIGHBD_MASKSADMXN_SSSE3(16, 4)
HIGHBD_MASKSADMXN_SSSE3(8, 32)
HIGHBD_MASKSADMXN_SSSE3(32, 8)
#endif
static INLINE unsigned int highbd_masked_sad_ssse3(
const uint8_t *src8, int src_stride, const uint8_t *a8, int a_stride,

View file

@ -126,6 +126,12 @@ MASK_SUBPIX_VAR8XH_SSSE3(8)
MASK_SUBPIX_VAR8XH_SSSE3(4)
MASK_SUBPIX_VAR4XH_SSSE3(8)
MASK_SUBPIX_VAR4XH_SSSE3(4)
#if CONFIG_EXT_PARTITION_TYPES
MASK_SUBPIX_VAR4XH_SSSE3(16)
MASK_SUBPIX_VAR_SSSE3(16, 4)
MASK_SUBPIX_VAR8XH_SSSE3(32)
MASK_SUBPIX_VAR_SSSE3(32, 8)
#endif
static INLINE __m128i filter_block(const __m128i a, const __m128i b,
const __m128i filter) {
@ -564,6 +570,7 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
const uint8_t *msk, int msk_stride, int invert_mask, uint32_t *sse) { \
uint64_t sse64; \
int sum; \
int64_t var; \
uint16_t temp[(H + 1) * W]; \
const uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
const uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \
@ -579,7 +586,8 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
msk_stride, W, H, &sse64, &sum); \
*sse = (uint32_t)ROUND_POWER_OF_TWO(sse64, 4); \
sum = ROUND_POWER_OF_TWO(sum, 2); \
return *sse - (uint32_t)(((int64_t)sum * sum) / (W * H)); \
var = (int64_t)(*sse) - (((int64_t)sum * sum) / (W * H)); \
return (var >= 0) ? (uint32_t)var : 0; \
} \
unsigned int aom_highbd_12_masked_sub_pixel_variance##W##x##H##_ssse3( \
const uint8_t *src8, int src_stride, int xoffset, int yoffset, \
@ -587,6 +595,7 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
const uint8_t *msk, int msk_stride, int invert_mask, uint32_t *sse) { \
uint64_t sse64; \
int sum; \
int64_t var; \
uint16_t temp[(H + 1) * W]; \
const uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
const uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \
@ -602,7 +611,8 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
msk_stride, W, H, &sse64, &sum); \
*sse = (uint32_t)ROUND_POWER_OF_TWO(sse64, 8); \
sum = ROUND_POWER_OF_TWO(sum, 4); \
return *sse - (uint32_t)(((int64_t)sum * sum) / (W * H)); \
var = (int64_t)(*sse) - (((int64_t)sum * sum) / (W * H)); \
return (var >= 0) ? (uint32_t)var : 0; \
}
#define HIGHBD_MASK_SUBPIX_VAR4XH_SSSE3(H) \
@ -634,6 +644,7 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
const uint8_t *msk, int msk_stride, int invert_mask, uint32_t *sse) { \
int sse_; \
int sum; \
int64_t var; \
uint16_t temp[(H + 1) * 4]; \
const uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
const uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \
@ -649,7 +660,8 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
msk_stride, H, &sse_, &sum); \
*sse = (uint32_t)ROUND_POWER_OF_TWO(sse_, 4); \
sum = ROUND_POWER_OF_TWO(sum, 2); \
return *sse - (uint32_t)(((int64_t)sum * sum) / (4 * H)); \
var = (int64_t)(*sse) - (((int64_t)sum * sum) / (4 * H)); \
return (var >= 0) ? (uint32_t)var : 0; \
} \
unsigned int aom_highbd_12_masked_sub_pixel_variance4x##H##_ssse3( \
const uint8_t *src8, int src_stride, int xoffset, int yoffset, \
@ -657,6 +669,7 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
const uint8_t *msk, int msk_stride, int invert_mask, uint32_t *sse) { \
int sse_; \
int sum; \
int64_t var; \
uint16_t temp[(H + 1) * 4]; \
const uint16_t *src = CONVERT_TO_SHORTPTR(src8); \
const uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); \
@ -672,7 +685,8 @@ static void highbd_masked_variance4xh(const uint16_t *src_ptr, int src_stride,
msk_stride, H, &sse_, &sum); \
*sse = (uint32_t)ROUND_POWER_OF_TWO(sse_, 8); \
sum = ROUND_POWER_OF_TWO(sum, 4); \
return *sse - (uint32_t)(((int64_t)sum * sum) / (4 * H)); \
var = (int64_t)(*sse) - (((int64_t)sum * sum) / (4 * H)); \
return (var >= 0) ? (uint32_t)var : 0; \
}
#if CONFIG_EXT_PARTITION
@ -693,6 +707,12 @@ HIGHBD_MASK_SUBPIX_VAR_SSSE3(8, 8)
HIGHBD_MASK_SUBPIX_VAR_SSSE3(8, 4)
HIGHBD_MASK_SUBPIX_VAR4XH_SSSE3(8)
HIGHBD_MASK_SUBPIX_VAR4XH_SSSE3(4)
#if CONFIG_EXT_PARTITION_TYPES
HIGHBD_MASK_SUBPIX_VAR4XH_SSSE3(16)
HIGHBD_MASK_SUBPIX_VAR_SSSE3(16, 4)
HIGHBD_MASK_SUBPIX_VAR_SSSE3(8, 32)
HIGHBD_MASK_SUBPIX_VAR_SSSE3(32, 8)
#endif
static INLINE __m128i highbd_filter_block(const __m128i a, const __m128i b,
const __m128i filter) {

View file

@ -137,6 +137,12 @@ OBMCSADWXH(8, 8)
OBMCSADWXH(8, 4)
OBMCSADWXH(4, 8)
OBMCSADWXH(4, 4)
#if CONFIG_EXT_PARTITION_TYPES
OBMCSADWXH(4, 16)
OBMCSADWXH(16, 4)
OBMCSADWXH(8, 32)
OBMCSADWXH(32, 8)
#endif
////////////////////////////////////////////////////////////////////////////////
// High bit-depth
@ -260,4 +266,10 @@ HBD_OBMCSADWXH(8, 8)
HBD_OBMCSADWXH(8, 4)
HBD_OBMCSADWXH(4, 8)
HBD_OBMCSADWXH(4, 4)
#if CONFIG_EXT_PARTITION_TYPES
HBD_OBMCSADWXH(4, 16)
HBD_OBMCSADWXH(16, 4)
HBD_OBMCSADWXH(8, 32)
HBD_OBMCSADWXH(32, 8)
#endif
#endif // CONFIG_HIGHBITDEPTH

View file

@ -146,6 +146,12 @@ OBMCVARWXH(8, 8)
OBMCVARWXH(8, 4)
OBMCVARWXH(4, 8)
OBMCVARWXH(4, 4)
#if CONFIG_EXT_PARTITION_TYPES
OBMCVARWXH(4, 16)
OBMCVARWXH(16, 4)
OBMCVARWXH(8, 32)
OBMCVARWXH(32, 8)
#endif
////////////////////////////////////////////////////////////////////////////////
// High bit-depth
@ -353,4 +359,10 @@ HBD_OBMCVARWXH(8, 8)
HBD_OBMCVARWXH(8, 4)
HBD_OBMCVARWXH(4, 8)
HBD_OBMCVARWXH(4, 4)
#if CONFIG_EXT_PARTITION_TYPES
HBD_OBMCVARWXH(4, 16)
HBD_OBMCVARWXH(16, 4)
HBD_OBMCVARWXH(8, 32)
HBD_OBMCVARWXH(32, 8)
#endif
#endif // CONFIG_HIGHBITDEPTH

View file

@ -251,3 +251,9 @@ SADNXN4D 8, 8
SADNXN4D 8, 4
SADNXN4D 4, 8
SADNXN4D 4, 4
%if CONFIG_EXT_PARTITION_TYPES
SADNXN4D 4, 16
SADNXN4D 16, 4
SADNXN4D 8, 32
SADNXN4D 32, 8
%endif

View file

@ -704,7 +704,12 @@ unsigned int aom_highbd_sad128x128_avg_avx2(const uint8_t *src, int src_stride,
static INLINE void get_4d_sad_from_mm256_epi32(const __m256i *v,
uint32_t *res) {
__m256i u0, u1, u2, u3;
#if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
const __m256i mask = _mm256_setr_epi32(UINT32_MAX, 0, UINT32_MAX, 0,
UINT32_MAX, 0, UINT32_MAX, 0);
#else
const __m256i mask = _mm256_set1_epi64x(UINT32_MAX);
#endif
__m128i sad;
// 8 32-bit summation

View file

@ -208,6 +208,10 @@ SAD32XN 16 ; sad32x16_sse2
SAD32XN 64, 1 ; sad32x64_avg_sse2
SAD32XN 32, 1 ; sad32x32_avg_sse2
SAD32XN 16, 1 ; sad32x16_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
SAD32XN 8 ; sad_32x8_sse2
SAD32XN 8, 1 ; sad_32x8_avg_sse2
%endif
; unsigned int aom_sad16x{8,16}_sse2(uint8_t *src, int src_stride,
; uint8_t *ref, int ref_stride);
@ -254,6 +258,10 @@ SAD16XN 8 ; sad16x8_sse2
SAD16XN 32, 1 ; sad16x32_avg_sse2
SAD16XN 16, 1 ; sad16x16_avg_sse2
SAD16XN 8, 1 ; sad16x8_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
SAD16XN 4 ; sad_16x4_sse2
SAD16XN 4, 1 ; sad_16x4_avg_sse2
%endif
; unsigned int aom_sad8x{8,16}_sse2(uint8_t *src, int src_stride,
; uint8_t *ref, int ref_stride);
@ -298,6 +306,10 @@ SAD8XN 4 ; sad8x4_sse2
SAD8XN 16, 1 ; sad8x16_avg_sse2
SAD8XN 8, 1 ; sad8x8_avg_sse2
SAD8XN 4, 1 ; sad8x4_avg_sse2
%if CONFIG_EXT_PARTITION_TYPES
SAD8XN 32 ; sad_8x32_sse2
SAD8XN 32, 1 ; sad_8x32_avg_sse2
%endif
; unsigned int aom_sad4x{4, 8}_sse2(uint8_t *src, int src_stride,
; uint8_t *ref, int ref_stride);
@ -343,3 +355,7 @@ SAD4XN 8 ; sad4x8_sse
SAD4XN 4 ; sad4x4_sse
SAD4XN 8, 1 ; sad4x8_avg_sse
SAD4XN 4, 1 ; sad4x4_avg_sse
%if CONFIG_EXT_PARTITION_TYPES
SAD4XN 16 ; sad_4x16_sse2
SAD4XN 16, 1 ; sad_4x16_avg_sse2
%endif

View file

@ -17,6 +17,9 @@
#include "aom_ports/mem.h"
#include "./av1_rtcd.h"
#include "av1/common/filter.h"
typedef void (*getNxMvar_fn_t)(const unsigned char *src, int src_stride,
const unsigned char *ref, int ref_stride,
unsigned int *sse, int *sum);
@ -335,6 +338,52 @@ unsigned int aom_mse16x16_sse2(const uint8_t *src, int src_stride,
return *sse;
}
#if CONFIG_EXT_PARTITION_TYPES
unsigned int aom_variance4x16_sse2(const uint8_t *src, int src_stride,
const uint8_t *ref, int ref_stride,
unsigned int *sse) {
int sum;
variance_sse2(src, src_stride, ref, ref_stride, 4, 16, sse, &sum,
get4x4var_sse2, 4);
assert(sum <= 255 * 4 * 16);
assert(sum >= -255 * 4 * 16);
return *sse - (unsigned int)(((int64_t)sum * sum) >> 6);
}
unsigned int aom_variance16x4_sse2(const uint8_t *src, int src_stride,
const uint8_t *ref, int ref_stride,
unsigned int *sse) {
int sum;
variance_sse2(src, src_stride, ref, ref_stride, 16, 4, sse, &sum,
get4x4var_sse2, 4);
assert(sum <= 255 * 16 * 4);
assert(sum >= -255 * 16 * 4);
return *sse - (unsigned int)(((int64_t)sum * sum) >> 6);
}
unsigned int aom_variance8x32_sse2(const uint8_t *src, int src_stride,
const uint8_t *ref, int ref_stride,
unsigned int *sse) {
int sum;
variance_sse2(src, src_stride, ref, ref_stride, 8, 32, sse, &sum,
aom_get8x8var_sse2, 8);
assert(sum <= 255 * 8 * 32);
assert(sum >= -255 * 8 * 32);
return *sse - (unsigned int)(((int64_t)sum * sum) >> 8);
}
unsigned int aom_variance32x8_sse2(const uint8_t *src, int src_stride,
const uint8_t *ref, int ref_stride,
unsigned int *sse) {
int sum;
variance_sse2(src, src_stride, ref, ref_stride, 32, 8, sse, &sum,
aom_get8x8var_sse2, 8);
assert(sum <= 255 * 32 * 8);
assert(sum >= -255 * 32 * 8);
return *sse - (unsigned int)(((int64_t)sum * sum) >> 8);
}
#endif
// The 2 unused parameters are place holders for PIC enabled build.
// These definitions are for functions defined in subpel_variance.asm
#define DECL(w, opt) \
@ -342,13 +391,13 @@ unsigned int aom_mse16x16_sse2(const uint8_t *src, int src_stride,
const uint8_t *src, ptrdiff_t src_stride, int x_offset, int y_offset, \
const uint8_t *dst, ptrdiff_t dst_stride, int height, unsigned int *sse, \
void *unused0, void *unused)
#define DECLS(opt1, opt2) \
DECL(4, opt1); \
DECL(8, opt1); \
DECL(16, opt1)
#define DECLS(opt) \
DECL(4, opt); \
DECL(8, opt); \
DECL(16, opt)
DECLS(sse2, sse2);
DECLS(ssse3, ssse3);
DECLS(sse2);
DECLS(ssse3);
#undef DECLS
#undef DECL
@ -384,23 +433,44 @@ DECLS(ssse3, ssse3);
return sse - (unsigned int)(cast_prod(cast se * se) >> (wlog2 + hlog2)); \
}
#define FNS(opt1, opt2) \
FN(64, 64, 16, 6, 6, opt1, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt1, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt1, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt1, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt1, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt1, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt1, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt1, (int32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt1, (int32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt1, (int32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt1, (int32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt1, (int32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt1, (int32_t), (int32_t))
#if CONFIG_EXT_PARTITION_TYPES
#define FNS(opt) \
FN(64, 64, 16, 6, 6, opt, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt, (int32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt, (int32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt, (int32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt, (int32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt, (int32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt, (int32_t), (int32_t)); \
FN(4, 16, 4, 2, 4, opt, (int32_t), (int32_t)); \
FN(16, 4, 16, 4, 2, opt, (int32_t), (int32_t)); \
FN(8, 32, 8, 3, 5, opt, (int32_t), (int32_t)); \
FN(32, 8, 16, 5, 3, opt, (int32_t), (int32_t))
#else
#define FNS(opt) \
FN(64, 64, 16, 6, 6, opt, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt, (int32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt, (int32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt, (int32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt, (int32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt, (int32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt, (int32_t), (int32_t))
#endif
FNS(sse2, sse2);
FNS(ssse3, ssse3);
FNS(sse2);
FNS(ssse3);
#undef FNS
#undef FN
@ -412,13 +482,13 @@ FNS(ssse3, ssse3);
const uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *sec, \
ptrdiff_t sec_stride, int height, unsigned int *sse, void *unused0, \
void *unused)
#define DECLS(opt1, opt2) \
DECL(4, opt1); \
DECL(8, opt1); \
DECL(16, opt1)
#define DECLS(opt) \
DECL(4, opt); \
DECL(8, opt); \
DECL(16, opt)
DECLS(sse2, sse2);
DECLS(ssse3, ssse3);
DECLS(sse2);
DECLS(ssse3);
#undef DECL
#undef DECLS
@ -455,236 +525,149 @@ DECLS(ssse3, ssse3);
return sse - (unsigned int)(cast_prod(cast se * se) >> (wlog2 + hlog2)); \
}
#define FNS(opt1, opt2) \
FN(64, 64, 16, 6, 6, opt1, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt1, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt1, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt1, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt1, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt1, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt1, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt1, (uint32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt1, (uint32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt1, (uint32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt1, (uint32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt1, (uint32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt1, (uint32_t), (int32_t))
#if CONFIG_EXT_PARTITION_TYPES
#define FNS(opt) \
FN(64, 64, 16, 6, 6, opt, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt, (uint32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt, (uint32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt, (uint32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt, (uint32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt, (uint32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt, (uint32_t), (int32_t)); \
FN(4, 16, 4, 2, 4, opt, (int32_t), (int32_t)); \
FN(16, 4, 16, 4, 2, opt, (int32_t), (int32_t)); \
FN(8, 32, 8, 3, 5, opt, (int32_t), (int32_t)); \
FN(32, 8, 16, 5, 3, opt, (int32_t), (int32_t))
#else
#define FNS(opt) \
FN(64, 64, 16, 6, 6, opt, (int64_t), (int64_t)); \
FN(64, 32, 16, 6, 5, opt, (int64_t), (int64_t)); \
FN(32, 64, 16, 5, 6, opt, (int64_t), (int64_t)); \
FN(32, 32, 16, 5, 5, opt, (int64_t), (int64_t)); \
FN(32, 16, 16, 5, 4, opt, (int64_t), (int64_t)); \
FN(16, 32, 16, 4, 5, opt, (int64_t), (int64_t)); \
FN(16, 16, 16, 4, 4, opt, (uint32_t), (int64_t)); \
FN(16, 8, 16, 4, 3, opt, (uint32_t), (int32_t)); \
FN(8, 16, 8, 3, 4, opt, (uint32_t), (int32_t)); \
FN(8, 8, 8, 3, 3, opt, (uint32_t), (int32_t)); \
FN(8, 4, 8, 3, 2, opt, (uint32_t), (int32_t)); \
FN(4, 8, 4, 2, 3, opt, (uint32_t), (int32_t)); \
FN(4, 4, 4, 2, 2, opt, (uint32_t), (int32_t))
#endif
FNS(sse2, sse);
FNS(ssse3, ssse3);
FNS(sse2);
FNS(ssse3);
#undef FNS
#undef FN
void aom_upsampled_pred_sse2(uint8_t *comp_pred, int width, int height,
int subpel_x_q3, int subpel_y_q3,
const uint8_t *ref, int ref_stride) {
int i, j;
int stride = ref_stride << 3;
if (width >= 16) {
// read 16 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 16) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i s2 = _mm_loadu_si128((const __m128i *)(ref + 32));
__m128i s3 = _mm_loadu_si128((const __m128i *)(ref + 48));
__m128i s4 = _mm_loadu_si128((const __m128i *)(ref + 64));
__m128i s5 = _mm_loadu_si128((const __m128i *)(ref + 80));
__m128i s6 = _mm_loadu_si128((const __m128i *)(ref + 96));
__m128i s7 = _mm_loadu_si128((const __m128i *)(ref + 112));
__m128i t0, t1, t2, t3;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
t1 = _mm_unpacklo_epi8(s2, s3);
s3 = _mm_unpackhi_epi8(s2, s3);
t2 = _mm_unpacklo_epi8(s4, s5);
s5 = _mm_unpackhi_epi8(s4, s5);
t3 = _mm_unpacklo_epi8(s6, s7);
s7 = _mm_unpackhi_epi8(s6, s7);
s0 = _mm_unpacklo_epi8(t0, s1);
s2 = _mm_unpacklo_epi8(t1, s3);
s4 = _mm_unpacklo_epi8(t2, s5);
s6 = _mm_unpacklo_epi8(t3, s7);
s0 = _mm_unpacklo_epi32(s0, s2);
s4 = _mm_unpacklo_epi32(s4, s6);
s0 = _mm_unpacklo_epi64(s0, s4);
_mm_storeu_si128((__m128i *)(comp_pred), s0);
if (!subpel_x_q3 && !subpel_y_q3) {
if (width >= 16) {
int i;
assert(!(width & 15));
/*Read 16 pixels one row at a time.*/
for (i = 0; i < height; i++) {
int j;
for (j = 0; j < width; j += 16) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
_mm_storeu_si128((__m128i *)comp_pred, s0);
comp_pred += 16;
ref += 16;
}
ref += ref_stride - width;
}
} else if (width >= 8) {
int i;
assert(!(width & 7));
assert(!(height & 1));
/*Read 8 pixels two rows at a time.*/
for (i = 0; i < height; i += 2) {
__m128i s0 = _mm_loadl_epi64((const __m128i *)ref);
__m128i s1 = _mm_loadl_epi64((const __m128i *)(ref + ref_stride));
__m128i t0 = _mm_unpacklo_epi64(s0, s1);
_mm_storeu_si128((__m128i *)comp_pred, t0);
comp_pred += 16;
ref += 16 * 8;
ref += 2 * ref_stride;
}
ref += stride - (width << 3);
}
} else if (width >= 8) {
// read 8 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 8) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i s2 = _mm_loadu_si128((const __m128i *)(ref + 32));
__m128i s3 = _mm_loadu_si128((const __m128i *)(ref + 48));
__m128i t0, t1;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
t1 = _mm_unpacklo_epi8(s2, s3);
s3 = _mm_unpackhi_epi8(s2, s3);
s0 = _mm_unpacklo_epi8(t0, s1);
s2 = _mm_unpacklo_epi8(t1, s3);
s0 = _mm_unpacklo_epi32(s0, s2);
_mm_storel_epi64((__m128i *)(comp_pred), s0);
comp_pred += 8;
ref += 8 * 8;
} else {
int i;
assert(!(width & 3));
assert(!(height & 3));
/*Read 4 pixels four rows at a time.*/
for (i = 0; i < height; i++) {
__m128i s0 = _mm_cvtsi32_si128(*(const uint32_t *)ref);
__m128i s1 = _mm_cvtsi32_si128(*(const uint32_t *)(ref + ref_stride));
__m128i s2 =
_mm_cvtsi32_si128(*(const uint32_t *)(ref + 2 * ref_stride));
__m128i s3 =
_mm_cvtsi32_si128(*(const uint32_t *)(ref + 3 * ref_stride));
__m128i t0 = _mm_unpacklo_epi32(s0, s1);
__m128i t1 = _mm_unpacklo_epi32(s2, s3);
__m128i u0 = _mm_unpacklo_epi64(t0, t1);
_mm_storeu_si128((__m128i *)comp_pred, u0);
comp_pred += 16;
ref += 4 * ref_stride;
}
ref += stride - (width << 3);
}
} else {
// read 4 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 4) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i t0;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
s0 = _mm_unpacklo_epi8(t0, s1);
*(int *)comp_pred = _mm_cvtsi128_si32(s0);
comp_pred += 4;
ref += 4 * 8;
}
ref += stride - (width << 3);
InterpFilterParams filter;
filter = av1_get_interp_filter_params(EIGHTTAP_REGULAR);
if (!subpel_y_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
aom_convolve8_horiz(ref, ref_stride, comp_pred, width, kernel, 16, NULL,
-1, width, height);
} else if (!subpel_x_q3) {
const int16_t *kernel;
kernel = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
aom_convolve8_vert(ref, ref_stride, comp_pred, width, NULL, -1, kernel,
16, width, height);
} else {
DECLARE_ALIGNED(16, uint8_t,
temp[((MAX_SB_SIZE * 2 + 16) + 16) * MAX_SB_SIZE]);
const int16_t *kernel_x;
const int16_t *kernel_y;
int intermediate_height;
kernel_x = av1_get_interp_filter_subpel_kernel(filter, subpel_x_q3 << 1);
kernel_y = av1_get_interp_filter_subpel_kernel(filter, subpel_y_q3 << 1);
intermediate_height =
(((height - 1) * 8 + subpel_y_q3) >> 3) + filter.taps;
assert(intermediate_height <= (MAX_SB_SIZE * 2 + 16) + 16);
aom_convolve8_horiz(ref - ref_stride * ((filter.taps >> 1) - 1),
ref_stride, temp, MAX_SB_SIZE, kernel_x, 16, NULL, -1,
width, intermediate_height);
aom_convolve8_vert(temp + MAX_SB_SIZE * ((filter.taps >> 1) - 1),
MAX_SB_SIZE, comp_pred, width, NULL, -1, kernel_y, 16,
width, height);
}
}
}
void aom_comp_avg_upsampled_pred_sse2(uint8_t *comp_pred, const uint8_t *pred,
int width, int height, const uint8_t *ref,
int width, int height, int subpel_x_q3,
int subpel_y_q3, const uint8_t *ref,
int ref_stride) {
const __m128i zero = _mm_set1_epi16(0);
const __m128i one = _mm_set1_epi16(1);
int i, j;
int stride = ref_stride << 3;
if (width >= 16) {
// read 16 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 16) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i s2 = _mm_loadu_si128((const __m128i *)(ref + 32));
__m128i s3 = _mm_loadu_si128((const __m128i *)(ref + 48));
__m128i s4 = _mm_loadu_si128((const __m128i *)(ref + 64));
__m128i s5 = _mm_loadu_si128((const __m128i *)(ref + 80));
__m128i s6 = _mm_loadu_si128((const __m128i *)(ref + 96));
__m128i s7 = _mm_loadu_si128((const __m128i *)(ref + 112));
__m128i p0 = _mm_loadu_si128((const __m128i *)pred);
__m128i p1;
__m128i t0, t1, t2, t3;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
t1 = _mm_unpacklo_epi8(s2, s3);
s3 = _mm_unpackhi_epi8(s2, s3);
t2 = _mm_unpacklo_epi8(s4, s5);
s5 = _mm_unpackhi_epi8(s4, s5);
t3 = _mm_unpacklo_epi8(s6, s7);
s7 = _mm_unpackhi_epi8(s6, s7);
s0 = _mm_unpacklo_epi8(t0, s1);
s2 = _mm_unpacklo_epi8(t1, s3);
s4 = _mm_unpacklo_epi8(t2, s5);
s6 = _mm_unpacklo_epi8(t3, s7);
s0 = _mm_unpacklo_epi32(s0, s2);
s4 = _mm_unpacklo_epi32(s4, s6);
s0 = _mm_unpacklo_epi8(s0, zero);
s4 = _mm_unpacklo_epi8(s4, zero);
p1 = _mm_unpackhi_epi8(p0, zero);
p0 = _mm_unpacklo_epi8(p0, zero);
p0 = _mm_adds_epu16(s0, p0);
p1 = _mm_adds_epu16(s4, p1);
p0 = _mm_adds_epu16(p0, one);
p1 = _mm_adds_epu16(p1, one);
p0 = _mm_srli_epi16(p0, 1);
p1 = _mm_srli_epi16(p1, 1);
p0 = _mm_packus_epi16(p0, p1);
_mm_storeu_si128((__m128i *)(comp_pred), p0);
comp_pred += 16;
pred += 16;
ref += 16 * 8;
}
ref += stride - (width << 3);
}
} else if (width >= 8) {
// read 8 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 8) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i s2 = _mm_loadu_si128((const __m128i *)(ref + 32));
__m128i s3 = _mm_loadu_si128((const __m128i *)(ref + 48));
__m128i p0 = _mm_loadl_epi64((const __m128i *)pred);
__m128i t0, t1;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
t1 = _mm_unpacklo_epi8(s2, s3);
s3 = _mm_unpackhi_epi8(s2, s3);
s0 = _mm_unpacklo_epi8(t0, s1);
s2 = _mm_unpacklo_epi8(t1, s3);
s0 = _mm_unpacklo_epi32(s0, s2);
s0 = _mm_unpacklo_epi8(s0, zero);
p0 = _mm_unpacklo_epi8(p0, zero);
p0 = _mm_adds_epu16(s0, p0);
p0 = _mm_adds_epu16(p0, one);
p0 = _mm_srli_epi16(p0, 1);
p0 = _mm_packus_epi16(p0, zero);
_mm_storel_epi64((__m128i *)(comp_pred), p0);
comp_pred += 8;
pred += 8;
ref += 8 * 8;
}
ref += stride - (width << 3);
}
} else {
// read 4 points at one time
for (i = 0; i < height; i++) {
for (j = 0; j < width; j += 4) {
__m128i s0 = _mm_loadu_si128((const __m128i *)ref);
__m128i s1 = _mm_loadu_si128((const __m128i *)(ref + 16));
__m128i p0 = _mm_cvtsi32_si128(*(const uint32_t *)pred);
__m128i t0;
t0 = _mm_unpacklo_epi8(s0, s1);
s1 = _mm_unpackhi_epi8(s0, s1);
s0 = _mm_unpacklo_epi8(t0, s1);
s0 = _mm_unpacklo_epi8(s0, zero);
p0 = _mm_unpacklo_epi8(p0, zero);
p0 = _mm_adds_epu16(s0, p0);
p0 = _mm_adds_epu16(p0, one);
p0 = _mm_srli_epi16(p0, 1);
p0 = _mm_packus_epi16(p0, zero);
*(int *)comp_pred = _mm_cvtsi128_si32(p0);
comp_pred += 4;
pred += 4;
ref += 4 * 8;
}
ref += stride - (width << 3);
}
int n;
int i;
aom_upsampled_pred(comp_pred, width, height, subpel_x_q3, subpel_y_q3, ref,
ref_stride);
/*The total number of pixels must be a multiple of 16 (e.g., 4x4).*/
assert(!(width * height & 15));
n = width * height >> 4;
for (i = 0; i < n; i++) {
__m128i s0 = _mm_loadu_si128((const __m128i *)comp_pred);
__m128i p0 = _mm_loadu_si128((const __m128i *)pred);
_mm_storeu_si128((__m128i *)comp_pred, _mm_avg_epu8(s0, p0));
comp_pred += 16;
pred += 16;
}
}

View file

@ -21,7 +21,7 @@ set(AOM_MEM_SOURCES
function (setup_aom_mem_targets)
add_library(aom_mem OBJECT ${AOM_MEM_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_mem PARENT_SCOPE)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_mem>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_mem>)
endfunction ()
endif () # AOM_AOM_MEM_AOM_MEM_CMAKE_

View file

@ -45,25 +45,24 @@ function (setup_aom_ports_targets)
elseif ("${AOM_TARGET_CPU}" MATCHES "arm")
add_library(aom_ports OBJECT ${AOM_PORTS_SOURCES_ARM})
set(aom_ports_has_symbols 1)
list(APPEND AOM_LIB_TARGETS aom_ports)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_ports>)
endif ()
if (aom_ports_has_symbols)
target_sources(aom_ports PUBLIC ${AOM_PORTS_INCLUDES})
target_sources(aom_ports PRIVATE ${AOM_PORTS_INCLUDES})
if ("${AOM_TARGET_CPU}" STREQUAL "x86" OR
"${AOM_TARGET_CPU}" STREQUAL "x86_64")
target_sources(aom_ports PUBLIC ${AOM_PORTS_INCLUDES_X86})
target_sources(aom_ports PRIVATE ${AOM_PORTS_INCLUDES_X86})
endif ()
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} PARENT_SCOPE)
else ()
target_sources(aom PUBLIC ${AOM_PORTS_INCLUDES})
target_sources(aom PRIVATE ${AOM_PORTS_INCLUDES})
if ("${AOM_TARGET_CPU}" STREQUAL "x86" OR
"${AOM_TARGET_CPU}" STREQUAL "x86_64")
target_sources(aom PUBLIC ${AOM_PORTS_INCLUDES_X86})
target_sources(aom PRIVATE ${AOM_PORTS_INCLUDES_X86})
endif ()
endif ()
endfunction ()

View file

@ -26,11 +26,11 @@ set(AOM_SCALE_INTRIN_DSPR2
# target must exist before this function is called.
function (setup_aom_scale_targets)
add_library(aom_scale OBJECT ${AOM_SCALE_SOURCES})
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_scale>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_scale>)
if (HAVE_DSPR2)
add_intrinsics_object_library("" "dspr2" "aom_scale"
"AOM_SCALE_INTRIN_DSPR2")
"AOM_SCALE_INTRIN_DSPR2" "aom_scale")
endif ()
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_scale PARENT_SCOPE)

View file

@ -69,6 +69,10 @@ typedef struct yv12_buffer_config {
int subsampling_y;
unsigned int bit_depth;
aom_color_space_t color_space;
#if CONFIG_COLORSPACE_HEADERS
aom_transfer_function_t transfer_function;
aom_chroma_sample_position_t chroma_sample_position;
#endif
aom_color_range_t color_range;
int render_width;
int render_height;

View file

@ -28,7 +28,7 @@ endif ()
function (setup_aom_util_targets)
add_library(aom_util OBJECT ${AOM_UTIL_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_util PARENT_SCOPE)
target_sources(aom PUBLIC $<TARGET_OBJECTS:aom_util>)
target_sources(aom PRIVATE $<TARGET_OBJECTS:aom_util>)
endfunction ()
endif () # AOM_AOM_UTIL_AOM_UTIL_CMAKE_

View file

@ -519,7 +519,7 @@ static int main_loop(int argc, const char **argv_) {
int use_y4m = 1;
int opt_yv12 = 0;
int opt_i420 = 0;
aom_codec_dec_cfg_t cfg = { 0, 0, 0 };
aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH };
#if CONFIG_HIGHBITDEPTH
unsigned int output_bit_depth = 0;
#endif

View file

@ -194,9 +194,6 @@ static const arg_def_t disable_warning_prompt =
"Display warnings, but do not prompt user to continue.");
#if CONFIG_HIGHBITDEPTH
static const arg_def_t test16bitinternalarg = ARG_DEF(
NULL, "test-16bit-internal", 0, "Force use of 16 bit internal buffer");
static const struct arg_enum_list bitdepth_enum[] = {
{ "8", AOM_BITS_8 }, { "10", AOM_BITS_10 }, { "12", AOM_BITS_12 }, { NULL, 0 }
};
@ -258,6 +255,11 @@ static const arg_def_t error_resilient =
ARG_DEF(NULL, "error-resilient", 1, "Enable error resiliency features");
static const arg_def_t lag_in_frames =
ARG_DEF(NULL, "lag-in-frames", 1, "Max number of frames to lag");
#if CONFIG_EXT_TILE
static const arg_def_t large_scale_tile =
ARG_DEF(NULL, "large-scale-tile", 1,
"Large scale tile coding (0: off (default), 1: on)");
#endif // CONFIG_EXT_TILE
static const arg_def_t *global_args[] = { &use_yv12,
&use_i420,
@ -276,24 +278,31 @@ static const arg_def_t *global_args[] = { &use_yv12,
&framerate,
&error_resilient,
#if CONFIG_HIGHBITDEPTH
&test16bitinternalarg,
&bitdeptharg,
#endif
&lag_in_frames,
#if CONFIG_EXT_TILE
&large_scale_tile,
#endif // CONFIG_EXT_TILE
NULL };
static const arg_def_t dropframe_thresh =
ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
static const arg_def_t resize_allowed =
ARG_DEF(NULL, "resize-allowed", 1, "Spatial resampling enabled (bool)");
static const arg_def_t resize_width =
ARG_DEF(NULL, "resize-width", 1, "Width of encoded frame");
static const arg_def_t resize_height =
ARG_DEF(NULL, "resize-height", 1, "Height of encoded frame");
static const arg_def_t resize_up_thresh =
ARG_DEF(NULL, "resize-up", 1, "Upscale threshold (buf %)");
static const arg_def_t resize_down_thresh =
ARG_DEF(NULL, "resize-down", 1, "Downscale threshold (buf %)");
static const arg_def_t resize_mode =
ARG_DEF(NULL, "resize-mode", 1, "Frame resize mode");
static const arg_def_t resize_numerator =
ARG_DEF(NULL, "resize-numerator", 1, "Frame resize numerator");
static const arg_def_t resize_kf_numerator =
ARG_DEF(NULL, "resize-kf-numerator", 1, "Frame resize keyframe numerator");
#if CONFIG_FRAME_SUPERRES
static const arg_def_t superres_mode =
ARG_DEF(NULL, "superres-mode", 1, "Frame super-resolution mode");
static const arg_def_t superres_numerator =
ARG_DEF(NULL, "superres-numerator", 1, "Frame super-resolution numerator");
static const arg_def_t superres_kf_numerator =
ARG_DEF(NULL, "superres-kf-numerator", 1,
"Frame super-resolution keyframe numerator");
#endif // CONFIG_FRAME_SUPERRES
static const struct arg_enum_list end_usage_enum[] = { { "vbr", AOM_VBR },
{ "cbr", AOM_CBR },
{ "cq", AOM_CQ },
@ -317,12 +326,25 @@ static const arg_def_t buf_initial_sz =
ARG_DEF(NULL, "buf-initial-sz", 1, "Client initial buffer size (ms)");
static const arg_def_t buf_optimal_sz =
ARG_DEF(NULL, "buf-optimal-sz", 1, "Client optimal buffer size (ms)");
static const arg_def_t *rc_args[] = {
&dropframe_thresh, &resize_allowed, &resize_width, &resize_height,
&resize_up_thresh, &resize_down_thresh, &end_usage, &target_bitrate,
&min_quantizer, &max_quantizer, &undershoot_pct, &overshoot_pct,
&buf_sz, &buf_initial_sz, &buf_optimal_sz, NULL
};
static const arg_def_t *rc_args[] = { &dropframe_thresh,
&resize_mode,
&resize_numerator,
&resize_kf_numerator,
#if CONFIG_FRAME_SUPERRES
&superres_mode,
&superres_numerator,
&superres_kf_numerator,
#endif // CONFIG_FRAME_SUPERRES
&end_usage,
&target_bitrate,
&min_quantizer,
&max_quantizer,
&undershoot_pct,
&overshoot_pct,
&buf_sz,
&buf_initial_sz,
&buf_optimal_sz,
NULL };
static const arg_def_t bias_pct =
ARG_DEF(NULL, "bias-pct", 1, "CBR/VBR bias (0=CBR, 100=VBR)");
@ -367,17 +389,16 @@ static const arg_def_t max_intra_rate_pct =
#if CONFIG_AV1_ENCODER
static const arg_def_t cpu_used_av1 =
ARG_DEF(NULL, "cpu-used", 1, "CPU Used (0..8)");
#if CONFIG_EXT_TILE
static const arg_def_t single_tile_decoding =
ARG_DEF(NULL, "single-tile-decoding", 1,
"Single tile decoding (0: off (default), 1: on)");
#endif // CONFIG_EXT_TILE
static const arg_def_t tile_cols =
ARG_DEF(NULL, "tile-columns", 1, "Number of tile columns to use, log2");
static const arg_def_t tile_rows =
ARG_DEF(NULL, "tile-rows", 1,
"Number of tile rows to use, log2 (set to 0 while threads > 1)");
#if CONFIG_EXT_TILE
static const arg_def_t tile_encoding_mode =
ARG_DEF(NULL, "tile-encoding-mode", 1,
"Tile encoding mode (0: normal"
" (default), 1: vr)");
#endif
#if CONFIG_DEPENDENT_HORZTILES
static const arg_def_t tile_dependent_rows =
ARG_DEF(NULL, "tile-dependent-rows", 1, "Enable dependent Tile rows");
@ -397,14 +418,12 @@ static const arg_def_t qm_min = ARG_DEF(
static const arg_def_t qm_max = ARG_DEF(
NULL, "qm-max", 1, "Max quant matrix flatness (0..15), default is 16");
#endif
#if CONFIG_TILE_GROUPS
static const arg_def_t num_tg = ARG_DEF(
NULL, "num-tile-groups", 1, "Maximum number of tile groups, default is 1");
static const arg_def_t mtu_size =
ARG_DEF(NULL, "mtu-size", 1,
"MTU size for a tile group, default is 0 (no MTU targeting), "
"overrides maximum number of tile groups");
#endif
#if CONFIG_TEMPMV_SIGNALING
static const arg_def_t disable_tempmv = ARG_DEF(
NULL, "disable-tempmv", 1, "Disable temporal mv prediction (default is 0)");
@ -449,9 +468,16 @@ static const struct arg_enum_list color_space_enum[] = {
{ "bt709", AOM_CS_BT_709 },
{ "smpte170", AOM_CS_SMPTE_170 },
{ "smpte240", AOM_CS_SMPTE_240 },
#if CONFIG_COLORSPACE_HEADERS
{ "bt2020ncl", AOM_CS_BT_2020_NCL },
{ "bt2020cl", AOM_CS_BT_2020_CL },
{ "sRGB", AOM_CS_SRGB },
{ "ICtCp", AOM_CS_ICTCP },
#else
{ "bt2020", AOM_CS_BT_2020 },
{ "reserved", AOM_CS_RESERVED },
{ "sRGB", AOM_CS_SRGB },
#endif
{ NULL, 0 }
};
@ -459,6 +485,32 @@ static const arg_def_t input_color_space =
ARG_DEF_ENUM(NULL, "color-space", 1, "The color space of input content:",
color_space_enum);
#if CONFIG_COLORSPACE_HEADERS
static const struct arg_enum_list transfer_function_enum[] = {
{ "unknown", AOM_TF_UNKNOWN },
{ "bt709", AOM_TF_BT_709 },
{ "pq", AOM_TF_PQ },
{ "hlg", AOM_TF_HLG },
{ NULL, 0 }
};
static const arg_def_t input_transfer_function = ARG_DEF_ENUM(
NULL, "transfer-function", 1, "The transfer function of input content:",
transfer_function_enum);
static const struct arg_enum_list chroma_sample_position_enum[] = {
{ "unknown", AOM_CSP_UNKNOWN },
{ "vertical", AOM_CSP_VERTICAL },
{ "colocated", AOM_CSP_COLOCATED },
{ NULL, 0 }
};
static const arg_def_t input_chroma_sample_position =
ARG_DEF_ENUM(NULL, "chroma-sample-position", 1,
"The chroma sample position when chroma 4:2:0 is signaled:",
chroma_sample_position_enum);
#endif
static const struct arg_enum_list tune_content_enum[] = {
{ "default", AOM_CONTENT_DEFAULT },
{ "screen", AOM_CONTENT_SCREEN },
@ -485,11 +537,11 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
&auto_altref,
&sharpness,
&static_thresh,
#if CONFIG_EXT_TILE
&single_tile_decoding,
#endif // CONFIG_EXT_TILE
&tile_cols,
&tile_rows,
#if CONFIG_EXT_TILE
&tile_encoding_mode,
#endif
#if CONFIG_DEPENDENT_HORZTILES
&tile_dependent_rows,
#endif
@ -518,15 +570,17 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
&noise_sens,
&tune_content,
&input_color_space,
#if CONFIG_COLORSPACE_HEADERS
&input_transfer_function,
&input_chroma_sample_position,
#endif
&min_gf_interval,
&max_gf_interval,
#if CONFIG_EXT_PARTITION
&superblock_size,
#endif // CONFIG_EXT_PARTITION
#if CONFIG_TILE_GROUPS
&num_tg,
&mtu_size,
#endif
#if CONFIG_TEMPMV_SIGNALING
&disable_tempmv,
#endif
@ -539,11 +593,11 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
AOME_SET_ENABLEAUTOALTREF,
AOME_SET_SHARPNESS,
AOME_SET_STATIC_THRESHOLD,
#if CONFIG_EXT_TILE
AV1E_SET_SINGLE_TILE_DECODING,
#endif // CONFIG_EXT_TILE
AV1E_SET_TILE_COLUMNS,
AV1E_SET_TILE_ROWS,
#if CONFIG_EXT_TILE
AV1E_SET_TILE_ENCODING_MODE,
#endif
#if CONFIG_DEPENDENT_HORZTILES
AV1E_SET_TILE_DEPENDENT_ROWS,
#endif
@ -572,15 +626,17 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
AV1E_SET_NOISE_SENSITIVITY,
AV1E_SET_TUNE_CONTENT,
AV1E_SET_COLOR_SPACE,
#if CONFIG_COLORSPACE_HEADERS
AV1E_SET_TRANSFER_FUNCTION,
AV1E_SET_CHROMA_SAMPLE_POSITION,
#endif
AV1E_SET_MIN_GF_INTERVAL,
AV1E_SET_MAX_GF_INTERVAL,
#if CONFIG_EXT_PARTITION
AV1E_SET_SUPERBLOCK_SIZE,
#endif // CONFIG_EXT_PARTITION
#if CONFIG_TILE_GROUPS
AV1E_SET_NUM_TG,
AV1E_SET_MTU,
#endif
#if CONFIG_TEMPMV_SIGNALING
AV1E_SET_DISABLE_TEMPMV,
#endif
@ -651,10 +707,8 @@ struct stream_config {
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
int arg_ctrl_cnt;
int write_webm;
#if CONFIG_HIGHBITDEPTH
// whether to use 16bit internal buffers
int use_16bit_internal;
#endif
};
struct stream_state {
@ -906,9 +960,7 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
static const int *ctrl_args_map = NULL;
struct stream_config *config = &stream->config;
int eos_mark_found = 0;
#if CONFIG_HIGHBITDEPTH
int test_16bit_internal = 0;
#endif
int webm_forced = 0;
// Handle codec specific options
if (0) {
@ -937,6 +989,13 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
if (arg_match(&arg, &outputfile, argi)) {
config->out_fn = arg.val;
if (!webm_forced) {
const size_t out_fn_len = strlen(config->out_fn);
if (out_fn_len >= 4 &&
!strcmp(config->out_fn + out_fn_len - 4, ".ivf")) {
config->write_webm = 0;
}
}
} else if (arg_match(&arg, &fpf_name, argi)) {
config->stats_fn = arg.val;
#if CONFIG_FP_MB_STATS
@ -946,6 +1005,7 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
} else if (arg_match(&arg, &use_webm, argi)) {
#if CONFIG_WEBM_IO
config->write_webm = 1;
webm_forced = 1;
#else
die("Error: --webm specified but webm is disabled.");
#endif
@ -976,18 +1036,26 @@ 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 CONFIG_EXT_TILE
} else if (arg_match(&arg, &large_scale_tile, argi)) {
config->cfg.large_scale_tile = arg_parse_uint(&arg);
#endif // CONFIG_EXT_TILE
} else if (arg_match(&arg, &dropframe_thresh, argi)) {
config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_allowed, argi)) {
config->cfg.rc_resize_allowed = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_width, argi)) {
config->cfg.rc_scaled_width = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_height, argi)) {
config->cfg.rc_scaled_height = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_up_thresh, argi)) {
config->cfg.rc_resize_up_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_down_thresh, argi)) {
config->cfg.rc_resize_down_thresh = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_mode, argi)) {
config->cfg.rc_resize_mode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_numerator, argi)) {
config->cfg.rc_resize_numerator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &resize_kf_numerator, argi)) {
config->cfg.rc_resize_kf_numerator = arg_parse_uint(&arg);
#if CONFIG_FRAME_SUPERRES
} else if (arg_match(&arg, &superres_mode, argi)) {
config->cfg.rc_superres_mode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_numerator, argi)) {
config->cfg.rc_superres_numerator = arg_parse_uint(&arg);
} else if (arg_match(&arg, &superres_kf_numerator, argi)) {
config->cfg.rc_superres_kf_numerator = arg_parse_uint(&arg);
#endif // CONFIG_FRAME_SUPERRES
} else if (arg_match(&arg, &end_usage, argi)) {
config->cfg.rc_end_usage = arg_parse_enum_or_int(&arg);
} else if (arg_match(&arg, &target_bitrate, argi)) {
@ -1026,13 +1094,6 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
config->cfg.kf_max_dist = arg_parse_uint(&arg);
} else if (arg_match(&arg, &kf_disabled, argi)) {
config->cfg.kf_mode = AOM_KF_DISABLED;
#if CONFIG_HIGHBITDEPTH
} else if (arg_match(&arg, &test16bitinternalarg, argi)) {
if (strcmp(global->codec->name, "av1") == 0 ||
strcmp(global->codec->name, "av1") == 0) {
test_16bit_internal = 1;
}
#endif
} else {
int i, match = 0;
for (i = 0; ctrl_args[i]; i++) {
@ -1062,18 +1123,14 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
}
#if CONFIG_HIGHBITDEPTH
config->use_16bit_internal =
test_16bit_internal || (config->cfg.g_profile > 1) || !CONFIG_LOWBITDEPTH;
config->cfg.g_bit_depth > AOM_BITS_8 || !CONFIG_LOWBITDEPTH;
#endif
return eos_mark_found;
}
#define FOREACH_STREAM(func) \
do { \
struct stream_state *stream; \
for (stream = streams; stream; stream = stream->next) { \
func; \
} \
} while (0)
#define FOREACH_STREAM(iterator, list) \
for (struct stream_state *iterator = list; iterator; \
iterator = iterator->next)
static void validate_stream_config(const struct stream_state *stream,
const struct AvxEncoderConfig *global) {
@ -1183,6 +1240,8 @@ static void show_stream_config(struct stream_state *stream,
if (stream->next || stream->index)
fprintf(stderr, "\nStream Index: %d\n", stream->index);
fprintf(stderr, "Destination file: %s\n", stream->config.out_fn);
fprintf(stderr, "Coding path: %s\n",
stream->config.use_16bit_internal ? "HBD" : "LBD");
fprintf(stderr, "Encoder parameters:\n");
SHOW(g_usage);
@ -1197,12 +1256,18 @@ static void show_stream_config(struct stream_state *stream,
SHOW(g_error_resilient);
SHOW(g_pass);
SHOW(g_lag_in_frames);
#if CONFIG_EXT_TILE
SHOW(large_scale_tile);
#endif // CONFIG_EXT_TILE
SHOW(rc_dropframe_thresh);
SHOW(rc_resize_allowed);
SHOW(rc_scaled_width);
SHOW(rc_scaled_height);
SHOW(rc_resize_up_thresh);
SHOW(rc_resize_down_thresh);
SHOW(rc_resize_mode);
SHOW(rc_resize_numerator);
SHOW(rc_resize_kf_numerator);
#if CONFIG_FRAME_SUPERRES
SHOW(rc_superres_mode);
SHOW(rc_superres_numerator);
SHOW(rc_superres_kf_numerator);
#endif // CONFIG_FRAME_SUPERRES
SHOW(rc_end_usage);
SHOW(rc_target_bitrate);
SHOW(rc_min_quantizer);
@ -1340,7 +1405,7 @@ static void initialize_encoder(struct stream_state *stream,
#if CONFIG_AV1_DECODER
if (global->test_decode != TEST_DECODE_OFF) {
const AvxInterface *decoder = get_aom_decoder_by_name(global->codec->name);
aom_codec_dec_cfg_t cfg = { 0, 0, 0 };
aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH };
aom_codec_dec_init(&stream->decoder, decoder->codec_interface(), &cfg, 0);
#if CONFIG_EXT_TILE
@ -1351,7 +1416,7 @@ static void initialize_encoder(struct stream_state *stream,
aom_codec_control(&stream->decoder, AV1_SET_DECODE_TILE_COL, -1);
ctx_exit_on_error(&stream->decoder, "Failed to set decode_tile_col");
}
#endif
#endif // CONFIG_EXT_TILE
}
#endif
}
@ -1730,8 +1795,10 @@ int main(int argc, const char **argv_) {
if (argi[0][0] == '-' && argi[0][1])
die("Error: Unrecognized option %s\n", *argi);
FOREACH_STREAM(check_encoder_config(global.disable_warning_prompt, &global,
&stream->config.cfg););
FOREACH_STREAM(stream, streams) {
check_encoder_config(global.disable_warning_prompt, &global,
&stream->config.cfg);
}
/* Handle non-option arguments */
input.filename = argv[0];
@ -1753,13 +1820,13 @@ int main(int argc, const char **argv_) {
* the data from the first stream's configuration.
*/
if (!input.width || !input.height) {
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.cfg.g_w && stream->config.cfg.g_h) {
input.width = stream->config.cfg.g_w;
input.height = stream->config.cfg.g_h;
break;
}
});
};
}
/* Update stream configurations from the input file's parameters */
@ -1774,21 +1841,21 @@ int main(int argc, const char **argv_) {
* to be the same as the codec bit-depth.
*/
if (!input.bit_depth) {
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.cfg.g_input_bit_depth)
input.bit_depth = stream->config.cfg.g_input_bit_depth;
else
input.bit_depth = stream->config.cfg.g_input_bit_depth =
(int)stream->config.cfg.g_bit_depth;
});
}
if (input.bit_depth > 8) input.fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
} else {
FOREACH_STREAM(
{ stream->config.cfg.g_input_bit_depth = input.bit_depth; });
FOREACH_STREAM(stream, streams) {
stream->config.cfg.g_input_bit_depth = input.bit_depth;
}
}
#if CONFIG_HIGHBITDEPTH
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (input.fmt != AOM_IMG_FMT_I420 && input.fmt != AOM_IMG_FMT_I42016) {
/* Automatically upgrade if input is non-4:2:0 but a 4:2:0 profile
was selected. */
@ -1824,6 +1891,7 @@ int main(int argc, const char **argv_) {
}
}
if (stream->config.cfg.g_profile > 1) {
if (!CONFIG_HIGHBITDEPTH) fatal("Unsupported profile.");
stream->config.use_16bit_internal = 1;
}
if (profile_updated && !global.quiet) {
@ -1832,56 +1900,34 @@ int main(int argc, const char **argv_) {
"match input format.\n",
stream->config.cfg.g_profile);
}
});
#else
FOREACH_STREAM({
if (input.fmt != AOM_IMG_FMT_I420 && input.fmt != AOM_IMG_FMT_I42016) {
/* Automatically upgrade if input is non-4:2:0 but a 4:2:0 profile
was selected. */
switch (stream->config.cfg.g_profile) {
case 0:
stream->config.cfg.g_profile = 1;
profile_updated = 1;
break;
case 2:
stream->config.cfg.g_profile = 3;
profile_updated = 1;
break;
default: break;
}
}
if (profile_updated && !global.quiet) {
fprintf(stderr,
"Warning: automatically upgrading to profile %d to "
"match input format.\n",
stream->config.cfg.g_profile);
}
});
#endif
}
FOREACH_STREAM(set_stream_dimensions(stream, input.width, input.height));
FOREACH_STREAM(validate_stream_config(stream, &global));
FOREACH_STREAM(stream, streams) {
set_stream_dimensions(stream, input.width, input.height);
}
FOREACH_STREAM(stream, streams) { validate_stream_config(stream, &global); }
/* Ensure that --passes and --pass are consistent. If --pass is set and
* --passes=2, ensure --fpf was set.
*/
if (global.pass && global.passes == 2)
FOREACH_STREAM({
if (global.pass && global.passes == 2) {
FOREACH_STREAM(stream, streams) {
if (!stream->config.stats_fn)
die("Stream %d: Must specify --fpf when --pass=%d"
" and --passes=2\n",
stream->index, global.pass);
});
}
}
#if !CONFIG_WEBM_IO
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.write_webm) {
stream->config.write_webm = 0;
warn(
"aomenc was compiled without WebM container support."
"Producing IVF output");
}
});
}
#endif
/* Use the frame rate from the file only if none was specified
@ -1890,31 +1936,39 @@ int main(int argc, const char **argv_) {
if (!global.have_framerate) {
global.framerate.num = input.framerate.numerator;
global.framerate.den = input.framerate.denominator;
FOREACH_STREAM(stream->config.cfg.g_timebase.den = global.framerate.num;
stream->config.cfg.g_timebase.num = global.framerate.den);
FOREACH_STREAM(stream, streams) {
stream->config.cfg.g_timebase.den = global.framerate.num;
stream->config.cfg.g_timebase.num = global.framerate.den;
}
}
/* Show configuration */
if (global.verbose && pass == 0)
FOREACH_STREAM(show_stream_config(stream, &global, &input));
if (global.verbose && pass == 0) {
FOREACH_STREAM(stream, streams) {
show_stream_config(stream, &global, &input);
}
}
if (pass == (global.pass ? global.pass - 1 : 0)) {
if (input.file_type == FILE_TYPE_Y4M)
/*The Y4M reader does its own allocation.
Just initialize this here to avoid problems if we never read any
frames.*/
frames.*/
memset(&raw, 0, sizeof(raw));
else
aom_img_alloc(&raw, input.fmt, input.width, input.height, 32);
FOREACH_STREAM(stream->rate_hist = init_rate_histogram(
&stream->config.cfg, &global.framerate));
FOREACH_STREAM(stream, streams) {
stream->rate_hist =
init_rate_histogram(&stream->config.cfg, &global.framerate);
}
}
FOREACH_STREAM(setup_pass(stream, &global, pass));
FOREACH_STREAM(
open_output_file(stream, &global, &input.pixel_aspect_ratio));
FOREACH_STREAM(initialize_encoder(stream, &global));
FOREACH_STREAM(stream, streams) { setup_pass(stream, &global, pass); }
FOREACH_STREAM(stream, streams) {
open_output_file(stream, &global, &input.pixel_aspect_ratio);
}
FOREACH_STREAM(stream, streams) { initialize_encoder(stream, &global); }
#if CONFIG_HIGHBITDEPTH
if (strcmp(global.codec->name, "av1") == 0 ||
@ -1922,7 +1976,7 @@ int main(int argc, const char **argv_) {
// Check to see if at least one stream uses 16 bit internal.
// Currently assume that the bit_depths for all streams using
// highbitdepth are the same.
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.use_16bit_internal) {
use_16bit_internal = 1;
}
@ -1932,7 +1986,7 @@ int main(int argc, const char **argv_) {
input_shift = (int)stream->config.cfg.g_bit_depth -
stream->config.cfg.g_input_bit_depth;
}
});
};
}
#endif
@ -1990,31 +2044,35 @@ int main(int argc, const char **argv_) {
aom_usec_timer_start(&timer);
if (use_16bit_internal) {
assert(frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.use_16bit_internal)
encode_frame(stream, &global,
frame_avail ? frame_to_encode : NULL, frames_in);
else
assert(0);
});
};
} else {
assert((frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH) == 0);
FOREACH_STREAM(encode_frame(stream, &global,
frame_avail ? frame_to_encode : NULL,
frames_in));
FOREACH_STREAM(stream, streams) {
encode_frame(stream, &global, frame_avail ? frame_to_encode : NULL,
frames_in);
}
}
#else
aom_usec_timer_start(&timer);
FOREACH_STREAM(encode_frame(stream, &global, frame_avail ? &raw : NULL,
frames_in));
FOREACH_STREAM(stream, streams) {
encode_frame(stream, &global, frame_avail ? &raw : NULL, frames_in);
}
#endif
aom_usec_timer_mark(&timer);
cx_time += aom_usec_timer_elapsed(&timer);
FOREACH_STREAM(update_quantizer_histogram(stream));
FOREACH_STREAM(stream, streams) { update_quantizer_histogram(stream); }
got_data = 0;
FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
FOREACH_STREAM(stream, streams) {
get_cx_data(stream, &global, &got_data);
}
if (!got_data && input.length && streams != NULL &&
!streams->frames_out) {
@ -2043,8 +2101,11 @@ int main(int argc, const char **argv_) {
estimated_time_left = average_rate ? remaining / average_rate : -1;
}
if (got_data && global.test_decode != TEST_DECODE_OFF)
FOREACH_STREAM(test_decode(stream, global.test_decode, global.codec));
if (got_data && global.test_decode != TEST_DECODE_OFF) {
FOREACH_STREAM(stream, streams) {
test_decode(stream, global.test_decode, global.codec);
}
}
}
fflush(stdout);
@ -2054,68 +2115,84 @@ int main(int argc, const char **argv_) {
if (stream_cnt > 1) fprintf(stderr, "\n");
if (!global.quiet) {
FOREACH_STREAM(fprintf(
stderr, "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64
"b/f %7" PRId64 "b/s"
" %7" PRId64 " %s (%.2f fps)\033[K\n",
pass + 1, global.passes, frames_in, stream->frames_out,
(int64_t)stream->nbytes,
seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0,
seen_frames
? (int64_t)stream->nbytes * 8 * (int64_t)global.framerate.num /
global.framerate.den / seen_frames
: 0,
stream->cx_time > 9999999 ? stream->cx_time / 1000 : stream->cx_time,
stream->cx_time > 9999999 ? "ms" : "us",
usec_to_fps(stream->cx_time, seen_frames)));
FOREACH_STREAM(stream, streams) {
fprintf(stderr, "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64
"b/f %7" PRId64
"b/s"
" %7" PRId64 " %s (%.2f fps)\033[K\n",
pass + 1, global.passes, frames_in, stream->frames_out,
(int64_t)stream->nbytes,
seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0,
seen_frames
? (int64_t)stream->nbytes * 8 *
(int64_t)global.framerate.num / global.framerate.den /
seen_frames
: 0,
stream->cx_time > 9999999 ? stream->cx_time / 1000
: stream->cx_time,
stream->cx_time > 9999999 ? "ms" : "us",
usec_to_fps(stream->cx_time, seen_frames));
}
}
if (global.show_psnr) {
if (global.codec->fourcc == AV1_FOURCC) {
FOREACH_STREAM(
show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1));
FOREACH_STREAM(stream, streams) {
show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1);
}
} else {
FOREACH_STREAM(show_psnr(stream, 255.0));
FOREACH_STREAM(stream, streams) { show_psnr(stream, 255.0); }
}
}
FOREACH_STREAM(aom_codec_destroy(&stream->encoder));
FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->encoder); }
if (global.test_decode != TEST_DECODE_OFF) {
FOREACH_STREAM(aom_codec_destroy(&stream->decoder));
FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->decoder); }
}
close_input_file(&input);
if (global.test_decode == TEST_DECODE_FATAL) {
FOREACH_STREAM(res |= stream->mismatch_seen);
FOREACH_STREAM(stream, streams) { res |= stream->mismatch_seen; }
}
FOREACH_STREAM(stream, streams) {
close_output_file(stream, global.codec->fourcc);
}
FOREACH_STREAM(close_output_file(stream, global.codec->fourcc));
FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1));
FOREACH_STREAM(stream, streams) {
stats_close(&stream->stats, global.passes - 1);
}
#if CONFIG_FP_MB_STATS
FOREACH_STREAM(stats_close(&stream->fpmb_stats, global.passes - 1));
FOREACH_STREAM(stream, streams) {
stats_close(&stream->fpmb_stats, global.passes - 1);
}
#endif
if (global.pass) break;
}
if (global.show_q_hist_buckets)
FOREACH_STREAM(
show_q_histogram(stream->counts, global.show_q_hist_buckets));
if (global.show_q_hist_buckets) {
FOREACH_STREAM(stream, streams) {
show_q_histogram(stream->counts, global.show_q_hist_buckets);
}
}
if (global.show_rate_hist_buckets)
FOREACH_STREAM(show_rate_histogram(stream->rate_hist, &stream->config.cfg,
global.show_rate_hist_buckets));
FOREACH_STREAM(destroy_rate_histogram(stream->rate_hist));
if (global.show_rate_hist_buckets) {
FOREACH_STREAM(stream, streams) {
show_rate_histogram(stream->rate_hist, &stream->config.cfg,
global.show_rate_hist_buckets);
}
}
FOREACH_STREAM(stream, streams) { destroy_rate_histogram(stream->rate_hist); }
#if CONFIG_INTERNAL_STATS
/* TODO(jkoleszar): This doesn't belong in this executable. Do it for now,
* to match some existing utilities.
*/
if (!(global.pass == 1 && global.passes == 2))
FOREACH_STREAM({
if (!(global.pass == 1 && global.passes == 2)) {
FOREACH_STREAM(stream, streams) {
FILE *f = fopen("opsnr.stt", "a");
if (stream->mismatch_seen) {
fprintf(f, "First mismatch occurred in frame %d\n",
@ -2124,7 +2201,8 @@ int main(int argc, const char **argv_) {
fprintf(f, "No mismatch detected in recon buffers\n");
}
fclose(f);
});
}
}
#endif
#if CONFIG_HIGHBITDEPTH

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,18 +0,0 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AV1_COMMON_CLPF_H_
#define AV1_COMMON_CLPF_H_
#include "av1/common/reconinter.h"
int av1_clpf_sample(int X, int A, int B, int C, int D, int E, int F, int G,
int H, int b, unsigned int dmp);
#endif

File diff suppressed because it is too large Load diff

View file

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

View file

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

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

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

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

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

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