azul_core/video.rs
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
14use crate::resources::RawImageFormat;
15use azul_css::{AzString, U8Vec};
16
17/// Requested video-playback configuration.
18#[repr(C)]
19#[derive(Debug, Clone, PartialEq)]
20pub 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
32impl 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
43impl 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)]
60pub 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
69impl 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).
81impl_option!(VideoFrame, OptionVideoFrame, copy = false, [Clone, Debug]);