diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 43f813b83..c3cfdb2f6 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -119,6 +119,9 @@ 835A8FD327957310005B3C39 /* json.c in Sources */ = {isa = PBXBuildFile; fileRef = 835A8FC627957310005B3C39 /* json.c */; }; 835EDD8A27A000E8001EDCCE /* gsx.wv in Resources */ = {isa = PBXBuildFile; fileRef = 835EDD8027A000E8001EDCCE /* gsx.wv */; }; 835F00BB279BD1CD00055FCF /* SecondsFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 835F00B8279BD1CD00055FCF /* SecondsFormatter.m */; }; + 835FAC7927BCDF2A00BA8562 /* AVIFDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 835FAC7527BCDF2A00BA8562 /* AVIFDecoder.m */; }; + 835FAC7E27BCDF5B00BA8562 /* libaom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 835FAC7C27BCDF5B00BA8562 /* libaom.a */; }; + 835FAC7F27BCDF5B00BA8562 /* libavif.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 835FAC7D27BCDF5B00BA8562 /* libavif.a */; }; 8360EF6D17F92E56005208A4 /* HighlyComplete.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF0517F92B24005208A4 /* HighlyComplete.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 836D28A818086386005B7299 /* MiniModeMenuTitleTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */; }; 836EF0C827BB91E600BF35B2 /* libogg.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836EF0C427BB919300BF35B2 /* libogg.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; @@ -906,6 +909,21 @@ 835EDD8027A000E8001EDCCE /* gsx.wv */ = {isa = PBXFileReference; lastKnownFileType = file; path = gsx.wv; sourceTree = ""; }; 835F00B4279BD1CD00055FCF /* SecondsFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecondsFormatter.h; sourceTree = ""; }; 835F00B8279BD1CD00055FCF /* SecondsFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecondsFormatter.m; sourceTree = ""; }; + 835FAC6727BCDF2A00BA8562 /* aomdx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aomdx.h; sourceTree = ""; }; + 835FAC6827BCDF2A00BA8562 /* aom_frame_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_frame_buffer.h; sourceTree = ""; }; + 835FAC6927BCDF2A00BA8562 /* aom_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_encoder.h; sourceTree = ""; }; + 835FAC6A27BCDF2A00BA8562 /* aom_integer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_integer.h; sourceTree = ""; }; + 835FAC6B27BCDF2A00BA8562 /* aom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom.h; sourceTree = ""; }; + 835FAC6C27BCDF2A00BA8562 /* aom_external_partition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_external_partition.h; sourceTree = ""; }; + 835FAC6D27BCDF2A00BA8562 /* aom_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_image.h; sourceTree = ""; }; + 835FAC6E27BCDF2A00BA8562 /* aom_codec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_codec.h; sourceTree = ""; }; + 835FAC6F27BCDF2A00BA8562 /* aom_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aom_decoder.h; sourceTree = ""; }; + 835FAC7027BCDF2A00BA8562 /* aomcx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aomcx.h; sourceTree = ""; }; + 835FAC7227BCDF2A00BA8562 /* avif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avif.h; sourceTree = ""; }; + 835FAC7427BCDF2A00BA8562 /* AVIFDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AVIFDecoder.h; sourceTree = ""; }; + 835FAC7527BCDF2A00BA8562 /* AVIFDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AVIFDecoder.m; sourceTree = ""; }; + 835FAC7C27BCDF5B00BA8562 /* libaom.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaom.a; path = ThirdParty/avif/lib/libaom.a; sourceTree = ""; }; + 835FAC7D27BCDF5B00BA8562 /* libavif.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavif.a; path = ThirdParty/avif/lib/libavif.a; sourceTree = ""; }; 8360EF0017F92B23005208A4 /* HighlyComplete.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyComplete.xcodeproj; path = Plugins/HighlyComplete/HighlyComplete.xcodeproj; sourceTree = ""; }; 836D28A618086386005B7299 /* MiniModeMenuTitleTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MiniModeMenuTitleTransformer.h; path = Window/MiniModeMenuTitleTransformer.h; sourceTree = ""; }; 836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MiniModeMenuTitleTransformer.m; path = Window/MiniModeMenuTitleTransformer.m; sourceTree = ""; }; @@ -1029,6 +1047,8 @@ 8355D6B8180613FB00D05687 /* Security.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 17BB5CED0B8A86010009ACB1 /* AudioToolbox.framework in Frameworks */, + 835FAC7F27BCDF5B00BA8562 /* libavif.a in Frameworks */, + 835FAC7E27BCDF5B00BA8562 /* libaom.a in Frameworks */, 17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */, 17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */, 838F851E256B4E5E00C3E614 /* Sparkle.framework in Frameworks */, @@ -1085,6 +1105,8 @@ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( + 835FAC7C27BCDF5B00BA8562 /* libaom.a */, + 835FAC7D27BCDF5B00BA8562 /* libavif.a */, 836EF0CD27BB94F100BF35B2 /* libopusfile.0.dylib */, 836EF0CC27BB94E100BF35B2 /* libopus.0.dylib */, 836EF0C727BB91BC00BF35B2 /* libFLAC.8.dylib */, @@ -1139,6 +1161,7 @@ 177EBF770B8BC2A70000BC8C /* ThirdParty */ = { isa = PBXGroup; children = ( + 835FAC6427BCDF2900BA8562 /* avif */, 835A8FC527957310005B3C39 /* json */, 177EBF850B8BC2A70000BC8C /* ImageTextCell */, 179790DD0C087AB7001D6996 /* OpenURLPanel */, @@ -1664,6 +1687,58 @@ path = Formatters; sourceTree = ""; }; + 835FAC6427BCDF2900BA8562 /* avif */ = { + isa = PBXGroup; + children = ( + 835FAC6527BCDF2900BA8562 /* include */, + 835FAC7327BCDF2A00BA8562 /* source */, + ); + path = avif; + sourceTree = ""; + }; + 835FAC6527BCDF2900BA8562 /* include */ = { + isa = PBXGroup; + children = ( + 835FAC6627BCDF2900BA8562 /* aom */, + 835FAC7127BCDF2A00BA8562 /* avif */, + ); + path = include; + sourceTree = ""; + }; + 835FAC6627BCDF2900BA8562 /* aom */ = { + isa = PBXGroup; + children = ( + 835FAC6727BCDF2A00BA8562 /* aomdx.h */, + 835FAC6827BCDF2A00BA8562 /* aom_frame_buffer.h */, + 835FAC6927BCDF2A00BA8562 /* aom_encoder.h */, + 835FAC6A27BCDF2A00BA8562 /* aom_integer.h */, + 835FAC6B27BCDF2A00BA8562 /* aom.h */, + 835FAC6C27BCDF2A00BA8562 /* aom_external_partition.h */, + 835FAC6D27BCDF2A00BA8562 /* aom_image.h */, + 835FAC6E27BCDF2A00BA8562 /* aom_codec.h */, + 835FAC6F27BCDF2A00BA8562 /* aom_decoder.h */, + 835FAC7027BCDF2A00BA8562 /* aomcx.h */, + ); + path = aom; + sourceTree = ""; + }; + 835FAC7127BCDF2A00BA8562 /* avif */ = { + isa = PBXGroup; + children = ( + 835FAC7227BCDF2A00BA8562 /* avif.h */, + ); + path = avif; + sourceTree = ""; + }; + 835FAC7327BCDF2A00BA8562 /* source */ = { + isa = PBXGroup; + children = ( + 835FAC7427BCDF2A00BA8562 /* AVIFDecoder.h */, + 835FAC7527BCDF2A00BA8562 /* AVIFDecoder.m */, + ); + path = source; + sourceTree = ""; + }; 8360EF0117F92B23005208A4 /* Products */ = { isa = PBXGroup; children = ( @@ -2415,6 +2490,7 @@ 1755E1F90BA0D2B600CA3560 /* PlaylistLoader.m in Sources */, 8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */, 179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */, + 835FAC7927BCDF2A00BA8562 /* AVIFDecoder.m in Sources */, EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */, 1791FF900CB43A2C0070BC5C /* MediaKeysApplication.m in Sources */, 5604D45B0D60349B004F5C5D /* SpotlightWindowController.m in Sources */, @@ -2743,10 +2819,14 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ThirdParty/avif/include; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "$(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/ThirdParty/avif/lib", + ); MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_CFLAGS = ( "-D__MACOSX__", @@ -2787,10 +2867,14 @@ ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/ThirdParty/Frameworks"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + HEADER_SEARCH_PATHS = ThirdParty/avif/include; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "$(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/ThirdParty/avif/lib", + ); MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_CFLAGS = ( "-D__MACOSX__", diff --git a/Playlist/PlaylistEntry.m b/Playlist/PlaylistEntry.m index 20f6b1b55..ed1097422 100644 --- a/Playlist/PlaylistEntry.m +++ b/Playlist/PlaylistEntry.m @@ -7,6 +7,7 @@ // #import "PlaylistEntry.h" +#import "AVIFDecoder.h" #import "SecondsFormatter.h" @implementation PlaylistEntry @@ -29,6 +30,7 @@ @synthesize errorMessage; @synthesize URL; +@synthesize trashURL; @synthesize artist; @synthesize albumartist; @@ -378,7 +380,15 @@ NSImage *image = [NSImage imageNamed:imageCacheTag]; if(image == nil) { - image = [[NSImage alloc] initWithData:albumArtInternal]; + if([AVIFDecoder isAVIFFormatForData:albumArtInternal]) { + CGImageRef imageRef = [AVIFDecoder createAVIFImageWithData:albumArtInternal]; + if(imageRef) { + image = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize]; + CFRelease(imageRef); + } + } else { + image = [[NSImage alloc] initWithData:albumArtInternal]; + } [image setName:imageCacheTag]; } diff --git a/ThirdParty/avif/README.md b/ThirdParty/avif/README.md new file mode 100644 index 000000000..92cb79642 --- /dev/null +++ b/ThirdParty/avif/README.md @@ -0,0 +1,40 @@ +These were built from libavif and libaom, from the following repositories: + +https://github.com/link-u/libaom - at revision: v2.0.0-586-gdee179da7 +https://github.com/AOMediaCodec/libavif - at revision: v0.9.3-43-g380d91a + +libaom was built to two separate targets, with the following options: + +``` +arch -x86_64 /usr/local/bin/cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.12" -DCONFIG_AV1_ENCODER=0 -DCONFIG_WEBM_IO=0 +make -j8 +``` + +``` +cmake .. -DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="11.0" -DCONFIG_AV1_ENCODER=0 -DCONFIG_WEBM_IO=0 -DCONFIG_RUNTIME_CPU_DETECT=0 +make -j8 +``` + +And then they were merged using lipo. + +libavif was built with the following: + +``` +arch -x86_64 /usr/local/bin/cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.12" -DAVIF_CODEC_AOM=ON -DBUILD_SHARED_LIBS=OFF +make -j8 +``` + +``` +cmake .. -DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="11.0" -DAVIF_CODEC_AOM=ON -DBUILD_SHARED_LIBS=OFF +make -j8 +``` + +And then they were merged with lipo. + +The AVIF decoder contained in the source directory was based on code from +the following repository: + +https://github.com/dreampiggy/AVIFQuickLook + + +I updated the code to work with newer libavif. diff --git a/ThirdParty/avif/include/aom/aom.h b/ThirdParty/avif/include/aom/aom.h new file mode 100644 index 000000000..cb7291419 --- /dev/null +++ b/ThirdParty/avif/include/aom/aom.h @@ -0,0 +1,109 @@ +/* + * 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. + */ + +/*!\defgroup aom AOM + * \ingroup codecs + * AOM is aom's newest video compression algorithm that uses motion + * compensated prediction, Discrete Cosine Transform (DCT) coding of the + * prediction error signal and context dependent entropy coding techniques + * based on arithmetic principles. It features: + * - YUV 4:2:0 image format + * - Macro-block based coding (16x16 luma plus two 8x8 chroma) + * - 1/4 (1/8) pixel accuracy motion compensated prediction + * - 4x4 DCT transform + * - 128 level linear quantizer + * - In loop deblocking filter + * - Context-based entropy coding + * + * @{ + */ +/*!\file + * \brief Provides controls common to both the AOM encoder and decoder. + */ +#ifndef AOM_AOM_AOM_H_ +#define AOM_AOM_AOM_H_ + +#include "aom/aom_codec.h" +#include "aom/aom_image.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*!\brief Control functions + * + * The set of macros define the control functions of AOM interface + */ +enum aom_com_control_id { + /* TODO(https://crbug.com/aomedia/2671): The encoder overlaps the range of + * these values for its control ids, see the NOTEs in aom/aomcx.h. These + * should be migrated to something like the AOM_DECODER_CTRL_ID_START range + * next time we're ready to break the ABI. + */ + AV1_GET_REFERENCE = 128, /**< get a pointer to a reference frame, + av1_ref_frame_t* parameter */ + AV1_SET_REFERENCE = 129, /**< write a frame into a reference buffer, + av1_ref_frame_t* parameter */ + AV1_COPY_REFERENCE = 130, /**< get a copy of reference frame from the decoderm + av1_ref_frame_t* parameter */ + AOM_COMMON_CTRL_ID_MAX, + + AV1_GET_NEW_FRAME_IMAGE = + 192, /**< get a pointer to the new frame, aom_image_t* parameter */ + AV1_COPY_NEW_FRAME_IMAGE = 193, /**< copy the new frame to an external buffer, + aom_image_t* parameter */ + + AOM_DECODER_CTRL_ID_START = 256 +}; + +/*!\brief AV1 specific reference frame data struct + * + * Define the data struct to access av1 reference frames. + */ +typedef struct av1_ref_frame { + int idx; /**< frame index to get (input) */ + int use_external_ref; /**< Directly use external ref buffer(decoder only) */ + aom_image_t img; /**< img structure to populate (output) */ +} av1_ref_frame_t; + +/*!\cond */ +/*!\brief aom decoder control function parameter type + * + * Defines the data type for each of AOM decoder control function requires. + * + * \note For each control ID "X", a macro-define of + * AOM_CTRL_X is provided. It is used at compile time to determine + * if the control ID is supported by the libaom library available, + * when the libaom version cannot be controlled. + */ +AOM_CTRL_USE_TYPE(AV1_GET_REFERENCE, av1_ref_frame_t *) +#define AOM_CTRL_AV1_GET_REFERENCE + +AOM_CTRL_USE_TYPE(AV1_SET_REFERENCE, av1_ref_frame_t *) +#define AOM_CTRL_AV1_SET_REFERENCE + +AOM_CTRL_USE_TYPE(AV1_COPY_REFERENCE, av1_ref_frame_t *) +#define AOM_CTRL_AV1_COPY_REFERENCE + +AOM_CTRL_USE_TYPE(AV1_GET_NEW_FRAME_IMAGE, aom_image_t *) +#define AOM_CTRL_AV1_GET_NEW_FRAME_IMAGE + +AOM_CTRL_USE_TYPE(AV1_COPY_NEW_FRAME_IMAGE, aom_image_t *) +#define AOM_CTRL_AV1_COPY_NEW_FRAME_IMAGE + +/*!\endcond */ +/*! @} - end defgroup aom */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOM_H_ diff --git a/ThirdParty/avif/include/aom/aom_codec.h b/ThirdParty/avif/include/aom/aom_codec.h new file mode 100644 index 000000000..e46529cec --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_codec.h @@ -0,0 +1,552 @@ +/* + * 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. + */ + +/////////////////////////////////////////////////////////////////////////////// +// Internal implementation details +/////////////////////////////////////////////////////////////////////////////// +// +// There are two levels of interfaces used to access the AOM codec: the +// the aom_codec_iface and the aom_codec_ctx. +// +// 1. aom_codec_iface_t +// (Related files: aom/aom_codec.h, aom/src/aom_codec.c, +// aom/internal/aom_codec_internal.h, av1/av1_cx_iface.c, +// av1/av1_dx_iface.c) +// +// Used to initialize the codec context, which contains the configuration for +// for modifying the encoder/decoder during run-time. See the other +// documentation in this header file for more details. For the most part, +// users will call helper functions, such as aom_codec_iface_name, +// aom_codec_get_caps, etc., to interact with it. +// +// The main purpose of the aom_codec_iface_t is to provide a way to generate +// a default codec config, find out what capabilities the implementation has, +// and create an aom_codec_ctx_t (which is actually used to interact with the +// codec). +// +// Note that the implementations for the AV1 algorithm are located in +// av1/av1_cx_iface.c and av1/av1_dx_iface.c +// +// +// 2. aom_codec_ctx_t +// (Related files: aom/aom_codec.h, av1/av1_cx_iface.c, av1/av1_dx_iface.c, +// aom/aomcx.h, aom/aomdx.h, aom/src/aom_encoder.c, aom/src/aom_decoder.c) +// +// The actual interface between user code and the codec. It stores the name +// of the codec, a pointer back to the aom_codec_iface_t that initialized it, +// initialization flags, a config for either encoder or the decoder, and a +// pointer to internal data. +// +// The codec is configured / queried through calls to aom_codec_control, +// which takes a control ID (listed in aomcx.h and aomdx.h) and a parameter. +// In the case of "getter" control IDs, the parameter is modified to have +// the requested value; in the case of "setter" control IDs, the codec's +// configuration is changed based on the parameter. Note that a aom_codec_err_t +// is returned, which indicates if the operation was successful or not. +// +// Note that for the encoder, the aom_codec_alg_priv_t points to the +// the aom_codec_alg_priv structure in av1/av1_cx_iface.c, and for the decoder, +// the struct in av1/av1_dx_iface.c. Variables such as AV1_COMP cpi are stored +// here and also used in the core algorithm. +// +// At the end, aom_codec_destroy should be called for each initialized +// aom_codec_ctx_t. + +/*!\defgroup codec Common Algorithm Interface + * This abstraction allows applications to easily support multiple video + * formats with minimal code duplication. This section describes the interface + * common to all codecs (both encoders and decoders). + * @{ + */ + +/*!\file + * \brief Describes the codec algorithm interface to applications. + * + * This file describes the interface between an application and a + * video codec algorithm. + * + * An application instantiates a specific codec instance by using + * aom_codec_dec_init() or aom_codec_enc_init() and a pointer to the + * algorithm's interface structure: + *
+ *     my_app.c:
+ *       extern aom_codec_iface_t my_codec;
+ *       {
+ *           aom_codec_ctx_t algo;
+ *           int threads = 4;
+ *           aom_codec_dec_cfg_t cfg = { threads, 0, 0, 1 };
+ *           res = aom_codec_dec_init(&algo, &my_codec, &cfg, 0);
+ *       }
+ *     
+ * + * Once initialized, the instance is managed using other functions from + * the aom_codec_* family. + */ +#ifndef AOM_AOM_AOM_CODEC_H_ +#define AOM_AOM_AOM_CODEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "aom/aom_image.h" +#include "aom/aom_integer.h" + +/*!\brief Decorator indicating a function is deprecated */ +#ifndef AOM_DEPRECATED +#if defined(__GNUC__) && __GNUC__ +#define AOM_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define AOM_DEPRECATED +#else +#define AOM_DEPRECATED +#endif +#endif /* AOM_DEPRECATED */ + +#ifndef AOM_DECLSPEC_DEPRECATED +#if defined(__GNUC__) && __GNUC__ +#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */ +#elif defined(_MSC_VER) +/*!\brief \copydoc #AOM_DEPRECATED */ +#define AOM_DECLSPEC_DEPRECATED __declspec(deprecated) +#else +#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */ +#endif +#endif /* AOM_DECLSPEC_DEPRECATED */ + +/*!\brief Decorator indicating a function is potentially unused */ +#ifdef AOM_UNUSED +#elif defined(__GNUC__) || defined(__clang__) +#define AOM_UNUSED __attribute__((unused)) +#else +#define AOM_UNUSED +#endif + +/*!\brief Decorator indicating that given struct/union/enum is packed */ +#ifndef ATTRIBUTE_PACKED +#if defined(__GNUC__) && __GNUC__ +#define ATTRIBUTE_PACKED __attribute__((packed)) +#elif defined(_MSC_VER) +#define ATTRIBUTE_PACKED +#else +#define ATTRIBUTE_PACKED +#endif +#endif /* ATTRIBUTE_PACKED */ + +/*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this value + * must be bumped. Examples include, but are not limited to, changing + * types, removing or reassigning enums, adding/removing/rearranging + * fields to structures + */ +#define AOM_CODEC_ABI_VERSION (5 + AOM_IMAGE_ABI_VERSION) /**<\hideinitializer*/ + +/*!\brief Algorithm return codes */ +typedef enum { + /*!\brief Operation completed without error */ + AOM_CODEC_OK, + + /*!\brief Unspecified error */ + AOM_CODEC_ERROR, + + /*!\brief Memory operation failed */ + AOM_CODEC_MEM_ERROR, + + /*!\brief ABI version mismatch */ + AOM_CODEC_ABI_MISMATCH, + + /*!\brief Algorithm does not have required capability */ + AOM_CODEC_INCAPABLE, + + /*!\brief The given bitstream is not supported. + * + * The bitstream was unable to be parsed at the highest level. The decoder + * is unable to proceed. This error \ref SHOULD be treated as fatal to the + * stream. */ + AOM_CODEC_UNSUP_BITSTREAM, + + /*!\brief Encoded bitstream uses an unsupported feature + * + * The decoder does not implement a feature required by the encoder. This + * return code should only be used for features that prevent future + * pictures from being properly decoded. This error \ref MAY be treated as + * fatal to the stream or \ref MAY be treated as fatal to the current GOP. + */ + AOM_CODEC_UNSUP_FEATURE, + + /*!\brief The coded data for this stream is corrupt or incomplete + * + * There was a problem decoding the current frame. This return code + * should only be used for failures that prevent future pictures from + * being properly decoded. This error \ref MAY be treated as fatal to the + * stream or \ref MAY be treated as fatal to the current GOP. If decoding + * is continued for the current GOP, artifacts may be present. + */ + AOM_CODEC_CORRUPT_FRAME, + + /*!\brief An application-supplied parameter is not valid. + * + */ + AOM_CODEC_INVALID_PARAM, + + /*!\brief An iterator reached the end of list. + * + */ + AOM_CODEC_LIST_END + +} aom_codec_err_t; + +/*! \brief Codec capabilities bitfield + * + * Each codec advertises the capabilities it supports as part of its + * ::aom_codec_iface_t interface structure. Capabilities are extra interfaces + * or functionality, and are not required to be supported. + * + * The available flags are specified by AOM_CODEC_CAP_* defines. + */ +typedef long aom_codec_caps_t; +#define AOM_CODEC_CAP_DECODER 0x1 /**< Is a decoder */ +#define AOM_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */ + +/*! \brief Initialization-time Feature Enabling + * + * Certain codec features must be known at initialization time, to allow for + * proper memory allocation. + * + * The available flags are specified by AOM_CODEC_USE_* defines. + */ +typedef long aom_codec_flags_t; + +/*!\brief Time Stamp Type + * + * An integer, which when multiplied by the stream's time base, provides + * the absolute time of a sample. + */ +typedef int64_t aom_codec_pts_t; + +/*!\brief Codec interface structure. + * + * Contains function pointers and other data private to the codec + * implementation. This structure is opaque to the application. Common + * functions used with this structure: + * - aom_codec_iface_name(aom_codec_iface_t *iface): get the + * name of the codec + * - aom_codec_get_caps(aom_codec_iface_t *iface): returns + * the capabilities of the codec + * - aom_codec_enc_config_default: generate the default config for + * initializing the encoder (see documention in aom_encoder.h) + * - aom_codec_dec_init, aom_codec_enc_init: initialize the codec context + * structure (see documentation on aom_codec_ctx). + * + * To get access to the AV1 encoder and decoder, use aom_codec_av1_cx() and + * aom_codec_av1_dx(). + */ +typedef const struct aom_codec_iface aom_codec_iface_t; + +/*!\brief Codec private data structure. + * + * Contains data private to the codec implementation. This structure is opaque + * to the application. + */ +typedef struct aom_codec_priv aom_codec_priv_t; + +/*!\brief Compressed Frame Flags + * + * This type represents a bitfield containing information about a compressed + * frame that may be useful to an application. The most significant 16 bits + * can be used by an algorithm to provide additional detail, for example to + * support frame types that are codec specific (MPEG-1 D-frames for example) + */ +typedef uint32_t aom_codec_frame_flags_t; +#define AOM_FRAME_IS_KEY 0x1 /**< frame is the start of a GOP */ +/*!\brief frame can be dropped without affecting the stream (no future frame + * depends on this one) */ +#define AOM_FRAME_IS_DROPPABLE 0x2 +/*!\brief this is an INTRA_ONLY frame */ +#define AOM_FRAME_IS_INTRAONLY 0x10 +/*!\brief this is an S-frame */ +#define AOM_FRAME_IS_SWITCH 0x20 +/*!\brief this is an error-resilient frame */ +#define AOM_FRAME_IS_ERROR_RESILIENT 0x40 +/*!\brief this is a key-frame dependent recovery-point frame */ +#define AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT 0x80 + +/*!\brief Iterator + * + * Opaque storage used for iterating over lists. + */ +typedef const void *aom_codec_iter_t; + +/*!\brief Codec context structure + * + * All codecs \ref MUST support this context structure fully. In general, + * this data should be considered private to the codec algorithm, and + * not be manipulated or examined by the calling application. Applications + * may reference the 'name' member to get a printable description of the + * algorithm. + */ +typedef struct aom_codec_ctx { + const char *name; /**< Printable interface name */ + aom_codec_iface_t *iface; /**< Interface pointers */ + aom_codec_err_t err; /**< Last returned error */ + const char *err_detail; /**< Detailed info, if available */ + aom_codec_flags_t init_flags; /**< Flags passed at init time */ + union { + /**< Decoder Configuration Pointer */ + const struct aom_codec_dec_cfg *dec; + /**< Encoder Configuration Pointer */ + const struct aom_codec_enc_cfg *enc; + const void *raw; + } config; /**< Configuration pointer aliasing union */ + aom_codec_priv_t *priv; /**< Algorithm private storage */ +} aom_codec_ctx_t; + +/*!\brief Bit depth for codec + * * + * This enumeration determines the bit depth of the codec. + */ +typedef enum aom_bit_depth { + AOM_BITS_8 = 8, /**< 8 bits */ + AOM_BITS_10 = 10, /**< 10 bits */ + AOM_BITS_12 = 12, /**< 12 bits */ +} aom_bit_depth_t; + +/*!\brief Superblock size selection. + * + * Defines the superblock size used for encoding. The superblock size can + * either be fixed at 64x64 or 128x128 pixels, or it can be dynamically + * selected by the encoder for each frame. + */ +typedef enum aom_superblock_size { + AOM_SUPERBLOCK_SIZE_64X64, /**< Always use 64x64 superblocks. */ + AOM_SUPERBLOCK_SIZE_128X128, /**< Always use 128x128 superblocks. */ + AOM_SUPERBLOCK_SIZE_DYNAMIC /**< Select superblock size dynamically. */ +} aom_superblock_size_t; + +/* + * Library Version Number Interface + * + * For example, see the following sample return values: + * aom_codec_version() (1<<16 | 2<<8 | 3) + * aom_codec_version_str() "v1.2.3-rc1-16-gec6a1ba" + * aom_codec_version_extra_str() "rc1-16-gec6a1ba" + */ + +/*!\brief Return the version information (as an integer) + * + * Returns a packed encoding of the library version number. This will only + * include the major.minor.patch component of the version number. Note that this + * encoded value should be accessed through the macros provided, as the encoding + * may change in the future. + * + */ +int aom_codec_version(void); + +/*!\brief Return the major version number */ +#define aom_codec_version_major() ((aom_codec_version() >> 16) & 0xff) + +/*!\brief Return the minor version number */ +#define aom_codec_version_minor() ((aom_codec_version() >> 8) & 0xff) + +/*!\brief Return the patch version number */ +#define aom_codec_version_patch() ((aom_codec_version() >> 0) & 0xff) + +/*!\brief Return the version information (as a string) + * + * Returns a printable string containing the full library version number. This + * may contain additional text following the three digit version number, as to + * indicate release candidates, prerelease versions, etc. + * + */ +const char *aom_codec_version_str(void); + +/*!\brief Return the version information (as a string) + * + * Returns a printable "extra string". This is the component of the string + * returned by aom_codec_version_str() following the three digit version number. + * + */ +const char *aom_codec_version_extra_str(void); + +/*!\brief Return the build configuration + * + * Returns a printable string containing an encoded version of the build + * configuration. This may be useful to aom support. + * + */ +const char *aom_codec_build_config(void); + +/*!\brief Return the name for a given interface + * + * Returns a human readable string for name of the given codec interface. + * + * \param[in] iface Interface pointer + * + */ +const char *aom_codec_iface_name(aom_codec_iface_t *iface); + +/*!\brief Convert error number to printable string + * + * Returns a human readable string for the last error returned by the + * algorithm. The returned error will be one line and will not contain + * any newline characters. + * + * + * \param[in] err Error number. + * + */ +const char *aom_codec_err_to_string(aom_codec_err_t err); + +/*!\brief Retrieve error synopsis for codec context + * + * Returns a human readable string for the last error returned by the + * algorithm. The returned error will be one line and will not contain + * any newline characters. + * + * + * \param[in] ctx Pointer to this instance's context. + * + */ +const char *aom_codec_error(aom_codec_ctx_t *ctx); + +/*!\brief Retrieve detailed error information for codec context + * + * Returns a human readable string providing detailed information about + * the last error. + * + * \param[in] ctx Pointer to this instance's context. + * + * \retval NULL + * No detailed information is available. + */ +const char *aom_codec_error_detail(aom_codec_ctx_t *ctx); + +/* REQUIRED FUNCTIONS + * + * The following functions are required to be implemented for all codecs. + * They represent the base case functionality expected of all codecs. + */ + +/*!\brief Destroy a codec instance + * + * Destroys a codec context, freeing any associated memory buffers. + * + * \param[in] ctx Pointer to this instance's context + * + * \retval #AOM_CODEC_OK + * The codec algorithm initialized. + * \retval #AOM_CODEC_MEM_ERROR + * Memory allocation failed. + */ +aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx); + +/*!\brief Get the capabilities of an algorithm. + * + * Retrieves the capabilities bitfield from the algorithm's interface. + * + * \param[in] iface Pointer to the algorithm interface + * + */ +aom_codec_caps_t aom_codec_get_caps(aom_codec_iface_t *iface); + +/*!\name Codec Control + * + * The aom_codec_control function exchanges algorithm specific data with the + * codec instance. Additionally, the macro AOM_CODEC_CONTROL_TYPECHECKED is + * provided, which will type-check the parameter against the control ID before + * calling aom_codec_control - note that this macro requires the control ID + * to be directly encoded in it, e.g., + * AOM_CODEC_CONTROL_TYPECHECKED(&ctx, AOME_SET_CPUUSED, 8). + * + * The codec control IDs can be found in aom.h, aomcx.h, and aomdx.h + * (defined as aom_com_control_id, aome_enc_control_id, and aom_dec_control_id). + * @{ + */ +/*!\brief Algorithm Control + * + * aom_codec_control takes a context, a control ID, and a third parameter + * (with varying type). If the context is non-null and an error occurs, + * ctx->err will be set to the same value as the return value. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] ctrl_id Algorithm specific control identifier + * + * \retval #AOM_CODEC_OK + * The control request was processed. + * \retval #AOM_CODEC_ERROR + * The control request was not processed. + * \retval #AOM_CODEC_INVALID_PARAM + * The data was not valid. + */ +aom_codec_err_t aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...); + +/*!\brief aom_codec_control wrapper macro (adds type-checking, less flexible) + * + * This macro allows for type safe conversions across the variadic parameter + * to aom_codec_control(). However, it requires the explicit control ID + * be passed in (it cannot be passed in via a variable) -- otherwise a compiler + * error will occur. After the type checking, it calls aom_codec_control. + */ +#define AOM_CODEC_CONTROL_TYPECHECKED(ctx, id, data) \ + aom_codec_control_typechecked_##id(ctx, id, data) /**<\hideinitializer*/ + +/*!\brief Creates typechecking mechanisms for aom_codec_control + * + * It defines a static function with the correctly typed arguments as a wrapper + * to the type-unsafe aom_codec_control function. It also creates a typedef + * for each type. + */ +#define AOM_CTRL_USE_TYPE(id, typ) \ + static aom_codec_err_t aom_codec_control_typechecked_##id( \ + aom_codec_ctx_t *, int, typ) AOM_UNUSED; \ + static aom_codec_err_t aom_codec_control_typechecked_##id( \ + aom_codec_ctx_t *ctx, int ctrl, typ data) { \ + return aom_codec_control(ctx, ctrl, data); \ + } /**<\hideinitializer*/ \ + typedef typ aom_codec_control_type_##id; +/*!@} end Codec Control group */ + +/*!\brief OBU types. */ +typedef enum ATTRIBUTE_PACKED { + OBU_SEQUENCE_HEADER = 1, + OBU_TEMPORAL_DELIMITER = 2, + OBU_FRAME_HEADER = 3, + OBU_TILE_GROUP = 4, + OBU_METADATA = 5, + OBU_FRAME = 6, + OBU_REDUNDANT_FRAME_HEADER = 7, + OBU_TILE_LIST = 8, + OBU_PADDING = 15, +} OBU_TYPE; + +/*!\brief OBU metadata types. */ +typedef enum { + OBU_METADATA_TYPE_AOM_RESERVED_0 = 0, + OBU_METADATA_TYPE_HDR_CLL = 1, + OBU_METADATA_TYPE_HDR_MDCV = 2, + OBU_METADATA_TYPE_SCALABILITY = 3, + OBU_METADATA_TYPE_ITUT_T35 = 4, + OBU_METADATA_TYPE_TIMECODE = 5, +} OBU_METADATA_TYPE; + +/*!\brief Returns string representation of OBU_TYPE. + * + * \param[in] type The OBU_TYPE to convert to string. + */ +const char *aom_obu_type_to_string(OBU_TYPE type); + +/*!@} - end defgroup codec*/ +#ifdef __cplusplus +} +#endif +#endif // AOM_AOM_AOM_CODEC_H_ diff --git a/ThirdParty/avif/include/aom/aom_decoder.h b/ThirdParty/avif/include/aom/aom_decoder.h new file mode 100644 index 000000000..5af2690b2 --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_decoder.h @@ -0,0 +1,257 @@ +/* + * 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 AOM_AOM_AOM_DECODER_H_ +#define AOM_AOM_AOM_DECODER_H_ + +/*!\defgroup decoder Decoder Algorithm Interface + * \ingroup codec + * This abstraction allows applications using this decoder to easily support + * multiple video formats with minimal code duplication. This section describes + * the interface common to all decoders. + * @{ + */ + +/*!\file + * \brief Describes the decoder algorithm interface to applications. + * + * This file describes the interface between an application and a + * video decoder algorithm. + * + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "aom/aom_codec.h" +#include "aom/aom_frame_buffer.h" + +/*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this value + * must be bumped. Examples include, but are not limited to, changing + * types, removing or reassigning enums, adding/removing/rearranging + * fields to structures + */ +#define AOM_DECODER_ABI_VERSION \ + (6 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/ + +/*! \brief Decoder capabilities bitfield + * + * Each decoder advertises the capabilities it supports as part of its + * ::aom_codec_iface_t interface structure. Capabilities are extra interfaces + * or functionality, and are not required to be supported by a decoder. + * + * The available flags are specified by AOM_CODEC_CAP_* defines. + */ +/*!brief Can support external frame buffers */ +#define AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x200000 + +/*! \brief Initialization-time Feature Enabling + * + * Certain codec features must be known at initialization time, to allow for + * proper memory allocation. + * + * The available flags are specified by AOM_CODEC_USE_* defines. + */ + +/*!\brief Stream properties + * + * This structure is used to query or set properties of the decoded + * stream. + */ +typedef struct aom_codec_stream_info { + unsigned int w; /**< Width (or 0 for unknown/default) */ + unsigned int h; /**< Height (or 0 for unknown/default) */ + unsigned int is_kf; /**< Current frame is a keyframe */ + unsigned int number_spatial_layers; /**< Number of spatial layers */ + unsigned int number_temporal_layers; /**< Number of temporal layers */ + unsigned int is_annexb; /**< Is Bitstream in Annex-B format */ +} aom_codec_stream_info_t; + +/* REQUIRED FUNCTIONS + * + * The following functions are required to be implemented for all decoders. + * They represent the base case functionality expected of all decoders. + */ + +/*!\brief Initialization Configurations + * + * This structure is used to pass init time configuration options to the + * decoder. + */ +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 */ + 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 + * + * Initializes a decoder context using the given interface. Applications + * should call the aom_codec_dec_init convenience macro instead of this + * function directly, to ensure that the ABI version number parameter + * is properly initialized. + * + * If the library was configured with cmake -DCONFIG_MULTITHREAD=0, this + * call is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] iface Pointer to the algorithm interface to use. + * \param[in] cfg Configuration to use, if known. May be NULL. + * \param[in] flags Bitfield of AOM_CODEC_USE_* flags + * \param[in] ver ABI version number. Must be set to + * AOM_DECODER_ABI_VERSION + * \retval #AOM_CODEC_OK + * The decoder algorithm initialized. + * \retval #AOM_CODEC_MEM_ERROR + * Memory allocation failed. + */ +aom_codec_err_t aom_codec_dec_init_ver(aom_codec_ctx_t *ctx, + aom_codec_iface_t *iface, + const aom_codec_dec_cfg_t *cfg, + aom_codec_flags_t flags, int ver); + +/*!\brief Convenience macro for aom_codec_dec_init_ver() + * + * Ensures the ABI version parameter is properly set. + */ +#define aom_codec_dec_init(ctx, iface, cfg, flags) \ + aom_codec_dec_init_ver(ctx, iface, cfg, flags, AOM_DECODER_ABI_VERSION) + +/*!\brief Parse stream info from a buffer + * + * Performs high level parsing of the bitstream. Construction of a decoder + * context is not necessary. Can be used to determine if the bitstream is + * of the proper format, and to extract information from the stream. + * + * \param[in] iface Pointer to the algorithm interface + * \param[in] data Pointer to a block of data to parse + * \param[in] data_sz Size of the data buffer + * \param[in,out] si Pointer to stream info to update. The is_annexb + * member \ref MUST be properly initialized. This + * function sets the rest of the members. + * + * \retval #AOM_CODEC_OK + * Bitstream is parsable and stream information updated. + * \retval #AOM_CODEC_INVALID_PARAM + * One of the arguments is invalid, for example a NULL pointer. + * \retval #AOM_CODEC_UNSUP_BITSTREAM + * The decoder didn't recognize the coded data, or the + * buffer was too short. + */ +aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface, + const uint8_t *data, size_t data_sz, + aom_codec_stream_info_t *si); + +/*!\brief Return information about the current stream. + * + * Returns information about the stream that has been parsed during decoding. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] si Pointer to stream info to update. + * + * \retval #AOM_CODEC_OK + * Bitstream is parsable and stream information updated. + * \retval #AOM_CODEC_INVALID_PARAM + * One of the arguments is invalid, for example a NULL pointer. + * \retval #AOM_CODEC_UNSUP_BITSTREAM + * The decoder couldn't parse the submitted data. + */ +aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx, + aom_codec_stream_info_t *si); + +/*!\brief Decode data + * + * Processes a buffer of coded data. Encoded data \ref MUST be passed in DTS + * (decode time stamp) order. Frames produced will always be in PTS + * (presentation time stamp) order. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] data Pointer to this block of new coded data. + * \param[in] data_sz Size of the coded data, in bytes. + * \param[in] user_priv Application specific data to associate with + * this frame. + * + * \return Returns #AOM_CODEC_OK if the coded data was processed completely + * and future pictures can be decoded without error. Otherwise, + * see the descriptions of the other error codes in ::aom_codec_err_t + * for recoverability capabilities. + */ +aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data, + size_t data_sz, void *user_priv); + +/*!\brief Decoded frames iterator + * + * Iterates over a list of the frames available for display. The iterator + * storage should be initialized to NULL to start the iteration. Iteration is + * complete when this function returns NULL. + * + * The list of available frames becomes valid upon completion of the + * aom_codec_decode call, and remains valid until the next call to + * aom_codec_decode. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] iter Iterator storage, initialized to NULL + * + * \return Returns a pointer to an image, if one is ready for display. Frames + * produced will always be in PTS (presentation time stamp) order. + */ +aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter); + +/*!\defgroup cap_external_frame_buffer External Frame Buffer Functions + * + * The following function is required to be implemented for all decoders + * that advertise the AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability. + * Calling this function for codecs that don't advertise this capability + * will result in an error code being returned, usually AOM_CODEC_INCAPABLE. + * @{ + */ + +/*!\brief Pass in external frame buffers for the decoder to use. + * + * Registers functions to be called when libaom needs a frame buffer + * to decode the current frame and a function to be called when libaom does + * not internally reference the frame buffer. This set function must + * be called before the first call to decode or libaom will assume the + * default behavior of allocating frame buffers internally. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb_get Pointer to the get callback function + * \param[in] cb_release Pointer to the release callback function + * \param[in] cb_priv Callback's private data + * + * \retval #AOM_CODEC_OK + * External frame buffers will be used by libaom. + * \retval #AOM_CODEC_INVALID_PARAM + * One or more of the callbacks were NULL. + * \retval #AOM_CODEC_ERROR + * Decoder context not initialized. + * \retval #AOM_CODEC_INCAPABLE + * Algorithm not capable of using external frame buffers. + * + * \note + * When decoding AV1, the application may be required to pass in at least + * #AOM_MAXIMUM_WORK_BUFFERS external frame buffers. + */ +aom_codec_err_t aom_codec_set_frame_buffer_functions( +aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get, +aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv); + +/*!@} - end defgroup cap_external_frame_buffer */ + +/*!@} - end defgroup decoder*/ +#ifdef __cplusplus +} +#endif +#endif // AOM_AOM_AOM_DECODER_H_ diff --git a/ThirdParty/avif/include/aom/aom_encoder.h b/ThirdParty/avif/include/aom/aom_encoder.h new file mode 100644 index 000000000..f11c7f087 --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_encoder.h @@ -0,0 +1,1127 @@ +/* + * 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 AOM_AOM_AOM_ENCODER_H_ +#define AOM_AOM_AOM_ENCODER_H_ + +/*!\defgroup encoder Encoder Algorithm Interface + * \ingroup codec + * This abstraction allows applications using this encoder to easily support + * multiple video formats with minimal code duplication. This section describes + * the interface common to all encoders. + * @{ + */ + +/*!\file + * \brief Describes the encoder algorithm interface to applications. + * + * This file describes the interface between an application and a + * video encoder algorithm. + * + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "aom/aom_codec.h" + +/*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this value + * must be bumped. Examples include, but are not limited to, changing + * types, removing or reassigning enums, adding/removing/rearranging + * fields to structures + */ +#define AOM_ENCODER_ABI_VERSION \ + (8 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/ + +/*! \brief Encoder capabilities bitfield + * + * Each encoder advertises the capabilities it supports as part of its + * ::aom_codec_iface_t interface structure. Capabilities are extra + * interfaces or functionality, and are not required to be supported + * by an encoder. + * + * The available flags are specified by AOM_CODEC_CAP_* defines. + */ +#define AOM_CODEC_CAP_PSNR 0x10000 /**< Can issue PSNR packets */ + +/*! Can support input images at greater than 8 bitdepth. + */ +#define AOM_CODEC_CAP_HIGHBITDEPTH 0x40000 + +/*! \brief Initialization-time Feature Enabling + * + * Certain codec features must be known at initialization time, to allow + * for proper memory allocation. + * + * The available flags are specified by AOM_CODEC_USE_* defines. + */ +#define AOM_CODEC_USE_PSNR 0x10000 /**< Calculate PSNR on each frame */ +/*!\brief Make the encoder output one partition at a time. */ +#define AOM_CODEC_USE_HIGHBITDEPTH 0x40000 /**< Use high bitdepth */ + +/*!\brief Generic fixed size buffer structure + * + * This structure is able to hold a reference to any fixed size buffer. + */ +typedef struct aom_fixed_buf { + void *buf; /**< Pointer to the data. Does NOT own the data! */ + size_t sz; /**< Length of the buffer, in chars */ +} aom_fixed_buf_t; /**< alias for struct aom_fixed_buf */ + +/*!\brief Error Resilient flags + * + * These flags define which error resilient features to enable in the + * encoder. The flags are specified through the + * aom_codec_enc_cfg::g_error_resilient variable. + */ +typedef uint32_t aom_codec_er_flags_t; +/*!\brief Improve resiliency against losses of whole frames */ +#define AOM_ERROR_RESILIENT_DEFAULT 0x1 + +/*!\brief Encoder output packet variants + * + * This enumeration lists the different kinds of data packets that can be + * returned by calls to aom_codec_get_cx_data(). Algorithms \ref MAY + * extend this list to provide additional functionality. + */ +enum aom_codec_cx_pkt_kind { + AOM_CODEC_CX_FRAME_PKT, /**< Compressed video frame */ + AOM_CODEC_STATS_PKT, /**< Two-pass statistics for this frame */ + AOM_CODEC_FPMB_STATS_PKT, /**< first pass mb statistics for this frame */ + AOM_CODEC_PSNR_PKT, /**< PSNR statistics for this frame */ + AOM_CODEC_CUSTOM_PKT = 256 /**< Algorithm extensions */ +}; + +/*!\brief Encoder output packet + * + * This structure contains the different kinds of output data the encoder + * may produce while compressing a frame. + */ +typedef struct aom_codec_cx_pkt { + enum aom_codec_cx_pkt_kind kind; /**< packet variant */ + union { + struct { + void *buf; /**< compressed data buffer */ + size_t sz; /**< length of compressed data */ + /*!\brief time stamp to show frame (in timebase units) */ + aom_codec_pts_t pts; + /*!\brief duration to show frame (in timebase units) */ + unsigned long duration; + aom_codec_frame_flags_t flags; /**< flags for this frame */ + /*!\brief the partition id defines the decoding order of the partitions. + * Only applicable when "output partition" mode is enabled. First + * partition has id 0.*/ + int partition_id; + /*!\brief size of the visible frame in this packet */ + size_t vis_frame_size; + } frame; /**< data for compressed frame packet */ + aom_fixed_buf_t twopass_stats; /**< data for two-pass packet */ + aom_fixed_buf_t firstpass_mb_stats; /**< first pass mb packet */ + struct aom_psnr_pkt { + unsigned int samples[4]; /**< Number of samples, total/y/u/v */ + uint64_t sse[4]; /**< sum squared error, total/y/u/v */ + double psnr[4]; /**< PSNR, total/y/u/v */ + } psnr; /**< data for PSNR packet */ + aom_fixed_buf_t raw; /**< data for arbitrary packets */ + + /* This packet size is fixed to allow codecs to extend this + * interface without having to manage storage for raw packets, + * i.e., if it's smaller than 128 bytes, you can store in the + * packet list directly. + */ + char pad[128 - sizeof(enum aom_codec_cx_pkt_kind)]; /**< fixed sz */ + } data; /**< packet data */ +} aom_codec_cx_pkt_t; /**< alias for struct aom_codec_cx_pkt */ + +/*!\brief Rational Number + * + * This structure holds a fractional value. + */ +typedef struct aom_rational { + int num; /**< fraction numerator */ + int den; /**< fraction denominator */ +} aom_rational_t; /**< alias for struct aom_rational */ + +/*!\brief Multi-pass Encoding Pass */ +enum aom_enc_pass { + AOM_RC_ONE_PASS, /**< Single pass mode */ + AOM_RC_FIRST_PASS, /**< First pass of multi-pass mode */ + AOM_RC_LAST_PASS /**< Final pass of multi-pass mode */ +}; + +/*!\brief Rate control mode */ +enum aom_rc_mode { + AOM_VBR, /**< Variable Bit Rate (VBR) mode */ + AOM_CBR, /**< Constant Bit Rate (CBR) mode */ + AOM_CQ, /**< Constrained Quality (CQ) mode */ + AOM_Q, /**< Constant Quality (Q) mode */ +}; + +/*!\brief Keyframe placement mode. + * + * This enumeration determines whether keyframes are placed automatically by + * the encoder or whether this behavior is disabled. Older releases of this + * SDK were implemented such that AOM_KF_FIXED meant keyframes were disabled. + * This name is confusing for this behavior, so the new symbols to be used + * are AOM_KF_AUTO and AOM_KF_DISABLED. + */ +enum aom_kf_mode { + AOM_KF_FIXED, /**< deprecated, implies AOM_KF_DISABLED */ + AOM_KF_AUTO, /**< Encoder determines optimal placement automatically */ + AOM_KF_DISABLED = 0 /**< Encoder does not place keyframes. */ +}; + +/*!\brief Frame super-resolution mode. */ +typedef enum { + /**< Frame super-resolution is disabled for all frames. */ + AOM_SUPERRES_NONE, + /**< All frames are coded at the specified scale and super-resolved. */ + AOM_SUPERRES_FIXED, + /**< All frames are coded at a random scale and super-resolved. */ + AOM_SUPERRES_RANDOM, + /**< Super-resolution scale for each frame is determined based on the q index + of that frame. */ + AOM_SUPERRES_QTHRESH, + /**< Full-resolution or super-resolution and the scale (in case of + super-resolution) are automatically selected for each frame. */ + AOM_SUPERRES_AUTO, +} aom_superres_mode; + +/*!\brief Encoder Config Options + * + * This type allows to enumerate and control flags defined for encoder control + * via config file at runtime. + */ +typedef struct cfg_options { + /*!\brief Indicate init by cfg file + * 0 or 1 + */ + unsigned int init_by_cfg_file; + /*!\brief Superblock size + * 0, 64 or 128 + */ + unsigned int super_block_size; + /*!\brief max partition size + * 8, 16, 32, 64, 128 + */ + unsigned int max_partition_size; + /*!\brief min partition size + * 8, 16, 32, 64, 128 + */ + unsigned int min_partition_size; + /*!\brief disable AB Shape partition type + * + */ + unsigned int disable_ab_partition_type; + /*!\brief disable rectangular partition type + * + */ + unsigned int disable_rect_partition_type; + /*!\brief disable 1:4/4:1 partition type + * + */ + unsigned int disable_1to4_partition_type; + /*!\brief disable flip and identity transform type + * + */ + unsigned int disable_flip_idtx; + /*!\brief disable CDEF filter + * + */ + unsigned int disable_cdef; + /*!\brief disable Loop Restoration Filter + * + */ + unsigned int disable_lr; + /*!\brief disable OBMC + * + */ + unsigned int disable_obmc; + /*!\brief disable Warped Motion + * + */ + unsigned int disable_warp_motion; + /*!\brief disable global motion + * + */ + unsigned int disable_global_motion; + /*!\brief disable dist weighted compound + * + */ + unsigned int disable_dist_wtd_comp; + /*!\brief disable diff weighted compound + * + */ + unsigned int disable_diff_wtd_comp; + /*!\brief disable inter/intra compound + * + */ + unsigned int disable_inter_intra_comp; + /*!\brief disable masked compound + * + */ + unsigned int disable_masked_comp; + /*!\brief disable one sided compound + * + */ + unsigned int disable_one_sided_comp; + /*!\brief disable Palette + * + */ + unsigned int disable_palette; + /*!\brief disable Intra Block Copy + * + */ + unsigned int disable_intrabc; + /*!\brief disable chroma from luma + * + */ + unsigned int disable_cfl; + /*!\brief disable intra smooth mode + * + */ + unsigned int disable_smooth_intra; + /*!\brief disable filter intra + * + */ + unsigned int disable_filter_intra; + /*!\brief disable dual filter + * + */ + unsigned int disable_dual_filter; + /*!\brief disable intra angle delta + * + */ + unsigned int disable_intra_angle_delta; + /*!\brief disable intra edge filter + * + */ + unsigned int disable_intra_edge_filter; + /*!\brief disable 64x64 transform + * + */ + unsigned int disable_tx_64x64; + /*!\brief disable smooth inter/intra + * + */ + unsigned int disable_smooth_inter_intra; + /*!\brief disable inter/inter wedge comp + * + */ + unsigned int disable_inter_inter_wedge; + /*!\brief disable inter/intra wedge comp + * + */ + unsigned int disable_inter_intra_wedge; + /*!\brief disable paeth intra + * + */ + unsigned int disable_paeth_intra; + /*!\brief disable trellis quantization + * + */ + unsigned int disable_trellis_quant; + /*!\brief disable ref frame MV + * + */ + unsigned int disable_ref_frame_mv; + /*!\brief use reduced reference frame set + * + */ + unsigned int reduced_reference_set; + /*!\brief use reduced transform type set + * + */ + unsigned int reduced_tx_type_set; +} cfg_options_t; + +/*!\brief Encoded Frame Flags + * + * This type indicates a bitfield to be passed to aom_codec_encode(), defining + * per-frame boolean values. By convention, bits common to all codecs will be + * named AOM_EFLAG_*, and bits specific to an algorithm will be named + * /algo/_eflag_*. The lower order 16 bits are reserved for common use. + */ +typedef long aom_enc_frame_flags_t; +/*!\brief Force this frame to be a keyframe */ +#define AOM_EFLAG_FORCE_KF (1 << 0) + +/*!\brief Encoder configuration structure + * + * This structure contains the encoder settings that have common representations + * across all codecs. This doesn't imply that all codecs support all features, + * however. + */ +typedef struct aom_codec_enc_cfg { + /* + * generic settings (g) + */ + + /*!\brief Algorithm specific "usage" value + * + * Algorithms may define multiple values for usage, which may convey the + * intent of how the application intends to use the stream. If this value + * is non-zero, consult the documentation for the codec to determine its + * meaning. + */ + unsigned int g_usage; + + /*!\brief Maximum number of threads to use + * + * For multi-threaded implementations, use no more than this number of + * threads. The codec may use fewer threads than allowed. The value + * 0 is equivalent to the value 1. + */ + unsigned int g_threads; + + /*!\brief Bitstream profile to use + * + * Some codecs support a notion of multiple bitstream profiles. Typically + * this maps to a set of features that are turned on or off. Often the + * profile to use is determined by the features of the intended decoder. + * Consult the documentation for the codec to determine the valid values + * for this parameter, or set to zero for a sane default. + */ + unsigned int g_profile; /**< profile of bitstream to use */ + + /*!\brief Width of the frame + * + * This value identifies the presentation resolution of the frame, + * in pixels. Note that the frames passed as input to the encoder must + * have this resolution. Frames will be presented by the decoder in this + * resolution, independent of any spatial resampling the encoder may do. + */ + unsigned int g_w; + + /*!\brief Height of the frame + * + * This value identifies the presentation resolution of the frame, + * in pixels. Note that the frames passed as input to the encoder must + * have this resolution. Frames will be presented by the decoder in this + * resolution, independent of any spatial resampling the encoder may do. + */ + unsigned int g_h; + + /*!\brief Max number of frames to encode + * + */ + unsigned int g_limit; + + /*!\brief Forced maximum width of the frame + * + * If this value is non-zero then it is used to force the maximum frame + * width written in write_sequence_header(). + */ + unsigned int g_forced_max_frame_width; + + /*!\brief Forced maximum height of the frame + * + * If this value is non-zero then it is used to force the maximum frame + * height written in write_sequence_header(). + */ + unsigned int g_forced_max_frame_height; + + /*!\brief Bit-depth of the codec + * + * This value identifies the bit_depth of the codec, + * Only certain bit-depths are supported as identified in the + * aom_bit_depth_t enum. + */ + aom_bit_depth_t g_bit_depth; + + /*!\brief Bit-depth of the input frames + * + * This value identifies the bit_depth of the input frames in bits. + * Note that the frames passed as input to the encoder must have + * this bit-depth. + */ + unsigned int g_input_bit_depth; + + /*!\brief Stream timebase units + * + * Indicates the smallest interval of time, in seconds, used by the stream. + * For fixed frame rate material, or variable frame rate material where + * frames are timed at a multiple of a given clock (ex: video capture), + * the \ref RECOMMENDED method is to set the timebase to the reciprocal + * of the frame rate (ex: 1001/30000 for 29.970 Hz NTSC). This allows the + * pts to correspond to the frame number, which can be handy. For + * re-encoding video from containers with absolute time timestamps, the + * \ref RECOMMENDED method is to set the timebase to that of the parent + * container or multimedia framework (ex: 1/1000 for ms, as in FLV). + */ + struct aom_rational g_timebase; + + /*!\brief Enable error resilient modes. + * + * The error resilient bitfield indicates to the encoder which features + * it should enable to take measures for streaming over lossy or noisy + * links. + */ + aom_codec_er_flags_t g_error_resilient; + + /*!\brief Multi-pass Encoding Mode + * + * This value should be set to the current phase for multi-pass encoding. + * For single pass, set to #AOM_RC_ONE_PASS. + */ + enum aom_enc_pass g_pass; + + /*!\brief Allow lagged encoding + * + * If set, this value allows the encoder to consume a number of input + * frames before producing output frames. This allows the encoder to + * base decisions for the current frame on future frames. This does + * increase the latency of the encoding pipeline, so it is not appropriate + * in all situations (ex: realtime encoding). + * + * Note that this is a maximum value -- the encoder may produce frames + * sooner than the given limit. Set this value to 0 to disable this + * feature. + */ + unsigned int g_lag_in_frames; + + /* + * rate control settings (rc) + */ + + /*!\brief Temporal resampling configuration, if supported by the codec. + * + * Temporal resampling allows the codec to "drop" frames as a strategy to + * meet its target data rate. This can cause temporal discontinuities in + * the encoded video, which may appear as stuttering during playback. This + * trade-off is often acceptable, but for many applications is not. It can + * be disabled in these cases. + * + * Note that not all codecs support this feature. All aom AVx codecs do. + * For other codecs, consult the documentation for that algorithm. + * + * This threshold is described as a percentage of the target data buffer. + * When the data buffer falls below this percentage of fullness, a + * dropped frame is indicated. Set the threshold to zero (0) to disable + * this feature. + */ + unsigned int rc_dropframe_thresh; + + /*!\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 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_mode; + + /*!\brief Frame resize denominator. + * + * The denominator for resize to use, assuming 8 as the numerator. + * + * Valid denominators are 8 - 16 for now. + */ + unsigned int rc_resize_denominator; + + /*!\brief Keyframe resize denominator. + * + * The denominator for resize to use, assuming 8 as the numerator. + * + * Valid denominators are 8 - 16 for now. + */ + unsigned int rc_resize_kf_denominator; + + /*!\brief Frame super-resolution scaling mode. + * + * 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. + */ + aom_superres_mode rc_superres_mode; + + /*!\brief Frame super-resolution denominator. + * + * The denominator 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 denominators are 8 to 16. + * + * Used only by AOM_SUPERRES_FIXED. + */ + unsigned int rc_superres_denominator; + + /*!\brief Keyframe super-resolution denominator. + * + * The denominator 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 denominators are 8 - 16 for now. + */ + unsigned int rc_superres_kf_denominator; + + /*!\brief Frame super-resolution q threshold. + * + * The q level threshold after which superres is used. + * Valid values are 1 to 63. + * + * Used only by AOM_SUPERRES_QTHRESH + */ + unsigned int rc_superres_qthresh; + + /*!\brief Keyframe super-resolution q threshold. + * + * The q level threshold after which superres is used for key frames. + * Valid values are 1 to 63. + * + * Used only by AOM_SUPERRES_QTHRESH + */ + unsigned int rc_superres_kf_qthresh; + + /*!\brief Rate control algorithm to use. + * + * Indicates whether the end usage of this stream is to be streamed over + * a bandwidth constrained link, indicating that Constant Bit Rate (CBR) + * mode should be used, or whether it will be played back on a high + * bandwidth link, as from a local disk, where higher variations in + * bitrate are acceptable. + */ + enum aom_rc_mode rc_end_usage; + + /*!\brief Two-pass stats buffer. + * + * A buffer containing all of the stats packets produced in the first + * pass, concatenated. + */ + aom_fixed_buf_t rc_twopass_stats_in; + + /*!\brief first pass mb stats buffer. + * + * A buffer containing all of the first pass mb stats packets produced + * in the first pass, concatenated. + */ + aom_fixed_buf_t rc_firstpass_mb_stats_in; + + /*!\brief Target data rate + * + * Target bandwidth to use for this stream, in kilobits per second. + */ + unsigned int rc_target_bitrate; + + /* + * quantizer settings + */ + + /*!\brief Minimum (Best Quality) Quantizer + * + * The quantizer is the most direct control over the quality of the + * encoded image. The range of valid values for the quantizer is codec + * specific. Consult the documentation for the codec to determine the + * values to use. To determine the range programmatically, call + * aom_codec_enc_config_default() with a usage value of 0. + */ + unsigned int rc_min_quantizer; + + /*!\brief Maximum (Worst Quality) Quantizer + * + * The quantizer is the most direct control over the quality of the + * encoded image. The range of valid values for the quantizer is codec + * specific. Consult the documentation for the codec to determine the + * values to use. To determine the range programmatically, call + * aom_codec_enc_config_default() with a usage value of 0. + */ + unsigned int rc_max_quantizer; + + /* + * bitrate tolerance + */ + + /*!\brief Rate control adaptation undershoot control + * + * This value, controls the tolerance of the VBR algorithm to undershoot + * and is used as a trigger threshold for more agressive adaptation of Q. + * + * Valid values in the range 0-100. + */ + unsigned int rc_undershoot_pct; + + /*!\brief Rate control adaptation overshoot control + * + * This value, controls the tolerance of the VBR algorithm to overshoot + * and is used as a trigger threshold for more agressive adaptation of Q. + * + * Valid values in the range 0-1000. + */ + unsigned int rc_overshoot_pct; + + /* + * decoder buffer model parameters + */ + + /*!\brief Decoder Buffer Size + * + * This value indicates the amount of data that may be buffered by the + * decoding application. Note that this value is expressed in units of + * time (milliseconds). For example, a value of 5000 indicates that the + * client will buffer (at least) 5000ms worth of encoded data. Use the + * target bitrate (#rc_target_bitrate) to convert to bits/bytes, if + * necessary. + */ + unsigned int rc_buf_sz; + + /*!\brief Decoder Buffer Initial Size + * + * This value indicates the amount of data that will be buffered by the + * decoding application prior to beginning playback. This value is + * expressed in units of time (milliseconds). Use the target bitrate + * (#rc_target_bitrate) to convert to bits/bytes, if necessary. + */ + unsigned int rc_buf_initial_sz; + + /*!\brief Decoder Buffer Optimal Size + * + * This value indicates the amount of data that the encoder should try + * to maintain in the decoder's buffer. This value is expressed in units + * of time (milliseconds). Use the target bitrate (#rc_target_bitrate) + * to convert to bits/bytes, if necessary. + */ + unsigned int rc_buf_optimal_sz; + + /* + * 2 pass rate control parameters + */ + + /*!\brief Two-pass mode CBR/VBR bias + * + * Bias, expressed on a scale of 0 to 100, for determining target size + * for the current frame. The value 0 indicates the optimal CBR mode + * value should be used. The value 100 indicates the optimal VBR mode + * value should be used. Values in between indicate which way the + * encoder should "lean." + */ + unsigned int rc_2pass_vbr_bias_pct; + + /*!\brief Two-pass mode per-GOP minimum bitrate + * + * This value, expressed as a percentage of the target bitrate, indicates + * the minimum bitrate to be used for a single GOP (aka "section") + */ + unsigned int rc_2pass_vbr_minsection_pct; + + /*!\brief Two-pass mode per-GOP maximum bitrate + * + * This value, expressed as a percentage of the target bitrate, indicates + * the maximum bitrate to be used for a single GOP (aka "section") + */ + unsigned int rc_2pass_vbr_maxsection_pct; + + /* + * keyframing settings (kf) + */ + + /*!\brief Option to enable forward reference key frame + * + */ + int fwd_kf_enabled; + + /*!\brief Keyframe placement mode + * + * This value indicates whether the encoder should place keyframes at a + * fixed interval, or determine the optimal placement automatically + * (as governed by the #kf_min_dist and #kf_max_dist parameters) + */ + enum aom_kf_mode kf_mode; + + /*!\brief Keyframe minimum interval + * + * This value, expressed as a number of frames, prevents the encoder from + * placing a keyframe nearer than kf_min_dist to the previous keyframe. At + * least kf_min_dist frames non-keyframes will be coded before the next + * keyframe. Set kf_min_dist equal to kf_max_dist for a fixed interval. + */ + unsigned int kf_min_dist; + + /*!\brief Keyframe maximum interval + * + * This value, expressed as a number of frames, forces the encoder to code + * a keyframe if one has not been coded in the last kf_max_dist frames. + * A value of 0 implies all frames will be keyframes. Set kf_min_dist + * equal to kf_max_dist for a fixed interval. + */ + unsigned int kf_max_dist; + + /*!\brief sframe interval + * + * This value, expressed as a number of frames, forces the encoder to code + * an S-Frame every sframe_dist frames. + */ + unsigned int sframe_dist; + + /*!\brief sframe insertion mode + * + * This value must be set to 1 or 2, and tells the encoder how to insert + * S-Frames. It will only have an effect if sframe_dist != 0. + * + * If altref is enabled: + * - if sframe_mode == 1, the considered frame will be made into an + * S-Frame only if it is an altref frame + * - if sframe_mode == 2, the next altref frame will be made into an + * S-Frame. + * + * Otherwise: the considered frame will be made into an S-Frame. + */ + unsigned int sframe_mode; + + /*!\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; + + /*!\brief Monochrome mode + * + * If this is nonzero, the encoder will generate a monochrome stream + * with no chroma planes. + */ + unsigned int monochrome; + + /*!\brief full_still_picture_hdr + * + * If this is nonzero, the encoder will generate a full header even for + * still picture encoding. if zero, a reduced header is used for still + * picture. This flag has no effect when a regular video with more than + * a single frame is encoded. + */ + unsigned int full_still_picture_hdr; + + /*!\brief Bitstream syntax mode + * + * This value indicates the bitstream syntax mode. + * A value of 0 indicates bitstream is saved as Section 5 bitstream. A value + * of 1 indicates the bitstream is saved in Annex-B format + */ + unsigned int save_as_annexb; + + /*!\brief Number of explicit tile widths specified + * + * This value indicates the number of tile widths specified + * A value of 0 implies no tile widths are specified. + * Tile widths are given in the array tile_widths[] + */ + int tile_width_count; + + /*!\brief Number of explicit tile heights specified + * + * This value indicates the number of tile heights specified + * A value of 0 implies no tile heights are specified. + * Tile heights are given in the array tile_heights[] + */ + int tile_height_count; + +/*!\brief Maximum number of tile widths in tile widths array + * + * This define gives the maximum number of elements in the tile_widths array. + */ +#define MAX_TILE_WIDTHS 64 // maximum tile width array length + + /*!\brief Array of specified tile widths + * + * This array specifies tile widths (and may be empty) + * The number of widths specified is given by tile_width_count + */ + int tile_widths[MAX_TILE_WIDTHS]; + +/*!\brief Maximum number of tile heights in tile heights array. + * + * This define gives the maximum number of elements in the tile_heights array. + */ +#define MAX_TILE_HEIGHTS 64 // maximum tile height array length + + /*!\brief Array of specified tile heights + * + * This array specifies tile heights (and may be empty) + * The number of heights specified is given by tile_height_count + */ + int tile_heights[MAX_TILE_HEIGHTS]; + + /*!\brief Whether encoder should use fixed QP offsets. + * + * If a value of 1 is provided, encoder will use fixed QP offsets for frames + * at different levels of the pyramid. + * - If 'fixed_qp_offsets' is also provided, encoder will use the given + * offsets + * - If not, encoder will select the fixed offsets based on the cq-level + * provided. + * If a value of 0 is provided and fixed_qp_offset are not provided, encoder + * will NOT use fixed QP offsets. + * Note: This option is only relevant for --end-usage=q. + */ + unsigned int use_fixed_qp_offsets; + +/*!\brief Number of fixed QP offsets + * + * This defines the number of elements in the fixed_qp_offsets array. + */ +#define FIXED_QP_OFFSET_COUNT 5 + + /*!\brief Array of fixed QP offsets + * + * This array specifies fixed QP offsets (range: 0 to 63) for frames at + * different levels of the pyramid. It is a comma-separated list of 5 values: + * - QP offset for keyframe + * - QP offset for ALTREF frame + * - QP offset for 1st level internal ARF + * - QP offset for 2nd level internal ARF + * - QP offset for 3rd level internal ARF + * Notes: + * - QP offset for leaf level frames is not explicitly specified. These frames + * use the worst quality allowed (--cq-level). + * - This option is only relevant for --end-usage=q. + */ + int fixed_qp_offsets[FIXED_QP_OFFSET_COUNT]; + + /*!\brief Options defined per config file + * + */ + cfg_options_t encoder_cfg; +} aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */ + +/*!\brief Initialize an encoder instance + * + * Initializes a encoder context using the given interface. Applications + * should call the aom_codec_enc_init convenience macro instead of this + * function directly, to ensure that the ABI version number parameter + * is properly initialized. + * + * If the library was configured with --disable-multithread, this call + * is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] iface Pointer to the algorithm interface to use. + * \param[in] cfg Configuration to use, if known. + * \param[in] flags Bitfield of AOM_CODEC_USE_* flags + * \param[in] ver ABI version number. Must be set to + * AOM_ENCODER_ABI_VERSION + * \retval #AOM_CODEC_OK + * The decoder algorithm initialized. + * \retval #AOM_CODEC_MEM_ERROR + * Memory allocation failed. + */ +aom_codec_err_t aom_codec_enc_init_ver(aom_codec_ctx_t *ctx, + aom_codec_iface_t *iface, + const aom_codec_enc_cfg_t *cfg, + aom_codec_flags_t flags, int ver); + +/*!\brief Convenience macro for aom_codec_enc_init_ver() + * + * Ensures the ABI version parameter is properly set. + */ +#define aom_codec_enc_init(ctx, iface, cfg, flags) \ + aom_codec_enc_init_ver(ctx, iface, cfg, flags, AOM_ENCODER_ABI_VERSION) + +/*!\brief Get the default configuration for a usage. + * + * Initializes an encoder configuration structure with default values. Supports + * the notion of "usages" so that an algorithm may offer different default + * settings depending on the user's intended goal. This function \ref SHOULD + * be called by all applications to initialize the configuration structure + * before specializing the configuration with application specific values. + * + * \param[in] iface Pointer to the algorithm interface to use. + * \param[out] cfg Configuration buffer to populate. + * \param[in] usage Algorithm specific usage value. For AV1, must be + * set to AOM_USAGE_GOOD_QUALITY (0) or + * AOM_USAGE_REALTIME (1). + * + * \retval #AOM_CODEC_OK + * The configuration was populated. + * \retval #AOM_CODEC_INCAPABLE + * Interface is not an encoder interface. + * \retval #AOM_CODEC_INVALID_PARAM + * A parameter was NULL, or the usage value was not recognized. + */ +aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface, + aom_codec_enc_cfg_t *cfg, + unsigned int usage); + +/*!\brief Set or change configuration + * + * Reconfigures an encoder instance according to the given configuration. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cfg Configuration buffer to use + * + * \retval #AOM_CODEC_OK + * The configuration was populated. + * \retval #AOM_CODEC_INCAPABLE + * Interface is not an encoder interface. + * \retval #AOM_CODEC_INVALID_PARAM + * A parameter was NULL, or the usage value was not recognized. + */ +aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx, + const aom_codec_enc_cfg_t *cfg); + +/*!\brief Get global stream headers + * + * Retrieves a stream level global header packet, if supported by the codec. + * Calls to this function should be deferred until all configuration information + * has been passed to libaom. Otherwise the global header data may be + * invalidated by additional configuration changes. + * + * The AV1 implementation of this function returns an OBU. The OBU returned is + * in Low Overhead Bitstream Format. Specifically, the obu_has_size_field bit is + * set, and the buffer contains the obu_size field for the returned OBU. + * + * \param[in] ctx Pointer to this instance's context + * + * \retval NULL + * Encoder does not support global header, or an error occurred while + * generating the global header. + * + * \retval Non-NULL + * Pointer to buffer containing global header packet. The caller owns the + * memory associated with this buffer, and must free the 'buf' member of the + * aom_fixed_buf_t as well as the aom_fixed_buf_t pointer. Memory returned + * must be freed via call to free(). + */ +aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx); + +/*!\brief usage parameter analogous to AV1 GOOD QUALITY mode. */ +#define AOM_USAGE_GOOD_QUALITY (0) +/*!\brief usage parameter analogous to AV1 REALTIME mode. */ +#define AOM_USAGE_REALTIME (1) + +/*!\brief Encode a frame + * + * Encodes a video frame at the given "presentation time." The presentation + * time stamp (PTS) \ref MUST be strictly increasing. + * + * When the last frame has been passed to the encoder, this function should + * continue to be called in a loop, with the img parameter set to NULL. This + * will signal the end-of-stream condition to the encoder and allow it to + * encode any held buffers. Encoding is complete when aom_codec_encode() is + * called with img set to NULL and aom_codec_get_cx_data() returns no data. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] img Image data to encode, NULL to flush. + * \param[in] pts Presentation time stamp, in timebase units. If img + * is NULL, pts is ignored. + * \param[in] duration Duration to show frame, in timebase units. If img + * is not NULL, duration must be nonzero. If img is + * NULL, duration is ignored. + * \param[in] flags Flags to use for encoding this frame. + * + * \retval #AOM_CODEC_OK + * The configuration was populated. + * \retval #AOM_CODEC_INCAPABLE + * Interface is not an encoder interface. + * \retval #AOM_CODEC_INVALID_PARAM + * A parameter was NULL, the image format is unsupported, etc. + */ +aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img, + aom_codec_pts_t pts, unsigned long duration, + aom_enc_frame_flags_t flags); + +/*!\brief Set compressed data output buffer + * + * Sets the buffer that the codec should output the compressed data + * into. This call effectively sets the buffer pointer returned in the + * next AOM_CODEC_CX_FRAME_PKT packet. Subsequent packets will be + * appended into this buffer. The buffer is preserved across frames, + * so applications must periodically call this function after flushing + * the accumulated compressed data to disk or to the network to reset + * the pointer to the buffer's head. + * + * `pad_before` bytes will be skipped before writing the compressed + * data, and `pad_after` bytes will be appended to the packet. The size + * of the packet will be the sum of the size of the actual compressed + * data, pad_before, and pad_after. The padding bytes will be preserved + * (not overwritten). + * + * Note that calling this function does not guarantee that the returned + * compressed data will be placed into the specified buffer. In the + * event that the encoded data will not fit into the buffer provided, + * the returned packet \ref MAY point to an internal buffer, as it would + * if this call were never used. In this event, the output packet will + * NOT have any padding, and the application must free space and copy it + * to the proper place. This is of particular note in configurations + * that may output multiple packets for a single encoded frame (e.g., lagged + * encoding) or if the application does not reset the buffer periodically. + * + * Applications may restore the default behavior of the codec providing + * the compressed data buffer by calling this function with a NULL + * buffer. + * + * Applications \ref MUSTNOT call this function during iteration of + * aom_codec_get_cx_data(). + * + * \param[in] ctx Pointer to this instance's context + * \param[in] buf Buffer to store compressed data into + * \param[in] pad_before Bytes to skip before writing compressed data + * \param[in] pad_after Bytes to skip after writing compressed data + * + * \retval #AOM_CODEC_OK + * The buffer was set successfully. + * \retval #AOM_CODEC_INVALID_PARAM + * A parameter was NULL, the image format is unsupported, etc. + */ +aom_codec_err_t aom_codec_set_cx_data_buf(aom_codec_ctx_t *ctx, + const aom_fixed_buf_t *buf, + unsigned int pad_before, + unsigned int pad_after); + +/*!\brief Encoded data iterator + * + * Iterates over a list of data packets to be passed from the encoder to the + * application. The different kinds of packets available are enumerated in + * #aom_codec_cx_pkt_kind. + * + * #AOM_CODEC_CX_FRAME_PKT packets should be passed to the application's + * muxer. Multiple compressed frames may be in the list. + * #AOM_CODEC_STATS_PKT packets should be appended to a global buffer. + * + * The application \ref MUST silently ignore any packet kinds that it does + * not recognize or support. + * + * The data buffers returned from this function are only guaranteed to be + * valid until the application makes another call to any aom_codec_* function. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] iter Iterator storage, initialized to NULL + * + * \return Returns a pointer to an output data packet (compressed frame data, + * two-pass statistics, etc.) or NULL to signal end-of-list. + * + */ +const aom_codec_cx_pkt_t *aom_codec_get_cx_data(aom_codec_ctx_t *ctx, + aom_codec_iter_t *iter); + +/*!\brief Get Preview Frame + * + * Returns an image that can be used as a preview. Shows the image as it would + * exist at the decompressor. The application \ref MUST NOT write into this + * image buffer. + * + * \param[in] ctx Pointer to this instance's context + * + * \return Returns a pointer to a preview image, or NULL if no image is + * available. + * + */ +const aom_image_t *aom_codec_get_preview_frame(aom_codec_ctx_t *ctx); + +/*!@} - end defgroup encoder*/ +#ifdef __cplusplus +} +#endif +#endif // AOM_AOM_AOM_ENCODER_H_ diff --git a/ThirdParty/avif/include/aom/aom_external_partition.h b/ThirdParty/avif/include/aom/aom_external_partition.h new file mode 100644 index 000000000..9e10fb7da --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_external_partition.h @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2021, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ +#ifndef AOM_AOM_AOM_EXTERNAL_PARTITION_H_ +#define AOM_AOM_AOM_EXTERNAL_PARTITION_H_ + +/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder + * \ingroup aom + * + * @{ + */ +#include + +/*!\file + * \brief Provides function pointer definitions for the external partition. + */ + +/*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this value + * must be bumped. Examples include, but are not limited to, changing + * types, removing or reassigning enums, adding/removing/rearranging + * fields to structures. + */ +#define AOM_EXT_PART_ABI_VERSION 3 + +#ifdef __cplusplus +extern "C" { +#endif + +/*!\brief Abstract external partition model handler + */ +typedef void *aom_ext_part_model_t; + +/*!\brief Number of features to determine whether to skip partition none and + * do partition split directly. The same as "FEATURE_SIZE_SMS_SPLIT". + */ +#define AOM_EXT_PART_SIZE_DIRECT_SPLIT 17 + +/*!\brief Number of features to use simple motion search to prune out + * rectangular partition in some direction. The same as + * "FEATURE_SIZE_SMS_PRUNE_PART". + */ +#define AOM_EXT_PART_SIZE_PRUNE_PART 25 + +/*!\brief Number of features to prune split and rectangular partition + * after PARTITION_NONE. + */ +#define AOM_EXT_PART_SIZE_PRUNE_NONE 4 + +/*!\brief Number of features to terminates partition after partition none using + * simple_motion_search features and the rate, distortion, and rdcost of + * PARTITION_NONE. The same as "FEATURE_SIZE_SMS_TERM_NONE". + */ +#define AOM_EXT_PART_SIZE_TERM_NONE 28 + +/*!\brief Number of features to terminates partition after partition split. + */ +#define AOM_EXT_PART_SIZE_TERM_SPLIT 31 + +/*!\brief Number of features to prune rectangular partition using stats + * collected after partition split. + */ +#define AOM_EXT_PART_SIZE_PRUNE_RECT 9 + +/*!\brief Number of features to prune AB partition using stats + * collected after rectangular partition.. + */ +#define AOM_EXT_PART_SIZE_PRUNE_AB 10 + +/*!\brief Number of features to prune 4-way partition using stats + * collected after AB partition. + */ +#define AOM_EXT_PART_SIZE_PRUNE_4_WAY 18 + +/*!\brief Decision mode of the external partition model. + * AOM_EXT_PART_WHOLE_TREE: the external partition model should provide the + * whole partition tree for the superblock. + * + * AOM_EXT_PART_RECURSIVE: the external partition model provides the partition + * decision of the current block only. The decision process starts from + * the superblock size, down to the smallest block size (4x4) recursively. + */ +typedef enum aom_ext_part_decision_mode { + AOM_EXT_PART_WHOLE_TREE = 0, + AOM_EXT_PART_RECURSIVE = 1, +} aom_ext_part_decision_mode_t; + +/*!\brief Config information sent to the external partition model. + * + * For example, the maximum superblock size determined by the sequence header. + */ +typedef struct aom_ext_part_config { + int superblock_size; ///< super block size (either 64x64 or 128x128) +} aom_ext_part_config_t; + +/*!\brief Features pass to the external model to make partition decisions. + * Specifically, features collected before NONE partition. + * Features "f" are used to determine: + * partition_none_allowed, partition_horz_allowed, partition_vert_allowed, + * do_rectangular_split, do_square_split + * Features "f_part2" are used to determine: + * prune_horz, prune_vert. + */ +typedef struct aom_partition_features_before_none { + /*! features to determine whether skip partition none and do split directly */ + float f[AOM_EXT_PART_SIZE_DIRECT_SPLIT]; + /*! features to determine whether to prune rectangular partition */ + float f_part2[AOM_EXT_PART_SIZE_PRUNE_PART]; +} aom_partition_features_before_none_t; + +/*!\brief Features pass to the external model to make partition decisions. + * Specifically, features collected after NONE partition. + */ +typedef struct aom_partition_features_none { + /*! features to prune split and rectangular partition */ + float f[AOM_EXT_PART_SIZE_PRUNE_NONE]; + /*! features to determine termination of partition */ + float f_terminate[AOM_EXT_PART_SIZE_TERM_NONE]; +} aom_partition_features_none_t; + +/*!\brief Features pass to the external model to make partition decisions. + * Specifically, features collected after SPLIT partition. + */ +typedef struct aom_partition_features_split { + /*! features to determine termination of partition */ + float f_terminate[AOM_EXT_PART_SIZE_TERM_SPLIT]; + /*! features to determine pruning rect partition */ + float f_prune_rect[AOM_EXT_PART_SIZE_PRUNE_RECT]; +} aom_partition_features_split_t; + +/*!\brief Features pass to the external model to make partition decisions. + * Specifically, features collected after RECTANGULAR partition. + */ +typedef struct aom_partition_features_rect { + /*! features to determine pruning AB partition */ + float f[AOM_EXT_PART_SIZE_PRUNE_AB]; +} aom_partition_features_rect_t; + +/*!\brief Features pass to the external model to make partition decisions. + * Specifically, features collected after AB partition: HORZ_A, HORZ_B, VERT_A, + * VERT_B. + */ +typedef struct aom_partition_features_ab { + /*! features to determine pruning 4-way partition */ + float f[AOM_EXT_PART_SIZE_PRUNE_4_WAY]; +} aom_partition_features_ab_t; + +/*!\brief Feature id to tell the external model the current stage in partition + * pruning and what features to use to make decisions accordingly. + */ +typedef enum { + AOM_EXT_PART_FEATURE_BEFORE_NONE, + AOM_EXT_PART_FEATURE_BEFORE_NONE_PART2, + AOM_EXT_PART_FEATURE_AFTER_NONE, + AOM_EXT_PART_FEATURE_AFTER_NONE_PART2, + AOM_EXT_PART_FEATURE_AFTER_SPLIT, + AOM_EXT_PART_FEATURE_AFTER_SPLIT_PART2, + AOM_EXT_PART_FEATURE_AFTER_RECT, + AOM_EXT_PART_FEATURE_AFTER_AB +} AOM_EXT_PART_FEATURE_ID; + +/*!\brief Features collected from the tpl process. + * + * The tpl process collects information that help measure the inter-frame + * dependency. + * The tpl process is computed in the unit of tpl_bsize_1d (16x16). + * Therefore, the max number of units inside a superblock is + * 128x128 / (16x16) = 64. Change it if the tpl process changes. + */ +typedef struct aom_sb_tpl_features { + int available; ///< If tpl stats are available + int tpl_unit_length; ///< The block length of tpl process + int num_units; ///< The number of units inside the current superblock + int64_t intra_cost[64]; ///< The intra cost of each unit + int64_t inter_cost[64]; ///< The inter cost of each unit + int64_t mc_dep_cost[64]; ///< The motion compensated dependency cost +} aom_sb_tpl_features_t; + +/*!\brief Features collected from the simple motion process. + * + * The simple motion process collects information by applying motion compensated + * prediction on each block. + * The block size is 16x16, which could be changed. If it is changed, update + * comments and the array size here. + */ +typedef struct aom_sb_simple_motion_features { + int unit_length; ///< The block length of the simple motion process + int num_units; ///< The number of units inside the current superblock + int block_sse[64]; ///< Sum of squared error of each unit + int block_var[64]; ///< Variance of each unit +} aom_sb_simple_motion_features_t; + +/*!\brief Features of each super block. + * + * Features collected for each super block before partition search. + */ +typedef struct aom_sb_features { + /*! Features from motion search */ + aom_sb_simple_motion_features_t motion_features; + /*! Features from tpl process */ + aom_sb_tpl_features_t tpl_features; +} aom_sb_features_t; + +/*!\brief Features pass to the external model to make partition decisions. + * + * The encoder sends these features to the external model through + * "func()" defined in ..... + * + * NOTE: new member variables may be added to this structure in the future. + * Once new features are finalized, bump the major version of libaom. + */ +typedef struct aom_partition_features { + // Features for the current supervised multi-stage ML model. + /*! Feature ID to indicate active features */ + AOM_EXT_PART_FEATURE_ID id; + /*! Features collected before NONE partition */ + aom_partition_features_before_none_t before_part_none; + /*! Features collected after NONE partition */ + aom_partition_features_none_t after_part_none; + /*! Features collected after SPLIT partition */ + aom_partition_features_split_t after_part_split; + /*! Features collected after RECTANGULAR partition */ + aom_partition_features_rect_t after_part_rect; + /*! Features collected after AB partition */ + aom_partition_features_ab_t after_part_ab; + + // Features for a new ML model. + aom_sb_features_t sb_features; ///< Features collected for the super block + int mi_row; ///< Mi_row position of the block + int mi_col; ///< Mi_col position of the block + int frame_width; ///< Frame width + int frame_height; ///< Frame height + int block_size; ///< As "BLOCK_SIZE" in av1/common/enums.h +} aom_partition_features_t; + +/*!\brief Partition decisions received from the external model. + * + * The encoder receives partition decisions and encodes the superblock + * with the given partition type. + * The encoder receives it from "func()" define in .... + * + * NOTE: new member variables may be added to this structure in the future. + * Once new features are finalized, bump the major version of libaom. + */ +typedef struct aom_partition_decision { + // Decisions for directly set partition types + int is_final_decision; ///< The flag whether it's the final decision + int num_nodes; ///< The number of leaf nodes + int partition_decision[2048]; ///< Partition decisions + int current_decision; ///< Partition decision for the current block + + // Decisions for partition type pruning + int terminate_partition_search; ///< Terminate further partition search + int partition_none_allowed; ///< Allow partition none type + int partition_rect_allowed[2]; ///< Allow rectangular partitions + int do_rectangular_split; ///< Try rectangular split partition + int do_square_split; ///< Try square split partition + int prune_rect_part[2]; ///< Prune rectangular partition + int horza_partition_allowed; ///< Allow HORZ_A partitioin + int horzb_partition_allowed; ///< Allow HORZ_B partitioin + int verta_partition_allowed; ///< Allow VERT_A partitioin + int vertb_partition_allowed; ///< Allow VERT_B partitioin + int partition_horz4_allowed; ///< Allow HORZ4 partition + int partition_vert4_allowed; ///< Allow VERT4 partition +} aom_partition_decision_t; + +/*!\brief Encoding stats for the given partition decision. + * + * The encoding stats collected by encoding the superblock with the + * given partition types. + * The encoder sends the stats to the external model for training + * or inference though "func()" defined in .... + */ +typedef struct aom_partition_stats { + int rate; ///< Rate cost of the block + int64_t dist; ///< Distortion of the block + int64_t rdcost; ///< Rate-distortion cost of the block +} aom_partition_stats_t; + +/*!\brief Enum for return status. + */ +typedef enum aom_ext_part_status { + AOM_EXT_PART_OK = 0, ///< Status of success + AOM_EXT_PART_ERROR = 1, ///< Status of failure + AOM_EXT_PART_TEST = 2, ///< Status used for tests +} aom_ext_part_status_t; + +/*!\brief Callback of creating an external partition model. + * + * The callback is invoked by the encoder to create an external partition + * model. + * + * \param[in] priv Callback's private data + * \param[in] part_config Config information pointer for model creation + * \param[out] ext_part_model Pointer to the model + */ +typedef aom_ext_part_status_t (*aom_ext_part_create_model_fn_t)( +void *priv, const aom_ext_part_config_t *part_config, +aom_ext_part_model_t *ext_part_model); + +/*!\brief Callback of sending features to the external partition model. + * + * The callback is invoked by the encoder to send features to the external + * partition model. + * + * \param[in] ext_part_model The external model + * \param[in] part_features Pointer to the features + */ +typedef aom_ext_part_status_t (*aom_ext_part_send_features_fn_t)( +aom_ext_part_model_t ext_part_model, +const aom_partition_features_t *part_features); + +/*!\brief Callback of receiving partition decisions from the external + * partition model. + * + * The callback is invoked by the encoder to receive partition decisions from + * the external partition model. + * + * \param[in] ext_part_model The external model + * \param[in] ext_part_decision Pointer to the partition decisions + */ +typedef aom_ext_part_status_t (*aom_ext_part_get_decision_fn_t)( +aom_ext_part_model_t ext_part_model, +aom_partition_decision_t *ext_part_decision); + +/*!\brief Callback of sending stats to the external partition model. + * + * The callback is invoked by the encoder to send encoding stats to + * the external partition model. + * + * \param[in] ext_part_model The external model + * \param[in] ext_part_stats Pointer to the encoding stats + */ +typedef aom_ext_part_status_t (*aom_ext_part_send_partition_stats_fn_t)( +aom_ext_part_model_t ext_part_model, +const aom_partition_stats_t *ext_part_stats); + +/*!\brief Callback of deleting the external partition model. + * + * The callback is invoked by the encoder to delete the external partition + * model. + * + * \param[in] ext_part_model The external model + */ +typedef aom_ext_part_status_t (*aom_ext_part_delete_model_fn_t)( +aom_ext_part_model_t ext_part_model); + +/*!\brief Callback function set for external partition model. + * + * Uses can enable external partition model by registering a set of + * callback functions with the flag: AV1E_SET_EXTERNAL_PARTITION_MODEL + */ +typedef struct aom_ext_part_funcs { + /*! + * Create an external partition model. + */ + aom_ext_part_create_model_fn_t create_model; + + /*! + * Send features to the external partition model to make partition decisions. + */ + aom_ext_part_send_features_fn_t send_features; + + /*! + * Get partition decisions from the external partition model. + */ + aom_ext_part_get_decision_fn_t get_partition_decision; + + /*! + * Send stats of the current partition to the external model. + */ + aom_ext_part_send_partition_stats_fn_t send_partition_stats; + + /*! + * Delete the external partition model. + */ + aom_ext_part_delete_model_fn_t delete_model; + + /*! + * The decision mode of the model. + */ + aom_ext_part_decision_mode_t decision_mode; + + /*! + * Private data for the external partition model. + */ + void *priv; +} aom_ext_part_funcs_t; + +/*!@} - end defgroup aom_encoder*/ +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOM_EXTERNAL_PARTITION_H_ diff --git a/ThirdParty/avif/include/aom/aom_frame_buffer.h b/ThirdParty/avif/include/aom/aom_frame_buffer.h new file mode 100644 index 000000000..c09eb1e4b --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_frame_buffer.h @@ -0,0 +1,84 @@ +/* + * 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 AOM_AOM_AOM_FRAME_BUFFER_H_ +#define AOM_AOM_AOM_FRAME_BUFFER_H_ + +/*!\file + * \brief Describes the decoder external frame buffer interface. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "aom/aom_integer.h" + +/*!\brief The maximum number of work buffers used by libaom. + * Support maximum 4 threads to decode video in parallel. + * Each thread will use one work buffer. + * TODO(hkuang): Add support to set number of worker threads dynamically. + */ +#define AOM_MAXIMUM_WORK_BUFFERS 8 + +/*!\brief The maximum number of reference buffers that a AV1 encoder may use. + */ +#define AOM_MAXIMUM_REF_BUFFERS 8 + +/*!\brief External frame buffer + * + * This structure holds allocated frame buffers used by the decoder. + */ +typedef struct aom_codec_frame_buffer { + uint8_t *data; /**< Pointer to the data buffer */ + size_t size; /**< Size of data in bytes */ + void *priv; /**< Frame's private data */ +} aom_codec_frame_buffer_t; + +/*!\brief get frame buffer callback prototype + * + * This callback is invoked by the decoder to retrieve data for the frame + * buffer in order for the decode call to complete. The callback must + * allocate at least min_size in bytes and assign it to fb->data. The callback + * must zero out all the data allocated. Then the callback must set fb->size + * to the allocated size. The application does not need to align the allocated + * data. The callback is triggered when the decoder needs a frame buffer to + * decode a compressed image into. This function may be called more than once + * for every call to aom_codec_decode. The application may set fb->priv to + * some data which will be passed back in the aom_image_t and the release + * function call. |fb| is guaranteed to not be NULL. On success the callback + * must return 0. Any failure the callback must return a value less than 0. + * + * \param[in] priv Callback's private data + * \param[in] new_size Size in bytes needed by the buffer + * \param[in,out] fb Pointer to aom_codec_frame_buffer_t + */ +typedef int (*aom_get_frame_buffer_cb_fn_t)(void *priv, size_t min_size, + aom_codec_frame_buffer_t *fb); + +/*!\brief release frame buffer callback prototype + * + * This callback is invoked by the decoder when the frame buffer is not + * referenced by any other buffers. |fb| is guaranteed to not be NULL. On + * success the callback must return 0. Any failure the callback must return + * a value less than 0. + * + * \param[in] priv Callback's private data + * \param[in] fb Pointer to aom_codec_frame_buffer_t + */ +typedef int (*aom_release_frame_buffer_cb_fn_t)(void *priv, + aom_codec_frame_buffer_t *fb); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOM_FRAME_BUFFER_H_ diff --git a/ThirdParty/avif/include/aom/aom_image.h b/ThirdParty/avif/include/aom/aom_image.h new file mode 100644 index 000000000..0e270d5b9 --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_image.h @@ -0,0 +1,436 @@ +/* + * 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. + */ + +/*!\file + * \brief Describes the aom image descriptor and associated operations + * + */ +#ifndef AOM_AOM_AOM_IMAGE_H_ +#define AOM_AOM_AOM_IMAGE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "aom/aom_integer.h" + +/*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this value + * must be bumped. Examples include, but are not limited to, changing + * types, removing or reassigning enums, adding/removing/rearranging + * fields to structures + */ +#define AOM_IMAGE_ABI_VERSION (9) /**<\hideinitializer*/ + +#define AOM_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */ +#define AOM_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */ +/** 0x400 used to signal alpha channel, skipping for backwards compatibility. */ +#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */ + +/*!\brief List of supported image formats */ +typedef enum aom_img_fmt { + AOM_IMG_FMT_NONE, + AOM_IMG_FMT_YV12 = + AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | 1, /**< planar YVU */ + AOM_IMG_FMT_I420 = AOM_IMG_FMT_PLANAR | 2, + AOM_IMG_FMT_AOMYV12 = AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | + 3, /** < planar 4:2:0 format with aom color space */ + AOM_IMG_FMT_AOMI420 = AOM_IMG_FMT_PLANAR | 4, + AOM_IMG_FMT_I422 = AOM_IMG_FMT_PLANAR | 5, + AOM_IMG_FMT_I444 = AOM_IMG_FMT_PLANAR | 6, + AOM_IMG_FMT_I42016 = AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_YV1216 = AOM_IMG_FMT_YV12 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_I42216 = AOM_IMG_FMT_I422 | AOM_IMG_FMT_HIGHBITDEPTH, + AOM_IMG_FMT_I44416 = AOM_IMG_FMT_I444 | AOM_IMG_FMT_HIGHBITDEPTH, +} aom_img_fmt_t; /**< alias for enum aom_img_fmt */ + +/*!\brief List of supported color primaries */ +typedef enum aom_color_primaries { + AOM_CICP_CP_RESERVED_0 = 0, /**< For future use */ + AOM_CICP_CP_BT_709 = 1, /**< BT.709 */ + AOM_CICP_CP_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_CP_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_CP_BT_470_M = 4, /**< BT.470 System M (historical) */ + AOM_CICP_CP_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_CP_BT_601 = 6, /**< BT.601 */ + AOM_CICP_CP_SMPTE_240 = 7, /**< SMPTE 240 */ + AOM_CICP_CP_GENERIC_FILM = + 8, /**< Generic film (color filters using illuminant C) */ + AOM_CICP_CP_BT_2020 = 9, /**< BT.2020, BT.2100 */ + AOM_CICP_CP_XYZ = 10, /**< SMPTE 428 (CIE 1921 XYZ) */ + AOM_CICP_CP_SMPTE_431 = 11, /**< SMPTE RP 431-2 */ + AOM_CICP_CP_SMPTE_432 = 12, /**< SMPTE EG 432-1 */ + AOM_CICP_CP_RESERVED_13 = 13, /**< For future use (values 13 - 21) */ + AOM_CICP_CP_EBU_3213 = 22, /**< EBU Tech. 3213-E */ + AOM_CICP_CP_RESERVED_23 = 23 /**< For future use (values 23 - 255) */ +} aom_color_primaries_t; /**< alias for enum aom_color_primaries */ + +/*!\brief List of supported transfer functions */ +typedef enum aom_transfer_characteristics { + AOM_CICP_TC_RESERVED_0 = 0, /**< For future use */ + AOM_CICP_TC_BT_709 = 1, /**< BT.709 */ + AOM_CICP_TC_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_TC_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_TC_BT_470_M = 4, /**< BT.470 System M (historical) */ + AOM_CICP_TC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_TC_BT_601 = 6, /**< BT.601 */ + AOM_CICP_TC_SMPTE_240 = 7, /**< SMPTE 240 M */ + AOM_CICP_TC_LINEAR = 8, /**< Linear */ + AOM_CICP_TC_LOG_100 = 9, /**< Logarithmic (100 : 1 range) */ + AOM_CICP_TC_LOG_100_SQRT10 = + 10, /**< Logarithmic (100 * Sqrt(10) : 1 range) */ + AOM_CICP_TC_IEC_61966 = 11, /**< IEC 61966-2-4 */ + AOM_CICP_TC_BT_1361 = 12, /**< BT.1361 */ + AOM_CICP_TC_SRGB = 13, /**< sRGB or sYCC*/ + AOM_CICP_TC_BT_2020_10_BIT = 14, /**< BT.2020 10-bit systems */ + AOM_CICP_TC_BT_2020_12_BIT = 15, /**< BT.2020 12-bit systems */ + AOM_CICP_TC_SMPTE_2084 = 16, /**< SMPTE ST 2084, ITU BT.2100 PQ */ + AOM_CICP_TC_SMPTE_428 = 17, /**< SMPTE ST 428 */ + AOM_CICP_TC_HLG = 18, /**< BT.2100 HLG, ARIB STD-B67 */ + AOM_CICP_TC_RESERVED_19 = 19 /**< For future use (values 19-255) */ +} aom_transfer_characteristics_t; /**< alias for enum aom_transfer_function */ + +/*!\brief List of supported matrix coefficients */ +typedef enum aom_matrix_coefficients { + AOM_CICP_MC_IDENTITY = 0, /**< Identity matrix */ + AOM_CICP_MC_BT_709 = 1, /**< BT.709 */ + AOM_CICP_MC_UNSPECIFIED = 2, /**< Unspecified */ + AOM_CICP_MC_RESERVED_3 = 3, /**< For future use */ + AOM_CICP_MC_FCC = 4, /**< US FCC 73.628 */ + AOM_CICP_MC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */ + AOM_CICP_MC_BT_601 = 6, /**< BT.601 */ + AOM_CICP_MC_SMPTE_240 = 7, /**< SMPTE 240 M */ + AOM_CICP_MC_SMPTE_YCGCO = 8, /**< YCgCo */ + AOM_CICP_MC_BT_2020_NCL = + 9, /**< BT.2020 non-constant luminance, BT.2100 YCbCr */ + AOM_CICP_MC_BT_2020_CL = 10, /**< BT.2020 constant luminance */ + AOM_CICP_MC_SMPTE_2085 = 11, /**< SMPTE ST 2085 YDzDx */ + AOM_CICP_MC_CHROMAT_NCL = + 12, /**< Chromaticity-derived non-constant luminance */ + AOM_CICP_MC_CHROMAT_CL = 13, /**< Chromaticity-derived constant luminance */ + AOM_CICP_MC_ICTCP = 14, /**< BT.2100 ICtCp */ + AOM_CICP_MC_RESERVED_15 = 15 /**< For future use (values 15-255) */ +} aom_matrix_coefficients_t; + +/*!\brief List of supported color range */ +typedef enum aom_color_range { + AOM_CR_STUDIO_RANGE = 0, /**< Y [16..235], UV [16..240] */ + AOM_CR_FULL_RANGE = 1 /**< YUV/RGB [0..255] */ +} aom_color_range_t; /**< alias for enum aom_color_range */ + +/*!\brief List of chroma sample positions */ +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 */ + +/*!\brief List of insert flags for Metadata + * + * These flags control how the library treats metadata during encode. + * + * While encoding, when metadata is added to an aom_image via + * aom_img_add_metadata(), the flag passed along with the metadata will + * determine where the metadata OBU will be placed in the encoded OBU stream. + * Metadata will be emitted into the output stream within the next temporal unit + * if it satisfies the specified insertion flag. + * + * During decoding, when the library encounters a metadata OBU, it is always + * flagged as AOM_MIF_ANY_FRAME and emitted with the next output aom_image. + */ +typedef enum aom_metadata_insert_flags { + AOM_MIF_NON_KEY_FRAME = 0, /**< Adds metadata if it's not keyframe */ + AOM_MIF_KEY_FRAME = 1, /**< Adds metadata only if it's a keyframe */ + AOM_MIF_ANY_FRAME = 2 /**< Adds metadata to any type of frame */ +} aom_metadata_insert_flags_t; + +/*!\brief Array of aom_metadata structs for an image. */ +typedef struct aom_metadata_array aom_metadata_array_t; + +/*!\brief Metadata payload. */ +typedef struct aom_metadata { + uint32_t type; /**< Metadata type */ + uint8_t *payload; /**< Metadata payload data */ + size_t sz; /**< Metadata payload size */ + aom_metadata_insert_flags_t insert_flag; /**< Metadata insertion flag */ +} aom_metadata_t; + +/**\brief Image Descriptor */ +typedef struct aom_image { + aom_img_fmt_t fmt; /**< Image Format */ + aom_color_primaries_t cp; /**< CICP Color Primaries */ + aom_transfer_characteristics_t tc; /**< CICP Transfer Characteristics */ + aom_matrix_coefficients_t mc; /**< CICP Matrix Coefficients */ + int monochrome; /**< Whether image is monochrome */ + aom_chroma_sample_position_t csp; /**< chroma sample position */ + aom_color_range_t range; /**< Color Range */ + + /* Image storage dimensions */ + unsigned int w; /**< Stored image width */ + unsigned int h; /**< Stored image height */ + unsigned int bit_depth; /**< Stored image bit-depth */ + + /* Image display dimensions */ + unsigned int d_w; /**< Displayed image width */ + unsigned int d_h; /**< Displayed image height */ + + /* Image intended rendering dimensions */ + unsigned int r_w; /**< Intended rendering image width */ + unsigned int r_h; /**< Intended rendering image height */ + + /* Chroma subsampling info */ + unsigned int x_chroma_shift; /**< subsampling order, X */ + unsigned int y_chroma_shift; /**< subsampling order, Y */ + +/* Image data pointers. */ +#define AOM_PLANE_PACKED 0 /**< To be used for all packed formats */ +#define AOM_PLANE_Y 0 /**< Y (Luminance) plane */ +#define AOM_PLANE_U 1 /**< U (Chroma) plane */ +#define AOM_PLANE_V 2 /**< V (Chroma) plane */ + unsigned char *planes[3]; /**< pointer to the top left pixel for each plane */ + int stride[3]; /**< stride between rows for each plane */ + size_t sz; /**< data size */ + + int bps; /**< bits per sample (for packed formats) */ + + int temporal_id; /**< Temporal layer Id of image */ + int spatial_id; /**< Spatial layer Id of image */ + + /*!\brief The following member may be set by the application to associate + * data with this image. + */ + void *user_priv; + + /* The following members should be treated as private. */ + unsigned char *img_data; /**< private */ + int img_data_owner; /**< private */ + int self_allocd; /**< private */ + + aom_metadata_array_t + *metadata; /**< Metadata payloads associated with the image. */ + + void *fb_priv; /**< Frame buffer data associated with the image. */ +} aom_image_t; /**< alias for struct aom_image */ + +/*!\brief Open a descriptor, allocating storage for the underlying image + * + * Returns a descriptor for storing an image of the given format. The + * storage for the image is allocated on the heap. + * + * \param[in] img Pointer to storage for descriptor. If this parameter + * is NULL, the storage for the descriptor will be + * allocated on the heap. + * \param[in] fmt Format for the image + * \param[in] d_w Width of the image + * \param[in] d_h Height of the image + * \param[in] align Alignment, in bytes, of the image buffer and + * each row in the image (stride). + * + * \return Returns a pointer to the initialized image descriptor. If the img + * parameter is non-null, the value of the img parameter will be + * returned. + */ +aom_image_t *aom_img_alloc(aom_image_t *img, aom_img_fmt_t fmt, + unsigned int d_w, unsigned int d_h, + unsigned int align); + +/*!\brief Open a descriptor, using existing storage for the underlying image + * + * Returns a descriptor for storing an image of the given format. The + * storage for the image has been allocated elsewhere, and a descriptor is + * desired to "wrap" that storage. + * + * \param[in] img Pointer to storage for descriptor. If this parameter + * is NULL, the storage for the descriptor will be + * allocated on the heap. + * \param[in] fmt Format for the image + * \param[in] d_w Width of the image + * \param[in] d_h Height of the image + * \param[in] align Alignment, in bytes, of each row in the image + * (stride). + * \param[in] img_data Storage to use for the image + * + * \return Returns a pointer to the initialized image descriptor. If the img + * parameter is non-null, the value of the img parameter will be + * returned. + */ +aom_image_t *aom_img_wrap(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w, + unsigned int d_h, unsigned int align, + unsigned char *img_data); + +/*!\brief Open a descriptor, allocating storage for the underlying image with a + * border + * + * Returns a descriptor for storing an image of the given format and its + * borders. The storage for the image is allocated on the heap. + * + * \param[in] img Pointer to storage for descriptor. If this parameter + * is NULL, the storage for the descriptor will be + * allocated on the heap. + * \param[in] fmt Format for the image + * \param[in] d_w Width of the image + * \param[in] d_h Height of the image + * \param[in] align Alignment, in bytes, of the image buffer and + * each row in the image (stride). + * \param[in] size_align Alignment, in pixels, of the image width and height. + * \param[in] border A border that is padded on four sides of the image. + * + * \return Returns a pointer to the initialized image descriptor. If the img + * parameter is non-null, the value of the img parameter will be + * returned. + */ +aom_image_t *aom_img_alloc_with_border(aom_image_t *img, aom_img_fmt_t fmt, + unsigned int d_w, unsigned int d_h, + unsigned int align, + unsigned int size_align, + unsigned int border); + +/*!\brief Set the rectangle identifying the displayed portion of the image + * + * Updates the displayed rectangle (aka viewport) on the image surface to + * match the specified coordinates and size. + * + * \param[in] img Image descriptor + * \param[in] x leftmost column + * \param[in] y topmost row + * \param[in] w width + * \param[in] h height + * \param[in] border A border that is padded on four sides of the image. + * + * \return 0 if the requested rectangle is valid, nonzero otherwise. + */ +int aom_img_set_rect(aom_image_t *img, unsigned int x, unsigned int y, + unsigned int w, unsigned int h, unsigned int border); + +/*!\brief Flip the image vertically (top for bottom) + * + * Adjusts the image descriptor's pointers and strides to make the image + * be referenced upside-down. + * + * \param[in] img Image descriptor + */ +void aom_img_flip(aom_image_t *img); + +/*!\brief Close an image descriptor + * + * Frees all allocated storage associated with an image descriptor. + * + * \param[in] img Image descriptor + */ +void aom_img_free(aom_image_t *img); + +/*!\brief Get the width of a plane + * + * Get the width of a plane of an image + * + * \param[in] img Image descriptor + * \param[in] plane Plane index + */ +int aom_img_plane_width(const aom_image_t *img, int plane); + +/*!\brief Get the height of a plane + * + * Get the height of a plane of an image + * + * \param[in] img Image descriptor + * \param[in] plane Plane index + */ +int aom_img_plane_height(const aom_image_t *img, int plane); + +/*!\brief Add metadata to image. + * + * Adds metadata to aom_image_t. + * Function makes a copy of the provided data parameter. + * Metadata insertion point is controlled by insert_flag. + * + * \param[in] img Image descriptor + * \param[in] type Metadata type + * \param[in] data Metadata contents + * \param[in] sz Metadata contents size + * \param[in] insert_flag Metadata insert flag + * + * \return Returns 0 on success. If img or data is NULL, sz is 0, or memory + * allocation fails, it returns -1. + */ +int aom_img_add_metadata(aom_image_t *img, uint32_t type, const uint8_t *data, + size_t sz, aom_metadata_insert_flags_t insert_flag); + +/*!\brief Return a metadata payload stored within the image metadata array. + * + * Gets the metadata (aom_metadata_t) at the indicated index in the image + * metadata array. + * + * \param[in] img Pointer to image descriptor to get metadata from + * \param[in] index Metadata index to get from metadata array + * + * \return Returns a const pointer to the selected metadata, if img and/or index + * is invalid, it returns NULL. + */ +const aom_metadata_t *aom_img_get_metadata(const aom_image_t *img, + size_t index); + +/*!\brief Return the number of metadata blocks within the image. + * + * Gets the number of metadata blocks contained within the provided image + * metadata array. + * + * \param[in] img Pointer to image descriptor to get metadata number + * from. + * + * \return Returns the size of the metadata array. If img or metadata is NULL, + * it returns 0. + */ +size_t aom_img_num_metadata(const aom_image_t *img); + +/*!\brief Remove metadata from image. + * + * Removes all metadata in image metadata list and sets metadata list pointer + * to NULL. + * + * \param[in] img Image descriptor + */ +void aom_img_remove_metadata(aom_image_t *img); + +/*!\brief Allocate memory for aom_metadata struct. + * + * Allocates storage for the metadata payload, sets its type and copies the + * payload data into the aom_metadata struct. A metadata payload buffer of size + * sz is allocated and sz bytes are copied from data into the payload buffer. + * + * \param[in] type Metadata type + * \param[in] data Metadata data pointer + * \param[in] sz Metadata size + * \param[in] insert_flag Metadata insert flag + * + * \return Returns the newly allocated aom_metadata struct. If data is NULL, + * sz is 0, or memory allocation fails, it returns NULL. + */ +aom_metadata_t *aom_img_metadata_alloc(uint32_t type, const uint8_t *data, + size_t sz, + aom_metadata_insert_flags_t insert_flag); + +/*!\brief Free metadata struct. + * + * Free metadata struct and its buffer. + * + * \param[in] metadata Metadata struct pointer + */ +void aom_img_metadata_free(aom_metadata_t *metadata); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOM_IMAGE_H_ diff --git a/ThirdParty/avif/include/aom/aom_integer.h b/ThirdParty/avif/include/aom/aom_integer.h new file mode 100644 index 000000000..b9dca0135 --- /dev/null +++ b/ThirdParty/avif/include/aom/aom_integer.h @@ -0,0 +1,68 @@ +/* + * 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 AOM_AOM_AOM_INTEGER_H_ +#define AOM_AOM_AOM_INTEGER_H_ + +/* get ptrdiff_t, size_t, wchar_t, NULL */ +#include + +#if defined(_MSC_VER) +#define AOM_FORCE_INLINE __forceinline +#define AOM_INLINE __inline +#else +#define AOM_FORCE_INLINE __inline__ __attribute__((always_inline)) +#define AOM_INLINE inline +#endif + +/* Assume platforms have the C99 standard integer types. */ + +#if defined(__cplusplus) +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif +#if !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif +#endif // __cplusplus + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif // __cplusplus + +// Returns size of uint64_t when encoded using LEB128. +size_t aom_uleb_size_in_bytes(uint64_t value); + +// Returns 0 on success, -1 on decode failure. +// On success, 'value' stores the decoded LEB128 value and 'length' stores +// the number of bytes decoded. +int aom_uleb_decode(const uint8_t *buffer, size_t available, uint64_t *value, + size_t *length); + +// Encodes LEB128 integer. Returns 0 when successful, and -1 upon failure. +int aom_uleb_encode(uint64_t value, size_t available, uint8_t *coded_value, + size_t *coded_size); + +// Encodes LEB128 integer to size specified. Returns 0 when successful, and -1 +// upon failure. +// Note: This will write exactly pad_to_size bytes; if the value cannot be +// encoded in this many bytes, then this will fail. +int aom_uleb_encode_fixed_size(uint64_t value, size_t available, + size_t pad_to_size, uint8_t *coded_value, + size_t *coded_size); + +#if defined(__cplusplus) +} // extern "C" +#endif // __cplusplus + +#endif // AOM_AOM_AOM_INTEGER_H_ diff --git a/ThirdParty/avif/include/aom/aomcx.h b/ThirdParty/avif/include/aom/aomcx.h new file mode 100644 index 000000000..f9b5374f8 --- /dev/null +++ b/ThirdParty/avif/include/aom/aomcx.h @@ -0,0 +1,1793 @@ +/* + * 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 AOM_AOM_AOMCX_H_ +#define AOM_AOM_AOMCX_H_ + +/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder + * \ingroup aom + * + * @{ + */ +#include "aom/aom.h" +#include "aom/aom_encoder.h" + +/*!\file + * \brief Provides definitions for using AOM or AV1 encoder algorithm within the + * aom Codec Interface. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*!\name Algorithm interface for AV1 + * + * This interface provides the capability to encode raw AV1 streams. + *@{ + */ + +/*!\brief A single instance of the AV1 encoder. + *\deprecated This access mechanism is provided for backwards compatibility; + * prefer aom_codec_av1_cx(). + */ +extern aom_codec_iface_t aom_codec_av1_cx_algo; + +/*!\brief The interface to the AV1 encoder. + */ +extern aom_codec_iface_t *aom_codec_av1_cx(void); +/*!@} - end algorithm interface member group */ + +/* + * Algorithm Flags + */ + +/*!\brief Don't reference the last frame + * + * When this flag is set, the encoder will not use the last frame as a + * predictor. When not set, the encoder will choose whether to use the + * last frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_LAST (1 << 16) +/*!\brief Don't reference the last2 frame + * + * When this flag is set, the encoder will not use the last2 frame as a + * predictor. When not set, the encoder will choose whether to use the + * last2 frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_LAST2 (1 << 17) +/*!\brief Don't reference the last3 frame + * + * When this flag is set, the encoder will not use the last3 frame as a + * predictor. When not set, the encoder will choose whether to use the + * last3 frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_LAST3 (1 << 18) +/*!\brief Don't reference the golden frame + * + * When this flag is set, the encoder will not use the golden frame as a + * predictor. When not set, the encoder will choose whether to use the + * golden frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_GF (1 << 19) + +/*!\brief Don't reference the alternate reference frame + * + * When this flag is set, the encoder will not use the alt ref frame as a + * predictor. When not set, the encoder will choose whether to use the + * alt ref frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_ARF (1 << 20) +/*!\brief Don't reference the bwd reference frame + * + * When this flag is set, the encoder will not use the bwd ref frame as a + * predictor. When not set, the encoder will choose whether to use the + * bwd ref frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_BWD (1 << 21) +/*!\brief Don't reference the alt2 reference frame + * + * When this flag is set, the encoder will not use the alt2 ref frame as a + * predictor. When not set, the encoder will choose whether to use the + * alt2 ref frame or not automatically. + */ +#define AOM_EFLAG_NO_REF_ARF2 (1 << 22) + +/*!\brief Don't update the last frame + * + * When this flag is set, the encoder will not update the last frame with + * the contents of the current frame. + */ +#define AOM_EFLAG_NO_UPD_LAST (1 << 23) + +/*!\brief Don't update the golden frame + * + * When this flag is set, the encoder will not update the golden frame with + * the contents of the current frame. + */ +#define AOM_EFLAG_NO_UPD_GF (1 << 24) + +/*!\brief Don't update the alternate reference frame + * + * When this flag is set, the encoder will not update the alt ref frame with + * the contents of the current frame. + */ +#define AOM_EFLAG_NO_UPD_ARF (1 << 25) +/*!\brief Disable entropy update + * + * When this flag is set, the encoder will not update its internal entropy + * model based on the entropy of this frame. + */ +#define AOM_EFLAG_NO_UPD_ENTROPY (1 << 26) +/*!\brief Disable ref frame mvs + * + * When this flag is set, the encoder will not allow frames to + * be encoded using mfmv. + */ +#define AOM_EFLAG_NO_REF_FRAME_MVS (1 << 27) +/*!\brief Enable error resilient frame + * + * When this flag is set, the encoder will code frames as error + * resilient. + */ +#define AOM_EFLAG_ERROR_RESILIENT (1 << 28) +/*!\brief Enable s frame mode + * + * When this flag is set, the encoder will code frames as an + * s frame. + */ +#define AOM_EFLAG_SET_S_FRAME (1 << 29) +/*!\brief Force primary_ref_frame to PRIMARY_REF_NONE + * + * When this flag is set, the encoder will set a frame's primary_ref_frame + * to PRIMARY_REF_NONE + */ +#define AOM_EFLAG_SET_PRIMARY_REF_NONE (1 << 30) + +/*!\brief AVx encoder control functions + * + * This set of macros define the control functions available for AVx + * encoder interface. + * + * \sa #aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...) + */ +enum aome_enc_control_id { + /*!\brief Codec control function to set which reference frame encoder can use, + * int parameter. + */ + AOME_USE_REFERENCE = 7, + + /*!\brief Codec control function to pass an ROI map to encoder, aom_roi_map_t* + * parameter. + */ + AOME_SET_ROI_MAP = 8, + + /*!\brief Codec control function to pass an Active map to encoder, + * aom_active_map_t* parameter. + */ + AOME_SET_ACTIVEMAP = 9, + + /* NOTE: enum 10 unused */ + + /*!\brief Codec control function to set encoder scaling mode, + * aom_scaling_mode_t* parameter. + */ + AOME_SET_SCALEMODE = 11, + + /*!\brief Codec control function to set encoder spatial layer id, unsigned int + * parameter. + */ + AOME_SET_SPATIAL_LAYER_ID = 12, + + /*!\brief Codec control function to set encoder internal speed settings, + * int parameter + * + * Changes in this value influences the complexity of algorithms used in + * encoding process, values greater than 0 will increase encoder speed at + * the expense of quality. + * + * Valid range: 0..8. 0 runs the slowest, and 8 runs the fastest; + * quality improves as speed decreases (since more compression + * possibilities are explored). + */ + AOME_SET_CPUUSED = 13, + + /*!\brief Codec control function to enable automatic set and use alf frames, + * unsigned int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AOME_SET_ENABLEAUTOALTREF = 14, + + /* NOTE: enum 15 unused */ + + /*!\brief Codec control function to set sharpness, unsigned int parameter. + */ + AOME_SET_SHARPNESS = AOME_SET_ENABLEAUTOALTREF + 2, // 16 + + /*!\brief Codec control function to set the threshold for MBs treated static, + * unsigned int parameter + */ + AOME_SET_STATIC_THRESHOLD = 17, + + /* NOTE: enum 18 unused */ + + /*!\brief Codec control function to get last quantizer chosen by the encoder, + * int* parameter + * + * Return value uses internal quantizer scale defined by the codec. + */ + AOME_GET_LAST_QUANTIZER = AOME_SET_STATIC_THRESHOLD + 2, // 19 + + /*!\brief Codec control function to get last quantizer chosen by the encoder, + * int* parameter + * + * Return value uses the 0..63 scale as used by the rc_*_quantizer config + * parameters. + */ + AOME_GET_LAST_QUANTIZER_64 = 20, + + /*!\brief Codec control function to set the max no of frames to create arf, + * unsigned int parameter + */ + AOME_SET_ARNR_MAXFRAMES = 21, + + /*!\brief Codec control function to set the filter strength for the arf, + * unsigned int parameter + */ + AOME_SET_ARNR_STRENGTH = 22, + + /* NOTE: enum 23 unused */ + + /*!\brief Codec control function to set visual tuning, aom_tune_metric (int) + * parameter + */ + AOME_SET_TUNING = AOME_SET_ARNR_STRENGTH + 2, // 24 + + /*!\brief Codec control function to set constrained / constant quality level, + * unsigned int parameter + * + * Valid range: 0..63 + * + * \attention For this value to be used aom_codec_enc_cfg_t::rc_end_usage + * must be set to #AOM_CQ or #AOM_Q. + */ + AOME_SET_CQ_LEVEL = 25, + + /*!\brief Codec control function to set max data rate for intra frames, + * unsigned int parameter + * + * This value controls additional clamping on the maximum size of a + * keyframe. It is expressed as a percentage of the average + * per-frame bitrate, with the special (and default) value 0 meaning + * unlimited, or no additional clamping beyond the codec's built-in + * algorithm. + * + * For example, to allocate no more than 4.5 frames worth of bitrate + * to a keyframe, set this to 450. + */ + AOME_SET_MAX_INTRA_BITRATE_PCT = 26, + + /*!\brief Codec control function to set number of spatial layers, int + * parameter + */ + AOME_SET_NUMBER_SPATIAL_LAYERS = 27, + + /*!\brief Codec control function to set max data rate for inter frames, + * unsigned int parameter + * + * This value controls additional clamping on the maximum size of an + * inter frame. It is expressed as a percentage of the average + * per-frame bitrate, with the special (and default) value 0 meaning + * unlimited, or no additional clamping beyond the codec's built-in + * algorithm. + * + * For example, to allow no more than 4.5 frames worth of bitrate + * to an inter frame, set this to 450. + */ + AV1E_SET_MAX_INTER_BITRATE_PCT = AOME_SET_MAX_INTRA_BITRATE_PCT + 2, // 28 + + /*!\brief Boost percentage for Golden Frame in CBR mode, unsigned int + * parameter + * + * This value controls the amount of boost given to Golden Frame in + * CBR mode. It is expressed as a percentage of the average + * per-frame bitrate, with the special (and default) value 0 meaning + * the feature is off, i.e., no golden frame boost in CBR mode and + * average bitrate target is used. + * + * For example, to allow 100% more bits, i.e, 2X, in a golden frame + * than average frame, set this to 100. + */ + AV1E_SET_GF_CBR_BOOST_PCT = 29, + + /* NOTE: enum 30 unused */ + + /*!\brief Codec control function to set lossless encoding mode, unsigned int + * parameter + * + * AV1 can operate in lossless encoding mode, in which the bitstream + * produced will be able to decode and reconstruct a perfect copy of + * input source. + * + * - 0 = normal coding mode, may be lossy (default) + * - 1 = lossless coding mode + */ + AV1E_SET_LOSSLESS = AV1E_SET_GF_CBR_BOOST_PCT + 2, // 31 + + /*!\brief Codec control function to enable the row based multi-threading + * of the encoder, unsigned int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ROW_MT = 32, + + /*!\brief Codec control function to set number of tile columns. unsigned int + * parameter + * + * In encoding and decoding, AV1 allows an input image frame be partitioned + * into separate vertical tile columns, which can be encoded or decoded + * independently. This enables easy implementation of parallel encoding and + * decoding. The parameter for this control describes the number of tile + * columns (in log2 units), which has a valid range of [0, 6]: + * \verbatim + 0 = 1 tile column + 1 = 2 tile columns + 2 = 4 tile columns + ..... + n = 2**n tile columns + \endverbatim + * By default, the value is 0, i.e. one single column tile for entire image. + */ + AV1E_SET_TILE_COLUMNS = 33, + + /*!\brief Codec control function to set number of tile rows, unsigned int + * parameter + * + * In encoding and decoding, AV1 allows an input image frame be partitioned + * into separate horizontal tile rows, which can be encoded or decoded + * independently. The parameter for this control describes the number of tile + * rows (in log2 units), which has a valid range of [0, 6]: + * \verbatim + 0 = 1 tile row + 1 = 2 tile rows + 2 = 4 tile rows + ..... + n = 2**n tile rows + \endverbatim + * By default, the value is 0, i.e. one single row tile for entire image. + */ + AV1E_SET_TILE_ROWS = 34, + + /*!\brief Codec control function to enable RDO modulated by frame temporal + * dependency, unsigned int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_TPL_MODEL = 35, + + /*!\brief Codec control function to enable temporal filtering on key frame, + * unsigned int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_KEYFRAME_FILTERING = 36, + + /*!\brief Codec control function to enable frame parallel decoding feature, + * unsigned int parameter + * + * AV1 has a bitstream feature to reduce decoding dependency between frames + * by turning off backward update of probability context used in encoding + * and decoding. This allows staged parallel processing of more than one + * video frames in the decoder. This control function provides a mean to + * turn this feature on or off for bitstreams produced by encoder. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_FRAME_PARALLEL_DECODING = 37, + + /*!\brief Codec control function to enable error_resilient_mode, int parameter + * + * AV1 has a bitstream feature to guarantee parseability of a frame + * by turning on the error_resilient_decoding mode, even though the + * reference buffers are unreliable or not received. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_ERROR_RESILIENT_MODE = 38, + + /*!\brief Codec control function to enable s_frame_mode, int parameter + * + * AV1 has a bitstream feature to designate certain frames as S-frames, + * from where we can switch to a different stream, + * even though the reference buffers may not be exactly identical. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_S_FRAME_MODE = 39, + + /*!\brief Codec control function to set adaptive quantization mode, unsigned + * int parameter + * + * AV1 has a segment based feature that allows encoder to adaptively change + * quantization parameter for each segment within a frame to improve the + * subjective quality. This control makes encoder operate in one of the + * several AQ_modes supported. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_AQ_MODE = 40, + + /*!\brief Codec control function to enable/disable periodic Q boost, unsigned + * int parameter + * + * One AV1 encoder speed feature is to enable quality boost by lowering + * frame level Q periodically. This control function provides a mean to + * turn on/off this feature. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_FRAME_PERIODIC_BOOST = 41, + + /*!\brief Codec control function to set noise sensitivity, unsigned int + * parameter + * + * - 0 = disable (default) + * - 1 = enable (Y only) + */ + AV1E_SET_NOISE_SENSITIVITY = 42, + + /*!\brief Codec control function to set content type, aom_tune_content + * parameter + * + * - AOM_CONTENT_DEFAULT = Regular video content (default) + * - AOM_CONTENT_SCREEN = Screen capture content + */ + AV1E_SET_TUNE_CONTENT = 43, + + /*!\brief Codec control function to set CDF update mode, unsigned int + * parameter + * + * - 0: no update + * - 1: update on every frame (default) + * - 2: selectively update + */ + AV1E_SET_CDF_UPDATE_MODE = 44, + + /*!\brief Codec control function to set color space info, int parameter + * + * - 0 = For future use + * - 1 = BT.709 + * - 2 = Unspecified (default) + * - 3 = For future use + * - 4 = BT.470 System M (historical) + * - 5 = BT.470 System B, G (historical) + * - 6 = BT.601 + * - 7 = SMPTE 240 + * - 8 = Generic film (color filters using illuminant C) + * - 9 = BT.2020, BT.2100 + * - 10 = SMPTE 428 (CIE 1921 XYZ) + * - 11 = SMPTE RP 431-2 + * - 12 = SMPTE EG 432-1 + * - 13..21 = For future use + * - 22 = EBU Tech. 3213-E + * - 23 = For future use + */ + AV1E_SET_COLOR_PRIMARIES = 45, + + /*!\brief Codec control function to set transfer function info, int parameter + * + * - 0 = For future use + * - 1 = BT.709 + * - 2 = Unspecified (default) + * - 3 = For future use + * - 4 = BT.470 System M (historical) + * - 5 = BT.470 System B, G (historical) + * - 6 = BT.601 + * - 7 = SMPTE 240 M + * - 8 = Linear + * - 9 = Logarithmic (100 : 1 range) + * - 10 = Logarithmic (100 * Sqrt(10) : 1 range) + * - 11 = IEC 61966-2-4 + * - 12 = BT.1361 + * - 13 = sRGB or sYCC + * - 14 = BT.2020 10-bit systems + * - 15 = BT.2020 12-bit systems + * - 16 = SMPTE ST 2084, ITU BT.2100 PQ + * - 17 = SMPTE ST 428 + * - 18 = BT.2100 HLG, ARIB STD-B67 + * - 19 = For future use + */ + AV1E_SET_TRANSFER_CHARACTERISTICS = 46, + + /*!\brief Codec control function to set transfer function info, int parameter + * + * - 0 = Identity matrix + * - 1 = BT.709 + * - 2 = Unspecified (default) + * - 3 = For future use + * - 4 = US FCC 73.628 + * - 5 = BT.470 System B, G (historical) + * - 6 = BT.601 + * - 7 = SMPTE 240 M + * - 8 = YCgCo + * - 9 = BT.2020 non-constant luminance, BT.2100 YCbCr + * - 10 = BT.2020 constant luminance + * - 11 = SMPTE ST 2085 YDzDx + * - 12 = Chromaticity-derived non-constant luminance + * - 13 = Chromaticity-derived constant luminance + * - 14 = BT.2100 ICtCp + * - 15 = For future use + */ + AV1E_SET_MATRIX_COEFFICIENTS = 47, + + /*!\brief Codec control function to set chroma 4:2:0 sample position info, + * aom_chroma_sample_position_t parameter + * + * AOM_CSP_UNKNOWN is default + */ + AV1E_SET_CHROMA_SAMPLE_POSITION = 48, + + /*!\brief Codec control function to set minimum interval between GF/ARF + * frames, unsigned int parameter + * + * By default the value is set as 4. + */ + AV1E_SET_MIN_GF_INTERVAL = 49, + + /*!\brief Codec control function to set minimum interval between GF/ARF + * frames, unsigned int parameter + * + * By default the value is set as 16. + */ + AV1E_SET_MAX_GF_INTERVAL = 50, + + /*!\brief Codec control function to get an active map back from the encoder, + aom_active_map_t* parameter + */ + AV1E_GET_ACTIVEMAP = 51, + + /*!\brief Codec control function to set color range bit, int parameter + * + * - 0 = Limited range, 16..235 or HBD equivalent (default) + * - 1 = Full range, 0..255 or HBD equivalent + */ + AV1E_SET_COLOR_RANGE = 52, + + /*!\brief Codec control function to set intended rendering image size, + * int32_t[2] parameter + * + * By default, this is identical to the image size in pixels. + */ + AV1E_SET_RENDER_SIZE = 53, + + /*!\brief Control to set target sequence level index for a certain operating + * point(OP), int parameter + * Possible values are in the form of "ABxy"(pad leading zeros if less than + * 4 digits). + * - AB: OP index. + * - xy: Target level index for the OP. Can be values 0~23(corresponding to + * level 2.0 ~ 7.3) or 24(keep level stats only for level monitoring) or + * 31(maximum level parameter, no level-based constraints). + * + * E.g.: + * - "0" means target level index 0 for the 0th OP; + * - "111" means target level index 11 for the 1st OP; + * - "1021" means target level index 21 for the 10th OP. + * + * If the target level is not specified for an OP, the maximum level parameter + * of 31 is used as default. + */ + AV1E_SET_TARGET_SEQ_LEVEL_IDX = 54, + + /*!\brief Codec control function to get sequence level index for each + * operating point. int* parameter. There can be at most 32 operating points. + * The results will be written into a provided integer array of sufficient + * size. + */ + AV1E_GET_SEQ_LEVEL_IDX = 55, + + /*!\brief Codec control function to set intended superblock size, unsigned int + * parameter + * + * By default, the superblock size is determined separately for each + * frame by the encoder. + */ + AV1E_SET_SUPERBLOCK_SIZE = 56, + + /*!\brief Codec control function to enable automatic set and use of + * bwd-pred frames, unsigned int parameter + * + * - 0 = disable (default) + * - 1 = enable + */ + AOME_SET_ENABLEAUTOBWDREF = 57, + + /*!\brief Codec control function to encode with CDEF, unsigned int parameter + * + * CDEF is the constrained directional enhancement filter which is an + * in-loop filter aiming to remove coding artifacts + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_CDEF = 58, + + /*!\brief Codec control function to encode with Loop Restoration Filter, + * unsigned int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_RESTORATION = 59, + + /*!\brief Codec control function to force video mode, unsigned int parameter + * + * - 0 = do not force video mode (default) + * - 1 = force video mode even for a single frame + */ + AV1E_SET_FORCE_VIDEO_MODE = 60, + + /*!\brief Codec control function to predict with OBMC mode, unsigned int + * parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_OBMC = 61, + + /*!\brief Codec control function to encode without trellis quantization, + * unsigned int parameter + * + * - 0 = apply trellis quantization (default) + * - 1 = do not apply trellis quantization + * - 2 = disable trellis quantization in rd search + * - 3 = disable trellis quantization in estimate yrd + */ + AV1E_SET_DISABLE_TRELLIS_QUANT = 62, + + /*!\brief Codec control function to encode with quantisation matrices, + * unsigned int parameter + * + * AOM can operate with default quantisation matrices dependent on + * quantisation level and block type. + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_ENABLE_QM = 63, + + /*!\brief Codec control function to set the min quant matrix flatness, + * unsigned int parameter + * + * AOM can operate with different ranges of quantisation matrices. + * As quantisation levels increase, the matrices get flatter. This + * control sets the minimum level of flatness from which the matrices + * are determined. + * + * By default, the encoder sets this minimum at half the available + * range. + */ + AV1E_SET_QM_MIN = 64, + + /*!\brief Codec control function to set the max quant matrix flatness, + * unsigned int parameter + * + * AOM can operate with different ranges of quantisation matrices. + * As quantisation levels increase, the matrices get flatter. This + * control sets the maximum level of flatness possible. + * + * By default, the encoder sets this maximum at the top of the + * available range. + */ + AV1E_SET_QM_MAX = 65, + + /*!\brief Codec control function to set the min quant matrix flatness, + * unsigned int parameter + * + * AOM can operate with different ranges of quantisation matrices. + * As quantisation levels increase, the matrices get flatter. This + * control sets the flatness for luma (Y). + * + * By default, the encoder sets this minimum at half the available + * range. + */ + AV1E_SET_QM_Y = 66, + + /*!\brief Codec control function to set the min quant matrix flatness, + * unsigned int parameter + * + * AOM can operate with different ranges of quantisation matrices. + * As quantisation levels increase, the matrices get flatter. This + * control sets the flatness for chroma (U). + * + * By default, the encoder sets this minimum at half the available + * range. + */ + AV1E_SET_QM_U = 67, + + /*!\brief Codec control function to set the min quant matrix flatness, + * unsigned int parameter + * + * AOM can operate with different ranges of quantisation matrices. + * As quantisation levels increase, the matrices get flatter. This + * control sets the flatness for chrome (V). + * + * By default, the encoder sets this minimum at half the available + * range. + */ + AV1E_SET_QM_V = 68, + + /* NOTE: enum 69 unused */ + + /*!\brief Codec control function to set a maximum number of tile groups, + * unsigned int parameter + * + * This will set the maximum number of tile groups. This will be + * overridden if an MTU size is set. The default value is 1. + */ + AV1E_SET_NUM_TG = 70, + + /*!\brief Codec control function to set an MTU size for a tile group, unsigned + * int parameter + * + * This will set the maximum number of bytes in a tile group. This can be + * exceeded only if a single tile is larger than this amount. + * + * By default, the value is 0, in which case a fixed number of tile groups + * is used. + */ + AV1E_SET_MTU = 71, + + /* NOTE: enum 72 unused */ + + /*!\brief Codec control function to enable/disable rectangular partitions, int + * parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_RECT_PARTITIONS = 73, + + /*!\brief Codec control function to enable/disable AB partitions, int + * parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_AB_PARTITIONS = 74, + + /*!\brief Codec control function to enable/disable 1:4 and 4:1 partitions, int + * parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_1TO4_PARTITIONS = 75, + + /*!\brief Codec control function to set min partition size, int parameter + * + * min_partition_size is applied to both width and height of the partition. + * i.e, both width and height of a partition can not be smaller than + * the min_partition_size, except the partition at the picture boundary. + * + * Valid values: [4, 8, 16, 32, 64, 128]. The default value is 4 for + * 4x4. + */ + AV1E_SET_MIN_PARTITION_SIZE = 76, + + /*!\brief Codec control function to set max partition size, int parameter + * + * max_partition_size is applied to both width and height of the partition. + * i.e, both width and height of a partition can not be larger than + * the max_partition_size. + * + * Valid values:[4, 8, 16, 32, 64, 128] The default value is 128 for + * 128x128. + */ + AV1E_SET_MAX_PARTITION_SIZE = 77, + + /*!\brief Codec control function to turn on / off intra edge filter + * at sequence level, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_INTRA_EDGE_FILTER = 78, + + /*!\brief Codec control function to turn on / off frame order hint (int + * parameter). Affects: joint compound mode, motion field motion vector, + * ref frame sign bias + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_ORDER_HINT = 79, + + /*!\brief Codec control function to turn on / off 64-length transforms, int + * parameter + * + * This will enable or disable usage of length 64 transforms in any + * direction. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_TX64 = 80, + + /*!\brief Codec control function to turn on / off flip and identity + * transforms, int parameter + * + * This will enable or disable usage of flip and identity transform + * types in any direction. If enabled, this includes: + * - FLIPADST_DCT + * - DCT_FLIPADST + * - FLIPADST_FLIPADST + * - ADST_FLIPADST + * - FLIPADST_ADST + * - IDTX + * - V_DCT + * - H_DCT + * - V_ADST + * - H_ADST + * - V_FLIPADST + * - H_FLIPADST + * + * Valid values: + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_FLIP_IDTX = 81, + + /* Note: enum value 82 unused */ + + /*!\brief Codec control function to turn on / off dist-wtd compound mode + * at sequence level, int parameter + * + * This will enable or disable distance-weighted compound mode. + * \attention If AV1E_SET_ENABLE_ORDER_HINT is 0, then this flag is forced + * to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_DIST_WTD_COMP = 83, + + /*!\brief Codec control function to turn on / off ref frame mvs (mfmv) usage + * at sequence level, int parameter + * + * \attention If AV1E_SET_ENABLE_ORDER_HINT is 0, then this flag is forced + * to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_REF_FRAME_MVS = 84, + + /*!\brief Codec control function to set temporal mv prediction + * enabling/disabling at frame level, int parameter + * + * \attention If AV1E_SET_ENABLE_REF_FRAME_MVS is 0, then this flag is + * forced to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ALLOW_REF_FRAME_MVS = 85, + + /*!\brief Codec control function to turn on / off dual interpolation filter + * for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable + */ + AV1E_SET_ENABLE_DUAL_FILTER = 86, + + /*!\brief Codec control function to turn on / off delta quantization in chroma + * planes usage for a sequence, int parameter + * + * - 0 = disable (default) + * - 1 = enable + */ + AV1E_SET_ENABLE_CHROMA_DELTAQ = 87, + + /*!\brief Codec control function to turn on / off masked compound usage + * (wedge and diff-wtd compound modes) for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_MASKED_COMP = 88, + + /*!\brief Codec control function to turn on / off one sided compound usage + * for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_ONESIDED_COMP = 89, + + /*!\brief Codec control function to turn on / off interintra compound + * for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_INTERINTRA_COMP = 90, + + /*!\brief Codec control function to turn on / off smooth inter-intra + * mode for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_SMOOTH_INTERINTRA = 91, + + /*!\brief Codec control function to turn on / off difference weighted + * compound, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_DIFF_WTD_COMP = 92, + + /*!\brief Codec control function to turn on / off interinter wedge + * compound, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_INTERINTER_WEDGE = 93, + + /*!\brief Codec control function to turn on / off interintra wedge + * compound, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_INTERINTRA_WEDGE = 94, + + /*!\brief Codec control function to turn on / off global motion usage + * for a sequence, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_GLOBAL_MOTION = 95, + + /*!\brief Codec control function to turn on / off warped motion usage + * at sequence level, int parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_WARPED_MOTION = 96, + + /*!\brief Codec control function to turn on / off warped motion usage + * at frame level, int parameter + * + * \attention If AV1E_SET_ENABLE_WARPED_MOTION is 0, then this flag is + * forced to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ALLOW_WARPED_MOTION = 97, + + /*!\brief Codec control function to turn on / off filter intra usage at + * sequence level, int parameter + * + * \attention If AV1E_SET_ENABLE_FILTER_INTRA is 0, then this flag is + * forced to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_FILTER_INTRA = 98, + + /*!\brief Codec control function to turn on / off smooth intra modes usage, + * int parameter + * + * This will enable or disable usage of smooth, smooth_h and smooth_v intra + * modes. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_SMOOTH_INTRA = 99, + + /*!\brief Codec control function to turn on / off Paeth intra mode usage, int + * parameter + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_PAETH_INTRA = 100, + + /*!\brief Codec control function to turn on / off CFL uv intra mode usage, int + * parameter + * + * This will enable or disable usage of chroma-from-luma intra mode. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_CFL_INTRA = 101, + + /*!\brief Codec control function to turn on / off frame superresolution, int + * parameter + * + * \attention If AV1E_SET_ENABLE_SUPERRES is 0, then this flag is forced to 0. + * + * - 0 = disable + * - 1 = enable (default) + */ + AV1E_SET_ENABLE_SUPERRES = 102, + + /*!\brief Codec control function to turn on / off overlay frames for + * filtered ALTREF frames, int parameter + * + * This will enable or disable coding of overlay frames for filtered ALTREF + * frames. When set to 0, overlay frames are not used but show existing frame + * is used to display the filtered ALTREF frame as is. As a result the decoded + * frame rate remains the same as the display frame rate. The default is 1. + */ + AV1E_SET_ENABLE_OVERLAY = 103, + + /*!\brief Codec control function to turn on/off palette mode, int parameter */ + AV1E_SET_ENABLE_PALETTE = 104, + + /*!\brief Codec control function to turn on/off intra block copy mode, int + parameter */ + AV1E_SET_ENABLE_INTRABC = 105, + + /*!\brief Codec control function to turn on/off intra angle delta, int + parameter */ + AV1E_SET_ENABLE_ANGLE_DELTA = 106, + + /*!\brief Codec control function to set the delta q mode, unsigned int + * parameter + * + * AV1 supports a delta q mode feature, that allows modulating q per + * superblock. + * + * - 0 = deltaq signaling off + * - 1 = use modulation to maximize objective quality (default) + * - 2 = use modulation to maximize perceptual quality + */ + AV1E_SET_DELTAQ_MODE = 107, + + /*!\brief Codec control function to turn on/off loopfilter modulation + * when delta q modulation is enabled, unsigned int parameter. + * + * \attention AV1 only supports loopfilter modulation when delta q + * modulation is enabled as well. + */ + AV1E_SET_DELTALF_MODE = 108, + + /*!\brief Codec control function to set the single tile decoding mode, + * unsigned int parameter + * + * \attention Only applicable if large scale tiling is on. + * + * - 0 = single tile decoding is off + * - 1 = single tile decoding is on (default) + */ + AV1E_SET_SINGLE_TILE_DECODING = 109, + + /*!\brief Codec control function to enable the extreme motion vector unit + * test, unsigned int parameter + * + * - 0 = off + * - 1 = MAX_EXTREME_MV + * - 2 = MIN_EXTREME_MV + * + * \note This is only used in motion vector unit test. + */ + AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST = 110, + + /*!\brief Codec control function to signal picture timing info in the + * bitstream, aom_timing_info_type_t parameter. Default is + * AOM_TIMING_UNSPECIFIED. + */ + AV1E_SET_TIMING_INFO_TYPE = 111, + + /*!\brief Codec control function to add film grain parameters (one of several + * preset types) info in the bitstream, int parameter + * + Valid range: 0..16, 0 is unknown, 1..16 are test vectors + */ + AV1E_SET_FILM_GRAIN_TEST_VECTOR = 112, + + /*!\brief Codec control function to set the path to the film grain parameters, + * const char* parameter + */ + AV1E_SET_FILM_GRAIN_TABLE = 113, + + /*!\brief Sets the noise level, int parameter */ + AV1E_SET_DENOISE_NOISE_LEVEL = 114, + + /*!\brief Sets the denoisers block size, unsigned int parameter */ + AV1E_SET_DENOISE_BLOCK_SIZE = 115, + + /*!\brief Sets the chroma subsampling x value, unsigned int parameter */ + AV1E_SET_CHROMA_SUBSAMPLING_X = 116, + + /*!\brief Sets the chroma subsampling y value, unsigned int parameter */ + AV1E_SET_CHROMA_SUBSAMPLING_Y = 117, + + /*!\brief Control to use a reduced tx type set, int parameter */ + AV1E_SET_REDUCED_TX_TYPE_SET = 118, + + /*!\brief Control to use dct only for intra modes, int parameter */ + AV1E_SET_INTRA_DCT_ONLY = 119, + + /*!\brief Control to use dct only for inter modes, int parameter */ + AV1E_SET_INTER_DCT_ONLY = 120, + + /*!\brief Control to use default tx type only for intra modes, int parameter + */ + AV1E_SET_INTRA_DEFAULT_TX_ONLY = 121, + + /*!\brief Control to use adaptive quantize_b, int parameter */ + AV1E_SET_QUANT_B_ADAPT = 122, + + /*!\brief Control to select maximum height for the GF group pyramid structure, + * unsigned int parameter + * + * Valid range: 0..4 + */ + AV1E_SET_GF_MAX_PYRAMID_HEIGHT = 123, + + /*!\brief Control to select maximum reference frames allowed per frame, int + * parameter + * + * Valid range: 3..7 + */ + AV1E_SET_MAX_REFERENCE_FRAMES = 124, + + /*!\brief Control to use reduced set of single and compound references, int + parameter */ + AV1E_SET_REDUCED_REFERENCE_SET = 125, + + /* NOTE: enums 126-139 unused */ + /* NOTE: Need a gap in enum values to avoud conflict with 128, 129, 130 */ + + /*!\brief Control to set frequency of the cost updates for coefficients, + * unsigned int parameter + * + * - 0 = update at SB level (default) + * - 1 = update at SB row level in tile + * - 2 = update at tile level + * - 3 = turn off + */ + AV1E_SET_COEFF_COST_UPD_FREQ = 140, + + /*!\brief Control to set frequency of the cost updates for mode, unsigned int + * parameter + * + * - 0 = update at SB level (default) + * - 1 = update at SB row level in tile + * - 2 = update at tile level + * - 3 = turn off + */ + AV1E_SET_MODE_COST_UPD_FREQ = 141, + + /*!\brief Control to set frequency of the cost updates for motion vectors, + * unsigned int parameter + * + * - 0 = update at SB level (default) + * - 1 = update at SB row level in tile + * - 2 = update at tile level + * - 3 = turn off + */ + AV1E_SET_MV_COST_UPD_FREQ = 142, + + /*!\brief Control to set bit mask that specifies which tier each of the 32 + * possible operating points conforms to, unsigned int parameter + * + * - 0 = main tier (default) + * - 1 = high tier + */ + AV1E_SET_TIER_MASK = 143, + + /*!\brief Control to set minimum compression ratio, unsigned int parameter + * Take integer values. If non-zero, encoder will try to keep the compression + * ratio of each frame to be higher than the given value divided by 100. + * E.g. 850 means minimum compression ratio of 8.5. + */ + AV1E_SET_MIN_CR = 144, + + /* NOTE: enums 145-149 unused */ + + /*!\brief Codec control function to set the layer id, aom_svc_layer_id_t* + * parameter + */ + AV1E_SET_SVC_LAYER_ID = 150, + + /*!\brief Codec control function to set SVC paramaeters, aom_svc_params_t* + * parameter + */ + AV1E_SET_SVC_PARAMS = 151, + + /*!\brief Codec control function to set reference frame config: + * the ref_idx and the refresh flags for each buffer slot. + * aom_svc_ref_frame_config_t* parameter + */ + AV1E_SET_SVC_REF_FRAME_CONFIG = 152, + + /*!\brief Codec control function to set the path to the VMAF model used when + * tuning the encoder for VMAF, const char* parameter + */ + AV1E_SET_VMAF_MODEL_PATH = 153, + + /*!\brief Codec control function to enable EXT_TILE_DEBUG in AV1 encoder, + * unsigned int parameter + * + * - 0 = disable (default) + * - 1 = enable + * + * \note This is only used in lightfield example test. + */ + AV1E_ENABLE_EXT_TILE_DEBUG = 154, + + /*!\brief Codec control function to enable the superblock multipass unit test + * in AV1 to ensure that the encoder does not leak state between different + * passes. unsigned int parameter. + * + * - 0 = disable (default) + * - 1 = enable + * + * \note This is only used in sb_multipass unit test. + */ + AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST = 155, + + /*!\brief Control to select minimum height for the GF group pyramid structure, + * unsigned int parameter + * + * Valid values: 0..4 + */ + AV1E_SET_GF_MIN_PYRAMID_HEIGHT = 156, + + /*!\brief Control to set average complexity of the corpus in the case of + * single pass vbr based on LAP, unsigned int parameter + */ + AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP = 157, +}; + +/*!\brief aom 1-D scaling mode + * + * This set of constants define 1-D aom scaling modes + */ +typedef enum aom_scaling_mode_1d { + AOME_NORMAL = 0, + AOME_FOURFIVE = 1, + AOME_THREEFIVE = 2, + AOME_THREEFOUR = 3, + AOME_ONEFOUR = 4, + AOME_ONEEIGHT = 5, + AOME_ONETWO = 6 +} AOM_SCALING_MODE; + +/*!\brief Max number of segments + * + * This is the limit of number of segments allowed within a frame. + * + * Currently same as "MAX_SEGMENTS" in AV1, the maximum that AV1 supports. + * + */ +#define AOM_MAX_SEGMENTS 8 + +/*!\brief aom region of interest map + * + * These defines the data structures for the region of interest map + * + * TODO(yaowu): create a unit test for ROI map related APIs + * + */ +typedef struct aom_roi_map { + /*! An id between 0 and 7 for each 8x8 region within a frame. */ + unsigned char *roi_map; + unsigned int rows; /**< Number of rows. */ + unsigned int cols; /**< Number of columns. */ + int delta_q[AOM_MAX_SEGMENTS]; /**< Quantizer deltas. */ + int delta_lf[AOM_MAX_SEGMENTS]; /**< Loop filter deltas. */ + /*! Static breakout threshold for each segment. */ + unsigned int static_threshold[AOM_MAX_SEGMENTS]; +} aom_roi_map_t; + +/*!\brief aom active region map + * + * These defines the data structures for active region map + * + */ + +typedef struct aom_active_map { + /*!\brief specify an on (1) or off (0) each 16x16 region within a frame */ + unsigned char *active_map; + unsigned int rows; /**< number of rows */ + unsigned int cols; /**< number of cols */ +} aom_active_map_t; + +/*!\brief aom image scaling mode + * + * This defines the data structure for image scaling mode + * + */ +typedef struct aom_scaling_mode { + AOM_SCALING_MODE h_scaling_mode; /**< horizontal scaling mode */ + AOM_SCALING_MODE v_scaling_mode; /**< vertical scaling mode */ +} aom_scaling_mode_t; + +/*!brief AV1 encoder content type */ +typedef enum { + AOM_CONTENT_DEFAULT, + AOM_CONTENT_SCREEN, + AOM_CONTENT_INVALID +} aom_tune_content; + +/*!brief AV1 encoder timing info type signaling */ +typedef enum { + AOM_TIMING_UNSPECIFIED, + AOM_TIMING_EQUAL, + AOM_TIMING_DEC_MODEL +} aom_timing_info_type_t; + +/*!\brief Model tuning parameters + * + * Changes the encoder to tune for certain types of input material. + * + */ +typedef enum { + AOM_TUNE_PSNR = 0, + AOM_TUNE_SSIM = 1, + /* NOTE: enums 2 and 3 unused */ + AOM_TUNE_VMAF_WITH_PREPROCESSING = 4, + AOM_TUNE_VMAF_WITHOUT_PREPROCESSING = 5, + AOM_TUNE_VMAF_MAX_GAIN = 6 +} aom_tune_metric; + +#define AOM_MAX_LAYERS 32 /**< Max number of layers */ +#define AOM_MAX_SS_LAYERS 4 /**< Max number of spatial layers */ +#define AOM_MAX_TS_LAYERS 8 /**< Max number of temporal layers */ + +/*!brief Struct for spatial and temporal layer ID */ +typedef struct aom_svc_layer_id { + int spatial_layer_id; /**< Spatial layer ID */ + int temporal_layer_id; /**< Temporal layer ID */ +} aom_svc_layer_id_t; + +/*!brief Parameter type for SVC */ +typedef struct aom_svc_params { + int number_spatial_layers; /**< Number of spatial layers */ + int number_temporal_layers; /**< Number of temporal layers */ + int max_quantizers[AOM_MAX_LAYERS]; /**< Max Q for each layer */ + int min_quantizers[AOM_MAX_LAYERS]; /**< Min Q for each layer */ + int scaling_factor_num[AOM_MAX_SS_LAYERS]; /**< Scaling factor-numerator */ + int scaling_factor_den[AOM_MAX_SS_LAYERS]; /**< Scaling factor-denominator */ + /*! Target bitrate for each layer */ + int layer_target_bitrate[AOM_MAX_LAYERS]; + /*! Frame rate factor for each temporal layer */ + int framerate_factor[AOM_MAX_TS_LAYERS]; +} aom_svc_params_t; + +/*!brief Parameters for setting ref frame config */ +typedef struct aom_svc_ref_frame_config { + // 7 references: LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), + // GOLDEN_FRAME(3), BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6). + int reference[7]; /**< Reference flag for each of the 7 references. */ + /*! Buffer slot index for each of 7 references. */ + int ref_idx[7]; + int refresh[8]; /**< Refresh flag for each of the 8 slots. */ +} aom_svc_ref_frame_config_t; + +/*!\cond */ +/*!\brief Encoder control function parameter type + * + * Defines the data types that AOME/AV1E control functions take. + * + * \note Additional common controls are defined in aom.h. + * + * \note For each control ID "X", a macro-define of + * AOM_CTRL_X is provided. It is used at compile time to determine + * if the control ID is supported by the libaom library available, + * when the libaom version cannot be controlled. + */ +AOM_CTRL_USE_TYPE(AOME_USE_REFERENCE, int) +#define AOM_CTRL_AOME_USE_REFERENCE + +AOM_CTRL_USE_TYPE(AOME_SET_ROI_MAP, aom_roi_map_t *) +#define AOM_CTRL_AOME_SET_ROI_MAP + +AOM_CTRL_USE_TYPE(AOME_SET_ACTIVEMAP, aom_active_map_t *) +#define AOM_CTRL_AOME_SET_ACTIVEMAP + +AOM_CTRL_USE_TYPE(AOME_SET_SCALEMODE, aom_scaling_mode_t *) +#define AOM_CTRL_AOME_SET_SCALEMODE + +AOM_CTRL_USE_TYPE(AOME_SET_SPATIAL_LAYER_ID, unsigned int) +#define AOM_CTRL_AOME_SET_SPATIAL_LAYER_ID + +AOM_CTRL_USE_TYPE(AOME_SET_CPUUSED, int) +#define AOM_CTRL_AOME_SET_CPUUSED + +AOM_CTRL_USE_TYPE(AOME_SET_ENABLEAUTOALTREF, unsigned int) +#define AOM_CTRL_AOME_SET_ENABLEAUTOALTREF + +AOM_CTRL_USE_TYPE(AOME_SET_ENABLEAUTOBWDREF, unsigned int) +#define AOM_CTRL_AOME_SET_ENABLEAUTOBWDREF + +AOM_CTRL_USE_TYPE(AOME_SET_SHARPNESS, unsigned int) +#define AOM_CTRL_AOME_SET_SHARPNESS + +AOM_CTRL_USE_TYPE(AOME_SET_STATIC_THRESHOLD, unsigned int) +#define AOM_CTRL_AOME_SET_STATIC_THRESHOLD + +AOM_CTRL_USE_TYPE(AOME_SET_ARNR_MAXFRAMES, unsigned int) +#define AOM_CTRL_AOME_SET_ARNR_MAXFRAMES + +AOM_CTRL_USE_TYPE(AOME_SET_ARNR_STRENGTH, unsigned int) +#define AOM_CTRL_AOME_SET_ARNR_STRENGTH + +AOM_CTRL_USE_TYPE(AOME_SET_TUNING, int) /* aom_tune_metric */ +#define AOM_CTRL_AOME_SET_TUNING + +AOM_CTRL_USE_TYPE(AOME_SET_CQ_LEVEL, unsigned int) +#define AOM_CTRL_AOME_SET_CQ_LEVEL + +AOM_CTRL_USE_TYPE(AV1E_SET_ROW_MT, unsigned int) +#define AOM_CTRL_AV1E_SET_ROW_MT + +AOM_CTRL_USE_TYPE(AV1E_SET_TILE_COLUMNS, unsigned int) +#define AOM_CTRL_AV1E_SET_TILE_COLUMNS + +AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, unsigned int) +#define AOM_CTRL_AV1E_SET_TILE_ROWS + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_TPL_MODEL, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_TPL_MODEL + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_KEYFRAME_FILTERING, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_KEYFRAME_FILTERING + +AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER, int *) +#define AOM_CTRL_AOME_GET_LAST_QUANTIZER + +AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER_64, int *) +#define AOM_CTRL_AOME_GET_LAST_QUANTIZER_64 + +AOM_CTRL_USE_TYPE(AOME_SET_MAX_INTRA_BITRATE_PCT, unsigned int) +#define AOM_CTRL_AOME_SET_MAX_INTRA_BITRATE_PCT + +AOM_CTRL_USE_TYPE(AOME_SET_MAX_INTER_BITRATE_PCT, unsigned int) +#define AOM_CTRL_AOME_SET_MAX_INTER_BITRATE_PCT + +AOM_CTRL_USE_TYPE(AOME_SET_NUMBER_SPATIAL_LAYERS, int) +#define AOME_CTRL_AOME_SET_NUMBER_SPATIAL_LAYERS + +AOM_CTRL_USE_TYPE(AV1E_SET_GF_CBR_BOOST_PCT, unsigned int) +#define AOM_CTRL_AV1E_SET_GF_CBR_BOOST_PCT + +AOM_CTRL_USE_TYPE(AV1E_SET_LOSSLESS, unsigned int) +#define AOM_CTRL_AV1E_SET_LOSSLESS + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_CDEF, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_CDEF + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_RESTORATION, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_RESTORATION + +AOM_CTRL_USE_TYPE(AV1E_SET_FORCE_VIDEO_MODE, unsigned int) +#define AOM_CTRL_AV1E_SET_FORCE_VIDEO_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_OBMC, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_OBMC + +AOM_CTRL_USE_TYPE(AV1E_SET_DISABLE_TRELLIS_QUANT, unsigned int) +#define AOM_CTRL_AV1E_SET_DISABLE_TRELLIS_QUANT + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_QM, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_QM + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIST_8X8, unsigned int) +#define AOM_CTRL_AV1E_SET_ENABLE_DIST_8X8 + +AOM_CTRL_USE_TYPE(AV1E_SET_QM_MIN, unsigned int) +#define AOM_CTRL_AV1E_SET_QM_MIN + +AOM_CTRL_USE_TYPE(AV1E_SET_QM_MAX, unsigned int) +#define AOM_CTRL_AV1E_SET_QM_MAX + +AOM_CTRL_USE_TYPE(AV1E_SET_QM_Y, unsigned int) +#define AOM_CTRL_AV1E_SET_QM_Y + +AOM_CTRL_USE_TYPE(AV1E_SET_QM_U, unsigned int) +#define AOM_CTRL_AV1E_SET_QM_U + +AOM_CTRL_USE_TYPE(AV1E_SET_QM_V, unsigned int) +#define AOM_CTRL_AV1E_SET_QM_V + +AOM_CTRL_USE_TYPE(AV1E_SET_NUM_TG, unsigned int) +#define AOM_CTRL_AV1E_SET_NUM_TG + +AOM_CTRL_USE_TYPE(AV1E_SET_MTU, unsigned int) +#define AOM_CTRL_AV1E_SET_MTU + +AOM_CTRL_USE_TYPE(AV1E_SET_TIMING_INFO_TYPE, int) /* aom_timing_info_type_t */ +#define AOM_CTRL_AV1E_SET_TIMING_INFO_TYPE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_RECT_PARTITIONS, int) +#define AOM_CTRL_AV1E_SET_ENABLE_RECT_PARTITIONS + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_AB_PARTITIONS, int) +#define AOM_CTRL_AV1E_SET_ENABLE_AB_PARTITIONS + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_1TO4_PARTITIONS, int) +#define AOM_CTRL_AV1E_SET_ENABLE_1TO4_PARTITIONS + +AOM_CTRL_USE_TYPE(AV1E_SET_MIN_PARTITION_SIZE, int) +#define AOM_CTRL_AV1E_SET_MIN_PARTITION_SIZE + +AOM_CTRL_USE_TYPE(AV1E_SET_MAX_PARTITION_SIZE, int) +#define AOM_CTRL_AV1E_SET_MAX_PARTITION_SIZE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, int) +#define AOM_CTRL_AV1E_SET_ENABLE_INTRA_EDGE_FILTER + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ORDER_HINT, int) +#define AOM_CTRL_AV1E_SET_ENABLE_ORDER_HINT + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_TX64, int) +#define AOM_CTRL_AV1E_SET_ENABLE_TX64 + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_FLIP_IDTX, int) +#define AOM_CTRL_AV1E_SET_ENABLE_FLIP_IDTX + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIST_WTD_COMP, int) +#define AOM_CTRL_AV1E_SET_ENABLE_DIST_WTD_COMP + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_REF_FRAME_MVS, int) +#define AOM_CTRL_AV1E_SET_ENABLE_REF_FRAME_MVS + +AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_REF_FRAME_MVS, int) +#define AOM_CTRL_AV1E_SET_ALLOW_REF_FRAME_MVS + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DUAL_FILTER, int) +#define AOM_CTRL_AV1E_SET_ENABLE_DUAL_FILTER + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_CHROMA_DELTAQ, int) +#define AOM_CTRL_AV1E_SET_ENABLE_CHROMA_DELTAQ + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_MASKED_COMP, int) +#define AOM_CTRL_AV1E_SET_ENABLE_MASKED_COMP + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ONESIDED_COMP, int) +#define AOM_CTRL_AV1E_SET_ENABLE_ONESIDED_COMP + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_COMP, int) +#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTRA_COMP + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_SMOOTH_INTERINTRA + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIFF_WTD_COMP, int) +#define AOM_CTRL_AV1E_SET_ENABLE_DIFF_WTD_COMP + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTER_WEDGE, int) +#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTER_WEDGE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_WEDGE, int) +#define AOM_CTRL_AV1E_SET_ENABLE_INTERINTRA_WEDGE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_GLOBAL_MOTION, int) +#define AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_WARPED_MOTION, int) +#define AOM_CTRL_AV1E_SET_ENABLE_WARPED_MOTION + +AOM_CTRL_USE_TYPE(AV1E_SET_ALLOW_WARPED_MOTION, int) +#define AOM_CTRL_AV1E_SET_ALLOW_WARPED_MOTION + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_FILTER_INTRA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_FILTER_INTRA + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTRA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_SMOOTH_INTRA + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PAETH_INTRA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_PAETH_INTRA + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_CFL_INTRA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_CFL_INTRA + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SUPERRES, int) +#define AOM_CTRL_AV1E_SET_ENABLE_SUPERRES + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_OVERLAY, int) +#define AOM_CTRL_AV1E_SET_ENABLE_OVERLAY + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_PALETTE, int) +#define AOM_CTRL_AV1E_SET_ENABLE_PALETTE + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTRABC, int) +#define AOM_CTRL_AV1E_SET_ENABLE_INTRABC + +AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_ANGLE_DELTA, int) +#define AOM_CTRL_AV1E_SET_ENABLE_ANGLE_DELTA + +AOM_CTRL_USE_TYPE(AV1E_SET_FRAME_PARALLEL_DECODING, unsigned int) +#define AOM_CTRL_AV1E_SET_FRAME_PARALLEL_DECODING + +AOM_CTRL_USE_TYPE(AV1E_SET_ERROR_RESILIENT_MODE, int) +#define AOM_CTRL_AV1E_SET_ERROR_RESILIENT_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_S_FRAME_MODE, int) +#define AOM_CTRL_AV1E_SET_S_FRAME_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_AQ_MODE, unsigned int) +#define AOM_CTRL_AV1E_SET_AQ_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_DELTAQ_MODE, unsigned int) +#define AOM_CTRL_AV1E_SET_DELTAQ_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_DELTALF_MODE, unsigned int) +#define AOM_CTRL_AV1E_SET_DELTALF_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_FRAME_PERIODIC_BOOST, unsigned int) +#define AOM_CTRL_AV1E_SET_FRAME_PERIODIC_BOOST + +AOM_CTRL_USE_TYPE(AV1E_SET_NOISE_SENSITIVITY, unsigned int) +#define AOM_CTRL_AV1E_SET_NOISE_SENSITIVITY + +AOM_CTRL_USE_TYPE(AV1E_SET_TUNE_CONTENT, int) /* aom_tune_content */ +#define AOM_CTRL_AV1E_SET_TUNE_CONTENT + +AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_PRIMARIES, int) +#define AOM_CTRL_AV1E_SET_COLOR_PRIMARIES + +AOM_CTRL_USE_TYPE(AV1E_SET_TRANSFER_CHARACTERISTICS, int) +#define AOM_CTRL_AV1E_SET_TRANSFER_CHARACTERISTICS + +AOM_CTRL_USE_TYPE(AV1E_SET_MATRIX_COEFFICIENTS, int) +#define AOM_CTRL_AV1E_SET_MATRIX_COEFFICIENTS + +AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SAMPLE_POSITION, int) +#define AOM_CTRL_AV1E_SET_CHROMA_SAMPLE_POSITION + +AOM_CTRL_USE_TYPE(AV1E_SET_MIN_GF_INTERVAL, unsigned int) +#define AOM_CTRL_AV1E_SET_MIN_GF_INTERVAL + +AOM_CTRL_USE_TYPE(AV1E_SET_MAX_GF_INTERVAL, unsigned int) +#define AOM_CTRL_AV1E_SET_MAX_GF_INTERVAL + +AOM_CTRL_USE_TYPE(AV1E_GET_ACTIVEMAP, aom_active_map_t *) +#define AOM_CTRL_AV1E_GET_ACTIVEMAP + +AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_RANGE, int) +#define AOM_CTRL_AV1E_SET_COLOR_RANGE + +#define AOM_CTRL_AV1E_SET_RENDER_SIZE +AOM_CTRL_USE_TYPE(AV1E_SET_RENDER_SIZE, int *) + +AOM_CTRL_USE_TYPE(AV1E_SET_SUPERBLOCK_SIZE, unsigned int) +#define AOM_CTRL_AV1E_SET_SUPERBLOCK_SIZE + +AOM_CTRL_USE_TYPE(AV1E_GET_SEQ_LEVEL_IDX, int *) +#define AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX + +AOM_CTRL_USE_TYPE(AV1E_SET_SINGLE_TILE_DECODING, unsigned int) +#define AOM_CTRL_AV1E_SET_SINGLE_TILE_DECODING + +AOM_CTRL_USE_TYPE(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int) +#define AOM_CTRL_AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST + +AOM_CTRL_USE_TYPE(AV1E_ENABLE_EXT_TILE_DEBUG, unsigned int) +#define AOM_CTRL_AV1E_ENABLE_EXT_TILE_DEBUG + +AOM_CTRL_USE_TYPE(AV1E_SET_VMAF_MODEL_PATH, const char *) +#define AOM_CTRL_AV1E_SET_VMAF_MODEL_PATH + +AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TEST_VECTOR, int) +#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TEST_VECTOR + +AOM_CTRL_USE_TYPE(AV1E_SET_FILM_GRAIN_TABLE, const char *) +#define AOM_CTRL_AV1E_SET_FILM_GRAIN_TABLE + +AOM_CTRL_USE_TYPE(AV1E_SET_CDF_UPDATE_MODE, unsigned int) +#define AOM_CTRL_AV1E_SET_CDF_UPDATE_MODE + +AOM_CTRL_USE_TYPE(AV1E_SET_DENOISE_NOISE_LEVEL, int) +#define AOM_CTRL_AV1E_SET_DENOISE_NOISE_LEVEL + +AOM_CTRL_USE_TYPE(AV1E_SET_DENOISE_BLOCK_SIZE, unsigned int) +#define AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE + +AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_X, unsigned int) +#define AOM_CTRL_AV1E_SET_CHROMA_SUBSAMPLING_X + +AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_Y, unsigned int) +#define AOM_CTRL_AV1E_SET_CHROMA_SUBSAMPLING_Y + +AOM_CTRL_USE_TYPE(AV1E_SET_REDUCED_TX_TYPE_SET, int) +#define AOM_CTRL_AV1E_SET_REDUCED_TX_TYPE_SET + +AOM_CTRL_USE_TYPE(AV1E_SET_INTRA_DCT_ONLY, int) +#define AOM_CTRL_AV1E_SET_INTRA_DCT_ONLY + +AOM_CTRL_USE_TYPE(AV1E_SET_INTER_DCT_ONLY, int) +#define AOM_CTRL_AV1E_SET_INTER_DCT_ONLY + +AOM_CTRL_USE_TYPE(AV1E_SET_INTRA_DEFAULT_TX_ONLY, int) +#define AOM_CTRL_AV1E_SET_INTRA_DEFAULT_TX_ONLY + +AOM_CTRL_USE_TYPE(AV1E_SET_QUANT_B_ADAPT, int) +#define AOM_CTRL_AV1E_SET_QUANT_B_ADAPT + +AOM_CTRL_USE_TYPE(AV1E_SET_GF_MIN_PYRAMID_HEIGHT, unsigned int) +#define AOM_CTRL_AV1E_SET_GF_MIN_PYRAMID_HEIGHT + +AOM_CTRL_USE_TYPE(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, unsigned int) +#define AOM_CTRL_AV1E_SET_GF_MAX_PYRAMID_HEIGHT + +AOM_CTRL_USE_TYPE(AV1E_SET_MAX_REFERENCE_FRAMES, int) +#define AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES + +AOM_CTRL_USE_TYPE(AV1E_SET_REDUCED_REFERENCE_SET, int) +#define AOM_CTRL_AV1E_SET_REDUCED_REFERENCE_SET + +AOM_CTRL_USE_TYPE(AV1E_SET_COEFF_COST_UPD_FREQ, unsigned int) +#define AOM_CTRL_AV1E_SET_COEFF_COST_UPD_FREQ + +AOM_CTRL_USE_TYPE(AV1E_SET_MODE_COST_UPD_FREQ, unsigned int) +#define AOM_CTRL_AV1E_SET_MODE_COST_UPD_FREQ + +AOM_CTRL_USE_TYPE(AV1E_SET_MV_COST_UPD_FREQ, unsigned int) +#define AOM_CTRL_AV1E_SET_MV_COST_UPD_FREQ + +AOM_CTRL_USE_TYPE(AV1E_SET_TARGET_SEQ_LEVEL_IDX, int) +#define AOM_CTRL_AV1E_SET_TARGET_SEQ_LEVEL_IDX + +AOM_CTRL_USE_TYPE(AV1E_SET_TIER_MASK, unsigned int) +#define AOM_CTRL_AV1E_SET_TIER_MASK + +AOM_CTRL_USE_TYPE(AV1E_SET_MIN_CR, unsigned int) +#define AOM_CTRL_AV1E_SET_MIN_CR + +AOM_CTRL_USE_TYPE(AV1E_SET_SVC_LAYER_ID, aom_svc_layer_id_t *) +#define AOME_CTRL_AV1E_SET_SVC_LAYER_ID + +AOM_CTRL_USE_TYPE(AV1E_SET_SVC_PARAMS, aom_svc_params_t *) +#define AOME_CTRL_AV1E_SET_SVC_PARAMS + +AOM_CTRL_USE_TYPE(AV1E_SET_SVC_REF_FRAME_CONFIG, aom_svc_ref_frame_config_t *) +#define AOME_CTRL_AV1E_SET_SVC_REF_FRAME_CONFIG + +AOM_CTRL_USE_TYPE(AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST, unsigned int) +#define AOM_CTRL_AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST + +AOM_CTRL_USE_TYPE(AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP, unsigned int) +#define AOM_CTRL_AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP + +/*!\endcond */ +/*! @} - end defgroup aom_encoder */ +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOMCX_H_ diff --git a/ThirdParty/avif/include/aom/aomdx.h b/ThirdParty/avif/include/aom/aomdx.h new file mode 100644 index 000000000..d4dff24af --- /dev/null +++ b/ThirdParty/avif/include/aom/aomdx.h @@ -0,0 +1,417 @@ +/* + * 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. + */ + +/*!\defgroup aom_decoder AOMedia AOM/AV1 Decoder + * \ingroup aom + * + * @{ + */ +/*!\file + * \brief Provides definitions for using AOM or AV1 within the aom Decoder + * interface. + */ +#ifndef AOM_AOM_AOMDX_H_ +#define AOM_AOM_AOMDX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Include controls common to both the encoder and decoder */ +#include "aom/aom.h" + +/*!\name Algorithm interface for AV1 + * + * This interface provides the capability to decode AV1 streams. + * @{ + */ + +/*!\brief A single instance of the AV1 decoder. + *\deprecated This access mechanism is provided for backwards compatibility; + * prefer aom_codec_av1_dx(). + */ +extern aom_codec_iface_t aom_codec_av1_dx_algo; +/*!\brief The interface to the AV1 decoder. + */ +extern aom_codec_iface_t *aom_codec_av1_dx(void); + +/*!@} - end algorithm interface member group */ + +/** Data structure that stores bit accounting for debug + */ +typedef struct Accounting Accounting; + +#ifndef AOM_INSPECTION_H_ +/** Callback that inspects decoder frame data. + */ +typedef void (*aom_inspect_cb)(void *decoder, void *ctx); + +#endif + +/*!\brief Structure to hold inspection callback and context. + * + * Defines a structure to hold the inspection callback function and calling + * context. + */ +typedef struct aom_inspect_init { + /*! Inspection callback. */ + aom_inspect_cb inspect_cb; + + /*! Inspection context. */ + void *inspect_ctx; +} aom_inspect_init; + +/*!\brief Structure to collect a buffer index when inspecting. + * + * Defines a structure to hold the buffer and return an index + * when calling decode from inspect. This enables us to decode + * non showable sub frames. + */ +typedef struct { + /*! Pointer for new position in compressed buffer after decoding 1 OBU. */ + const unsigned char *buf; + /*! Index into reference buffer array to see result of decoding 1 OBU. */ + int idx; + /*! Is a show existing frame. */ + int show_existing; +} Av1DecodeReturn; + +/*!\brief Structure to hold a tile's start address and size in the bitstream. + * + * Defines a structure to hold a tile's start address and size in the bitstream. + */ +typedef struct aom_tile_data { + /*! Tile data size. */ + size_t coded_tile_data_size; + /*! Tile's start address. */ + const void *coded_tile_data; + /*! Extra size information. */ + size_t extra_size; +} aom_tile_data; + +/*!\brief Structure to hold the external reference frame pointer. + * + * Define a structure to hold the external reference frame pointer. + */ +typedef struct av1_ext_ref_frame { + /*! Start pointer of external references. */ + aom_image_t *img; + /*! Number of available external references. */ + int num; +} av1_ext_ref_frame_t; + +/*!\enum aom_dec_control_id + * \brief AOM decoder control functions + * + * This set of macros define the control functions available for the AOM + * decoder interface. + * + * \sa #aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...) + */ +enum aom_dec_control_id { + /*!\brief Codec control function to get info on which reference frames were + * updated by the last decode, int* parameter + */ + AOMD_GET_LAST_REF_UPDATES = AOM_DECODER_CTRL_ID_START, + + /*!\brief Codec control function to check if the indicated frame is + corrupted, int* parameter + */ + AOMD_GET_FRAME_CORRUPTED, + + /*!\brief Codec control function to get info on which reference frames were + * used by the last decode, int* parameter + */ + AOMD_GET_LAST_REF_USED, + + /*!\brief Codec control function to get the dimensions that the current + * frame is decoded at, int* parameter. This may be different to the + * intended display size for the frame as specified in the wrapper or frame + * header (see AV1D_GET_DISPLAY_SIZE). + */ + AV1D_GET_FRAME_SIZE, + + /*!\brief Codec control function to get the current frame's intended display + * dimensions (as specified in the wrapper or frame header), int* parameter. + * This may be different to the decoded dimensions of this frame (see + * AV1D_GET_FRAME_SIZE). + */ + AV1D_GET_DISPLAY_SIZE, + + /*!\brief Codec control function to get the bit depth of the stream, + * unsigned int* parameter + */ + AV1D_GET_BIT_DEPTH, + + /*!\brief Codec control function to get the image format of the stream, + * aom_img_fmt_t* parameter + */ + AV1D_GET_IMG_FORMAT, + + /*!\brief Codec control function to get the size of the tile, unsigned int + parameter */ + AV1D_GET_TILE_SIZE, + + /*!\brief Codec control function to get the tile count in a tile list, int* + * parameter + */ + AV1D_GET_TILE_COUNT, + + /*!\brief Codec control function to set the byte alignment of the planes in + * the reference buffers, int parameter + * + * Valid values are power of 2, from 32 to 1024. A value of 0 sets + * legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly + * follows Y plane, and V plane directly follows U plane. Default value is 0. + */ + AV1_SET_BYTE_ALIGNMENT, + + /*!\brief Codec control function to invert the decoding order to from right to + * left, int parameter + * + * The function is used in a test to confirm the decoding independence of tile + * columns. The function may be used in application where this order + * of decoding is desired. int parameter + * + * TODO(yaowu): Rework the unit test that uses this control, and in a future + * release, this test-only control shall be removed. + */ + AV1_INVERT_TILE_DECODE_ORDER, + + /*!\brief Codec control function to set the skip loop filter flag, int + * parameter + * + * Valid values are integers. The decoder will skip the loop filter + * when its value is set to nonzero. If the loop filter is skipped the + * decoder may accumulate decode artifacts. The default value is 0. + */ + AV1_SET_SKIP_LOOP_FILTER, + + /*!\brief Codec control function to retrieve a pointer to the Accounting + * struct, takes Accounting** as parameter + * + * If called before a frame has been decoded, this returns AOM_CODEC_ERROR. + * The caller should ensure that AOM_CODEC_OK is returned before attempting + * to dereference the Accounting pointer. + * + * \attention When compiled without --enable-accounting, this returns + * AOM_CODEC_INCAPABLE. + */ + AV1_GET_ACCOUNTING, + + /*!\brief Codec control function to get last decoded frame quantizer, + * int* parameter + * + * Returned value uses internal quantizer scale defined by the codec. + */ + AOMD_GET_LAST_QUANTIZER, + + /*!\brief Codec control function to set the range of tile decoding, int + * parameter + * + * A value that is greater and equal to zero indicates only the specific + * row/column is decoded. A value that is -1 indicates the whole row/column + * is decoded. A special case is both values are -1 that means the whole + * frame is decoded. + */ + AV1_SET_DECODE_TILE_ROW, + AV1_SET_DECODE_TILE_COL, + + /*!\brief Codec control function to set the tile coding mode, int parameter + * + * - 0 = tiles are coded in normal tile mode + * - 1 = tiles are coded in large-scale tile mode + */ + AV1_SET_TILE_MODE, + + /*!\brief Codec control function to get the frame header information of an + * encoded frame, unsigned int* parameter + */ + AV1D_GET_FRAME_HEADER_INFO, + + /*!\brief Codec control function to get the start address and size of a + * tile in the coded bitstream, aom_tile_data* parameter. + */ + AV1D_GET_TILE_DATA, + + /*!\brief Codec control function to set the external references' pointers in + * the decoder, av1_ext_ref_frame_t* parameter. + * + * This is used while decoding the tile list OBU in large-scale tile coding + * mode. + */ + AV1D_SET_EXT_REF_PTR, + + /*!\brief Codec control function to enable the ext-tile software debug and + * testing code in the decoder, unsigned int parameter + */ + AV1D_EXT_TILE_DEBUG, + + /*!\brief Codec control function to enable the row based multi-threading of + * decoding, unsigned int parameter + * + * - 0 = disabled + * - 1 = enabled (default) + */ + AV1D_SET_ROW_MT, + + /*!\brief Codec control function to indicate whether bitstream is in + * Annex-B format, unsigned int parameter + */ + AV1D_SET_IS_ANNEXB, + + /*!\brief Codec control function to indicate which operating point to use, + * int parameter + * + * A scalable stream may define multiple operating points, each of which + * defines a set of temporal and spatial layers to be processed. The + * operating point index may take a value between 0 and + * operating_points_cnt_minus_1 (which is at most 31). + */ + AV1D_SET_OPERATING_POINT, + + /*!\brief Codec control function to indicate whether to output one frame per + * temporal unit (the default), or one frame per spatial layer. int parameter + * + * In a scalable stream, each temporal unit corresponds to a single "frame" + * of video, and within a temporal unit there may be multiple spatial layers + * with different versions of that frame. + * For video playback, only the highest-quality version (within the + * selected operating point) is needed, but for some use cases it is useful + * to have access to multiple versions of a frame when they are available. + */ + AV1D_SET_OUTPUT_ALL_LAYERS, + + /*!\brief Codec control function to set an aom_inspect_cb callback that is + * invoked each time a frame is decoded, aom_inspect_init* parameter + * + * \attention When compiled without --enable-inspection, this + * returns AOM_CODEC_INCAPABLE. + */ + AV1_SET_INSPECTION_CALLBACK, + + /*!\brief Codec control function to set the skip film grain flag, int + * parameter + * + * Valid values are integers. The decoder will skip the film grain when its + * value is set to nonzero. The default value is 0. + */ + AV1D_SET_SKIP_FILM_GRAIN, + + AOM_DECODER_CTRL_ID_MAX, + + AOMD_GET_FWD_KF_PRESENT, + + /*!\brief Codec control function to get the frame flags of the previous frame + * decoded. This will return a flag of type aom_codec_frame_flags_t. + */ + AOMD_GET_FRAME_FLAGS, +}; + +/*!\cond */ +/*!\brief AOM decoder control function parameter type + * + * Defines the data types that AOMD control functions take. + * + * \note Additional common controls are defined in aom.h. + * + * \note For each control ID "X", a macro-define of + * AOM_CTRL_X is provided. It is used at compile time to determine + * if the control ID is supported by the libaom library available, + * when the libaom version cannot be controlled. + */ +AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_UPDATES, int *) +#define AOM_CTRL_AOMD_GET_LAST_REF_UPDATES + +AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_CORRUPTED, int *) +#define AOM_CTRL_AOMD_GET_FRAME_CORRUPTED + +AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_USED, int *) +#define AOM_CTRL_AOMD_GET_LAST_REF_USED + +AOM_CTRL_USE_TYPE(AOMD_GET_LAST_QUANTIZER, int *) +#define AOM_CTRL_AOMD_GET_LAST_QUANTIZER + +AOM_CTRL_USE_TYPE(AOMD_GET_FWD_KF_PRESENT, int *) +#define AOM_CTRL_AOMD_GET_FWD_KF_PRESENT + +AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_FLAGS, int *) +#define AOM_CTRL_AOMD_GET_FRAME_FLAGS + +AOM_CTRL_USE_TYPE(AV1D_GET_DISPLAY_SIZE, int *) +#define AOM_CTRL_AV1D_GET_DISPLAY_SIZE + +AOM_CTRL_USE_TYPE(AV1D_GET_BIT_DEPTH, unsigned int *) +#define AOM_CTRL_AV1D_GET_BIT_DEPTH + +AOM_CTRL_USE_TYPE(AV1D_GET_IMG_FORMAT, aom_img_fmt_t *) +#define AOM_CTRL_AV1D_GET_IMG_FORMAT + +AOM_CTRL_USE_TYPE(AV1D_GET_TILE_SIZE, unsigned int *) +#define AOM_CTRL_AV1D_GET_TILE_SIZE + +AOM_CTRL_USE_TYPE(AV1D_GET_TILE_COUNT, unsigned int *) +#define AOM_CTRL_AV1D_GET_TILE_COUNT + +AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_SIZE, int *) +#define AOM_CTRL_AV1D_GET_FRAME_SIZE + +AOM_CTRL_USE_TYPE(AV1_INVERT_TILE_DECODE_ORDER, int) +#define AOM_CTRL_AV1_INVERT_TILE_DECODE_ORDER + +AOM_CTRL_USE_TYPE(AV1_GET_ACCOUNTING, Accounting **) +#define AOM_CTRL_AV1_GET_ACCOUNTING + +AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_ROW, int) +#define AOM_CTRL_AV1_SET_DECODE_TILE_ROW + +AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_COL, int) +#define AOM_CTRL_AV1_SET_DECODE_TILE_COL + +AOM_CTRL_USE_TYPE(AV1_SET_TILE_MODE, unsigned int) +#define AOM_CTRL_AV1_SET_TILE_MODE + +AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_HEADER_INFO, aom_tile_data *) +#define AOM_CTRL_AV1D_GET_FRAME_HEADER_INFO + +AOM_CTRL_USE_TYPE(AV1D_GET_TILE_DATA, aom_tile_data *) +#define AOM_CTRL_AV1D_GET_TILE_DATA + +AOM_CTRL_USE_TYPE(AV1D_SET_EXT_REF_PTR, av1_ext_ref_frame_t *) +#define AOM_CTRL_AV1D_SET_EXT_REF_PTR + +AOM_CTRL_USE_TYPE(AV1D_EXT_TILE_DEBUG, unsigned int) +#define AOM_CTRL_AV1D_EXT_TILE_DEBUG + +AOM_CTRL_USE_TYPE(AV1D_SET_ROW_MT, unsigned int) +#define AOM_CTRL_AV1D_SET_ROW_MT + +AOM_CTRL_USE_TYPE(AV1D_SET_SKIP_FILM_GRAIN, int) +#define AOM_CTRL_AV1D_SET_SKIP_FILM_GRAIN + +AOM_CTRL_USE_TYPE(AV1D_SET_IS_ANNEXB, unsigned int) +#define AOM_CTRL_AV1D_SET_IS_ANNEXB + +AOM_CTRL_USE_TYPE(AV1D_SET_OPERATING_POINT, int) +#define AOM_CTRL_AV1D_SET_OPERATING_POINT + +AOM_CTRL_USE_TYPE(AV1D_SET_OUTPUT_ALL_LAYERS, int) +#define AOM_CTRL_AV1D_SET_OUTPUT_ALL_LAYERS + +AOM_CTRL_USE_TYPE(AV1_SET_INSPECTION_CALLBACK, aom_inspect_init *) +#define AOM_CTRL_AV1_SET_INSPECTION_CALLBACK +/*!\endcond */ +/*! @} - end defgroup aom_decoder */ +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AOM_AOMDX_H_ diff --git a/ThirdParty/avif/include/avif/avif.h b/ThirdParty/avif/include/avif/avif.h new file mode 100644 index 000000000..04a083881 --- /dev/null +++ b/ThirdParty/avif/include/avif/avif.h @@ -0,0 +1,1042 @@ +// Copyright 2019 Joe Drago. All rights reserved. +// SPDX-License-Identifier: BSD-2-Clause + +#ifndef AVIF_AVIF_H +#define AVIF_AVIF_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// --------------------------------------------------------------------------- +// Export macros + +// AVIF_BUILDING_SHARED_LIBS should only be defined when libavif is being built +// as a shared library. +// AVIF_DLL should be defined if libavif is a shared library. If you are using +// libavif as CMake dependency, through CMake package config file or through +// pkg-config, this is defined automatically. +// +// Here's what AVIF_API will be defined as in shared build: +// | | Windows | Unix | +// | Build | __declspec(dllexport) | __attribute__((visibility("default"))) | +// | Use | __declspec(dllimport) | | +// +// For static build, AVIF_API is always defined as nothing. + +#if defined(_WIN32) +#define AVIF_HELPER_EXPORT __declspec(dllexport) +#define AVIF_HELPER_IMPORT __declspec(dllimport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define AVIF_HELPER_EXPORT __attribute__((visibility("default"))) +#define AVIF_HELPER_IMPORT +#else +#define AVIF_HELPER_EXPORT +#define AVIF_HELPER_IMPORT +#endif + +#if defined(AVIF_DLL) +#if defined(AVIF_BUILDING_SHARED_LIBS) +#define AVIF_API AVIF_HELPER_EXPORT +#else +#define AVIF_API AVIF_HELPER_IMPORT +#endif // defined(AVIF_BUILDING_SHARED_LIBS) +#else +#define AVIF_API +#endif // defined(AVIF_DLL) + +// --------------------------------------------------------------------------- +// Constants + +// AVIF_VERSION_DEVEL should always be 0 for official releases / version tags, +// and non-zero during development of the next release. This should allow for +// downstream projects to do greater-than preprocessor checks on AVIF_VERSION +// to leverage in-development code without breaking their stable builds. +#define AVIF_VERSION_MAJOR 0 +#define AVIF_VERSION_MINOR 9 +#define AVIF_VERSION_PATCH 3 +#define AVIF_VERSION_DEVEL 1 +#define AVIF_VERSION \ + ((AVIF_VERSION_MAJOR * 1000000) + (AVIF_VERSION_MINOR * 10000) + (AVIF_VERSION_PATCH * 100) + AVIF_VERSION_DEVEL) + +typedef int avifBool; +#define AVIF_TRUE 1 +#define AVIF_FALSE 0 + +#define AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE 256 + +// A reasonable default for maximum image size to avoid out-of-memory errors or integer overflow in +// (32-bit) int or unsigned int arithmetic operations. +#define AVIF_DEFAULT_IMAGE_SIZE_LIMIT (16384 * 16384) + +// a 12 hour AVIF image sequence, running at 60 fps (a basic sanity check as this is quite ridiculous) +#define AVIF_DEFAULT_IMAGE_COUNT_LIMIT (12 * 3600 * 60) + +#define AVIF_QUANTIZER_LOSSLESS 0 +#define AVIF_QUANTIZER_BEST_QUALITY 0 +#define AVIF_QUANTIZER_WORST_QUALITY 63 + +#define AVIF_PLANE_COUNT_YUV 3 + +#define AVIF_SPEED_DEFAULT -1 +#define AVIF_SPEED_SLOWEST 0 +#define AVIF_SPEED_FASTEST 10 + +typedef enum avifPlanesFlag { + AVIF_PLANES_YUV = (1 << 0), + AVIF_PLANES_A = (1 << 1), + + AVIF_PLANES_ALL = 0xff +} avifPlanesFlag; +typedef uint32_t avifPlanesFlags; + +enum avifChannelIndex { + // rgbPlanes + AVIF_CHAN_R = 0, + AVIF_CHAN_G = 1, + AVIF_CHAN_B = 2, + + // yuvPlanes + AVIF_CHAN_Y = 0, + AVIF_CHAN_U = 1, + AVIF_CHAN_V = 2 +}; + +// --------------------------------------------------------------------------- +// Version + +AVIF_API const char* avifVersion(void); +AVIF_API void avifCodecVersions(char outBuffer[256]); +AVIF_API unsigned int avifLibYUVVersion(void); // returns 0 if libavif wasn't compiled with libyuv support + +// --------------------------------------------------------------------------- +// Memory management + +AVIF_API void* avifAlloc(size_t size); +AVIF_API void avifFree(void* p); + +// --------------------------------------------------------------------------- +// avifResult + +typedef enum avifResult { + AVIF_RESULT_OK = 0, + AVIF_RESULT_UNKNOWN_ERROR, + AVIF_RESULT_INVALID_FTYP, + AVIF_RESULT_NO_CONTENT, + AVIF_RESULT_NO_YUV_FORMAT_SELECTED, + AVIF_RESULT_REFORMAT_FAILED, + AVIF_RESULT_UNSUPPORTED_DEPTH, + AVIF_RESULT_ENCODE_COLOR_FAILED, + AVIF_RESULT_ENCODE_ALPHA_FAILED, + AVIF_RESULT_BMFF_PARSE_FAILED, + AVIF_RESULT_NO_AV1_ITEMS_FOUND, + AVIF_RESULT_DECODE_COLOR_FAILED, + AVIF_RESULT_DECODE_ALPHA_FAILED, + AVIF_RESULT_COLOR_ALPHA_SIZE_MISMATCH, + AVIF_RESULT_ISPE_SIZE_MISMATCH, + AVIF_RESULT_NO_CODEC_AVAILABLE, + AVIF_RESULT_NO_IMAGES_REMAINING, + AVIF_RESULT_INVALID_EXIF_PAYLOAD, + AVIF_RESULT_INVALID_IMAGE_GRID, + AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION, + AVIF_RESULT_TRUNCATED_DATA, + AVIF_RESULT_IO_NOT_SET, // the avifIO field of avifDecoder is not set + AVIF_RESULT_IO_ERROR, + AVIF_RESULT_WAITING_ON_IO, // similar to EAGAIN/EWOULDBLOCK, this means the avifIO doesn't have necessary data available yet + AVIF_RESULT_INVALID_ARGUMENT, // an argument passed into this function is invalid + AVIF_RESULT_NOT_IMPLEMENTED, // a requested code path is not (yet) implemented + AVIF_RESULT_OUT_OF_MEMORY +} avifResult; + +AVIF_API const char* avifResultToString(avifResult result); + +// --------------------------------------------------------------------------- +// avifROData/avifRWData: Generic raw memory storage + +typedef struct avifROData { + const uint8_t* data; + size_t size; +} avifROData; + +// Note: Use avifRWDataFree() if any avif*() function populates one of these. + +typedef struct avifRWData { + uint8_t* data; + size_t size; +} avifRWData; + +// clang-format off +// Initialize avifROData/avifRWData on the stack with this +#define AVIF_DATA_EMPTY { NULL, 0 } +// clang-format on + +AVIF_API void avifRWDataRealloc(avifRWData* raw, size_t newSize); +AVIF_API void avifRWDataSet(avifRWData* raw, const uint8_t* data, size_t len); +AVIF_API void avifRWDataFree(avifRWData* raw); + +// --------------------------------------------------------------------------- +// avifPixelFormat + +typedef enum avifPixelFormat { + // No pixels are present + AVIF_PIXEL_FORMAT_NONE = 0, + + AVIF_PIXEL_FORMAT_YUV444, + AVIF_PIXEL_FORMAT_YUV422, + AVIF_PIXEL_FORMAT_YUV420, + AVIF_PIXEL_FORMAT_YUV400 +} avifPixelFormat; +AVIF_API const char* avifPixelFormatToString(avifPixelFormat format); + +typedef struct avifPixelFormatInfo { + avifBool monochrome; + int chromaShiftX; + int chromaShiftY; +} avifPixelFormatInfo; + +AVIF_API void avifGetPixelFormatInfo(avifPixelFormat format, avifPixelFormatInfo* info); + +// --------------------------------------------------------------------------- +// avifChromaSamplePosition + +typedef enum avifChromaSamplePosition { + AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN = 0, + AVIF_CHROMA_SAMPLE_POSITION_VERTICAL = 1, + AVIF_CHROMA_SAMPLE_POSITION_COLOCATED = 2 +} avifChromaSamplePosition; + +// --------------------------------------------------------------------------- +// avifRange + +typedef enum avifRange { + AVIF_RANGE_LIMITED = 0, + AVIF_RANGE_FULL = 1 +} avifRange; + +// --------------------------------------------------------------------------- +// CICP enums - https://www.itu.int/rec/T-REC-H.273-201612-I/en + +enum { + // This is actually reserved, but libavif uses it as a sentinel value. + AVIF_COLOR_PRIMARIES_UNKNOWN = 0, + + AVIF_COLOR_PRIMARIES_BT709 = 1, + AVIF_COLOR_PRIMARIES_IEC61966_2_4 = 1, + AVIF_COLOR_PRIMARIES_UNSPECIFIED = 2, + AVIF_COLOR_PRIMARIES_BT470M = 4, + AVIF_COLOR_PRIMARIES_BT470BG = 5, + AVIF_COLOR_PRIMARIES_BT601 = 6, + AVIF_COLOR_PRIMARIES_SMPTE240 = 7, + AVIF_COLOR_PRIMARIES_GENERIC_FILM = 8, + AVIF_COLOR_PRIMARIES_BT2020 = 9, + AVIF_COLOR_PRIMARIES_XYZ = 10, + AVIF_COLOR_PRIMARIES_SMPTE431 = 11, + AVIF_COLOR_PRIMARIES_SMPTE432 = 12, // DCI P3 + AVIF_COLOR_PRIMARIES_EBU3213 = 22 +}; +typedef uint16_t avifColorPrimaries; // AVIF_COLOR_PRIMARIES_* + +// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY +AVIF_API void avifColorPrimariesGetValues(avifColorPrimaries acp, float outPrimaries[8]); +AVIF_API avifColorPrimaries avifColorPrimariesFind(const float inPrimaries[8], const char** outName); + +enum { + // This is actually reserved, but libavif uses it as a sentinel value. + AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN = 0, + + AVIF_TRANSFER_CHARACTERISTICS_BT709 = 1, + AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED = 2, + AVIF_TRANSFER_CHARACTERISTICS_BT470M = 4, // 2.2 gamma + AVIF_TRANSFER_CHARACTERISTICS_BT470BG = 5, // 2.8 gamma + AVIF_TRANSFER_CHARACTERISTICS_BT601 = 6, + AVIF_TRANSFER_CHARACTERISTICS_SMPTE240 = 7, + AVIF_TRANSFER_CHARACTERISTICS_LINEAR = 8, + AVIF_TRANSFER_CHARACTERISTICS_LOG100 = 9, + AVIF_TRANSFER_CHARACTERISTICS_LOG100_SQRT10 = 10, + AVIF_TRANSFER_CHARACTERISTICS_IEC61966 = 11, + AVIF_TRANSFER_CHARACTERISTICS_BT1361 = 12, + AVIF_TRANSFER_CHARACTERISTICS_SRGB = 13, + AVIF_TRANSFER_CHARACTERISTICS_BT2020_10BIT = 14, + AVIF_TRANSFER_CHARACTERISTICS_BT2020_12BIT = 15, + AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084 = 16, // PQ + AVIF_TRANSFER_CHARACTERISTICS_SMPTE428 = 17, + AVIF_TRANSFER_CHARACTERISTICS_HLG = 18 +}; +typedef uint16_t avifTransferCharacteristics; // AVIF_TRANSFER_CHARACTERISTICS_* + +enum { + AVIF_MATRIX_COEFFICIENTS_IDENTITY = 0, + AVIF_MATRIX_COEFFICIENTS_BT709 = 1, + AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED = 2, + AVIF_MATRIX_COEFFICIENTS_FCC = 4, + AVIF_MATRIX_COEFFICIENTS_BT470BG = 5, + AVIF_MATRIX_COEFFICIENTS_BT601 = 6, + AVIF_MATRIX_COEFFICIENTS_SMPTE240 = 7, + AVIF_MATRIX_COEFFICIENTS_YCGCO = 8, + AVIF_MATRIX_COEFFICIENTS_BT2020_NCL = 9, + AVIF_MATRIX_COEFFICIENTS_BT2020_CL = 10, + AVIF_MATRIX_COEFFICIENTS_SMPTE2085 = 11, + AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL = 12, + AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL = 13, + AVIF_MATRIX_COEFFICIENTS_ICTCP = 14 +}; +typedef uint16_t avifMatrixCoefficients; // AVIF_MATRIX_COEFFICIENTS_* + +// --------------------------------------------------------------------------- +// avifDiagnostics + +typedef struct avifDiagnostics { + // Upon receiving an error from any non-const libavif API call, if the toplevel structure used + // in the API call (avifDecoder, avifEncoder) contains a diag member, this buffer may be + // populated with a NULL-terminated, freeform error string explaining the most recent error in + // more detail. It will be cleared at the beginning of every non-const API call. + // + // Note: If an error string contains the "[Strict]" prefix, it means that you encountered an + // error that only occurs during strict decoding. If you disable strict mode, you will no + // longer encounter this error. + char error[AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE]; +} avifDiagnostics; + +AVIF_API void avifDiagnosticsClearError(avifDiagnostics* diag); + +// --------------------------------------------------------------------------- +// Optional transformation structs + +typedef enum avifTransformFlag { + AVIF_TRANSFORM_NONE = 0, + + AVIF_TRANSFORM_PASP = (1 << 0), + AVIF_TRANSFORM_CLAP = (1 << 1), + AVIF_TRANSFORM_IROT = (1 << 2), + AVIF_TRANSFORM_IMIR = (1 << 3) +} avifTransformFlag; +typedef uint32_t avifTransformFlags; + +typedef struct avifPixelAspectRatioBox { + // 'pasp' from ISO/IEC 14496-12:2015 12.1.4.3 + + // define the relative width and height of a pixel + uint32_t hSpacing; + uint32_t vSpacing; +} avifPixelAspectRatioBox; + +typedef struct avifCleanApertureBox { + // 'clap' from ISO/IEC 14496-12:2015 12.1.4.3 + + // a fractional number which defines the exact clean aperture width, in counted pixels, of the video image + uint32_t widthN; + uint32_t widthD; + + // a fractional number which defines the exact clean aperture height, in counted pixels, of the video image + uint32_t heightN; + uint32_t heightD; + + // a fractional number which defines the horizontal offset of clean aperture centre minus (width-1)/2. Typically 0. + uint32_t horizOffN; + uint32_t horizOffD; + + // a fractional number which defines the vertical offset of clean aperture centre minus (height-1)/2. Typically 0. + uint32_t vertOffN; + uint32_t vertOffD; +} avifCleanApertureBox; + +typedef struct avifImageRotation { + // 'irot' from ISO/IEC 23008-12:2017 6.5.10 + + // angle * 90 specifies the angle (in anti-clockwise direction) in units of degrees. + uint8_t angle; // legal values: [0-3] +} avifImageRotation; + +typedef struct avifImageMirror { + // 'imir' from ISO/IEC 23008-12:2017 6.5.12 (Draft Amendment 2): + // + // 'mode' specifies how the mirroring is performed: + // + // 0 indicates that the top and bottom parts of the image are exchanged; + // 1 specifies that the left and right parts are exchanged. + // + // NOTE In Exif, orientation tag can be used to signal mirroring operations. Exif + // orientation tag 4 corresponds to mode = 0 of ImageMirror, and Exif orientation tag 2 + // corresponds to mode = 1 accordingly. + // + // Legal values: [0, 1] + // + // NOTE: As of HEIF Draft Amendment 2, the name of this variable has changed from 'axis' to 'mode' as + // the logic behind it has been *inverted*. Please use the wording above describing the legal + // values for 'mode' and update any code that previously may have used `axis` to use + // the *opposite* value (0 now means top-to-bottom, where it used to mean left-to-right). + uint8_t mode; +} avifImageMirror; + +// --------------------------------------------------------------------------- +// avifCropRect - Helper struct/functions to work with avifCleanApertureBox + +typedef struct avifCropRect { + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +} avifCropRect; + +// These will return AVIF_FALSE if the resultant values violate any standards, and if so, the output +// values are not guaranteed to be complete or correct and should not be used. +AVIF_API avifBool avifCropRectConvertCleanApertureBox(avifCropRect* cropRect, + const avifCleanApertureBox* clap, + uint32_t imageW, + uint32_t imageH, + avifPixelFormat yuvFormat, + avifDiagnostics* diag); +AVIF_API avifBool avifCleanApertureBoxConvertCropRect(avifCleanApertureBox* clap, + const avifCropRect* cropRect, + uint32_t imageW, + uint32_t imageH, + avifPixelFormat yuvFormat, + avifDiagnostics* diag); + +// --------------------------------------------------------------------------- +// avifImage + +typedef struct avifImage { + // Image information + uint32_t width; + uint32_t height; + uint32_t depth; // all planes must share this depth; if depth>8, all planes are uint16_t internally + + avifPixelFormat yuvFormat; + avifRange yuvRange; + avifChromaSamplePosition yuvChromaSamplePosition; + uint8_t* yuvPlanes[AVIF_PLANE_COUNT_YUV]; + uint32_t yuvRowBytes[AVIF_PLANE_COUNT_YUV]; + avifBool imageOwnsYUVPlanes; + + avifRange alphaRange; + uint8_t* alphaPlane; + uint32_t alphaRowBytes; + avifBool imageOwnsAlphaPlane; + avifBool alphaPremultiplied; + + // ICC Profile + avifRWData icc; + + // CICP information: + // These are stored in the AV1 payload and used to signal YUV conversion. Additionally, if an + // ICC profile is not specified, these will be stored in the AVIF container's `colr` box with + // a type of `nclx`. If your system supports ICC profiles, be sure to check for the existence + // of one (avifImage.icc) before relying on the values listed here! + avifColorPrimaries colorPrimaries; + avifTransferCharacteristics transferCharacteristics; + avifMatrixCoefficients matrixCoefficients; + + // Transformations - These metadata values are encoded/decoded when transformFlags are set + // appropriately, but do not impact/adjust the actual pixel buffers used (images won't be + // pre-cropped or mirrored upon decode). Basic explanations from the standards are offered in + // comments above, but for detailed explanations, please refer to the HEIF standard (ISO/IEC + // 23008-12:2017) and the BMFF standard (ISO/IEC 14496-12:2015). + // + // To encode any of these boxes, set the values in the associated box, then enable the flag in + // transformFlags. On decode, only honor the values in boxes with the associated transform flag set. + avifTransformFlags transformFlags; + avifPixelAspectRatioBox pasp; + avifCleanApertureBox clap; + avifImageRotation irot; + avifImageMirror imir; + + // Metadata - set with avifImageSetMetadata*() before write, check .size>0 for existence after read + avifRWData exif; + avifRWData xmp; +} avifImage; + +AVIF_API avifImage* avifImageCreate(int width, int height, int depth, avifPixelFormat yuvFormat); +AVIF_API avifImage* avifImageCreateEmpty(void); // helper for making an image to decode into +AVIF_API void avifImageCopy(avifImage* dstImage, const avifImage* srcImage, avifPlanesFlags planes); // deep copy +AVIF_API void avifImageDestroy(avifImage* image); + +AVIF_API void avifImageSetProfileICC(avifImage* image, const uint8_t* icc, size_t iccSize); + +// Warning: If the Exif payload is set and invalid, avifEncoderWrite() may return AVIF_RESULT_INVALID_EXIF_PAYLOAD +AVIF_API void avifImageSetMetadataExif(avifImage* image, const uint8_t* exif, size_t exifSize); +AVIF_API void avifImageSetMetadataXMP(avifImage* image, const uint8_t* xmp, size_t xmpSize); + +AVIF_API void avifImageAllocatePlanes(avifImage* image, avifPlanesFlags planes); // Ignores any pre-existing planes +AVIF_API void avifImageFreePlanes(avifImage* image, avifPlanesFlags planes); // Ignores already-freed planes +AVIF_API void avifImageStealPlanes(avifImage* dstImage, avifImage* srcImage, avifPlanesFlags planes); + +// --------------------------------------------------------------------------- +// Understanding maxThreads +// +// libavif's structures and API use the setting 'maxThreads' in a few places. The intent of this +// setting is to limit concurrent thread activity/usage, not necessarily to put a hard ceiling on +// how many sleeping threads happen to exist behind the scenes. The goal of this setting is to +// ensure that at any given point during libavif's encoding or decoding, no more than *maxThreads* +// threads are simultaneously **active and taking CPU time**. +// +// As an important example, when encoding an image sequence that has an alpha channel, two +// long-lived underlying AV1 encoders must simultaneously exist (one for color, one for alpha). For +// each additional frame fed into libavif, its YUV planes are fed into one instance of the AV1 +// encoder, and its alpha plane is fed into another. These operations happen serially, so only one +// of these AV1 encoders is ever active at a time. However, the AV1 encoders might pre-create a +// pool of worker threads upon initialization, so during this process, twice the amount of worker +// threads actually simultaneously exist on the machine, but half of them are guaranteed to be +// sleeping. +// +// This design ensures that AV1 implementations are given as many threads as possible to ensure a +// speedy encode or decode, despite the complexities of occasionally needing two AV1 codec instances +// (due to alpha payloads being separate from color payloads). If your system has a hard ceiling on +// the number of threads that can ever be in flight at a given time, please account for this +// accordingly. + +// --------------------------------------------------------------------------- +// Optional YUV<->RGB support + +// To convert to/from RGB, create an avifRGBImage on the stack, call avifRGBImageSetDefaults() on +// it, and then tweak the values inside of it accordingly. At a minimum, you should populate +// ->pixels and ->rowBytes with an appropriately sized pixel buffer, which should be at least +// (->rowBytes * ->height) bytes, where ->rowBytes is at least (->width * avifRGBImagePixelSize()). +// If you don't want to supply your own pixel buffer, you can use the +// avifRGBImageAllocatePixels()/avifRGBImageFreePixels() convenience functions. + +// avifImageRGBToYUV() and avifImageYUVToRGB() will perform depth rescaling and limited<->full range +// conversion, if necessary. Pixels in an avifRGBImage buffer are always full range, and conversion +// routines will fail if the width and height don't match the associated avifImage. + +// If libavif is built with libyuv fast paths enabled, libavif will use libyuv for conversion from +// YUV to RGB if the following requirements are met: +// +// * YUV depth: 8 +// * RGB depth: 8 +// * rgb.chromaUpsampling: AVIF_CHROMA_UPSAMPLING_AUTOMATIC, AVIF_CHROMA_UPSAMPLING_FASTEST +// * rgb.format: AVIF_RGB_FORMAT_RGBA, AVIF_RGB_FORMAT_BGRA (420/422 support for AVIF_RGB_FORMAT_ABGR, AVIF_RGB_FORMAT_ARGB) +// * CICP is one of the following combinations (CP/TC/MC/Range): +// * x/x/[2|5|6]/Full +// * [5|6]/x/12/Full +// * x/x/[1|2|5|6|9]/Limited +// * [1|2|5|6|9]/x/12/Limited + +typedef enum avifRGBFormat { + AVIF_RGB_FORMAT_RGB = 0, + AVIF_RGB_FORMAT_RGBA, // This is the default format set in avifRGBImageSetDefaults(). + AVIF_RGB_FORMAT_ARGB, + AVIF_RGB_FORMAT_BGR, + AVIF_RGB_FORMAT_BGRA, + AVIF_RGB_FORMAT_ABGR +} avifRGBFormat; +AVIF_API uint32_t avifRGBFormatChannelCount(avifRGBFormat format); +AVIF_API avifBool avifRGBFormatHasAlpha(avifRGBFormat format); + +typedef enum avifChromaUpsampling { + AVIF_CHROMA_UPSAMPLING_AUTOMATIC = 0, // Chooses best trade off of speed/quality (prefers libyuv, else uses BEST_QUALITY) + AVIF_CHROMA_UPSAMPLING_FASTEST = 1, // Chooses speed over quality (prefers libyuv, else uses NEAREST) + AVIF_CHROMA_UPSAMPLING_BEST_QUALITY = 2, // Chooses the best quality upsampling, given settings (avoids libyuv) + AVIF_CHROMA_UPSAMPLING_NEAREST = 3, // Uses nearest-neighbor filter (built-in) + AVIF_CHROMA_UPSAMPLING_BILINEAR = 4 // Uses bilinear filter (built-in) +} avifChromaUpsampling; + +typedef struct avifRGBImage { + uint32_t width; // must match associated avifImage + uint32_t height; // must match associated avifImage + uint32_t depth; // legal depths [8, 10, 12, 16]. if depth>8, pixels must be uint16_t internally + avifRGBFormat format; // all channels are always full range + avifChromaUpsampling chromaUpsampling; // Defaults to AVIF_CHROMA_UPSAMPLING_AUTOMATIC: How to upsample non-4:4:4 UV (ignored for 444) when converting to RGB. + // Unused when converting to YUV. avifRGBImageSetDefaults() prefers quality over speed. + avifBool ignoreAlpha; // Used for XRGB formats, treats formats containing alpha (such as ARGB) as if they were + // RGB, treating the alpha bits as if they were all 1. + avifBool alphaPremultiplied; // indicates if RGB value is pre-multiplied by alpha. Default: false + avifBool isFloat; // indicates if RGBA values are in half float (f16) format. Valid only when depth == 16. Default: false + + uint8_t* pixels; + uint32_t rowBytes; +} avifRGBImage; + +// Sets rgb->width, rgb->height, and rgb->depth to image->width, image->height, and image->depth. +// Sets rgb->pixels to NULL and rgb->rowBytes to 0. Sets the other fields of 'rgb' to default +// values. +AVIF_API void avifRGBImageSetDefaults(avifRGBImage* rgb, const avifImage* image); +AVIF_API uint32_t avifRGBImagePixelSize(const avifRGBImage* rgb); + +// Convenience functions. If you supply your own pixels/rowBytes, you do not need to use these. +AVIF_API void avifRGBImageAllocatePixels(avifRGBImage* rgb); +AVIF_API void avifRGBImageFreePixels(avifRGBImage* rgb); + +// The main conversion functions +AVIF_API avifResult avifImageRGBToYUV(avifImage* image, const avifRGBImage* rgb); +AVIF_API avifResult avifImageYUVToRGB(const avifImage* image, avifRGBImage* rgb); + +// Premultiply handling functions. +// (Un)premultiply is automatically done by the main conversion functions above, +// so usually you don't need to call these. They are there for convenience. +AVIF_API avifResult avifRGBImagePremultiplyAlpha(avifRGBImage* rgb); +AVIF_API avifResult avifRGBImageUnpremultiplyAlpha(avifRGBImage* rgb); + +// --------------------------------------------------------------------------- +// YUV Utils + +AVIF_API int avifFullToLimitedY(int depth, int v); +AVIF_API int avifFullToLimitedUV(int depth, int v); +AVIF_API int avifLimitedToFullY(int depth, int v); +AVIF_API int avifLimitedToFullUV(int depth, int v); + +// --------------------------------------------------------------------------- +// Codec selection + +typedef enum avifCodecChoice { + AVIF_CODEC_CHOICE_AUTO = 0, + AVIF_CODEC_CHOICE_AOM, + AVIF_CODEC_CHOICE_DAV1D, // Decode only + AVIF_CODEC_CHOICE_LIBGAV1, // Decode only + AVIF_CODEC_CHOICE_RAV1E, // Encode only + AVIF_CODEC_CHOICE_SVT // Encode only +} avifCodecChoice; + +typedef enum avifCodecFlag { + AVIF_CODEC_FLAG_CAN_DECODE = (1 << 0), + AVIF_CODEC_FLAG_CAN_ENCODE = (1 << 1) +} avifCodecFlag; +typedef uint32_t avifCodecFlags; + +// If this returns NULL, the codec choice/flag combination is unavailable +AVIF_API const char* avifCodecName(avifCodecChoice choice, avifCodecFlags requiredFlags); +AVIF_API avifCodecChoice avifCodecChoiceFromName(const char* name); + +typedef struct avifCodecConfigurationBox { + // [skipped; is constant] unsigned int (1)marker = 1; + // [skipped; is constant] unsigned int (7)version = 1; + + uint8_t seqProfile; // unsigned int (3) seq_profile; + uint8_t seqLevelIdx0; // unsigned int (5) seq_level_idx_0; + uint8_t seqTier0; // unsigned int (1) seq_tier_0; + uint8_t highBitdepth; // unsigned int (1) high_bitdepth; + uint8_t twelveBit; // unsigned int (1) twelve_bit; + uint8_t monochrome; // unsigned int (1) monochrome; + uint8_t chromaSubsamplingX; // unsigned int (1) chroma_subsampling_x; + uint8_t chromaSubsamplingY; // unsigned int (1) chroma_subsampling_y; + uint8_t chromaSamplePosition; // unsigned int (2) chroma_sample_position; + + // unsigned int (3)reserved = 0; + // unsigned int (1)initial_presentation_delay_present; + // if (initial_presentation_delay_present) { + // unsigned int (4)initial_presentation_delay_minus_one; + // } else { + // unsigned int (4)reserved = 0; + // } +} avifCodecConfigurationBox; + +// --------------------------------------------------------------------------- +// avifIO + +struct avifIO; + +// Destroy must completely destroy all child structures *and* free the avifIO object itself. +// This function pointer is optional, however, if the avifIO object isn't intended to be owned by +// a libavif encoder/decoder. +typedef void (*avifIODestroyFunc)(struct avifIO* io); + +// This function should return a block of memory that *must* remain valid until another read call to +// this avifIO struct is made (reusing a read buffer is acceptable/expected). +// +// * If offset exceeds the size of the content (past EOF), return AVIF_RESULT_IO_ERROR. +// * If offset is *exactly* at EOF, provide a 0-byte buffer and return AVIF_RESULT_OK. +// * If (offset+size) exceeds the contents' size, it must truncate the range to provide all +// bytes from the offset to EOF. +// * If the range is unavailable yet (due to network conditions or any other reason), +// return AVIF_RESULT_WAITING_ON_IO. +// * Otherwise, provide the range and return AVIF_RESULT_OK. +typedef avifResult (*avifIOReadFunc)(struct avifIO* io, uint32_t readFlags, uint64_t offset, size_t size, avifROData* out); + +typedef avifResult (*avifIOWriteFunc)(struct avifIO* io, uint32_t writeFlags, uint64_t offset, const uint8_t* data, size_t size); + +typedef struct avifIO { + avifIODestroyFunc destroy; + avifIOReadFunc read; + + // This is reserved for future use - but currently ignored. Set it to a null pointer. + avifIOWriteFunc write; + + // If non-zero, this is a hint to internal structures of the max size offered by the content + // this avifIO structure is reading. If it is a static memory source, it should be the size of + // the memory buffer; if it is a file, it should be the file's size. If this information cannot + // be known (as it is streamed-in), set a reasonable upper boundary here (larger than the file + // can possibly be for your environment, but within your environment's memory constraints). This + // is used for sanity checks when allocating internal buffers to protect against + // malformed/malicious files. + uint64_t sizeHint; + + // If true, *all* memory regions returned from *all* calls to read are guaranteed to be + // persistent and exist for the lifetime of the avifIO object. If false, libavif will make + // in-memory copies of samples and metadata content, and a memory region returned from read must + // only persist until the next call to read. + avifBool persistent; + + // The contents of this are defined by the avifIO implementation, and should be fully destroyed + // by the implementation of the associated destroy function, unless it isn't owned by the avifIO + // struct. It is not necessary to use this pointer in your implementation. + void* data; +} avifIO; + +AVIF_API avifIO* avifIOCreateMemoryReader(const uint8_t* data, size_t size); +AVIF_API avifIO* avifIOCreateFileReader(const char* filename); +AVIF_API void avifIODestroy(avifIO* io); + +// --------------------------------------------------------------------------- +// avifDecoder + +// Some encoders (including very old versions of avifenc) do not implement the AVIF standard +// perfectly, and thus create invalid files. However, these files are likely still recoverable / +// decodable, if it wasn't for the strict requirements imposed by libavif's decoder. These flags +// allow a user of avifDecoder to decide what level of strictness they want in their project. +typedef enum avifStrictFlag { + // Disables all strict checks. + AVIF_STRICT_DISABLED = 0, + + // Requires the PixelInformationProperty ('pixi') be present in AV1 image items. libheif v1.11.0 + // or older does not add the 'pixi' item property to AV1 image items. If you need to decode AVIF + // images encoded by libheif v1.11.0 or older, be sure to disable this bit. (This issue has been + // corrected in libheif v1.12.0.) + AVIF_STRICT_PIXI_REQUIRED = (1 << 0), + + // This demands that the values surfaced in the clap box are valid, determined by attempting to + // convert the clap box to a crop rect using avifCropRectConvertCleanApertureBox(). If this + // function returns AVIF_FALSE and this strict flag is set, the decode will fail. + AVIF_STRICT_CLAP_VALID = (1 << 1), + + // Requires the ImageSpatialExtentsProperty ('ispe') be present in alpha auxiliary image items. + // avif-serialize 0.7.3 or older does not add the 'ispe' item property to alpha auxiliary image + // items. If you need to decode AVIF images encoded by the cavif encoder with avif-serialize + // 0.7.3 or older, be sure to disable this bit. (This issue has been corrected in avif-serialize + // 0.7.4.) See https://github.com/kornelski/avif-serialize/issues/3 and + // https://crbug.com/1246678. + AVIF_STRICT_ALPHA_ISPE_REQUIRED = (1 << 2), + + // Maximum strictness; enables all bits above. This is avifDecoder's default. + AVIF_STRICT_ENABLED = AVIF_STRICT_PIXI_REQUIRED | AVIF_STRICT_CLAP_VALID | AVIF_STRICT_ALPHA_ISPE_REQUIRED +} avifStrictFlag; +typedef uint32_t avifStrictFlags; + +// Useful stats related to a read/write +typedef struct avifIOStats { + size_t colorOBUSize; + size_t alphaOBUSize; +} avifIOStats; + +struct avifDecoderData; + +typedef enum avifDecoderSource { + // Honor the major brand signaled in the beginning of the file to pick between an AVIF sequence + // ('avis', tracks-based) or a single image ('avif', item-based). If the major brand is neither + // of these, prefer the AVIF sequence ('avis', tracks-based), if present. + AVIF_DECODER_SOURCE_AUTO = 0, + + // Use the primary item and the aux (alpha) item in the avif(s). + // This is where single-image avifs store their image. + AVIF_DECODER_SOURCE_PRIMARY_ITEM, + + // Use the chunks inside primary/aux tracks in the moov block. + // This is where avifs image sequences store their images. + AVIF_DECODER_SOURCE_TRACKS, + + // Decode the thumbnail item. Currently unimplemented. + // AVIF_DECODER_SOURCE_THUMBNAIL_ITEM +} avifDecoderSource; + +// Information about the timing of a single image in an image sequence +typedef struct avifImageTiming { + uint64_t timescale; // timescale of the media (Hz) + double pts; // presentation timestamp in seconds (ptsInTimescales / timescale) + uint64_t ptsInTimescales; // presentation timestamp in "timescales" + double duration; // in seconds (durationInTimescales / timescale) + uint64_t durationInTimescales; // duration in "timescales" +} avifImageTiming; + +typedef enum avifProgressiveState { + // The current AVIF/Source does not offer a progressive image. This will always be the state + // for an image sequence. + AVIF_PROGRESSIVE_STATE_UNAVAILABLE = 0, + + // The current AVIF/Source offers a progressive image, but avifDecoder.allowProgressive is not + // enabled, so it will behave as if the image was not progressive and will simply decode the + // best version of this item. + AVIF_PROGRESSIVE_STATE_AVAILABLE, + + // The current AVIF/Source offers a progressive image, and avifDecoder.allowProgressive is true. + // In this state, avifDecoder.imageCount will be the count of all of the available progressive + // layers, and any specific layer can be decoded using avifDecoderNthImage() as if it was an + // image sequence, or simply using repeated calls to avifDecoderNextImage() to decode better and + // better versions of this image. + AVIF_PROGRESSIVE_STATE_ACTIVE +} avifProgressiveState; +AVIF_API const char* avifProgressiveStateToString(avifProgressiveState progressiveState); + +typedef struct avifDecoder { + // -------------------------------------------------------------------------------------------- + // Inputs + + // Defaults to AVIF_CODEC_CHOICE_AUTO: Preference determined by order in availableCodecs table (avif.c) + avifCodecChoice codecChoice; + + // Defaults to 1. -- NOTE: Please see the "Understanding maxThreads" comment block above + int maxThreads; + + // avifs can have multiple sets of images in them. This specifies which to decode. + // Set this via avifDecoderSetSource(). + avifDecoderSource requestedSource; + + // If this is true and a progressive AVIF is decoded, avifDecoder will behave as if the AVIF is + // an image sequence, in that it will set imageCount to the number of progressive frames + // available, and avifDecoderNextImage()/avifDecoderNthImage() will allow for specific layers + // of a progressive image to be decoded. To distinguish between a progressive AVIF and an AVIF + // image sequence, inspect avifDecoder.progressiveState. + avifBool allowProgressive; + + // Enable any of these to avoid reading and surfacing specific data to the decoded avifImage. + // These can be useful if your avifIO implementation heavily uses AVIF_RESULT_WAITING_ON_IO for + // streaming data, as some of these payloads are (unfortunately) packed at the end of the file, + // which will cause avifDecoderParse() to return AVIF_RESULT_WAITING_ON_IO until it finds them. + // If you don't actually leverage this data, it is best to ignore it here. + avifBool ignoreExif; + avifBool ignoreXMP; + + // This represents the maximum size of a image (in pixel count) that libavif and the underlying + // AV1 decoder should attempt to decode. It defaults to AVIF_DEFAULT_IMAGE_SIZE_LIMIT, and can be + // set to a smaller value. The value 0 is reserved. + // Note: Only some underlying AV1 codecs support a configurable size limit (such as dav1d). + uint32_t imageSizeLimit; + + // This provides an upper bound on how many images the decoder is willing to attempt to decode, + // to provide a bit of protection from malicious or malformed AVIFs citing millions upon + // millions of frames, only to be invalid later. The default is AVIF_DEFAULT_IMAGE_COUNT_LIMIT + // (see comment above), and setting this to 0 disables the limit. + uint32_t imageCountLimit; + + // Strict flags. Defaults to AVIF_STRICT_ENABLED. See avifStrictFlag definitions above. + avifStrictFlags strictFlags; + + // -------------------------------------------------------------------------------------------- + // Outputs + + // All decoded image data; owned by the decoder. All information in this image is incrementally + // added and updated as avifDecoder*() functions are called. After a successful call to + // avifDecoderParse(), all values in decoder->image (other than the planes/rowBytes themselves) + // will be pre-populated with all information found in the outer AVIF container, prior to any + // AV1 decoding. If the contents of the inner AV1 payload disagree with the outer container, + // these values may change after calls to avifDecoderRead*(),avifDecoderNextImage(), or + // avifDecoderNthImage(). + // + // The YUV and A contents of this image are likely owned by the decoder, so be sure to copy any + // data inside of this image before advancing to the next image or reusing the decoder. It is + // legal to call avifImageYUVToRGB() on this in between calls to avifDecoderNextImage(), but use + // avifImageCopy() if you want to make a complete, permanent copy of this image's YUV content or + // metadata. + avifImage* image; + + // Counts and timing for the current image in an image sequence. Uninteresting for single image files. + int imageIndex; // 0-based + int imageCount; // Always 1 for non-progressive, non-sequence AVIFs. + avifProgressiveState progressiveState; // See avifProgressiveState declaration + avifImageTiming imageTiming; // + uint64_t timescale; // timescale of the media (Hz) + double duration; // in seconds (durationInTimescales / timescale) + uint64_t durationInTimescales; // duration in "timescales" + + // This is true when avifDecoderParse() detects an alpha plane. Use this to find out if alpha is + // present after a successful call to avifDecoderParse(), but prior to any call to + // avifDecoderNextImage() or avifDecoderNthImage(), as decoder->image->alphaPlane won't exist yet. + avifBool alphaPresent; + + // stats from the most recent read, possibly 0s if reading an image sequence + avifIOStats ioStats; + + // Additional diagnostics (such as detailed error state) + avifDiagnostics diag; + + // -------------------------------------------------------------------------------------------- + // Internals + + // Use one of the avifDecoderSetIO*() functions to set this + avifIO* io; + + // Internals used by the decoder + struct avifDecoderData* data; +} avifDecoder; + +AVIF_API avifDecoder* avifDecoderCreate(void); +AVIF_API void avifDecoderDestroy(avifDecoder* decoder); + +// Simple interfaces to decode a single image, independent of the decoder afterwards (decoder may be destroyed). +AVIF_API avifResult avifDecoderRead(avifDecoder* decoder, avifImage* image); // call avifDecoderSetIO*() first +AVIF_API avifResult avifDecoderReadMemory(avifDecoder* decoder, avifImage* image, const uint8_t* data, size_t size); +AVIF_API avifResult avifDecoderReadFile(avifDecoder* decoder, avifImage* image, const char* filename); + +// Multi-function alternative to avifDecoderRead() for image sequences and gaining direct access +// to the decoder's YUV buffers (for performance's sake). Data passed into avifDecoderParse() is NOT +// copied, so it must continue to exist until the decoder is destroyed. +// +// Usage / function call order is: +// * avifDecoderCreate() +// * avifDecoderSetSource() - optional, the default (AVIF_DECODER_SOURCE_AUTO) is usually sufficient +// * avifDecoderSetIO*() +// * avifDecoderParse() +// * avifDecoderNextImage() - in a loop, using decoder->image after each successful call +// * avifDecoderDestroy() +// +// NOTE: Until avifDecoderParse() returns AVIF_RESULT_OK, no data in avifDecoder should +// be considered valid, and no queries (such as Keyframe/Timing/MaxExtent) should be made. +// +// You can use avifDecoderReset() any time after a successful call to avifDecoderParse() +// to reset the internal decoder back to before the first frame. Calling either +// avifDecoderSetSource() or avifDecoderParse() will automatically Reset the decoder. +// +// avifDecoderSetSource() allows you not only to choose whether to parse tracks or +// items in a file containing both, but switch between sources without having to +// Parse again. Normally AVIF_DECODER_SOURCE_AUTO is enough for the common path. +AVIF_API avifResult avifDecoderSetSource(avifDecoder* decoder, avifDecoderSource source); +// Note: When avifDecoderSetIO() is called, whether 'decoder' takes ownership of 'io' depends on +// whether io->destroy is set. avifDecoderDestroy(decoder) calls avifIODestroy(io), which calls +// io->destroy(io) if io->destroy is set. Therefore, if io->destroy is not set, then +// avifDecoderDestroy(decoder) has no effects on 'io'. +AVIF_API void avifDecoderSetIO(avifDecoder* decoder, avifIO* io); +AVIF_API avifResult avifDecoderSetIOMemory(avifDecoder* decoder, const uint8_t* data, size_t size); +AVIF_API avifResult avifDecoderSetIOFile(avifDecoder* decoder, const char* filename); +AVIF_API avifResult avifDecoderParse(avifDecoder* decoder); +AVIF_API avifResult avifDecoderNextImage(avifDecoder* decoder); +AVIF_API avifResult avifDecoderNthImage(avifDecoder* decoder, uint32_t frameIndex); +AVIF_API avifResult avifDecoderReset(avifDecoder* decoder); + +// Keyframe information +// frameIndex - 0-based, matching avifDecoder->imageIndex, bound by avifDecoder->imageCount +// "nearest" keyframe means the keyframe prior to this frame index (returns frameIndex if it is a keyframe) +// These functions may be used after a successful call (AVIF_RESULT_OK) to avifDecoderParse(). +AVIF_API avifBool avifDecoderIsKeyframe(const avifDecoder* decoder, uint32_t frameIndex); +AVIF_API uint32_t avifDecoderNearestKeyframe(const avifDecoder* decoder, uint32_t frameIndex); + +// Timing helper - This does not change the current image or invoke the codec (safe to call repeatedly) +// This function may be used after a successful call (AVIF_RESULT_OK) to avifDecoderParse(). +AVIF_API avifResult avifDecoderNthImageTiming(const avifDecoder* decoder, uint32_t frameIndex, avifImageTiming* outTiming); + +// --------------------------------------------------------------------------- +// avifExtent + +typedef struct avifExtent { + uint64_t offset; + size_t size; +} avifExtent; + +// Streaming data helper - Use this to calculate the maximal AVIF data extent encompassing all AV1 +// sample data needed to decode the Nth image. The offset will be the earliest offset of all +// required AV1 extents for this frame, and the size will create a range including the last byte of +// the last AV1 sample needed. Note that this extent may include non-sample data, as a frame's +// sample data may be broken into multiple extents and interleaved with other data, or in +// non-sequential order. This extent will also encompass all AV1 samples that this frame's sample +// depends on to decode (such as samples for reference frames), from the nearest keyframe up to this +// Nth frame. +// +// If avifDecoderNthImageMaxExtent() returns AVIF_RESULT_OK and the extent's size is 0 bytes, this +// signals that libavif doesn't expect to call avifIO's Read for this frame's decode. This happens if +// data for this frame was read as a part of avifDecoderParse() (typically in an idat box inside of +// a meta box). +// +// This function may be used after a successful call (AVIF_RESULT_OK) to avifDecoderParse(). +AVIF_API avifResult avifDecoderNthImageMaxExtent(const avifDecoder* decoder, uint32_t frameIndex, avifExtent* outExtent); + +// --------------------------------------------------------------------------- +// avifEncoder + +struct avifEncoderData; +struct avifCodecSpecificOptions; + +// Notes: +// * If avifEncoderWrite() returns AVIF_RESULT_OK, output must be freed with avifRWDataFree() +// * If (maxThreads < 2), multithreading is disabled +// * NOTE: Please see the "Understanding maxThreads" comment block above +// * Quality range: [AVIF_QUANTIZER_BEST_QUALITY - AVIF_QUANTIZER_WORST_QUALITY] +// * To enable tiling, set tileRowsLog2 > 0 and/or tileColsLog2 > 0. +// Tiling values range [0-6], where the value indicates a request for 2^n tiles in that dimension. +// * Speed range: [AVIF_SPEED_SLOWEST - AVIF_SPEED_FASTEST]. Slower should make for a better quality +// image in less bytes. AVIF_SPEED_DEFAULT means "Leave the AV1 codec to its default speed settings"./ +// If avifEncoder uses rav1e, the speed value is directly passed through (0-10). If libaom is used, +// a combination of settings are tweaked to simulate this speed range. +typedef struct avifEncoder { + // Defaults to AVIF_CODEC_CHOICE_AUTO: Preference determined by order in availableCodecs table (avif.c) + avifCodecChoice codecChoice; + + // settings (see Notes above) + int maxThreads; + int minQuantizer; + int maxQuantizer; + int minQuantizerAlpha; + int maxQuantizerAlpha; + int tileRowsLog2; + int tileColsLog2; + int speed; + int keyframeInterval; // How many frames between automatic forced keyframes; 0 to disable (default). + uint64_t timescale; // timescale of the media (Hz) + + // stats from the most recent write + avifIOStats ioStats; + + // Additional diagnostics (such as detailed error state) + avifDiagnostics diag; + + // Internals used by the encoder + struct avifEncoderData* data; + struct avifCodecSpecificOptions* csOptions; +} avifEncoder; + +AVIF_API avifEncoder* avifEncoderCreate(void); +AVIF_API avifResult avifEncoderWrite(avifEncoder* encoder, const avifImage* image, avifRWData* output); +AVIF_API void avifEncoderDestroy(avifEncoder* encoder); + +typedef enum avifAddImageFlag { + AVIF_ADD_IMAGE_FLAG_NONE = 0, + + // Force this frame to be a keyframe (sync frame). + AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME = (1 << 0), + + // Use this flag when encoding a single image. Signals "still_picture" to AV1 encoders, which + // tweaks various compression rules. This is enabled automatically when using the + // avifEncoderWrite() single-image encode path. + AVIF_ADD_IMAGE_FLAG_SINGLE = (1 << 1) +} avifAddImageFlag; +typedef uint32_t avifAddImageFlags; + +// Multi-function alternative to avifEncoderWrite() for image sequences. +// +// Usage / function call order is: +// * avifEncoderCreate() +// * Set encoder->timescale (Hz) correctly +// * avifEncoderAddImage() ... [repeatedly; at least once] +// OR +// * avifEncoderAddImageGrid() [exactly once, AVIF_ADD_IMAGE_FLAG_SINGLE is assumed] +// * avifEncoderFinish() +// * avifEncoderDestroy() +// + +AVIF_API avifResult avifEncoderAddImage(avifEncoder* encoder, const avifImage* image, uint64_t durationInTimescales, avifAddImageFlags addImageFlags); +AVIF_API avifResult avifEncoderAddImageGrid(avifEncoder* encoder, + uint32_t gridCols, + uint32_t gridRows, + const avifImage* const* cellImages, + avifAddImageFlags addImageFlags); +AVIF_API avifResult avifEncoderFinish(avifEncoder* encoder, avifRWData* output); + +// Codec-specific, optional "advanced" tuning settings, in the form of string key/value pairs. These +// should be set as early as possible, preferably just after creating avifEncoder but before +// performing any other actions. +// key must be non-NULL, but passing a NULL value will delete that key, if it exists. +// Setting an incorrect or unknown option for the current codec will cause errors of type +// AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION from avifEncoderWrite() or avifEncoderAddImage(). +AVIF_API void avifEncoderSetCodecSpecificOption(avifEncoder* encoder, const char* key, const char* value); + +// Helpers +AVIF_API avifBool avifImageUsesU16(const avifImage* image); + +// Returns AVIF_TRUE if input begins with a valid FileTypeBox (ftyp) that supports +// either the brand 'avif' or 'avis' (or both), without performing any allocations. +AVIF_API avifBool avifPeekCompatibleFileType(const avifROData* input); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // ifndef AVIF_AVIF_H diff --git a/ThirdParty/avif/lib/libaom.a b/ThirdParty/avif/lib/libaom.a new file mode 100644 index 000000000..334643df1 Binary files /dev/null and b/ThirdParty/avif/lib/libaom.a differ diff --git a/ThirdParty/avif/lib/libavif.a b/ThirdParty/avif/lib/libavif.a new file mode 100644 index 000000000..97efb1b8b Binary files /dev/null and b/ThirdParty/avif/lib/libavif.a differ diff --git a/ThirdParty/avif/source/AVIFDecoder.h b/ThirdParty/avif/source/AVIFDecoder.h new file mode 100644 index 000000000..87b9d3c18 --- /dev/null +++ b/ThirdParty/avif/source/AVIFDecoder.h @@ -0,0 +1,21 @@ +// +// AVIFDecoder.h +// AVIFQuickLook +// +// Created by lizhuoli on 2019/4/15. +// Copyright © 2019 dreampiggy. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AVIFDecoder : NSObject + ++ (nullable CGImageRef)createAVIFImageAtPath:(nonnull NSString *)path CF_RETURNS_RETAINED; ++ (nullable CGImageRef)createAVIFImageWithData:(nonnull NSData *)data CF_RETURNS_RETAINED; ++ (BOOL)isAVIFFormatForData:(nullable NSData *)data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ThirdParty/avif/source/AVIFDecoder.m b/ThirdParty/avif/source/AVIFDecoder.m new file mode 100644 index 000000000..e5eae94b9 --- /dev/null +++ b/ThirdParty/avif/source/AVIFDecoder.m @@ -0,0 +1,131 @@ +// +// AVIFDecoder.m +// AVIFQuickLook +// +// Created by lizhuoli on 2019/4/15. +// Copyright © 2019 dreampiggy. All rights reserved. +// + +#import "AVIFDecoder.h" +#import +#import +#import + +// Convert 8/10/12bit AVIF image into RGBA8888 +static void ConvertAvifImagePlanarToRGB(avifImage *avif, uint8_t *outPixels) { + BOOL hasAlpha = avif->alphaPlane != NULL; + avifRGBImage avifRgb = {0}; + avifRGBImageSetDefaults(&avifRgb, avif); + avifRgb.format = hasAlpha ? AVIF_RGB_FORMAT_RGBA : AVIF_RGB_FORMAT_RGB; + avifRgb.depth = 8; + avifRgb.rowBytes = avif->width * avifRGBImagePixelSize(&avifRgb); + avifRgb.pixels = malloc(avifRgb.rowBytes * avifRgb.height); + if(avifRgb.pixels) { + size_t components = hasAlpha ? 4 : 3; + avifImageYUVToRGB(avif, &avifRgb); + for(int j = 0; j < avifRgb.height; ++j) { + for(int i = 0; i < avifRgb.width; ++i) { + uint8_t *pixel = &outPixels[components * (i + (j * avifRgb.width))]; + pixel[0] = avifRgb.pixels[i * components + (j * avifRgb.rowBytes) + 0]; + pixel[1] = avifRgb.pixels[i * components + (j * avifRgb.rowBytes) + 1]; + pixel[2] = avifRgb.pixels[i * components + (j * avifRgb.rowBytes) + 2]; + if(hasAlpha) { + pixel[3] = avifRgb.pixels[i * components + (j * avifRgb.rowBytes) + 3]; + } + } + } + free(avifRgb.pixels); + } +} + +static void FreeImageData(void *info, const void *data, size_t size) { + free((void *)data); +} + +@implementation AVIFDecoder + ++ (nullable CGImageRef)createAVIFImageAtPath:(nonnull NSString *)path { + NSData *data = [NSData dataWithContentsOfFile:path]; + if(!data) { + return nil; + } + if(![AVIFDecoder isAVIFFormatForData:data]) { + return nil; + } + + return [AVIFDecoder createAVIFImageWithData:data]; +} + ++ (nullable CGImageRef)createAVIFImageWithData:(nonnull NSData *)data CF_RETURNS_RETAINED { + // Decode it + avifDecoder *decoder = avifDecoderCreate(); + avifImage *avif = avifImageCreateEmpty(); + avifResult result = avifDecoderReadMemory(decoder, avif, [data bytes], [data length]); + if(result != AVIF_RESULT_OK) { + avifImageDestroy(avif); + avifDecoderDestroy(decoder); + return nil; + } + + int width = avif->width; + int height = avif->height; + BOOL hasAlpha = avif->alphaPlane != NULL; + size_t components = hasAlpha ? 4 : 3; + size_t bitsPerComponent = 8; + size_t bitsPerPixel = components * bitsPerComponent; + size_t rowBytes = width * bitsPerPixel / 8; + + uint8_t *dest = calloc(width * components * height, sizeof(uint8_t)); + if(!dest) { + avifImageDestroy(avif); + avifDecoderDestroy(decoder); + return nil; + } + // convert planar to RGB888/RGBA8888 + ConvertAvifImagePlanarToRGB(avif, dest); + + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, dest, rowBytes * height, FreeImageData); + CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; + bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone; + CGColorSpaceRef colorSpaceRef = [self colorSpaceGetDeviceRGB]; + CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; + CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, rowBytes, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); + + // clean up + CGDataProviderRelease(provider); + avifImageDestroy(avif); + avifDecoderDestroy(decoder); + + return imageRef; +} + +#pragma mark - Helper ++ (BOOL)isAVIFFormatForData:(nullable NSData *)data { + if(!data) { + return NO; + } + if(data.length >= 12) { + //....ftypavif ....ftypavis + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; + if([testString isEqualToString:@"ftypavif"] || [testString isEqualToString:@"ftypavis"]) { + return YES; + } + } + + return NO; +} + ++ (CGColorSpaceRef)colorSpaceGetDeviceRGB { + CGColorSpaceRef screenColorSpace = NSScreen.mainScreen.colorSpace.CGColorSpace; + if(screenColorSpace) { + return screenColorSpace; + } + static CGColorSpaceRef colorSpace; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + colorSpace = CGColorSpaceCreateDeviceRGB(); + }); + return colorSpace; +} + +@end