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 解码器来说,它们是强制性的(如 内存到内存状态视频解码器接口 中进一步记录的那样)。

类型 v4l2_decoder_cmd
结构体 v4l2_decoder_cmd

__u32

cmd

解码器命令,参见 解码器命令

__u32

flags

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

union {

(anonymous)

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(如果没有格式限制)或 V4L2_DEC_START_FMT_GOP(如果解码器对完整的 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 命令。