• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Parameters for streams in virtio video devices.
6 
7 use std::convert::{From, Into, TryFrom};
8 
9 use base::error;
10 use data_model::Le32;
11 
12 use crate::virtio::video::command::{QueueType, ReadCmdError};
13 use crate::virtio::video::format::*;
14 use crate::virtio::video::protocol::*;
15 
16 /// Safe wrapper of `virtio_video_params`.
17 /// Note that this struct doesn't have a field corresponding to `queue_type` in
18 /// `virtio_video_params`. The type of queue should be stored by one that has an `Params` instance.
19 #[derive(Debug, Default, Clone)]
20 pub struct Params {
21     // Use `Option<Format>` instead of `Format` because an image format may not be determined until
22     // video decoding is started in the decoder.
23     pub format: Option<Format>,
24     pub frame_width: u32,
25     pub frame_height: u32,
26     pub min_buffers: u32,
27     pub max_buffers: u32,
28     pub crop: Crop,
29     pub frame_rate: u32,
30     pub plane_formats: Vec<PlaneFormat>,
31 }
32 
33 impl TryFrom<virtio_video_params> for Params {
34     type Error = ReadCmdError;
35 
36     fn try_from(
37         virtio_video_params {
38             format,
39             frame_width,
40             frame_height,
41             min_buffers,
42             max_buffers,
43             crop,
44             frame_rate,
45             num_planes,
46             plane_formats,
47             ..
48         }: virtio_video_params,
49     ) -> Result<Self, Self::Error> {
50         let num_planes = Into::<u32>::into(num_planes); // as usize;
51         if num_planes as usize > plane_formats.len() {
52             error!(
53                 "num_planes must not exceed {} but {}",
54                 plane_formats.len(),
55                 Into::<u32>::into(num_planes)
56             );
57             return Err(ReadCmdError::InvalidArgument);
58         }
59         let plane_formats = plane_formats[0..num_planes as usize]
60             .iter()
61             .map(|x| Into::<PlaneFormat>::into(*x))
62             .collect::<Vec<_>>();
63 
64         Ok(Params {
65             format: Format::n(format.into()),
66             frame_width: frame_width.into(),
67             frame_height: frame_height.into(),
68             min_buffers: min_buffers.into(),
69             max_buffers: max_buffers.into(),
70             crop: crop.into(),
71             frame_rate: frame_rate.into(),
72             plane_formats,
73         })
74     }
75 }
76 
77 impl Params {
to_virtio_video_params(&self, queue_type: QueueType) -> virtio_video_params78     pub fn to_virtio_video_params(&self, queue_type: QueueType) -> virtio_video_params {
79         let Params {
80             format,
81             frame_width,
82             frame_height,
83             min_buffers,
84             max_buffers,
85             crop,
86             frame_rate,
87             plane_formats,
88         } = self;
89         let num_planes = Le32::from(plane_formats.len() as u32);
90         let mut p_fmts: [virtio_video_plane_format; VIRTIO_VIDEO_MAX_PLANES as usize] =
91             Default::default();
92         for (i, pf) in plane_formats.iter().enumerate() {
93             p_fmts[i] = Into::<virtio_video_plane_format>::into(*pf);
94         }
95 
96         virtio_video_params {
97             queue_type: (queue_type as u32).into(),
98             format: format
99                 .map(|f| Le32::from(f as u32))
100                 .unwrap_or_else(|| Le32::from(0)),
101             frame_width: Le32::from(*frame_width),
102             frame_height: Le32::from(*frame_height),
103             min_buffers: Le32::from(*min_buffers),
104             max_buffers: Le32::from(*max_buffers),
105             crop: virtio_video_crop::from(*crop),
106             frame_rate: Le32::from(*frame_rate),
107             num_planes,
108             plane_formats: p_fmts,
109         }
110     }
111 }
112