xref: /aosp_15_r20/external/crosvm/media/libvda/src/decode/event.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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 //! Events reported by VDA over pipe FD.
6 
7 use std::fmt;
8 use std::fmt::Display;
9 
10 use enumn::N;
11 
12 use super::bindings;
13 use crate::error::*;
14 
15 /// Represents a response from libvda.
16 ///
17 /// Each value corresponds to a value of [`VideoDecodeAccelerator::Result`](https://cs.chromium.org/chromium/src/components/arc/common/video_decode_accelerator.mojom?rcl=128dc1f18791dc4593b9fd671aab84cb72bf6830&l=84).
18 #[derive(Debug, Clone, Copy, N)]
19 #[repr(u32)]
20 pub enum Response {
21     Success = bindings::vda_result_SUCCESS,
22     IllegalState = bindings::vda_result_ILLEGAL_STATE,
23     InvalidArgument = bindings::vda_result_INVALID_ARGUMENT,
24     UnreadableInput = bindings::vda_result_UNREADABLE_INPUT,
25     PlatformFailure = bindings::vda_result_PLATFORM_FAILURE,
26     InsufficientResources = bindings::vda_result_INSUFFICIENT_RESOURCES,
27     Cancelled = bindings::vda_result_CANCELLED,
28 }
29 
30 impl Response {
new(res: bindings::vda_result_t) -> Response31     pub(crate) fn new(res: bindings::vda_result_t) -> Response {
32         Response::n(res).unwrap_or_else(|| panic!("Unknown response is reported from VDA: {}", res))
33     }
34 }
35 
36 impl Display for Response {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result37     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38         use self::Response::*;
39         match self {
40             Success => write!(f, "success"),
41             IllegalState => write!(f, "illegal state"),
42             InvalidArgument => write!(f, "invalid argument"),
43             UnreadableInput => write!(f, "unreadable input"),
44             PlatformFailure => write!(f, "platform failure"),
45             InsufficientResources => write!(f, "insufficient resources"),
46             Cancelled => write!(f, "cancelled"),
47         }
48     }
49 }
50 
51 impl From<Response> for Result<()> {
from(r: Response) -> Self52     fn from(r: Response) -> Self {
53         match r {
54             Response::Success => Ok(()),
55             _ => Err(Error::LibVdaFailure(r)),
56         }
57     }
58 }
59 
60 /// Represents a notified event from libvda.
61 #[derive(Debug)]
62 pub enum Event {
63     /// Requests the users to provide output buffers.
64     ProvidePictureBuffers {
65         min_num_buffers: u32,
66         width: i32,
67         height: i32,
68         visible_rect_left: i32,
69         visible_rect_top: i32,
70         visible_rect_right: i32,
71         visible_rect_bottom: i32,
72     },
73     /// Notifies the user of a decoded frame ready for display.
74     /// These events will arrive in display order.
75     PictureReady {
76         buffer_id: i32,
77         bitstream_id: i32,
78         left: i32,
79         top: i32,
80         right: i32,
81         bottom: i32,
82     },
83     /// Notifies the end of bitstream buffer.
84     NotifyEndOfBitstreamBuffer {
85         bitstream_id: i32,
86     },
87     NotifyError(Response),
88     /// Notifies the result of operation issued by `Session::reset`.
89     ResetResponse(Response),
90     /// Notifies the result of operation issued by `Session::flush`.
91     FlushResponse(Response),
92 }
93 
94 impl Event {
95     /// Creates a new `Event` from a `vda_event_t` instance.
96     /// This function is safe if `event` was a value read from libvda's pipe.
new(event: bindings::vda_event_t) -> Result<Event>97     pub(crate) unsafe fn new(event: bindings::vda_event_t) -> Result<Event> {
98         use self::Event::*;
99 
100         let data = event.event_data;
101         match event.event_type {
102             bindings::vda_event_type_PROVIDE_PICTURE_BUFFERS => {
103                 let d = data.provide_picture_buffers;
104                 Ok(ProvidePictureBuffers {
105                     min_num_buffers: d.min_num_buffers,
106                     width: d.width,
107                     height: d.height,
108                     visible_rect_left: d.visible_rect_left,
109                     visible_rect_top: d.visible_rect_top,
110                     visible_rect_right: d.visible_rect_right,
111                     visible_rect_bottom: d.visible_rect_bottom,
112                 })
113             }
114             bindings::vda_event_type_PICTURE_READY => {
115                 let d = data.picture_ready;
116                 Ok(PictureReady {
117                     buffer_id: d.picture_buffer_id,
118                     bitstream_id: d.bitstream_id,
119                     left: d.crop_left,
120                     top: d.crop_top,
121                     right: d.crop_right,
122                     bottom: d.crop_bottom,
123                 })
124             }
125             bindings::vda_event_type_NOTIFY_END_OF_BITSTREAM_BUFFER => {
126                 Ok(NotifyEndOfBitstreamBuffer {
127                     bitstream_id: data.bitstream_id,
128                 })
129             }
130             bindings::vda_event_type_NOTIFY_ERROR => Ok(NotifyError(Response::new(data.result))),
131             bindings::vda_event_type_RESET_RESPONSE => {
132                 Ok(ResetResponse(Response::new(data.result)))
133             }
134             bindings::vda_event_type_FLUSH_RESPONSE => {
135                 Ok(FlushResponse(Response::new(data.result)))
136             }
137             t => panic!("Unknown event is reported from VDA: {}", t),
138         }
139     }
140 }
141