webm_sys/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
pub mod mux {
    use core::ffi::{c_char, c_void};
    use core::ptr::NonNull;

    #[repr(C)]
    pub struct IWriter {
        _opaque_c_aligned: *mut c_void,
    }
    pub type WriterMutPtr = *mut IWriter;
    pub type WriterNonNullPtr = NonNull<IWriter>;

    pub type WriterWriteFn = extern "C" fn(*mut c_void, *const c_void, usize) -> bool;
    pub type WriterGetPosFn = extern "C" fn(*mut c_void) -> u64;
    pub type WriterSetPosFn = extern "C" fn(*mut c_void, u64) -> bool;
    pub type WriterElementStartNotifyFn = extern "C" fn(*mut c_void, u64, i64);

    /// An opaque number used to identify an added track.
    pub type TrackNum = u64;

    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    #[repr(i32)]
    pub enum ResultCode {
        /// The function completed without error
        Ok = 0,

        /// An invalid parameter was passed (e.g. a null pointer or an invalid track number)
        BadParam = -1,

        /// `libwebm` returned an error, and no more specific error info is known. No assumptions
        /// should be made about whether this is an issue with the caller, or something internal
        /// to `libwebm`.
        UnknownLibwebmError = -2,
    }

    // audio
    pub const OPUS_CODEC_ID: u32 = 0;
    pub const VORBIS_CODEC_ID: u32 = 1;

    // video
    pub const VP8_CODEC_ID: u32 = 0;
    pub const VP9_CODEC_ID: u32 = 1;
    pub const AV1_CODEC_ID: u32 = 2;

    #[repr(C)]
    pub struct Segment {
        _opaque_c_aligned: *mut c_void,
    }
    pub type SegmentMutPtr = *mut Segment;
    pub type SegmentNonNullPtr = NonNull<Segment>;

    #[link(name = "webmadapter", kind = "static")]
    extern "C" {
        #[link_name = "mux_new_writer"]
        pub fn new_writer(
            write: Option<WriterWriteFn>,
            get_pos: Option<WriterGetPosFn>,
            set_pos: Option<WriterSetPosFn>,
            element_start_notify: Option<WriterElementStartNotifyFn>,
            user_data: *mut c_void,
        ) -> WriterMutPtr;
        #[link_name = "mux_delete_writer"]
        pub fn delete_writer(writer: WriterMutPtr);

        #[link_name = "mux_new_segment"]
        pub fn new_segment() -> SegmentMutPtr;
        #[link_name = "mux_initialize_segment"]
        pub fn initialize_segment(segment: SegmentMutPtr, writer: WriterMutPtr) -> ResultCode;
        #[link_name = "mux_set_color"]
        pub fn mux_set_color(
            segment: SegmentMutPtr,
            video_track_num: TrackNum,
            bits_per_channel: u8,
            sampling_horiz: u8,
            sampling_vert: u8,
            color_range: u8,
        ) -> ResultCode;
        #[link_name = "mux_set_writing_app"]
        pub fn mux_set_writing_app(segment: SegmentMutPtr, name: *const c_char);
        #[link_name = "mux_finalize_segment"]
        pub fn finalize_segment(segment: SegmentMutPtr, duration: u64) -> ResultCode;
        #[link_name = "mux_delete_segment"]
        pub fn delete_segment(segment: SegmentMutPtr);

        #[link_name = "mux_segment_add_video_track"]
        pub fn segment_add_video_track(
            segment: SegmentMutPtr,
            width: i32,
            height: i32,
            number: i32,
            codec_id: u32,
            track_num_out: *mut TrackNum,
        ) -> ResultCode;
        #[link_name = "mux_segment_add_audio_track"]
        pub fn segment_add_audio_track(
            segment: SegmentMutPtr,
            sample_rate: i32,
            channels: i32,
            number: i32,
            codec_id: u32,
            track_num_out: *mut TrackNum,
        ) -> ResultCode;
        #[link_name = "mux_segment_add_frame"]
        pub fn segment_add_frame(
            segment: SegmentMutPtr,
            track_num: TrackNum,
            frame: *const u8,
            length: usize,
            timestamp_ns: u64,
            keyframe: bool,
        ) -> ResultCode;
        #[link_name = "mux_segment_set_codec_private"]
        pub fn segment_set_codec_private(
            segment: SegmentMutPtr,
            track_num: TrackNum,
            data: *const u8,
            len: i32,
        ) -> ResultCode;
    }
}

#[test]
fn smoke_test() {
    unsafe {
        let segment = mux::new_segment();
        assert!(!segment.is_null());
        mux::delete_segment(segment);
    }
}