diff --git a/UI/ffmpeg-utils.cpp b/UI/ffmpeg-utils.cpp index 806473f53..c3cd54eb3 100644 --- a/UI/ffmpeg-utils.cpp +++ b/UI/ffmpeg-utils.cpp @@ -80,29 +80,19 @@ vector GetSupportedFormats() return formats; } -static const char *get_encoder_name(const char *format_name, - enum AVCodecID codec_id) +FFmpegCodec FFmpegFormat::GetDefaultEncoder(FFmpegCodecType codec_type) const { - const AVCodec *codec = avcodec_find_encoder(codec_id); - if (codec == nullptr && codec_id == AV_CODEC_ID_NONE) - return nullptr; - else if (codec == nullptr) - return format_name; - else - return codec->name; -} + const AVCodecID codec_id = codec_type == VIDEO ? video_codec + : audio_codec; + if (codec_type == UNKNOWN || codec_id == AV_CODEC_ID_NONE) + return {}; -const char *FFmpegFormat::GetDefaultName(FFmpegCodecType codec_type) const -{ + if (auto codec = avcodec_find_encoder(codec_id)) + return {codec}; - switch (codec_type) { - case FFmpegCodecType::AUDIO: - return get_encoder_name(name, audio_codec); - case FFmpegCodecType::VIDEO: - return get_encoder_name(name, video_codec); - default: - return nullptr; - } + /* Fall back to using the format name as the encoder, + * this works for some formats such as FLV. */ + return FFmpegCodec{name, codec_id, codec_type}; } bool FFCodecAndFormatCompatible(const char *codec, const char *format) diff --git a/UI/ffmpeg-utils.hpp b/UI/ffmpeg-utils.hpp index 6fb2add9d..c6e23ffce 100644 --- a/UI/ffmpeg-utils.hpp +++ b/UI/ffmpeg-utils.hpp @@ -47,6 +47,8 @@ static bool strequal(const char *a, const char *b) return strcmp(a, b) == 0; } +struct FFmpegCodec; + struct FFmpegFormat { const char *name; const char *long_name; @@ -60,7 +62,12 @@ struct FFmpegFormat { FFmpegFormat(const char *name, const char *mime_type) : name(name), - mime_type(mime_type) + long_name(nullptr), + mime_type(mime_type), + extensions(nullptr), + audio_codec(AV_CODEC_ID_NONE), + video_codec(AV_CODEC_ID_NONE), + codec_tags(nullptr) { } @@ -75,7 +82,7 @@ struct FFmpegFormat { { } - const char *GetDefaultName(FFmpegCodecType codec_type) const; + FFmpegCodec GetDefaultEncoder(FFmpegCodecType codec_type) const; bool HasAudio() const { return audio_codec != AV_CODEC_ID_NONE; } bool HasVideo() const { return video_codec != AV_CODEC_ID_NONE; } @@ -101,6 +108,7 @@ struct FFmpegCodec { FFmpegCodec(const char *name, int id, FFmpegCodecType type = UNKNOWN) : name(name), + long_name(nullptr), id(id), type(type) { diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index 59b494e5c..ae2a3478e 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -199,24 +199,6 @@ static int FindEncoder(QComboBox *combo, const char *name, int id) return -1; } -static FFmpegCodec GetDefaultCodec(const FFmpegFormat &format, - FFmpegCodecType codecType) -{ - int id = 0; - switch (codecType) { - case AUDIO: - id = format.audio_codec; - break; - case VIDEO: - id = format.video_codec; - break; - default: - return FFmpegCodec(); - } - - return FFmpegCodec{format.GetDefaultName(codecType), nullptr, id}; -} - #define INVALID_BITRATE 10000 static int FindClosestAvailableAudioBitrate(QComboBox *box, int bitrate) { @@ -1151,14 +1133,23 @@ static void AddCodec(QComboBox *combo, const FFmpegCodec &codec) static void AddDefaultCodec(QComboBox *combo, const FFmpegFormat &format, FFmpegCodecType codecType) { - FFmpegCodec cd = GetDefaultCodec(format, codecType); + FFmpegCodec codec = format.GetDefaultEncoder(codecType); - int existingIdx = FindEncoder(combo, cd.name, cd.id); + int existingIdx = FindEncoder(combo, codec.name, codec.id); if (existingIdx >= 0) combo->removeItem(existingIdx); - combo->addItem(QString("%1 (%2)").arg(cd.name, AV_ENCODER_DEFAULT_STR), - QVariant::fromValue(cd)); + QString itemText; + if (codec.long_name) { + itemText = QString("%1 - %2 (%3)") + .arg(codec.name, codec.long_name, + AV_ENCODER_DEFAULT_STR); + } else { + itemText = QString("%1 (%2)").arg(codec.name, + AV_ENCODER_DEFAULT_STR); + } + + combo->addItem(itemText, QVariant::fromValue(codec)); } #define AV_ENCODER_DISABLE_STR \ @@ -4386,9 +4377,9 @@ void OBSBasicSettings::on_advOutFFFormat_currentIndexChanged(int idx) ui->advOutFFFormatDesc->setText(format.long_name); FFmpegCodec defaultAudioCodecDesc = - GetDefaultCodec(format, AUDIO); + format.GetDefaultEncoder(FFmpegCodecType::AUDIO); FFmpegCodec defaultVideoCodecDesc = - GetDefaultCodec(format, VIDEO); + format.GetDefaultEncoder(FFmpegCodecType::VIDEO); SelectEncoder(ui->advOutFFAEncoder, defaultAudioCodecDesc.name, defaultAudioCodecDesc.id); SelectEncoder(ui->advOutFFVEncoder, defaultVideoCodecDesc.name,