diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..051d09d --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +eval "$(lorri direnv)" diff --git a/src/codec/decoder/opened.rs b/src/codec/decoder/opened.rs index e14c508..eb7fc8b 100644 --- a/src/codec/decoder/opened.rs +++ b/src/codec/decoder/opened.rs @@ -1,10 +1,13 @@ -use std::ops::{Deref, DerefMut}; +use std::{ + ops::{Deref, DerefMut}, + ptr, +}; use super::{Audio, Decoder, Subtitle, Video}; use crate::{ codec::{Context, Profile}, ffi::*, - media, Error, Rational, + media, packet, Error, Frame, Rational, }; pub struct Opened(pub Decoder); @@ -37,6 +40,35 @@ impl Opened { } } + pub fn send_packet(&mut self, packet: &P) -> Result<(), Error> { + unsafe { + match avcodec_send_packet(self.as_mut_ptr(), packet.as_ptr()) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + + /// Sends a NULL packet to the decoder to signal end of stream and enter + /// draining mode. + pub fn send_eof(&mut self) -> Result<(), Error> { + unsafe { + match avcodec_send_packet(self.as_mut_ptr(), ptr::null()) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + + pub fn receive_frame(&mut self, frame: &mut Frame) -> Result<(), Error> { + unsafe { + match avcodec_receive_frame(self.as_mut_ptr(), frame.as_mut_ptr()) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + pub fn bit_rate(&self) -> usize { unsafe { (*self.as_ptr()).bit_rate as usize } } diff --git a/src/codec/encoder/encoder.rs b/src/codec/encoder/encoder.rs index 9617df0..bc2839b 100644 --- a/src/codec/encoder/encoder.rs +++ b/src/codec/encoder/encoder.rs @@ -1,9 +1,11 @@ -use std::ops::{Deref, DerefMut}; - -use libc::c_int; +use std::{ + ops::{Deref, DerefMut}, + os::raw::c_int, + ptr, +}; use super::{audio, subtitle, video}; -use crate::{codec::Context, media, Error, Rational}; +use crate::{codec::Context, ffi::*, media, packet, Error, Frame, Rational}; pub struct Encoder(pub Context); @@ -56,6 +58,30 @@ impl Encoder { } } + pub fn send_frame(&mut self, frame: &Frame) -> Result<(), Error> { + unsafe { + match avcodec_send_frame(self.as_mut_ptr(), frame.as_ptr()) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + + /// Sends a NULL packet to the encoder to signal end of stream and enter + /// draining mode. + pub fn send_eof(&mut self) -> Result<(), Error> { + unsafe { self.send_frame(&Frame::wrap(ptr::null_mut())) } + } + + pub fn receive_packet(&mut self, packet: &mut P) -> Result<(), Error> { + unsafe { + match avcodec_receive_packet(self.as_mut_ptr(), packet.as_mut_ptr()) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + pub fn set_strict_std_compliance(&mut self, value: i32) { unsafe { (*self.as_mut_ptr()).strict_std_compliance = value as c_int; diff --git a/src/format/context/common.rs b/src/format/context/common.rs index 70c8587..508dfe3 100644 --- a/src/format/context/common.rs +++ b/src/format/context/common.rs @@ -71,7 +71,7 @@ impl Context { } #[inline] - fn nb_streams(&self) -> u32 { + pub fn nb_streams(&self) -> u32 { unsafe { (*self.as_ptr()).nb_streams } }