devices/virtio/video/
async_cmd_desc_map.rs1use std::collections::BTreeMap;
6
7use crate::virtio::video::command::QueueType;
8use crate::virtio::video::device::AsyncCmdResponse;
9use crate::virtio::video::device::AsyncCmdTag;
10use crate::virtio::video::error::VideoError;
11use crate::virtio::video::protocol;
12use crate::virtio::video::response::CmdResponse;
13use crate::virtio::DescriptorChain;
14
15#[derive(Default)]
18pub struct AsyncCmdDescMap(BTreeMap<AsyncCmdTag, DescriptorChain>);
19
20impl AsyncCmdDescMap {
21 pub fn insert(&mut self, tag: AsyncCmdTag, descriptor_chain: DescriptorChain) {
22 self.0.insert(tag, descriptor_chain);
23 }
24
25 pub fn remove(&mut self, tag: &AsyncCmdTag) -> Option<DescriptorChain> {
26 self.0.remove(tag)
27 }
28
29 pub fn create_cancellation_responses(
36 &self,
37 target_stream_id: &u32,
38 target_queue_type: Option<QueueType>,
39 processing_tag: Option<AsyncCmdTag>,
40 ) -> Vec<AsyncCmdResponse> {
41 let mut responses = vec![];
42 for tag in self.0.keys().filter(|&&k| Some(k) != processing_tag) {
43 match tag {
44 AsyncCmdTag::Queue {
45 stream_id,
46 queue_type,
47 ..
48 } if stream_id == target_stream_id
49 && target_queue_type.as_ref().unwrap_or(queue_type) == queue_type =>
50 {
51 responses.push(AsyncCmdResponse::from_response(
52 *tag,
53 CmdResponse::ResourceQueue {
54 timestamp: 0,
55 flags: protocol::VIRTIO_VIDEO_BUFFER_FLAG_ERR,
56 size: 0,
57 },
58 ));
59 }
60 AsyncCmdTag::Drain { stream_id } if stream_id == target_stream_id => {
61 responses.push(AsyncCmdResponse::from_error(
64 *tag,
65 VideoError::InvalidOperation,
66 ));
67 }
68 AsyncCmdTag::Clear {
69 stream_id,
70 queue_type,
71 } if stream_id == target_stream_id
72 && target_queue_type.as_ref().unwrap_or(queue_type) == queue_type =>
73 {
74 responses.push(AsyncCmdResponse::from_error(
77 *tag,
78 VideoError::InvalidOperation,
79 ));
80 }
81 _ => {
82 }
84 }
85 }
86 responses
87 }
88}