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