Merge pull request #1943 from jazztickets/av1

AV1 export support
This commit is contained in:
itsmattkc
2023-02-08 13:03:51 -08:00
committed by GitHub
12 changed files with 246 additions and 22 deletions
+1 -1
View File
@@ -51,7 +51,7 @@ jobs:
${{ matrix.cmake-gen }}>
runs-on: ubuntu-latest
container:
image: olivevideoeditor/ci-olive:2022.2
image: olivevideoeditor/ci-olive:2022.3
steps:
- name: Checkout Source Code
+4
View File
@@ -64,6 +64,8 @@ QString ExportCodec::GetCodecName(ExportCodec::Codec c)
return tr("Vorbis");
case kCodecVP9:
return tr("VP9");
case kCodecAV1:
return tr("AV1");
case kCodecSRT:
return tr("SubRip SRT");
case kCodecCount:
@@ -90,6 +92,7 @@ bool ExportCodec::IsCodecAStillImage(ExportCodec::Codec c)
case kCodecOpus:
case kCodecFLAC:
case kCodecVP9:
case kCodecAV1:
case kCodecSRT:
return false;
case kCodecOpenEXR:
@@ -121,6 +124,7 @@ bool ExportCodec::IsCodecLossless(Codec c)
case kCodecVorbis:
case kCodecOpus:
case kCodecVP9:
case kCodecAV1:
case kCodecSRT:
case kCodecOpenEXR:
case kCodecPNG:
+1
View File
@@ -53,6 +53,7 @@ public:
kCodecVorbis,
kCodecFLAC,
kCodecSRT,
kCodecAV1,
kCodecCount
};
+2 -2
View File
@@ -123,7 +123,7 @@ QList<ExportCodec::Codec> ExportFormat::GetVideoCodecs(ExportFormat::Format f)
case kFormatQuickTime:
return {ExportCodec::kCodecH264, ExportCodec::kCodecH264rgb, ExportCodec::kCodecH265, ExportCodec::kCodecProRes, ExportCodec::kCodecCineform};
case kFormatWebM:
return {ExportCodec::kCodecVP9};
return {ExportCodec::kCodecAV1, ExportCodec::kCodecVP9};
case kFormatOgg:
case kFormatWAV:
case kFormatMPEG4Audio:
@@ -152,7 +152,7 @@ QList<ExportCodec::Codec> ExportFormat::GetAudioCodecs(ExportFormat::Format f)
case kFormatQuickTime:
return {ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM};
case kFormatWebM:
return {ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM, ExportCodec::kCodecVorbis, ExportCodec::kCodecOpus};
return {ExportCodec::kCodecOpus, ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM, ExportCodec::kCodecVorbis};
// Audio only formats
case kFormatWAV:
+6
View File
@@ -898,6 +898,12 @@ const AVCodec *FFmpegEncoder::GetEncoder(ExportCodec::Codec c, SampleFormat afor
return avcodec_find_encoder(AV_CODEC_ID_HEVC);
case ExportCodec::kCodecVP9:
return avcodec_find_encoder(AV_CODEC_ID_VP9);
case ExportCodec::kCodecAV1: {
const AVCodec *encoder = avcodec_find_encoder_by_name("libsvtav1");
if(!encoder)
encoder = avcodec_find_encoder(AV_CODEC_ID_AV1);
return encoder;
}
case ExportCodec::kCodecOpenEXR:
return avcodec_find_encoder(AV_CODEC_ID_EXR);
case ExportCodec::kCodecPNG:
+2
View File
@@ -16,6 +16,8 @@
set(OLIVE_SOURCES
${OLIVE_SOURCES}
dialog/export/codec/av1section.cpp
dialog/export/codec/av1section.h
dialog/export/codec/cineformsection.cpp
dialog/export/codec/cineformsection.h
dialog/export/codec/codecsection.cpp
+132
View File
@@ -0,0 +1,132 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "av1section.h"
#include <QCheckBox>
#include <QComboBox>
#include <QGridLayout>
#include <QLabel>
#include "common/qtutils.h"
#include "widget/slider/integerslider.h"
namespace olive {
AV1Section::AV1Section(QWidget *parent) :
AV1Section(AV1CRFSection::kDefaultAV1CRF, parent)
{
}
AV1Section::AV1Section(int default_crf, QWidget *parent) :
CodecSection(parent)
{
QGridLayout* layout = new QGridLayout(this);
layout->setMargin(0);
int row = 0;
layout->addWidget(new QLabel(tr("Preset:")), row, 0);
preset_combobox_ = new QComboBox();
preset_combobox_->setToolTip(tr("This parameter governs the efficiency/encode-time trade-off.\n"
"Lower presets will result in an output with better quality for a given file size, but will take longer to encode.\n"
"Higher presets can result in a very fast encode, but will make some compromises on visual quality for a given crf value."));
for (int i = 0; i <= 13; i++)
preset_combobox_->addItem(QString::number(i));
preset_combobox_->setCurrentIndex(8);
layout->addWidget(preset_combobox_, row, 1);
row++;
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
QComboBox* compression_box = new QComboBox();
compression_box->setToolTip(tr("This parameter governs the quality/size trade-off.\n"
"Higher CRF values will result in a final output that takes less space, but begins to lose detail.\n"
"Lower CRF values retain more detail at the cost of larger file sizes.\n"
"The possible range of CRF in SVT-AV1 is 1-63."));
// These items must correspond to the CompressionMethod enum
compression_box->addItem(tr("Constant Rate Factor"));
layout->addWidget(compression_box, row, 1);
row++;
compression_method_stack_ = new QStackedWidget();
layout->addWidget(compression_method_stack_, row, 0, 1, 2);
crf_section_ = new AV1CRFSection(default_crf);
compression_method_stack_->addWidget(crf_section_);
connect(compression_box,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
compression_method_stack_,
&QStackedWidget::setCurrentIndex);
}
void AV1Section::AddOpts(EncodingParams *params)
{
CompressionMethod method = static_cast<CompressionMethod>(compression_method_stack_->currentIndex());
if (method == kConstantRateFactor) {
// Set Quantizer value
params->set_video_option(QStringLiteral("qp"), QString::number(crf_section_->GetValue()));
}
params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex()));
}
AV1CRFSection::AV1CRFSection(int default_crf, QWidget *parent) :
QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
crf_slider_ = new QSlider(Qt::Horizontal);
crf_slider_->setMinimum(kMinimumCRF);
crf_slider_->setMaximum(kMaximumCRF);
crf_slider_->setValue(default_crf);
layout->addWidget(crf_slider_);
IntegerSlider* crf_input = new IntegerSlider();
crf_input->setMaximumWidth(QtUtils::QFontMetricsWidth(crf_input->fontMetrics(), QStringLiteral("HHHH")));
crf_input->SetMinimum(kMinimumCRF);
crf_input->SetMaximum(kMaximumCRF);
crf_input->SetValue(default_crf);
crf_input->SetDefaultValue(default_crf);
layout->addWidget(crf_input);
connect(crf_slider_, &QSlider::valueChanged, crf_input, &IntegerSlider::SetValue);
connect(crf_input, &IntegerSlider::ValueChanged, crf_slider_, &QSlider::setValue);
}
int AV1CRFSection::GetValue() const
{
return crf_slider_->value();
}
}
+74
View File
@@ -0,0 +1,74 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef AV1SECTION_H
#define AV1SECTION_H
#include <QSlider>
#include <QStackedWidget>
#include <QComboBox>
#include "codecsection.h"
#include "widget/slider/floatslider.h"
namespace olive {
class AV1CRFSection : public QWidget
{
Q_OBJECT
public:
AV1CRFSection(int default_crf, QWidget* parent = nullptr);
int GetValue() const;
static const int kDefaultAV1CRF = 30;
private:
static const int kMinimumCRF = 0;
static const int kMaximumCRF = 63;
QSlider* crf_slider_;
};
class AV1Section : public CodecSection
{
Q_OBJECT
public:
enum CompressionMethod {
kConstantRateFactor,
};
AV1Section(QWidget* parent = nullptr);
AV1Section(int default_crf, QWidget* parent);
virtual void AddOpts(EncodingParams* params) override;
private:
QStackedWidget* compression_method_stack_;
AV1CRFSection* crf_section_;
QComboBox *preset_combobox_;
};
}
#endif // AV1SECTION_H
+6
View File
@@ -193,6 +193,9 @@ QWidget *ExportVideoTab::SetupCodecSection()
h265_section_ = new H265Section();
codec_stack_->addWidget(h265_section_);
av1_section_ = new AV1Section();
codec_stack_->addWidget(av1_section_);
cineform_section_ = new CineformSection();
codec_stack_->addWidget(cineform_section_);
@@ -253,6 +256,9 @@ void ExportVideoTab::VideoCodecChanged()
case ExportCodec::kCodecH265:
SetCodecSection(h265_section_);
break;
case ExportCodec::kCodecAV1:
SetCodecSection(av1_section_);
break;
case ExportCodec::kCodecCineform:
SetCodecSection(cineform_section_);
break;
+2
View File
@@ -26,6 +26,7 @@
#include <QWidget>
#include "common/qtutils.h"
#include "dialog/export/codec/av1section.h"
#include "dialog/export/codec/cineformsection.h"
#include "dialog/export/codec/codecstack.h"
#include "dialog/export/codec/h264section.h"
@@ -181,6 +182,7 @@ private:
ImageSection* image_section_;
H264Section* h264_section_;
H264Section* h265_section_;
AV1Section* av1_section_;
CineformSection *cineform_section_;
ColorSpaceChooser* color_space_chooser_;
+3 -6
View File
@@ -9,7 +9,7 @@ ARG CI_COMMON_VERSION=2
ARG FFMPEG_VERSION=5.0
ARG NASM_VERSION=2.15.05
ARG YASM_VERSION=1.3.0
ARG AOM_VERSION=v3.3.0
ARG SVTAV1_VERSION=v1.1.0
ARG X265_VERSION=3.5
ARG OGG_VERSION=1.3.5
ARG OPUS_VERSION=1.3.1
@@ -22,7 +22,6 @@ ARG XVID_VERSION=1.3.7
ARG OPENJPEG_VERSION=2.4.0
ARG LIBPNG_VERSION=1.6.37
# TODO: Make version of x264 selectable?
ARG NUM_JOBS=2
FROM ${OLIVE_ORG}/ci-common:${CI_COMMON_VERSION} as ci-ffmpeg
@@ -31,7 +30,7 @@ ARG CI_COMMON_VERSION
ARG FFMPEG_VERSION
ARG NASM_VERSION
ARG YASM_VERSION
ARG AOM_VERSION
ARG SVTAV1_VERSION
ARG X265_VERSION
ARG OGG_VERSION
ARG OPUS_VERSION
@@ -43,7 +42,6 @@ ARG LAME_VERSION
ARG XVID_VERSION
ARG OPENJPEG_VERSION
ARG LIBPNG_VERSION
ARG NUM_JOBS
LABEL maintainer="olivevideoeditor@gmail.com"
LABEL org.opencontainers.image.name="$OLIVE_ORG/ci-ffmpeg"
@@ -62,7 +60,7 @@ ENV OLIVE_ORG=${OLIVE_ORG} \
FFMPEG_VERSION=${FFMPEG_VERSION} \
NASM_VERSION=${NASM_VERSION} \
YASM_VERSION=${YASM_VERSION} \
AOM_VERSION=${AOM_VERSION} \
SVTAV1_VERSION=${SVTAV1_VERSION} \
X265_VERSION=${X265_VERSION} \
OGG_VERSION=${OGG_VERSION} \
OPUS_VERSION=${OPUS_VERSION} \
@@ -74,7 +72,6 @@ ENV OLIVE_ORG=${OLIVE_ORG} \
XVID_VERSION=${XVID_VERSION} \
OPENJPEG_VERSION=${OPENJPEG_VERSION} \
LIBPNG_VERSION=${LIBPNG_VERSION} \
NUM_JOBS=${NUM_JOBS} \
OLIVE_INSTALL_PREFIX=/usr/local
RUN /tmp/before_build.sh && \
+13 -13
View File
@@ -20,8 +20,8 @@ set -ex
cd nasm*
./autogen.sh
./configure \
--prefix="${OLIVE_INSTALL_PREFIX}"
make -j${NUM_JOBS}
--prefix="/usr"
make -j$(nproc)
make install
cd ..
rm -rf nasm*
@@ -34,8 +34,8 @@ set -ex
rm -f yasm.tar.gz
cd yasm*
./configure \
--prefix="${OLIVE_INSTALL_PREFIX}"
make -j${NUM_JOBS}
--prefix="/usr"
make -j$(nproc)
make install
cd ..
rm -rf yasm*
@@ -44,19 +44,19 @@ set -ex
# join jobs, some libs depend on NASM/YASM
wait
# Set up libaom
# Set up libsvtav1
{
git clone --depth 1 --branch "${AOM_VERSION}" "https://aomedia.googlesource.com/aom"
cd aom
mkdir _build
cd _build
git clone --depth 1 --branch "${SVTAV1_VERSION}" "https://gitlab.com/AOMediaCodec/SVT-AV1.git"
cd SVT-AV1/Build
cmake .. \
-G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX="${OLIVE_INSTALL_PREFIX}" \
-DBUILD_SHARED_LIBS=1
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_APPS=OFF
cmake --build .
cmake --install .
cd ../..
rm -rf aom
rm -rf SVT-AV1
} &
# Set up libx264
@@ -269,7 +269,7 @@ PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:$PKG_CONFIG
--enable-gpl \
--enable-version3 \
--enable-shared \
--enable-libaom \
--enable-libsvtav1 \
--enable-libfreetype \
--enable-libx264 \
--enable-libx265 \
@@ -286,7 +286,7 @@ PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:$PKG_CONFIG
--extra-libs=-lm \
--extra-cflags="-I${OLIVE_INSTALL_PREFIX}/include" \
--extra-ldflags="-L${OLIVE_INSTALL_PREFIX}/lib"
make -j${NUM_JOBS}
make -j$(nproc)
make install
cd ..
rm -rf ffmpeg*