0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

UI: Only use FFmpeg compat check for external codecs

For all the codecs we ship with OBS we can use a hardcoded lookup
instead as the FFmpeg one is unreliable.
This commit is contained in:
derrod 2023-03-31 15:50:17 +02:00 committed by Jim
parent 6fc9235b09
commit c8d274edac

View File

@ -23,6 +23,7 @@
#include <initializer_list> #include <initializer_list>
#include <sstream> #include <sstream>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <QCompleter> #include <QCompleter>
#include <QGuiApplication> #include <QGuiApplication>
#include <QLineEdit> #include <QLineEdit>
@ -4933,6 +4934,37 @@ void OBSBasicSettings::AdvOutSplitFileChanged()
ui->advOutSplitFileSize->setVisible(splitFileType == 1); ui->advOutSplitFileSize->setVisible(splitFileType == 1);
} }
static const unordered_set<string> builtin_codecs = {
"h264", "hevc", "av1", "prores", "aac",
"opus", "alac", "pcm_s16le", "pcm_s24le", "pcm_f32le"};
static const unordered_map<string, unordered_set<string>> codec_compat = {
// Technically our muxer supports HEVC and AV1 as well, but nothing else does
{"flv", {"h264", "aac"}},
{"ts", {"h264", "hevc", "aac", "opus"}},
{"m3u8",
{"h264", "hevc", "aac"}}, // Also using MPEG-TS, but no Opus support
{"mov",
{"h264", "hevc", "prores", "aac", "alac", "pcm_s16le", "pcm_s24le",
"pcm_f32le"}},
{"mp4", {"h264", "hevc", "av1", "aac", "opus", "alac", "flac"}},
// MKV supports everything
{"mkv", {}},
};
static bool ContainerSupportsCodec(const string &container, const string &codec)
{
auto iter = codec_compat.find(container);
if (iter == codec_compat.end())
return false;
auto codecs = iter->second;
// Assume everything is supported
if (codecs.empty())
return true;
return codecs.count(codec) > 0;
}
static void DisableIncompatibleCodecs(QComboBox *cbox, const string &format, static void DisableIncompatibleCodecs(QComboBox *cbox, const string &format,
const QString &streamEncoder) const QString &streamEncoder)
{ {
@ -4954,20 +4986,11 @@ static void DisableIncompatibleCodecs(QComboBox *cbox, const string &format,
encoderId.c_str()); encoderId.c_str());
const char *codec = obs_get_encoder_codec(encoderId.c_str()); const char *codec = obs_get_encoder_codec(encoderId.c_str());
bool is_compatible = false; bool is_compatible = ContainerSupportsCodec(format, codec);
/* FFmpeg's check does not work for MPEG-TS and MKV. */ /* Fall back to FFmpeg check if codec not one of the built-in ones. */
if (format == "ts") { if (!is_compatible && !builtin_codecs.count(codec))
is_compatible = strcmp(codec, "aac") == 0 ||
strcmp(codec, "opus") == 0 ||
strcmp(codec, "hevc") == 0 ||
strcmp(codec, "h264") == 0;
} else if (format == "mkv") {
/* MKV eats everything. */
is_compatible = true;
} else {
is_compatible = ff_format_codec_compatible( is_compatible = ff_format_codec_compatible(
codec, format.c_str()); codec, format.c_str());
}
QStandardItemModel *model = QStandardItemModel *model =
dynamic_cast<QStandardItemModel *>(cbox->model()); dynamic_cast<QStandardItemModel *>(cbox->model());
@ -5011,8 +5034,6 @@ void OBSBasicSettings::AdvOutRecCheckCodecs()
/* Remove leading "f" for fragmented MP4/MOV */ /* Remove leading "f" for fragmented MP4/MOV */
if (format == "fmp4" || format == "fmov") if (format == "fmp4" || format == "fmov")
format = format.erase(0, 1); format = format.erase(0, 1);
else if (format == "m3u8")
format = "hls";
QString streamEncoder = ui->advOutEncoder->currentData().toString(); QString streamEncoder = ui->advOutEncoder->currentData().toString();
@ -5655,23 +5676,12 @@ static void DisableIncompatibleSimpleCodecs(QComboBox *cbox,
codec = obs_get_encoder_codec(encoder_id); codec = obs_get_encoder_codec(encoder_id);
} }
bool is_compatible = true;
if (format == "flv") {
/* If FLV, only H.264 and AAC are compatible */
is_compatible = codec == "aac" || codec == "h264";
} else if (format == "mov" || format == "fmov") {
/* If MOV, Opus is not compatible */
is_compatible = codec != "opus";
} else if (format == "ts") {
/* If MPEG-TS, AV1 is incompatible */
is_compatible = codec != "av1";
}
QStandardItemModel *model = QStandardItemModel *model =
dynamic_cast<QStandardItemModel *>(cbox->model()); dynamic_cast<QStandardItemModel *>(cbox->model());
QStandardItem *item = model->item(idx); QStandardItem *item = model->item(idx);
if (is_compatible) { if (ContainerSupportsCodec(QT_TO_UTF8(format),
QT_TO_UTF8(codec))) {
item->setFlags(Qt::ItemIsSelectable | item->setFlags(Qt::ItemIsSelectable |
Qt::ItemIsEnabled); Qt::ItemIsEnabled);
} else { } else {
@ -5701,23 +5711,12 @@ static void DisableIncompatibleSimpleContainer(QComboBox *cbox,
for (int idx = 0; idx < cbox->count(); idx++) { for (int idx = 0; idx < cbox->count(); idx++) {
QString format = cbox->itemData(idx).toString(); QString format = cbox->itemData(idx).toString();
bool is_compatible = true;
if (format == "flv") {
/* If flv, ónly H.264 and AAC are compatible */
is_compatible = aCodec == "aac" && vCodec == "h264";
} else if (format == "mov" || format == "fmov") {
/* If MOV, Opus is not compatible */
is_compatible = aCodec != "opus";
} else if (format == "ts") {
/* If MPEG-TS, AV1 is incompatible */
is_compatible = vCodec != "av1";
}
QStandardItemModel *model = QStandardItemModel *model =
dynamic_cast<QStandardItemModel *>(cbox->model()); dynamic_cast<QStandardItemModel *>(cbox->model());
QStandardItem *item = model->item(idx); QStandardItem *item = model->item(idx);
if (is_compatible) { if (ContainerSupportsCodec(QT_TO_UTF8(format),
QT_TO_UTF8(vCodec))) {
item->setFlags(Qt::ItemIsSelectable | item->setFlags(Qt::ItemIsSelectable |
Qt::ItemIsEnabled); Qt::ItemIsEnabled);
} else { } else {