1use std::ffi::c_void;
8
9use crate::api::Wmv2Decoder;
10
11#[repr(C)]
12pub struct Wmv2FrameView {
13 pub width: u32,
14 pub height: u32,
15
16 pub y_ptr: *const u8,
17 pub y_len: usize,
18 pub y_stride: usize,
19
20 pub cb_ptr: *const u8,
21 pub cb_len: usize,
22 pub cb_stride: usize,
23
24 pub cr_ptr: *const u8,
25 pub cr_len: usize,
26 pub cr_stride: usize,
27}
28
29struct Opaque {
30 dec: Wmv2Decoder,
31 has_frame: bool,
32}
33
34#[no_mangle]
38pub extern "C" fn wmv2_decoder_create(
39 width: u32,
40 height: u32,
41 extradata: *const u8,
42 extradata_len: usize,
43) -> *mut c_void {
44 let extra = unsafe {
45 if extradata.is_null() || extradata_len == 0 {
46 &[][..]
47 } else {
48 std::slice::from_raw_parts(extradata, extradata_len)
49 }
50 };
51
52 let dec = Wmv2Decoder::new(width, height, extra);
53 let opaque = Box::new(Opaque {
54 dec,
55 has_frame: false,
56 });
57 Box::into_raw(opaque) as *mut c_void
58}
59
60#[no_mangle]
61pub extern "C" fn wmv2_decoder_destroy(handle: *mut c_void) {
62 if handle.is_null() {
63 return;
64 }
65 unsafe {
66 let _ = Box::from_raw(handle as *mut Opaque);
67 }
68}
69
70#[no_mangle]
78pub extern "C" fn wmv2_decoder_decode(
79 handle: *mut c_void,
80 payload: *const u8,
81 payload_len: usize,
82 is_key_frame: i32,
83) -> i32 {
84 if handle.is_null() {
85 return -1;
86 }
87 if payload.is_null() || payload_len == 0 {
88 return -1;
89 }
90
91 let opaque = unsafe { &mut *(handle as *mut Opaque) };
92 let data = unsafe { std::slice::from_raw_parts(payload, payload_len) };
93
94 match opaque.dec.decode_frame(data, is_key_frame != 0) {
95 Ok(Some(_)) => {
96 opaque.has_frame = true;
97 1
98 }
99 Ok(None) => {
100 opaque.has_frame = false;
101 0
102 }
103 Err(_) => {
104 opaque.has_frame = false;
105 -2
106 }
107 }
108}
109
110#[no_mangle]
119pub extern "C" fn wmv2_decoder_get_frame(handle: *mut c_void, out: *mut Wmv2FrameView) -> i32 {
120 if handle.is_null() || out.is_null() {
121 return -1;
122 }
123
124 let opaque = unsafe { &mut *(handle as *mut Opaque) };
125 if !opaque.has_frame {
126 return 0;
127 }
128
129 let f = opaque.dec.current_frame();
130 let y_stride = f.width as usize;
131 let uv_stride = (f.width as usize) / 2;
132
133 unsafe {
134 *out = Wmv2FrameView {
135 width: f.width,
136 height: f.height,
137 y_ptr: f.y.as_ptr(),
138 y_len: f.y.len(),
139 y_stride,
140 cb_ptr: f.cb.as_ptr(),
141 cb_len: f.cb.len(),
142 cb_stride: uv_stride,
143 cr_ptr: f.cr.as_ptr(),
144 cr_len: f.cr.len(),
145 cr_stride: uv_stride,
146 };
147 }
148
149 1
150}