ffmpeg_the_third/codec/subtitle/
mod.rs1pub 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 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 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 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 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}