codec/context: make destructors safe
This commit is contained in:
parent
19548810dd
commit
9736980b02
@ -1,4 +1,5 @@
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use libc::c_int;
|
||||
use ffi::*;
|
||||
@ -10,15 +11,14 @@ use super::encoder::Encoder;
|
||||
|
||||
pub struct Context {
|
||||
ptr: *mut AVCodecContext,
|
||||
|
||||
_own: bool,
|
||||
owner: Option<Rc<Drop>>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Context { }
|
||||
|
||||
impl Context {
|
||||
pub unsafe fn wrap(ptr: *mut AVCodecContext) -> Self {
|
||||
Context { ptr: ptr, _own: false }
|
||||
pub unsafe fn wrap(ptr: *mut AVCodecContext, owner: Option<Rc<Drop>>) -> Self {
|
||||
Context { ptr: ptr, owner: owner }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVCodecContext {
|
||||
@ -33,7 +33,7 @@ impl Context {
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
unsafe {
|
||||
Context { ptr: avcodec_alloc_context3(ptr::null()), _own: true }
|
||||
Context { ptr: avcodec_alloc_context3(ptr::null()), owner: None }
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,8 +107,8 @@ impl Context {
|
||||
|
||||
impl Drop for Context {
|
||||
fn drop(&mut self) {
|
||||
if self._own {
|
||||
unsafe {
|
||||
if self.owner.is_none() {
|
||||
avcodec_free_context(&mut self.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
pub mod video;
|
||||
pub use self::video::Video;
|
||||
pub use self::video::Encoder as Video;
|
||||
|
||||
pub mod audio;
|
||||
pub use self::audio::Audio;
|
||||
pub use self::audio::Encoder as Audio;
|
||||
|
||||
pub mod subtitle;
|
||||
pub use self::subtitle::Subtitle;
|
||||
pub use self::subtitle::Encoder as Subtitle;
|
||||
|
||||
pub mod motion_estimation;
|
||||
pub use self::motion_estimation::MotionEstimation;
|
||||
@ -31,27 +31,27 @@ use ::media;
|
||||
pub struct Encoder(pub Context);
|
||||
|
||||
impl Encoder {
|
||||
pub fn video(self) -> Result<Video, Error> {
|
||||
pub fn video(self) -> Result<video::Video, Error> {
|
||||
if self.medium() == media::Type::Video {
|
||||
Ok(Video(self))
|
||||
Ok(video::Video(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio(self) -> Result<Audio, Error> {
|
||||
pub fn audio(self) -> Result<audio::Audio, Error> {
|
||||
if self.medium() == media::Type::Audio {
|
||||
Ok(Audio(self))
|
||||
Ok(audio::Audio(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtitle(self) -> Result<Subtitle, Error> {
|
||||
pub fn subtitle(self) -> Result<subtitle::Subtitle, Error> {
|
||||
if self.medium() == media::Type::Subtitle {
|
||||
Ok(Subtitle(self))
|
||||
Ok(subtitle::Subtitle(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
|
@ -87,10 +87,6 @@ impl<'a> SideData<'a> {
|
||||
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> {
|
||||
|
@ -1,19 +1,22 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
|
||||
use ffi::*;
|
||||
use libc::{c_int, c_uint};
|
||||
use ::{media, Stream, StreamMut, DictionaryRef};
|
||||
use super::destructor::{self, Destructor};
|
||||
|
||||
pub struct Context {
|
||||
ptr: *mut AVFormatContext,
|
||||
dtor: Rc<Destructor>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Context { }
|
||||
|
||||
impl Context {
|
||||
pub unsafe fn wrap(ptr: *mut AVFormatContext) -> Self {
|
||||
Context { ptr: ptr }
|
||||
pub unsafe fn wrap(ptr: *mut AVFormatContext, mode: destructor::Mode) -> Self {
|
||||
Context { ptr: ptr, dtor: Rc::new(Destructor::new(ptr, mode)) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
|
||||
@ -23,6 +26,10 @@ impl Context {
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFormatContext {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
pub unsafe fn destructor(&self) -> Rc<Destructor> {
|
||||
self.dtor.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
@ -32,7 +39,7 @@ impl Context {
|
||||
None
|
||||
}
|
||||
else {
|
||||
Some(Stream::wrap(*(*self.as_ptr()).streams.offset(index as isize)))
|
||||
Some(Stream::wrap(self, index))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,21 +50,17 @@ impl Context {
|
||||
None
|
||||
}
|
||||
else {
|
||||
Some(StreamMut::wrap(*(*self.as_mut_ptr()).streams.offset(index as isize)))
|
||||
Some(StreamMut::wrap(self, index))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn streams(&self) -> StreamIter {
|
||||
unsafe {
|
||||
StreamIter::new(self.as_ptr())
|
||||
}
|
||||
StreamIter::new(self)
|
||||
}
|
||||
|
||||
pub fn streams_mut(&mut self) -> StreamIterMut {
|
||||
unsafe {
|
||||
StreamIterMut::new(self.as_mut_ptr())
|
||||
}
|
||||
StreamIterMut::new(self)
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> DictionaryRef {
|
||||
@ -68,23 +71,19 @@ impl Context {
|
||||
}
|
||||
|
||||
pub struct Best<'a> {
|
||||
ptr: *const AVFormatContext,
|
||||
context: &'a Context,
|
||||
|
||||
wanted: i32,
|
||||
related: i32,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Best<'a> {
|
||||
pub unsafe fn new<'b>(ptr: *const AVFormatContext) -> Best<'b> {
|
||||
pub unsafe fn new<'b, 'c: 'b>(context: &'c Context) -> Best<'b> {
|
||||
Best {
|
||||
ptr: ptr,
|
||||
context: context,
|
||||
|
||||
wanted: -1,
|
||||
related: -1,
|
||||
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,12 +100,12 @@ impl<'a> Best<'a> {
|
||||
pub fn best<'b>(self, kind: media::Type) -> Option<Stream<'b>> where 'a: 'b {
|
||||
unsafe {
|
||||
let mut decoder = ptr::null_mut();
|
||||
let index = av_find_best_stream(self.ptr,
|
||||
let index = av_find_best_stream(self.context.as_ptr(),
|
||||
kind.into(), self.wanted as c_int, self.related as c_int,
|
||||
&mut decoder, 0);
|
||||
|
||||
if index >= 0 && !decoder.is_null() {
|
||||
Some(Stream::wrap(*(*self.ptr).streams.offset(index as isize)))
|
||||
Some(Stream::wrap(self.context, index as usize))
|
||||
}
|
||||
else {
|
||||
None
|
||||
@ -116,34 +115,32 @@ impl<'a> Best<'a> {
|
||||
}
|
||||
|
||||
pub struct StreamIter<'a> {
|
||||
ptr: *const AVFormatContext,
|
||||
cur: c_uint,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
context: &'a Context,
|
||||
current: c_uint,
|
||||
}
|
||||
|
||||
impl<'a> StreamIter<'a> {
|
||||
pub fn new(ptr: *const AVFormatContext) -> Self {
|
||||
StreamIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||
pub fn new<'s, 'c: 's>(context: &'c Context) -> StreamIter<'s> {
|
||||
StreamIter { context: context, current: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StreamIter<'a> {
|
||||
pub fn wanted<'b: 'a, 'c: 'a>(&'a self, stream: &'b Stream) -> Best<'a> {
|
||||
pub fn wanted<'b, 'c>(&self, stream: &'b Stream) -> Best<'c> where 'a: 'b, 'a: 'c {
|
||||
unsafe {
|
||||
Best::new(self.ptr).wanted(stream)
|
||||
Best::new(self.context).wanted(stream)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn related<'b: 'a>(&'a self, stream: &'b Stream) -> Best<'a> {
|
||||
pub fn related<'b, 'c>(&self, stream: &'b Stream) -> Best<'c> where 'a: 'b, 'a: 'c {
|
||||
unsafe {
|
||||
Best::new(self.ptr).related(stream)
|
||||
Best::new(self.context).related(stream)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn best<'b: 'a>(&'a self, kind: media::Type) -> Option<Stream<'b>> {
|
||||
pub fn best<'b>(&self, kind: media::Type) -> Option<Stream<'b>> where 'a: 'b {
|
||||
unsafe {
|
||||
Best::new(self.ptr).best(kind)
|
||||
Best::new(self.context).best(kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,19 +150,21 @@ impl<'a> Iterator for StreamIter<'a> {
|
||||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
if self.cur >= (*self.ptr).nb_streams {
|
||||
None
|
||||
}
|
||||
else {
|
||||
self.cur += 1;
|
||||
Some(Stream::wrap(*(*self.ptr).streams.offset((self.cur - 1) as isize)))
|
||||
if self.current >= (*self.context.as_ptr()).nb_streams {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.current += 1;
|
||||
|
||||
Some(Stream::wrap(self.context, (self.current - 1) as usize))
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
unsafe {
|
||||
((*self.ptr).nb_streams as usize, Some((*self.ptr).nb_streams as usize))
|
||||
let length = (*self.context.as_ptr()).nb_streams as usize;
|
||||
|
||||
(length - self.current as usize, Some(length - self.current as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,15 +172,13 @@ impl<'a> Iterator for StreamIter<'a> {
|
||||
impl<'a> ExactSizeIterator for StreamIter<'a> { }
|
||||
|
||||
pub struct StreamIterMut<'a> {
|
||||
ptr: *const AVFormatContext,
|
||||
cur: c_uint,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
context: &'a mut Context,
|
||||
current: c_uint,
|
||||
}
|
||||
|
||||
impl<'a> StreamIterMut<'a> {
|
||||
pub fn new(ptr: *mut AVFormatContext) -> Self {
|
||||
StreamIterMut { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||
pub fn new<'s, 'c: 's>(context: &'c mut Context) -> StreamIterMut<'s> {
|
||||
StreamIterMut { context: context, current: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,19 +187,21 @@ impl<'a> Iterator for StreamIterMut<'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)))
|
||||
if self.current >= (*self.context.as_ptr()).nb_streams {
|
||||
return None
|
||||
}
|
||||
|
||||
self.current += 1;
|
||||
|
||||
Some(StreamMut::wrap(mem::transmute_copy(&self.context), (self.current - 1) as usize))
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
unsafe {
|
||||
((*self.ptr).nb_streams as usize, Some((*self.ptr).nb_streams as usize))
|
||||
let length = (*self.context.as_ptr()).nb_streams as usize;
|
||||
|
||||
(length - self.current as usize, Some(length - self.current as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
src/format/context/destructor.rs
Normal file
35
src/format/context/destructor.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use ffi::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Mode {
|
||||
Input,
|
||||
Output,
|
||||
}
|
||||
|
||||
pub struct Destructor {
|
||||
ptr: *mut AVFormatContext,
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl Destructor {
|
||||
pub unsafe fn new(ptr: *mut AVFormatContext, mode: Mode) -> Self {
|
||||
Destructor {
|
||||
ptr: ptr,
|
||||
mode: mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Destructor {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
match self.mode {
|
||||
Mode::Input =>
|
||||
avformat_close_input(&mut self.ptr),
|
||||
|
||||
Mode::Output =>
|
||||
avformat_free_context(self.ptr),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::ffi::CString;
|
||||
|
||||
use ffi::*;
|
||||
use ::{Error, Codec, Stream, Packet, format};
|
||||
use super::common::Context;
|
||||
use super::destructor;
|
||||
|
||||
pub struct Input {
|
||||
ptr: *mut AVFormatContext,
|
||||
@ -15,7 +17,7 @@ unsafe impl Send for Input { }
|
||||
|
||||
impl Input {
|
||||
pub unsafe fn wrap(ptr: *mut AVFormatContext) -> Self {
|
||||
Input { ptr: ptr, ctx: Context::wrap(ptr) }
|
||||
Input { ptr: ptr, ctx: Context::wrap(ptr, destructor::Mode::Input) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
|
||||
@ -135,14 +137,6 @@ impl DerefMut for Input {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Input {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
avformat_close_input(&mut self.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PacketIter<'a> {
|
||||
context: &'a mut Input,
|
||||
}
|
||||
@ -161,10 +155,11 @@ impl<'a> Iterator for PacketIter<'a> {
|
||||
|
||||
loop {
|
||||
match packet.read(self.context) {
|
||||
Ok(..) =>
|
||||
return Some((unsafe {
|
||||
Stream::wrap(*(*self.context.as_ptr()).streams.offset(packet.stream() as isize))
|
||||
}, packet)),
|
||||
Ok(..) => unsafe {
|
||||
return Some((
|
||||
Stream::wrap(mem::transmute_copy(&self.context), packet.stream()),
|
||||
packet));
|
||||
},
|
||||
|
||||
Err(Error::Eof) =>
|
||||
return None,
|
||||
|
@ -1,3 +1,6 @@
|
||||
pub mod destructor;
|
||||
pub use self::destructor::Destructor;
|
||||
|
||||
pub mod input;
|
||||
pub use self::input::Input;
|
||||
|
||||
|
@ -5,6 +5,7 @@ use std::ffi::CString;
|
||||
use ffi::*;
|
||||
use ::{Error, Codec, StreamMut, Dictionary, format};
|
||||
use super::common::Context;
|
||||
use super::destructor;
|
||||
|
||||
pub struct Output {
|
||||
ptr: *mut AVFormatContext,
|
||||
@ -15,7 +16,7 @@ unsafe impl Send for Output { }
|
||||
|
||||
impl Output {
|
||||
pub unsafe fn wrap(ptr: *mut AVFormatContext) -> Self {
|
||||
Output { ptr: ptr, ctx: Context::wrap(ptr) }
|
||||
Output { ptr: ptr, ctx: Context::wrap(ptr, destructor::Mode::Output) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
|
||||
@ -74,7 +75,9 @@ impl Output {
|
||||
panic!("out of memory");
|
||||
}
|
||||
|
||||
StreamMut::wrap(ptr)
|
||||
let index = (*self.ctx.as_ptr()).nb_streams - 1;
|
||||
|
||||
StreamMut::wrap(&mut self.ctx, index as usize)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,14 +102,6 @@ impl DerefMut for Output {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Output {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
avformat_free_context(self.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dump(ctx: &Output, index: i32, url: Option<&str>) {
|
||||
let url = url.map(|u| CString::new(u).unwrap());
|
||||
|
||||
|
@ -1,33 +1,29 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use libc::c_int;
|
||||
use ffi::*;
|
||||
use ::format;
|
||||
use ::codec::{self, packet};
|
||||
use ::{Rational, Discard};
|
||||
use super::Disposition;
|
||||
use format::context::common::Context;
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub struct Stream<'a> {
|
||||
ptr: *mut AVStream,
|
||||
|
||||
_marker: PhantomData<&'a format::Context>,
|
||||
context: &'a Context,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> Stream<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVStream) -> Self {
|
||||
Stream { ptr: ptr, _marker: PhantomData }
|
||||
pub unsafe fn wrap(context: &Context, index: usize) -> Stream {
|
||||
Stream { context: context, index: index }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVStream {
|
||||
self.ptr as *const _
|
||||
*(*self.context.as_ptr()).streams.offset(self.index as isize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Stream<'a> {
|
||||
pub fn codec(&self) -> codec::Context {
|
||||
unsafe {
|
||||
codec::Context::wrap((*self.as_ptr()).codec)
|
||||
codec::Context::wrap((*self.as_ptr()).codec, Some(self.context.destructor()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,9 +70,7 @@ impl<'a> Stream<'a> {
|
||||
}
|
||||
|
||||
pub fn side_data(&self) -> SideDataIter {
|
||||
unsafe {
|
||||
SideDataIter::new(self.as_ptr())
|
||||
}
|
||||
SideDataIter::new(self)
|
||||
}
|
||||
|
||||
pub fn frame_rate(&self) -> Rational {
|
||||
@ -86,16 +80,24 @@ impl<'a> Stream<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SideDataIter<'a> {
|
||||
ptr: *const AVStream,
|
||||
cur: c_int,
|
||||
impl<'a> PartialEq for Stream<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
unsafe {
|
||||
self.as_ptr() == other.as_ptr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_marker: PhantomData<&'a Stream<'a>>,
|
||||
impl<'a> Eq for Stream<'a> { }
|
||||
|
||||
pub struct SideDataIter<'a> {
|
||||
stream: &'a Stream<'a>,
|
||||
current: c_int,
|
||||
}
|
||||
|
||||
impl<'a> SideDataIter<'a> {
|
||||
pub fn new(ptr: *const AVStream) -> Self {
|
||||
SideDataIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||
pub fn new<'sd, 's: 'sd>(stream: &'s Stream) -> SideDataIter<'sd> {
|
||||
SideDataIter { stream: stream, current: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,19 +106,22 @@ impl<'a> Iterator for SideDataIter<'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)))
|
||||
if self.current >= (*self.stream.as_ptr()).nb_side_data {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.current += 1;
|
||||
|
||||
Some(packet::SideData::wrap(
|
||||
(*self.stream.as_ptr()).side_data.offset((self.current - 1) as isize)))
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
unsafe {
|
||||
((*self.ptr).nb_side_data as usize, Some((*self.ptr).nb_side_data as usize))
|
||||
let length = (*self.stream.as_ptr()).nb_side_data as usize;
|
||||
|
||||
(length - self.current as usize, Some(length - self.current as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,30 @@
|
||||
use std::ops::Deref;
|
||||
use std::mem;
|
||||
|
||||
use ffi::*;
|
||||
use ::Rational;
|
||||
use super::Stream;
|
||||
use format::context::common::Context;
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub struct StreamMut<'a> {
|
||||
ptr: *mut AVStream,
|
||||
imm: Stream<'a>,
|
||||
context: &'a mut Context,
|
||||
index: usize,
|
||||
|
||||
immutable: Stream<'a>,
|
||||
}
|
||||
|
||||
impl<'a> StreamMut<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVStream) -> Self {
|
||||
StreamMut { ptr: ptr, imm: Stream::wrap(ptr) }
|
||||
}
|
||||
pub unsafe fn wrap(context: &mut Context, index: usize) -> StreamMut {
|
||||
StreamMut {
|
||||
context: mem::transmute_copy(&context),
|
||||
index: index,
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVStream {
|
||||
self.ptr as *const _
|
||||
immutable: Stream::wrap(mem::transmute_copy(&context), index)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVStream {
|
||||
self.ptr
|
||||
*(*self.context.as_mut_ptr()).streams.offset(self.index as isize)
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +46,6 @@ impl<'a> Deref for StreamMut<'a> {
|
||||
type Target = Stream<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.imm
|
||||
&self.immutable
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user