devices/virtio/video/
params.rs1use std::convert::From;
8use std::convert::Into;
9use std::convert::TryFrom;
10
11use base::error;
12use data_model::Le32;
13
14use crate::virtio::video::command::QueueType;
15use crate::virtio::video::command::ReadCmdError;
16use crate::virtio::video::format::*;
17use crate::virtio::video::protocol::*;
18use crate::virtio::video::resource::ResourceType;
19
20#[derive(Debug, Default, Clone)]
24pub struct Params {
25 pub format: Option<Format>,
28 pub resource_type: ResourceType,
29 pub frame_width: u32,
30 pub frame_height: u32,
31 pub min_buffers: u32,
32 pub max_buffers: u32,
33 pub crop: Crop,
34 pub frame_rate: u32,
35 pub plane_formats: Vec<PlaneFormat>,
36}
37
38impl TryFrom<virtio_video_params> for Params {
39 type Error = ReadCmdError;
40
41 fn try_from(
42 virtio_video_params {
43 format,
44 frame_width,
45 frame_height,
46 min_buffers,
47 max_buffers,
48 crop,
49 frame_rate,
50 num_planes,
51 plane_formats,
52 ..
53 }: virtio_video_params,
54 ) -> Result<Self, Self::Error> {
55 let num_planes = Into::<u32>::into(num_planes); if num_planes as usize > plane_formats.len() {
57 error!(
58 "num_planes must not exceed {} but {}",
59 plane_formats.len(),
60 Into::<u32>::into(num_planes)
61 );
62 return Err(ReadCmdError::InvalidArgument);
63 }
64 let plane_formats = plane_formats[0..num_planes as usize]
65 .iter()
66 .map(|x| Into::<PlaneFormat>::into(*x))
67 .collect::<Vec<_>>();
68
69 Ok(Params {
70 format: Format::n(format.into()),
71 resource_type: Default::default(),
72 frame_width: frame_width.into(),
73 frame_height: frame_height.into(),
74 min_buffers: min_buffers.into(),
75 max_buffers: max_buffers.into(),
76 crop: crop.into(),
77 frame_rate: frame_rate.into(),
78 plane_formats,
79 })
80 }
81}
82
83impl TryFrom<virtio_video_params_ext> for Params {
84 type Error = ReadCmdError;
85
86 fn try_from(
87 virtio_video_params_ext {
88 base,
89 resource_type,
90 ..
91 }: virtio_video_params_ext,
92 ) -> Result<Self, Self::Error> {
93 let mut params = Params::try_from(base)?;
94 params.resource_type = match resource_type.into() {
95 VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES => ResourceType::GuestPages,
96 VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT => ResourceType::VirtioObject,
97 _ => return Err(ReadCmdError::InvalidArgument),
98 };
99
100 Ok(params)
101 }
102}
103
104impl Params {
105 pub fn to_virtio_video_params(&self, queue_type: QueueType) -> virtio_video_params {
106 let Params {
107 format,
108 resource_type: _,
109 frame_width,
110 frame_height,
111 min_buffers,
112 max_buffers,
113 crop,
114 frame_rate,
115 plane_formats,
116 } = self;
117 let num_planes = Le32::from(plane_formats.len() as u32);
118 let mut p_fmts: [virtio_video_plane_format; VIRTIO_VIDEO_MAX_PLANES as usize] =
119 Default::default();
120 for (i, pf) in plane_formats.iter().enumerate() {
121 p_fmts[i] = Into::<virtio_video_plane_format>::into(*pf);
122 }
123
124 virtio_video_params {
125 queue_type: (queue_type as u32).into(),
126 format: format
127 .map(|f| Le32::from(f as u32))
128 .unwrap_or_else(|| Le32::from(0)),
129 frame_width: Le32::from(*frame_width),
130 frame_height: Le32::from(*frame_height),
131 min_buffers: Le32::from(*min_buffers),
132 max_buffers: Le32::from(*max_buffers),
133 crop: virtio_video_crop::from(*crop),
134 frame_rate: Le32::from(*frame_rate),
135 num_planes,
136 plane_formats: p_fmts,
137 }
138 }
139
140 pub fn to_virtio_video_params_ext(&self, queue_type: QueueType) -> virtio_video_params_ext {
141 let Params { resource_type, .. } = self;
142
143 let resource_type = match *resource_type {
144 ResourceType::GuestPages => VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES,
145 ResourceType::VirtioObject => VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT,
146 };
147
148 virtio_video_params_ext {
149 base: self.to_virtio_video_params(queue_type),
150 resource_type: Le32::from(resource_type),
151 padding: Default::default(),
152 }
153 }
154}