7.7. ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD

7.7.1. 名称

VIDIOC_DECODER_CMD - VIDIOC_TRY_DECODER_CMD - 执行解码器命令

7.7.2. 概要

VIDIOC_DECODER_CMD

int ioctl(int fd, VIDIOC_DECODER_CMD, struct v4l2_decoder_cmd *argp)

VIDIOC_TRY_DECODER_CMD

int ioctl(int fd, VIDIOC_TRY_DECODER_CMD, struct v4l2_decoder_cmd *argp)

7.7.3. 参数

fd

open() 返回的文件描述符。

argp

指向结构体 v4l2_decoder_cmd 的指针。

7.7.4. 描述

这些 ioctl 控制音频/视频(通常是 MPEG)解码器。VIDIOC_DECODER_CMD 向解码器发送命令,VIDIOC_TRY_DECODER_CMD 可用于尝试命令而无需实际执行它。要发送命令,应用程序必须初始化结构体 v4l2_decoder_cmd 的所有字段,并使用指向该结构的指针调用 VIDIOC_DECODER_CMDVIDIOC_TRY_DECODER_CMD

cmd 字段必须包含命令代码。某些命令使用 flags 字段来获取其他信息。

如果解码器尚未启动,write()ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF 调用会向解码器发送隐式的 START 命令。适用于 mem2mem 解码器的两个队列。

流文件描述符的 close()VIDIOC_STREAMOFF 调用会向解码器发送隐式的立即 STOP 命令,并且所有缓冲的数据都会被丢弃。适用于 mem2mem 解码器的两个队列。

原则上,这些 ioctl 是可选的,并非所有驱动程序都可能支持它们。它们是在 Linux 3.3 中引入的。但是,对于有状态的 mem2mem 解码器来说,它们是强制性的(如 内存到内存有状态视频解码器接口 中进一步记录的)。

type v4l2_decoder_cmd
结构体 v4l2_decoder_cmd

__u32

cmd

解码器命令,请参阅 解码器命令

__u32

flags

与命令一起使用的标志。如果此命令没有定义任何标志,驱动程序和应用程序必须将此字段设置为零。

union {

(匿名)

struct

start

包含 V4L2_DEC_CMD_START 命令的附加数据的结构体。

__s32

speed

播放速度和方向。播放速度定义为正常速度的 speed/1000。因此,1000 是正常播放速度。负数表示反向播放,因此 -1000 以正常速度反向播放。速度 -1、0 和 1 有特殊含义:速度 0 是 1000(正常播放)的简写。速度 1 仅向前步进一帧,速度 -1 仅向后步进一帧。

__u32

format

格式限制。此字段由驱动程序设置,而不是由应用程序设置。可能的值为:如果没有格式限制,则为 V4L2_DEC_START_FMT_NONE;如果解码器在完整的 GOP(图片组)上运行,则为 V4L2_DEC_START_FMT_GOP。这通常是反向播放的情况:解码器需要完整的 GOP,然后它可以按相反的顺序播放它们。因此,要实现反向播放,应用程序必须向解码器馈送视频文件中的最后一个 GOP,然后是之前的 GOP,依此类推。

struct

stop

包含 V4L2_DEC_CMD_STOP 命令的附加数据的结构体。

__u64

pts

在此 pts 处停止播放,如果播放已经超过该时间戳,则立即停止播放。如果要停止在解码最后一帧之后,则将其保留为 0。

struct

raw

__u32

data[16]

保留以供将来扩展。驱动程序和应用程序必须将数组设置为零。

}

解码器命令

V4L2_DEC_CMD_START

0

启动解码器。当解码器已经在运行或暂停时,此命令只会更改播放速度。这意味着,当解码器暂停时调用 V4L2_DEC_CMD_START 不会恢复解码器。您必须显式调用 V4L2_DEC_CMD_RESUME 才能这样做。此命令有一个标志:V4L2_DEC_CMD_START_MUTE_AUDIO。如果设置,则在以非标准速度播放时将静音音频。

对于实现 内存到内存有状态视频解码器接口 的设备,一旦使用 V4L2_DEC_CMD_STOP 命令启动排空序列,它必须在调用此命令之前驱动到完成。任何在排空序列正在进行时尝试调用此命令的操作都将触发 EBUSY 错误代码。在没有显式调用 V4L2_DEC_CMD_STOP 的情况下,该命令也可用于在解码器自身启动的隐式停止情况下重新启动解码器。有关更多详细信息,请参阅 内存到内存有状态视频解码器接口

V4L2_DEC_CMD_STOP

1

停止解码器。当解码器已经停止时,此命令不执行任何操作。此命令有两个标志:如果设置 V4L2_DEC_CMD_STOP_TO_BLACK,则解码器在停止解码后会将画面设置为黑色。否则,最后一个图像将重复。如果设置 V4L2_DEC_CMD_STOP_IMMEDIATELY,则解码器会立即停止(忽略 pts 值),否则它将保持解码,直到时间戳 >= pts 或直到解码完其内部缓冲区中的最后一个待处理数据。

对于实现 内存到内存有状态视频解码器接口 的设备,该命令将启动 内存到内存有状态视频解码器接口 中记录的排空序列。在这种情况下,不接受任何标志或其他参数。在序列完成之前再次尝试调用该命令的任何操作都将触发 EBUSY 错误代码。

V4L2_DEC_CMD_PAUSE

2

暂停解码器。当解码器尚未启动时,驱动程序将返回 EPERM 错误代码。当解码器已经暂停时,此命令不执行任何操作。此命令有一个标志:如果设置 V4L2_DEC_CMD_PAUSE_TO_BLACK,则在暂停时将解码器输出设置为黑色。

V4L2_DEC_CMD_RESUME

3

在 PAUSE 命令之后恢复解码。当解码器尚未启动时,驱动程序将返回 EPERM 错误代码。当解码器已经在运行时,此命令不执行任何操作。此命令没有定义任何标志。

V4L2_DEC_CMD_FLUSH

4

刷新所有持有的捕获缓冲区。仅对无状态解码器有效。此命令通常在应用程序到达流末尾且最后一个输出缓冲区设置了 V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF 标志时使用。这将阻止将包含最后一个解码帧的捕获缓冲区出队。因此,可以使用此命令显式刷新该最终解码帧。如果没有持有的捕获缓冲区,则此命令不执行任何操作。

7.7.5. 返回值

成功时返回 0,错误时返回 -1,并适当地设置 errno 变量。通用错误代码在通用错误代码章节中描述。

EBUSY

正在进行实现内存到内存的有状态视频解码器接口的设备的清空序列。在完成之前,不允许发出另一个解码器命令。

EINVAL

cmd 字段无效。

EPERM

当解码器未运行时,应用程序发送了 PAUSE 或 RESUME 命令。