From ff1b880be6967515b6b5b36ceaab800de55b61dd Mon Sep 17 00:00:00 2001 From: meh Date: Thu, 4 Jun 2015 03:03:19 +0200 Subject: [PATCH] *: make internal pointer handling safer --- src/codec/codec.rs | 26 ++++--- src/codec/context.rs | 62 +++++++++------- src/codec/decoder/audio.rs | 26 +++---- src/codec/decoder/mod.rs | 18 ++--- src/codec/decoder/subtitle.rs | 2 +- src/codec/decoder/video.rs | 36 +++++----- src/codec/encoder/audio.rs | 4 +- src/codec/encoder/mod.rs | 18 ++--- src/codec/encoder/subtitle.rs | 4 +- src/codec/encoder/video.rs | 70 +++++++++--------- src/codec/packet/mod.rs | 48 +++++++------ src/codec/packet/side_data.rs | 16 ++++- src/codec/picture.rs | 113 ++++++++++++----------------- src/codec/subtitle/mod.rs | 124 +++++++++++++++++++++++--------- src/device/extensions.rs | 22 +++--- src/device/mod.rs | 16 ++++- src/format/context.rs | 104 ++++++++++++++++----------- src/format/format.rs | 44 ++++++++---- src/format/mod.rs | 8 +-- src/format/stream/mod.rs | 42 +++++++---- src/software/scaling/context.rs | 47 +++++++----- src/software/scaling/filter.rs | 30 +++++--- src/software/scaling/vector.rs | 34 +++++---- src/util/dictionary.rs | 33 ++++++--- src/util/frame/audio.rs | 54 ++++++++------ src/util/frame/mod.rs | 56 ++++++++++----- src/util/frame/side_data.rs | 20 ++++-- src/util/frame/video.rs | 72 +++++++++---------- 28 files changed, 683 insertions(+), 466 deletions(-) diff --git a/src/codec/codec.rs b/src/codec/codec.rs index fe3dd9f..a5b46b7 100644 --- a/src/codec/codec.rs +++ b/src/codec/codec.rs @@ -9,53 +9,63 @@ use ::Error; use ::codec::context::Opened; pub struct Codec<'a> { - pub ptr: *mut AVCodec, + ptr: *mut AVCodec, _marker: PhantomData<&'a ()>, } impl<'a> Codec<'a> { - pub fn wrap(ptr: *mut AVCodec) -> Self { + pub unsafe fn wrap(ptr: *mut AVCodec) -> Self { Codec { ptr: ptr, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const AVCodec { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodec { + self.ptr + } +} + +impl<'a> Codec<'a> { pub fn open(&self) -> Result { Context::new().open(self) } pub fn is_encoder(&self) -> bool { unsafe { - av_codec_is_encoder(self.ptr) != 0 + av_codec_is_encoder(self.as_ptr()) != 0 } } pub fn is_decoder(&self) -> bool { unsafe { - av_codec_is_decoder(self.ptr) != 0 + av_codec_is_decoder(self.as_ptr()) != 0 } } 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).long_name).to_bytes()) + from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).long_name).to_bytes()) } } pub fn medium(&self) -> media::Type { unsafe { - media::Type::from((*self.ptr).kind) + media::Type::from((*self.as_ptr()).kind) } } pub fn id(&self) -> Id { unsafe { - Id::from((*self.ptr).id) + Id::from((*self.as_ptr()).id) } } } diff --git a/src/codec/context.rs b/src/codec/context.rs index f2df4d0..4679939 100644 --- a/src/codec/context.rs +++ b/src/codec/context.rs @@ -10,11 +10,25 @@ use super::decoder::Decoder; use super::encoder::Encoder; pub struct Context { - pub ptr: *mut AVCodecContext, + ptr: *mut AVCodecContext, _own: bool, } +impl Context { + pub unsafe fn wrap(ptr: *mut AVCodecContext) -> Self { + Context { ptr: ptr, _own: false } + } + + pub unsafe fn as_ptr(&self) -> *const AVCodecContext { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodecContext { + self.ptr + } +} + impl Context { pub fn new() -> Self { unsafe { @@ -22,22 +36,18 @@ impl Context { } } - pub fn wrap(ptr: *mut AVCodecContext) -> Self { - Context { ptr: ptr, _own: false } - } - - pub fn open(self, codec: &Codec) -> Result { + pub fn open(mut self, codec: &Codec) -> Result { unsafe { - match avcodec_open2(self.ptr, codec.ptr, ptr::null_mut()) { + match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) { 0 => Ok(Opened(self)), e => Err(Error::from(e)) } } } - pub fn open_with(self, codec: &Codec, mut options: Dictionary) -> Result { + pub fn open_with(mut self, codec: &Codec, options: Dictionary) -> Result { unsafe { - match avcodec_open2(self.ptr, codec.ptr, &mut options.ptr) { + match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut options.take()) { 0 => Ok(Opened(self)), e => Err(Error::from(e)) } @@ -64,65 +74,65 @@ impl Context { pub fn codec(&self) -> Option { unsafe { - if (*self.ptr).codec == ptr::null() { + if (*self.as_ptr()).codec == ptr::null() { None } else { - Some(Codec::wrap((*self.ptr).codec as *mut _)) + Some(Codec::wrap((*self.as_ptr()).codec as *mut _)) } } } pub fn medium(&self) -> media::Type { unsafe { - media::Type::from((*self.ptr).codec_type) + media::Type::from((*self.as_ptr()).codec_type) } } pub fn id(&self) -> Id { unsafe { - Id::from((*self.ptr).codec_id) + Id::from((*self.as_ptr()).codec_id) } } pub fn bit_rate(&self) -> usize { unsafe { - (*self.ptr).bit_rate as usize + (*self.as_ptr()).bit_rate as usize } } pub fn delay(&self) -> usize { unsafe { - (*self.ptr).delay as usize + (*self.as_ptr()).delay as usize } } pub fn compliance(&mut self, value: Compliance) { unsafe { - (*self.ptr).strict_std_compliance = value.into(); + (*self.as_mut_ptr()).strict_std_compliance = value.into(); } } pub fn debug(&mut self, value: Debug) { unsafe { - (*self.ptr).debug = value.bits(); + (*self.as_mut_ptr()).debug = value.bits(); } } pub fn set_threading(&mut self, config: threading::Config) { unsafe { - (*self.ptr).thread_type = config.kind.into(); - (*self.ptr).thread_count = config.count as c_int; - (*self.ptr).thread_safe_callbacks = if config.safe { 1 } else { 0 }; + (*self.as_mut_ptr()).thread_type = config.kind.into(); + (*self.as_mut_ptr()).thread_count = config.count as c_int; + (*self.as_mut_ptr()).thread_safe_callbacks = if config.safe { 1 } else { 0 }; } } pub fn threading(&self) -> threading::Config { unsafe { threading::Config { - kind: threading::Type::from((*self.ptr).active_thread_type), - count: (*self.ptr).thread_count as usize, - safe: (*self.ptr).thread_safe_callbacks != 0, + kind: threading::Type::from((*self.as_ptr()).active_thread_type), + count: (*self.as_ptr()).thread_count as usize, + safe: (*self.as_ptr()).thread_safe_callbacks != 0, } } } @@ -134,7 +144,7 @@ impl Drop for Context { fn drop(&mut self) { if self._own { unsafe { - avcodec_free_context(&mut self.ptr); + avcodec_free_context(&mut self.as_mut_ptr()); } } } @@ -150,7 +160,7 @@ impl Clone for Context { fn clone_from(&mut self, source: &Self) { unsafe { - avcodec_copy_context(self.ptr, source.ptr); + avcodec_copy_context(self.as_mut_ptr(), source.as_ptr()); } } } @@ -192,7 +202,7 @@ impl Opened { impl Drop for Opened { fn drop(&mut self) { unsafe { - avcodec_close(self.0.ptr); + avcodec_close(self.as_mut_ptr()); } } } diff --git a/src/codec/decoder/audio.rs b/src/codec/decoder/audio.rs index 4c8d46b..7b0eb2d 100644 --- a/src/codec/decoder/audio.rs +++ b/src/codec/decoder/audio.rs @@ -15,7 +15,7 @@ impl Audio { unsafe { let mut got: c_int = 0; - match avcodec_decode_audio4(self.ptr, out.ptr, &mut got, &packet.val) { + match avcodec_decode_audio4(self.as_mut_ptr(), out.as_mut_ptr(), &mut got, packet.as_ptr()) { e if e < 0 => Err(Error::from(e)), _ => Ok(got != 0) } @@ -24,73 +24,73 @@ impl Audio { pub fn rate(&self) -> u32 { unsafe { - (*self.ptr).sample_rate as u32 + (*self.as_ptr()).sample_rate as u32 } } pub fn channels(&self) -> u16 { unsafe { - (*self.ptr).channels as u16 + (*self.as_ptr()).channels as u16 } } pub fn format(&self) -> format::Sample { unsafe { - format::Sample::from((*self.ptr).sample_fmt) + format::Sample::from((*self.as_ptr()).sample_fmt) } } pub fn request_format(&mut self, value: format::Sample) { unsafe { - (*self.ptr).request_sample_fmt = value.into(); + (*self.as_mut_ptr()).request_sample_fmt = value.into(); } } pub fn frames(&self) -> usize { unsafe { - (*self.ptr).frame_number as usize + (*self.as_ptr()).frame_number as usize } } pub fn align(&self) -> usize { unsafe { - (*self.ptr).block_align as usize + (*self.as_ptr()).block_align as usize } } pub fn channel_layout(&self) -> ChannelLayout { unsafe { - ChannelLayout::from_bits_truncate((*self.ptr).channel_layout) + ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout) } } pub fn set_channel_layout(&mut self, value: ChannelLayout) { unsafe { - (*self.ptr).channel_layout = value.bits(); + (*self.as_mut_ptr()).channel_layout = value.bits(); } } pub fn request_channel_layout(&mut self, value: ChannelLayout) { unsafe { - (*self.ptr).request_channel_layout = value.bits(); + (*self.as_mut_ptr()).request_channel_layout = value.bits(); } } pub fn audio_service(&mut self) -> AudioService { unsafe { - AudioService::from((*self.ptr).audio_service_type) + AudioService::from((*self.as_mut_ptr()).audio_service_type) } } pub fn max_rate(&self) -> usize { unsafe { - (*self.ptr).rc_max_rate as usize + (*self.as_ptr()).rc_max_rate as usize } } pub fn frame_start(&self) -> Option { unsafe { - match (*self.ptr).timecode_frame_start { + match (*self.as_ptr()).timecode_frame_start { -1 => None, n => Some(n as usize) } diff --git a/src/codec/decoder/mod.rs b/src/codec/decoder/mod.rs index 825c8ad..016a6d0 100644 --- a/src/codec/decoder/mod.rs +++ b/src/codec/decoder/mod.rs @@ -58,49 +58,49 @@ impl Decoder { pub fn conceal(&mut self, value: Conceal) { unsafe { - (*self.ptr).error_concealment = value.bits(); + (*self.as_mut_ptr()).error_concealment = value.bits(); } } pub fn check(&mut self, value: Check) { unsafe { - (*self.ptr).err_recognition = value.bits(); + (*self.as_mut_ptr()).err_recognition = value.bits(); } } pub fn profile(&self) -> Profile { unsafe { - Profile::from((self.id(), (*self.ptr).profile)) + Profile::from((self.id(), (*self.as_ptr()).profile)) } } pub fn skip_loop_filter(&mut self, value: Discard) { unsafe { - (*self.ptr).skip_loop_filter = value.into(); + (*self.as_mut_ptr()).skip_loop_filter = value.into(); } } pub fn skip_idct(&mut self, value: Discard) { unsafe { - (*self.ptr).skip_idct = value.into(); + (*self.as_mut_ptr()).skip_idct = value.into(); } } pub fn skip_frame(&mut self, value: Discard) { unsafe { - (*self.ptr).skip_frame = value.into(); + (*self.as_mut_ptr()).skip_frame = value.into(); } } pub fn subtitle_header(&self) -> &[u8] { unsafe { - from_raw_parts((*self.ptr).subtitle_header, (*self.ptr).subtitle_header_size as usize) + from_raw_parts((*self.as_ptr()).subtitle_header, (*self.as_ptr()).subtitle_header_size as usize) } } pub fn frame_rate(&self) -> Option { unsafe { - let value = (*self.ptr).framerate; + let value = (*self.as_ptr()).framerate; if value == (AVRational { num: 0, den: 1 }) { None @@ -113,7 +113,7 @@ impl Decoder { pub fn time_base(&self) -> Rational { unsafe { - Rational((*self.ptr).time_base) + Rational((*self.as_ptr()).time_base) } } } diff --git a/src/codec/decoder/subtitle.rs b/src/codec/decoder/subtitle.rs index 4538e1d..b6bc0c5 100644 --- a/src/codec/decoder/subtitle.rs +++ b/src/codec/decoder/subtitle.rs @@ -13,7 +13,7 @@ impl Subtitle { unsafe { let mut got: c_int = 0; - match avcodec_decode_subtitle2(self.ptr, &mut out.val, &mut got, &packet.val) { + match avcodec_decode_subtitle2(self.as_mut_ptr(), out.as_mut_ptr(), &mut got, packet.as_ptr()) { e if e < 0 => Err(Error::from(e)), _ => Ok(got != 0) } diff --git a/src/codec/decoder/video.rs b/src/codec/decoder/video.rs index bb71460..f63cef3 100644 --- a/src/codec/decoder/video.rs +++ b/src/codec/decoder/video.rs @@ -17,7 +17,7 @@ impl Video { unsafe { let mut got: c_int = 0; - match avcodec_decode_video2(self.ptr, out.ptr, &mut got, &packet.val) { + match avcodec_decode_video2(self.as_mut_ptr(), out.as_mut_ptr(), &mut got, packet.as_ptr()) { e if e < 0 => Err(Error::from(e)), _ => Ok(got != 0) } @@ -26,103 +26,103 @@ impl Video { pub fn width(&self) -> u32 { unsafe { - (*self.ptr).width as u32 + (*self.as_ptr()).width as u32 } } pub fn height(&self) -> u32 { unsafe { - (*self.ptr).height as u32 + (*self.as_ptr()).height as u32 } } pub fn format(&self) -> format::Pixel { unsafe { - format::Pixel::from((*self.ptr).pix_fmt) + format::Pixel::from((*self.as_ptr()).pix_fmt) } } pub fn set_format(&mut self, value: format::Pixel) { unsafe { - (*self.ptr).pix_fmt = value.into(); + (*self.as_mut_ptr()).pix_fmt = value.into(); } } pub fn has_b_frames(&self) -> bool { unsafe { - (*self.ptr).has_b_frames != 0 + (*self.as_ptr()).has_b_frames != 0 } } pub fn aspect_ratio(&self) -> Rational { unsafe { - Rational((*self.ptr).sample_aspect_ratio) + Rational((*self.as_ptr()).sample_aspect_ratio) } } pub fn color_space(&self) -> color::Space { unsafe { - color::Space::from((*self.ptr).colorspace) + color::Space::from((*self.as_ptr()).colorspace) } } pub fn color_range(&self) -> color::Range { unsafe { - color::Range::from((*self.ptr).color_range) + color::Range::from((*self.as_ptr()).color_range) } } pub fn color_primaries(&self) -> color::Primaries { unsafe { - color::Primaries::from((*self.ptr).color_primaries) + color::Primaries::from((*self.as_ptr()).color_primaries) } } pub fn color_transfer_characteristic(&self) -> color::TransferCharacteristic { unsafe { - color::TransferCharacteristic::from((*self.ptr).color_trc) + color::TransferCharacteristic::from((*self.as_ptr()).color_trc) } } pub fn chroma_location(&self) -> chroma::Location { unsafe { - chroma::Location::from((*self.ptr).chroma_sample_location) + chroma::Location::from((*self.as_ptr()).chroma_sample_location) } } pub fn set_slice_count(&mut self, value: usize) { unsafe { - (*self.ptr).slice_count = value as c_int; + (*self.as_mut_ptr()).slice_count = value as c_int; } } pub fn set_slice_flags(&mut self, value: slice::Flags) { unsafe { - (*self.ptr).slice_flags = value.bits(); + (*self.as_mut_ptr()).slice_flags = value.bits(); } } pub fn skip_top(&mut self, value: usize) { unsafe { - (*self.ptr).skip_top = value as c_int; + (*self.as_mut_ptr()).skip_top = value as c_int; } } pub fn skip_bottom(&mut self, value: usize) { unsafe { - (*self.ptr).skip_bottom = value as c_int; + (*self.as_mut_ptr()).skip_bottom = value as c_int; } } pub fn references(&self) -> usize { unsafe { - (*self.ptr).refs as usize + (*self.as_ptr()).refs as usize } } pub fn set_field_order(&mut self, value: FieldOrder) { unsafe { - (*self.ptr).field_order = value.into(); + (*self.as_mut_ptr()).field_order = value.into(); } } diff --git a/src/codec/encoder/audio.rs b/src/codec/encoder/audio.rs index 51aa3f9..09be933 100644 --- a/src/codec/encoder/audio.rs +++ b/src/codec/encoder/audio.rs @@ -10,11 +10,11 @@ use ::frame; pub struct Audio(pub Encoder); impl Audio { - pub fn encode(&self, frame: &frame::Audio, out: &mut Packet) -> Result { + pub fn encode(&mut self, frame: &frame::Audio, out: &mut Packet) -> Result { unsafe { let mut got: c_int = 0; - match avcodec_encode_audio2(self.ptr, &mut out.val, frame.ptr, &mut got) { + match avcodec_encode_audio2(self.as_mut_ptr(), out.as_mut_ptr(), frame.as_ptr(), &mut got) { e if e < 0 => Err(Error::from(e)), _ => Ok(got != 0) } diff --git a/src/codec/encoder/mod.rs b/src/codec/encoder/mod.rs index b583c20..4bb416f 100644 --- a/src/codec/encoder/mod.rs +++ b/src/codec/encoder/mod.rs @@ -62,29 +62,29 @@ impl Encoder { pub fn set_rate(&mut self, value: usize) { unsafe { - (*self.ptr).bit_rate = value as c_int; + (*self.as_mut_ptr()).bit_rate = value as c_int; } } pub fn set_tolerance(&mut self, value: usize) { unsafe { - (*self.ptr).bit_rate_tolerance = value as c_int; + (*self.as_mut_ptr()).bit_rate_tolerance = value as c_int; } } pub fn set_quality(&mut self, value: usize) { unsafe { - (*self.ptr).global_quality = value as c_int; + (*self.as_mut_ptr()).global_quality = value as c_int; } } pub fn set_compression(&mut self, value: Option) { unsafe { if let Some(value) = value { - (*self.ptr).compression_level = value as c_int; + (*self.as_mut_ptr()).compression_level = value as c_int; } else { - (*self.ptr).compression_level = -1; + (*self.as_mut_ptr()).compression_level = -1; } } } @@ -92,18 +92,18 @@ impl Encoder { pub fn set_frame_rate(&mut self, value: Option) { unsafe { if let Some(value) = value { - (*self.ptr).framerate = value.0; + (*self.as_mut_ptr()).framerate = value.0; } else { - (*self.ptr).framerate.num = 0; - (*self.ptr).framerate.den = 1; + (*self.as_mut_ptr()).framerate.num = 0; + (*self.as_mut_ptr()).framerate.den = 1; } } } pub fn set_time_base(&mut self, value: Rational) { unsafe { - (*self.ptr).time_base = value.0; + (*self.as_mut_ptr()).time_base = value.0; } } } diff --git a/src/codec/encoder/subtitle.rs b/src/codec/encoder/subtitle.rs index 64b40b6..03f1df7 100644 --- a/src/codec/encoder/subtitle.rs +++ b/src/codec/encoder/subtitle.rs @@ -9,9 +9,9 @@ use ::Error; pub struct Subtitle(pub Encoder); impl Subtitle { - pub fn encode(&self, subtitle: &::Subtitle, out: &mut [u8]) -> Result { + pub fn encode(&mut self, subtitle: &::Subtitle, out: &mut [u8]) -> Result { unsafe { - match avcodec_encode_subtitle(self.ptr, out.as_mut_ptr(), out.len() as c_int, &subtitle.val) { + match avcodec_encode_subtitle(self.as_mut_ptr(), out.as_mut_ptr(), out.len() as c_int, subtitle.as_ptr()) { e if e < 0 => Err(Error::from(e)), _ => Ok(true) } diff --git a/src/codec/encoder/video.rs b/src/codec/encoder/video.rs index 3d8ebb9..886d6df 100644 --- a/src/codec/encoder/video.rs +++ b/src/codec/encoder/video.rs @@ -11,11 +11,11 @@ use ::format; pub struct Video(pub Encoder); impl Video { - pub fn encode(&self, frame: &frame::Video, out: &mut Packet) -> Result { + pub fn encode(&mut self, frame: &frame::Video, out: &mut Packet) -> Result { unsafe { let mut got: c_int = 0; - match avcodec_encode_video2(self.ptr, &mut out.val, frame.ptr, &mut got) { + match avcodec_encode_video2(self.as_mut_ptr(), out.as_mut_ptr(), frame.as_ptr(), &mut got) { e if e < 0 => Err(Error::from(e)), _ => Ok(got != 0) } @@ -24,179 +24,179 @@ impl Video { pub fn set_width(&mut self, value: u32) { unsafe { - (*self.ptr).width = value as c_int; + (*self.as_mut_ptr()).width = value as c_int; } } pub fn set_height(&mut self, value: u32) { unsafe { - (*self.ptr).height = value as c_int; + (*self.as_mut_ptr()).height = value as c_int; } } pub fn set_gop(&mut self, value: u32) { unsafe { - (*self.ptr).gop_size = value as c_int; + (*self.as_mut_ptr()).gop_size = value as c_int; } } pub fn set_format(&mut self, value: format::Pixel) { unsafe { - (*self.ptr).pix_fmt = value.into(); + (*self.as_mut_ptr()).pix_fmt = value.into(); } } pub fn set_motion_estimation(&mut self, value: MotionEstimation) { unsafe { - (*self.ptr).me_method = value.into(); + (*self.as_mut_ptr()).me_method = value.into(); } } pub fn set_max_b_frames(&mut self, value: usize) { unsafe { - (*self.ptr).max_b_frames = value as c_int; + (*self.as_mut_ptr()).max_b_frames = value as c_int; } } pub fn set_b_quant_factor(&mut self, value: f32) { unsafe { - (*self.ptr).b_quant_factor = value as c_float; + (*self.as_mut_ptr()).b_quant_factor = value as c_float; } } pub fn set_b_quant_offset(&mut self, value: f32) { unsafe { - (*self.ptr).b_quant_offset = value as c_float; + (*self.as_mut_ptr()).b_quant_offset = value as c_float; } } pub fn set_i_quant_factor(&mut self, value: f32) { unsafe { - (*self.ptr).i_quant_factor = value as c_float; + (*self.as_mut_ptr()).i_quant_factor = value as c_float; } } pub fn set_i_quant_offset(&mut self, value: f32) { unsafe { - (*self.ptr).i_quant_offset = value as c_float; + (*self.as_mut_ptr()).i_quant_offset = value as c_float; } } pub fn set_lumi_masking(&mut self, value: f32) { unsafe { - (*self.ptr).lumi_masking = value as c_float; + (*self.as_mut_ptr()).lumi_masking = value as c_float; } } pub fn set_temporal_cplx_masking(&mut self, value: f32) { unsafe { - (*self.ptr).temporal_cplx_masking = value as c_float; + (*self.as_mut_ptr()).temporal_cplx_masking = value as c_float; } } pub fn set_spatial_cplx_masking(&mut self, value: f32) { unsafe { - (*self.ptr).spatial_cplx_masking = value as c_float; + (*self.as_mut_ptr()).spatial_cplx_masking = value as c_float; } } pub fn set_p_masking(&mut self, value: f32) { unsafe { - (*self.ptr).p_masking = value as c_float; + (*self.as_mut_ptr()).p_masking = value as c_float; } } pub fn set_dark_masking(&mut self, value: f32) { unsafe { - (*self.ptr).dark_masking = value as c_float; + (*self.as_mut_ptr()).dark_masking = value as c_float; } } pub fn set_prediction(&mut self, value: Prediction) { unsafe { - (*self.ptr).prediction_method = value.into(); + (*self.as_mut_ptr()).prediction_method = value.into(); } } pub fn set_aspect_ratio(&mut self, value: Rational) { unsafe { - (*self.ptr).sample_aspect_ratio = value.0; + (*self.as_mut_ptr()).sample_aspect_ratio = value.0; } } pub fn set_me_comparison(&mut self, value: Comparison) { unsafe { - (*self.ptr).me_cmp = value.into(); + (*self.as_mut_ptr()).me_cmp = value.into(); } } pub fn set_me_sub_comparison(&mut self, value: Comparison) { unsafe { - (*self.ptr).me_sub_cmp = value.into(); + (*self.as_mut_ptr()).me_sub_cmp = value.into(); } } pub fn set_mb_comparison(&mut self, value: Comparison) { unsafe { - (*self.ptr).mb_cmp = value.into(); + (*self.as_mut_ptr()).mb_cmp = value.into(); } } pub fn set_ildct_comparison(&mut self, value: Comparison) { unsafe { - (*self.ptr).ildct_cmp = value.into(); + (*self.as_mut_ptr()).ildct_cmp = value.into(); } } pub fn set_dia_size(&mut self, value: usize) { unsafe { - (*self.ptr).dia_size = value as c_int; + (*self.as_mut_ptr()).dia_size = value as c_int; } } pub fn set_last_predictors(&mut self, value: usize) { unsafe { - (*self.ptr).last_predictor_count = value as c_int; + (*self.as_mut_ptr()).last_predictor_count = value as c_int; } } pub fn set_pre_me(&mut self, value: MotionEstimation) { unsafe { - (*self.ptr).pre_me = value.into(); + (*self.as_mut_ptr()).pre_me = value.into(); } } pub fn set_me_pre_comparison(&mut self, value: Comparison) { unsafe { - (*self.ptr).me_pre_cmp = value.into(); + (*self.as_mut_ptr()).me_pre_cmp = value.into(); } } pub fn set_pre_dia_size(&mut self, value: usize) { unsafe { - (*self.ptr).pre_dia_size = value as c_int; + (*self.as_mut_ptr()).pre_dia_size = value as c_int; } } pub fn set_me_subpel_quality(&mut self, value: usize) { unsafe { - (*self.ptr).me_subpel_quality = value as c_int; + (*self.as_mut_ptr()).me_subpel_quality = value as c_int; } } pub fn set_me_range(&mut self, value: usize) { unsafe { - (*self.ptr).me_range = value as c_int; + (*self.as_mut_ptr()).me_range = value as c_int; } } pub fn set_intra_quant_bias(&mut self, value: Option) { unsafe { if let Some(value) = value { - (*self.ptr).intra_quant_bias = value as c_int; + (*self.as_mut_ptr()).intra_quant_bias = value as c_int; } else { - (*self.ptr).intra_quant_bias = FF_DEFAULT_QUANT_BIAS; + (*self.as_mut_ptr()).intra_quant_bias = FF_DEFAULT_QUANT_BIAS; } } } @@ -204,17 +204,17 @@ impl Video { pub fn set_inter_quant_bias(&mut self, value: Option) { unsafe { if let Some(value) = value { - (*self.ptr).inter_quant_bias = value as c_int; + (*self.as_mut_ptr()).inter_quant_bias = value as c_int; } else { - (*self.ptr).inter_quant_bias = FF_DEFAULT_QUANT_BIAS; + (*self.as_mut_ptr()).inter_quant_bias = FF_DEFAULT_QUANT_BIAS; } } } pub fn set_mb_decision(&mut self, value: Decision) { unsafe { - (*self.ptr).mb_decision = value.into(); + (*self.as_mut_ptr()).mb_decision = value.into(); } } } diff --git a/src/codec/packet/mod.rs b/src/codec/packet/mod.rs index b698605..0c9cc78 100644 --- a/src/codec/packet/mod.rs +++ b/src/codec/packet/mod.rs @@ -10,78 +10,86 @@ use libc::c_int; use ffi::*; -pub struct Packet { - pub val: AVPacket, +pub struct Packet(AVPacket); + +impl Packet { + pub unsafe fn as_ptr(&self) -> *const AVPacket { + &self.0 + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVPacket { + &mut self.0 + } } impl Packet { - pub fn new() -> Self { + pub fn empty() -> Self { unsafe { let mut pkt: AVPacket = mem::zeroed(); av_init_packet(&mut pkt); - Packet { val: pkt } + Packet(pkt) } } - pub fn sized(size: usize) -> Self { + pub fn new(size: usize) -> Self { unsafe { let mut pkt: AVPacket = mem::zeroed(); av_init_packet(&mut pkt); av_new_packet(&mut pkt, size as c_int); - Packet { val: pkt } + Packet(pkt) } } pub fn shrink(&mut self, size: usize) { unsafe { - av_shrink_packet(&mut self.val, size as c_int); + av_shrink_packet(&mut self.0, size as c_int); } } pub fn grow(&mut self, size: usize) { unsafe { - av_grow_packet(&mut self.val, size as c_int); + av_grow_packet(&mut self.0, size as c_int); } } pub fn flags(&self) -> Flags { - Flags::from_bits_truncate(self.val.flags) + Flags::from_bits_truncate(self.0.flags) } pub fn set_flags(&mut self, value: Flags) { - self.val.flags = value.bits(); + self.0.flags = value.bits(); } pub fn pts(&self) -> i64 { - self.val.pts as i64 + self.0.pts as i64 } pub fn dts(&self) -> i64 { - self.val.dts as i64 + self.0.dts as i64 } pub fn size(&self) -> usize { - self.val.size as usize + self.0.size as usize } pub fn duration(&self) -> usize { - self.val.duration as usize + self.0.duration as usize } pub fn position(&self) -> isize { - self.val.pos as isize + self.0.pos as isize } pub fn convergence(&self) -> isize { - self.val.convergence_duration as isize + self.0.convergence_duration as isize } pub fn side_data(&self) -> SideDataIter { - SideDataIter::new(&self.val) + SideDataIter::new(&self.0) } } @@ -89,7 +97,7 @@ unsafe impl Send for Packet { } impl Clone for Packet { fn clone(&self) -> Self { - let mut pkt = Packet::new(); + let mut pkt = Packet::empty(); pkt.clone_from(self); pkt @@ -97,7 +105,7 @@ impl Clone for Packet { fn clone_from(&mut self, source: &Self) { unsafe { - av_copy_packet(&mut self.val, &source.val); + av_copy_packet(&mut self.0, &source.0); } } } @@ -105,7 +113,7 @@ impl Clone for Packet { impl Drop for Packet { fn drop(&mut self) { unsafe { - av_free_packet(&mut self.val); + av_free_packet(&mut self.0); } } } diff --git a/src/codec/packet/side_data.rs b/src/codec/packet/side_data.rs index 5c098d4..090c034 100644 --- a/src/codec/packet/side_data.rs +++ b/src/codec/packet/side_data.rs @@ -77,19 +77,29 @@ pub struct SideData<'a> { } impl<'a> SideData<'a> { - pub fn wrap(ptr: *mut AVPacketSideData) -> Self { + pub unsafe fn wrap(ptr: *mut AVPacketSideData) -> Self { SideData { ptr: ptr, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const AVPacketSideData { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVPacketSideData { + self.ptr + } +} + +impl<'a> SideData<'a> { pub fn kind(&self) -> Type { unsafe { - Type::from((*self.ptr).kind) + Type::from((*self.as_ptr()).kind) } } pub fn data(&self) -> &[u8] { unsafe { - slice::from_raw_parts((*self.ptr).data, (*self.ptr).size as usize) + slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize) } } } diff --git a/src/codec/picture.rs b/src/codec/picture.rs index 45c864a..e30913b 100644 --- a/src/codec/picture.rs +++ b/src/codec/picture.rs @@ -1,16 +1,16 @@ use std::mem; use std::slice; -use std::marker::{Reflect, PhantomData}; +use std::marker::PhantomData; use libc::{c_int, size_t}; use ffi::*; -use ::util::format::Pixel; +use ::format; use ::Error; pub struct Picture<'a> { - pub ptr: *mut AVPicture, + ptr: *mut AVPicture, - format: Pixel, + format: format::Pixel, width: u32, height: u32, @@ -19,7 +19,30 @@ pub struct Picture<'a> { } impl<'a> Picture<'a> { - pub fn size(format: Pixel, width: u32, height: u32) -> Result { + pub unsafe fn wrap(ptr: *mut AVPicture, format: format::Pixel, width: u32, height: u32) -> Self { + Picture { + ptr: ptr, + + format: format, + width: width, + height: height, + + _own: false, + _marker: PhantomData + } + } + + pub unsafe fn as_ptr(&self) -> *const AVPicture { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVPicture { + self.ptr + } +} + +impl<'a> Picture<'a> { + pub fn size(format: format::Pixel, width: u32, height: u32) -> Result { unsafe { match avpicture_get_size(format.into(), width as c_int, height as c_int) { v if v >= 0 => Ok(v as usize), @@ -28,7 +51,7 @@ impl<'a> Picture<'a> { } } - pub fn new(format: Pixel, width: u32, height: u32) -> Result { + pub fn new(format: format::Pixel, width: u32, height: u32) -> Result { unsafe { let ptr = av_malloc(mem::size_of::() as size_t) as *mut AVPicture; @@ -49,20 +72,7 @@ impl<'a> Picture<'a> { } } - pub fn wrap(ptr: *mut AVPicture, format: Pixel, width: u32, height: u32) -> Self { - Picture { - ptr: ptr, - - format: format, - width: width, - height: height, - - _own: false, - _marker: PhantomData - } - } - - pub fn format(&self) -> Pixel { + pub fn format(&self) -> format::Pixel { self.format } @@ -83,62 +93,50 @@ impl<'a> Picture<'a> { } } - pub fn layout_as(&self, format: Pixel, width: u32, height: u32, out: &mut [u8]) -> Result { + pub fn layout_as(&self, format: format::Pixel, width: u32, height: u32, out: &mut [u8]) -> Result { unsafe { - match avpicture_layout(self.ptr, format.into(), width as c_int, height as c_int, out.as_mut_ptr(), out.len() as c_int) { + match avpicture_layout(self.as_ptr(), format.into(), width as c_int, height as c_int, out.as_mut_ptr(), out.len() as c_int) { s if s >= 0 => Ok(s as usize), e => Err(Error::from(e)) } } } - pub fn crop(&mut self, source: &Picture, top: u32, left: u32) -> Result<(), Error> { + pub fn crop(&self, source: &mut Picture, top: u32, left: u32) -> Result<(), Error> { if self.format != source.format { return Err(Error::Bug); } unsafe { - match av_picture_crop(self.ptr, source.ptr, self.format.into(), top as c_int, left as c_int) { + match av_picture_crop(source.as_mut_ptr(), self.as_ptr(), self.format.into(), top as c_int, left as c_int) { 0 => Ok(()), e => Err(Error::from(e)) } } } - pub fn data(&self) -> Result, Error> { - if !valid::(self.format) { - return Err(Error::InvalidData); - } - + pub fn data(&self) -> Vec<&[u8]> { let mut result = Vec::new(); unsafe { - for (i, length) in (*self.ptr).linesize.iter().take_while(|l| **l > 0).enumerate() { - result.push(slice::from_raw_parts( - mem::transmute((*self.ptr).data[i]), - ((*length as usize) * (self.height as usize)) / mem::size_of::())); + for (i, length) in (*self.as_ptr()).linesize.iter().take_while(|l| **l > 0).enumerate() { + result.push(slice::from_raw_parts((*self.as_ptr()).data[i], (*length as usize) * (self.height as usize))) } } - Ok(result) + result } - pub fn data_mut(&mut self) -> Result, Error> { - if !valid::(self.format) { - return Err(Error::InvalidData); - } - + pub fn data_mut(&mut self) -> Vec<&mut [u8]> { let mut result = Vec::new(); unsafe { - for (i, length) in (*self.ptr).linesize.iter().take_while(|l| **l > 0).enumerate() { - result.push(slice::from_raw_parts_mut( - mem::transmute((*self.ptr).data[i]), - ((*length as usize) * (self.height as usize)) / mem::size_of::())); + for (i, length) in (*self.as_ptr()).linesize.iter().take_while(|l| **l > 0).enumerate() { + result.push(slice::from_raw_parts_mut((*self.as_ptr()).data[i], (*length as usize) * (self.height as usize))) } } - Ok(result) + result } } @@ -152,7 +150,7 @@ impl<'a> Clone for Picture<'a> { fn clone_from(&mut self, source: &Self) { unsafe { - av_picture_copy(self.ptr, source.ptr, source.format.into(), source.width as c_int, source.height as c_int); + av_picture_copy(self.as_mut_ptr(), source.as_ptr(), source.format.into(), source.width as c_int, source.height as c_int); } } } @@ -161,31 +159,8 @@ impl<'a> Drop for Picture<'a> { fn drop(&mut self) { if self._own { unsafe { - av_free(mem::transmute(self.ptr)); + av_free(self.as_mut_ptr() as *mut _); } } } } - -pub fn valid(format: Pixel) -> bool { - if mem::size_of::() == 1 { - return true; - } - - match format { - Pixel::None => - false, - - Pixel::RGB24 | Pixel::BGR24 => - mem::size_of::() == 3, - - Pixel::ARGB | Pixel::RGBA | Pixel::ABGR | Pixel::BGRA => - mem::size_of::() == 4 * 4, - - Pixel::ZRGB | Pixel::RGBZ | Pixel::ZBGR | Pixel::BGRZ => - mem::size_of::() == 4 * 4, - - _ => - false - } -} diff --git a/src/codec/subtitle/mod.rs b/src/codec/subtitle/mod.rs index fa0e7db..af78c21 100644 --- a/src/codec/subtitle/mod.rs +++ b/src/codec/subtitle/mod.rs @@ -3,6 +3,7 @@ pub use self::flag::Flags; use std::marker::PhantomData; use std::mem; +use std::ptr; use std::ffi::CStr; use std::str::from_utf8_unchecked; use std::ops::Deref; @@ -42,43 +43,51 @@ impl Into for Type { } } -pub struct Subtitle { - pub val: AVSubtitle, +pub struct Subtitle(AVSubtitle); + +impl Subtitle { + pub unsafe fn as_ptr(&self) -> *const AVSubtitle { + &self.0 + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitle { + &mut self.0 + } } impl Subtitle { pub fn new() -> Self { unsafe { - Subtitle { val: mem::zeroed() } + Subtitle(mem::zeroed()) } } pub fn pts(&self) -> i64 { - self.val.pts as i64 + self.0.pts as i64 } pub fn set_pts(&mut self, value: i64) { - self.val.pts = value as int64_t; + self.0.pts = value as int64_t; } pub fn start(&self) -> u32 { - self.val.start_display_time as u32 + self.0.start_display_time as u32 } pub fn set_start(&mut self, value: u32) { - self.val.start_display_time = value as uint32_t; + self.0.start_display_time = value as uint32_t; } pub fn end(&self) -> u32 { - self.val.end_display_time as u32 + self.0.end_display_time as u32 } pub fn set_end(&mut self, value: u32) { - self.val.end_display_time = value as uint32_t; + self.0.end_display_time = value as uint32_t; } pub fn rects(&self) -> RectIter { - RectIter::new(&self.val) + RectIter::new(&self.0) } } @@ -119,87 +128,124 @@ pub enum Rect<'a> { } impl<'a> Rect<'a> { - pub fn wrap(ptr: *mut AVSubtitleRect) -> Self { - unsafe { - match Type::from((*ptr).kind) { - Type::None => Rect::None, - Type::Bitmap => Rect::Bitmap(Bitmap::wrap(ptr)), - Type::Text => Rect::Text(Text::wrap(ptr)), - Type::Ass => Rect::Ass(Ass::wrap(ptr)) - } + pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self { + match Type::from((*ptr).kind) { + Type::None => Rect::None, + Type::Bitmap => Rect::Bitmap(Bitmap::wrap(ptr)), + Type::Text => Rect::Text(Text::wrap(ptr)), + Type::Ass => Rect::Ass(Ass::wrap(ptr)) } } + pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect { + match self { + &Rect::None => ptr::null(), + &Rect::Bitmap(ref b) => b.as_ptr(), + &Rect::Text(ref t) => t.as_ptr(), + &Rect::Ass(ref a) => a.as_ptr() + } + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect { + match self { + &mut Rect::None => ptr::null_mut(), + &mut Rect::Bitmap(ref mut b) => b.as_mut_ptr(), + &mut Rect::Text(ref mut t) => t.as_mut_ptr(), + &mut Rect::Ass(ref mut a) => a.as_mut_ptr() + } + } +} + +impl<'a> Rect<'a> { pub fn flags(&self) -> Flags { unsafe { Flags::from_bits_truncate(match self { &Rect::None => 0, - &Rect::Bitmap(ref b) => (*b.ptr).flags, - &Rect::Text(ref t) => (*t.ptr).flags, - &Rect::Ass(ref a) => (*a.ptr).flags + &Rect::Bitmap(ref b) => (*b.as_ptr()).flags, + &Rect::Text(ref t) => (*t.as_ptr()).flags, + &Rect::Ass(ref a) => (*a.as_ptr()).flags }) } } } pub struct Bitmap<'a> { - pub ptr: *mut AVSubtitleRect, + ptr: *mut AVSubtitleRect, _marker: PhantomData<&'a ()>, } impl<'a> Bitmap<'a> { - pub fn wrap(ptr: *mut AVSubtitleRect) -> Self { + pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self { Bitmap { ptr: ptr, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect { + self.ptr + } +} + +impl<'a> Bitmap<'a> { pub fn x(&self) -> usize { unsafe { - (*self.ptr).x as usize + (*self.as_ptr()).x as usize } } pub fn y(&self) -> usize { unsafe { - (*self.ptr).y as usize + (*self.as_ptr()).y as usize } } pub fn width(&self) -> u32 { unsafe { - (*self.ptr).w as u32 + (*self.as_ptr()).w as u32 } } pub fn height(&self) -> u32 { unsafe { - (*self.ptr).h as u32 + (*self.as_ptr()).h as u32 } } pub fn colors(&self) -> usize { unsafe { - (*self.ptr).nb_colors as usize + (*self.as_ptr()).nb_colors as usize } } + // XXX: verify safety pub fn picture(&self, format: format::Pixel) -> Picture<'a> { unsafe { - Picture::wrap(&mut (*self.ptr).pict, format, (*self.ptr).w as u32, (*self.ptr).h as u32) + Picture::wrap(&(*self.as_ptr()).pict as *const _ as *mut _, format, (*self.as_ptr()).w as u32, (*self.as_ptr()).h as u32) } } } pub struct Text<'a> { - pub ptr: *mut AVSubtitleRect, + ptr: *mut AVSubtitleRect, _marker: PhantomData<&'a ()>, } impl<'a> Text<'a> { - pub fn wrap(ptr: *mut AVSubtitleRect) -> Self { + pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self { Text { ptr: ptr, _marker: PhantomData } } + + pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect { + self.ptr + } } impl<'a> Deref for Text<'a> { @@ -207,21 +253,29 @@ impl<'a> Deref for Text<'a> { fn deref<'b>(&'b self) -> &'b str { unsafe { - from_utf8_unchecked(CStr::from_ptr((*self.ptr).text).to_bytes()) + from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes()) } } } pub struct Ass<'a> { - pub ptr: *mut AVSubtitleRect, + ptr: *mut AVSubtitleRect, _marker: PhantomData<&'a ()>, } impl<'a> Ass<'a> { - pub fn wrap(ptr: *mut AVSubtitleRect) -> Self { + pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self { Ass { ptr: ptr, _marker: PhantomData } } + + pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect { + self.ptr + } } impl<'a> Deref for Ass<'a> { @@ -229,7 +283,7 @@ impl<'a> Deref for Ass<'a> { fn deref<'b>(&'b self) -> &'b str { unsafe { - from_utf8_unchecked(CStr::from_ptr((*self.ptr).ass).to_bytes()) + from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes()) } } } diff --git a/src/device/extensions.rs b/src/device/extensions.rs index 438e832..e396509 100644 --- a/src/device/extensions.rs +++ b/src/device/extensions.rs @@ -9,7 +9,9 @@ use libc::c_int; impl Context { pub fn devices(&self) -> Result { - DeviceIter::new(self.ptr) + unsafe { + DeviceIter::wrap(self.as_ptr()) + } } } @@ -21,20 +23,20 @@ pub struct DeviceIter<'a> { } impl<'a> DeviceIter<'a> { - pub fn new(ctx: *mut AVFormatContext) -> Result { - unsafe { - let mut ptr: *mut AVDeviceInfoList = ptr::null_mut(); + pub unsafe fn wrap(ctx: *const AVFormatContext) -> Result { + let mut ptr: *mut AVDeviceInfoList = ptr::null_mut(); - match avdevice_list_devices(ctx, &mut ptr) { - n if n < 0 => - Err(Error::from(n)), + match avdevice_list_devices(ctx, &mut ptr) { + n if n < 0 => + Err(Error::from(n)), - _ => - Ok(DeviceIter { ptr: ptr, cur: 0, _marker: PhantomData }) - } + _ => + Ok(DeviceIter { ptr: ptr, cur: 0, _marker: PhantomData }) } } +} +impl<'a> DeviceIter<'a> { pub fn default(&self) -> usize { unsafe { (*self.ptr).default_device as usize diff --git a/src/device/mod.rs b/src/device/mod.rs index 5bc8ac1..5c349fd 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -15,19 +15,29 @@ pub struct Info<'a> { } impl<'a> Info<'a> { - pub fn wrap(ptr: *mut AVDeviceInfo) -> Self { + pub unsafe fn wrap(ptr: *mut AVDeviceInfo) -> Self { Info { ptr: ptr, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const AVDeviceInfo { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVDeviceInfo { + self.ptr + } +} + +impl<'a> Info<'a> { pub fn name(&self) -> &str { unsafe { - from_utf8_unchecked(CStr::from_ptr((*self.ptr).device_name).to_bytes()) + from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_name).to_bytes()) } } pub fn description(&self) -> &str { unsafe { - from_utf8_unchecked(CStr::from_ptr((*self.ptr).device_description).to_bytes()) + from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_description).to_bytes()) } } } diff --git a/src/format/context.rs b/src/format/context.rs index bb942b3..2bcaa5d 100644 --- a/src/format/context.rs +++ b/src/format/context.rs @@ -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 { 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 { 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 { 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 { 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 { 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 { } } -pub fn open_with(path: &Path, mut options: Dictionary) -> Result { +pub fn open_with(path: &Path, options: Dictionary) -> Result { 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 { 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 { } } -pub fn open_as_with(path: &Path, format: &Format, mut options: Dictionary) -> Result { +pub fn open_as_with(path: &Path, format: &Format, options: Dictionary) -> Result { 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 => { diff --git a/src/format/format.rs b/src/format/format.rs index bdf3eea..44832b7 100644 --- a/src/format/format.rs +++ b/src/format/format.rs @@ -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!() diff --git a/src/format/mod.rs b/src/format/mod.rs index 129ae70..17de0b7 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -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()); } } } diff --git a/src/format/stream/mod.rs b/src/format/stream/mod.rs index 4151858..f7c757a 100644 --- a/src/format/stream/mod.rs +++ b/src/format/stream/mod.rs @@ -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 } } } diff --git a/src/software/scaling/context.rs b/src/software/scaling/context.rs index 8cb61d9..2c722d9 100644 --- a/src/software/scaling/context.rs +++ b/src/software/scaling/context.rs @@ -2,17 +2,10 @@ use std::ptr; use libc::{c_int}; use ffi::*; -use ::{Error, Picture}; +use ::{Error, frame}; use ::util::format; use super::Flags; -pub struct Context { - pub ptr: *mut SwsContext, - - input: Definition, - output: Definition, -} - #[derive(Eq, PartialEq, Copy, Clone, Debug)] pub struct Definition { pub format: format::Pixel, @@ -20,15 +13,33 @@ pub struct Definition { pub height: u32, } +pub struct Context { + ptr: *mut SwsContext, + + input: Definition, + output: Definition, +} + +impl Context { + pub unsafe fn as_ptr(&self) -> *const SwsContext { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut SwsContext { + self.ptr + } +} + impl Context { pub fn get(src_format: format::Pixel, src_w: u32, src_h: u32, dst_format: format::Pixel, dst_w: u32, dst_h: u32, flags: Flags) -> Result { unsafe { - let ptr = sws_getContext(src_w as c_int, src_h as c_int, src_format.into(), - dst_w as c_int, dst_h as c_int, dst_format.into(), - flags.bits(), - ptr::null_mut(), ptr::null_mut(), ptr::null_mut()); + let ptr = sws_getContext( + src_w as c_int, src_h as c_int, src_format.into(), + dst_w as c_int, dst_h as c_int, dst_format.into(), + flags.bits(), + ptr::null_mut(), ptr::null_mut(), ptr::null_mut()); if ptr != ptr::null_mut() { Ok(Context { @@ -70,7 +81,7 @@ impl Context { }; unsafe { - self.ptr = sws_getCachedContext(self.ptr, + self.ptr = sws_getCachedContext(self.as_mut_ptr(), src_w as c_int, src_h as c_int, src_format.into(), dst_w as c_int, dst_h as c_int, dst_format.into(), flags.bits(), ptr::null_mut(), ptr::null_mut(), ptr::null()); @@ -85,7 +96,7 @@ impl Context { &self.output } - pub fn run(&self, input: &Picture, output: &mut Picture) -> Result<(), Error> { + pub fn run(&mut self, input: &frame::Video, output: &mut frame::Video) -> Result<(), Error> { if input.format() != self.input.format || input.width() != self.input.width || input.height() != self.input.height { return Err(Error::InputChanged); } @@ -95,10 +106,10 @@ impl Context { } unsafe { - sws_scale(self.ptr, - (*input.ptr).data.as_ptr() as *const *const _, (*input.ptr).linesize.as_ptr() as *const _, + sws_scale(self.as_mut_ptr(), + (*input.as_ptr()).data.as_ptr() as *const *const _, (*input.as_ptr()).linesize.as_ptr() as *const _, 0, self.output.height as c_int, - (*output.ptr).data.as_ptr() as *mut *mut _, (*output.ptr).linesize.as_ptr() as *mut _); + (*output.as_mut_ptr()).data.as_ptr() as *mut *mut _, (*output.as_mut_ptr()).linesize.as_ptr() as *mut _); } Ok(()) @@ -108,7 +119,7 @@ impl Context { impl Drop for Context { fn drop(&mut self) { unsafe { - sws_freeContext(self.ptr); + sws_freeContext(self.as_mut_ptr()); } } } diff --git a/src/software/scaling/filter.rs b/src/software/scaling/filter.rs index d391305..2be3a73 100644 --- a/src/software/scaling/filter.rs +++ b/src/software/scaling/filter.rs @@ -2,7 +2,17 @@ use ffi::*; use super::Vector; pub struct Filter { - pub ptr: *mut SwsFilter, + ptr: *mut SwsFilter, +} + +impl Filter { + pub unsafe fn as_ptr(&self) -> *const SwsFilter { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut SwsFilter { + self.ptr + } } impl Filter { @@ -24,49 +34,49 @@ impl Filter { pub fn luma_horizontal(&self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumH) + Vector::wrap((*self.as_ptr()).lumH) } } pub fn luma_horizontal_mut(&mut self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumH) + Vector::wrap((*self.as_mut_ptr()).lumH) } } pub fn luma_vertical(&self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_ptr()).lumV) } } pub fn luma_vertical_mut(&mut self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_mut_ptr()).lumV) } } pub fn chroma_horizontal(&self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_ptr()).lumV) } } pub fn chroma_horizontal_mut(&mut self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_mut_ptr()).lumV) } } pub fn chroma_vertical(&self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_ptr()).lumV) } } pub fn chroma_vertical_mut(&mut self) -> Vector { unsafe { - Vector::wrap((*self.ptr).lumV) + Vector::wrap((*self.as_mut_ptr()).lumV) } } } @@ -74,7 +84,7 @@ impl Filter { impl Drop for Filter { fn drop(&mut self) { unsafe { - sws_freeFilter(self.ptr); + sws_freeFilter(self.as_mut_ptr()); } } } diff --git a/src/software/scaling/vector.rs b/src/software/scaling/vector.rs index aea265d..631f9a2 100644 --- a/src/software/scaling/vector.rs +++ b/src/software/scaling/vector.rs @@ -5,17 +5,27 @@ use libc::{c_int, c_double}; use ffi::*; pub struct Vector<'a> { - pub ptr: *mut SwsVector, + ptr: *mut SwsVector, _own: bool, _marker: PhantomData<&'a ()>, } impl<'a> Vector<'a> { - pub fn wrap(ptr: *mut SwsVector) -> Self { + pub unsafe fn wrap(ptr: *mut SwsVector) -> Self { Vector { ptr: ptr, _own: false, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const SwsVector { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut SwsVector { + self.ptr + } +} + +impl<'a> Vector<'a> { pub fn new(length: usize) -> Self { unsafe { Vector { ptr: sws_allocVec(length as c_int), _own: true, _marker: PhantomData } @@ -42,49 +52,49 @@ impl<'a> Vector<'a> { pub fn scale(&mut self, scalar: f64) { unsafe { - sws_scaleVec(self.ptr, scalar as c_double); + sws_scaleVec(self.as_mut_ptr(), scalar as c_double); } } pub fn normalize(&mut self, height: f64) { unsafe { - sws_normalizeVec(self.ptr, height as c_double); + sws_normalizeVec(self.as_mut_ptr(), height as c_double); } } pub fn conv(&mut self, other: &Vector) { unsafe { - sws_convVec(self.ptr, other.ptr); + sws_convVec(self.as_mut_ptr(), other.as_ptr()); } } pub fn add(&mut self, other: &Vector) { unsafe { - sws_addVec(self.ptr, other.ptr); + sws_addVec(self.as_mut_ptr(), other.as_ptr()); } } pub fn sub(&mut self, other: &Vector) { unsafe { - sws_subVec(self.ptr, other.ptr); + sws_subVec(self.as_mut_ptr(), other.as_ptr()); } } pub fn shift(&mut self, value: usize) { unsafe { - sws_shiftVec(self.ptr, value as c_int); + sws_shiftVec(self.as_mut_ptr(), value as c_int); } } pub fn coefficients(&self) -> &[f64] { unsafe { - slice::from_raw_parts((*self.ptr).coeff, (*self.ptr).length as usize) + slice::from_raw_parts((*self.as_ptr()).coeff, (*self.as_ptr()).length as usize) } } pub fn coefficients_mut(&self) -> &[f64] { unsafe { - slice::from_raw_parts_mut((*self.ptr).coeff, (*self.ptr).length as usize) + slice::from_raw_parts_mut((*self.as_ptr()).coeff, (*self.as_ptr()).length as usize) } } } @@ -92,7 +102,7 @@ impl<'a> Vector<'a> { impl<'a> Clone for Vector<'a> { fn clone(&self) -> Self { unsafe { - Vector { ptr: sws_cloneVec(self.ptr), _own: true, _marker: PhantomData } + Vector { ptr: sws_cloneVec(self.as_ptr()), _own: true, _marker: PhantomData } } } } @@ -101,7 +111,7 @@ impl<'a> Drop for Vector<'a> { fn drop(&mut self) { unsafe { if self._own { - sws_freeVec(self.ptr); + sws_freeVec(self.as_mut_ptr()); } } } diff --git a/src/util/dictionary.rs b/src/util/dictionary.rs index 33c9e6b..912328f 100644 --- a/src/util/dictionary.rs +++ b/src/util/dictionary.rs @@ -4,33 +4,46 @@ use std::ptr; use ffi::*; pub struct Dictionary<'a> { - pub ptr: *mut AVDictionary, + ptr: *mut AVDictionary, _own: bool, _marker: PhantomData<&'a ()>, } impl<'a> Dictionary<'a> { - pub fn new() -> Self { - Dictionary { ptr: ptr::null_mut(), _own: true, _marker: PhantomData } - } - - pub fn wrap(ptr: *mut AVDictionary) -> Self { + pub unsafe fn wrap(ptr: *mut AVDictionary) -> Self { Dictionary { ptr: ptr, _own: false, _marker: PhantomData } } - pub fn take(&mut self) -> *mut AVDictionary { - self._own = false; + pub unsafe fn own(ptr: *mut AVDictionary) -> Self { + Dictionary { ptr: ptr, _own: true, _marker: PhantomData } + } + pub unsafe fn as_ptr(&self) -> *const AVDictionary { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVDictionary { self.ptr } + + pub unsafe fn take(mut self) -> *mut AVDictionary { + self._own = false; + self.ptr + } +} + +impl<'a> Dictionary<'a> { + pub fn new() -> Self { + Dictionary { ptr: ptr::null_mut(), _own: true, _marker: PhantomData } + } } impl<'a> Drop for Dictionary<'a> { fn drop(&mut self) { unsafe { - if self._own && self.ptr != ptr::null_mut() { - av_dict_free(&mut self.ptr); + if self._own && self.as_ptr() != ptr::null() { + av_dict_free(&mut self.as_mut_ptr()); } } } diff --git a/src/util/frame/audio.rs b/src/util/frame/audio.rs index e6955a8..0e5395c 100644 --- a/src/util/frame/audio.rs +++ b/src/util/frame/audio.rs @@ -11,22 +11,28 @@ use super::Frame; #[derive(PartialEq, Eq)] pub struct Audio(Frame); +impl Audio { + pub unsafe fn wrap(ptr: *mut AVFrame) -> Self { + Audio(Frame::wrap(ptr)) + } +} + impl Audio { pub fn empty() -> Self { unsafe { - Audio(Frame { ptr: av_frame_alloc() }) + Audio(Frame::empty()) } } - pub fn new(format: format::Sample, samples: usize, layout: ChannelLayout) -> Self { + pub fn new(format: format::Sample, length: usize, layout: ChannelLayout) -> Self { unsafe { let mut frame = Audio::empty(); frame.set_format(format); - frame.set_sample_number(samples); + frame.set_length(length); frame.set_channel_layout(layout); - av_frame_get_buffer(frame.ptr, 1); + av_frame_get_buffer(frame.as_mut_ptr(), 1); frame } @@ -34,75 +40,79 @@ impl Audio { pub fn format(&self) -> format::Sample { unsafe { - if (*self.ptr).format == -1 { + if (*self.as_ptr()).format == -1 { format::Sample::None } else { - format::Sample::from(mem::transmute::<_, AVSampleFormat>(((*self.ptr).format))) + format::Sample::from(mem::transmute::<_, AVSampleFormat>(((*self.as_ptr()).format))) } } } pub fn set_format(&mut self, value: format::Sample) { unsafe { - (*self.ptr).format = mem::transmute::(value.into()); + (*self.as_mut_ptr()).format = mem::transmute::(value.into()); } } pub fn channel_layout(&self) -> ChannelLayout { unsafe { - ChannelLayout::from_bits_truncate(av_frame_get_channel_layout(self.ptr) as c_ulonglong) + ChannelLayout::from_bits_truncate(av_frame_get_channel_layout(self.as_ptr()) as c_ulonglong) } } pub fn set_channel_layout(&mut self, value: ChannelLayout) { unsafe { - av_frame_set_channel_layout(self.ptr, value.bits() as int64_t); + av_frame_set_channel_layout(self.as_mut_ptr(), value.bits() as int64_t); } } pub fn channels(&self) -> u16 { unsafe { - av_frame_get_channels(self.ptr) as u16 + av_frame_get_channels(self.as_ptr()) as u16 } } pub fn set_channels(&mut self, value: u16) { unsafe { - av_frame_set_channels(self.ptr, value as c_int); + av_frame_set_channels(self.as_mut_ptr(), value as c_int); } } pub fn rate(&self) -> u32 { unsafe { - av_frame_get_sample_rate(self.ptr) as u32 + av_frame_get_sample_rate(self.as_ptr()) as u32 } } pub fn set_rate(&mut self, value: u32) { unsafe { - av_frame_set_sample_rate(self.ptr, value as c_int); + av_frame_set_sample_rate(self.as_mut_ptr(), value as c_int); } } - pub fn sample_number(&self) -> usize { + pub fn length(&self) -> usize { unsafe { - (*self.ptr).nb_samples as usize + (*self.as_ptr()).nb_samples as usize } } - pub fn set_sample_number(&mut self, value: usize) { + pub fn set_length(&mut self, value: usize) { unsafe { - (*self.ptr).nb_samples = value as c_int; + (*self.as_mut_ptr()).nb_samples = value as c_int; } } pub fn samples(&self) -> Samples { - Samples::wrap(self.ptr as *mut AVPicture, self.format(), self.rate(), self.sample_number(), self.channels(), self.channel_layout()) + unsafe { + Samples::wrap(self.as_ptr() as *mut AVPicture, self.format(), self.rate(), self.length(), self.channels(), self.channel_layout()) + } } pub fn samples_mut(&mut self) -> Samples { - Samples::wrap(self.ptr as *mut AVPicture, self.format(), self.rate(), self.sample_number(), self.channels(), self.channel_layout()) + unsafe { + Samples::wrap(self.as_ptr() as *mut AVPicture, self.format(), self.rate(), self.length(), self.channels(), self.channel_layout()) + } } } @@ -124,7 +134,7 @@ impl DerefMut for Audio { impl Clone for Audio { fn clone(&self) -> Self { - let mut cloned = Audio::new(self.format(), self.sample_number(), self.channel_layout()); + let mut cloned = Audio::new(self.format(), self.length(), self.channel_layout()); cloned.clone_from(self); cloned @@ -132,8 +142,8 @@ impl Clone for Audio { fn clone_from(&mut self, source: &Self) { unsafe { - av_frame_copy(self.ptr, source.ptr); - av_frame_copy_props(self.ptr, source.ptr); + av_frame_copy(self.as_mut_ptr(), source.as_ptr()); + av_frame_copy_props(self.as_mut_ptr(), source.as_ptr()); } } } diff --git a/src/util/frame/mod.rs b/src/util/frame/mod.rs index 26bbafd..67e0343 100644 --- a/src/util/frame/mod.rs +++ b/src/util/frame/mod.rs @@ -28,13 +28,33 @@ pub struct Packet { #[derive(PartialEq, Eq)] pub struct Frame { - pub ptr: *mut AVFrame, + ptr: *mut AVFrame, + + _own: bool, +} + +impl Frame { + pub unsafe fn wrap(ptr: *mut AVFrame) -> Self { + Frame { ptr: ptr, _own: false } + } + + pub unsafe fn empty() -> Self { + Frame { ptr: av_frame_alloc(), _own: true } + } + + pub unsafe fn as_ptr(&self) -> *const AVFrame { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrame { + self.ptr + } } impl Frame { pub fn is_key(&self) -> bool { unsafe { - (*self.ptr).key_frame == 1 + (*self.as_ptr()).key_frame == 1 } } @@ -45,25 +65,25 @@ impl Frame { pub fn packet(&self) -> Packet { unsafe { Packet { - duration: av_frame_get_pkt_duration(self.ptr) as i64, - position: av_frame_get_pkt_pos(self.ptr) as i64, - size: av_frame_get_pkt_size(self.ptr) as usize, + duration: av_frame_get_pkt_duration(self.as_ptr()) as i64, + position: av_frame_get_pkt_pos(self.as_ptr()) as i64, + size: av_frame_get_pkt_size(self.as_ptr()) as usize, - pts: (*self.ptr).pkt_pts, - dts: (*self.ptr).pkt_dts, + pts: (*self.as_ptr()).pkt_pts, + dts: (*self.as_ptr()).pkt_dts, } } } pub fn pts(&self) -> i64 { unsafe { - (*self.ptr).pts as i64 + (*self.as_ptr()).pts as i64 } } pub fn timestamp(&self) -> Option { unsafe { - match av_frame_get_best_effort_timestamp(self.ptr) { + match av_frame_get_best_effort_timestamp(self.as_ptr()) { AV_NOPTS_VALUE => None, t => Some(t as i64) } @@ -72,31 +92,31 @@ impl Frame { pub fn quality(&self) -> usize { unsafe { - (*self.ptr).quality as usize + (*self.as_ptr()).quality as usize } } pub fn flags(&self) -> Flags { unsafe { - Flags::from_bits_truncate((*self.ptr).flags) + Flags::from_bits_truncate((*self.as_ptr()).flags) } } pub fn metadata(&self) -> Dictionary { unsafe { - Dictionary::wrap(av_frame_get_metadata(self.ptr)) + Dictionary::wrap(av_frame_get_metadata(self.as_ptr())) } } - pub fn set_metadata(&mut self, mut value: Dictionary) { + pub fn set_metadata(&mut self, value: Dictionary) { unsafe { - av_frame_set_metadata(self.ptr, value.take()); + av_frame_set_metadata(self.as_mut_ptr(), value.take()); } } pub fn side_data(&self, kind: side_data::Type) -> Option { unsafe { - let ptr = av_frame_get_side_data(self.ptr, kind.into()); + let ptr = av_frame_get_side_data(self.as_ptr(), kind.into()); if ptr == ptr::null_mut() { None @@ -109,7 +129,7 @@ impl Frame { pub fn new_side_data(&mut self, kind: side_data::Type, size: usize) -> Option { unsafe { - let ptr = av_frame_new_side_data(self.ptr, kind.into(), size as c_int); + let ptr = av_frame_new_side_data(self.as_mut_ptr(), kind.into(), size as c_int); if ptr == ptr::null_mut() { None @@ -122,7 +142,7 @@ impl Frame { pub fn remove_side_data(&mut self, kind: side_data::Type) { unsafe { - av_frame_remove_side_data(self.ptr, kind.into()); + av_frame_remove_side_data(self.as_mut_ptr(), kind.into()); } } } @@ -132,7 +152,7 @@ unsafe impl Send for Frame { } impl Drop for Frame { fn drop(&mut self) { unsafe { - av_frame_free(&mut self.ptr); + av_frame_free(&mut self.as_mut_ptr()); } } } diff --git a/src/util/frame/side_data.rs b/src/util/frame/side_data.rs index 3305b94..8cc3722 100644 --- a/src/util/frame/side_data.rs +++ b/src/util/frame/side_data.rs @@ -67,31 +67,41 @@ impl Into for Type { } pub struct SideData<'a> { - pub ptr: *mut AVFrameSideData, + ptr: *mut AVFrameSideData, _marker: PhantomData<&'a Frame>, } impl<'a> SideData<'a> { - pub fn wrap(ptr: *mut AVFrameSideData) -> Self { + pub unsafe fn wrap(ptr: *mut AVFrameSideData) -> Self { SideData { ptr: ptr, _marker: PhantomData } } + pub unsafe fn as_ptr(&self) -> *const AVFrameSideData { + self.ptr as *const _ + } + + pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFrameSideData { + self.ptr + } +} + +impl<'a> SideData<'a> { pub fn kind(&self) -> Type { unsafe { - Type::from((*self.ptr).kind) + Type::from((*self.as_ptr()).kind) } } pub fn data(&self) -> &[u8] { unsafe { - slice::from_raw_parts((*self.ptr).data, (*self.ptr).size as usize) + slice::from_raw_parts((*self.as_ptr()).data, (*self.as_ptr()).size as usize) } } pub fn metadata(&self) -> Dictionary { unsafe { - Dictionary::wrap((*self.ptr).metadata) + Dictionary::wrap((*self.as_ptr()).metadata) } } } diff --git a/src/util/frame/video.rs b/src/util/frame/video.rs index 80660cd..88090ed 100644 --- a/src/util/frame/video.rs +++ b/src/util/frame/video.rs @@ -3,7 +3,7 @@ use std::mem; use std::ops::{Deref, DerefMut}; use ffi::*; -use ::{Rational, Picture}; +use ::Rational; use ::util::format; use ::util::chroma; use ::picture; @@ -13,10 +13,16 @@ use super::Frame; #[derive(PartialEq, Eq)] pub struct Video(Frame); +impl Video { + pub unsafe fn wrap(ptr: *mut AVFrame) -> Self { + Video(Frame::wrap(ptr)) + } +} + impl Video { pub fn empty() -> Self { unsafe { - Video(Frame { ptr: av_frame_alloc() }) + Video(Frame::empty()) } } @@ -28,160 +34,152 @@ impl Video { frame.set_width(width); frame.set_height(height); - av_frame_get_buffer(frame.ptr, 1); + av_frame_get_buffer(frame.as_mut_ptr(), 1); frame } } - pub fn picture(&self) -> Picture { - Picture::wrap(self.ptr as *mut AVPicture, self.format(), self.width(), self.height()) - } - - pub fn picture_mut(&mut self) -> Picture { - Picture::wrap(self.ptr as *mut AVPicture, self.format(), self.width(), self.height()) - } - pub fn format(&self) -> format::Pixel { unsafe { - if (*self.ptr).format == -1 { + if (*self.as_ptr()).format == -1 { format::Pixel::None } else { - format::Pixel::from(mem::transmute::<_, AVPixelFormat>(((*self.ptr).format))) + format::Pixel::from(mem::transmute::<_, AVPixelFormat>(((*self.as_ptr()).format))) } } } pub fn set_format(&mut self, value: format::Pixel) { unsafe { - (*self.ptr).format = mem::transmute::(value.into()); + (*self.as_mut_ptr()).format = mem::transmute::(value.into()); } } pub fn kind(&self) -> picture::Type { unsafe { - picture::Type::from((*self.ptr).pict_type) + picture::Type::from((*self.as_ptr()).pict_type) } } pub fn is_interlaced(&self) -> bool { unsafe { - (*self.ptr).interlaced_frame != 0 + (*self.as_ptr()).interlaced_frame != 0 } } pub fn is_top_first(&self) -> bool { unsafe { - (*self.ptr).top_field_first != 0 + (*self.as_ptr()).top_field_first != 0 } } pub fn has_palette_changed(&self) -> bool { unsafe { - (*self.ptr).palette_has_changed != 0 + (*self.as_ptr()).palette_has_changed != 0 } } pub fn width(&self) -> u32 { unsafe { - (*self.ptr).width as u32 + (*self.as_ptr()).width as u32 } } pub fn set_width(&mut self, value: u32) { unsafe { - (*self.ptr).width = value as c_int; + (*self.as_mut_ptr()).width = value as c_int; } } pub fn height(&self) -> u32 { unsafe { - (*self.ptr).height as u32 + (*self.as_ptr()).height as u32 } } pub fn set_height(&mut self, value: u32) { unsafe { - (*self.ptr).height = value as c_int; + (*self.as_mut_ptr()).height = value as c_int; } } pub fn color_space(&self) -> color::Space { unsafe { - color::Space::from(av_frame_get_colorspace(self.ptr)) + color::Space::from(av_frame_get_colorspace(self.as_ptr())) } } pub fn set_color_space(&mut self, value: color::Space) { unsafe { - av_frame_set_colorspace(self.ptr, value.into()); + av_frame_set_colorspace(self.as_mut_ptr(), value.into()); } } pub fn color_range(&self) -> color::Range { unsafe { - color::Range::from(av_frame_get_color_range(self.ptr)) + color::Range::from(av_frame_get_color_range(self.as_ptr())) } } pub fn set_color_range(&mut self, value: color::Range) { unsafe { - av_frame_set_color_range(self.ptr, value.into()); + av_frame_set_color_range(self.as_mut_ptr(), value.into()); } } pub fn color_primaries(&self) -> color::Primaries { unsafe { - color::Primaries::from((*self.ptr).color_primaries) + color::Primaries::from((*self.as_ptr()).color_primaries) } } pub fn set_color_primaries(&mut self, value: color::Primaries) { unsafe { - (*self.ptr).color_primaries = value.into(); + (*self.as_mut_ptr()).color_primaries = value.into(); } } pub fn color_transfer_characteristic(&self) -> color::TransferCharacteristic { unsafe { - color::TransferCharacteristic::from((*self.ptr).color_trc) + color::TransferCharacteristic::from((*self.as_ptr()).color_trc) } } pub fn set_color_transfer_characteristic(&mut self, value: color::TransferCharacteristic) { unsafe { - (*self.ptr).color_trc = value.into(); + (*self.as_mut_ptr()).color_trc = value.into(); } } pub fn chroma_location(&self) -> chroma::Location { unsafe { - chroma::Location::from((*self.ptr).chroma_location) + chroma::Location::from((*self.as_ptr()).chroma_location) } } pub fn aspect_ratio(&self) -> Rational { unsafe { - Rational((*self.ptr).sample_aspect_ratio) + Rational((*self.as_ptr()).sample_aspect_ratio) } } pub fn coded_number(&self) -> usize { unsafe { - (*self.ptr).coded_picture_number as usize + (*self.as_ptr()).coded_picture_number as usize } } pub fn display_number(&self) -> usize { unsafe { - (*self.ptr).display_picture_number as usize + (*self.as_ptr()).display_picture_number as usize } } pub fn repeat(&self) -> f64 { unsafe { - (*self.ptr).repeat_pict as f64 + (*self.as_ptr()).repeat_pict as f64 } } } @@ -212,8 +210,8 @@ impl Clone for Video { fn clone_from(&mut self, source: &Self) { unsafe { - av_frame_copy(self.ptr, source.ptr); - av_frame_copy_props(self.ptr, source.ptr); + av_frame_copy(self.as_mut_ptr(), source.as_ptr()); + av_frame_copy_props(self.as_mut_ptr(), source.as_ptr()); } } }