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

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

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

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

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

注意

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

7.25.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.25.2. 此驱动的默认用例是什么?

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

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

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

7.25.3. 支持的编解码器

支持以下编解码器

  • FWHT

  • MPEG2

  • VP8

  • VP9

  • H.264

  • HEVC

  • AV1

7.25.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.25.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  ...!I..@...I....
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  ...6..@.Md0..O.^
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 期间被删除。 这是为了减少混乱。