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