export: use codec IDs rather than strings
Vastly improves portability between library versions.
This commit is contained in:
@@ -23,6 +23,10 @@ set(OLIVE_SOURCES
|
|||||||
codec/decoder.cpp
|
codec/decoder.cpp
|
||||||
codec/encoder.h
|
codec/encoder.h
|
||||||
codec/encoder.cpp
|
codec/encoder.cpp
|
||||||
|
codec/exportcodec.h
|
||||||
|
codec/exportcodec.cpp
|
||||||
|
codec/exportformat.h
|
||||||
|
codec/exportformat.cpp
|
||||||
codec/frame.h
|
codec/frame.h
|
||||||
codec/frame.cpp
|
codec/frame.cpp
|
||||||
codec/samplebuffer.h
|
codec/samplebuffer.h
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ void EncodingParams::SetFilename(const QString &filename)
|
|||||||
filename_ = filename;
|
filename_ = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodingParams::EnableVideo(const VideoRenderingParams &video_params, const QString &vcodec)
|
void EncodingParams::EnableVideo(const VideoRenderingParams &video_params, const ExportCodec::Codec &vcodec)
|
||||||
{
|
{
|
||||||
video_enabled_ = true;
|
video_enabled_ = true;
|
||||||
video_params_ = video_params;
|
video_params_ = video_params;
|
||||||
video_codec_ = vcodec;
|
video_codec_ = vcodec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodingParams::EnableAudio(const AudioRenderingParams &audio_params, const QString &acodec)
|
void EncodingParams::EnableAudio(const AudioRenderingParams &audio_params, const ExportCodec::Codec &acodec)
|
||||||
{
|
{
|
||||||
audio_enabled_ = true;
|
audio_enabled_ = true;
|
||||||
audio_params_ = audio_params;
|
audio_params_ = audio_params;
|
||||||
@@ -98,7 +98,7 @@ bool EncodingParams::video_enabled() const
|
|||||||
return video_enabled_;
|
return video_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &EncodingParams::video_codec() const
|
const ExportCodec::Codec &EncodingParams::video_codec() const
|
||||||
{
|
{
|
||||||
return video_codec_;
|
return video_codec_;
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ bool EncodingParams::audio_enabled() const
|
|||||||
return audio_enabled_;
|
return audio_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &EncodingParams::audio_codec() const
|
const ExportCodec::Codec &EncodingParams::audio_codec() const
|
||||||
{
|
{
|
||||||
return audio_codec_;
|
return audio_codec_;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -24,6 +24,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "codec/exportcodec.h"
|
||||||
|
#include "codec/exportformat.h"
|
||||||
#include "codec/frame.h"
|
#include "codec/frame.h"
|
||||||
#include "common/timerange.h"
|
#include "common/timerange.h"
|
||||||
#include "render/audioparams.h"
|
#include "render/audioparams.h"
|
||||||
@@ -40,8 +42,8 @@ public:
|
|||||||
|
|
||||||
void SetFilename(const QString& filename);
|
void SetFilename(const QString& filename);
|
||||||
|
|
||||||
void EnableVideo(const VideoRenderingParams& video_params, const QString& vcodec);
|
void EnableVideo(const VideoRenderingParams& video_params, const ExportCodec::Codec& vcodec);
|
||||||
void EnableAudio(const AudioRenderingParams& audio_params, const QString& acodec);
|
void EnableAudio(const AudioRenderingParams& audio_params, const ExportCodec::Codec &acodec);
|
||||||
|
|
||||||
void set_video_option(const QString& key, const QString& value);
|
void set_video_option(const QString& key, const QString& value);
|
||||||
void set_video_bit_rate(const int64_t& rate);
|
void set_video_bit_rate(const int64_t& rate);
|
||||||
@@ -52,7 +54,7 @@ public:
|
|||||||
const QString& filename() const;
|
const QString& filename() const;
|
||||||
|
|
||||||
bool video_enabled() const;
|
bool video_enabled() const;
|
||||||
const QString& video_codec() const;
|
const ExportCodec::Codec& video_codec() const;
|
||||||
const VideoRenderingParams& video_params() const;
|
const VideoRenderingParams& video_params() const;
|
||||||
const QHash<QString, QString>& video_opts() const;
|
const QHash<QString, QString>& video_opts() const;
|
||||||
const int64_t& video_bit_rate() const;
|
const int64_t& video_bit_rate() const;
|
||||||
@@ -61,7 +63,7 @@ public:
|
|||||||
const int& video_threads() const;
|
const int& video_threads() const;
|
||||||
|
|
||||||
bool audio_enabled() const;
|
bool audio_enabled() const;
|
||||||
const QString& audio_codec() const;
|
const ExportCodec::Codec &audio_codec() const;
|
||||||
const AudioRenderingParams& audio_params() const;
|
const AudioRenderingParams& audio_params() const;
|
||||||
|
|
||||||
const rational& GetExportLength() const;
|
const rational& GetExportLength() const;
|
||||||
@@ -71,7 +73,7 @@ private:
|
|||||||
QString filename_;
|
QString filename_;
|
||||||
|
|
||||||
bool video_enabled_;
|
bool video_enabled_;
|
||||||
QString video_codec_;
|
ExportCodec::Codec video_codec_;
|
||||||
VideoRenderingParams video_params_;
|
VideoRenderingParams video_params_;
|
||||||
QHash<QString, QString> video_opts_;
|
QHash<QString, QString> video_opts_;
|
||||||
int64_t video_bit_rate_;
|
int64_t video_bit_rate_;
|
||||||
@@ -80,7 +82,7 @@ private:
|
|||||||
int video_threads_;
|
int video_threads_;
|
||||||
|
|
||||||
bool audio_enabled_;
|
bool audio_enabled_;
|
||||||
QString audio_codec_;
|
ExportCodec::Codec audio_codec_;
|
||||||
AudioRenderingParams audio_params_;
|
AudioRenderingParams audio_params_;
|
||||||
|
|
||||||
rational export_length_;
|
rational export_length_;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
Olive - Non-Linear Video Editor
|
||||||
|
Copyright (C) 2019 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 "exportcodec.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
QString ExportCodec::GetCodecName(ExportCodec::Codec c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case kCodecDNxHD:
|
||||||
|
return tr("DNxHD");
|
||||||
|
case kCodecH264:
|
||||||
|
return tr("H.264");
|
||||||
|
case kCodecH265:
|
||||||
|
return tr("H.265");
|
||||||
|
case kCodecOpenEXR:
|
||||||
|
return tr("OpenEXR");
|
||||||
|
case kCodecPNG:
|
||||||
|
return tr("PNG");
|
||||||
|
case kCodecProRes:
|
||||||
|
return tr("ProRes");
|
||||||
|
case kCodecTIFF:
|
||||||
|
return tr("TIFF");
|
||||||
|
case kCodecMP2:
|
||||||
|
return tr("MP2");
|
||||||
|
case kCodecMP3:
|
||||||
|
return tr("MP3");
|
||||||
|
case kCodecAAC:
|
||||||
|
return tr("AAC");
|
||||||
|
case kCodecPCM:
|
||||||
|
return tr("PCM (Uncompressed)");
|
||||||
|
case kCodecCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tr("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExportCodec::IsCodecAStillImage(ExportCodec::Codec c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case kCodecDNxHD:
|
||||||
|
case kCodecH264:
|
||||||
|
case kCodecH265:
|
||||||
|
case kCodecProRes:
|
||||||
|
case kCodecMP2:
|
||||||
|
case kCodecMP3:
|
||||||
|
case kCodecAAC:
|
||||||
|
case kCodecPCM:
|
||||||
|
return false;
|
||||||
|
case kCodecOpenEXR:
|
||||||
|
case kCodecPNG:
|
||||||
|
case kCodecTIFF:
|
||||||
|
return true;
|
||||||
|
case kCodecCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
@@ -21,34 +21,35 @@
|
|||||||
#ifndef EXPORTCODEC_H
|
#ifndef EXPORTCODEC_H
|
||||||
#define EXPORTCODEC_H
|
#define EXPORTCODEC_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
|
|
||||||
OLIVE_NAMESPACE_ENTER
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
class ExportCodec {
|
class ExportCodec : public QObject {
|
||||||
public:
|
public:
|
||||||
enum Flag {
|
enum Codec {
|
||||||
kNone,
|
kCodecDNxHD,
|
||||||
kStillImage
|
kCodecH264,
|
||||||
|
kCodecH265,
|
||||||
|
kCodecOpenEXR,
|
||||||
|
kCodecPNG,
|
||||||
|
kCodecProRes,
|
||||||
|
kCodecTIFF,
|
||||||
|
|
||||||
|
kCodecMP2,
|
||||||
|
kCodecMP3,
|
||||||
|
kCodecAAC,
|
||||||
|
kCodecPCM,
|
||||||
|
|
||||||
|
kCodecCount
|
||||||
};
|
};
|
||||||
|
|
||||||
ExportCodec(const QString& name, const QString& id, Flag flags = kNone) :
|
static QString GetCodecName(Codec c);
|
||||||
name_(name),
|
|
||||||
id_(id),
|
|
||||||
flags_(flags)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString& name() const {return name_;}
|
static bool IsCodecAStillImage(Codec c);
|
||||||
const QString& id() const {return id_;}
|
|
||||||
const Flag& flags() const {return flags_;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString name_;
|
|
||||||
QString id_;
|
|
||||||
Flag flags_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
Olive - Non-Linear Video Editor
|
||||||
|
Copyright (C) 2019 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 "exportformat.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
QString ExportFormat::GetName(olive::ExportFormat::Format f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case kFormatDNxHD:
|
||||||
|
return tr("DNxHD");
|
||||||
|
case kFormatMatroska:
|
||||||
|
return tr("Matroska Video");
|
||||||
|
case kFormatMPEG4:
|
||||||
|
return tr("MPEG-4 Video");
|
||||||
|
case kFormatOpenEXR:
|
||||||
|
return tr("OpenEXR");
|
||||||
|
case kFormatPNG:
|
||||||
|
return tr("PNG");
|
||||||
|
case kFormatTIFF:
|
||||||
|
return tr("TIFF");
|
||||||
|
case kFormatQuickTime:
|
||||||
|
return tr("QuickTime");
|
||||||
|
case kFormatCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tr("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExportFormat::GetExtension(ExportFormat::Format f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case kFormatDNxHD:
|
||||||
|
return QStringLiteral("mxf");
|
||||||
|
case kFormatMatroska:
|
||||||
|
return QStringLiteral("mkv");
|
||||||
|
case kFormatMPEG4:
|
||||||
|
return QStringLiteral("mp4");
|
||||||
|
case kFormatOpenEXR:
|
||||||
|
return QStringLiteral("exr");
|
||||||
|
case kFormatPNG:
|
||||||
|
return QStringLiteral("png");
|
||||||
|
case kFormatTIFF:
|
||||||
|
return QStringLiteral("tiff");
|
||||||
|
case kFormatQuickTime:
|
||||||
|
return QStringLiteral("mov");
|
||||||
|
case kFormatCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExportFormat::GetEncoder(ExportFormat::Format f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case kFormatDNxHD:
|
||||||
|
case kFormatMatroska:
|
||||||
|
case kFormatQuickTime:
|
||||||
|
case kFormatMPEG4:
|
||||||
|
return QStringLiteral("ffmpeg");
|
||||||
|
case kFormatOpenEXR:
|
||||||
|
case kFormatPNG:
|
||||||
|
case kFormatTIFF:
|
||||||
|
return QStringLiteral("oiio");
|
||||||
|
case kFormatCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ExportCodec::Codec> ExportFormat::GetVideoCodecs(ExportFormat::Format f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case kFormatDNxHD:
|
||||||
|
return {ExportCodec::kCodecDNxHD};
|
||||||
|
case kFormatMatroska:
|
||||||
|
return {ExportCodec::kCodecH264, ExportCodec::kCodecH265};
|
||||||
|
case kFormatMPEG4:
|
||||||
|
return {ExportCodec::kCodecH264, ExportCodec::kCodecH265};
|
||||||
|
case kFormatOpenEXR:
|
||||||
|
return {ExportCodec::kCodecOpenEXR};
|
||||||
|
case kFormatPNG:
|
||||||
|
return {ExportCodec::kCodecPNG};
|
||||||
|
case kFormatTIFF:
|
||||||
|
return {ExportCodec::kCodecTIFF};
|
||||||
|
case kFormatQuickTime:
|
||||||
|
return {ExportCodec::kCodecH264, ExportCodec::kCodecH265, ExportCodec::kCodecProRes};
|
||||||
|
case kFormatCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ExportCodec::Codec> ExportFormat::GetAudioCodecs(ExportFormat::Format f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case kFormatDNxHD:
|
||||||
|
return {ExportCodec::kCodecPCM};
|
||||||
|
case kFormatMatroska:
|
||||||
|
return {ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM};
|
||||||
|
case kFormatMPEG4:
|
||||||
|
return {ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM};
|
||||||
|
case kFormatQuickTime:
|
||||||
|
return {ExportCodec::kCodecAAC, ExportCodec::kCodecMP2, ExportCodec::kCodecMP3, ExportCodec::kCodecPCM};
|
||||||
|
case kFormatOpenEXR:
|
||||||
|
case kFormatPNG:
|
||||||
|
case kFormatTIFF:
|
||||||
|
return {};
|
||||||
|
case kFormatCount:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
@@ -25,32 +25,29 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "common/define.h"
|
#include "common/define.h"
|
||||||
|
#include "exportcodec.h"
|
||||||
|
|
||||||
OLIVE_NAMESPACE_ENTER
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
class ExportFormat {
|
class ExportFormat : public QObject {
|
||||||
public:
|
public:
|
||||||
ExportFormat(const QString& name, const QString& extension, const QString& encoder, const QList<int>& vcodecs, const QList<int>& acodecs) :
|
enum Format {
|
||||||
name_(name),
|
kFormatDNxHD,
|
||||||
extension_(extension),
|
kFormatMatroska,
|
||||||
encoder_(encoder),
|
kFormatMPEG4,
|
||||||
video_codecs_(vcodecs),
|
kFormatOpenEXR,
|
||||||
audio_codecs_(acodecs)
|
kFormatQuickTime,
|
||||||
{
|
kFormatPNG,
|
||||||
}
|
kFormatTIFF,
|
||||||
|
|
||||||
const QString& name() const {return name_;}
|
kFormatCount
|
||||||
const QString& extension() const {return extension_;}
|
};
|
||||||
const QString& encoder() const {return encoder_;}
|
|
||||||
const QList<int>& video_codecs() const {return video_codecs_;}
|
|
||||||
const QList<int>& audio_codecs() const {return audio_codecs_;}
|
|
||||||
|
|
||||||
private:
|
static QString GetName(Format f);
|
||||||
QString name_;
|
static QString GetExtension(Format f);
|
||||||
QString extension_;
|
static QString GetEncoder(Format f);
|
||||||
QString encoder_;
|
static QList<ExportCodec::Codec> GetVideoCodecs(ExportFormat::Format f);
|
||||||
QList<int> video_codecs_;
|
static QList<ExportCodec::Codec> GetAudioCodecs(ExportFormat::Format f);
|
||||||
QList<int> audio_codecs_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -362,19 +362,57 @@ fail:
|
|||||||
return succeeded;
|
return succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AVCodecContext** codec_ctx_ptr, const QString& codec)
|
bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AVCodecContext** codec_ctx_ptr, const ExportCodec::Codec& codec)
|
||||||
{
|
{
|
||||||
if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
|
if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
|
||||||
Error(QStringLiteral("Cannot initialize a stream that is not a video or audio type"));
|
Error(QStringLiteral("Cannot initialize a stream that is not a video or audio type"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve codec and convert to C string
|
// Retrieve codec
|
||||||
QByteArray codec_bytes = codec.toUtf8();
|
AVCodecID codec_id;
|
||||||
const char* codec_c_str = codec_bytes.constData();
|
|
||||||
|
switch (codec) {
|
||||||
|
case ExportCodec::kCodecDNxHD:
|
||||||
|
codec_id = AV_CODEC_ID_DNXHD;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecAAC:
|
||||||
|
codec_id = AV_CODEC_ID_AAC;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecMP2:
|
||||||
|
codec_id = AV_CODEC_ID_MP2;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecMP3:
|
||||||
|
codec_id = AV_CODEC_ID_MP3;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecH264:
|
||||||
|
codec_id = AV_CODEC_ID_H264;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecH265:
|
||||||
|
codec_id = AV_CODEC_ID_HEVC;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecOpenEXR:
|
||||||
|
codec_id = AV_CODEC_ID_EXR;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecPNG:
|
||||||
|
codec_id = AV_CODEC_ID_PNG;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecTIFF:
|
||||||
|
codec_id = AV_CODEC_ID_TIFF;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecProRes:
|
||||||
|
codec_id = AV_CODEC_ID_PRORES;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecPCM:
|
||||||
|
codec_id = AV_CODEC_ID_PCM_S16LE;
|
||||||
|
break;
|
||||||
|
case ExportCodec::kCodecCount:
|
||||||
|
Error(QStringLiteral("Unknown internal codec"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Find encoder with this name
|
// Find encoder with this name
|
||||||
AVCodec* encoder = avcodec_find_encoder_by_name(codec_c_str);
|
AVCodec* encoder = avcodec_find_encoder(codec_id);
|
||||||
|
|
||||||
if (!encoder) {
|
if (!encoder) {
|
||||||
Error(QStringLiteral("Failed to find codec for %1").arg(codec));
|
Error(QStringLiteral("Failed to find codec for %1").arg(codec));
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ private:
|
|||||||
|
|
||||||
bool WriteAVFrame(AVFrame* frame, AVCodecContext *codec_ctx, AVStream *stream);
|
bool WriteAVFrame(AVFrame* frame, AVCodecContext *codec_ctx, AVStream *stream);
|
||||||
|
|
||||||
bool InitializeStream(enum AVMediaType type, AVStream** stream, AVCodecContext** codec_ctx, const QString& codec);
|
bool InitializeStream(enum AVMediaType type, AVStream** stream, AVCodecContext** codec_ctx, const ExportCodec::Codec &codec);
|
||||||
bool InitializeCodecContext(AVStream** stream, AVCodecContext** codec_ctx, AVCodec* codec);
|
bool InitializeCodecContext(AVStream** stream, AVCodecContext** codec_ctx, AVCodec* codec);
|
||||||
bool SetupCodecContext(AVStream *stream, AVCodecContext *codec_ctx, AVCodec *codec);
|
bool SetupCodecContext(AVStream *stream, AVCodecContext *codec_ctx, AVCodec *codec);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ class OIIODecoder : public Decoder
|
|||||||
public:
|
public:
|
||||||
OIIODecoder();
|
OIIODecoder();
|
||||||
|
|
||||||
|
enum ExportCodec {
|
||||||
|
kCodecEXR,
|
||||||
|
kCodecPNG,
|
||||||
|
kCodecTIFF
|
||||||
|
};
|
||||||
|
|
||||||
virtual QString id() override;
|
virtual QString id() override;
|
||||||
|
|
||||||
virtual bool Probe(Footage *f, const QAtomicInt* cancelled) override;
|
virtual bool Probe(Footage *f, const QAtomicInt* cancelled) override;
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ set(OLIVE_SOURCES
|
|||||||
dialog/export/exportadvancedvideodialog.cpp
|
dialog/export/exportadvancedvideodialog.cpp
|
||||||
dialog/export/exportaudiotab.h
|
dialog/export/exportaudiotab.h
|
||||||
dialog/export/exportaudiotab.cpp
|
dialog/export/exportaudiotab.cpp
|
||||||
dialog/export/exportcodec.h
|
|
||||||
dialog/export/exportformat.h
|
|
||||||
dialog/export/exportvideotab.h
|
dialog/export/exportvideotab.h
|
||||||
dialog/export/exportvideotab.cpp
|
dialog/export/exportvideotab.cpp
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
|
|||||||
+24
-102
@@ -41,8 +41,7 @@ OLIVE_NAMESPACE_ENTER
|
|||||||
|
|
||||||
ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
viewer_node_(viewer_node),
|
viewer_node_(viewer_node)
|
||||||
previously_selected_format_(0)
|
|
||||||
{
|
{
|
||||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
|
||||||
@@ -164,16 +163,15 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
|||||||
// Set default filename
|
// Set default filename
|
||||||
SetDefaultFilename();
|
SetDefaultFilename();
|
||||||
|
|
||||||
// Set up available export formats
|
|
||||||
SetUpFormats();
|
|
||||||
|
|
||||||
// Populate combobox formats
|
// Populate combobox formats
|
||||||
foreach (const ExportFormat& format, formats_) {
|
for (int i=0; i<ExportFormat::kFormatCount; i++) {
|
||||||
format_combobox_->addItem(format.name());
|
format_combobox_->addItem(ExportFormat::GetName(static_cast<ExportFormat::Format>(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
format_combobox_->setCurrentIndex(kFormatMPEG4);
|
format_combobox_->setCurrentIndex(ExportFormat::kFormatMPEG4);
|
||||||
|
previously_selected_format_ = ExportFormat::kFormatMPEG4;
|
||||||
|
|
||||||
video_tab_->width_slider()->SetValue(viewer_node_->video_params().width());
|
video_tab_->width_slider()->SetValue(viewer_node_->video_params().width());
|
||||||
video_tab_->width_slider()->SetDefaultValue(viewer_node_->video_params().width());
|
video_tab_->width_slider()->SetDefaultValue(viewer_node_->video_params().width());
|
||||||
video_tab_->height_slider()->SetValue(viewer_node_->video_params().height());
|
video_tab_->height_slider()->SetValue(viewer_node_->video_params().height());
|
||||||
@@ -235,7 +233,7 @@ void ExportDialog::StartExport()
|
|||||||
|
|
||||||
// Validate if the entered filename contains the correct extension (the extension is necessary for both FFmpeg and
|
// Validate if the entered filename contains the correct extension (the extension is necessary for both FFmpeg and
|
||||||
// OIIO to determine the output format)
|
// OIIO to determine the output format)
|
||||||
QString necessary_ext = QStringLiteral(".%1").arg(formats_.at(format_combobox_->currentIndex()).extension());
|
QString necessary_ext = QStringLiteral(".%1").arg(ExportFormat::GetExtension(static_cast<ExportFormat::Format>(format_combobox_->currentIndex())));
|
||||||
|
|
||||||
// If it doesn't, see if the user wants to append it automatically. If not, we don't abort the export.
|
// If it doesn't, see if the user wants to append it automatically. If not, we don't abort the export.
|
||||||
if (!filename_edit_->text().endsWith(necessary_ext, Qt::CaseInsensitive)) {
|
if (!filename_edit_->text().endsWith(necessary_ext, Qt::CaseInsensitive)) {
|
||||||
@@ -317,12 +315,12 @@ void ExportDialog::closeEvent(QCloseEvent *e)
|
|||||||
|
|
||||||
void ExportDialog::BrowseFilename()
|
void ExportDialog::BrowseFilename()
|
||||||
{
|
{
|
||||||
const ExportFormat& current_format = formats_.at(format_combobox_->currentIndex());
|
ExportFormat::Format f = static_cast<ExportFormat::Format>(format_combobox_->currentIndex());
|
||||||
|
|
||||||
QString browsed_fn = QFileDialog::getSaveFileName(this,
|
QString browsed_fn = QFileDialog::getSaveFileName(this,
|
||||||
"",
|
"",
|
||||||
filename_edit_->text(),
|
filename_edit_->text(),
|
||||||
QStringLiteral("%1 (*.%2)").arg(current_format.name(), current_format.extension()),
|
QStringLiteral("%1 (*.%2)").arg(ExportFormat::GetName(f), ExportFormat::GetExtension(f)),
|
||||||
nullptr,
|
nullptr,
|
||||||
|
|
||||||
// We don't confirm overwrite here because we do it later
|
// We don't confirm overwrite here because we do it later
|
||||||
@@ -336,9 +334,9 @@ void ExportDialog::BrowseFilename()
|
|||||||
void ExportDialog::FormatChanged(int index)
|
void ExportDialog::FormatChanged(int index)
|
||||||
{
|
{
|
||||||
QString current_filename = filename_edit_->text();
|
QString current_filename = filename_edit_->text();
|
||||||
const QString& previously_selected_ext = formats_.at(previously_selected_format_).extension();
|
QString previously_selected_ext = ExportFormat::GetExtension(previously_selected_format_);
|
||||||
const ExportFormat& current_format = formats_.at(index);
|
ExportFormat::Format current_format = static_cast<ExportFormat::Format>(index);
|
||||||
const QString& currently_selected_ext = current_format.extension();
|
QString currently_selected_ext = ExportFormat::GetExtension(current_format);
|
||||||
|
|
||||||
// If the previous extension was added, remove it
|
// If the previous extension was added, remove it
|
||||||
if (current_filename.endsWith(previously_selected_ext, Qt::CaseInsensitive)) {
|
if (current_filename.endsWith(previously_selected_ext, Qt::CaseInsensitive)) {
|
||||||
@@ -350,18 +348,18 @@ void ExportDialog::FormatChanged(int index)
|
|||||||
current_filename.append(currently_selected_ext);
|
current_filename.append(currently_selected_ext);
|
||||||
filename_edit_->setText(current_filename);
|
filename_edit_->setText(current_filename);
|
||||||
|
|
||||||
previously_selected_format_ = index;
|
previously_selected_format_ = current_format;
|
||||||
|
|
||||||
// Update video and audio comboboxes
|
// Update video and audio comboboxes
|
||||||
video_tab_->codec_combobox()->clear();
|
video_tab_->codec_combobox()->clear();
|
||||||
foreach (int vcodec, current_format.video_codecs()) {
|
foreach (ExportCodec::Codec vcodec, ExportFormat::GetVideoCodecs(current_format)) {
|
||||||
video_tab_->codec_combobox()->addItem(codecs_.at(vcodec).name(), vcodec);
|
video_tab_->codec_combobox()->addItem(ExportCodec::GetCodecName(vcodec), vcodec);
|
||||||
}
|
}
|
||||||
VideoCodecChanged();
|
VideoCodecChanged();
|
||||||
|
|
||||||
audio_tab_->codec_combobox()->clear();
|
audio_tab_->codec_combobox()->clear();
|
||||||
foreach (int acodec, current_format.audio_codecs()) {
|
foreach (ExportCodec::Codec acodec, ExportFormat::GetAudioCodecs(current_format)) {
|
||||||
audio_tab_->codec_combobox()->addItem(codecs_.at(acodec).name(), acodec);
|
audio_tab_->codec_combobox()->addItem(ExportCodec::GetCodecName(acodec), acodec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,89 +397,15 @@ void ExportDialog::ResolutionChanged()
|
|||||||
|
|
||||||
void ExportDialog::VideoCodecChanged()
|
void ExportDialog::VideoCodecChanged()
|
||||||
{
|
{
|
||||||
int codec_index = video_tab_->codec_combobox()->currentData().toInt();
|
ExportCodec::Codec codec = static_cast<ExportCodec::Codec>(video_tab_->codec_combobox()->currentData().toInt());
|
||||||
const ExportCodec& codec = codecs_.at(codec_index);
|
|
||||||
|
|
||||||
if (codec_index == kCodecH264) {
|
if (codec == ExportCodec::kCodecH264) {
|
||||||
video_tab_->SetCodecSection(video_tab_->h264_section());
|
video_tab_->SetCodecSection(video_tab_->h264_section());
|
||||||
} else if (codec.flags() & ExportCodec::kStillImage) {
|
} else if (ExportCodec::IsCodecAStillImage(codec)) {
|
||||||
video_tab_->SetCodecSection(video_tab_->image_section());
|
video_tab_->SetCodecSection(video_tab_->image_section());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportDialog::SetUpFormats()
|
|
||||||
{
|
|
||||||
// Set up codecs
|
|
||||||
for (int i=0;i<kCodecCount;i++) {
|
|
||||||
switch (static_cast<Codec>(i)) {
|
|
||||||
case kCodecDNxHD:
|
|
||||||
codecs_.append(ExportCodec(tr("DNxHD"), "dnxhd"));
|
|
||||||
break;
|
|
||||||
case kCodecH264:
|
|
||||||
codecs_.append(ExportCodec(tr("H.264"), "libx264"));
|
|
||||||
break;
|
|
||||||
case kCodecH265:
|
|
||||||
codecs_.append(ExportCodec(tr("H.265"), "libx265"));
|
|
||||||
break;
|
|
||||||
case kCodecOpenEXR:
|
|
||||||
codecs_.append(ExportCodec(tr("OpenEXR"), "exr", ExportCodec::kStillImage));
|
|
||||||
break;
|
|
||||||
case kCodecPNG:
|
|
||||||
codecs_.append(ExportCodec(tr("PNG"), "png", ExportCodec::kStillImage));
|
|
||||||
break;
|
|
||||||
case kCodecProRes:
|
|
||||||
codecs_.append(ExportCodec(tr("ProRes"), "prores"));
|
|
||||||
break;
|
|
||||||
case kCodecTIFF:
|
|
||||||
codecs_.append(ExportCodec(tr("TIFF"), "tiff", ExportCodec::kStillImage));
|
|
||||||
break;
|
|
||||||
case kCodecMP2:
|
|
||||||
codecs_.append(ExportCodec(tr("MP2"), "mp2"));
|
|
||||||
break;
|
|
||||||
case kCodecMP3:
|
|
||||||
codecs_.append(ExportCodec(tr("MP3"), "libmp3lame"));
|
|
||||||
break;
|
|
||||||
case kCodecAAC:
|
|
||||||
codecs_.append(ExportCodec(tr("AAC"), "aac"));
|
|
||||||
break;
|
|
||||||
case kCodecPCM:
|
|
||||||
codecs_.append(ExportCodec(tr("PCM (Uncompressed)"), "pcm"));
|
|
||||||
break;
|
|
||||||
case kCodecCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up formats
|
|
||||||
for (int i=0;i<kFormatCount;i++) {
|
|
||||||
switch (static_cast<Format>(i)) {
|
|
||||||
case kFormatDNxHD:
|
|
||||||
formats_.append(ExportFormat(tr("DNxHD"), "mxf", "ffmpeg", {kCodecDNxHD}, {kCodecPCM}));
|
|
||||||
break;
|
|
||||||
case kFormatMatroska:
|
|
||||||
formats_.append(ExportFormat(tr("Matroska Video"), "mkv", "ffmpeg", {kCodecH264, kCodecH265}, {kCodecAAC, kCodecMP2, kCodecMP3, kCodecPCM}));
|
|
||||||
break;
|
|
||||||
case kFormatMPEG4:
|
|
||||||
formats_.append(ExportFormat(tr("MPEG-4 Video"), "mp4", "ffmpeg", {kCodecH264, kCodecH265}, {kCodecAAC, kCodecMP2, kCodecMP3, kCodecPCM}));
|
|
||||||
break;
|
|
||||||
case kFormatOpenEXR:
|
|
||||||
formats_.append(ExportFormat(tr("OpenEXR"), "exr", "oiio", {kCodecOpenEXR}, {}));
|
|
||||||
break;
|
|
||||||
case kFormatQuickTime:
|
|
||||||
formats_.append(ExportFormat(tr("QuickTime"), "mov", "ffmpeg", {kCodecH264, kCodecH265, kCodecProRes}, {kCodecAAC, kCodecMP2, kCodecMP3, kCodecPCM}));
|
|
||||||
break;
|
|
||||||
case kFormatPNG:
|
|
||||||
formats_.append(ExportFormat(tr("PNG"), "png", "oiio", {kCodecPNG}, {}));
|
|
||||||
break;
|
|
||||||
case kFormatTIFF:
|
|
||||||
formats_.append(ExportFormat(tr("TIFF"), "tiff", "oiio", {kCodecTIFF}, {}));
|
|
||||||
break;
|
|
||||||
case kFormatCount:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExportDialog::LoadPresets()
|
void ExportDialog::LoadPresets()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -532,9 +456,8 @@ ExportParams ExportDialog::GenerateParams() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (video_enabled_->isChecked()) {
|
if (video_enabled_->isChecked()) {
|
||||||
const ExportCodec& video_codec = codecs_.at(video_tab_->codec_combobox()->currentData().toInt());
|
ExportCodec::Codec video_codec = static_cast<ExportCodec::Codec>(video_tab_->codec_combobox()->currentData().toInt());
|
||||||
params.EnableVideo(video_render_params,
|
params.EnableVideo(video_render_params, video_codec);
|
||||||
video_codec.id());
|
|
||||||
|
|
||||||
params.set_video_threads(video_tab_->threads());
|
params.set_video_threads(video_tab_->threads());
|
||||||
|
|
||||||
@@ -544,9 +467,8 @@ ExportParams ExportDialog::GenerateParams() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (audio_enabled_->isChecked()) {
|
if (audio_enabled_->isChecked()) {
|
||||||
const ExportCodec& audio_codec = codecs_.at(audio_tab_->codec_combobox()->currentData().toInt());
|
ExportCodec::Codec audio_codec = static_cast<ExportCodec::Codec>(audio_tab_->codec_combobox()->currentData().toInt());
|
||||||
params.EnableAudio(audio_render_params,
|
params.EnableAudio(audio_render_params, audio_codec);
|
||||||
audio_codec.id());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
|
|
||||||
|
#include "codec/exportcodec.h"
|
||||||
|
#include "codec/exportformat.h"
|
||||||
#include "exportaudiotab.h"
|
#include "exportaudiotab.h"
|
||||||
#include "exportcodec.h"
|
|
||||||
#include "exportformat.h"
|
|
||||||
#include "exportvideotab.h"
|
#include "exportvideotab.h"
|
||||||
#include "task/export/export.h"
|
#include "task/export/export.h"
|
||||||
#include "widget/viewer/viewer.h"
|
#include "widget/viewer/viewer.h"
|
||||||
@@ -46,7 +46,6 @@ protected:
|
|||||||
virtual void closeEvent(QCloseEvent *e) override;
|
virtual void closeEvent(QCloseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetUpFormats();
|
|
||||||
void LoadPresets();
|
void LoadPresets();
|
||||||
void SetDefaultFilename();
|
void SetDefaultFilename();
|
||||||
|
|
||||||
@@ -58,14 +57,11 @@ private:
|
|||||||
|
|
||||||
ViewerOutput* viewer_node_;
|
ViewerOutput* viewer_node_;
|
||||||
|
|
||||||
QList<ExportFormat> formats_;
|
ExportFormat::Format previously_selected_format_;
|
||||||
int previously_selected_format_;
|
|
||||||
|
|
||||||
QCheckBox* video_enabled_;
|
QCheckBox* video_enabled_;
|
||||||
QCheckBox* audio_enabled_;
|
QCheckBox* audio_enabled_;
|
||||||
|
|
||||||
QList<ExportCodec> codecs_;
|
|
||||||
|
|
||||||
ViewerWidget* preview_viewer_;
|
ViewerWidget* preview_viewer_;
|
||||||
QLineEdit* filename_edit_;
|
QLineEdit* filename_edit_;
|
||||||
QComboBox* format_combobox_;
|
QComboBox* format_combobox_;
|
||||||
@@ -80,35 +76,6 @@ private:
|
|||||||
QWidget* preferences_area_;
|
QWidget* preferences_area_;
|
||||||
QDialogButtonBox* buttons_;
|
QDialogButtonBox* buttons_;
|
||||||
|
|
||||||
enum Format {
|
|
||||||
kFormatDNxHD,
|
|
||||||
kFormatMatroska,
|
|
||||||
kFormatMPEG4,
|
|
||||||
kFormatOpenEXR,
|
|
||||||
kFormatQuickTime,
|
|
||||||
kFormatPNG,
|
|
||||||
kFormatTIFF,
|
|
||||||
|
|
||||||
kFormatCount
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Codec {
|
|
||||||
kCodecDNxHD,
|
|
||||||
kCodecH264,
|
|
||||||
kCodecH265,
|
|
||||||
kCodecOpenEXR,
|
|
||||||
kCodecPNG,
|
|
||||||
kCodecProRes,
|
|
||||||
kCodecTIFF,
|
|
||||||
|
|
||||||
kCodecMP2,
|
|
||||||
kCodecMP3,
|
|
||||||
kCodecAAC,
|
|
||||||
kCodecPCM,
|
|
||||||
|
|
||||||
kCodecCount
|
|
||||||
};
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void BrowseFilename();
|
void BrowseFilename();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user