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 #[repr(C)]
45 pub struct Segment {
46 _opaque_c_aligned: *mut c_void,
47 }
48 pub type SegmentMutPtr = *mut Segment;
49 pub type SegmentNonNullPtr = NonNull<Segment>;
50
51 #[link(name = "webmadapter", kind = "static")]
52 unsafe extern "C" {
53 #[link_name = "mux_new_writer"]
54 pub fn new_writer(
55 write: Option<WriterWriteFn>,
56 get_pos: Option<WriterGetPosFn>,
57 set_pos: Option<WriterSetPosFn>,
58 element_start_notify: Option<WriterElementStartNotifyFn>,
59 user_data: *mut c_void,
60 ) -> WriterMutPtr;
61 #[link_name = "mux_delete_writer"]
62 pub fn delete_writer(writer: WriterMutPtr);
63
64 #[link_name = "mux_new_segment"]
65 pub fn new_segment() -> SegmentMutPtr;
66 #[link_name = "mux_initialize_segment"]
67 pub fn initialize_segment(segment: SegmentMutPtr, writer: WriterMutPtr) -> ResultCode;
68 #[link_name = "mux_set_color"]
69 pub fn mux_set_color(
70 segment: SegmentMutPtr,
71 video_track_num: TrackNum,
72 bits_per_channel: u8,
73 sampling_horiz: u8,
74 sampling_vert: u8,
75 color_range: u8,
76 ) -> ResultCode;
77 #[link_name = "mux_set_writing_app"]
78 pub fn mux_set_writing_app(segment: SegmentMutPtr, name: *const c_char);
79 #[link_name = "mux_finalize_segment"]
80 pub fn finalize_segment(segment: SegmentMutPtr, duration: u64) -> ResultCode;
81 #[link_name = "mux_delete_segment"]
82 pub fn delete_segment(segment: SegmentMutPtr);
83
84 #[link_name = "mux_segment_add_video_track"]
85 pub fn segment_add_video_track(
86 segment: SegmentMutPtr,
87 width: i32,
88 height: i32,
89 number: i32,
90 codec_id: u32,
91 track_num_out: *mut TrackNum,
92 ) -> ResultCode;
93 #[link_name = "mux_segment_add_audio_track"]
94 pub fn segment_add_audio_track(
95 segment: SegmentMutPtr,
96 sample_rate: i32,
97 channels: i32,
98 number: i32,
99 codec_id: u32,
100 track_num_out: *mut TrackNum,
101 ) -> ResultCode;
102 #[link_name = "mux_segment_add_frame"]
103 pub fn segment_add_frame(
104 segment: SegmentMutPtr,
105 track_num: TrackNum,
106 frame: *const u8,
107 length: usize,
108 timestamp_ns: u64,
109 keyframe: bool,
110 ) -> ResultCode;
111 #[link_name = "mux_segment_set_codec_private"]
112 pub fn segment_set_codec_private(
113 segment: SegmentMutPtr,
114 track_num: TrackNum,
115 data: *const u8,
116 len: i32,
117 ) -> ResultCode;
118 }
119}
120
121#[test]
122fn smoke_test() {
123 unsafe {
124 let segment = mux::new_segment();
125 assert!(!segment.is_null());
126 mux::delete_segment(segment);
127 }
128}