format/stream: avoid unsoundness splitting Stream into StreamMut
This commit is contained in:
parent
d1fa9bd864
commit
a282d85662
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use ffi::*;
|
use ffi::*;
|
||||||
use ::{Error, Codec, Stream, Packet, Dictionary};
|
use ::{Error, Codec, Stream, StreamMut, Packet, Dictionary};
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
ptr: *mut AVFormatContext,
|
ptr: *mut AVFormatContext,
|
||||||
@ -49,12 +49,40 @@ impl Context {
|
|||||||
!self._input
|
!self._input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stream(&self, index: usize) -> Option<Stream> {
|
||||||
|
unsafe {
|
||||||
|
if index >= (*self.as_ptr()).nb_streams as usize {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(Stream::wrap(*(*self.ptr).streams.offset(index as isize)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stream_mut(&mut self, index: usize) -> Option<StreamMut> {
|
||||||
|
unsafe {
|
||||||
|
if index >= (*self.as_ptr()).nb_streams as usize {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(StreamMut::wrap(*(*self.ptr).streams.offset(index as isize)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn streams(&self) -> StreamIter {
|
pub fn streams(&self) -> StreamIter {
|
||||||
unsafe {
|
unsafe {
|
||||||
StreamIter::new(self.as_ptr())
|
StreamIter::new(self.as_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn streams_mut(&mut self) -> StreamIterMut {
|
||||||
|
unsafe {
|
||||||
|
StreamIterMut::new(self.as_mut_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn metadata(&self) -> Dictionary {
|
pub fn metadata(&self) -> Dictionary {
|
||||||
unsafe {
|
unsafe {
|
||||||
Dictionary::wrap((*self.as_ptr()).metadata)
|
Dictionary::wrap((*self.as_ptr()).metadata)
|
||||||
@ -190,6 +218,35 @@ impl<'a> Iterator for StreamIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct StreamIterMut<'a> {
|
||||||
|
ptr: *const AVFormatContext,
|
||||||
|
cur: c_uint,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a Context>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> StreamIterMut<'a> {
|
||||||
|
pub fn new(ptr: *mut AVFormatContext) -> Self {
|
||||||
|
StreamIterMut { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for StreamIterMut<'a> {
|
||||||
|
type Item = StreamMut<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||||
|
unsafe {
|
||||||
|
if self.cur >= (*self.ptr).nb_streams {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.cur += 1;
|
||||||
|
Some(StreamMut::wrap(*(*self.ptr).streams.offset((self.cur - 1) as isize)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PacketIter<'a> {
|
pub struct PacketIter<'a> {
|
||||||
context: &'a mut Context,
|
context: &'a mut Context,
|
||||||
}
|
}
|
||||||
|
@ -1,128 +1,8 @@
|
|||||||
pub mod disposition;
|
pub mod disposition;
|
||||||
pub use self::disposition::Disposition;
|
pub use self::disposition::Disposition;
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
mod stream;
|
||||||
|
pub use self::stream::Stream;
|
||||||
|
|
||||||
use libc::c_int;
|
mod stream_mut;
|
||||||
use ffi::*;
|
pub use self::stream_mut::StreamMut;
|
||||||
use ::format;
|
|
||||||
use ::codec::{self, packet};
|
|
||||||
use ::{Rational, Discard};
|
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
|
||||||
pub struct Stream<'a> {
|
|
||||||
ptr: *mut AVStream,
|
|
||||||
|
|
||||||
_marker: PhantomData<&'a format::Context>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Stream<'a> {
|
|
||||||
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.as_ptr()).codec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn index(&self) -> usize {
|
|
||||||
unsafe {
|
|
||||||
(*self.as_ptr()).index as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn time_base(&self) -> Rational {
|
|
||||||
unsafe {
|
|
||||||
Rational::from((*self.as_ptr()).time_base)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start_time(&self) -> i64 {
|
|
||||||
unsafe {
|
|
||||||
(*self.as_ptr()).start_time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn duration(&self) -> i64 {
|
|
||||||
unsafe {
|
|
||||||
(*self.as_ptr()).duration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frames(&self) -> i64 {
|
|
||||||
unsafe {
|
|
||||||
(*self.as_ptr()).nb_frames
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn disposition(&self) -> Disposition {
|
|
||||||
unsafe {
|
|
||||||
Disposition::from_bits_truncate((*self.as_ptr()).disposition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn discard(&self) -> Discard {
|
|
||||||
unsafe {
|
|
||||||
Discard::from((*self.as_ptr()).discard)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn side_data(&self) -> SideDataIter {
|
|
||||||
unsafe {
|
|
||||||
SideDataIter::new(self.as_ptr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_rate(&self) -> Rational {
|
|
||||||
unsafe {
|
|
||||||
Rational::from(av_stream_get_r_frame_rate(self.as_ptr()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_frame_rate(&mut self, value: Rational) {
|
|
||||||
unsafe {
|
|
||||||
av_stream_set_r_frame_rate(self.as_mut_ptr(), value.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SideDataIter<'a> {
|
|
||||||
ptr: *const AVStream,
|
|
||||||
cur: c_int,
|
|
||||||
|
|
||||||
_marker: PhantomData<&'a Stream<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SideDataIter<'a> {
|
|
||||||
pub fn new(ptr: *const AVStream) -> Self {
|
|
||||||
SideDataIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for SideDataIter<'a> {
|
|
||||||
type Item = packet::SideData<'a>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
|
||||||
unsafe {
|
|
||||||
if self.cur >= (*self.ptr).nb_side_data {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.cur += 1;
|
|
||||||
Some(packet::SideData::wrap((*self.ptr).side_data.offset((self.cur - 1) as isize)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
116
src/format/stream/stream.rs
Normal file
116
src/format/stream/stream.rs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use libc::c_int;
|
||||||
|
use ffi::*;
|
||||||
|
use ::format;
|
||||||
|
use ::codec::{self, packet};
|
||||||
|
use ::{Rational, Discard};
|
||||||
|
use super::Disposition;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub struct Stream<'a> {
|
||||||
|
ptr: *mut AVStream,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a format::Context>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Stream<'a> {
|
||||||
|
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 _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Stream<'a> {
|
||||||
|
pub fn codec(&self) -> codec::Context {
|
||||||
|
unsafe {
|
||||||
|
codec::Context::wrap((*self.as_ptr()).codec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*self.as_ptr()).index as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn time_base(&self) -> Rational {
|
||||||
|
unsafe {
|
||||||
|
Rational::from((*self.as_ptr()).time_base)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_time(&self) -> i64 {
|
||||||
|
unsafe {
|
||||||
|
(*self.as_ptr()).start_time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn duration(&self) -> i64 {
|
||||||
|
unsafe {
|
||||||
|
(*self.as_ptr()).duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frames(&self) -> i64 {
|
||||||
|
unsafe {
|
||||||
|
(*self.as_ptr()).nb_frames
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disposition(&self) -> Disposition {
|
||||||
|
unsafe {
|
||||||
|
Disposition::from_bits_truncate((*self.as_ptr()).disposition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn discard(&self) -> Discard {
|
||||||
|
unsafe {
|
||||||
|
Discard::from((*self.as_ptr()).discard)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn side_data(&self) -> SideDataIter {
|
||||||
|
unsafe {
|
||||||
|
SideDataIter::new(self.as_ptr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frame_rate(&self) -> Rational {
|
||||||
|
unsafe {
|
||||||
|
Rational::from(av_stream_get_r_frame_rate(self.as_ptr()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SideDataIter<'a> {
|
||||||
|
ptr: *const AVStream,
|
||||||
|
cur: c_int,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a Stream<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SideDataIter<'a> {
|
||||||
|
pub fn new(ptr: *const AVStream) -> Self {
|
||||||
|
SideDataIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for SideDataIter<'a> {
|
||||||
|
type Item = packet::SideData<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||||
|
unsafe {
|
||||||
|
if self.cur >= (*self.ptr).nb_side_data {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.cur += 1;
|
||||||
|
Some(packet::SideData::wrap((*self.ptr).side_data.offset((self.cur - 1) as isize)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
src/format/stream/stream_mut.rs
Normal file
41
src/format/stream/stream_mut.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use ::Rational;
|
||||||
|
use super::Stream;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub struct StreamMut<'a> {
|
||||||
|
ptr: *mut AVStream,
|
||||||
|
imm: Stream<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> StreamMut<'a> {
|
||||||
|
pub unsafe fn wrap(ptr: *mut AVStream) -> Self {
|
||||||
|
StreamMut { ptr: ptr, imm: Stream::wrap(ptr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
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> StreamMut<'a> {
|
||||||
|
pub fn set_frame_rate(&mut self, value: Rational) {
|
||||||
|
unsafe {
|
||||||
|
av_stream_set_r_frame_rate(self.as_mut_ptr(), value.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deref for StreamMut<'a> {
|
||||||
|
type Target = Stream<'a>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.imm
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ pub mod format;
|
|||||||
#[cfg(feature = "format")]
|
#[cfg(feature = "format")]
|
||||||
pub use format::format::Format;
|
pub use format::format::Format;
|
||||||
#[cfg(feature = "format")]
|
#[cfg(feature = "format")]
|
||||||
pub use format::stream::Stream;
|
pub use format::stream::{Stream, StreamMut};
|
||||||
|
|
||||||
#[cfg(feature = "codec")]
|
#[cfg(feature = "codec")]
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user