mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-19 20:32:15 +02:00
UI: Refactor FFmpeg utilities codec/format enumeration
This commit is contained in:
parent
c1cd268532
commit
c20bf0271c
@ -26,71 +26,25 @@ extern "C" {
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void GetCodecsForId(const FFmpegFormat &format,
|
||||
vector<FFmpegCodec> &codecs, enum AVCodecID id,
|
||||
bool ignore_compaibility)
|
||||
{
|
||||
|
||||
const AVCodec *codec = nullptr;
|
||||
void *i = 0;
|
||||
|
||||
while ((codec = av_codec_iterate(&i)) != nullptr) {
|
||||
if (codec->id != id)
|
||||
continue;
|
||||
// Not an encoding codec
|
||||
if (!av_codec_is_encoder(codec))
|
||||
continue;
|
||||
// Skip if not supported and compatibility check not disabled
|
||||
if (!ignore_compaibility &&
|
||||
!av_codec_get_tag(format.codec_tags, codec->id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FFmpegCodec d{codec->name, codec->long_name, codec->id};
|
||||
|
||||
const AVCodec *base_codec = avcodec_find_encoder(codec->id);
|
||||
if (strcmp(base_codec->name, codec->name) != 0) {
|
||||
d.alias = true;
|
||||
d.base_name = base_codec->name;
|
||||
}
|
||||
|
||||
switch (codec->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
d.type = FFmpegCodecType::AUDIO;
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
d.type = FFmpegCodecType::VIDEO;
|
||||
break;
|
||||
default:
|
||||
d.type = FFmpegCodecType::UNKNOWN;
|
||||
}
|
||||
|
||||
codecs.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<const AVCodecDescriptor *> GetCodecDescriptors()
|
||||
{
|
||||
std::vector<const AVCodecDescriptor *> codecs;
|
||||
|
||||
const AVCodecDescriptor *desc = nullptr;
|
||||
while ((desc = avcodec_descriptor_next(desc)) != nullptr)
|
||||
codecs.push_back(desc);
|
||||
|
||||
return codecs;
|
||||
}
|
||||
|
||||
vector<FFmpegCodec> GetFormatCodecs(const FFmpegFormat &format,
|
||||
bool ignore_compatibility)
|
||||
{
|
||||
vector<FFmpegCodec> codecs;
|
||||
auto codecDescriptors = GetCodecDescriptors();
|
||||
const AVCodec *codec;
|
||||
void *i = 0;
|
||||
|
||||
if (codecDescriptors.empty())
|
||||
return codecs;
|
||||
while ((codec = av_codec_iterate(&i)) != nullptr) {
|
||||
// Not an encoding codec
|
||||
if (!av_codec_is_encoder(codec))
|
||||
continue;
|
||||
// Skip if not supported and compatibility check not disabled
|
||||
if (!ignore_compatibility &&
|
||||
!av_codec_get_tag(format.codec_tags, codec->id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const AVCodecDescriptor *codec : codecDescriptors)
|
||||
GetCodecsForId(format, codecs, codec->id, ignore_compatibility);
|
||||
codecs.emplace_back(codec);
|
||||
}
|
||||
|
||||
return codecs;
|
||||
}
|
||||
@ -120,15 +74,7 @@ vector<FFmpegFormat> GetSupportedFormats()
|
||||
if (is_output_device(output_format->priv_class))
|
||||
continue;
|
||||
|
||||
formats.push_back({
|
||||
output_format->name,
|
||||
output_format->long_name,
|
||||
output_format->mime_type,
|
||||
output_format->extensions,
|
||||
output_format->audio_codec,
|
||||
output_format->video_codec,
|
||||
output_format->codec_tag,
|
||||
});
|
||||
formats.emplace_back(output_format);
|
||||
}
|
||||
|
||||
return formats;
|
||||
|
@ -58,6 +58,23 @@ struct FFmpegFormat {
|
||||
|
||||
FFmpegFormat() = default;
|
||||
|
||||
FFmpegFormat(const char *name, const char *mime_type)
|
||||
: name(name),
|
||||
mime_type(mime_type)
|
||||
{
|
||||
}
|
||||
|
||||
FFmpegFormat(const AVOutputFormat *av_format)
|
||||
: name(av_format->name),
|
||||
long_name(av_format->long_name),
|
||||
mime_type(av_format->mime_type),
|
||||
extensions(av_format->extensions),
|
||||
audio_codec(av_format->audio_codec),
|
||||
video_codec(av_format->video_codec),
|
||||
codec_tags(av_format->codec_tag)
|
||||
{
|
||||
}
|
||||
|
||||
const char *GetDefaultName(FFmpegCodecType codec_type) const;
|
||||
|
||||
bool HasAudio() const { return audio_codec != AV_CODEC_ID_NONE; }
|
||||
@ -85,6 +102,30 @@ struct FFmpegCodec {
|
||||
|
||||
FFmpegCodec() = default;
|
||||
|
||||
FFmpegCodec(const char *name, int id, FFmpegCodecType type = UNKNOWN)
|
||||
: name(name),
|
||||
id(id),
|
||||
type(type)
|
||||
{
|
||||
}
|
||||
|
||||
FFmpegCodec(const AVCodec *codec)
|
||||
: name(codec->name),
|
||||
long_name(codec->long_name),
|
||||
id(codec->id)
|
||||
{
|
||||
switch (codec->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
type = AUDIO;
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
type = VIDEO;
|
||||
break;
|
||||
default:
|
||||
type = UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const FFmpegCodec &codec) const
|
||||
{
|
||||
if (id != codec.id)
|
||||
|
@ -186,7 +186,7 @@ static inline QString GetComboData(QComboBox *combo)
|
||||
|
||||
static int FindEncoder(QComboBox *combo, const char *name, int id)
|
||||
{
|
||||
FFmpegCodec codec{name, nullptr, id};
|
||||
FFmpegCodec codec{name, id};
|
||||
|
||||
for (int i = 0; i < combo->count(); i++) {
|
||||
QVariant v = combo->itemData(i);
|
||||
@ -2238,7 +2238,7 @@ void OBSBasicSettings::LoadAdvOutputRecordingEncoderProperties()
|
||||
static void SelectFormat(QComboBox *combo, const char *name,
|
||||
const char *mimeType)
|
||||
{
|
||||
FFmpegFormat format{name, nullptr, mimeType};
|
||||
FFmpegFormat format{name, mimeType};
|
||||
|
||||
for (int i = 0; i < combo->count(); i++) {
|
||||
QVariant v = combo->itemData(i);
|
||||
|
Loading…
Reference in New Issue
Block a user