1
//! POD types for the video-playback surface
2
//! (SUPER_PLAN_2 ยง4 Priority 6 + research).
3
//!
4
//! Same "dumb widget" architecture as camera/screencap
5
//! (`azul_layout::widgets::video::VideoWidget`): a background thread decodes
6
//! the source (vk-video - GPU decode + HTTP-range fetch) and its writeback
7
//! uploads each frame into the shared GL-texture `ImageRef` + recomposites.
8
//! Defined here in `azul-core` so the config crosses the FFI without
9
//! `azul-layout` (or vk-video) as a dependency.
10
//!
11
//! Unlike the camera/screencap configs this carries a `source` string, so
12
//! it's `Clone` but not `Copy`.
13

            
14
use crate::resources::RawImageFormat;
15
use azul_css::{AzString, U8Vec};
16

            
17
/// Requested video-playback configuration.
18
#[repr(C)]
19
#[derive(Debug, Clone, PartialEq)]
20
pub struct VideoConfig {
21
    /// Source URL or file path (decoded via vk-video + HTTP-range fetch).
22
    pub source: AzString,
23
    /// Start playing automatically on mount.
24
    pub autoplay: bool,
25
    /// Restart from the beginning when the stream ends.
26
    pub looping: bool,
27
    /// Texture format the decoder delivers. `BGRA8` is the portable default;
28
    /// `Nv12` (a later `RawImageFormat` addition) is the zero-copy path.
29
    pub output_format: RawImageFormat,
30
}
31

            
32
impl Default for VideoConfig {
33
    fn default() -> Self {
34
        Self {
35
            source: AzString::from_const_str(""),
36
            autoplay: true,
37
            looping: false,
38
            output_format: RawImageFormat::BGRA8,
39
        }
40
    }
41
}
42

            
43
impl VideoConfig {
44
    /// A default config playing `source` (autoplay on, no loop, BGRA8).
45
    pub fn new(source: AzString) -> Self {
46
        Self {
47
            source,
48
            ..Self::default()
49
        }
50
    }
51
}
52

            
53
/// One captured or decoded frame - tightly-packed RGBA8 pixels
54
/// (`width * height * 4`). The unit a capture/decode worker produces, the
55
/// `set_on_frame` hook hands to user code (effects / save / send), and (P8)
56
/// azul-meet sends over UDP. Defined here (like [`crate::audio::AudioFrame`])
57
/// so it crosses the FFI without `azul-layout` as a dependency.
58
#[repr(C)]
59
#[derive(Debug, Clone, PartialEq)]
60
pub struct VideoFrame {
61
    /// Frame width in px.
62
    pub width: u32,
63
    /// Frame height in px.
64
    pub height: u32,
65
    /// Tightly-packed RGBA8 pixel bytes (`width * height * 4`).
66
    pub bytes: U8Vec,
67
}
68

            
69
impl VideoFrame {
70
    /// A frame wrapping `bytes` (tightly-packed RGBA8, `width * height * 4`).
71
    pub fn new(width: u32, height: u32, bytes: U8Vec) -> Self {
72
        Self {
73
            width,
74
            height,
75
            bytes,
76
        }
77
    }
78
}
79

            
80
// FFI Option wrapper for a frame-pull hook / accessor. `copy = false` (U8Vec).
81
impl_option!(VideoFrame, OptionVideoFrame, copy = false, [Clone, Debug]);