codec: add magic traits to get codecs by name and id
This commit is contained in:
parent
bde17a8bae
commit
66284eb045
@ -4,6 +4,7 @@ use {ChannelLayout, format};
|
||||
use super::codec::Codec;
|
||||
use ffi::*;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub struct Audio {
|
||||
codec: Codec,
|
||||
}
|
||||
|
130
src/codec/decoder/decoder.rs
Normal file
130
src/codec/decoder/decoder.rs
Normal file
@ -0,0 +1,130 @@
|
||||
use std::ptr;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use ffi::*;
|
||||
use codec::{Context, traits};
|
||||
use super::{Opened, Video, Audio, Subtitle, Conceal, Check};
|
||||
use ::{Error, Discard, Rational, Dictionary};
|
||||
|
||||
pub struct Decoder(pub Context);
|
||||
|
||||
impl Decoder {
|
||||
pub fn open(mut self) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as<D: traits::Decoder>(mut self, codec: D) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
if let Some(codec) = codec.decoder() {
|
||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as_with<D: traits::Decoder>(mut self, codec: D, options: Dictionary) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
if let Some(codec) = codec.decoder() {
|
||||
let mut opts = options.disown();
|
||||
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||
|
||||
Dictionary::own(opts);
|
||||
|
||||
match res {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn video(self) -> Result<Video, Error> {
|
||||
if let Some(codec) = super::find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.video())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio(self) -> Result<Audio, Error> {
|
||||
if let Some(codec) = super::find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.audio())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtitle(self) -> Result<Subtitle, Error> {
|
||||
if let Some(codec) = super::find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.subtitle())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn conceal(&mut self, value: Conceal) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).error_concealment = value.bits();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(&mut self, value: Check) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).err_recognition = value.bits();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_loop_filter(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_loop_filter = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_idct(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_idct = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_frame(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_frame = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn time_base(&self) -> Rational {
|
||||
unsafe {
|
||||
Rational::from((*self.as_ptr()).time_base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Decoder {
|
||||
type Target = Context;
|
||||
|
||||
fn deref(&self) -> &<Self as Deref>::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Decoder {
|
||||
fn deref_mut(&mut self) -> &mut<Self as Deref>::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
pub mod decoder;
|
||||
pub use self::decoder::Decoder;
|
||||
|
||||
pub mod video;
|
||||
pub use self::video::Video;
|
||||
|
||||
@ -18,135 +21,15 @@ pub use self::check::Check;
|
||||
pub mod opened;
|
||||
pub use self::opened::Opened;
|
||||
|
||||
use std::ptr;
|
||||
use std::ffi::CString;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use ffi::*;
|
||||
use super::{Id, Context};
|
||||
use ::{Codec, Error, Discard, Rational, Dictionary};
|
||||
use codec::Context;
|
||||
use ::Codec;
|
||||
use codec::Id;
|
||||
|
||||
pub struct Decoder(pub Context);
|
||||
|
||||
impl Decoder {
|
||||
pub fn open(mut self) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as(mut self, codec: &Codec) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
if codec.is_decoder() {
|
||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Opened, Error> {
|
||||
unsafe {
|
||||
if codec.is_decoder() {
|
||||
let mut opts = options.disown();
|
||||
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||
|
||||
Dictionary::own(opts);
|
||||
|
||||
match res {
|
||||
0 => Ok(Opened(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn video(self) -> Result<Video, Error> {
|
||||
if let Some(ref codec) = find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.video())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio(self) -> Result<Audio, Error> {
|
||||
if let Some(ref codec) = find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.audio())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtitle(self) -> Result<Subtitle, Error> {
|
||||
if let Some(ref codec) = find(self.id()) {
|
||||
self.open_as(codec).and_then(|o| o.subtitle())
|
||||
}
|
||||
else {
|
||||
Err(Error::DecoderNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn conceal(&mut self, value: Conceal) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).error_concealment = value.bits();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(&mut self, value: Check) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).err_recognition = value.bits();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_loop_filter(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_loop_filter = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_idct(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_idct = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_frame(&mut self, value: Discard) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).skip_frame = value.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn time_base(&self) -> Rational {
|
||||
unsafe {
|
||||
Rational::from((*self.as_ptr()).time_base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Decoder {
|
||||
type Target = Context;
|
||||
|
||||
fn deref(&self) -> &<Self as Deref>::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Decoder {
|
||||
fn deref_mut(&mut self) -> &mut<Self as Deref>::Target {
|
||||
&mut self.0
|
||||
}
|
||||
pub fn new() -> Decoder {
|
||||
Context::new().decoder()
|
||||
}
|
||||
|
||||
pub fn find(id: Id) -> Option<Codec> {
|
||||
|
@ -5,9 +5,9 @@ use libc::c_int;
|
||||
use ffi::*;
|
||||
|
||||
use super::Encoder as Super;
|
||||
use ::{Packet, Error, Dictionary, Codec, ChannelLayout};
|
||||
use ::frame;
|
||||
use ::{Packet, Error, Dictionary, ChannelLayout, frame};
|
||||
use ::util::format;
|
||||
use codec::traits;
|
||||
|
||||
pub struct Audio(pub Super);
|
||||
|
||||
@ -21,23 +21,23 @@ impl Audio {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as(mut self, codec: &Codec) -> Result<Encoder, Error> {
|
||||
pub fn open_as<E: traits::Encoder>(mut self, codec: E) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
|
||||
0 => Ok(Encoder(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||
pub fn open_as_with<E: traits::Encoder>(mut self, codec: E, options: Dictionary) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
let mut opts = options.disown();
|
||||
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||
|
||||
@ -49,7 +49,7 @@ impl Audio {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
104
src/codec/encoder/encoder.rs
Normal file
104
src/codec/encoder/encoder.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use libc::c_int;
|
||||
use codec::Context;
|
||||
use ::{Error, Rational, media};
|
||||
use super::{video, audio, subtitle};
|
||||
|
||||
pub struct Encoder(pub Context);
|
||||
|
||||
impl Encoder {
|
||||
pub fn video(self) -> Result<video::Video, Error> {
|
||||
if self.medium() == media::Type::Video {
|
||||
Ok(video::Video(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio(self) -> Result<audio::Audio, Error> {
|
||||
if self.medium() == media::Type::Audio {
|
||||
Ok(audio::Audio(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtitle(self) -> Result<subtitle::Subtitle, Error> {
|
||||
if self.medium() == media::Type::Subtitle {
|
||||
Ok(subtitle::Subtitle(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_bit_rate(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).bit_rate = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_bit_rate(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).rc_max_rate = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_tolerance(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).bit_rate_tolerance = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_quality(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).global_quality = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_compression(&mut self, value: Option<usize>) {
|
||||
unsafe {
|
||||
if let Some(value) = value {
|
||||
(*self.as_mut_ptr()).compression_level = value as c_int;
|
||||
}
|
||||
else {
|
||||
(*self.as_mut_ptr()).compression_level = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).time_base = value.into().into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) {
|
||||
unsafe {
|
||||
if let Some(value) = value {
|
||||
(*self.as_mut_ptr()).framerate = value.into().into();
|
||||
}
|
||||
else {
|
||||
(*self.as_mut_ptr()).framerate.num = 0;
|
||||
(*self.as_mut_ptr()).framerate.den = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Encoder {
|
||||
type Target = Context;
|
||||
|
||||
fn deref(&self) -> &<Self as Deref>::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Encoder {
|
||||
fn deref_mut(&mut self) -> &mut<Self as Deref>::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
pub mod encoder;
|
||||
pub use self::encoder::Encoder;
|
||||
|
||||
pub mod video;
|
||||
pub use self::video::Encoder as Video;
|
||||
|
||||
@ -20,110 +23,14 @@ pub mod decision;
|
||||
pub use self::decision::Decision;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use libc::c_int;
|
||||
use ffi::*;
|
||||
use super::{Id, Context};
|
||||
use ::{Codec, Error, Rational};
|
||||
use ::media;
|
||||
use codec::Context;
|
||||
use ::Codec;
|
||||
use codec::Id;
|
||||
|
||||
pub struct Encoder(pub Context);
|
||||
|
||||
impl Encoder {
|
||||
pub fn video(self) -> Result<video::Video, Error> {
|
||||
if self.medium() == media::Type::Video {
|
||||
Ok(video::Video(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio(self) -> Result<audio::Audio, Error> {
|
||||
if self.medium() == media::Type::Audio {
|
||||
Ok(audio::Audio(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subtitle(self) -> Result<subtitle::Subtitle, Error> {
|
||||
if self.medium() == media::Type::Subtitle {
|
||||
Ok(subtitle::Subtitle(self))
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_bit_rate(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).bit_rate = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_bit_rate(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).rc_max_rate = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_tolerance(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).bit_rate_tolerance = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_quality(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).global_quality = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_compression(&mut self, value: Option<usize>) {
|
||||
unsafe {
|
||||
if let Some(value) = value {
|
||||
(*self.as_mut_ptr()).compression_level = value as c_int;
|
||||
}
|
||||
else {
|
||||
(*self.as_mut_ptr()).compression_level = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).time_base = value.into().into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) {
|
||||
unsafe {
|
||||
if let Some(value) = value {
|
||||
(*self.as_mut_ptr()).framerate = value.into().into();
|
||||
}
|
||||
else {
|
||||
(*self.as_mut_ptr()).framerate.num = 0;
|
||||
(*self.as_mut_ptr()).framerate.den = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Encoder {
|
||||
type Target = Context;
|
||||
|
||||
fn deref(&self) -> &<Self as Deref>::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Encoder {
|
||||
fn deref_mut(&mut self) -> &mut<Self as Deref>::Target {
|
||||
&mut self.0
|
||||
}
|
||||
pub fn new() -> Encoder {
|
||||
Context::new().encoder()
|
||||
}
|
||||
|
||||
pub fn find(id: Id) -> Option<Codec> {
|
||||
|
@ -5,7 +5,8 @@ use libc::c_int;
|
||||
use ffi::*;
|
||||
|
||||
use super::Encoder as Super;
|
||||
use ::{Error, Dictionary, Codec};
|
||||
use ::{Error, Dictionary};
|
||||
use codec::traits;
|
||||
|
||||
pub struct Subtitle(pub Super);
|
||||
|
||||
@ -19,23 +20,23 @@ impl Subtitle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as(mut self, codec: &Codec) -> Result<Encoder, Error> {
|
||||
pub fn open_as<E: traits::Encoder>(mut self, codec: E) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
|
||||
0 => Ok(Encoder(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||
pub fn open_as_with<E: traits::Encoder>(mut self, codec: E, options: Dictionary) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
let mut opts = options.disown();
|
||||
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||
|
||||
@ -47,7 +48,7 @@ impl Subtitle {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,8 @@ use ffi::*;
|
||||
|
||||
use super::Encoder as Super;
|
||||
use super::{MotionEstimation, Prediction, Comparison, Decision};
|
||||
use ::{Packet, Error, Rational, Dictionary, Codec};
|
||||
use ::frame;
|
||||
use ::format;
|
||||
use ::{Packet, Error, Rational, Dictionary, frame, format};
|
||||
use codec::traits;
|
||||
|
||||
pub struct Video(pub Super);
|
||||
|
||||
@ -22,23 +21,23 @@ impl Video {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as(mut self, codec: &Codec) -> Result<Encoder, Error> {
|
||||
pub fn open_as<E: traits::Encoder>(mut self, codec: E) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
match avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), ptr::null_mut()) {
|
||||
0 => Ok(Encoder(self)),
|
||||
e => Err(Error::from(e))
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_as_with(mut self, codec: &Codec, options: Dictionary) -> Result<Encoder, Error> {
|
||||
pub fn open_as_with<E: traits::Encoder>(mut self, codec: E, options: Dictionary) -> Result<Encoder, Error> {
|
||||
unsafe {
|
||||
if codec.is_encoder() {
|
||||
if let Some(codec) = codec.encoder() {
|
||||
let mut opts = options.disown();
|
||||
let res = avcodec_open2(self.as_mut_ptr(), codec.as_ptr(), &mut opts);
|
||||
|
||||
@ -50,7 +49,7 @@ impl Video {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(Error::InvalidData)
|
||||
Err(Error::EncoderNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ pub mod threading;
|
||||
|
||||
pub mod encoder;
|
||||
pub mod decoder;
|
||||
pub mod traits;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::str::from_utf8_unchecked;
|
||||
|
113
src/codec/traits.rs
Normal file
113
src/codec/traits.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use ::Codec;
|
||||
use codec::{Id, Audio, Video};
|
||||
use super::{decoder, encoder};
|
||||
|
||||
pub trait Decoder {
|
||||
fn decoder(self) -> Option<Codec>;
|
||||
}
|
||||
|
||||
impl<'a> Decoder for &'a str {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
decoder::find_by_name(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for Id {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
decoder::find(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for Codec {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
if self.is_decoder() {
|
||||
Some(self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for Option<Codec> {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
self.and_then(|c| c.decoder())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for Audio {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
if self.is_decoder() {
|
||||
Some(*&*self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for Video {
|
||||
fn decoder(self) -> Option<Codec> {
|
||||
if self.is_decoder() {
|
||||
Some(*&*self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Encoder {
|
||||
fn encoder(self) -> Option<Codec>;
|
||||
}
|
||||
|
||||
impl<'a> Encoder for &'a str {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
encoder::find_by_name(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encoder for Id {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
encoder::find(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encoder for Codec {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
if self.is_encoder() {
|
||||
Some(self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encoder for Option<Codec> {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
self.and_then(|c| c.encoder())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encoder for Audio {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
if self.is_encoder() {
|
||||
Some(*&*self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encoder for Video {
|
||||
fn encoder(self) -> Option<Codec> {
|
||||
if self.is_encoder() {
|
||||
Some(*&*self)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ use {Rational, format};
|
||||
use super::codec::Codec;
|
||||
use ffi::*;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub struct Video {
|
||||
codec: Codec,
|
||||
}
|
||||
|
@ -3,9 +3,10 @@ use std::ptr;
|
||||
use std::ffi::CString;
|
||||
|
||||
use ffi::*;
|
||||
use ::{Error, Codec, StreamMut, Dictionary, format};
|
||||
use ::{Error, StreamMut, Dictionary, format};
|
||||
use super::common::Context;
|
||||
use super::destructor;
|
||||
use codec::traits;
|
||||
|
||||
pub struct Output {
|
||||
ptr: *mut AVFormatContext,
|
||||
@ -67,9 +68,10 @@ impl Output {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_stream(&mut self, codec: &Codec) -> StreamMut {
|
||||
pub fn add_stream<E: traits::Encoder>(&mut self, codec: E) -> Result<StreamMut, Error> {
|
||||
unsafe {
|
||||
let ptr = avformat_new_stream(self.as_mut_ptr(), codec.as_ptr());
|
||||
let codec = try!(codec.encoder().ok_or(Error::EncoderNotFound));
|
||||
let ptr = avformat_new_stream(self.as_mut_ptr(), codec.as_ptr());
|
||||
|
||||
if ptr.is_null() {
|
||||
panic!("out of memory");
|
||||
@ -77,7 +79,7 @@ impl Output {
|
||||
|
||||
let index = (*self.ctx.as_ptr()).nb_streams - 1;
|
||||
|
||||
StreamMut::wrap(&mut self.ctx, index as usize)
|
||||
Ok(StreamMut::wrap(&mut self.ctx, index as usize))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user