1use anyhow::{anyhow, Result};
2
3use crate::core::{FrameData, PixelFormat};
4use crate::h264::H264Config;
5use crate::mp4::EncodedSample;
6
7#[derive(Debug)]
8pub struct VideoFrame {
9 pub width: u32,
10 pub height: u32,
11 pub pts_us: i64,
12 pub format: PixelFormat,
13 pub data: FrameData,
15}
16
17pub trait H264Decoder {
18 fn push(&mut self, sample: EncodedSample) -> Result<()>;
19 fn flush(&mut self) -> Result<()>;
20 fn try_receive(&mut self) -> Result<Option<VideoFrame>>;
21}
22
23pub fn create_default_h264_decoder(cfg: &H264Config) -> Result<Box<dyn H264Decoder>> {
24 #[cfg(target_os = "windows")]
25 {
26 return Ok(Box::new(mf::MfH264Decoder::new(cfg.clone())?));
27 }
28
29 #[cfg(any(target_os = "macos", target_os = "ios"))]
30 {
31 return Ok(Box::new(vt::VtH264Decoder::new(cfg.clone())?));
32 }
33
34 #[cfg(target_os = "android")]
35 {
36 return Ok(Box::new(mediacodec::AndroidH264Decoder::new(cfg.clone())?));
37 }
38
39 #[cfg(target_os = "linux")]
40 {
41 return Ok(Box::new(gst::GstH264Decoder::new(cfg.clone())?));
42 }
43
44 #[allow(unreachable_code)]
45 Err(anyhow!("no supported H.264 system decoder backend for this target"))
46}
47
48#[cfg(target_os = "linux")]
49mod gst;
50
51#[cfg(target_os = "windows")]
52mod mf;
53
54#[cfg(any(target_os = "macos", target_os = "ios"))]
55mod vt;
56
57#[cfg(target_os = "android")]
58mod mediacodec;