ffmpeg_the_third/util/channel_layout/
channel_custom.rs1use libc::c_char;
2
3use crate::ffi::{AVChannel, AVChannelCustom};
4
5use super::Channel;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
11#[repr(transparent)]
12pub struct ChannelCustom(AVChannelCustom);
13
14impl ChannelCustom {
15 pub fn new(id: Channel) -> Self {
16 Self(AVChannelCustom {
17 id: AVChannel::from(id),
18 name: [0; 16],
19 opaque: std::ptr::null_mut(),
20 })
21 }
22
23 pub fn named<S: AsRef<str>>(id: Channel, name: S) -> Self {
24 let name = name.as_ref();
25 let name = to_char_array(name.as_bytes());
26
27 Self(AVChannelCustom {
28 id: AVChannel::from(id),
29 name,
30 opaque: std::ptr::null_mut(),
31 })
32 }
33}
34
35fn to_char_array(bytes: &[u8]) -> [c_char; 16] {
36 let mut result = [0; 16];
37
38 for (b, r) in bytes.iter().take(15).zip(&mut result) {
40 *r = *b as c_char;
41 }
42
43 result
44}
45
46impl From<AVChannelCustom> for ChannelCustom {
47 fn from(value: AVChannelCustom) -> Self {
48 Self(value)
49 }
50}
51
52impl From<ChannelCustom> for AVChannelCustom {
53 fn from(value: ChannelCustom) -> Self {
54 value.0
55 }
56}
57
58#[cfg(test)]
59mod test {
60 use super::*;
61 use std::alloc::Layout;
62
63 #[test]
64 fn is_repr_transparent() {
65 assert_eq!(
67 Layout::new::<AVChannelCustom>(),
68 Layout::new::<ChannelCustom>()
69 );
70 }
71
72 #[test]
73 fn new() {
74 let custom = ChannelCustom::new(Channel::FrontRight);
75 assert_eq!(custom.0.id, AVChannel::AV_CHAN_FRONT_RIGHT);
76 assert_eq!(custom.0.name, [0; 16]);
77 assert!(custom.0.opaque.is_null());
78 }
79
80 #[test]
81 fn named() {
82 let c_str_name = [
84 66, 111, 116, 116, 111, 109, 32, 102, 114, 111, 110, 116, 32, 114, 105, 0,
85 ];
86
87 let custom = ChannelCustom::named(Channel::BottomFrontRight, "Bottom front right");
88 assert_eq!(custom.0.id, AVChannel::AV_CHAN_BOTTOM_FRONT_RIGHT);
89 assert_eq!(custom.0.name, c_str_name);
90 assert!(custom.0.opaque.is_null());
91 }
92}