[Spice-devel] [PATCH RFC v4 1/1] virtio-video: Add virtio video device specification
Keiichi Watanabe
keiichiw at chromium.org
Tue Jun 23 11:13:25 UTC 2020
The virtio video encoder and decoder devices are virtual devices that
support video encoding and decoding respectively. Despite being different
devices, they use the same protocol.
Signed-off-by: Dmitry Sepp <dmitry.sepp at opensynergy.com>
Signed-off-by: Keiichi Watanabe <keiichiw at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
---
.gitignore | 1 +
content.tex | 1 +
images/video-buffer-lifecycle.dot | 18 +
make-setup-generated.sh | 8 +
virtio-video.tex | 1163 +++++++++++++++++++++++++++++
5 files changed, 1191 insertions(+)
create mode 100644 .gitignore
create mode 100644 images/video-buffer-lifecycle.dot
create mode 100644 virtio-video.tex
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..31272c2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/images/generated/
diff --git a/content.tex b/content.tex
index 24dbf84..0bf3f1c 100644
--- a/content.tex
+++ b/content.tex
@@ -6074,6 +6074,7 @@ \subsubsection{Legacy Interface: Framing Requirements}\label{sec:Device
\input{virtio-fs.tex}
\input{virtio-rpmb.tex}
\input{virtio-iommu.tex}
+\input{virtio-video.tex}
\chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
diff --git a/images/video-buffer-lifecycle.dot b/images/video-buffer-lifecycle.dot
new file mode 100644
index 0000000..98f379b
--- /dev/null
+++ b/images/video-buffer-lifecycle.dot
@@ -0,0 +1,18 @@
+digraph {
+ graph [ rankdir = LR, layout = dot ];
+
+ init [style = invis]
+ destroyed [style = invis]
+ created [label="Created", shape=circle]
+ dequeued [label="Dequeued", shape=circle]
+ queued [label="Queued", shape=circle]
+
+ init -> created [label="RESOURCE_CREATE"]
+
+ created -> queued [label="RESOURCE_QUEUE is sent"]
+ dequeued -> queued [label="RESOURCE_QUEUE\n is sent"]
+ queued -> dequeued [label="RESOURCE_QUEUE\n has returned"]
+
+ created -> destroyed [label="RESOURCE_DESTROY_ALL"]
+ dequeued -> destroyed [label="RESOURCE_DESTROY_ALL"]
+}
diff --git a/make-setup-generated.sh b/make-setup-generated.sh
index f15d148..4caff72 100755
--- a/make-setup-generated.sh
+++ b/make-setup-generated.sh
@@ -61,3 +61,11 @@ cat > setup-generated.tex <<EOF
\newcommand{\virtiodraftstagename}{$STAGENAME}
\newcommand{\virtiodraftoasisstagename}{$OASISSTAGENAME}
EOF
+
+# Generate PNG from DOT
+mkdir -p images/generated
+for file in images/*.dot
+do
+ BASENAME=`basename "$file" .dot`
+ dot -Tpng -o images/generated/${BASENAME}.png ${file}
+done
diff --git a/virtio-video.tex b/virtio-video.tex
new file mode 100644
index 0000000..a57e180
--- /dev/null
+++ b/virtio-video.tex
@@ -0,0 +1,1163 @@
+\section{Video Device}\label{sec:Device Types / Video Device}
+
+The virtio video encoder and decoder devices are virtual devices that support
+video encoding and decoding respectively. Despite being different devices, they
+use the same protocol.
+
+\subsection{Device ID}
+\label{sec:Device Types / Video Device / Device ID}
+
+\begin{description}
+\item[30] encoder device
+\item[31] decoder device
+\end{description}
+
+\subsection{Virtqueues}
+\label{sec:Device Types / Video Device / Virtqueues}
+
+\begin{description}
+\item[0] commandq - queue for driver commands and device responses to these
+ commands.
+\item[1] eventq - queue for events sent by the device to the driver.
+\end{description}
+
+\subsection{Feature bits}
+\label{sec:Device Types / Video Device / Feature bits}
+
+\begin{description}
+\item[VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES (0)] Guest pages can be used for video
+ buffers.
+\item[VIRTIO_VIDEO_F_RESOURCE_NON_CONTIG (1)] The device can use
+ non-contiguous memory for video buffers. Without this flag, the
+ driver and device MUST use video buffers that are contiguous for the device.
+\item[VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT (2)] Objects exported by
+ another virtio device can be used as video buffers.
+\end{description}
+
+\devicenormative{\subsubsection}{Feature bits}{Device Types / Video
+ Device / Feature bits}
+
+The device MUST present at least one of VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES or
+VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT.
+
+\subsection{Device configuration layout}
+\label{sec:Device Types / Video Device / Device configuration layout}
+
+Video device configuration uses the following layout structure:
+
+\begin{lstlisting}
+struct virtio_video_config {
+ le32 version;
+ le32 caps_length;
+};
+\end{lstlisting}
+
+\begin{description}
+\item[\field{version}] is the protocol version that the device understands. The
+ device MUST set this to 0.
+\item[\field{caps_length}] is the length of a device-writable descriptor
+ required to call VIRTIO_VIDEO_CMD_DEVICE_QUERY_CAPS in bytes. The device MUST
+ set this value.
+\end{description}
+
+\subsection{Supported formats}
+
+\subsubsection{Supported image formats}
+
+The following image formats are defined:
+\begin{lstlisting}
+enum virtio_video_image_format {
+ /* Raw formats */
+ VIRTIO_VIDEO_IMAGE_FORMAT_ARGB8888 = 1,
+ VIRTIO_VIDEO_IMAGE_FORMAT_BGRA8888,
+ VIRTIO_VIDEO_IMAGE_FORMAT_NV12, /* 12 Y/CbCr 4:2:0 */
+ VIRTIO_VIDEO_IMAGE_FORMAT_YUV420, /* 12 YUV 4:2:0 */
+ VIRTIO_VIDEO_IMAGE_FORMAT_YVU420, /* 12 YVU 4:2:0 */
+};
+\end{lstlisting}
+
+\subsubsection{Supported bitstream formats}
+
+The following bitstream formats are defined:
+\begin{lstlisting}
+enum virtio_video_codec {
+ VIRTIO_VIDEO_CODEC_MPEG2 = 1, /* MPEG-2 Part 2 */
+ VIRTIO_VIDEO_CODEC_MPEG4, /* MPEG-4 Part 2 */
+ VIRTIO_VIDEO_CODEC_H264, /* H.264 */
+ VIRTIO_VIDEO_CODEC_HEVC, /* HEVC aka H.265*/
+ VIRTIO_VIDEO_CODEC_VP8, /* VP8 */
+ VIRTIO_VIDEO_CODEC_VP9, /* VP9 */
+};
+
+union virtio_video_codec_params {
+ struct virtio_video_codec_h264 h264;
+ struct virtio_video_codec_hevc hevc;
+ struct virtio_video_codec_vp8 vp8;
+ struct virtio_video_codec_vp9 vp9;
+}
+
+struct virtio_video_bitstream_format {
+ le32 virtio_video_codec codec; /* VIRTIO_VIDEO_CODEC_* */
+ union virtio_video_codec_params params;
+};
+\end{lstlisting}
+
+The field \field{params} in \field{struct virtio_video_bitstream_format} is
+valid only when \field{codec} designates a value which has a corresponding field
+in \field{union virtio_video_codec_params}.
+
+The fields in \field{union virtio_video_codec_params} are defined below.
+
+\paragraph{H.264}
+
+When the field \field{codec} in \field{struct virtio_video_bitstream_format}
+is set to VIRTIO_VIDEO_CODEC_H264, \field{params.h264} MUST be set to a
+valid value defined as follows:
+
+\begin{lstlisting}
+enum virtio_video_codec_h264_profile {
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_BASELINE = 1,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_MAIN,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_EXTENDED,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_HIGH,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_HIGH10PROFILE,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_HIGH422PROFILE,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_HIGH444PREDICTIVEPROFILE,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_SCALABLEBASELINE,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_SCALABLEHIGH,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_STEREOHIGH,
+ VIRTIO_VIDEO_CODEC_H264_PROFILE_MULTIVIEWHIGH,
+};
+
+enum virtio_video_codec_h264_level {
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_1_0 = 1,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_1_1,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_1_2,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_1_3,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_2_0,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_2_1,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_2_2,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_3_0,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_3_1,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_3_2,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_4_0,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_4_1,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_4_2,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_5_0,
+ VIRTIO_VIDEO_CODEC_H264_LEVEL_5_1,
+};
+
+struct virtio_video_codec_h264 {
+ le32 profile; /* VIRTIO_VIDEO_CODEC_H264_PROFILE_* */
+ le32 level; /* VIRTIO_VIDEO_CODEC_H264_LEVEL_* */
+};
+\end{lstlisting}
+
+\paragraph{HEVC}
+
+When the field \field{codec} in \field{struct virtio_video_bitstream_format}
+is set to VIRTIO_VIDEO_CODEC_HEVC, \field{params.hevc} MUST be set to a
+valid value defined as follows:
+
+\begin{lstlisting}
+enum virtio_video_codec_hevc_profile {
+ VIRTIO_VIDEO_CODEC_HEVC_PROFILE_MAIN = 1,
+ VIRTIO_VIDEO_CODEC_HEVC_PROFILE_MAIN10,
+ VIRTIO_VIDEO_CODEC_HEVC_PROFILE_MAIN_STILL_PICTURE,
+};
+
+struct virtio_video_codec_hevc {
+ le32 profile; /* VIRTIO_VIDEO_CODEC_HEVC_PROFILE_* */
+};
+\end{lstlisting}
+
+\paragraph{VP8}
+
+When the field \field{codec} in \field{struct virtio_video_bitstream_format}
+is set to VIRTIO_VIDEO_CODEC_VP8, \field{params.vp8} MUST be set to a
+valid value defined as follows:
+
+\begin{lstlisting}
+enum virtio_video_codec_vp8_profile {
+ VIRTIO_VIDEO_CODEC_VP8_PROFILE_0 = 1,
+ VIRTIO_VIDEO_CODEC_VP8_PROFILE_1,
+ VIRTIO_VIDEO_CODEC_VP8_PROFILE_2,
+ VIRTIO_VIDEO_CODEC_VP8_PROFILE_3,
+};
+
+struct virtio_video_codec_vp8 {
+ le32 profile;/* VIRTIO_VIDEO_CODEC_VP8_PROFILE_* */
+};
+\end{lstlisting}
+
+\paragraph{VP9}
+
+When the field \field{codec} in \field{struct virtio_video_bitstream_format}
+is set to VIRTIO_VIDEO_CODEC_VP9, \field{params.vp9} MUST be set to a
+valid value defined as follows:
+
+\begin{lstlisting}
+enum virtio_video_codec_vp9_profile {
+ VIRTIO_VIDEO_CODEC_VP9_PROFILE_0 = 1,
+ VIRTIO_VIDEO_CODEC_VP9_PROFILE_1,
+ VIRTIO_VIDEO_CODEC_VP9_PROFILE_2,
+ VIRTIO_VIDEO_CODEC_VP9_PROFILE_3,
+};
+
+struct virtio_video_codec_vp9 {
+ le32 profile;/* VIRTIO_VIDEO_CODEC_VP9_PROFILE_* */
+};
+\end{lstlisting}
+
+\subsection{Device Initialization}
+\label{sec:Device Types / Video Device / Device Initialization}
+
+\devicenormative{\subsubsection}{Device Initialization}{Device Types /
+ Video Device / Device Initialization}
+
+The driver SHOULD query device capability by using the
+VIRTIO_VIDEO_CMD_DEVICE_QUERY_CAPS and use that information for the
+initial setup.
+
+\subsection{Device Operation}
+\label{sec:Device Types / Video Device / Device Operation}
+
+After initializing the device and setting the desired parameters,
+the driver allocates input and output buffers and queues them
+to the device. The device then performs the requested operation on the buffers.
+
+\subsubsection{Command Virtqueue}
+
+The command virtqueue is used to send commands and their responses. Commands
+MUST be written by the driver and their responses MUST be written by the device
+in the next device-writable descriptor.
+
+Different structure layouts are used for each command and response. Every
+command structure starts with a field storing a variant of \field{enum
+ virtio_video_cmd_type} defined as follows:
+\begin{lstlisting}
+enum virtio_video_cmd_type {
+ /* Global */
+ VIRTIO_VIDEO_CMD_DEVICE_QUERY_CAPS = 0x0100,
+
+ /* Stream */
+ VIRTIO_VIDEO_CMD_STREAM_CREATE = 0x0200,
+ VIRTIO_VIDEO_CMD_STREAM_DESTROY,
+ VIRTIO_VIDEO_CMD_STREAM_GET_PARAMS,
+ VIRTIO_VIDEO_CMD_STREAM_SET_PARAMS,
+ VIRTIO_VIDEO_CMD_STREAM_DRAIN,
+
+ /* Queue */
+ VIRTIO_VIDEO_CMD_QUEUE_CLEAR = 0x300,
+ VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES,
+
+ /* Resource*/
+ VIRTIO_VIDEO_CMD_RESOURCE_ATTACH = 0x400,
+ VIRTIO_VIDEO_CMD_RESOURCE_QUEUE,
+};
+\end{lstlisting}
+
+Each response structure starts with a field storing a variant of
+\field{enum virtio_video_result} defined as follows:
+\begin{lstlisting}
+enum virtio_video_result {
+ /* Success */
+ VIRTIO_VIDEO_RESULT_OK = 0x000,
+
+ /* Error */
+ VIRTIO_VIDEO_RESULT_ERR_INVALID_OPERATION = 0x0100,
+ VIRTIO_VIDEO_RESULT_ERR_INVALID_STREAM_ID,
+ VIRTIO_VIDEO_RESULT_ERR_INVALID_RESOURCE_ID,
+ VIRTIO_VIDEO_RESULT_ERR_INVALID_PARAMETER,
+ VIRTIO_VIDEO_RESULT_ERR_CANCELED,
+ VIRTIO_VIDEO_RESULT_ERR_OUT_OF_MEMORY,
+};
+\end{lstlisting}
+
+\paragraph{Query device capability}
+
+\begin{description}
+\item[VIRTIO_VIDEO_CMD_DEVICE_QUERY_CAPS] Retrieve information about device
+ capabilities.
+
+The driver sends this command with \field{struct
+ virtio_video_device_query_caps}.
+\begin{lstlisting}
+struct virtio_video_device_query_caps {
+ le32 cmd_type;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be set to VIRTIO_VIDEO_CMD_DEVICE_QUERY_CAPS.
+\end{description}
+
+The device responds with \field{struct virtio_video_device_query_caps_resp}.
+\begin{lstlisting}
+struct virtio_video_device_query_caps_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+ le32 num_image_formats;
+ le32 num_bitstream_formats;
+ /**
+ * Followed by
+ * struct virtio_video_image_format_desc image_formats[num_image_formats];
+ */
+ /**
+ * Followed by
+ * struct virtio_video_bitstream_format_desc bitstream_formats[num_bitstream_formats];
+ */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of variants of \field{enum
+ virtio_video_result}.
+\item[\field{num_image_formats}] is the number of supported image formats. If
+ \field{result} is not VIRTIO_VIDEO_RESULT_OK, the device MUST set this to 0.
+\item[\field{num_bitstream_formats}] is the number of supported bitstream
+ formats. If \field{result} is not VIRTIO_VIDEO_RESULT_OK, the device MUST set
+ this to 0.
+\end{description}
+
+The device MUST write two arrays of \field{struct
+ virtio_video_image_format_desc} and \field{struct
+ virtio_video_image_format_desc} following the \field{struct
+ virtio_video_device_query_caps_resp}. The lengths of these arrays MUST be
+\field{num_image_formats} and \field{num_bitstream_formats} respectively.
+\subparagraph{Image format description}
+
+The image format description \field{virtio_video_image_format_desc} is defined
+as follows:
+\begin{lstlisting}
+enum virtio_video_planes_layout {
+ VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER = 0,
+ VIRTIO_VIDEO_PLANES_LAYOUT_PER_PLANE,
+};
+
+struct virtio_video_image_format_desc {
+ le32 format; /* VIRTIO_VIDEO_CMD_IMAGE_FORMAT_* */
+ le32 planes_layouts; /* Bitmask with VIRTIO_VIDEO_PLANES_LAYOUT_* */
+ le32 plane_align;
+ le32 num_frames;
+ /**
+ * Followed by
+ * struct virtio_video_image_format_frame frames[num_frames];
+ */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{format}] specifies an image format. The device MUST set
+ one of the variants of \field{enum virtio_video_image_format}.
+\item[\field{planes_layouts}] is a bitmask representing the set of plane layout
+ types that the device supports.
+ \begin{description}
+ \item[\field{VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER}] The device expects
+ the planes of a frame to be laid out one after another in the same buffer.
+ \item[\field{VIRTIO_VIDEO_PLANES_LAYOUT_PER_PLANE}] The device expects the
+ planes of a frame to be located in separate buffers.
+ \end{description}
+\item[\field{plane_align}] is the plane alignment the device requires when
+ multiple planes are located in the same buffer. This field is valid only if
+ \field{planes_layouts} has the \field{VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER}
+ bit, and MUST be set to zero otherwise.
+\item[\field{num_frames}] is the number of \field{virtio_video_format_frame}
+ that follow.
+\end{description}
+
+The frame information \field{virtio_video_format_frame} is defined as follows:
+\begin{lstlisting}
+struct virtio_video_image_format_range {
+ le32 min;
+ le32 max;
+ le32 step;
+};
+
+struct virtio_video_image_format_frame {
+ struct virtio_video_image_format_range width;
+ struct virtio_video_image_format_range height;
+ le32 num_rates;
+ /**
+ * Followed by
+ * struct virtio_video_image_format_range frame_rates[num_rates];
+ */
+};
+\end{lstlisting}
+
+The value of \field{struct virtio_video_image_format_range} is used to represent
+the range of values supported by the device. The device MUST set \field{step} to
+a positive integer. An integer \(x\) is in a range \field{struct
+ virtio_video_image_format_range r} if \(\field{r.min} \le x \le
+\field{r.max}\) holds and \(x\) is equals to \((\field{min} + \field{step} *
+n)\) for some integer \(n\).
+
+\begin{description}
+\item[\field{width}] represents the range of widths supported by the device.
+\item[\field{height}] represents the range of heights supported by the device.
+\item[\field{num_rates}] is the length of the \field{frame_rates[]} array.
+\item[\field{frame_rates}] is the set of frame rates ranges supported
+ by the device.
+\end{description}
+
+\subparagraph{Bitstream format description}
+
+The bitstream format description \field{virtio_video_bitstream_format_desc} is
+defined as follows:
+\begin{lstlisting}
+struct virtio_video_bitstream_format_desc {
+ le32 virtio_video_codec codec;
+ le32 num_variants;
+ /**
+ * Followed by
+ * union virtio_video_codec_params variants[num_variants];
+ */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{codec}] specifies a codec. This field MUST be set to one of the
+ variants of \field{enum virtio_video_codec}.
+\item[\field{num_variants}] is the number of \field{union virtio_video_codec_params}
+ values that follow. If \field{union virtio_video_codec_params} has a field
+ corresponding to the specified \field{codec}, this value MUST be a positive
+ integer. Otherwise, it MUST be 0.
+\item[\field{variants}] is a list of supported variants of the given
+ \field{codec}. Only the field corresponding to the given \field{codec} MUST be
+ valid in each element.
+\end{description}
+\end{description}
+
+\devicenormative{\subparagraph}{Query device capability}{Device Types / Video
+ Device / Device Operation / Device Operation: Query device capability}
+
+The total size of the device response MUST be equals to \field{caps_length}
+bytes, as reported by the device configuration.
+
+\paragraph{Per stream operations}
+
+\begin{description}
+\item[VIRTIO_VIDEO_CMD_STREAM_CREATE] Create a video stream using the device.
+
+The driver sends this command with \field{struct virtio_video_stream_create}.
+\begin{lstlisting}
+enum virtio_video_mem_type {
+ VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES = 1,
+ VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT,
+};
+
+struct virtio_video_stream_create {
+ le32 cmd_type;
+ le32 in_mem_type; /* One of VIRTIO_VIDEO_MEM_TYPE_* types */
+ le32 out_mem_type; /* One of VIRTIO_VIDEO_MEM_TYPE_* types */
+ le32 codec; /* One of VIRTIO_VIDEO_CODEC_* types */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be set to VIRTIO_VIDEO_CMD_STREAM_CREATE.
+\item[\field{in_mem_type, out_mem_type}] is the type of buffer management for
+ input/output buffers. The driver MUST set a value in \field{enum
+ virtio_video_mem_type} for which the device reported a corresponding feature
+ bit.
+\begin{description}
+\item[\field{VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES}] Use guest pages. The driver
+ MUST not set this value if the feature bit VIRTIO_VIDEO_F_RESOURCE_GUEST_PAGES
+ is not set.
+\item[\field{VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT}] Use object exported by
+ another virtio device. The driver MUST not set this value if the feature bit
+ VIRTIO_VIDEO_F_RESOURCE_VIRTIO_OBJECT is not set.
+\end{description}
+\item[\field{codec}] is the video codec that will be used with this stream. The
+ driver MUST set it to one of the variants of \field{enum virtio_video_codec}.
+\end{description}
+
+The device responds with \field{struct virtio_video_stream_create_resp}:
+\begin{lstlisting}
+struct virtio_video_stream_create_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+ le32 stream_id;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\item[\field{stream_id}] is the ID of the created stream, allocated by the
+ device. It is only valid if \field{result} is VIRTIO_VIDEO_RESULT_OK.
+\end{description}
+
+\item[VIRTIO_VIDEO_CMD_STREAM_DESTROY] Destroy a video stream.
+
+The driver sends this command with \field{struct virtio_video_stream_destroy}.
+\begin{lstlisting}
+struct virtio_video_stream_destroy {
+ le32 cmd_type;
+ le32 stream_id;
+};
+\end{lstlisting}
+\begin{description}
+\item{\field{cmd_type}} MUST be set to VIRTIO_VIDEO_CMD_STREAM_DESTROY.
+\item{\field{stream_id}} is the ID of the stream to be destroyed. It must be set
+to the value of an existing stream.
+\end{description}
+
+The device responds with \field{struct virtio_video_stream_destroy_resp}.
+\begin{lstlisting}
+struct virtio_video_stream_destroy_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\end{description}
+
+\item[VIRTIO_VIDEO_CMD_STREAM_GET_PARAMS] Get the current stream parameters.
+
+The driver sends this command with \field{struct
+ virtio_video_stream_get_params}.
+\begin{lstlisting}
+struct virtio_video_stream_get_params {
+ le32 cmd_type;
+ le32 stream_id;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be set to VIRTIO_VIDEO_CMD_STREAM_GET_PARAMS.
+\item[\field{stream_id}] MUST be set to the ID of an existing stream, whose
+ parameters will be returned.
+\end{description}
+
+The device responds with \field{struct virtio_video_stream_get_params_resp}.
+\begin{lstlisting}
+struct virtio_video_stream_get_params_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+ struct virtio_video_params params;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of variants of \field{enum
+ virtio_video_result}.
+\item[\field{params}] is the stream parameters. It is only valid if
+ \field{result} is VIRTIO_VIDEO_RESULT_OK.
+\end{description}
+
+The struct \field{virtio_video_params} is defined as follows. Some of these
+parameters can be updated by the driver with VIRTIO_VIDEO_CMD_SET_PARAMS.
+\begin{lstlisting}
+struct virtio_video_crop {
+ le32 left;
+ le32 top;
+ le32 width;
+ le32 height;
+};
+
+enum virtio_video_rate_control {
+ VIRTIO_VIDEO_RATE_CONTROL_FRAME = 1,
+ VIRTIO_VIDEO_RATE_CONTROL_MACRO_BLOCK,
+};
+
+struct virtio_video_rc_range {
+ le32 min_qp;
+ le32 max_qp;
+};
+
+struct virtio_video_frame_qp {
+ le32 iframe_qp;
+ le32 pframe_qp;
+ le32 bframe_qp;
+};
+
+union virtio_video_quantization_param {
+ struct virtio_video_rc_range rc;
+ struct virtio_video_frame_qp no_rc;
+};
+
+struct virtio_video_params {
+ /* Image format */
+ le32 image_format; /* VIRTIO_VIDEO_IMAGE_FORMAT_* */
+ le32 min_image_buffers;
+ le32 max_image_buffers;
+ le32 cur_image_buffers;
+ le32 width;
+ le32 height;
+ struct virtio_video_crop crop;
+ le32 frame_rate;
+ le32 planes_layout;
+ le32 num_planes;
+ struct virtio_video_plane_format
+ plane_formats[VIRTIO_VIDEO_MAX_PLANES];
+
+ /* Bitstream format */
+ struct virtio_video_bitstream_format bitstream_format;
+ le32 min_bitstream_buffers;
+ le32 max_bitstream_buffers;
+ le32 cur_bitstream_buffers;
+
+ /* Bitrate (for encoder) */
+ le32 min_bitrate;
+ le32 max_bitrate;
+ le32 cur_bitrate;
+
+ /* Quantization parameter (for encoder) */
+ le32 rc_mode; /* VIRTIO_VIDEO_RATE_CONTROL_* */
+ union virtio_video_quantization_param qp;
+};
+\end{lstlisting}
+
+\begin{description}
+\item[\field{image_format}] is the image format used by the stream. It is
+ set to one of the variants of \field{enum virtio_video_image_format}.
+\item[\field{min_image_buffers}] is the minimum number of image buffers that the
+ device requires. The device MUST set this to a non-zero integer.
+\item[\field{max_image_buffers}] is the maximum number of image buffers that the
+ device can accept. The device MUST set this to an integer larger than
+ or equal to \field{min_image_buffers}.
+\item[\field{cur_image_buffers}] is the number of image buffers that the driver
+ can enqueue via VIRTIO_VIDEO_RESOURCE_QUEUE. These fields are set by the
+ driver to how many buffers it wishes to use, and set by the device
+ to how many buffers it allows to use.
+ The value MUST be larger than or equal to \field{min_image_buffers} and not
+ exceed \field{max_image_buffers}.
+\item[\field{width}] is the current width of frames in the stream.
+\item[\field{height}] is the current height of frames in the stream.
+\item[\field{crop}] is the current cropping rectangle for frames in the stream.
+\item[\field{frame_rate}] is the frame rate.
+\item[\field{planes_layout}] specifies the plane layout of the resource. The
+ driver MUST set this to one of the variants of \field{enum
+ virtio_video_planes_layout} that is supported for a current image format.
+\item[\field{num_planes}] is the number of planes per frame.
+\item[\field{plane_formats}] is an array containing the current planes format.
+ Only the first |\field{num_planes}| elements are valid. The struct
+ \field{virtio_video_plane_format} is defined as follows.
+\begin{lstlisting}
+struct virtio_video_plane_format {
+ le32 plane_size;
+ le32 stride;
+ le32 offset;
+};
+\end{lstlisting}
+\begin{description}
+\item[plane_size] is a size of the plane in bytes.
+\item[stride] is the line stride.
+\item[offset] is an offset from the beginning of the buffer. This field is valid
+ only if VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER is set to
+ \field{planes_layout}.
+\end{description}
+\item[\field{bitstream_format}] is the bitstream format used in the
+ stream.
+\item[\field{min_bitstream_buffers}] is the minimum number of bitstream buffers
+ that the device requires. The device MUST set this to a non-zero integer.
+\item[\field{max_bitstream_buffers}] is the maximum number of bitstream buffers
+ that the device can accept. The device MUST set this to an integer which is
+ larger than or equal to \field{min_bitstream_buffers}.
+\item[\field{cur_bitstream_buffers}] is the number of bitstream buffers that the
+ driver can enqueue via VIRTIO_VIDEO_RESOURCE_QUEUE. These fields are set by
+ the driver to how many buffers it wishes to use, and set by the device to how
+ many buffers it allows to use. The value MUST be larger than or equal to
+ \field{min_bitstream_buffers} and not exceed \field{max_bitstream_buffers}.
+\item[\field{min_bitrate}] is the minimum bitrate supported by the
+ device. (only for encoders)
+\item[\field{max_bitrate}] is the maximum bitrate supported by the
+ device. (only for encoders)
+\item[\field{cur_bitrate}] is the current bitrate of the stream. (only for
+ encoders)
+\item[\field{rc_mode}] whether rate control is enabled for the stream. If
+ this value is one of variants of \field{enum virtio_video_rate_control}, the
+ rate control described below is enabled. Otherwise, the quantization parameter
+ for each frame type is constant and set with \field{qp.no_rc}. (only for
+ encoders)
+ \begin{description}
+ \item[\field{VIRTIO_VIDEO_RATE_CONTROL_FRAME}] Frame level rate control is
+ enabled. In this mode, the quantization parameter is adjusted according to
+ \field{cur_bitrate}. Minimum and maximum value for the quantization
+ parameter can be set with \field{qp.rc}.
+ \item[\field{VIRTIO_VIDEO_RATE_CONTROL_MACRO_BLOCK}] Macroblock level rate
+ control is enabled. (only for MPEG4 and H.264 encoders)
+ \end{description}
+\item[\field{qp}] is the quantization parameter. (only for encoders)
+\end{description}
+
+After the device responds to VIRTIO_VIDEO_CMD_STREAM_GET_PARAMS, it MUST keep
+responding the same value until one of the followings events occurs:
+\begin{itemize}
+\item the driver sends VIRTIO_VIDEO_CMD_STREAM_SET_PARAMS via commandq.
+\item the device sends VIRTIO_VIDEO_EVENT_DECODER_RESOLUTION_CHANGED via eventq.
+\end{itemize}
+
+\item[VIRTIO_VIDEO_CMD_STREAM_SET_PARAMS] Update the current stream parameters.
+
+The driver sends this command with \field{struct
+ virtio_video_stream_set_params}.
+\begin{lstlisting}
+struct virtio_video_stream_set_params {
+ le32 cmd_type;
+ le32 stream_id;
+ struct virtio_video_params params;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be VIRTIO_VIDEO_CMD_TYPE_SET_PARAMS.
+\item[\field{stream_id}] is the ID of the stream whose parameters are to be
+ updated.
+\item[\field{params}] the new parameters requested by the driver.
+\end{description}
+
+The device responds with \field{struct virtio_video_stream_set_params_resp}.
+\begin{lstlisting}
+struct virtio_video_stream_set_params_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+ struct virtio_video_params params;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\item[\field{params}] the updated stream parameters. Values may differ from the
+ requested one depending on the device's and codec capabilities, and values
+ that are not directly changed by the SET_PARAMS command may also be changed.
+ It is the responsibility of the driver to check all values for potential
+ changes and update its state accordingly.
+\end{description}
+
+\item[VIRTIO_VIDEO_CMD_STREAM_DRAIN] Complete processing all queued input
+ buffers.
+
+VIRTIO_VIDEO_CMD_STREAM_DRAIN ensures that all sent
+VIRTIO_VIDEO_CMD_RESOURCE_QUEUE commands for input buffers have been processed
+by the device and that related output buffers are available to the driver.
+
+The driver sends this command with \field{struct virtio_video_stream_drain}.
+\begin{lstlisting}
+struct virtio_video_stream_drain {
+ le32 cmd_type;
+ le32 stream_id;
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be VIRTIO_VIDEO_CMD_TYPE_STREAM_DRAIN.
+\item[\field{stream_id}] is a valid stream ID.
+\end{description}
+
+The device responds with \field{struct virtio_video_stream_drain_resp}.
+\begin{lstlisting}
+struct virtio_video_stream_drain_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\end{description}
+
+\begin{itemize*}
+\item Before the device sends the response of a VIRTIO_VIDEO_CMD_STREAM_DRAIN
+ command, it MUST process and respond to all of
+ VIRTIO_VIDEO_CMD_RESOURCE_* commands for the input queue which are sent before
+ the drain command.
+\item While the device is processing a VIRTIO_VIDEO_CMD_STREAM_DRAIN
+ command, it MUST return
+ VIRTIO_VIDEO_RESP_ERR_INVALID_OPERATION to the following incoming commands:
+ \begin{itemize*}
+ \item VIRTIO_VIDEO_CMD_RESOURCE_* commands with an input buffer, or
+ \item VIRTIO_VIDEO_CMD_STREAM_DRAIN commands.
+ \end{itemize*}
+\item If the processing was stopped due to
+ VIRTIO_VIDEO_CMD_QUEUE_CLEAR, the device MUST respond with
+ VIRTIO_VIDEO_RESP_OK_NODATA as response type and
+ VIRTIO_VIDEO_BUFFER_FLAG_ERR in \field{flags}.
+\end{itemize*}
+\end{description}
+
+\paragraph{Per queue commands}
+
+\begin{description}
+\item[VIRTIO_VIDEO_CMD_QUEUE_CLEAR] Discard all pending resource commands for a
+ given queue.
+
+The driver sends this command with \field{struct virtio_video_queue_clear}.
+\begin{lstlisting}
+enum virtio_video_queue_type {
+ VIRTIO_VIDEO_QUEUE_TYPE_INPUT = 1,
+ VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT,
+};
+
+struct virtio_video_queue_clear {
+ le32 cmd_type;
+ le32 stream_id;
+ le32 queue_type; /* One of VIRTIO_VIDEO_QUEUE_TYPE_* types */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be VIRTIO_VIDEO_CMD_TYPE_QUEUE_CLEAR.
+\item[\field{stream_id}] is a valid stream ID.
+\item[\field{queue_type}] is the queue to be cleared. This MUST be one of
+ variants of \field{enum virtio_video_queue_type}.
+\end{description}
+
+The device responds with \field{struct virtio_video_queue_clear_resp}.
+\begin{lstlisting}
+struct virtio_video_queue_clear_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\end{description}
+
+\begin{itemize*}
+\item Before the device sends a response for VIRTIO_VIDEO_CMD_QUEUE_CLEAR, it
+ MUST respond with VIRTIO_VIDEO_RESULT_ERR_CANCELED to the following pending
+ commands:
+ \begin{itemize*}
+ \item VIRTIO_VIDEO_CMD_RESOURCE_* on the input queue,
+ \item VIRTIO_VIDEO_CMD_STREAM_DRAIN.
+ \end{itemize*}
+\item While the device is processing a VIRTIO_VIDEO_CMD_QUEUE_CLEAR, it
+ MUST return VIRTIO_VIDEO_RESP_ERR_INVALID_OPERATION to the following incoming
+ commands:
+ \begin{itemize*}
+ \item VIRTIO_VIDEO_CMD_STREAM_DRAIN,
+ \item VIRTIO_VIDEO_CMD_QUEUE_CLEAR, or
+ \item VIRTIO_VIDEO_CMD_RESOURCE_*.
+ \end{itemize*}
+\end{itemize*}
+
+\item[VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES] Detach all the resources of an
+ input or an output queue.
+
+The command VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES is used to detach all
+resources attached by VIRTIO_VIDEO_CMD_RESOURCE_ATTACH for a given queue.
+The driver sends this command with \field{struct
+ virtio_video_queue_detach_resources}.
+\begin{lstlisting}
+struct virtio_video_queue_detach_resources {
+ le32 cmd_type;
+ le32 stream_id;
+ le32 queue_type; /* One of VIRTIO_VIDEO_QUEUE_TYPE_* types */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES.
+\item[\field{stream_id}] is a stream ID.
+\item[\field{queue_type}] MUST be a variant of \field{enum
+ virtio_video_queue_type}.
+\end{description}
+
+The device responds with \field{virtio_video_queue_detach_resources_resp}.
+\begin{lstlisting}
+struct virtio_video_queue_detach_resources_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\end{description}
+\end{description}
+
+\paragraph{Per resource commands}
+
+\begin{description}
+\item[VIRTIO_VIDEO_CMD_RESOURCE_ATTACH] Attach memory entries to use as a video
+ buffer.
+
+The driver sends this command with \field{struct virtio_video_resource_attach}.
+\begin{lstlisting}
+struct virtio_video_resource_attach {
+ le32 cmd_type;
+ le32 stream_id;
+ le32 queue_type;
+ le32 resource_id;
+ union virtio_video_resource resources[];
+};
+
+struct virtio_video_resource_attach_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be set to VIRTIO_VIDEO_CMD_RESOURCE_ATTACH.
+\item[\field{stream_id}] is the ID of the stream.
+\item[\field{queue_type}] is the direction of the queue.
+\item[\field{resource_id}] is the ID of the resource. If the \field{queue_type}
+ indicates the queue for an image format, \field{resource_id} MUST be an
+ integer less than \field{cur_image_buffers} in \field{virtio_video_params}
+ obtained via VIRTIO_VIDEO_GET_PARAMS. Otherwise, \field{resource_id} MUST be
+ less than \field{cur_bitstream_buffers}.
+\item[\field{resources}] specifies memory regions that will be attached. Its
+ length of the array depends on the value of \field{planes_layout} in
+ \field{virtio_video_params} obtained via VIRTIO_VIDEO_GET_PARAMS. If it is
+ VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER, the length MUST be 1. If it is
+ VIRTIO_VIDEO_LAYOUT_PER_PLANE, the length MUST be equal to \field{num_planes}
+ in \field{virtio_video_params}.
+
+ The struct \field{virtio_video_resource} is defined as follows:
+ \begin{lstlisting}
+union virtio_video_resource {
+ struct virtio_video_resource_sg_list sg_list;
+ struct virtio_video_resource_object object;
+};
+\end{lstlisting}
+\begin{description}
+ \item[sg_list] represents a scatter-gather list. This field is valid when
+ VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES is set for the specified queue type in
+ VIRTIO_VIDEO_CMD_STREAM_CREATE command. The struct
+ \field{virtio_video_resource_sg_list} is defined as follows:
+ \begin{lstlisting}
+struct virtio_video_resource_sg_entry {
+ le64 addr;
+ le32 length;
+ u8 padding[4];
+};
+
+struct virtio_video_resource_sg_list {
+ le32 num_entries;
+ u8 padding[4];
+ struct virtio_video_resource_sg_entry entries[];
+};
+\end{lstlisting}
+The \field{num_entries} in \field{virtio_video_resource_sg_list} is the number
+of \field{virtio_video_resource_sg_entry} instances that follow.
+
+Each field in \field{virtio_video_resource_sg_entry} is used as follows:
+ \begin{description}
+ \item[\field{addr}] is the physical guest address.
+ \item[\field{length}] is the length of the resource.
+ \end{description}
+ \end{description}
+ \item[object] represents an object exported from other virtio devices as
+ defined in \ref{sec:Basic Facilities of a Virtio Device / Exporting
+ Objects}. This field is valid when VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT is
+ set for the specified queue type in VIRTIO_VIDEO_CMD_STREAM_CREATE command.
+ The struct \field{virtio_video_resource_object} is defined as follows:
+ \begin{lstlisting}
+struct virtio_video_resource_object {
+ u8 uuid[16];
+};
+ \end{lstlisting}
+ \begin{description}
+ \item[uuid] is a version 4 UUID specified by
+ \hyperref[intro:rfc4122]{[RFC4122]}.
+ \end{description}
+\end{description}
+
+The device responds with \field{struct virtio_video_resource_attach_resp}:
+\begin{lstlisting}
+struct virtio_video_resource_attach_resp {
+ le32 result; /* VIRTIO_VIDEO_RESULT_* */
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of the variants of \field{enum
+ virtio_video_result}.
+\end{description}
+
+\item[VIRTIO_VIDEO_CMD_RESOURCE_QUEUE] Add a buffer to the device's
+queue.
+
+\begin{lstlisting}
+enum virtio_video_enqueue_flag {
+ VIRTIO_VIDEO_ENQUEUE_FLAG_FORCE_KEY_FRAME = 0,
+};
+
+struct virtio_video_resource_queue {
+ le32 cmd_type;
+ le32 stream_id;
+ le32 queue_type; /* One of VIRTIO_VIDEO_QUEUE_TYPE_* types */
+ le32 resource_id;
+ le32 flags; /* Bitmask with VIRTIO_VIDEO_ENQUEUE_FLAG_* */
+ u8 padding[4];
+ le64 timestamp;
+ le32 data_sizes[VIRTIO_VIDEO_MAX_PLANES];
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{cmd_type}] MUST be set to VIRTIO_VIDEO_CMD_RESOURCE_QUEUE.
+\item[\field{stream_id}] is the ID for the stream the resource belongs to.
+\item[\field{queue_type}] direction of the queue this resource belongs to.
+\item[\field{resource_id}] is the ID of the resource to be queued.
+\item[\field{flags}] is a bitmask of VIRTIO_VIDEO_ENQUEUE_FLAG_* values
+ representing requirements when processing the resource. If the driver doesn't
+ have any requirement, it MUST set this value to 0.
+ \begin{description}
+ \item[\field{VIRTIO_VIDEO_ENQUEUE_FLAG_FORCE_KEY_FRAME}] The frame MUST be
+ encoded as a key frame. (only for encoders)
+ \end{description}
+\item[\field{timestamp}] is an abstract sequence counter that can be
+ used for synchronization. When \field{queue_type} is set to
+ VIRTIO_VIDEO_QUEUE_TYPE_INPUT, the driver MUST set this field to a unique
+ value per frame. If using multiple VIRTIO_VIDEO_RESOURCE_QUEUE requests per
+ frame, then the timestamps for a given frame MUST be identical.
+ For VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT, the driver MUST set it to 0.
+\item[\field{data_sizes}] number of data bytes used for each plane. The driver
+ MUST set this for each plane of an input buffer. For output buffers, the
+ driver MUST set this to zero.
+\end{description}
+
+The device responds with \field{virtio_video_resource_queue_resp}:
+\begin{lstlisting}
+enum virtio_video_dequeue_flag {
+ VIRTIO_VIDEO_DEQUEUE_FLAG_ERR = 0,
+ VIRTIO_VIDEO_DEQUEUE_FLAG_EOS,
+
+ /* Encoder only */
+ VIRTIO_VIDEO_DEQUEUE_FLAG_KEY_FRAME,
+ VIRTIO_VIDEO_DEQUEUE_FLAG_P_FRAME,
+ VIRTIO_VIDEO_DEQUEUE_FLAG_B_FRAME,
+};
+
+struct virtio_video_resource_queue_resp {
+ le32 result;
+ le32 flags;
+ le64 timestamp;
+ le32 data_sizes[VIRTIO_VIDEO_MAX_PLANES];
+};
+\end{lstlisting}
+\begin{description}
+\item[\field{result}] MUST be set to one of variants of \field{enum
+ virtio_video_result}.
+\item[\field{flags}] is a bitmask of VIRTIO_VIDEO_DEQUEUE_FLAG_* flags.
+ \begin{description}
+ \item[\field{VIRTIO_VIDEO_DEQUEUE_FLAG_ERR}] When this flag is set, the data
+ might have been corrupted or the process was terminated by
+ VIRTIO_VIDEO_CMD_QUEUE_CLEAR.
+ \item[\field{VIRTIO_VIDEO_DEQUEUE_FLAG_EOS}] When this flag is set, this is
+ the last frame for the current stream.
+ \item[\field{VIRTIO_VIDEO_DEQUEUE_FLAG_KEY_FRAME}] When this flag is set, the
+ buffer contains a compressed image which is a key frame. (only for encoders)
+ \item[\field{VIRTIO_VIDEO_DEQUEUE_FLAG_P_FRAME}] When this flag is set, the
+ buffer contains contain only differences to a previous key frame. (only for
+ encoders)
+ \item[\field{VIRTIO_VIDEO_DEQUEUE_FLAG_B_FRAME}] When this flag is set,
+ the buffer contains only the differences between the current frame and both
+ the preceding and following key frames to specify its content. (only for
+ encoders)
+ \end{description}
+\item[\field{timestamp}] is an abstract sequence counter that can be
+ used for synchronization. For an output buffer, the device MUST copy
+ the \field{timestamp} of the input buffer this output buffer was
+ produced from.
+\item[\field{timestamp}] is an abstract sequence counter that can be
+ used for synchronization. When \field{queue_type} is set to
+ VIRTIO_VIDEO_QUEUE_TYPE_INPUT, the device MUST set this field to 0.
+ For VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT, the device MUST copy the \field{timestamp}
+ from requests of input buffers the frame of this response was produced from.
+\item[\field{data_sizes}] is the size written by the device, for each valid
+ plane.
+\end{description}
+
+\begin{itemize*}
+\item For each VIRTIO_VIDEO_CMD_RESOURCE_QUEUE request, the device MUST send a
+ response to the queue request with VIRTIO_VIDEO_OK_NODATA when it has finished
+ processing the buffer successfully.
+\item The device MUST mark a buffer that triggered a processing error with the
+ VIRTIO_VIDEO_BUFFER_F_ERR flag.
+\item The device MUST mark the last buffer with the VIRTIO_VIDEO_BUFFER_F_EOS
+ flag to denote completion of the drain sequence.
+\item In case of encoder, to denote a particular frame type the device MUST mark
+ the respective buffer with VIRTIO_VIDEO_BUFFER_IFRAME,
+ VIRTIO_VIDEO_BUFFER_PFRAME, or VIRTIO_VIDEO_BUFFER_BFRAME.
+\item If the processing was stopped due to VIRTIO_VIDEO_CMD_QUEUE_CLEAR, the
+ device MUST set \field{result} to VIRTIO_VIDEO_RESP_OK_NODATA and set the bit
+ of VIRTIO_VIDEO_BUFFER_FLAG_ERR in \field{flags} in
+ \field{virtio_video_resource_queue_resp}.
+\item The driver and device MUST follow requirements about buffer ownership
+ explained in \ref{sec:Device Types / Video Device / Device Operation / Buffer
+ lifecycle}.
+\end{itemize*}
+\end{description}
+
+\subsubsection{Event Virtqueue}
+
+While processing buffers, the device can send asynchronous event notifications
+to the driver. The behaviour depends on the exact stream. For example, the
+decoder device sends a resolution change event when it encounters new resolution
+metadata in the stream.
+
+The device reports events on the event queue. The driver initially populates the
+queue with device-writeable buffers. When the device needs to report an event,
+it fills a buffer and notifies the driver. The driver consumes the event and
+adds a new buffer to the virtqueue.
+\begin{lstlisting}
+enum virtio_video_event_type {
+ /* For all devices */
+ VIRTIO_VIDEO_EVENT_ERROR = 0x0100,
+
+ /* For decoder only */
+ VIRTIO_VIDEO_EVENT_DECODER_RESOLUTION_CHANGED = 0x0200,
+};
+
+struct virtio_video_event {
+ le32 event_type; /* One of VIRTIO_VIDEO_EVENT_* types */
+ le32 stream_id;
+};
+\end{lstlisting}
+
+\begin{description}
+\item[\field{event_type}] type of the triggered event.
+\item[\field{stream_id}] id of the source stream.
+\end{description}
+
+The device MUST send VIRTIO_VIDEO_EVENT_DECODER_RESOLUTION_CHANGED whenever it
+encounters new resolution data in the stream. This includes the case of the
+initial device configuration after metadata has been parsed and the case of
+dynamic resolution change.
+
+\subsubsection{Buffer life cycle}
+\label{sec:Device Types / Video Device / Device Operation / Buffer
+ life cycle}
+
+The state machine in Figure~\ref{fig:buffer-lifecycle} shows the life
+cycle of a video buffer.
+``ATTACH'' and ``QUEUE'' on edges represent per-resource device operations
+VIRTIO_VIDEO_CMD_RESOURCE_ATTACH and VIRTIO_VIDEO_CMD_RESOURCE_QUEUE,
+respectively.
+The edges labeled with ''detach'' represents the following cases:
+\begin{itemize}
+\item VIRTIO_VIDEO_CMD_STREAM_DESTROY is completed,
+\item VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES is completed, or
+\item another resource is attached for the resource_id by
+ VIRTIO_VIDEO_CMD_RESOURCE_ATTACH.
+\end{itemize}
+
+VIRTIO_VIDEO_CMD_STREAM_DESTROY or VIRTIO_VIDEO_CMD_QUEUE_DETACH_RESOURCES.
+
+\begin{figure}[h]
+ \centering
+ \includegraphics[width=\textwidth]{images/generated/video-buffer-lifecycle.png}
+ \caption{Life Cycle of a Buffer}
+ \label{fig:buffer-lifecycle}
+\end{figure}
+
+
+\drivernormative{\subparagraph}{Buffer life cycle}{Device Types / Video Device /
+ Device Operation / Buffer life cycle}
+
+The following table shows whether the driver can read or write each buffer in
+each state in Figure~\ref{fig:buffer-lifecycle}. The driver MUST not read or
+write buffers in the state that doesn't permit.
+\begin{center}
+ \begin{tabular}{|c|c|c|}
+ \hline
+ State & Input buffers & Output buffers \\
+ \hline
+ Detached & Read / Write & Read \\
+ Queued & - & - \\
+ Dequeued & Read / Write & Read \\
+ \hline
+ \end{tabular}
+\end{center}
+
+\devicenormative{\subparagraph}{Buffer life cycle}{Device Types / Video
+ Device / Device Operation / Buffer life cycle}
+
+The following table shows whether the device can read or write each buffer in
+each state in Figure~\ref{fig:buffer-lifecycle}. The device MUST not read or
+write buffers in the state that doesn't permit.
+\begin{center}
+ \begin{tabular}{ |c|c|c| }
+ \hline
+ State & Input buffers & Output buffers \\
+ \hline
+ Detached & - & - \\
+ Queued & Read & Read / Write \\
+ Dequeued & - & Read \\
+ \hline
+ \end{tabular}
+\end{center}
--
2.27.0.111.gc72c7da667-goog
More information about the Spice-devel
mailing list