Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/video/response.rs
5394 views
1
// Copyright 2020 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
//! Data structures for commands of virtio video devices.
6
7
use std::io;
8
9
use data_model::Le32;
10
use data_model::Le64;
11
12
use crate::virtio::video::command::QueueType;
13
use crate::virtio::video::control::*;
14
use crate::virtio::video::error::VideoError;
15
use crate::virtio::video::format::*;
16
use crate::virtio::video::params::Params;
17
use crate::virtio::video::protocol::*;
18
use crate::virtio::Writer;
19
20
pub trait Response {
21
/// Writes an object to virtqueue.
22
fn write(&self, w: &mut Writer) -> Result<(), io::Error>;
23
}
24
25
#[derive(Debug, Clone)]
26
pub enum CmdError {
27
InvalidResourceId,
28
InvalidStreamId,
29
InvalidParameter,
30
InvalidOperation,
31
UnsupportedControl,
32
}
33
34
/// A response to a `VideoCmd`. These correspond to `VIRTIO_VIDEO_RESP_*`.
35
#[derive(Debug, Clone)]
36
pub enum CmdResponse {
37
NoData,
38
QueryCapability(Vec<FormatDesc>),
39
ResourceQueue {
40
timestamp: u64,
41
flags: u32,
42
size: u32,
43
},
44
GetParams {
45
queue_type: QueueType,
46
params: Params,
47
is_ext: bool,
48
},
49
QueryControl(QueryCtrlResponse),
50
GetControl(CtrlVal),
51
// TODO(alexlau): SetControl is unused, remove this after encoder CL lands.
52
#[allow(dead_code)]
53
SetControl,
54
Error(CmdError),
55
}
56
57
impl From<VideoError> for CmdResponse {
58
fn from(error: VideoError) -> Self {
59
let cmd_error = match error {
60
VideoError::InvalidResourceId { .. } => CmdError::InvalidResourceId,
61
VideoError::InvalidStreamId(_) => CmdError::InvalidStreamId,
62
VideoError::InvalidParameter => CmdError::InvalidParameter,
63
VideoError::UnsupportedControl(_) => CmdError::UnsupportedControl,
64
_ => CmdError::InvalidOperation,
65
};
66
CmdResponse::Error(cmd_error)
67
}
68
}
69
70
impl Response for CmdResponse {
71
/// Writes a response to virtqueue.
72
fn write(&self, w: &mut Writer) -> Result<(), io::Error> {
73
use CmdResponse::*;
74
75
let type_ = Le32::from(match self {
76
NoData => VIRTIO_VIDEO_RESP_OK_NODATA,
77
QueryCapability(_) => VIRTIO_VIDEO_RESP_OK_QUERY_CAPABILITY,
78
ResourceQueue { .. } => VIRTIO_VIDEO_RESP_OK_RESOURCE_QUEUE,
79
GetParams { .. } => VIRTIO_VIDEO_RESP_OK_GET_PARAMS,
80
QueryControl(_) => VIRTIO_VIDEO_RESP_OK_QUERY_CONTROL,
81
GetControl(_) => VIRTIO_VIDEO_RESP_OK_GET_CONTROL,
82
SetControl => VIRTIO_VIDEO_RESP_OK_NODATA,
83
Error(e) => {
84
match e {
85
// TODO(b/1518105): Add more detailed error code when a new protocol supports
86
// them.
87
CmdError::InvalidResourceId => VIRTIO_VIDEO_RESP_ERR_INVALID_RESOURCE_ID,
88
CmdError::InvalidStreamId => VIRTIO_VIDEO_RESP_ERR_INVALID_STREAM_ID,
89
CmdError::InvalidParameter => VIRTIO_VIDEO_RESP_ERR_INVALID_PARAMETER,
90
CmdError::InvalidOperation => VIRTIO_VIDEO_RESP_ERR_INVALID_OPERATION,
91
CmdError::UnsupportedControl => VIRTIO_VIDEO_RESP_ERR_UNSUPPORTED_CONTROL,
92
}
93
}
94
});
95
96
let hdr = virtio_video_cmd_hdr {
97
type_,
98
..Default::default()
99
};
100
101
match self {
102
NoData | Error(_) => w.write_obj(hdr),
103
QueryCapability(descs) => {
104
w.write_obj(virtio_video_query_capability_resp {
105
hdr,
106
num_descs: Le32::from(descs.len() as u32),
107
..Default::default()
108
})?;
109
descs.iter().try_for_each(|d| d.write(w))
110
}
111
ResourceQueue {
112
timestamp,
113
flags,
114
size,
115
} => w.write_obj(virtio_video_resource_queue_resp {
116
hdr,
117
timestamp: Le64::from(*timestamp),
118
flags: Le32::from(*flags),
119
size: Le32::from(*size),
120
}),
121
GetParams {
122
queue_type,
123
params,
124
is_ext,
125
} => {
126
if *is_ext {
127
let params = params.to_virtio_video_params_ext(*queue_type);
128
w.write_obj(virtio_video_get_params_ext_resp { hdr, params })
129
} else {
130
let params = params.to_virtio_video_params(*queue_type);
131
w.write_obj(virtio_video_get_params_resp { hdr, params })
132
}
133
}
134
QueryControl(r) => {
135
w.write_obj(virtio_video_query_control_resp { hdr })?;
136
r.write(w)
137
}
138
GetControl(val) => {
139
w.write_obj(virtio_video_get_control_resp { hdr })?;
140
val.write(w)
141
}
142
SetControl => w.write_obj(virtio_video_set_control_resp { hdr }),
143
}
144
}
145
}
146
147