Skip to main content

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