encoders/aom-av1: AV1 encoder based on libaom

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2021-08-28 14:36:42 +02:00
parent bb58424b22
commit 9a4ab558c0
9 changed files with 2120 additions and 8 deletions

View file

@ -83,14 +83,15 @@ jobs:
sudo apt-get purge libjpeg9-dev:amd64 libjpeg8-dev:amd64 libjpeg-turbo8-dev:amd64 sudo apt-get purge libjpeg9-dev:amd64 libjpeg8-dev:amd64 libjpeg-turbo8-dev:amd64
sudo apt-get install \ sudo apt-get install \
build-essential \ build-essential \
checkinstall \
pkg-config \
cmake \ cmake \
ninja-build \ ninja-build \
git \ git \
gcc-9 g++9 \
qt5-default libqwt-qt5-dev libqt5svg5-dev \ qt5-default libqwt-qt5-dev libqt5svg5-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \ libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \
libcurl4-openssl-dev \ libcurl4-openssl-dev
gcc-9 g++9 \
checkinstall pkg-config
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 800 --slave /usr/bin/g++ g++ /usr/bin/g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 800 --slave /usr/bin/g++ g++ /usr/bin/g++-9
- name: "libobs: Cache" - name: "libobs: Cache"

View file

@ -14,6 +14,7 @@ env:
QT_VERSION: "5.15.2" QT_VERSION: "5.15.2"
OBS_VERSION: "27.0.0-ci" OBS_VERSION: "27.0.0-ci"
OBSDEPS_VERSION: "27.0.0" OBSDEPS_VERSION: "27.0.0"
LIBAOM_VERSION: "3.1.2.115"
jobs: jobs:
windows: windows:
@ -64,6 +65,20 @@ jobs:
build/temp/qt-build build/temp/qt-build
build/temp/qt-src build/temp/qt-src
key: qt-${{ matrix.id }}-${{ env.OBSDEPS_VERSION }}-${{ env.QT_VERSION }}-${{ secrets.CACHE_VERSION }} key: qt-${{ matrix.id }}-${{ env.OBSDEPS_VERSION }}-${{ env.QT_VERSION }}-${{ secrets.CACHE_VERSION }}
- name: "libaom: Cache"
uses: actions/cache@v2
id: libaom-cache
with:
path: |
build/libaom
key: libaom-${{ matrix.id }}-${{ env.LIBAOM_VERSION }}-${{ secrets.CACHE_VERSION }}
- name: "libaom: Install"
if: "steps.libaom-cache.outputs.cache-hit != 'true'"
id: libaom-install
shell: bash
run: |
curl -L -o "aom.7z" "https://github.com/Xaymar/aom/releases/download/v${{ env.LIBAOM_VERSION }}/aom-windows-64-shared.7z"
7z x -o"build/libaom/" "aom.7z"
- name: "StreamFX: Configure" - name: "StreamFX: Configure"
shell: bash shell: bash
run: | run: |
@ -72,13 +87,14 @@ jobs:
-DCMAKE_INSTALL_PREFIX="build/distrib" \ -DCMAKE_INSTALL_PREFIX="build/distrib" \
-DPACKAGE_NAME="streamfx-${{ matrix.id }}" \ -DPACKAGE_NAME="streamfx-${{ matrix.id }}" \
-DPACKAGE_PREFIX="build/package" \ -DPACKAGE_PREFIX="build/package" \
-DDOWNLOAD_QT=ON \
-DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-windows-x86-64.7z" \ -DDOWNLOAD_OBS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBS_VERSION }}/obs-studio-x64-0.0.0.0-windows-x86-64.7z" \
-DDOWNLOAD_OBS_HASH="SHA256=EBF9853C8A553E16ECBCA22523F401E6CF1EB2E8DA93F1493FEF41D65BD06633" \ -DDOWNLOAD_OBS_HASH="SHA256=EBF9853C8A553E16ECBCA22523F401E6CF1EB2E8DA93F1493FEF41D65BD06633" \
-DDOWNLOAD_OBSDEPS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/deps-windows-x86.7z" \ -DDOWNLOAD_OBSDEPS_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/deps-windows-x86.7z" \
-DDOWNLOAD_OBSDEPS_HASH="SHA256=B4AED165016F0B64A7E8B256CCC12EAF8AF087F61B0B239B9D3D00277485B5B5" \ -DDOWNLOAD_OBSDEPS_HASH="SHA256=B4AED165016F0B64A7E8B256CCC12EAF8AF087F61B0B239B9D3D00277485B5B5" \
-DDOWNLOAD_QT=ON \
-DDOWNLOAD_QT_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/qt-${{ env.QT_VERSION }}-windows-x86-64.7z" \ -DDOWNLOAD_QT_URL="https://github.com/Xaymar/obs-studio/releases/download/${{ env.OBSDEPS_VERSION }}/qt-${{ env.QT_VERSION }}-windows-x86-64.7z" \
-DDOWNLOAD_QT_HASH="SHA256=109B9C21EF165B0C46DFAA9AD23124F2070ED4D74207C4AFB308183CB8D43BDD" -DDOWNLOAD_QT_HASH="SHA256=109B9C21EF165B0C46DFAA9AD23124F2070ED4D74207C4AFB308183CB8D43BDD" \
-DAOM_PATH="build/libaom/"
- name: "StreamFX: Build" - name: "StreamFX: Build"
shell: bash shell: bash
run: | run: |
@ -101,6 +117,7 @@ jobs:
with: with:
name: ${{ matrix.id }} name: ${{ matrix.id }}
path: build/package path: build/package
ubuntu: ubuntu:
name: "Ubuntu 64-bit" name: "Ubuntu 64-bit"
strategy: strategy:
@ -142,14 +159,15 @@ jobs:
sudo apt-get purge libjpeg9-dev:amd64 libjpeg8-dev:amd64 libjpeg-turbo8-dev:amd64 sudo apt-get purge libjpeg9-dev:amd64 libjpeg8-dev:amd64 libjpeg-turbo8-dev:amd64
sudo apt-get install \ sudo apt-get install \
build-essential \ build-essential \
checkinstall \
pkg-config \
cmake \ cmake \
ninja-build \ ninja-build \
git \ git \
${{ matrix.packages }} \
qt5-default libqwt-qt5-dev libqt5svg5-dev \ qt5-default libqwt-qt5-dev libqt5svg5-dev \
libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \ libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev \
libcurl4-openssl-dev \ libcurl4-openssl-dev
${{ matrix.packages }} \
checkinstall pkg-config
${{ matrix.extra_command }} ${{ matrix.extra_command }}
- name: "libobs: Cache" - name: "libobs: Cache"
uses: actions/cache@v2 uses: actions/cache@v2
@ -185,6 +203,7 @@ jobs:
with: with:
name: ${{ matrix.id }} name: ${{ matrix.id }}
path: build/package path: build/package
macos: macos:
strategy: strategy:
fail-fast: true fail-fast: true

View file

@ -294,6 +294,7 @@ set(${PREFIX}ENABLE_ENCODER_FFMPEG ON CACHE BOOL "Enable FFmpeg Encoder integrat
set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ON CACHE BOOL "Enable AMF Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ON CACHE BOOL "Enable AMF Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ON CACHE BOOL "Enable NVENC Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ON CACHE BOOL "Enable NVENC Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ON CACHE BOOL "Enable ProRes Encoder in FFmpeg.") set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ON CACHE BOOL "Enable ProRes Encoder in FFmpeg.")
set(${PREFIX}ENABLE_ENCODER_AOM_AV1 ON CACHE BOOL "Enable AOM AV1 Encoder.")
## Filters ## Filters
set(${PREFIX}ENABLE_FILTER_BLUR ON CACHE BOOL "Enable Blur Filter") set(${PREFIX}ENABLE_FILTER_BLUR ON CACHE BOOL "Enable Blur Filter")
@ -636,6 +637,18 @@ function(feature_encoder_ffmpeg RESOLVE)
endif() endif()
endfunction() endfunction()
function(feature_encoder_aom_av1 RESOLVE)
is_feature_enabled(ENCODER_AOM_AV1 T_CHECK)
if(RESOLVE AND T_CHECK)
if(NOT HAVE_AOM)
message(WARNING "${LOGPREFIX}: AOM AV1 encoder missing AOM library. Disabling...")
set_feature_disabled(ENCODER_AOM_AV1 ON)
endif()
elseif(T_CHECK)
set(REQUIRE_AOM ON PARENT_SCOPE)
endif()
endfunction()
function(feature_filter_blur RESOLVE) function(feature_filter_blur RESOLVE)
is_feature_enabled(FILTER_BLUR T_CHECK) is_feature_enabled(FILTER_BLUR T_CHECK)
endfunction() endfunction()
@ -749,6 +762,7 @@ endfunction()
# Set Requirements # Set Requirements
feature_encoder_ffmpeg(OFF) feature_encoder_ffmpeg(OFF)
feature_encoder_aom_av1(OFF)
feature_filter_blur(OFF) feature_filter_blur(OFF)
feature_filter_color_grade(OFF) feature_filter_color_grade(OFF)
feature_filter_displacement(OFF) feature_filter_displacement(OFF)
@ -821,6 +835,15 @@ if(REQUIRE_FFMPEG)
set(HAVE_FFMPEG ${FFmpeg_FOUND}) set(HAVE_FFMPEG ${FFmpeg_FOUND})
endif() endif()
#- AOM
set(HAVE_AOM OFF)
if(REQUIRE_AOM)
if(NOT D_PLATFORM_MAC)
find_package(AOM)
set(HAVE_AOM ${AOM_FOUND})
endif()
endif()
#- JSON #- JSON
set(HAVE_JSON OFF) set(HAVE_JSON OFF)
if(REQUIRE_JSON) if(REQUIRE_JSON)
@ -894,6 +917,7 @@ endif()
# Verify Requirements # Verify Requirements
feature_encoder_ffmpeg(ON) feature_encoder_ffmpeg(ON)
feature_encoder_aom_av1(ON)
feature_filter_blur(ON) feature_filter_blur(ON)
feature_filter_color_grade(ON) feature_filter_color_grade(ON)
feature_filter_displacement(ON) feature_filter_displacement(ON)
@ -1215,6 +1239,23 @@ if(T_CHECK)
endif() endif()
endif() endif()
# Encoder/AOM-AV1
is_feature_enabled(ENCODER_AOM_AV1 T_CHECK)
if(T_CHECK)
list (APPEND PROJECT_PRIVATE_SOURCE
"source/encoders/codecs/av1.hpp"
"source/encoders/codecs/av1.cpp"
"source/encoders/encoder-aom-av1.hpp"
"source/encoders/encoder-aom-av1.cpp"
)
list (APPEND PROJECT_INCLUDE_DIRS
${AOM_INCLUDE_DIR}
)
list(APPEND PROJECT_DEFINITIONS
ENABLE_ENCODER_AOM_AV1
)
endif()
# Filter/Blur # Filter/Blur
is_feature_enabled(FILTER_BLUR T_CHECK) is_feature_enabled(FILTER_BLUR T_CHECK)
if(T_CHECK) if(T_CHECK)
@ -1740,6 +1781,15 @@ endif()
if(${PREFIX}OBS_NATIVE) if(${PREFIX}OBS_NATIVE)
# Grouped builds don't offer standalone services. # Grouped builds don't offer standalone services.
install_obs_plugin_with_data(${PROJECT_NAME} data) install_obs_plugin_with_data(${PROJECT_NAME} data)
# Dependency: AOM
if(HAVE_AOM AND AOM_BINARY AND D_PLATFORM_WINDOWS)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"${AOM_BINARY}"
"${CMAKE_BINARY_DIR}/rundir/$<CONFIGURATION>/data/obs-plugins/${PROJECT_NAME}"
VERBATIM)
endif()
else() else()
if(STRUCTURE_UNIFIED) if(STRUCTURE_UNIFIED)
install( install(
@ -1764,6 +1814,14 @@ else()
OPTIONAL OPTIONAL
) )
endif() endif()
# Dependency: AOM
if(HAVE_AOM AND AOM_BINARY AND D_PLATFORM_WINDOWS)
install(
FILES ${AOM_BINARY}
DESTINATION "data/" COMPONENT StreamFX
)
endif()
elseif(D_PLATFORM_LINUX) elseif(D_PLATFORM_LINUX)
install( install(
TARGETS ${PROJECT_NAME} TARGETS ${PROJECT_NAME}
@ -1807,6 +1865,14 @@ else()
OPTIONAL OPTIONAL
) )
endif() endif()
# Dependency: AOM
if(HAVE_AOM AND AOM_BINARY AND D_PLATFORM_WINDOWS)
install(
FILES ${AOM_BINARY}
DESTINATION "data/obs-plugins/${PROJECT_NAME}/" COMPONENT StreamFX
)
endif()
elseif(D_PLATFORM_LINUX) elseif(D_PLATFORM_LINUX)
if(STRUCTURE_PACKAGEMANAGER) if(STRUCTURE_PACKAGEMANAGER)
install( install(

View file

@ -67,6 +67,66 @@ UI.Updater.Menu.Channel="Update Channel"
UI.Updater.Menu.Channel.Release="Release" UI.Updater.Menu.Channel.Release="Release"
UI.Updater.Menu.Channel.Testing="Testing" UI.Updater.Menu.Channel.Testing="Testing"
# Encoder/AOM-AV1
Encoder.AOM.AV1="AOM AV1 (direct)"
Encoder.AOM.AV1.Encoder="Encoder"
Encoder.AOM.AV1.Encoder.Usage="Usage"
Encoder.AOM.AV1.Encoder.Usage.GoodQuality="Good Quality"
Encoder.AOM.AV1.Encoder.Usage.RealTime="Real Time"
Encoder.AOM.AV1.Encoder.Usage.AllIntra="All Intra-Frame"
Encoder.AOM.AV1.Encoder.CPUUsage="CPU Usage"
Encoder.AOM.AV1.Encoder.CPUUsage.0="Placebo"
Encoder.AOM.AV1.Encoder.CPUUsage.1="Very Slow"
Encoder.AOM.AV1.Encoder.CPUUsage.2="Slower"
Encoder.AOM.AV1.Encoder.CPUUsage.3="Slow"
Encoder.AOM.AV1.Encoder.CPUUsage.4="Medium"
Encoder.AOM.AV1.Encoder.CPUUsage.5="Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.6="Faster"
Encoder.AOM.AV1.Encoder.CPUUsage.7="Very Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.8="Super Fast"
Encoder.AOM.AV1.Encoder.CPUUsage.9="Ultra Fast"
Encoder.AOM.AV1.Encoder.Profile="Profile"
Encoder.AOM.AV1.KeyFrames="Key-Frame"
Encoder.AOM.AV1.KeyFrames.IntervalType="Interval Type"
Encoder.AOM.AV1.KeyFrames.IntervalType.Frames="Frames"
Encoder.AOM.AV1.KeyFrames.IntervalType.Seconds="Seconds"
Encoder.AOM.AV1.KeyFrames.Interval="Interval"
Encoder.AOM.AV1.RateControl="Rate Control"
Encoder.AOM.AV1.RateControl.Mode="Mode"
Encoder.AOM.AV1.RateControl.Mode.CBR="Constant Bitrate (CBR)"
Encoder.AOM.AV1.RateControl.Mode.VBR="Variable Bitrate (VBR)"
Encoder.AOM.AV1.RateControl.Mode.CQ="Constrained Quality (CQ)"
Encoder.AOM.AV1.RateControl.Mode.Q="Constant Quality (Q)"
Encoder.AOM.AV1.RateControl.LookAhead="Look-Ahead"
Encoder.AOM.AV1.RateControl.Limits="Limits"
Encoder.AOM.AV1.RateControl.Limits.Bitrate="Bitrate"
Encoder.AOM.AV1.RateControl.Limits.Bitrate.Undershoot="Bitrate Undershoot"
Encoder.AOM.AV1.RateControl.Limits.Bitrate.Overshoot="Bitrate Overshoot"
Encoder.AOM.AV1.RateControl.Limits.Quality="Quality"
Encoder.AOM.AV1.RateControl.Limits.Quantizer.Minimum="Minimum Quantizer"
Encoder.AOM.AV1.RateControl.Limits.Quantizer.Maximum="Maximum Quantizer"
Encoder.AOM.AV1.RateControl.Buffer="Buffer"
Encoder.AOM.AV1.RateControl.Buffer.Size="Size"
Encoder.AOM.AV1.RateControl.Buffer.Size.Initial="Initial Size"
Encoder.AOM.AV1.RateControl.Buffer.Size.Optimal="Optimal Size"
Encoder.AOM.AV1.Advanced="Advanced"
Encoder.AOM.AV1.Advanced.Threads="Threads"
Encoder.AOM.AV1.Advanced.RowMultiThreading="Per-Row Multi-Threading"
Encoder.AOM.AV1.Advanced.Tile.Columns="Tile Columns"
Encoder.AOM.AV1.Advanced.Tile.Rows="Tile Rows"
Encoder.AOM.AV1.Advanced.Tune="Tune"
Encoder.AOM.AV1.Advanced.Tune.Metric="Metric"
Encoder.AOM.AV1.Advanced.Tune.Metric.PSNR="PSNR"
Encoder.AOM.AV1.Advanced.Tune.Metric.SSIM="SSIM"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithPreprocessing="VMAF (with pre-processing)"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.WithoutPreprocessing="VMAF (without pre-processing)"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.MaxGain="VMAF (NegMaxGain)"
Encoder.AOM.AV1.Advanced.Tune.Metric.VMAF.NegMaxGain="VMAF (MaxGain)"
Encoder.AOM.AV1.Advanced.Tune.Metric.Butteraugli="Butteraugli"
Encoder.AOM.AV1.Advanced.Tune.Content="Content"
Encoder.AOM.AV1.Advanced.Tune.Content.Screen="Screen"
Encoder.AOM.AV1.Advanced.Tune.Content.Film="Film"
# Blur # Blur
Blur.Type.Box="Box" Blur.Type.Box="Box"
Blur.Type.BoxLinear="Box Linear" Blur.Type.BoxLinear="Box Linear"
@ -299,6 +359,13 @@ Source.Mirror.Source.Audio.Layout.QuadraphonicLFE="Quadraphonic With LFE"
Source.Mirror.Source.Audio.Layout.Surround="Surround" Source.Mirror.Source.Audio.Layout.Surround="Surround"
Source.Mirror.Source.Audio.Layout.FullSurround="Full Surround" Source.Mirror.Source.Audio.Layout.FullSurround="Full Surround"
# Codec: AV1
Codec.AV1="AV1"
Codec.AV1.Profile="Profile"
Codec.AV1.Profile.Main="Main"
Codec.AV1.Profile.High="High"
Codec.AV1.Profile.Professional="Professional"
# Codec: H264 # Codec: H264
Codec.H264="H264" Codec.H264="H264"
Codec.H264.Profile="Profile" Codec.H264.Profile="Profile"

View file

@ -0,0 +1,35 @@
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "av1.hpp"
const char* streamfx::encoder::codec::av1::profile_to_string(profile p)
{
switch (p) {
case profile::MAIN:
return D_TRANSLATE(S_CODEC_AV1_PROFILE ".Main");
case profile::HIGH:
return D_TRANSLATE(S_CODEC_AV1_PROFILE ".High");
case profile::PROFESSIONAL:
return D_TRANSLATE(S_CODEC_AV1_PROFILE ".Professional");
default:
return "Unknown";
}
}

View file

@ -0,0 +1,36 @@
// Copyright (c) 2019 Michael Fabian Dirks <info@xaymar.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include "common.hpp"
#define S_CODEC_AV1 "Codec.AV1"
#define S_CODEC_AV1_PROFILE "Codec.AV1.Profile"
namespace streamfx::encoder::codec::av1 {
enum class profile {
MAIN = 0,
HIGH = 1,
PROFESSIONAL = 2,
UNKNOWN = -1,
};
const char* profile_to_string(profile p);
} // namespace streamfx::encoder::codec::av1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,196 @@
// Copyright (c) 2021 Michael Fabian Dirks <info@xaymar.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include "common.hpp"
#include <memory>
#include <queue>
#include "encoders/codecs/av1.hpp"
#include "obs/obs-encoder-factory.hpp"
#include "util/util-library.hpp"
#include "util/util-profiler.hpp"
#include <aom/aomcx.h>
namespace streamfx::encoder::aom::av1 {
class aom_av1_factory;
class aom_av1_instance : public obs::encoder_instance {
std::shared_ptr<aom_av1_factory> _factory;
aom_codec_iface_t* _iface;
aom_codec_ctx_t _ctx;
aom_codec_enc_cfg_t _cfg;
size_t _image_index;
std::vector<aom_image_t> _images;
aom_fixed_buf_t* _global_headers;
bool _initialized;
struct {
// Video (All Static)
uint16_t width;
uint16_t height;
struct {
uint32_t num;
uint32_t den;
} fps;
// Color (All Static)
aom_img_fmt color_format;
aom_color_primaries_t color_primaries;
aom_transfer_characteristics_t color_trc;
aom_matrix_coefficients_t color_matrix;
aom_color_range_t color_range;
bool monochrome;
// Encoder
codec::av1::profile profile; // Static
int8_t preset;
// Rate Control
aom_rc_mode rc_mode; // Static
int8_t rc_lookahead; // Static
int32_t rc_bitrate;
int32_t rc_bitrate_overshoot;
int32_t rc_bitrate_undershoot;
int8_t rc_quality;
int8_t rc_quantizer_min;
int8_t rc_quantizer_max;
int32_t rc_buffer_ms;
int32_t rc_buffer_initial_ms;
int32_t rc_buffer_optimal_ms;
// Key-Frames
aom_kf_mode kf_mode;
int32_t kf_distance_min;
int32_t kf_distance_max;
// Threads and Tiling (All Static)
int8_t threads;
int8_t rowmultithreading;
int8_t tile_columns;
int8_t tile_rows;
aom_tune_metric tune_metric;
aom_tune_content tune_content;
} _settings;
#ifdef ENABLE_PROFILING
std::shared_ptr<streamfx::util::profiler> _profiler_copy;
std::shared_ptr<streamfx::util::profiler> _profiler_encode;
std::shared_ptr<streamfx::util::profiler> _profiler_packet;
#endif
public:
aom_av1_instance(obs_data_t* settings, obs_encoder_t* self, bool is_hw);
virtual ~aom_av1_instance();
virtual void migrate(obs_data_t* settings, uint64_t version);
virtual bool update(obs_data_t* settings);
void log();
virtual bool get_extra_data(uint8_t** extra_data, size_t* size);
virtual bool get_sei_data(uint8_t** sei_data, size_t* size);
virtual void get_video_info(struct video_scale_info* info);
virtual bool encode_video(encoder_frame* frame, encoder_packet* packet, bool* received_packet);
};
class aom_av1_factory : public obs::encoder_factory<aom_av1_factory, aom_av1_instance> {
std::shared_ptr<::streamfx::util::library> _library;
public:
aom_av1_factory();
~aom_av1_factory();
const char* get_name() override;
void* create(obs_data_t* settings, obs_encoder_t* encoder, bool is_hw) override;
void get_defaults2(obs_data_t* data) override;
obs_properties_t* get_properties2(instance_t* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public:
// aom_codec.h
decltype(&aom_codec_version) libaom_codec_version;
decltype(&aom_codec_version_str) libaom_codec_version_str;
decltype(&aom_codec_version_extra_str) libaom_codec_version_extra_str;
decltype(&aom_codec_build_config) libaom_codec_build_config;
decltype(&aom_codec_iface_name) libaom_codec_iface_name;
decltype(&aom_codec_err_to_string) libaom_codec_err_to_string;
decltype(&aom_codec_error) libaom_codec_error;
decltype(&aom_codec_error_detail) libaom_codec_error_detail;
decltype(&aom_codec_destroy) libaom_codec_destroy;
decltype(&aom_codec_get_caps) libaom_codec_get_caps;
decltype(&aom_codec_control) libaom_codec_control;
decltype(&aom_codec_set_option) libaom_codec_set_option;
decltype(&aom_obu_type_to_string) libaom_obu_type_to_string;
// aom_integer.h
decltype(&aom_uleb_size_in_bytes) libaom_uleb_size_in_bytes;
decltype(&aom_uleb_decode) libaom_uleb_decode;
decltype(&aom_uleb_encode) libaom_uleb_encode;
decltype(&aom_uleb_encode_fixed_size) libaom_uleb_encode_fixed_size;
// aom_image.h
decltype(&aom_img_alloc) libaom_img_alloc;
decltype(&aom_img_wrap) libaom_img_wrap;
decltype(&aom_img_alloc_with_border) libaom_img_alloc_with_border;
decltype(&aom_img_set_rect) libaom_img_set_rect;
decltype(&aom_img_flip) libaom_img_flip;
decltype(&aom_img_free) libaom_img_free;
decltype(&aom_img_plane_width) libaom_img_plane_width;
decltype(&aom_img_plane_height) libaom_img_plane_height;
decltype(&aom_img_add_metadata) libaom_img_add_metadata;
decltype(&aom_img_get_metadata) libaom_img_get_metadata;
decltype(&aom_img_num_metadata) libaom_img_num_metadata;
decltype(&aom_img_remove_metadata) libaom_img_remove_metadata;
decltype(&aom_img_metadata_alloc) libaom_img_metadata_alloc;
decltype(&aom_img_metadata_free) libaom_img_metadata_free;
// aom_encoder.h
decltype(&aom_codec_enc_init_ver) libaom_codec_enc_init_ver;
decltype(&aom_codec_enc_config_default) libaom_codec_enc_config_default;
decltype(&aom_codec_enc_config_set) libaom_codec_enc_config_set;
decltype(&aom_codec_get_global_headers) libaom_codec_get_global_headers;
decltype(&aom_codec_encode) libaom_codec_encode;
decltype(&aom_codec_set_cx_data_buf) libaom_codec_set_cx_data_buf;
decltype(&aom_codec_get_cx_data) libaom_codec_get_cx_data;
decltype(&aom_codec_get_preview_frame) libaom_codec_get_preview_frame;
// aomcx.h
decltype(&aom_codec_av1_cx) libaom_codec_av1_cx;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<aom_av1_factory> get();
};
} // namespace streamfx::encoder::aom::av1

View file

@ -28,6 +28,9 @@
#include "nvidia/cuda/nvidia-cuda-obs.hpp" #include "nvidia/cuda/nvidia-cuda-obs.hpp"
#endif #endif
#ifdef ENABLE_ENCODER_AOM_AV1
#include "encoders/encoder-aom-av1.hpp"
#endif
#ifdef ENABLE_ENCODER_FFMPEG #ifdef ENABLE_ENCODER_FFMPEG
#include "encoders/encoder-ffmpeg.hpp" #include "encoders/encoder-ffmpeg.hpp"
#endif #endif
@ -129,6 +132,9 @@ try {
// Encoders // Encoders
{ {
#ifdef ENABLE_ENCODER_AOM_AV1
streamfx::encoder::aom::av1::aom_av1_factory::initialize();
#endif
#ifdef ENABLE_ENCODER_FFMPEG #ifdef ENABLE_ENCODER_FFMPEG
using namespace streamfx::encoder::ffmpeg; using namespace streamfx::encoder::ffmpeg;
ffmpeg_manager::initialize(); ffmpeg_manager::initialize();
@ -259,6 +265,9 @@ try {
{ {
#ifdef ENABLE_ENCODER_FFMPEG #ifdef ENABLE_ENCODER_FFMPEG
streamfx::encoder::ffmpeg::ffmpeg_manager::finalize(); streamfx::encoder::ffmpeg::ffmpeg_manager::finalize();
#endif
#ifdef ENABLE_ENCODER_AOM_AV1
streamfx::encoder::aom::av1::aom_av1_factory::finalize();
#endif #endif
} }