vainfo-源码分析
vainfo是一个用于查询VA-API(Video Acceleration API)配置信息的命令行工具。它能显示系统视频加速硬件支持的编解码profile、entrypoint及详细参数,支持基本和详细两种输出模式。基本模式显示驱动版本和profile/entrypoint组合,而详细模式(使用-a选项)会展示每个组合的具体配置属性。源码分析表明,main函数通过调用VA-API接口查询配置信
一、vainfo工具概述
vainfo是一个用于显示系统上VA-API(Video Acceleration API)配置信息和支持功能的命令行工具。它能够查询并展示系统视频加速硬件和驱动程序支持的编解码profile、entrypoint以及详细的配置参数,是开发和调试视频加速应用程序的重要工具。
项目地址:https://github.com/intel/libva-utils/blob/master/vainfo/vainfo.c

1. vainfo工具输出格式详解
通过分析vainfo.c文件的源代码,可以详细了解vainfo工具的输出格式生成逻辑。vainfo支持两种输出模式:基本输出模式和详细输出模式(使用-a选项)。
1.1 基本输出示例
默认情况下(不使用-a选项),vainfo会显示以下信息:
- VA-API版本和驱动版本信息
- 支持的编解码profile和entrypoint组合
以下是基本输出的示例格式:
libva info: VA-API version X.X.X
libva info: Driver version X.X.X
libva info: Trying to open /path/to/driver.so
libva info: Found init function __vaDriverInit_XX
vainfo: VA-API version: X.X.X (libva X.X.X)
vainfo: Driver version: X.X.X
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264Main : VAEntrypointVLD
VAProfileH264High : VAEntrypointVLD
1.2 详细输出示例(使用-a选项)
当使用-a或–all选项时,vainfo会显示每个profile/entrypoint组合的详细配置属性信息,包括像素格式、编码参数、解码参数等。
详细输出示例(部分):
libva info: VA-API version X.X.X
libva info: Driver version X.X.X
...
vainfo: VAProfileH264Main : VAEntrypointEncSlice
VAConfigAttribRTFormat : VA_RT_FORMAT_YUV420
VAConfigAttribEncRateControl : VA_RC_CBR | VA_RC_VBR
VAConfigAttribEncIntraRefresh : VA_ENC_INTRA_REFRESH_MAX 1
VAConfigAttribEncMaxRefFrames : 16
VAConfigAttribEncMaxSlices : 16
...
2. main函数流程和功能分析
main函数是vainfo工具的核心,负责整个程序的执行流程。通过分析vainfo.c文件的main函数代码,可以详细了解其功能实现。
2.1 核心代码解析
main函数的核心实现代码如下:
int main(int argc, char **argv)
{
VADisplay display;
VAStatus va_status;
int major_version, minor_version;
int i, j, k, num_profiles, num_entrypoints, num_attribs;
VAProfile *profile_list = NULL;
VAEntrypoint *entrypoint_list = NULL;
VAConfigAttrib *attrib_list = NULL;
VAGenericID config_id;
int ret = 0;
const char *display_name = NULL;
int option_index = 0;
// 命令行参数解析
parse_args(argc, argv, &display_name);
// VA显示设备初始化
display = va_open_display(display_name);
if (!display)
exit(1);
// 查询VA-API版本
va_status = vaInitialize(display, &major_version, &minor_version);
CHECK_VASTATUS("vaInitialize", va_status);
// 打印版本信息
printf("vainfo: VA-API version: %d.%d (libva %d.%d.%d)\n",
major_version, minor_version, LIBVA_MAJOR_VERSION,
LIBVA_MINOR_VERSION, LIBVA_MICRO_VERSION);
printf("vainfo: Driver version: %s\n", vaQueryVendorString(display));
// 查询并显示配置信息
va_status = vaQueryConfigProfiles(display, &profile_list, &num_profiles);
CHECK_VASTATUS("vaQueryConfigProfiles", va_status);
// 遍历所有profile
for (i = 0; i < num_profiles; i++) {
// 查询每个profile支持的entrypoint
va_status = vaQueryConfigEntrypoints(display, profile_list[i],
&entrypoint_list, &num_entrypoints);
CHECK_VASTATUS("vaQueryConfigEntrypoints", va_status);
// 遍历所有entrypoint
for (j = 0; j < num_entrypoints; j++) {
// 根据show_all_opt决定输出模式
if (show_all_opt) {
// 详细模式:创建配置并查询属性
va_status = vaCreateConfig(display, profile_list[i],
entrypoint_list[j],
NULL, 0, &config_id);
if (va_status != VA_STATUS_SUCCESS)
continue;
// 查询并显示详细配置属性
va_status = vaQueryConfigAttributes(display, profile_list[i],
entrypoint_list[j],
NULL, &num_attribs);
if (va_status == VA_STATUS_SUCCESS) {
attrib_list = malloc(num_attribs * sizeof(VAConfigAttrib));
// 查询并显示属性
va_status = vaQueryConfigAttributes(display,
profile_list[i],
entrypoint_list[j],
attrib_list, &num_attribs);
show_config_attributes(attrib_list, num_attribs);
free(attrib_list);
}
vaDestroyConfig(display, config_id);
} else {
// 基本模式:仅显示profile和entrypoint组合
printf(" %-32s: %s\n",
vaProfileStr(profile_list[i]),
vaEntrypointStr(entrypoint_list[j]));
}
}
free(entrypoint_list);
}
// 资源清理
free(profile_list);
vaTerminate(display);
va_close_display(display);
return ret;
}
2.2 执行流程详解
main函数的执行流程可以分为以下几个关键步骤:
-
初始化与参数解析
- 调用
parse_args函数解析命令行参数 - 设置
show_all_opt全局变量,控制是否显示详细配置属性 - 支持的命令行选项包括
--help和-a/--all
- 调用
-
VA-API显示设备初始化
- 调用
va_open_display函数初始化VA显示设备 - 调用
vaInitialize函数初始化VA-API并获取版本信息 - 使用
CHECK_VASTATUS宏检查VA函数调用的返回状态
- 调用
-
版本信息显示
- 打印VA-API版本号(运行时版本和编译时版本)
- 打印驱动程序版本信息
- 这些信息由
vaQueryVendorString函数获取
-
配置查询
- 调用
vaQueryConfigProfiles函数获取所有支持的profile - 对每个profile,调用
vaQueryConfigEntrypoints函数获取其支持的entrypoint - 这些信息通过动态内存分配存储在
profile_list和entrypoint_list中
- 调用
-
输出模式
- 默认模式:仅显示支持的profile和entrypoint组合,使用格式化输出
- 详细模式(-a选项):对于每个profile/entrypoint组合:
- 调用
vaCreateConfig创建配置 - 调用
vaQueryConfigAttributes查询配置属性 - 调用
show_config_attributes函数显示详细属性信息 - 调用
vaDestroyConfig销毁配置
- 调用
-
资源清理
- 释放动态分配的内存
- 调用
vaTerminate终止VA-API会话 - 调用
va_close_display关闭显示设备
3. -a选项输出的编解码参数功能
使用-a选项时,vainfo会通过show_config_attributes函数输出详细的编解码参数。这些参数涵盖了视频处理的各个方面。
3.1 基本视频格式参数
这些参数定义了视频处理支持的基本格式和能力:
-
像素格式支持(VAConfigAttribRTFormat)
- 显示支持的YUV和RGB系列格式,如YUV420、YUV422、YUV444、RGB等
- 代码实现:
if (attrib_list[VAConfigAttribRTFormat].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribRTFormat : "); print_rt_format(attrib_list[VAConfigAttribRTFormat].value); printf("\n"); }
-
空间残差(VAConfigAttribSpatialResidual)
- 支持的空间残差处理能力,影响视频编码质量
-
空间裁剪(VAConfigAttribSpatialCropping)
- 是否支持视频帧的空间裁剪功能
-
帧内残差(VAConfigAttribIntraResidual)
- 帧内编码的残差处理支持情况
-
加密属性(VAConfigAttribEncryption)
- 内容保护相关功能支持,如DRM等
3.2 编码专用参数
这些参数特定于视频编码功能:
-
码率控制模式(VAConfigAttribEncRateControl)
- 支持的码率控制方式,如CBR(恒定码率)、VBR(可变码率)等
- 代码实现:
if (attrib_list[VAConfigAttribEncRateControl].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribEncRateControl : "); print_enc_rate_control(attrib_list[VAConfigAttribEncRateControl].value); printf("\n"); }
-
交织模式(VAConfigAttribEncInterlaced)
- 是否支持隔行扫描编码
- 代码实现:
if (attrib_list[VAConfigAttribEncInterlaced].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribEncInterlaced : "); print_boolean(attrib_list[VAConfigAttribEncInterlaced].value); printf("\n"); }
-
最大参考帧(VAConfigAttribEncMaxRefFrames)
- 编码时可使用的最大参考帧数
- 影响编码效率和图像质量
-
最大瓦片/切片数(VAConfigAttribEncMaxTemporalLayers等)
- 编码可分割的最大瓦片行数/列数和切片数
- 与并行编码性能相关
-
切片结构(VAConfigAttribEncSliceStructure)
- 支持的切片组织结构,如灵活宏块排序(FMO)等
-
宏块信息(VAConfigAttribEncMacroblockInfo)
- 宏块级别的参数设置和支持情况
3.3 解码专用参数
这些参数特定于视频解码功能:
-
解码切片模式(VAConfigAttribDecSliceMode)
- 支持的解码切片处理方式
- 影响解码器处理效率
-
JPEG解码旋转(VAConfigAttribDecJPEG, VAConfigAttribDecJPEG ROT)
- JPEG解码时支持的旋转角度(0°、90°、180°、270°)
- 代码实现:
if (attrib_list[VAConfigAttribDecJPEG].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribDecJPEG : "); print_boolean(attrib_list[VAConfigAttribDecJPEG].value); printf("\n"); } if (attrib_list[VAConfigAttribDecJPEG_ROT].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribDecJPEG_ROT : "); print_jpeg_rot(attrib_list[VAConfigAttribDecJPEG_ROT].value); printf("\n"); }
-
解码处理类型(VAConfigAttribDecProcessing)
- 解码处理的类型支持,如是否支持I/P/B帧等
3.4 JPEG编码特定参数
这些参数特定于JPEG编码功能:
-
算术编码模式(VAConfigAttribEncJPEG, VAConfigAttribEncJPEG_ARITH)
- 是否支持JPEG算术编码模式
- 代码实现:
if (attrib_list[VAConfigAttribEncJPEG].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribEncJPEG : "); print_boolean(attrib_list[VAConfigAttribEncJPEG].value); printf("\n"); } if (attrib_list[VAConfigAttribEncJPEG_ARITH].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribEncJPEG_ARITH : "); print_boolean(attrib_list[VAConfigAttribEncJPEG_ARITH].value); printf("\n"); }
-
渐进DCT模式(VAConfigAttribEncJPEG_PROG)
- 是否支持JPEG渐进式DCT变换
-
质量范围(VAConfigAttribEncJPEG_QUALITY)
- JPEG编码的质量参数范围(通常为0-100)
-
量化方式(VAConfigAttribEncJPEG_QTABLE)
- 支持的量化方式和量化表设置
3.5 性能和多帧处理参数
这些参数与编码解码性能和多帧处理能力相关:
-
帧内刷新(VAConfigAttribEncIntraRefresh)
- 是否支持帧内刷新功能
- 用于错误恢复和网络适应性
- 代码实现:
if (attrib_list[VAConfigAttribEncIntraRefresh].value != VA_ATTRIB_NOT_SUPPORTED) { printf(" VAConfigAttribEncIntraRefresh : VA_ENC_INTRA_REFRESH_MAX %d\n", attrib_list[VAConfigAttribEncIntraRefresh].value); }
-
ROI支持(VAConfigAttribEncROI)
- 是否支持感兴趣区域(Region of Interest)编码
- 允许对视频中重要区域进行更高质量编码
-
并行码率控制(VAConfigAttribEncParallelRateControl)
- 是否支持并行码率控制
- 影响编码性能
-
动态缩放(VAConfigAttribEncDynamicScaling)
- 是否支持动态分辨率缩放
- 用于自适应比特率流
-
FEI功能(VAConfigAttribEncFEIFunctionType)
- 前端集成(Front End Integration)功能支持情况
- 如运动估计、去方块滤波等预处理功能
-
MV预测器数量(VAConfigAttribEncMV_PRED)
- 运动矢量预测器数量
- 影响编码效率和运动补偿精度
3.6 代码实现解析
show_config_attributes函数是实现-a选项详细输出的核心函数。以下是该函数的部分关键实现:
static void show_config_attributes(VAConfigAttrib *attrib_list, int num_attribs)
{
int i;
// 遍历所有配置属性
for (i = 0; i < num_attribs; i++) {
switch (attrib_list[i].type) {
case VAConfigAttribRTFormat:
// 显示像素格式
if (attrib_list[i].value != VA_ATTRIB_NOT_SUPPORTED) {
printf(" VAConfigAttribRTFormat : ");
print_rt_format(attrib_list[i].value);
printf("\n");
}
break;
case VAConfigAttribEncRateControl:
// 显示码率控制模式
if (attrib_list[i].value != VA_ATTRIB_NOT_SUPPORTED) {
printf(" VAConfigAttribEncRateControl : ");
print_enc_rate_control(attrib_list[i].value);
printf("\n");
}
break;
// 其他属性类型...
default:
// 对于不常见的属性类型,以十六进制显示
printf(" VAConfigAttrib(%d) : 0x%x\n",
attrib_list[i].type, attrib_list[i].value);
break;
}
}
}
该函数通过switch语句处理不同类型的配置属性,并调用相应的打印函数(如print_rt_format、print_enc_rate_control等)将属性值转换为人类可读的格式。对于不支持的属性,使用VA_ATTRIB_NOT_SUPPORTED标记进行判断,只显示系统支持的属性。
二、总结
vainfo工具是一个强大的VA-API诊断工具,通过分析其源代码可以深入了解VA-API的工作原理和系统的视频加速能力。main函数实现了完整的VA-API交互流程,包括初始化、查询和资源清理。而show_config_attributes函数则负责将复杂的配置参数转换为人类可读的格式。
-a选项输出的详细参数信息对于开发者了解系统的视频加速能力、选择合适的编解码配置以及进行性能优化都具有重要参考价值。实际输出内容会因系统硬件和驱动程序的不同而有所差异,但基本结构和参数类型保持一致。
三、举例
$ vainfo
libva info: VA-API version 1.14.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/zx_drv_video.so
libva info: Found init function __vaDriverInit_1_0
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.14 (libva 2.4.0)
vainfo: Driver version: ZX_VA
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG4Simple : VAEntrypointVLD
VAProfileMPEG4AdvancedSimple : VAEntrypointVLD
<unknown profile> : VAEntrypointVLD
<unknown profile> : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileH263Baseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileNone : VAEntrypointVideoProc
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileH264MultiviewHigh : VAEntrypointVLD
VAProfileH264MultiviewHigh : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileH264StereoHigh : VAEntrypointEncSlice
VAProfileVP8Version0_3 : VAEntrypointVLD
<unknown profile> : VAEntrypointVLD
<unknown profile> : VAEntrypointVLD
<unknown profile> : VAEntrypointVLD
1. 解码 (Decoding)
VAEntrypointVLD - Variable Length Decoding
支持的解码格式:MPEG2、MPEG4、H.264、VC1、H.263、JPEG、HEVC、VP8等
- MPEG2 Simple/Main
- MPEG4 Simple/AdvancedSimple
- H.264 Main/High/ConstrainedBaseline/MultiviewHigh/StereoHigh
- VC1 Simple/Main/Advanced
- H.263 Baseline
- JPEG Baseline
- HEVC Main/Main10
- VP8
2. 编码 (Encoding)
VAEntrypointEncSlice - 编码切片
VAEntrypointEncPicture - 编码图片
支持的编码格式:H.264、HEVC、JPEG
- H.264 Main/High/ConstrainedBaseline/MultiviewHigh/StereoHigh
- HEVC Main/Main10
- JPEG Baseline
3. 其他
VAProfileNone + VAEntrypointVideoProc
四、补充
EncSlice:用于视频编码,将帧分割成切片并行处理,支持 H.264、HEVC 等
EncPicture:用于图片编码,整帧处理,主要支持 JPEG
1. VA-API 架构
应用程序 → VA-API 接口 → 显卡驱动 → 硬件编码器
VA-API 是英特尔主导的开源视频加速接口,让应用程序能调用显卡的硬件编解码功能。
2. 编码条目点 (Encode Entrypoints)
2.1 VAEntrypointEncSlice - 编码切片
这是最常用的视频编码条目点。
工作原理:
- 切片(Slice):将一帧图像分割成多个独立编码的单元
- 并行处理:多个切片可以并行编码,提高效率
- 错误恢复:某个切片出错不影响其他切片
支持格式:
- H.264/AVC
- H.265/HEVC
- VP9
- AV1
编码流程:
text
原始帧 → 分割成切片 → 各切片独立编码 → 组合成码流
2.2 VAEntrypointEncPicture - 图片编码
特点:
- 针对整帧图片进行编码
- 主要用于静态图片编码
- 不支持切片分割
支持格式:
- JPEG 和 MJPEG( Motion JPEG)
3. 与具体编码格式的关系
3.1 H.264 与 EncSlice
# 你的 vainfo 输出显示:
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSlice
H.264 切片结构:
一帧画面
├── 切片 #1 (独立编码)
├── 切片 #2 (独立编码)
├── 切片 #3 (独立编码)
└── 切片 #4 (独立编码)
特点:
- 每个切片包含完整的编码信息
- 支持帧内预测和帧间预测
- 适合实时视频编码
3.2 JPEG 与 EncPicture
# 你的 vainfo 输出显示:
VAProfileJPEGBaseline : VAEntrypointEncPicture
JPEG 编码流程:
完整图片 → DCT变换 → 量化 → 熵编码 → JPEG文件
特点:
- 整张图片一次性处理
- 基于 DCT 变换的压缩
- 适合静态图片编码
- 技术细节对比
| 特性 | EncSlice | EncPicture |
|---|---|---|
| 处理单元 | 切片(Slice) | 整帧(Picture) |
| 主要用途 | 视频编码 | 图片编码 |
| 并行性 | 高(切片级并行) | 低(帧级) |
| 延迟 | 较低 | 较高 |
| 容错性 | 好(错误隔离) | 差(整帧影响) |
| 支持格式 | H.264, HEVC, VP9 | JPEG, MJPEG |
更多推荐


所有评论(0)