format: refactor format handling

This commit is contained in:
lummax 2015-09-06 17:26:22 +02:00 committed by meh
parent d1e693965c
commit 87ea1bd196
7 changed files with 264 additions and 224 deletions

View File

@ -3,7 +3,7 @@ use std::ptr;
use std::ffi::CString; use std::ffi::CString;
use ffi::*; use ffi::*;
use ::{Error, Codec, Stream, Packet}; use ::{Error, Codec, Stream, Packet, format};
use super::common::Context; use super::common::Context;
pub struct Input { pub struct Input {
@ -28,6 +28,12 @@ impl Input {
} }
impl Input { impl Input {
pub fn format(&self) -> format::Input {
unsafe {
format::Input::wrap((*self.as_ptr()).iformat)
}
}
pub fn video_codec(&self) -> Option<Codec> { pub fn video_codec(&self) -> Option<Codec> {
unsafe { unsafe {
let ptr = av_format_get_video_codec(self.as_ptr()); let ptr = av_format_get_video_codec(self.as_ptr());

View File

@ -3,7 +3,7 @@ use std::ptr;
use std::ffi::CString; use std::ffi::CString;
use ffi::*; use ffi::*;
use ::{Error, Codec, StreamMut, Dictionary}; use ::{Error, Codec, StreamMut, Dictionary, format};
use super::common::Context; use super::common::Context;
pub struct Output { pub struct Output {
@ -28,6 +28,12 @@ impl Output {
} }
impl Output { impl Output {
pub fn format(&self) -> format::Output {
unsafe {
format::Output::wrap((*self.as_ptr()).oformat)
}
}
pub fn write_header(&mut self) -> Result<(), Error> { pub fn write_header(&mut self) -> Result<(), Error> {
unsafe { unsafe {
match avformat_write_header(self.as_mut_ptr(), ptr::null_mut()) { match avformat_write_header(self.as_mut_ptr(), ptr::null_mut()) {
@ -74,7 +80,7 @@ impl Output {
pub fn set_metadata(&mut self, dictionary: Dictionary) { pub fn set_metadata(&mut self, dictionary: Dictionary) {
unsafe { unsafe {
(*self.as_mut_ptr()).metadata = dictionary.take(); (*self.as_mut_ptr()).metadata = dictionary.disown();
} }
} }
} }

View File

@ -1,221 +0,0 @@
use std::ptr;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use ffi::*;
pub enum Format {
Input(Input),
Output(Output),
}
impl Format {
pub fn name(&self) -> &str {
match self {
&Format::Input(ref f) => f.name(),
&Format::Output(ref f) => f.name()
}
}
pub fn description(&self) -> &str {
match self {
&Format::Input(ref f) => f.description(),
&Format::Output(ref f) => f.description()
}
}
pub fn extensions(&self) -> Vec<&str> {
match self {
&Format::Input(ref f) => f.extensions(),
&Format::Output(ref f) => f.extensions()
}
}
pub fn mime_types(&self) -> Vec<&str> {
match self {
&Format::Input(ref f) => f.mime_types(),
&Format::Output(ref f) => f.mime_types()
}
}
}
pub struct Input {
ptr: *mut AVInputFormat,
}
impl Input {
pub unsafe fn wrap(ptr: *mut AVInputFormat) -> Self {
Input { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVInputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVInputFormat {
self.ptr
}
}
impl Input {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).extensions;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).mime_type;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
}
pub struct Output {
ptr: *mut AVOutputFormat,
}
impl Output {
pub unsafe fn wrap(ptr: *mut AVOutputFormat) -> Self {
Output { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVOutputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVOutputFormat {
self.ptr
}
}
impl Output {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).extensions;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).mime_type;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
}
pub fn list() -> FormatIter {
FormatIter::new()
}
pub struct FormatIter {
input: *mut AVInputFormat,
output: *mut AVOutputFormat,
step: Step,
}
enum Step {
Input,
Output,
Done,
}
impl FormatIter {
pub fn new() -> Self {
FormatIter { input: ptr::null_mut(), output: ptr::null_mut(), step: Step::Input }
}
}
impl Iterator for FormatIter {
type Item = Format;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
match self.step {
Step::Input => {
let ptr = av_iformat_next(self.input);
if ptr.is_null() && !self.input.is_null() {
self.step = Step::Output;
self.next()
}
else {
self.input = ptr;
Some(Format::Input(Input::wrap(ptr)))
}
}
Step::Output => {
let ptr = av_oformat_next(self.output);
if ptr.is_null() && !self.output.is_null() {
self.step = Step::Done;
self.next()
}
else {
self.output = ptr;
Some(Format::Output(Output::wrap(ptr)))
}
}
Step::Done =>
None
}
}
}
}

View File

@ -0,0 +1,62 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use ffi::*;
pub struct Input {
ptr: *mut AVInputFormat,
}
impl Input {
pub unsafe fn wrap(ptr: *mut AVInputFormat) -> Self {
Input { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVInputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVInputFormat {
self.ptr
}
}
impl Input {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).extensions;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).mime_type;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
}

65
src/format/format/iter.rs Normal file
View File

@ -0,0 +1,65 @@
use std::ptr;
use ffi::*;
use super::{Format, Input, Output};
pub struct Iter {
input: *mut AVInputFormat,
output: *mut AVOutputFormat,
step: Step,
}
enum Step {
Input,
Output,
Done,
}
impl Iter {
pub fn new() -> Self {
Iter { input: ptr::null_mut(), output: ptr::null_mut(), step: Step::Input }
}
}
impl Iterator for Iter {
type Item = Format;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
match self.step {
Step::Input => {
let ptr = av_iformat_next(self.input);
if ptr.is_null() && !self.input.is_null() {
self.step = Step::Output;
self.next()
}
else {
self.input = ptr;
Some(Format::Input(Input::wrap(ptr)))
}
}
Step::Output => {
let ptr = av_oformat_next(self.output);
if ptr.is_null() && !self.output.is_null() {
self.step = Step::Done;
self.next()
}
else {
self.output = ptr;
Some(Format::Output(Output::wrap(ptr)))
}
}
Step::Done =>
None
}
}
}
}

47
src/format/format/mod.rs Normal file
View File

@ -0,0 +1,47 @@
mod input;
pub use self::input::Input;
mod output;
pub use self::output::Output;
mod iter;
pub use self::iter::Iter;
pub enum Format {
Input(Input),
Output(Output),
}
impl Format {
pub fn name(&self) -> &str {
match self {
&Format::Input(ref f) => f.name(),
&Format::Output(ref f) => f.name()
}
}
pub fn description(&self) -> &str {
match self {
&Format::Input(ref f) => f.description(),
&Format::Output(ref f) => f.description()
}
}
pub fn extensions(&self) -> Vec<&str> {
match self {
&Format::Input(ref f) => f.extensions(),
&Format::Output(ref f) => f.extensions()
}
}
pub fn mime_types(&self) -> Vec<&str> {
match self {
&Format::Input(ref f) => f.mime_types(),
&Format::Output(ref f) => f.mime_types()
}
}
}
pub fn list() -> Iter {
Iter::new()
}

View File

@ -0,0 +1,75 @@
use std::path::Path;
use std::ptr;
use std::ffi::{CStr, CString};
use std::str::from_utf8_unchecked;
use ffi::*;
use {codec, media};
pub struct Output {
ptr: *mut AVOutputFormat,
}
impl Output {
pub unsafe fn wrap(ptr: *mut AVOutputFormat) -> Self {
Output { ptr: ptr }
}
pub unsafe fn as_ptr(&self) -> *const AVOutputFormat {
self.ptr as *const _
}
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVOutputFormat {
self.ptr
}
}
impl Output {
pub fn name(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn description(&self) -> &str {
unsafe {
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
}
}
pub fn extensions(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).extensions;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
pub fn mime_types(&self) -> Vec<&str> {
unsafe {
let ptr = (*self.as_ptr()).mime_type;
if ptr.is_null() {
Vec::new()
}
else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()).split(',').collect()
}
}
}
pub fn codec<P: AsRef<Path>>(&self, path: &P, kind: media::Type) -> codec::Id {
// XXX: use to_cstring when stable
let path = CString::new(path.as_ref().as_os_str().to_str().unwrap()).unwrap();
unsafe {
codec::Id::from(av_guess_codec(self.as_ptr(), ptr::null(), path.as_ptr(), ptr::null(), kind.into()))
}
}
}