*: make internal pointer handling safer

This commit is contained in:
meh
2015-06-04 03:03:19 +02:00
parent b2c9dc3747
commit ff1b880be6
28 changed files with 683 additions and 466 deletions

View File

@ -9,11 +9,29 @@ use ffi::*;
use ::{Error, Dictionary, Codec, Stream, Format};
pub struct Context {
pub ptr: *mut AVFormatContext,
ptr: *mut AVFormatContext,
_input: bool,
}
impl Context {
pub unsafe fn input(ptr: *mut AVFormatContext) -> Self {
Context {
ptr: ptr,
_input: true,
}
}
pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFormatContext {
self.ptr
}
}
impl Context {
pub fn new() -> Self {
unsafe {
@ -25,27 +43,21 @@ impl Context {
}
}
pub fn input(ptr: *mut AVFormatContext) -> Self {
Context {
ptr: ptr,
_input: true,
}
}
pub fn streams(&self) -> StreamIter {
StreamIter::new(self.ptr)
unsafe {
StreamIter::new(self.as_ptr())
}
}
pub fn probe_score(&self) -> i32 {
unsafe {
av_format_get_probe_score(self.ptr)
av_format_get_probe_score(self.as_ptr())
}
}
pub fn video_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_video_codec(self.ptr);
let ptr = av_format_get_video_codec(self.as_ptr());
if ptr == ptr::null_mut() {
None
@ -56,15 +68,15 @@ impl Context {
}
}
pub fn set_video_codec(&mut self, value: Codec) {
pub fn set_video_codec(&mut self, mut value: Codec) {
unsafe {
av_format_set_video_codec(self.ptr, value.ptr);
av_format_set_video_codec(self.as_mut_ptr(), value.as_mut_ptr());
}
}
pub fn audio_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_audio_codec(self.ptr);
let ptr = av_format_get_audio_codec(self.as_ptr());
if ptr == ptr::null_mut() {
None
@ -75,15 +87,15 @@ impl Context {
}
}
pub fn set_audio_codec(&mut self, value: Codec) {
pub fn set_audio_codec(&mut self, mut value: Codec) {
unsafe {
av_format_set_audio_codec(self.ptr, value.ptr);
av_format_set_audio_codec(self.as_mut_ptr(), value.as_mut_ptr());
}
}
pub fn subtitle_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_subtitle_codec(self.ptr);
let ptr = av_format_get_subtitle_codec(self.as_ptr());
if ptr == ptr::null_mut() {
None
@ -94,15 +106,15 @@ impl Context {
}
}
pub fn set_subtitle_codec(&mut self, value: Codec) {
pub fn set_subtitle_codec(&mut self, mut value: Codec) {
unsafe {
av_format_set_subtitle_codec(self.ptr, value.ptr);
av_format_set_subtitle_codec(self.as_mut_ptr(), value.as_mut_ptr());
}
}
pub fn data_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_data_codec(self.ptr);
let ptr = av_format_get_data_codec(self.as_ptr());
if ptr == ptr::null_mut() {
None
@ -113,14 +125,16 @@ impl Context {
}
}
pub fn set_data_codec(&mut self, value: Codec) {
pub fn set_data_codec(&mut self, mut value: Codec) {
unsafe {
av_format_set_data_codec(self.ptr, value.ptr);
av_format_set_data_codec(self.as_mut_ptr(), value.as_mut_ptr());
}
}
pub fn packet(&self) -> Packet {
Packet::new(self.ptr)
pub fn packet(&mut self) -> Packet {
unsafe {
Packet::new(self.as_mut_ptr())
}
}
}
@ -128,10 +142,10 @@ impl Drop for Context {
fn drop(&mut self) {
unsafe {
if self._input {
avformat_close_input(&mut self.ptr);
avformat_close_input(&mut self.as_mut_ptr());
}
else {
avformat_free_context(self.ptr);
avformat_free_context(self.as_mut_ptr());
}
}
}
@ -144,20 +158,30 @@ pub struct Packet<'a> {
_marker: PhantomData<&'a Context>,
}
impl<'a> Packet<'a> {
pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFormatContext {
self.ptr
}
}
impl<'a> Packet<'a> {
pub fn new(ptr: *mut AVFormatContext) -> Self {
Packet { ptr: ptr, pkt: ::Packet::new(), _marker: PhantomData }
Packet { ptr: ptr, pkt: ::Packet::empty(), _marker: PhantomData }
}
pub fn stream(&self) -> Stream {
unsafe {
Stream::wrap(*(*self.ptr).streams.offset(self.pkt.val.stream_index as isize))
Stream::wrap(*(*self.as_ptr()).streams.offset((*self.pkt.as_ptr()).stream_index as isize))
}
}
pub fn read(&mut self) -> Result<(), Error> {
unsafe {
match av_read_frame(self.ptr, &mut self.pkt.val) {
match av_read_frame(self.as_mut_ptr(), self.pkt.as_mut_ptr()) {
0 => Ok(()),
e => Err(Error::from(e))
}
@ -166,7 +190,7 @@ impl<'a> Packet<'a> {
pub fn write(&mut self) -> Result<bool, Error> {
unsafe {
match av_write_frame(self.ptr, &mut self.pkt.val) {
match av_write_frame(self.as_mut_ptr(), self.pkt.as_mut_ptr()) {
1 => Ok(true),
0 => Ok(false),
e => Err(Error::from(e))
@ -239,14 +263,14 @@ pub fn open(path: &Path) -> Result<Context, Error> {
}
}
pub fn open_with(path: &Path, mut options: Dictionary) -> Result<Context, Error> {
pub fn open_with(path: &Path, options: Dictionary) -> Result<Context, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = path.as_os_str().to_cstring().unwrap().as_ptr();
let opts = &mut options.ptr;
let status = avformat_open_input(&mut ps, path, ptr::null_mut(), opts);
let mut opts = options.take();
let status = avformat_open_input(&mut ps, path, ptr::null_mut(), &mut opts);
av_dict_free(opts);
Dictionary::own(opts);
match status {
0 => {
@ -268,7 +292,7 @@ pub fn open_as(path: &Path, format: &Format) -> Result<Context, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = path.as_os_str().to_cstring().unwrap().as_ptr();
let status = avformat_open_input(&mut ps, path, format.ptr, ptr::null_mut());
let status = avformat_open_input(&mut ps, path, format.as_ptr(), ptr::null_mut());
match status {
0 => {
@ -289,15 +313,15 @@ pub fn open_as(path: &Path, format: &Format) -> Result<Context, Error> {
}
}
pub fn open_as_with(path: &Path, format: &Format, mut options: Dictionary) -> Result<Context, Error> {
pub fn open_as_with(path: &Path, format: &Format, options: Dictionary) -> Result<Context, Error> {
if let &Format::Input(ref format) = format {
unsafe {
let mut ps = ptr::null_mut();
let path = path.as_os_str().to_cstring().unwrap().as_ptr();
let opts = &mut options.ptr;
let status = avformat_open_input(&mut ps, path, format.ptr, opts);
let mut opts = options.take();
let status = avformat_open_input(&mut ps, path, format.as_ptr(), &mut opts);
av_dict_free(opts);
Dictionary::own(opts);
match status {
0 => {

View File

@ -40,29 +40,39 @@ impl Format {
}
pub struct Input {
pub ptr: *mut AVInputFormat,
ptr: *mut AVInputFormat,
}
impl Input {
pub fn wrap(ptr: *mut AVInputFormat) -> Self {
pub unsafe fn wrap(ptr: *mut AVInputFormat) -> Self {
Input { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVInputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVInputFormat {
self.ptr
}
}
impl Input {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.ptr).name).to_bytes())
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.ptr).name).to_bytes())
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.ptr).extensions;
let ptr = (*self.as_ptr()).extensions;
if ptr == ptr::null() {
vec!()
@ -75,7 +85,7 @@ impl Input {
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.ptr).mime_type;
let ptr = (*self.as_ptr()).mime_type;
if ptr == ptr::null() {
vec!()
@ -88,29 +98,39 @@ impl Input {
}
pub struct Output {
pub ptr: *mut AVOutputFormat,
ptr: *mut AVOutputFormat,
}
impl Output {
pub fn wrap(ptr: *mut AVOutputFormat) -> Self {
pub unsafe fn wrap(ptr: *mut AVOutputFormat) -> Self {
Output { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVOutputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVOutputFormat {
self.ptr
}
}
impl Output {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.ptr).name).to_bytes())
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.ptr).name).to_bytes())
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.ptr).extensions;
let ptr = (*self.as_ptr()).extensions;
if ptr == ptr::null() {
vec!()
@ -123,7 +143,7 @@ impl Output {
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.ptr).mime_type;
let ptr = (*self.as_ptr()).mime_type;
if ptr == ptr::null() {
vec!()

View File

@ -1,5 +1,5 @@
pub use ::util::format::Sample;
pub use ::util::format::Pixel;
pub use ::util::format::{sample, Sample};
pub use ::util::format::{pixel, Pixel};
pub mod stream;
@ -26,11 +26,11 @@ pub fn register_all() {
pub fn register(format: &Format) {
match format {
&Format::Input(ref format) => unsafe {
av_register_input_format(format.ptr);
av_register_input_format(format.as_ptr());
},
&Format::Output(ref format) => unsafe {
av_register_output_format(format.ptr);
av_register_output_format(format.as_ptr());
}
}
}

View File

@ -17,84 +17,96 @@ pub struct Stream<'a> {
}
impl<'a> Stream<'a> {
pub fn wrap(ptr: *mut AVStream) -> Self {
pub unsafe fn wrap(ptr: *mut AVStream) -> Self {
Stream { ptr: ptr, _marker: PhantomData }
}
pub unsafe fn as_ptr(&self) -> *const AVStream {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVStream {
self.ptr
}
}
impl<'a> Stream<'a> {
pub fn codec(&self) -> codec::Context {
unsafe {
codec::Context::wrap((*self.ptr).codec)
codec::Context::wrap((*self.as_ptr()).codec)
}
}
pub fn index(&self) -> usize {
unsafe {
(*self.ptr).index as usize
(*self.as_ptr()).index as usize
}
}
pub fn time_base(&self) -> Rational {
unsafe {
Rational((*self.ptr).time_base)
Rational((*self.as_ptr()).time_base)
}
}
pub fn start_time(&self) -> i64 {
unsafe {
(*self.ptr).start_time
(*self.as_ptr()).start_time
}
}
pub fn duration(&self) -> i64 {
unsafe {
(*self.ptr).duration
(*self.as_ptr()).duration
}
}
pub fn frames(&self) -> i64 {
unsafe {
(*self.ptr).nb_frames
(*self.as_ptr()).nb_frames
}
}
pub fn disposition(&self) -> Disposition {
unsafe {
Disposition::from_bits_truncate((*self.ptr).disposition)
Disposition::from_bits_truncate((*self.as_ptr()).disposition)
}
}
pub fn discard(&self) -> Discard {
unsafe {
Discard::from((*self.ptr).discard)
Discard::from((*self.as_ptr()).discard)
}
}
pub fn side_data(&self) -> SideDataIter {
SideDataIter::new(self.ptr)
unsafe {
SideDataIter::new(self.as_ptr())
}
}
pub fn frame_rate(&self) -> Rational {
unsafe {
Rational(av_stream_get_r_frame_rate(self.ptr))
Rational(av_stream_get_r_frame_rate(self.as_ptr()))
}
}
pub fn set_frame_rate(&self, value: Rational) {
pub fn set_frame_rate(&mut self, value: Rational) {
unsafe {
av_stream_set_r_frame_rate(self.ptr, value.0);
av_stream_set_r_frame_rate(self.as_mut_ptr(), value.0);
}
}
}
pub struct SideDataIter<'a> {
ptr: *mut AVStream,
ptr: *const AVStream,
cur: c_int,
_marker: PhantomData<&'a Stream<'a>>,
}
impl<'a> SideDataIter<'a> {
pub fn new(ptr: *mut AVStream) -> Self {
pub fn new(ptr: *const AVStream) -> Self {
SideDataIter { ptr: ptr, cur: 0, _marker: PhantomData }
}
}