diff --git a/Cargo.toml b/Cargo.toml index 4638903..d365f6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,11 +15,11 @@ rust-version = "1.70.0" [dependencies] rusty_ffmpeg = "0.14.0" -libc = "0.2" paste = "1.0" thiserror = "1.0" [dev-dependencies] +libc = "0.2" anyhow = "1.0.57" cstr = "0.2.11" once_cell = "1.12.0" diff --git a/src/avcodec/codec.rs b/src/avcodec/codec.rs index c22d300..6b1de33 100644 --- a/src/avcodec/codec.rs +++ b/src/avcodec/codec.rs @@ -79,26 +79,35 @@ impl Iterator for AVCodecIter { } impl<'codec> AVCodec { - /// Convenient function for probing a pointer until met specific memory - /// pattern. - fn probe_len(mut ptr: *const T, tail: T) -> usize { + /// Probing specific memory pattern and return the offset. + /// + /// # Safety + /// ptr needs to be terminated by tail + unsafe fn probe_len(mut ptr: *const T, tail: T) -> usize { for len in 0.. { - if unsafe { libc::memcmp(ptr as _, &tail as *const _ as _, mem::size_of::()) } == 0 { + let left = ptr as *const u8; + let left = unsafe { slice::from_raw_parts(left, mem::size_of::()) }; + let right = &tail as *const _ as *const u8; + let right = unsafe { slice::from_raw_parts(right, mem::size_of::()) }; + if left == right { return len; } unsafe { ptr = ptr.add(1); } } - unreachable!() + usize::MAX } - /// Convenient function for building a memory slice. - fn build_array<'a, T>(ptr: *const T, tail: T) -> Option<&'a [T]> { + /// Building a memory slice ends begin with `ptr` and ends with given `tail`. + /// + /// # Safety + /// ptr needs to be terminated by tail + unsafe fn build_array<'a, T>(ptr: *const T, tail: T) -> Option<&'a [T]> { if ptr.is_null() { None } else { - let len = Self::probe_len(ptr, tail); + let len = unsafe { Self::probe_len(ptr, tail) }; Some(unsafe { slice::from_raw_parts(ptr, len) }) } } @@ -106,25 +115,25 @@ impl<'codec> AVCodec { /// Return supported framerates of this [`AVCodec`]. pub fn supported_framerates(&'codec self) -> Option<&'codec [AVRational]> { // terminates with AVRational{0, 0} - Self::build_array(self.supported_framerates, AVRational { den: 0, num: 0 }) + unsafe { Self::build_array(self.supported_framerates, AVRational { den: 0, num: 0 }) } } /// Return supported pix_fmts of this [`AVCodec`]. pub fn pix_fmts(&'codec self) -> Option<&'codec [AVPixelFormat]> { // terminates with -1 - Self::build_array(self.pix_fmts, -1) + unsafe { Self::build_array(self.pix_fmts, -1) } } /// Return supported samplerates of this [`AVCodec`]. pub fn supported_samplerates(&'codec self) -> Option<&'codec [i32]> { // terminates with 0 - Self::build_array(self.supported_samplerates, 0) + unsafe { Self::build_array(self.supported_samplerates, 0) } } /// Return supported sample_fmts of this [`AVCodec`]. pub fn sample_fmts(&'codec self) -> Option<&'codec [ffi::AVSampleFormat]> { // terminates with -1 - Self::build_array(self.sample_fmts, -1) + unsafe { Self::build_array(self.sample_fmts, -1) } } } diff --git a/src/avutil/buffer.rs b/src/avutil/buffer.rs index a121ec4..65e3744 100644 --- a/src/avutil/buffer.rs +++ b/src/avutil/buffer.rs @@ -2,7 +2,7 @@ use crate::{ ffi, shared::{PointerUpgrade, RetUpgrade}, }; -use libc::c_int; +use std::os::raw::c_int; wrap!(AVBufferRef: ffi::AVBufferRef); diff --git a/src/avutil/channel_layout.rs b/src/avutil/channel_layout.rs index 745b709..eb06ff8 100644 --- a/src/avutil/channel_layout.rs +++ b/src/avutil/channel_layout.rs @@ -3,10 +3,10 @@ use crate::{ ffi, shared::{PointerUpgrade, RetUpgrade}, }; -use libc::c_void; use std::{ ffi::{CStr, CString}, mem::MaybeUninit, + os::raw::c_void, ptr::NonNull, }; diff --git a/src/avutil/dict.rs b/src/avutil/dict.rs index ce4a6f9..eda6f9c 100644 --- a/src/avutil/dict.rs +++ b/src/avutil/dict.rs @@ -2,6 +2,7 @@ use crate::{error::Result, ffi, shared::*}; use std::{ ffi::{CStr, CString}, + os::raw::c_void, ptr::{self, NonNull}, }; @@ -120,7 +121,7 @@ impl AVDictionary { .upgrade()?; let result = unsafe { CStr::from_ptr(s).to_owned() }; unsafe { - ffi::av_freep(&mut s as *mut _ as *mut libc::c_void); + ffi::av_freep(&mut s as *mut _ as *mut c_void); } Ok(result) } diff --git a/src/avutil/frame.rs b/src/avutil/frame.rs index 3b0d918..ade4017 100644 --- a/src/avutil/frame.rs +++ b/src/avutil/frame.rs @@ -5,7 +5,7 @@ use crate::{ shared::*, }; -use std::{fmt, mem::size_of, ptr::NonNull, slice}; +use std::{fmt, mem::size_of, os::raw::c_int, ptr::NonNull, slice}; wrap!(AVFrame: ffi::AVFrame); settable!(AVFrame { @@ -93,7 +93,7 @@ impl AVFrame { unsafe { &mut self.deref_mut().data } } - pub fn linesize_mut(&mut self) -> &mut [libc::c_int; 8] { + pub fn linesize_mut(&mut self) -> &mut [c_int; 8] { unsafe { &mut self.deref_mut().linesize } } diff --git a/src/avutil/rational.rs b/src/avutil/rational.rs index a9bd295..4c6df4b 100644 --- a/src/avutil/rational.rs +++ b/src/avutil/rational.rs @@ -1,3 +1,5 @@ +use std::os::raw::c_int; + use crate::ffi; pub use ffi::AVRational; @@ -15,7 +17,7 @@ pub use ffi::{av_cmp_q, av_inv_q, av_make_q, av_q2d}; /// /// `d` - double to convert /// `max` - Maximum allowed numerator and denominator -pub fn av_d2q(d: f64, max: libc::c_int) -> AVRational { +pub fn av_d2q(d: f64, max: c_int) -> AVRational { unsafe { ffi::av_d2q(d, max) } } @@ -49,7 +51,7 @@ pub fn av_sub_q(b: AVRational, c: AVRational) -> AVRational { /// Return `1` if `q1` is nearer to `q` than `q2`. /// `-1` if `q2` is nearer to `q` than `q1`. /// `0` if they have the same distance. -pub fn av_nearer_q(q: AVRational, q1: AVRational, q2: AVRational) -> libc::c_int { +pub fn av_nearer_q(q: AVRational, q1: AVRational, q2: AVRational) -> c_int { unsafe { ffi::av_nearer_q(q, q1, q2) } } @@ -63,7 +65,7 @@ pub fn av_q2intfloat(q: AVRational) -> u32 { #[inline] /// Return the best rational so that a and b are multiple of it. If the /// resulting denominator is larger than max_den, return def. -pub fn av_gcd_q(a: AVRational, b: AVRational, max_den: libc::c_int, def: AVRational) -> AVRational { +pub fn av_gcd_q(a: AVRational, b: AVRational, max_den: c_int, def: AVRational) -> AVRational { unsafe { ffi::av_gcd_q(a, b, max_den, def) } } diff --git a/src/error.rs b/src/error.rs index 7cffa5a..0217b65 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,8 +1,8 @@ //! Errors of the rsmpeg. -use libc::c_int; use std::{ cmp::{Eq, PartialEq}, num::TryFromIntError, + os::raw::c_int, }; use thiserror::Error; diff --git a/src/shared/mod.rs b/src/shared/mod.rs index c703864..a1d3edd 100644 --- a/src/shared/mod.rs +++ b/src/shared/mod.rs @@ -1,8 +1,7 @@ //! Internal shared convenient things. use crate::error::{Result, Ret, RsmpegError}; -use libc::c_int; use rusty_ffmpeg::ffi; -use std::{ops::Deref, ptr::NonNull}; +use std::{ops::Deref, os::raw::c_int, ptr::NonNull}; /// Triage a pointer to Some(non-null) or None pub trait PointerUpgrade: Sized {