1 // Copyright 2025 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 use std::path::PathBuf; 6 use std::rc::Rc; 7 8 use crate::c2_wrapper::c2_decoder::C2DecoderBackend; 9 use crate::decoder::stateless::av1::Av1; 10 use crate::decoder::stateless::h264::H264; 11 use crate::decoder::stateless::h265::H265; 12 use crate::decoder::stateless::vp8::Vp8; 13 use crate::decoder::stateless::vp9::Vp9; 14 use crate::decoder::stateless::DynStatelessVideoDecoder; 15 use crate::decoder::stateless::StatelessDecoder; 16 use crate::decoder::stateless::StatelessVideoDecoder; 17 use crate::decoder::BlockingMode; 18 use crate::video_frame::VideoFrame; 19 use crate::EncodedFormat; 20 use crate::Fourcc; 21 22 #[derive(Clone, Debug)] 23 pub struct C2VaapiDecoderOptions { 24 pub libva_device_path: Option<PathBuf>, 25 } 26 27 pub struct C2VaapiDecoder { 28 display: Rc<libva::Display>, 29 } 30 31 impl C2DecoderBackend for C2VaapiDecoder { 32 type DecoderOptions = C2VaapiDecoderOptions; 33 new(options: C2VaapiDecoderOptions) -> Result<Self, String>34 fn new(options: C2VaapiDecoderOptions) -> Result<Self, String> { 35 let display = match options.libva_device_path { 36 Some(libva_device_path) => libva::Display::open_drm_display(libva_device_path.clone()) 37 .map_err(|_| format!("failed to open libva display {libva_device_path:?}"))?, 38 None => libva::Display::open().ok_or("failed to open libva display")?, 39 }; 40 41 Ok(Self { display: display }) 42 } 43 supported_output_formats(&self) -> Result<Vec<Fourcc>, String>44 fn supported_output_formats(&self) -> Result<Vec<Fourcc>, String> { 45 let image_fmts = self 46 .display 47 .query_image_formats() 48 .map_err(|_| String::from("Failed to query image formats."))?; 49 50 let mut supported_formats: Vec<Fourcc> = Vec::new(); 51 for format in image_fmts.iter() { 52 supported_formats.push(Fourcc::from(format.fourcc)); 53 } 54 55 return Ok(supported_formats); 56 } 57 get_decoder<V: VideoFrame + 'static>( &mut self, format: EncodedFormat, ) -> Result<DynStatelessVideoDecoder<V>, String>58 fn get_decoder<V: VideoFrame + 'static>( 59 &mut self, 60 format: EncodedFormat, 61 ) -> Result<DynStatelessVideoDecoder<V>, String> { 62 Ok(match format { 63 EncodedFormat::H264 => StatelessDecoder::<H264, _>::new_vaapi( 64 self.display.clone(), 65 BlockingMode::NonBlocking, 66 ) 67 .map_err(|_| "Failed to instantiate H264 encoder")? 68 .into_trait_object(), 69 EncodedFormat::H265 => StatelessDecoder::<H265, _>::new_vaapi( 70 self.display.clone(), 71 BlockingMode::NonBlocking, 72 ) 73 .map_err(|_| "Failed to instantiate H265 encoder")? 74 .into_trait_object(), 75 EncodedFormat::VP8 => StatelessDecoder::<Vp8, _>::new_vaapi( 76 self.display.clone(), 77 BlockingMode::NonBlocking, 78 ) 79 .map_err(|_| "Failed to instantiate VP8 encoder")? 80 .into_trait_object(), 81 EncodedFormat::VP9 => StatelessDecoder::<Vp9, _>::new_vaapi( 82 self.display.clone(), 83 BlockingMode::NonBlocking, 84 ) 85 .map_err(|_| "Failed to instantiate VP9 encoder")? 86 .into_trait_object(), 87 EncodedFormat::AV1 => StatelessDecoder::<Av1, _>::new_vaapi( 88 self.display.clone(), 89 BlockingMode::NonBlocking, 90 ) 91 .map_err(|_| "Failed to instantiate AV1 encoder")? 92 .into_trait_object(), 93 }) 94 } 95 } 96