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 { dec, has_frame: false });
54 Box::into_raw(opaque) as *mut c_void
55}
56
57#[no_mangle]
58pub extern "C" fn wmv2_decoder_destroy(handle: *mut c_void) {
59 if handle.is_null() {
60 return;
61 }
62 unsafe {
63 let _ = Box::from_raw(handle as *mut Opaque);
64 }
65}
66
67#[no_mangle]
75pub extern "C" fn wmv2_decoder_decode(
76 handle: *mut c_void,
77 payload: *const u8,
78 payload_len: usize,
79 is_key_frame: i32,
80) -> i32 {
81 if handle.is_null() {
82 return -1;
83 }
84 if payload.is_null() || payload_len == 0 {
85 return -1;
86 }
87
88 let opaque = unsafe { &mut *(handle as *mut Opaque) };
89 let data = unsafe { std::slice::from_raw_parts(payload, payload_len) };
90
91 match opaque.dec.decode_frame(data, is_key_frame != 0) {
92 Ok(Some(_)) => {
93 opaque.has_frame = true;
94 1
95 }
96 Ok(None) => {
97 opaque.has_frame = false;
98 0
99 }
100 Err(_) => {
101 opaque.has_frame = false;
102 -2
103 }
104 }
105}
106
107#[no_mangle]
116pub extern "C" fn wmv2_decoder_get_frame(handle: *mut c_void, out: *mut Wmv2FrameView) -> i32 {
117 if handle.is_null() || out.is_null() {
118 return -1;
119 }
120
121 let opaque = unsafe { &mut *(handle as *mut Opaque) };
122 if !opaque.has_frame {
123 return 0;
124 }
125
126 let f = opaque.dec.current_frame();
127 let y_stride = f.width as usize;
128 let uv_stride = (f.width as usize) / 2;
129
130 unsafe {
131 *out = Wmv2FrameView {
132 width: f.width,
133 height: f.height,
134 y_ptr: f.y.as_ptr(),
135 y_len: f.y.len(),
136 y_stride,
137 cb_ptr: f.cb.as_ptr(),
138 cb_len: f.cb.len(),
139 cb_stride: uv_stride,
140 cr_ptr: f.cr.as_ptr(),
141 cr_len: f.cr.len(),
142 cr_stride: uv_stride,
143 };
144 }
145
146 1
147}