*: 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,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<Opened, Error> {
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)
}
}
}

View File

@ -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<Opened, Error> {
pub fn open(mut self, codec: &Codec) -> Result<Opened, Error> {
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<Opened, Error> {
pub fn open_with(mut self, codec: &Codec, options: Dictionary) -> Result<Opened, Error> {
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<Codec> {
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());
}
}
}

View File

@ -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<usize> {
unsafe {
match (*self.ptr).timecode_frame_start {
match (*self.as_ptr()).timecode_frame_start {
-1 => None,
n => Some(n as usize)
}

View File

@ -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<Rational> {
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)
}
}
}

View File

@ -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)
}

View File

@ -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();
}
}

View File

@ -10,11 +10,11 @@ use ::frame;
pub struct Audio(pub Encoder);
impl Audio {
pub fn encode(&self, frame: &frame::Audio, out: &mut Packet) -> Result<bool, Error> {
pub fn encode(&mut self, frame: &frame::Audio, out: &mut Packet) -> Result<bool, Error> {
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)
}

View File

@ -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<usize>) {
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<Rational>) {
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;
}
}
}

View File

@ -9,9 +9,9 @@ use ::Error;
pub struct Subtitle(pub Encoder);
impl Subtitle {
pub fn encode(&self, subtitle: &::Subtitle, out: &mut [u8]) -> Result<bool, Error> {
pub fn encode(&mut self, subtitle: &::Subtitle, out: &mut [u8]) -> Result<bool, Error> {
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)
}

View File

@ -11,11 +11,11 @@ use ::format;
pub struct Video(pub Encoder);
impl Video {
pub fn encode(&self, frame: &frame::Video, out: &mut Packet) -> Result<bool, Error> {
pub fn encode(&mut self, frame: &frame::Video, out: &mut Packet) -> Result<bool, Error> {
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<usize>) {
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<usize>) {
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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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)
}
}
}

View File

@ -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<usize, Error> {
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<usize, Error> {
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<Self, Error> {
pub fn new(format: format::Pixel, width: u32, height: u32) -> Result<Self, Error> {
unsafe {
let ptr = av_malloc(mem::size_of::<AVPicture>() 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<usize, Error> {
pub fn layout_as(&self, format: format::Pixel, width: u32, height: u32, out: &mut [u8]) -> Result<usize, Error> {
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<T: Reflect + 'static>(&self) -> Result<Vec<&[T]>, Error> {
if !valid::<T>(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::<T>()));
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<T: Reflect + 'static>(&mut self) -> Result<Vec<&mut [u8]>, Error> {
if !valid::<T>(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::<T>()));
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<T: Reflect + 'static>(format: Pixel) -> bool {
if mem::size_of::<T>() == 1 {
return true;
}
match format {
Pixel::None =>
false,
Pixel::RGB24 | Pixel::BGR24 =>
mem::size_of::<T>() == 3,
Pixel::ARGB | Pixel::RGBA | Pixel::ABGR | Pixel::BGRA =>
mem::size_of::<T>() == 4 * 4,
Pixel::ZRGB | Pixel::RGBZ | Pixel::ZBGR | Pixel::BGRZ =>
mem::size_of::<T>() == 4 * 4,
_ =>
false
}
}

View File

@ -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<AVSubtitleType> 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())
}
}
}