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