Skip to main content

ffmpeg_the_third/codec/subtitle/
mod.rs

1pub mod flag;
2pub use self::flag::Flags;
3
4mod rect;
5mod rect_common;
6pub use self::rect::RectRef;
7mod rect_mut;
8pub use self::rect_mut::RectMut;
9
10use std::iter::FusedIterator;
11use std::mem;
12use std::ptr::NonNull;
13
14use crate::ffi::*;
15use libc::size_t;
16#[cfg(feature = "serialize")]
17use serde::{Deserialize, Serialize};
18
19#[derive(Eq, PartialEq, Clone, Copy, Debug)]
20#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
21pub enum Type {
22    None,
23    Bitmap,
24    Text,
25    Ass,
26}
27
28impl From<AVSubtitleType> for Type {
29    fn from(value: AVSubtitleType) -> Type {
30        use AVSubtitleType as AV;
31
32        match value {
33            AV::NONE => Type::None,
34            AV::BITMAP => Type::Bitmap,
35            AV::TEXT => Type::Text,
36            AV::ASS => Type::Ass,
37
38            _ => unimplemented!(),
39        }
40    }
41}
42
43impl From<Type> for AVSubtitleType {
44    fn from(value: Type) -> AVSubtitleType {
45        use AVSubtitleType as AV;
46
47        match value {
48            Type::None => AV::NONE,
49            Type::Bitmap => AV::BITMAP,
50            Type::Text => AV::TEXT,
51            Type::Ass => AV::ASS,
52        }
53    }
54}
55
56pub struct Subtitle(AVSubtitle);
57
58impl Subtitle {
59    pub unsafe fn as_ptr(&self) -> *const AVSubtitle {
60        &self.0
61    }
62
63    pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitle {
64        &mut self.0
65    }
66}
67
68impl Subtitle {
69    pub fn new() -> Self {
70        unsafe { Subtitle(mem::zeroed()) }
71    }
72
73    pub fn pts(&self) -> Option<i64> {
74        match self.0.pts {
75            AV_NOPTS_VALUE => None,
76            pts => Some(pts),
77        }
78    }
79
80    pub fn set_pts(&mut self, value: Option<i64>) {
81        self.0.pts = value.unwrap_or(AV_NOPTS_VALUE);
82    }
83
84    pub fn start(&self) -> u32 {
85        self.0.start_display_time as u32
86    }
87
88    pub fn set_start(&mut self, value: u32) {
89        self.0.start_display_time = value;
90    }
91
92    pub fn end(&self) -> u32 {
93        self.0.end_display_time as u32
94    }
95
96    pub fn set_end(&mut self, value: u32) {
97        self.0.end_display_time = value;
98    }
99
100    pub fn rects(&self) -> RectIter<'_> {
101        unsafe {
102            let ptrs = if (*self.as_ptr()).rects.is_null() {
103                &[]
104            } else {
105                std::slice::from_raw_parts(
106                    (*self.as_ptr()).rects,
107                    (*self.as_ptr()).num_rects as usize,
108                )
109            };
110
111            RectIter::from_av_rects(ptrs)
112        }
113    }
114
115    pub fn rects_mut(&mut self) -> RectMutIter<'_> {
116        unsafe {
117            let ptrs = if (*self.as_ptr()).rects.is_null() {
118                &mut []
119            } else {
120                std::slice::from_raw_parts_mut(
121                    (*self.as_ptr()).rects,
122                    (*self.as_ptr()).num_rects as usize,
123                )
124            };
125
126            RectMutIter::from_av_rects(ptrs)
127        }
128    }
129
130    pub fn add_rect(&mut self, kind: Type) -> Option<RectMut<'_>> {
131        unsafe {
132            let new_sz = 1 + self.0.num_rects as usize;
133            let new_ptr = av_realloc(
134                self.0.rects as *mut _,
135                size_of::<*const AVSubtitleRect>() * new_sz,
136            ) as *mut *mut AVSubtitleRect;
137
138            if new_ptr.is_null() {
139                return None;
140            }
141
142            self.0.rects = new_ptr;
143            self.0.num_rects = new_sz as u32;
144
145            let rect = av_mallocz(size_of::<AVSubtitleRect>() as size_t) as *mut AVSubtitleRect;
146            let mut rect = NonNull::new(rect)?;
147
148            rect.as_mut().type_ = kind.into();
149            *self.0.rects.add(new_sz - 1) = rect.as_ptr();
150
151            Some(RectMut::from_ptr(rect))
152        }
153    }
154}
155
156#[derive(Debug, Clone)]
157pub struct RectIter<'s> {
158    raw_iter: std::slice::Iter<'s, *mut AVSubtitleRect>,
159}
160
161impl<'s> RectIter<'s> {
162    pub fn from_av_rects(rects: &'s [*mut AVSubtitleRect]) -> Self {
163        Self {
164            raw_iter: rects.iter(),
165        }
166    }
167}
168
169impl<'s> Iterator for RectIter<'s> {
170    type Item = RectRef<'s>;
171
172    fn next(&mut self) -> Option<Self::Item> {
173        unsafe {
174            // SAFETY: Lifetime is bounded by Self::Item (= 's)
175            self.raw_iter
176                .next()
177                .map(|&ptr| RectRef::from_ptr(NonNull::new(ptr).expect("ptr is non-null")))
178        }
179    }
180
181    fn size_hint(&self) -> (usize, Option<usize>) {
182        self.raw_iter.size_hint()
183    }
184}
185
186impl<'s> DoubleEndedIterator for RectIter<'s> {
187    fn next_back(&mut self) -> Option<Self::Item> {
188        unsafe {
189            // SAFETY: Lifetime is bounded by Self::Item (= 's)
190            self.raw_iter
191                .next_back()
192                .map(|&ptr| RectRef::from_ptr(NonNull::new(ptr).expect("ptr is non-null")))
193        }
194    }
195}
196
197impl<'s> ExactSizeIterator for RectIter<'s> {}
198impl<'s> FusedIterator for RectIter<'s> {}
199
200#[derive(Debug)]
201pub struct RectMutIter<'s> {
202    raw_iter: std::slice::IterMut<'s, *mut AVSubtitleRect>,
203}
204
205impl<'s> RectMutIter<'s> {
206    pub fn from_av_rects(rects: &'s mut [*mut AVSubtitleRect]) -> Self {
207        Self {
208            raw_iter: rects.iter_mut(),
209        }
210    }
211}
212
213impl<'s> Iterator for RectMutIter<'s> {
214    type Item = RectMut<'s>;
215
216    fn next(&mut self) -> Option<Self::Item> {
217        unsafe {
218            // SAFETY: Lifetime is bounded by Self::Item (= 's)
219            self.raw_iter
220                .next()
221                .map(|&mut ptr| RectMut::from_ptr(NonNull::new(ptr).expect("ptr is non-null")))
222        }
223    }
224
225    fn size_hint(&self) -> (usize, Option<usize>) {
226        self.raw_iter.size_hint()
227    }
228}
229
230impl<'s> DoubleEndedIterator for RectMutIter<'s> {
231    fn next_back(&mut self) -> Option<Self::Item> {
232        unsafe {
233            // SAFETY: Lifetime is bounded by Self::Item (= 's)
234            self.raw_iter
235                .next_back()
236                .map(|&mut ptr| RectMut::from_ptr(NonNull::new(ptr).expect("ptr is non-null")))
237        }
238    }
239}
240
241impl<'s> ExactSizeIterator for RectMutIter<'s> {}
242impl<'s> FusedIterator for RectMutIter<'s> {}
243
244impl Default for Subtitle {
245    fn default() -> Self {
246        Self::new()
247    }
248}