Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions src/audio/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,58 @@ use common::{self, Packet, Timebase};
use errors::*;
use util::OwnedOrRefMut;

/// Audio encoder.
///
/// Encoding is done by repeatedly calling `encode` with
/// the `Frame` that should be encoded and by consuming
/// the returned `Packet` iterator.
///
/// When no more frames need to be encoded,
/// the encoder should be `flush`ed to obtain
/// the remaining buffered packets.
pub struct Encoder {
ptr: *mut AVCodecContext,
}

impl Encoder {
/// Create a new encoder builder with the passed `codec`.
pub fn from_codec(codec: Codec) -> Result<EncoderBuilder> {
EncoderBuilder::from_codec(codec)
}

/// Returns the sample format of the encoder.
pub fn sample_format(&self) -> AVSampleFormat {
self.as_ref().sample_fmt
}

/// TODO: Check for underflow
// TODO: Check for underflow
/// Returns the sample rate of the encoder.
pub fn sample_rate(&self) -> u32 {
self.as_ref().sample_rate as u32
}

/// Returns the time base of the encoder.
pub fn time_base(&self) -> Timebase {
self.as_ref().time_base.into()
}

// Returns the frame size required by the encoder.
// If the result is `None`, any frame size can be used.
/// Returns the frame size required by the encoder.
/// If the result is `None`, any frame size may be used.
pub fn frame_size(&self) -> Option<usize> {
match self.as_ref().frame_size as usize {
0 => None,
size => Some(size),
}
}

/// Returns the codec of the encoder.
pub fn codec(&self) -> Codec {
unsafe {
Codec::from_ptr(self.as_ref().codec)
}
}
}

impl Encoder {
/// Encode a Frame and return the encoded packets as iterator.
pub fn encode<'a, F>(&mut self, frame: F) -> Result<Packets> where
F: Into<RefMutFrame<'a>>,
{
Expand Down Expand Up @@ -100,6 +113,9 @@ impl Encoder {
}
}

/// Flush the encoder.
/// The encoder may buffer data and needs to be flushed
/// to obtain the remaining packets as iterator.
pub fn flush(self) -> Result<Packets<'static>> {
unsafe {
// Flush encoder
Expand Down Expand Up @@ -135,6 +151,7 @@ impl Drop for Encoder {
}
}

/// Builder for creating encoders.
pub struct EncoderBuilder {
codec: Codec,
sample_format: Option<AVSampleFormat>,
Expand All @@ -143,6 +160,7 @@ pub struct EncoderBuilder {
}

impl EncoderBuilder {
/// Create a new encoder builder with the passed `codec`.
pub fn from_codec(codec: Codec) -> Result<Self> {
common::encoder::require_is_encoder(codec)?;
common::encoder::require_codec_type(MediaType::Audio, codec)?;
Expand All @@ -155,19 +173,23 @@ impl EncoderBuilder {
})
}

/// Set the sample format. Default: `AV_SAMPLE_FMT_S16`.
pub fn sample_format(&mut self, sample_format: AVSampleFormat) -> &mut Self {
self.sample_format = Some(sample_format); self
}

/// TODO: Check for overflow
// TODO: Check for overflow
/// Set the sample rate. Default: `44100`.
pub fn sample_rate(&mut self, sample_rate: u32) -> &mut Self {
self.sample_rate = Some(sample_rate); self
}

/// Set the channel layout. Default: `CHANNEL_LAYOUT_STEREO`.
pub fn channel_layout(&mut self, channel_layout: ChannelLayout) -> &mut Self {
self.channel_layout = Some(channel_layout); self
}

/// Open the encoder.
pub fn open(&self, format: OutputFormat) -> Result<Encoder> {
unsafe {
let sample_rate = self.sample_rate.unwrap_or(44100) as c_int;
Expand Down Expand Up @@ -198,6 +220,7 @@ impl EncoderBuilder {
}
}

/// Iterator over encoded packets.
pub struct Packets<'encoder> {
encoder: OwnedOrRefMut<'encoder, Encoder>,
}
Expand Down Expand Up @@ -246,4 +269,3 @@ impl<'encoder> Drop for Packets<'encoder> {
for _ in self {}
}
}

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![doc(html_root_url = "https://panicbit.github.io/rust-av/")]
// `error_chain!` can recurse deeply
#![recursion_limit = "1024"]
pub extern crate av_sys as ffi;
Expand Down
13 changes: 13 additions & 0 deletions src/video/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,38 @@ use super::{Frame, Scaler};
// TODO: Add align field to encoder
const ALIGN: usize = 32;

/// Video encoder.
///
/// Encoding is done by repeatedly calling `encode` with
/// the `Frame` that should be encoded and by consuming
/// the returned `Packet` iterator.
///
/// When no more frames need to be encoded,
/// the encoder should be `flush`ed to obtain
/// the remaining buffered packets.
pub struct Encoder {
ptr: *mut AVCodecContext,
scaler: Scaler,
tmp_frame: Option<Frame>,
}

impl Encoder {
/// Create a new encoder builder with the passed `codec`.
pub fn from_codec(codec: Codec) -> Result<EncoderBuilder> {
EncoderBuilder::from_codec(codec)
}

/// Returns the pixel format of the encoder.
pub fn pixel_format(&self) -> ffi::AVPixelFormat {
self.as_ref().pix_fmt
}

/// Returns the width of the encoder.
pub fn width(&self) -> usize {
self.as_ref().width as usize
}

/// Returns the height of the encoder.
pub fn height(&self) -> usize {
self.as_ref().height as usize
}
Expand Down