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