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