ffmpeg-encoder/prores: Improve pixel format override logic

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2020-04-04 19:16:28 +02:00 committed by Michael Fabian Dirks
parent 87163f5f70
commit 9e9e9cbcd5
3 changed files with 45 additions and 27 deletions

View File

@ -373,12 +373,12 @@ Codec.HEVC.Level.Description="Level determines the upper limits of resolution an
# Codec: Apple ProRes # Codec: Apple ProRes
Codec.ProRes.Profile="Profile" Codec.ProRes.Profile="Profile"
Codec.ProRes.Profile.APCO="422 Proxy/PXY (APCO)" Codec.ProRes.Profile.APCO="422 Proxy (APCO)"
Codec.ProRes.Profile.APCS="422 Light/LT (APCS)" Codec.ProRes.Profile.APCS="422 Lite (APCS)"
Codec.ProRes.Profile.APCN="422 Standard (APCN)" Codec.ProRes.Profile.APCN="422 Standard (APCN)"
Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)" Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Standard (AP4H)" Codec.ProRes.Profile.AP4H="4444 High Quality (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extra Quality/XQ (AP4X)" Codec.ProRes.Profile.AP4X="4444 Extrme Quality/XQ (AP4X)"
# Encoder: FFmpeg # Encoder: FFmpeg
FFmpegEncoder="FFmpeg Options" FFmpegEncoder="FFmpeg Options"

View File

@ -20,6 +20,7 @@
// SOFTWARE. // SOFTWARE.
#pragma once #pragma once
#include "common.hpp"
// Codec: ProRes // Codec: ProRes
#define P_PRORES "Codec.ProRes" #define P_PRORES "Codec.ProRes"
@ -30,3 +31,21 @@
#define P_PRORES_PROFILE_APCH "Codec.ProRes.Profile.APCH" #define P_PRORES_PROFILE_APCH "Codec.ProRes.Profile.APCH"
#define P_PRORES_PROFILE_AP4H "Codec.ProRes.Profile.AP4H" #define P_PRORES_PROFILE_AP4H "Codec.ProRes.Profile.AP4H"
#define P_PRORES_PROFILE_AP4X "Codec.ProRes.Profile.AP4X" #define P_PRORES_PROFILE_AP4X "Codec.ProRes.Profile.AP4X"
namespace encoder::codec::prores {
enum class profile : std::int32_t {
APCO = 0,
Y422_PROXY = APCO,
APCS = 1,
Y422_LT = APCS,
APCN = 2,
Y422 = APCN,
APCH = 3,
Y422_HQ = APCH,
AP4H = 4,
Y4444 = AP4H,
AP4X = 5,
Y4444_XQ = AP4X,
_COUNT,
};
}

View File

@ -20,6 +20,7 @@
// SOFTWARE. // SOFTWARE.
#include "prores_aw_handler.hpp" #include "prores_aw_handler.hpp"
#include <array>
#include "../codecs/prores.hpp" #include "../codecs/prores.hpp"
#include "ffmpeg/tools.hpp" #include "ffmpeg/tools.hpp"
#include "plugin.hpp" #include "plugin.hpp"
@ -34,26 +35,24 @@ using namespace encoder::ffmpeg::handler;
void prores_aw_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, void prores_aw_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec,
AVCodecContext*) AVCodecContext*)
{ {
std::string profile = ""; static const std::array<std::pair<encoder::codec::prores::profile, AVPixelFormat>,
static_cast<size_t>(encoder::codec::prores::profile::_COUNT)>
profile_to_format_map{
std::pair{encoder::codec::prores::profile::APCO, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCS, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCN, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCH, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::AP4H, AV_PIX_FMT_YUV444P10},
std::pair{encoder::codec::prores::profile::AP4X, AV_PIX_FMT_YUV444P10},
};
int profile_id = static_cast<int>(obs_data_get_int(settings, P_PRORES_PROFILE)); const std::int64_t profile_id = obs_data_get_int(settings, P_PRORES_PROFILE);
for (auto ptr = codec->profiles; ptr->profile != FF_PROFILE_UNKNOWN; ptr++) { for (auto kv : profile_to_format_map) {
if (ptr->profile == profile_id) { if (kv.first == static_cast<encoder::codec::prores::profile>(profile_id)) {
profile = ptr->name; target_format = kv.second;
break; break;
} }
} }
std::unordered_map<AVPixelFormat, std::list<std::string>> valid_formats = {
{AV_PIX_FMT_YUV422P10, {"apco", "apcs", "apcn", "apch"}}, {AV_PIX_FMT_YUV444P10, {"ap4h", "ap4x"}}};
for (auto kv : valid_formats) {
for (auto name : kv.second) {
if (profile == name) {
target_format = kv.first;
}
}
}
} }
void prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*, bool) void prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*, bool)
@ -63,18 +62,18 @@ void prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCod
inline const char* profile_to_name(const AVProfile* ptr) inline const char* profile_to_name(const AVProfile* ptr)
{ {
switch (ptr->profile) { switch (static_cast<encoder::codec::prores::profile>(ptr->profile)) {
case 0: case encoder::codec::prores::profile::APCO:
return D_TRANSLATE(P_PRORES_PROFILE_APCO); return D_TRANSLATE(P_PRORES_PROFILE_APCO);
case 1: case encoder::codec::prores::profile::APCS:
return D_TRANSLATE(P_PRORES_PROFILE_APCS); return D_TRANSLATE(P_PRORES_PROFILE_APCS);
case 2: case encoder::codec::prores::profile::APCN:
return D_TRANSLATE(P_PRORES_PROFILE_APCN); return D_TRANSLATE(P_PRORES_PROFILE_APCN);
case 3: case encoder::codec::prores::profile::APCH:
return D_TRANSLATE(P_PRORES_PROFILE_APCH); return D_TRANSLATE(P_PRORES_PROFILE_APCH);
case 4: case encoder::codec::prores::profile::AP4H:
return D_TRANSLATE(P_PRORES_PROFILE_AP4H); return D_TRANSLATE(P_PRORES_PROFILE_AP4H);
case 5: case encoder::codec::prores::profile::AP4X:
return D_TRANSLATE(P_PRORES_PROFILE_AP4X); return D_TRANSLATE(P_PRORES_PROFILE_AP4X);
default: default:
return ptr->name; return ptr->name;