Skip to main content

ffmpeg_the_third/codec/subtitle/
mod.rs

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