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 encode API over pipe FD. 6 7 use std::error; 8 use std::fmt; 9 use std::fmt::Display; 10 11 use enumn::N; 12 13 use super::bindings; 14 use super::session::VeaInputBufferId; 15 use super::session::VeaOutputBufferId; 16 use crate::error::*; 17 18 /// Represents an error from a libvda encode session. 19 #[derive(Debug, Clone, Copy, N)] 20 #[repr(u32)] 21 pub enum VeaError { 22 IllegalState = bindings::vea_error_ILLEGAL_STATE_ERROR, 23 InvalidArgument = bindings::vea_error_INVALID_ARGUMENT_ERROR, 24 PlatformFailure = bindings::vea_error_PLATFORM_FAILURE_ERROR, 25 } 26 27 impl error::Error for VeaError {} 28 29 impl VeaError { new(res: bindings::vea_error_t) -> VeaError30 pub(crate) fn new(res: bindings::vea_error_t) -> VeaError { 31 VeaError::n(res).unwrap_or_else(|| panic!("Unknown error is reported from VEA: {}", res)) 32 } 33 } 34 35 impl Display for VeaError { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 use self::VeaError::*; 38 match self { 39 IllegalState => write!(f, "illegal state"), 40 InvalidArgument => write!(f, "invalid argument"), 41 PlatformFailure => write!(f, "platform failure"), 42 } 43 } 44 } 45 46 /// Represents a notified event from libvda. 47 #[derive(Debug)] 48 pub enum Event { 49 /// Requests the user to provide input buffers. 50 RequireInputBuffers { 51 input_count: u32, 52 input_frame_width: u32, 53 input_frame_height: u32, 54 output_buffer_size: u32, 55 }, 56 /// Notifies the user that an input buffer has been processed. 57 ProcessedInputBuffer(VeaInputBufferId), 58 /// Notifies the user that an output buffer has been processed. 59 ProcessedOutputBuffer { 60 output_buffer_id: VeaOutputBufferId, 61 payload_size: u32, 62 key_frame: bool, 63 timestamp: i64, 64 }, 65 /// Notifies the result of operation issued by `Session::flush`. 66 FlushResponse { flush_done: bool }, 67 /// Notifies the user of an error. 68 NotifyError(VeaError), 69 } 70 71 impl Event { 72 /// Creates a new `Event` from a `vea_event_t` instance. 73 /// This function is safe if `event` was a value read from libvda's pipe. new(event: bindings::vea_event_t) -> Result<Self>74 pub(crate) unsafe fn new(event: bindings::vea_event_t) -> Result<Self> { 75 use self::Event::*; 76 77 let bindings::vea_event_t { 78 event_data, 79 event_type, 80 } = event; 81 82 match event_type { 83 bindings::vea_event_type_REQUIRE_INPUT_BUFFERS => { 84 let d = event_data.require_input_buffers; 85 Ok(RequireInputBuffers { 86 input_count: d.input_count, 87 input_frame_width: d.input_frame_width, 88 input_frame_height: d.input_frame_height, 89 output_buffer_size: d.output_buffer_size, 90 }) 91 } 92 bindings::vea_event_type_PROCESSED_INPUT_BUFFER => { 93 Ok(ProcessedInputBuffer(event_data.processed_input_buffer_id)) 94 } 95 bindings::vea_event_type_PROCESSED_OUTPUT_BUFFER => { 96 let d = event_data.processed_output_buffer; 97 Ok(ProcessedOutputBuffer { 98 output_buffer_id: d.output_buffer_id, 99 payload_size: d.payload_size, 100 key_frame: d.key_frame == 1, 101 timestamp: d.timestamp, 102 }) 103 } 104 bindings::vea_event_type_VEA_FLUSH_RESPONSE => Ok(FlushResponse { 105 flush_done: event_data.flush_done == 1, 106 }), 107 bindings::vea_event_type_VEA_NOTIFY_ERROR => { 108 Ok(NotifyError(VeaError::new(event_data.error))) 109 } 110 t => panic!("Unknown event is reported from VEA: {}", t), 111 } 112 } 113 } 114