1pub mod mux {
2 use core::ffi::{c_char, c_void};
3 use core::ptr::NonNull;
4
5 #[repr(C)]
6 pub struct IWriter {
7 _opaque_c_aligned: *mut c_void,
8 }
9 pub type WriterMutPtr = *mut IWriter;
10 pub type WriterNonNullPtr = NonNull<IWriter>;
11
12 pub type WriterWriteFn = extern "C" fn(*mut c_void, *const c_void, usize) -> bool;
13 pub type WriterGetPosFn = extern "C" fn(*mut c_void) -> u64;
14 pub type WriterSetPosFn = extern "C" fn(*mut c_void, u64) -> bool;
15 pub type WriterElementStartNotifyFn = extern "C" fn(*mut c_void, u64, i64);
16
17 pub type TrackNum = u64;
19
20 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
21 #[repr(i32)]
22 pub enum ResultCode {
23 Ok = 0,
25
26 BadParam = -1,
28
29 UnknownLibwebmError = -2,
33 }
34
35 pub const OPUS_CODEC_ID: u32 = 0;
37 pub const VORBIS_CODEC_ID: u32 = 1;
38
39 pub const VP8_CODEC_ID: u32 = 0;
41 pub const VP9_CODEC_ID: u32 = 1;
42 pub const AV1_CODEC_ID: u32 = 2;
43
44 pub const SEGMENT_MODE_LIVE: u32 = 0x1;
46 pub const SEGMENT_MODE_FILE: u32 = 0x2;
47
48 #[repr(C)]
49 pub struct Segment {
50 _opaque_c_aligned: *mut c_void,
51 }
52 pub type SegmentMutPtr = *mut Segment;
53 pub type SegmentNonNullPtr = NonNull<Segment>;
54
55 #[link(name = "webmadapter", kind = "static")]
56 unsafe extern "C" {
57 #[link_name = "mux_new_writer"]
58 pub fn new_writer(
59 write: Option<WriterWriteFn>,
60 get_pos: Option<WriterGetPosFn>,
61 set_pos: Option<WriterSetPosFn>,
62 element_start_notify: Option<WriterElementStartNotifyFn>,
63 user_data: *mut c_void,
64 ) -> WriterMutPtr;
65 #[link_name = "mux_delete_writer"]
66 pub fn delete_writer(writer: WriterMutPtr);
67
68 #[link_name = "mux_new_segment"]
69 pub fn new_segment() -> SegmentMutPtr;
70 #[link_name = "mux_initialize_segment"]
71 pub fn initialize_segment(segment: SegmentMutPtr, writer: WriterMutPtr) -> ResultCode;
72 #[link_name = "mux_set_color"]
73 pub fn mux_set_color(
74 segment: SegmentMutPtr,
75 video_track_num: TrackNum,
76 bits_per_channel: u8,
77 sampling_horiz: u8,
78 sampling_vert: u8,
79 color_range: u8,
80 ) -> ResultCode;
81 #[link_name = "mux_set_writing_app"]
82 pub fn mux_set_writing_app(segment: SegmentMutPtr, name: *const c_char);
83 #[link_name = "mux_finalize_segment"]
84 pub fn finalize_segment(segment: SegmentMutPtr, duration: u64) -> ResultCode;
85 #[link_name = "mux_delete_segment"]
86 pub fn delete_segment(segment: SegmentMutPtr);
87 #[link_name = "mux_segment_set_mode"]
88 pub fn segment_set_mode(segment: SegmentMutPtr, mode: u32) -> ResultCode;
89
90 #[link_name = "mux_segment_add_video_track"]
91 pub fn segment_add_video_track(
92 segment: SegmentMutPtr,
93 width: i32,
94 height: i32,
95 number: i32,
96 codec_id: u32,
97 track_num_out: *mut TrackNum,
98 ) -> ResultCode;
99 #[link_name = "mux_segment_add_audio_track"]
100 pub fn segment_add_audio_track(
101 segment: SegmentMutPtr,
102 sample_rate: i32,
103 channels: i32,
104 number: i32,
105 codec_id: u32,
106 track_num_out: *mut TrackNum,
107 ) -> ResultCode;
108 #[link_name = "mux_segment_add_frame"]
109 pub fn segment_add_frame(
110 segment: SegmentMutPtr,
111 track_num: TrackNum,
112 frame: *const u8,
113 length: usize,
114 timestamp_ns: u64,
115 keyframe: bool,
116 ) -> ResultCode;
117 #[link_name = "mux_segment_set_codec_private"]
118 pub fn segment_set_codec_private(
119 segment: SegmentMutPtr,
120 track_num: TrackNum,
121 data: *const u8,
122 len: i32,
123 ) -> ResultCode;
124 }
125}
126
127#[test]
128fn smoke_test() {
129 unsafe {
130 let segment = mux::new_segment();
131 assert!(!segment.is_null());
132 mux::delete_segment(segment);
133 }
134}