Codec (Linux): adds FFCodecShowOptions; code cleanup

This commit is contained in:
Carter Li
2026-06-01 18:02:15 +08:00
committed by 李通洲
parent 2c65eee00f
commit 35428606e7
4 changed files with 126 additions and 137 deletions
+19
View File
@@ -1914,6 +1914,25 @@
"type": "boolean",
"default": false
},
"showType": {
"description": "Which types of codecs to detect and show",
"type": "string",
"oneOf": [
{
"const": "both",
"description": "Show both decoders and encoders"
},
{
"const": "decoder",
"description": "Show only decoders"
},
{
"const": "encoder",
"description": "Show only encoders"
}
],
"default": "both"
},
"key": {
"$ref": "#/$defs/key"
},
+67 -137
View File
@@ -203,7 +203,7 @@ static void ffCodecFillGpuName(const drmDevice* dev, const char* path, FFstrbuf*
}
}
static const char* ffDetectCodecByVa(FFlist* result, bool* initialized) {
static const char* ffDetectCodecByVa(FFCodecOptions* options, FFlist* result, bool* initialized) {
*initialized = false;
FF_LIBRARY_LOAD_MESSAGE(libdrm, "libdrm" FF_LIBRARY_EXTENSION, 2)
@@ -288,23 +288,25 @@ static const char* ffDetectCodecByVa(FFlist* result, bool* initialized) {
FFCodecType decoderTypes = FF_CODEC_TYPE_NONE;
FFCodecType encoderTypes = FF_CODEC_TYPE_NONE;
for (int j = 0; j < numProfiles; ++j) {
bool hasDecoder = ffCodecProfileHasOutput(
display,
ffvaQueryConfigEntrypoints,
ffvaGetConfigAttributes,
maxEntrypoints,
entrypoints,
profiles[j],
false);
bool hasDecoder = (options->showType & FF_CODEC_SHOW_TYPE_DECODER) &&
ffCodecProfileHasOutput(
display,
ffvaQueryConfigEntrypoints,
ffvaGetConfigAttributes,
maxEntrypoints,
entrypoints,
profiles[j],
false);
bool hasEncoder = ffCodecProfileHasOutput(
display,
ffvaQueryConfigEntrypoints,
ffvaGetConfigAttributes,
maxEntrypoints,
entrypoints,
profiles[j],
true);
bool hasEncoder = (options->showType & FF_CODEC_SHOW_TYPE_ENCODER) &&
ffCodecProfileHasOutput(
display,
ffvaQueryConfigEntrypoints,
ffvaGetConfigAttributes,
maxEntrypoints,
entrypoints,
profiles[j],
true);
if (!hasDecoder && !hasEncoder) {
continue;
@@ -312,10 +314,10 @@ static const char* ffDetectCodecByVa(FFlist* result, bool* initialized) {
FFCodecType type = ffCodecProfileToType(profiles[j]);
if (hasDecoder) {
decoderTypes = (FFCodecType) ((uint32_t) decoderTypes | (uint32_t) type);
decoderTypes |= type;
}
if (hasEncoder) {
encoderTypes = (FFCodecType) ((uint32_t) encoderTypes | (uint32_t) type);
encoderTypes |= type;
}
}
@@ -341,123 +343,51 @@ static const struct FFCodecVdpauCodec {
VdpDecoderProfile profile;
FFCodecType type;
} FF_CODEC_VDPAU_CODECS[] = {
#ifdef VDP_DECODER_PROFILE_MPEG1
{ VDP_DECODER_PROFILE_MPEG1, FF_CODEC_TYPE_MPEG1 },
#endif
#ifdef VDP_DECODER_PROFILE_MPEG2_SIMPLE
{ VDP_DECODER_PROFILE_MPEG2_SIMPLE, FF_CODEC_TYPE_MPEG2 },
#endif
#ifdef VDP_DECODER_PROFILE_MPEG2_MAIN
{ VDP_DECODER_PROFILE_MPEG2_MAIN, FF_CODEC_TYPE_MPEG2 },
#endif
#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_SP
{ VDP_DECODER_PROFILE_MPEG4_PART2_SP, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_MPEG4_PART2_ASP
{ VDP_DECODER_PROFILE_MPEG4_PART2_ASP, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX4_QMOBILE
{ VDP_DECODER_PROFILE_DIVX4_QMOBILE, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX4_MOBILE
{ VDP_DECODER_PROFILE_DIVX4_MOBILE, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX4_HOME_THEATER
{ VDP_DECODER_PROFILE_DIVX4_HOME_THEATER, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX4_HD_1080P
{ VDP_DECODER_PROFILE_DIVX4_HD_1080P, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX5_QMOBILE
{ VDP_DECODER_PROFILE_DIVX5_QMOBILE, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX5_MOBILE
{ VDP_DECODER_PROFILE_DIVX5_MOBILE, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX5_HOME_THEATER
{ VDP_DECODER_PROFILE_DIVX5_HOME_THEATER, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_DIVX5_HD_1080P
{ VDP_DECODER_PROFILE_DIVX5_HD_1080P, FF_CODEC_TYPE_DIVX_XVID },
#endif
#ifdef VDP_DECODER_PROFILE_H264_BASELINE
{ VDP_DECODER_PROFILE_H264_BASELINE, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_MAIN
{ VDP_DECODER_PROFILE_H264_MAIN, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_HIGH
{ VDP_DECODER_PROFILE_H264_HIGH, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE
{ VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_EXTENDED
{ VDP_DECODER_PROFILE_H264_EXTENDED, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_PROGRESSIVE_HIGH
{ VDP_DECODER_PROFILE_H264_PROGRESSIVE_HIGH, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_CONSTRAINED_HIGH
{ VDP_DECODER_PROFILE_H264_CONSTRAINED_HIGH, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
{ VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE, FF_CODEC_TYPE_H264 },
#endif
#ifdef VDP_DECODER_PROFILE_VC1_SIMPLE
{ VDP_DECODER_PROFILE_VC1_SIMPLE, FF_CODEC_TYPE_VC1 },
#endif
#ifdef VDP_DECODER_PROFILE_VC1_MAIN
{ VDP_DECODER_PROFILE_VC1_MAIN, FF_CODEC_TYPE_VC1 },
#endif
#ifdef VDP_DECODER_PROFILE_VC1_ADVANCED
{ VDP_DECODER_PROFILE_VC1_ADVANCED, FF_CODEC_TYPE_VC1 },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN
{ VDP_DECODER_PROFILE_HEVC_MAIN, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_10
{ VDP_DECODER_PROFILE_HEVC_MAIN_10, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_STILL
{ VDP_DECODER_PROFILE_HEVC_MAIN_STILL, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_12
{ VDP_DECODER_PROFILE_HEVC_MAIN_12, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444
{ VDP_DECODER_PROFILE_HEVC_MAIN_444, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_10
{ VDP_DECODER_PROFILE_HEVC_MAIN_444_10, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_12
{ VDP_DECODER_PROFILE_HEVC_MAIN_444_12, FF_CODEC_TYPE_HEVC },
#endif
#ifdef VDP_DECODER_PROFILE_VP9_PROFILE_0
{ VDP_DECODER_PROFILE_VP9_PROFILE_0, FF_CODEC_TYPE_VP9 },
#endif
#ifdef VDP_DECODER_PROFILE_VP9_PROFILE_1
{ VDP_DECODER_PROFILE_VP9_PROFILE_1, FF_CODEC_TYPE_VP9 },
#endif
#ifdef VDP_DECODER_PROFILE_VP9_PROFILE_2
{ VDP_DECODER_PROFILE_VP9_PROFILE_2, FF_CODEC_TYPE_VP9 },
#endif
#ifdef VDP_DECODER_PROFILE_VP9_PROFILE_3
{ VDP_DECODER_PROFILE_VP9_PROFILE_3, FF_CODEC_TYPE_VP9 },
#endif
#ifdef VDP_DECODER_PROFILE_AV1_MAIN
{ VDP_DECODER_PROFILE_AV1_MAIN, FF_CODEC_TYPE_AV1 },
#endif
#ifdef VDP_DECODER_PROFILE_AV1_HIGH
{ VDP_DECODER_PROFILE_AV1_HIGH, FF_CODEC_TYPE_AV1 },
#endif
#ifdef VDP_DECODER_PROFILE_AV1_PROFESSIONAL
{ VDP_DECODER_PROFILE_AV1_PROFESSIONAL, FF_CODEC_TYPE_AV1 },
#endif
{ 0, FF_CODEC_TYPE_MPEG1 }, // VDP_DECODER_PROFILE_MPEG1
{ 1, FF_CODEC_TYPE_MPEG2 }, // VDP_DECODER_PROFILE_MPEG2_SIMPLE
{ 2, FF_CODEC_TYPE_MPEG2 }, // VDP_DECODER_PROFILE_MPEG2_MAIN
{ 12, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_MPEG4_PART2_SP
{ 13, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_MPEG4_PART2_ASP
{ 14, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX4_QMOBILE
{ 15, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX4_MOBILE
{ 16, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX4_HOME_THEATER
{ 17, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX4_HD_1080P
{ 18, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX5_QMOBILE
{ 19, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX5_MOBILE
{ 20, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX5_HOME_THEATER
{ 21, FF_CODEC_TYPE_DIVX_XVID }, // VDP_DECODER_PROFILE_DIVX5_HD_1080P
{ 6, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_BASELINE
{ 7, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_MAIN
{ 8, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_HIGH
{ 22, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE
{ 23, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_EXTENDED
{ 24, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_PROGRESSIVE_HIGH
{ 25, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_CONSTRAINED_HIGH
{ 26, FF_CODEC_TYPE_H264 }, // VDP_DECODER_PROFILE_H264_HIGH_444_PREDICTIVE
{ 9, FF_CODEC_TYPE_VC1 }, // VDP_DECODER_PROFILE_VC1_SIMPLE
{ 10, FF_CODEC_TYPE_VC1 }, // VDP_DECODER_PROFILE_VC1_MAIN
{ 11, FF_CODEC_TYPE_VC1 }, // VDP_DECODER_PROFILE_VC1_ADVANCED
{ 100, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN
{ 101, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_10
{ 102, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_STILL
{ 103, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_12
{ 104, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_444
{ 105, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_444_10
{ 106, FF_CODEC_TYPE_HEVC }, // VDP_DECODER_PROFILE_HEVC_MAIN_444_12
{ 27, FF_CODEC_TYPE_VP9 }, // VDP_DECODER_PROFILE_VP9_PROFILE_0
{ 28, FF_CODEC_TYPE_VP9 }, // VDP_DECODER_PROFILE_VP9_PROFILE_1
{ 29, FF_CODEC_TYPE_VP9 }, // VDP_DECODER_PROFILE_VP9_PROFILE_2
{ 30, FF_CODEC_TYPE_VP9 }, // VDP_DECODER_PROFILE_VP9_PROFILE_3
{ 107, FF_CODEC_TYPE_AV1 }, // VDP_DECODER_PROFILE_AV1_MAIN
{ 108, FF_CODEC_TYPE_AV1 }, // VDP_DECODER_PROFILE_AV1_HIGH
{ 109, FF_CODEC_TYPE_AV1 }, // VDP_DECODER_PROFILE_AV1_PROFESSIONAL
};
static const char* ffDetectCodecByVdpau(FFlist* result) {
static const char* ffDetectCodecByVdpau(FFCodecOptions* options, FFlist* result) {
if (options->showType == FF_CODEC_SHOW_TYPE_DECODER) {
return "VDPAU only supports decoding";
}
FF_LIBRARY_LOAD_MESSAGE(libX11, "libX11" FF_LIBRARY_EXTENSION, 6)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libX11, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libX11, XCloseDisplay)
@@ -529,19 +459,19 @@ static const char* ffDetectCodecByVdpau(FFlist* result) {
}
#endif
const char* ffDetectCodecNative(FF_A_UNUSED FFCodecOptions* options, FFlist* result /* list of FFCodecResult */) {
const char* ffDetectCodecNative(FFCodecOptions* options, FFlist* result /* list of FFCodecResult */) {
FF_SUPPRESS_IO();
#if FF_CODEC_HAVE_VA
bool vaInitialized = false;
const char* vaError = ffDetectCodecByVa(result, &vaInitialized);
const char* vaError = ffDetectCodecByVa(options, result, &vaInitialized);
if (vaError == NULL && vaInitialized) {
return NULL;
}
#endif
#if FF_CODEC_HAVE_VDPAU
return ffDetectCodecByVdpau(result);
return ffDetectCodecByVdpau(options, result);
#endif
return "Fastfetch was built without DRM / VA-API / VDPAU headers";
+31
View File
@@ -159,6 +159,22 @@ void ffParseCodecJsonObject(FFCodecOptions* options, yyjson_val* module) {
continue;
}
if (unsafe_yyjson_equals_str(key, "showType")) {
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]){
{ "encoder", FF_CODEC_SHOW_TYPE_ENCODER },
{ "decoder", FF_CODEC_SHOW_TYPE_DECODER },
{ "both", FF_CODEC_SHOW_TYPE_BOTH },
{},
});
if (error) {
ffPrintError(FF_CODEC_MODULE_NAME, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "Invalid %s value: %s", unsafe_yyjson_get_str(key), error);
} else {
options->showType = (FFCodecShowType) value;
}
continue;
}
ffPrintError(FF_CODEC_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
}
}
@@ -167,6 +183,20 @@ void ffGenerateCodecJsonConfig(FFCodecOptions* options, yyjson_mut_doc* doc, yyj
ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
yyjson_mut_obj_add_bool(doc, module, "splitGPU", options->splitGPU);
yyjson_mut_obj_add_bool(doc, module, "useVulkan", options->useVulkan);
switch (options->showType) {
case FF_CODEC_SHOW_TYPE_ENCODER:
yyjson_mut_obj_add_str(doc, module, "showType", "encoder");
break;
case FF_CODEC_SHOW_TYPE_DECODER:
yyjson_mut_obj_add_str(doc, module, "showType", "decoder");
break;
case FF_CODEC_SHOW_TYPE_BOTH:
yyjson_mut_obj_add_str(doc, module, "showType", "both");
break;
default:
break;
}
}
bool ffGenerateCodecJsonResult(FFCodecOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
@@ -208,6 +238,7 @@ void ffInitCodecOptions(FFCodecOptions* options) {
ffOptionInitModuleArg(&options->moduleArgs, "󰈫");
options->splitGPU = false;
options->useVulkan = false;
options->showType = FF_CODEC_SHOW_TYPE_BOTH;
}
void ffDestroyCodecOptions(FFCodecOptions* options) {
+9
View File
@@ -2,10 +2,19 @@
#include "common/option.h"
typedef enum FF_A_PACKED FFCodecShowType {
FF_CODEC_SHOW_TYPE_NONE = 0,
FF_CODEC_SHOW_TYPE_ENCODER = 1 << 0,
FF_CODEC_SHOW_TYPE_DECODER = 1 << 1,
FF_CODEC_SHOW_TYPE_BOTH = FF_CODEC_SHOW_TYPE_ENCODER | FF_CODEC_SHOW_TYPE_DECODER,
FF_CODEC_SHOW_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFCodecShowType;
typedef struct FFCodecOptions {
FFModuleArgs moduleArgs;
bool splitGPU;
bool useVulkan;
FFCodecShowType showType;
} FFCodecOptions;
static_assert(sizeof(FFCodecOptions) <= FF_OPTION_MAX_SIZE, "FFCodecOptions size exceeds maximum allowed size");