• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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