codec/subtitle: improve Subtitle handling
This commit is contained in:
parent
9a22b27733
commit
72e300f09e
@ -1,6 +1,49 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use libc::{c_uint, uint32_t, int64_t};
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
|
use ::format;
|
||||||
|
use ::Picture;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
flags Flags: i32 {
|
||||||
|
const FLAG_FORCED = AV_SUBTITLE_FLAG_FORCED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
||||||
|
pub enum Type {
|
||||||
|
None,
|
||||||
|
Bitmap,
|
||||||
|
Text,
|
||||||
|
Ass,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AVSubtitleType> for Type {
|
||||||
|
fn from(value: AVSubtitleType) -> Type {
|
||||||
|
match value {
|
||||||
|
SUBTITLE_NONE => Type::None,
|
||||||
|
SUBTITLE_BITMAP => Type::Bitmap,
|
||||||
|
SUBTITLE_TEXT => Type::Text,
|
||||||
|
SUBTITLE_ASS => Type::Ass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<AVSubtitleType> for Type {
|
||||||
|
fn into(self) -> AVSubtitleType {
|
||||||
|
match self {
|
||||||
|
Type::None => SUBTITLE_NONE,
|
||||||
|
Type::Bitmap => SUBTITLE_BITMAP,
|
||||||
|
Type::Text => SUBTITLE_TEXT,
|
||||||
|
Type::Ass => SUBTITLE_ASS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Subtitle {
|
pub struct Subtitle {
|
||||||
pub val: AVSubtitle,
|
pub val: AVSubtitle,
|
||||||
@ -12,4 +55,182 @@ impl Subtitle {
|
|||||||
Subtitle { val: mem::zeroed() }
|
Subtitle { val: mem::zeroed() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pts(&self) -> isize {
|
||||||
|
self.val.pts as isize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pts(&mut self, value: isize) {
|
||||||
|
self.val.pts = value as int64_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(&self) -> usize {
|
||||||
|
self.val.start_display_time as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_start(&mut self, value: usize) {
|
||||||
|
self.val.start_display_time = value as uint32_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(&self) -> usize {
|
||||||
|
self.val.end_display_time as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_end(&mut self, value: usize) {
|
||||||
|
self.val.end_display_time = value as uint32_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rects<'a>(&'a self) -> RectIter<'a> {
|
||||||
|
RectIter::new(&self.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RectIter<'a> {
|
||||||
|
ptr: *const AVSubtitle,
|
||||||
|
cur: c_uint,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a Subtitle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RectIter<'a> {
|
||||||
|
pub fn new(ptr: *const AVSubtitle) -> Self {
|
||||||
|
RectIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for RectIter<'a> {
|
||||||
|
type Item = Rect<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||||
|
unsafe {
|
||||||
|
if self.cur >= (*self.ptr).num_rects {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.cur += 1;
|
||||||
|
Rect::wrap(*(*self.ptr).rects.offset((self.cur - 1) as isize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Rect<'a> {
|
||||||
|
Bitmap(Bitmap<'a>),
|
||||||
|
Text(Text<'a>),
|
||||||
|
Ass(Ass<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Rect<'a> {
|
||||||
|
pub fn wrap(ptr: *mut AVSubtitleRect) -> Option<Self> {
|
||||||
|
unsafe {
|
||||||
|
match Type::from((*ptr).kind) {
|
||||||
|
Type::None => None,
|
||||||
|
Type::Bitmap => Some(Rect::Bitmap(Bitmap::wrap(ptr))),
|
||||||
|
Type::Text => Some(Rect::Text(Text::wrap(ptr))),
|
||||||
|
Type::Ass => Some(Rect::Ass(Ass::wrap(ptr)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flags(&self) -> Flags {
|
||||||
|
unsafe {
|
||||||
|
Flags::from_bits_truncate(match self {
|
||||||
|
&Rect::Bitmap(ref b) => (*b.ptr).flags,
|
||||||
|
&Rect::Text(ref t) => (*t.ptr).flags,
|
||||||
|
&Rect::Ass(ref a) => (*a.ptr).flags
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Bitmap<'a> {
|
||||||
|
pub ptr: *mut AVSubtitleRect,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Bitmap<'a> {
|
||||||
|
pub fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||||
|
Bitmap { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn x(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.ptr).x as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.ptr).y as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.ptr).w as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn height(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.ptr).h as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn colors(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.ptr).nb_colors as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn picture(&self, format: format::Pixel) -> Picture<'a> {
|
||||||
|
unsafe {
|
||||||
|
Picture::wrap(&mut (*self.ptr).pict, format, (*self.ptr).w as usize, (*self.ptr).h as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Text<'a> {
|
||||||
|
pub ptr: *mut AVSubtitleRect,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Text<'a> {
|
||||||
|
pub fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||||
|
Text { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for Text<'a> {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
fn deref<'b>(&'b self) -> &'b str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr((*self.ptr).text).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Ass<'a> {
|
||||||
|
pub ptr: *mut AVSubtitleRect,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ass<'a> {
|
||||||
|
pub fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||||
|
Ass { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for Ass<'a> {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
fn deref<'b>(&'b self) -> &'b str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr((*self.ptr).ass).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ pub use format::stream::Stream;
|
|||||||
|
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
pub use codec::packet::{self, Packet};
|
pub use codec::packet::{self, Packet};
|
||||||
pub use codec::subtitle::Subtitle;
|
pub use codec::subtitle::{self, Subtitle};
|
||||||
pub use codec::picture::Picture;
|
pub use codec::picture::Picture;
|
||||||
pub use codec::discard::Discard;
|
pub use codec::discard::Discard;
|
||||||
pub use codec::codec::Codec;
|
pub use codec::codec::Codec;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user