simplify ffmpeg wrapper crate

This was using PhantomData to enforce lifetimes + raw pointers. Simpler to
convert to a reference. This also enforces non-null.
This commit is contained in:
Scott Lamb 2017-11-30 14:40:31 -08:00
parent 5c8970fe8a
commit 10550bc35f

View File

@ -34,7 +34,6 @@ extern crate libc;
use std::cell::{Ref, RefCell}; use std::cell::{Ref, RefCell};
use std::ffi::CStr; use std::ffi::CStr;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::marker::PhantomData;
use std::ptr; use std::ptr;
use std::sync; use std::sync;
@ -168,14 +167,14 @@ impl InputFormatContext {
pub fn read_frame<'i>(&'i self) -> Result<Packet<'i>, Error> { pub fn read_frame<'i>(&'i self) -> Result<Packet<'i>, Error> {
let pkt = self.pkt.borrow(); let pkt = self.pkt.borrow();
Error::wrap(unsafe { av_read_frame(self.ctx, *pkt) })?; Error::wrap(unsafe { av_read_frame(self.ctx, *pkt) })?;
Ok(Packet { _ctx: PhantomData, pkt: pkt }) Ok(Packet(pkt))
} }
pub fn streams<'i>(&'i self) -> Streams<'i> { pub fn streams<'i>(&'i self) -> Streams<'i> {
Streams { Streams(unsafe {
_owner: PhantomData, let s = moonfire_ffmpeg_fctx_streams(self.ctx);
streams: unsafe { moonfire_ffmpeg_fctx_streams(self.ctx) }, std::slice::from_raw_parts(s.streams, s.len as usize)
} })
} }
} }
@ -204,15 +203,12 @@ struct StreamsLen {
len: libc::size_t, len: libc::size_t,
} }
pub struct Packet<'i> { pub struct Packet<'i>(Ref<'i, *mut AVPacket>);
_ctx: PhantomData<&'i InputFormatContext>,
pkt: Ref<'i, *mut AVPacket>,
}
impl<'i> Packet<'i> { impl<'i> Packet<'i> {
pub fn is_key(&self) -> bool { unsafe { moonfire_ffmpeg_packet_is_key(*self.pkt) } } pub fn is_key(&self) -> bool { unsafe { moonfire_ffmpeg_packet_is_key(*self.0) } }
pub fn pts(&self) -> Option<i64> { pub fn pts(&self) -> Option<i64> {
match unsafe { moonfire_ffmpeg_packet_pts(*self.pkt) } { match unsafe { moonfire_ffmpeg_packet_pts(*self.0) } {
v if v == unsafe { moonfire_ffmpeg_av_nopts_value } => None, v if v == unsafe { moonfire_ffmpeg_av_nopts_value } => None,
v => Some(v), v => Some(v),
} }
@ -222,22 +218,22 @@ impl<'i> Packet<'i> {
None => unsafe { moonfire_ffmpeg_av_nopts_value }, None => unsafe { moonfire_ffmpeg_av_nopts_value },
Some(v) => v, Some(v) => v,
}; };
unsafe { moonfire_ffmpeg_packet_set_pts(*self.pkt, real_pts); } unsafe { moonfire_ffmpeg_packet_set_pts(*self.0, real_pts); }
} }
pub fn dts(&self) -> i64 { unsafe { moonfire_ffmpeg_packet_dts(*self.pkt) } } pub fn dts(&self) -> i64 { unsafe { moonfire_ffmpeg_packet_dts(*self.0) } }
pub fn set_dts(&mut self, dts: i64) { pub fn set_dts(&mut self, dts: i64) {
unsafe { moonfire_ffmpeg_packet_set_dts(*self.pkt, dts); } unsafe { moonfire_ffmpeg_packet_set_dts(*self.0, dts); }
} }
pub fn duration(&self) -> i32 { unsafe { moonfire_ffmpeg_packet_duration(*self.pkt) } } pub fn duration(&self) -> i32 { unsafe { moonfire_ffmpeg_packet_duration(*self.0) } }
pub fn set_duration(&mut self, dur: i32) { pub fn set_duration(&mut self, dur: i32) {
unsafe { moonfire_ffmpeg_packet_set_duration(*self.pkt, dur) } unsafe { moonfire_ffmpeg_packet_set_duration(*self.0, dur) }
} }
pub fn stream_index(&self) -> usize { pub fn stream_index(&self) -> usize {
unsafe { moonfire_ffmpeg_packet_stream_index(*self.pkt) as usize } unsafe { moonfire_ffmpeg_packet_stream_index(*self.0) as usize }
} }
pub fn data(&self) -> Option<&[u8]> { pub fn data(&self) -> Option<&[u8]> {
unsafe { unsafe {
let d = moonfire_ffmpeg_packet_data(*self.pkt); let d = moonfire_ffmpeg_packet_data(*self.0);
if d.data.is_null() { if d.data.is_null() {
None None
} else { } else {
@ -245,72 +241,51 @@ impl<'i> Packet<'i> {
} }
} }
} }
//pub fn deref(self) -> &'i InputFormatContext { self.ctx }
} }
impl<'i> Drop for Packet<'i> { impl<'i> Drop for Packet<'i> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
av_packet_unref(*self.pkt); av_packet_unref(*self.0);
} }
} }
} }
pub struct Streams<'owner> { pub struct Streams<'owner>(&'owner [*const AVStream]);
_owner: PhantomData<&'owner ()>,
streams: StreamsLen,
}
impl<'owner> Streams<'owner> { impl<'owner> Streams<'owner> {
pub fn get(&self, i: usize) -> Stream<'owner> { pub fn get(&self, i: usize) -> Stream<'owner> { Stream(unsafe { self.0[i].as_ref() }.unwrap()) }
assert!(i < self.streams.len); pub fn len(&self) -> usize { self.0.len() }
Stream {
_owner: PhantomData,
stream: unsafe { *self.streams.streams.offset(i as isize) }
}
}
pub fn len(&self) -> usize { self.streams.len }
} }
pub struct Stream<'o> { pub struct Stream<'o>(&'o AVStream);
_owner: PhantomData<&'o ()>,
stream: *const AVStream,
}
impl<'o> Stream<'o> { impl<'o> Stream<'o> {
pub fn codec<'s>(&'s self) -> CodecContext<'s> { pub fn codec<'s>(&'s self) -> CodecContext<'s> {
CodecContext { CodecContext(unsafe { moonfire_ffmpeg_stream_codec(self.0).as_ref() }.unwrap())
_owner: PhantomData,
ctx: unsafe { moonfire_ffmpeg_stream_codec(self.stream) },
}
} }
pub fn time_base(&self) -> AVRational { pub fn time_base(&self) -> AVRational {
unsafe { moonfire_ffmpeg_stream_time_base(self.stream) } unsafe { moonfire_ffmpeg_stream_time_base(self.0) }
} }
} }
pub struct CodecContext<'s> { pub struct CodecContext<'s>(&'s AVCodecContext);
_owner: PhantomData<&'s ()>,
ctx: *const AVCodecContext,
}
impl<'s> CodecContext<'s> { impl<'s> CodecContext<'s> {
pub fn extradata(&self) -> &[u8] { pub fn extradata(&self) -> &[u8] {
unsafe { unsafe {
let d = moonfire_ffmpeg_cctx_extradata(self.ctx); let d = moonfire_ffmpeg_cctx_extradata(self.0);
::std::slice::from_raw_parts(d.data, d.len) ::std::slice::from_raw_parts(d.data, d.len)
} }
} }
pub fn width(&self) -> libc::c_int { unsafe { moonfire_ffmpeg_cctx_width(self.ctx) } } pub fn width(&self) -> libc::c_int { unsafe { moonfire_ffmpeg_cctx_width(self.0) } }
pub fn height(&self) -> libc::c_int { unsafe { moonfire_ffmpeg_cctx_height(self.ctx) } } pub fn height(&self) -> libc::c_int { unsafe { moonfire_ffmpeg_cctx_height(self.0) } }
pub fn codec_id(&self) -> CodecId { pub fn codec_id(&self) -> CodecId {
CodecId(unsafe { moonfire_ffmpeg_cctx_codec_id(self.ctx) }) CodecId(unsafe { moonfire_ffmpeg_cctx_codec_id(self.0) })
} }
pub fn codec_type(&self) -> MediaType { pub fn codec_type(&self) -> MediaType {
MediaType(unsafe { moonfire_ffmpeg_cctx_codec_type(self.ctx) }) MediaType(unsafe { moonfire_ffmpeg_cctx_codec_type(self.0) })
} }
} }