7.24. 虚拟无状态解码器驱动 (visl)

用于无状态 uAPI 开发的虚拟无状态解码器设备。

此工具的目标是帮助开发和测试使用 V4L2 无状态 API 解码媒体的用户空间应用程序。

即使在没有硬件可用或编解码器的内核 uAPI 尚未上游时,用户空间实现也可以使用 visl 运行解码循环。这可以在早期阶段发现错误。

此驱动程序还可以跟踪提交给它的 V4L2 控制的内容。它还可以通过 debugfs 接口转储 vb2 缓冲区的内容。这在许多方面类似于其他流行的编码/解码 API 可用的跟踪基础设施,并且可以通过使用另一个(工作)应用程序作为参考来帮助开发用户空间应用程序。

注意

visl 不执行实际的视频帧解码。V4L2 测试模式生成器用于将各种调试信息写入捕获缓冲区。

7.24.1. 模块参数

  • visl_debug: 激活调试信息,通过 dprintk 打印各种调试消息。还控制是否显示每帧调试信息。默认为关闭。请注意,启用此功能可能会导致通过串行传输速度缓慢。

  • visl_transtime_ms: 模拟的进程时间,以毫秒为单位。减慢解码速度对于调试可能很有用。

  • visl_dprintk_frame_start, visl_dprintk_frame_nframes: 指示激活 dprintk 的帧范围。这仅控制每帧的 dprintk 跟踪。请注意,通过串行打印大量数据可能会很慢。

  • keep_bitstream_buffers: 控制在解码会话后是否保留比特流(即 OUTPUT)缓冲区。默认为 false,以减少混乱。当使用 GDB 实时调试客户端程序时,keep_bitstream_buffers == false 效果很好。

  • bitstream_trace_frame_start, bitstream_trace_nframes: 类似于 visl_dprintk_frame_start, visl_dprintk_nframes,但控制通过 debugfs 转储缓冲区数据。

  • tpg_verbose: 在每个输出帧上写入额外信息,以便于调试 API。当设置为 true 时,对于给定的输入,输出帧不稳定,因为某些信息(如指针或队列状态)将被添加到其中。

7.24.2. 此驱动程序的默认用例是什么?

此驱动程序可以用作比较不同用户空间实现的一种方式。这假设一个工作的客户端针对 visl 运行,并且随后使用 ftrace 和 OUTPUT 缓冲区数据来调试正在进行中的实现。

即使实际上没有进行视频解码,也可以针对给定输入的参考使用输出帧,除非将 tpg_verbose 设置为 true。

根据 tpg_verbose 参数值,可以直接从 CAPTURE 缓冲区读取有关参考帧、它们的时间戳、OUTPUT 和 CAPTURE 队列的状态等信息。

7.24.3. 支持的编解码器

支持以下编解码器

  • FWHT

  • MPEG2

  • VP8

  • VP9

  • H.264

  • HEVC

  • AV1

7.24.4. visl 跟踪事件

跟踪事件是按编解码器定义的,例如

$ ls /sys/kernel/tracing/events/ | grep visl
visl_av1_controls
visl_fwht_controls
visl_h264_controls
visl_hevc_controls
visl_mpeg2_controls
visl_vp8_controls
visl_vp9_controls

例如,为了转储 HEVC SPS 数据

$ echo 1 >  /sys/kernel/tracing/events/visl_hevc_controls/v4l2_ctrl_hevc_sps/enable

SPS 数据将被转储到跟踪缓冲区,即

$ cat /sys/kernel/tracing/trace
video_parameter_set_id 0
seq_parameter_set_id 0
pic_width_in_luma_samples 1920
pic_height_in_luma_samples 1080
bit_depth_luma_minus8 0
bit_depth_chroma_minus8 0
log2_max_pic_order_cnt_lsb_minus4 4
sps_max_dec_pic_buffering_minus1 6
sps_max_num_reorder_pics 2
sps_max_latency_increase_plus1 0
log2_min_luma_coding_block_size_minus3 0
log2_diff_max_min_luma_coding_block_size 3
log2_min_luma_transform_block_size_minus2 0
log2_diff_max_min_luma_transform_block_size 3
max_transform_hierarchy_depth_inter 2
max_transform_hierarchy_depth_intra 2
pcm_sample_bit_depth_luma_minus1 0
pcm_sample_bit_depth_chroma_minus1 0
log2_min_pcm_luma_coding_block_size_minus3 0
log2_diff_max_min_pcm_luma_coding_block_size 0
num_short_term_ref_pic_sets 0
num_long_term_ref_pics_sps 0
chroma_format_idc 1
sps_max_sub_layers_minus1 0
flags AMP_ENABLED|SAMPLE_ADAPTIVE_OFFSET|TEMPORAL_MVP_ENABLED|STRONG_INTRA_SMOOTHING_ENABLED

7.24.5. 通过 debugfs 转储 OUTPUT 缓冲区数据

如果启用了 VISL_DEBUGFS Kconfig,visl 将根据 bitstream_trace_frame_start 和 bitstream_trace_nframes 的值,使用 OUTPUT 缓冲区数据填充 /sys/kernel/debug/visl/bitstream。这可以突出显示错误,因为损坏的客户端可能无法正确填充缓冲区。

为每个处理的 OUTPUT 缓冲区创建一个文件。它的名称包含一个整数,表示缓冲区序列,即

snprintf(name, 32, "bitstream%d", run->src->sequence);

转储值只需从文件中读取,即

对于序列 == 0 的缓冲区

$ xxd /sys/kernel/debug/visl/bitstream/bitstream0
00000000: 2601 af04 d088 bc25 a173 0e41 a4f2 3274  &......%.s.A..2t
00000010: c668 cb28 e775 b4ac f53a ba60 f8fd 3aa1  .h.(.u...:.`..:.
00000020: 46b4 bcfc 506c e227 2372 e5f5 d7ea 579f  F...Pl.'#r....W.
00000030: 6371 5eb5 0eb8 23b5 ca6a 5de5 983a 19e4  cq^...#..j]..:..
00000040: e8c3 4320 b4ba a226 cbc1 4138 3a12 32d6  ..C ...&..A8:.2.
00000050: fef3 247b 3523 4e90 9682 ac8e eb0c a389  ..${5#N.........
00000060: ddd0 6cfc 0187 0e20 7aae b15b 1812 3d33  ..l.... z..[..=3
00000070: e1c5 f425 a83a 00b7 4f18 8127 3c4c aefb  ...%.:..O..'<L..

对于序列 == 1 的缓冲区

$ xxd /sys/kernel/debug/visl/bitstream/bitstream1
00000000: 0201 d021 49e1 0c40 aa11 1449 14a6 01dc  [email protected]....
00000010: 7023 889a c8cd 2cd0 13b4 dab0 e8ca 21fe  p#....,.......!.
00000020: c4c8 ab4c 486e 4e2f b0df 96cc c74e 8dde  ...LHnN/.....N..
00000030: 8ce7 ee36 d880 4095 4d64 30a0 ff4f 0c5e  [email protected].^
00000040: f16b a6a1 d806 ca2a 0ece a673 7bea 1f37  .k.....*...s{..7
00000050: 370f 5bb9 1dc4 ba21 6434 bc53 0173 cba0  7.[....!d4.S.s..
00000060: dfe6 bc99 01ea b6e0 346b 92b5 c8de 9f5d  ........4k.....]
00000070: e7cc 3484 1769 fef2 a693 a945 2c8b 31da  ..4..i.....E,.1.

等等。

默认情况下,这些文件会在 STREAMOFF 期间删除。这是为了减少混乱。