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.ProRes.Profile="Profile"
Codec.ProRes.Profile.APCO="422 Proxy/PXY (APCO)"
Codec.ProRes.Profile.APCS="422 Light/LT (APCS)"
Codec.ProRes.Profile.APCO="422 Proxy (APCO)"
Codec.ProRes.Profile.APCS="422 Lite (APCS)"
Codec.ProRes.Profile.APCN="422 Standard (APCN)"
Codec.ProRes.Profile.APCH="422 High Quality/HQ (APCH)"
Codec.ProRes.Profile.AP4H="4444 Standard (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extra Quality/XQ (AP4X)"
Codec.ProRes.Profile.AP4H="4444 High Quality (AP4H)"
Codec.ProRes.Profile.AP4X="4444 Extrme Quality/XQ (AP4X)"
# Encoder: FFmpeg
FFmpegEncoder="FFmpeg Options"

View file

@ -20,6 +20,7 @@
// SOFTWARE.
#pragma once
#include "common.hpp"
// Codec: ProRes
#define P_PRORES "Codec.ProRes"
@ -30,3 +31,21 @@
#define P_PRORES_PROFILE_APCH "Codec.ProRes.Profile.APCH"
#define P_PRORES_PROFILE_AP4H "Codec.ProRes.Profile.AP4H"
#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.
#include "prores_aw_handler.hpp"
#include <array>
#include "../codecs/prores.hpp"
#include "ffmpeg/tools.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,
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));
for (auto ptr = codec->profiles; ptr->profile != FF_PROFILE_UNKNOWN; ptr++) {
if (ptr->profile == profile_id) {
profile = ptr->name;
const std::int64_t profile_id = obs_data_get_int(settings, P_PRORES_PROFILE);
for (auto kv : profile_to_format_map) {
if (kv.first == static_cast<encoder::codec::prores::profile>(profile_id)) {
target_format = kv.second;
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)
@ -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)
{
switch (ptr->profile) {
case 0:
switch (static_cast<encoder::codec::prores::profile>(ptr->profile)) {
case encoder::codec::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);
case 2:
case encoder::codec::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);
case 4:
case encoder::codec::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);
default:
return ptr->name;