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::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> {}