Refactor format::{Input, Output} (#79)
* Refactor format::Input * Refactor format::Output * Remove av_register_* API This was deprecated in 4.0 (2018) and without it, we never need a mutable pointer to AVInputFormat/AVOutputFormat
This commit is contained in:
parent
ef14631f71
commit
764ec831f9
@ -3,50 +3,60 @@ use std::ptr;
|
||||
use crate::ffi::*;
|
||||
use crate::format;
|
||||
|
||||
pub struct AudioIter(*mut AVInputFormat);
|
||||
pub struct AudioIter(*const AVInputFormat);
|
||||
|
||||
impl Iterator for AudioIter {
|
||||
type Item = format::Input;
|
||||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
let ptr = av_input_audio_device_next(self.0) as *mut AVInputFormat;
|
||||
let inner = self.0;
|
||||
|
||||
if ptr.is_null() && !self.0.is_null() {
|
||||
None
|
||||
} else {
|
||||
// Pre-5.0 FFmpeg uses a non-const pointer here
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
let inner = inner as *mut _;
|
||||
|
||||
let ptr = av_input_audio_device_next(inner);
|
||||
|
||||
if let Some(input) = format::Input::from_raw(ptr) {
|
||||
self.0 = ptr;
|
||||
|
||||
Some(format::Input::wrap(ptr))
|
||||
Some(input)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio() -> AudioIter {
|
||||
AudioIter(ptr::null_mut())
|
||||
AudioIter(ptr::null())
|
||||
}
|
||||
|
||||
pub struct VideoIter(*mut AVInputFormat);
|
||||
pub struct VideoIter(*const AVInputFormat);
|
||||
|
||||
impl Iterator for VideoIter {
|
||||
type Item = format::Input;
|
||||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
let ptr = av_input_video_device_next(self.0) as *mut AVInputFormat;
|
||||
let inner = self.0;
|
||||
|
||||
if ptr.is_null() && !self.0.is_null() {
|
||||
None
|
||||
} else {
|
||||
// Pre-5.0 FFmpeg uses a non-const pointer here
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
let inner = inner as *mut _;
|
||||
|
||||
let ptr = av_input_video_device_next(inner);
|
||||
|
||||
if let Some(input) = format::Input::from_raw(ptr) {
|
||||
self.0 = ptr;
|
||||
|
||||
Some(format::Input::wrap(ptr))
|
||||
Some(input)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn video() -> VideoIter {
|
||||
VideoIter(ptr::null_mut())
|
||||
VideoIter(ptr::null())
|
||||
}
|
||||
|
@ -3,21 +3,26 @@ use std::ptr;
|
||||
use crate::ffi::*;
|
||||
use crate::format;
|
||||
|
||||
pub struct AudioIter(*mut AVOutputFormat);
|
||||
pub struct AudioIter(*const AVOutputFormat);
|
||||
|
||||
impl Iterator for AudioIter {
|
||||
type Item = format::Output;
|
||||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
let ptr = av_output_audio_device_next(self.0) as *mut AVOutputFormat;
|
||||
let inner = self.0;
|
||||
|
||||
if ptr.is_null() && !self.0.is_null() {
|
||||
None
|
||||
// Pre-5.0 FFmpeg uses a non-const pointer here
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
let inner = inner as *mut _;
|
||||
|
||||
let ptr = av_output_audio_device_next(inner);
|
||||
|
||||
if let Some(output) = format::Output::from_raw(ptr) {
|
||||
self.0 = ptr;
|
||||
Some(output)
|
||||
} else {
|
||||
self.0 = ptr as *mut AVOutputFormat;
|
||||
|
||||
Some(format::Output::wrap(ptr))
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,21 +32,26 @@ pub fn audio() -> AudioIter {
|
||||
AudioIter(ptr::null_mut())
|
||||
}
|
||||
|
||||
pub struct VideoIter(*mut AVOutputFormat);
|
||||
pub struct VideoIter(*const AVOutputFormat);
|
||||
|
||||
impl Iterator for VideoIter {
|
||||
type Item = format::Output;
|
||||
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
let ptr = av_output_video_device_next(self.0) as *mut AVOutputFormat;
|
||||
let inner = self.0;
|
||||
|
||||
if ptr.is_null() && !self.0.is_null() {
|
||||
None
|
||||
// Pre-5.0 FFmpeg uses a non-const pointer here
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
let inner = inner as *mut _;
|
||||
|
||||
let ptr = av_output_video_device_next(inner);
|
||||
|
||||
if let Some(output) = format::Output::from_raw(ptr) {
|
||||
self.0 = ptr;
|
||||
Some(output)
|
||||
} else {
|
||||
self.0 = ptr as *mut AVOutputFormat;
|
||||
|
||||
Some(format::Output::wrap(ptr))
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ impl Input {
|
||||
|
||||
impl Input {
|
||||
pub fn format(&self) -> format::Input {
|
||||
unsafe { format::Input::wrap((*self.as_ptr()).iformat as *mut AVInputFormat) }
|
||||
unsafe { format::Input::from_raw((*self.as_ptr()).iformat).expect("iformat is non-null") }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
|
@ -35,7 +35,7 @@ impl Output {
|
||||
|
||||
impl Output {
|
||||
pub fn format(&self) -> format::Output {
|
||||
unsafe { format::Output::wrap((*self.as_ptr()).oformat as *mut AVOutputFormat) }
|
||||
unsafe { format::Output::from_raw((*self.as_ptr()).oformat).expect("oformat is non-null") }
|
||||
}
|
||||
|
||||
pub fn write_header(&mut self) -> Result<(), Error> {
|
||||
|
@ -1,34 +1,37 @@
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use crate::ffi::*;
|
||||
use crate::utils;
|
||||
|
||||
use super::Flags;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Input {
|
||||
ptr: *mut AVInputFormat,
|
||||
ptr: NonNull<AVInputFormat>,
|
||||
}
|
||||
|
||||
impl Input {
|
||||
pub unsafe fn wrap(ptr: *mut AVInputFormat) -> Self {
|
||||
Input { ptr }
|
||||
pub unsafe fn from_raw(ptr: *const AVInputFormat) -> Option<Self> {
|
||||
NonNull::new(ptr as *mut _).map(|ptr| Self { ptr })
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVInputFormat {
|
||||
self.ptr as *const _
|
||||
pub fn as_ptr(self) -> *const AVInputFormat {
|
||||
self.ptr.as_ptr()
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVInputFormat {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl Input {
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(self) -> &'static str {
|
||||
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &str {
|
||||
pub fn description(self) -> &'static str {
|
||||
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
|
||||
}
|
||||
|
||||
pub fn extensions(&self) -> Vec<&str> {
|
||||
pub fn flags(self) -> Flags {
|
||||
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
|
||||
}
|
||||
|
||||
pub fn extensions(self) -> Vec<&'static str> {
|
||||
unsafe {
|
||||
let ptr = (*self.as_ptr()).extensions;
|
||||
|
||||
@ -40,7 +43,7 @@ impl Input {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mime_types(&self) -> Vec<&str> {
|
||||
pub fn mime_types(self) -> Vec<&'static str> {
|
||||
unsafe {
|
||||
let ptr = (*self.as_ptr()).mime_type;
|
||||
|
||||
|
@ -26,11 +26,7 @@ impl Iterator for DemuxerIter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let next = av_demuxer_iterate(&mut self.ptr);
|
||||
if next.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Input::wrap(next as _))
|
||||
}
|
||||
Input::from_raw(next)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,11 +53,7 @@ impl Iterator for MuxerIter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let next = av_muxer_iterate(&mut self.ptr);
|
||||
if next.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(Output::wrap(next as _))
|
||||
}
|
||||
Output::from_raw(next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,39 @@
|
||||
use std::path::Path;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use std::ptr::{self, NonNull};
|
||||
|
||||
use super::Flags;
|
||||
use crate::ffi::*;
|
||||
use crate::{codec, media, utils};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Output {
|
||||
ptr: *mut AVOutputFormat,
|
||||
ptr: NonNull<AVOutputFormat>,
|
||||
}
|
||||
|
||||
impl Output {
|
||||
pub unsafe fn wrap(ptr: *mut AVOutputFormat) -> Self {
|
||||
Output { ptr }
|
||||
pub unsafe fn from_raw(ptr: *const AVOutputFormat) -> Option<Self> {
|
||||
NonNull::new(ptr as *mut _).map(|ptr| Self { ptr })
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVOutputFormat {
|
||||
self.ptr as *const _
|
||||
pub fn as_ptr(self) -> *const AVOutputFormat {
|
||||
self.ptr.as_ptr()
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVOutputFormat {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl Output {
|
||||
pub fn name(&self) -> &str {
|
||||
pub fn name(self) -> &'static str {
|
||||
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
|
||||
}
|
||||
|
||||
pub fn description(&self) -> &str {
|
||||
pub fn description(self) -> &'static str {
|
||||
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
|
||||
}
|
||||
|
||||
pub fn extensions(&self) -> Vec<&str> {
|
||||
pub fn flags(self) -> Flags {
|
||||
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
|
||||
}
|
||||
|
||||
pub fn extensions(self) -> Vec<&'static str> {
|
||||
unsafe {
|
||||
let ptr = (*self.as_ptr()).extensions;
|
||||
|
||||
@ -46,7 +45,7 @@ impl Output {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mime_types(&self) -> Vec<&str> {
|
||||
pub fn mime_types(self) -> Vec<&'static str> {
|
||||
unsafe {
|
||||
let ptr = (*self.as_ptr()).mime_type;
|
||||
|
||||
@ -58,9 +57,9 @@ impl Output {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codec<P: AsRef<Path>>(&self, path: &P, kind: media::Type) -> codec::Id {
|
||||
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();
|
||||
let path = CString::new(path.as_ref().to_str().unwrap()).unwrap();
|
||||
|
||||
unsafe {
|
||||
codec::Id::from(av_guess_codec(
|
||||
@ -72,8 +71,4 @@ impl Output {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flags(&self) -> Flags {
|
||||
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
|
||||
}
|
||||
}
|
||||
|
@ -23,27 +23,6 @@ use crate::ffi::*;
|
||||
use crate::utils;
|
||||
use crate::{Dictionary, Error};
|
||||
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
pub fn register_all() {
|
||||
unsafe {
|
||||
av_register_all();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
pub fn register_input(mut format: Input) {
|
||||
unsafe {
|
||||
av_register_input_format(format.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
pub fn register_output(mut format: Output) {
|
||||
unsafe {
|
||||
av_register_output_format(format.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn version() -> u32 {
|
||||
unsafe { avformat_version() }
|
||||
}
|
||||
|
@ -83,11 +83,6 @@ fn init_error() {
|
||||
util::error::register_all();
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "format", not(feature = "ffmpeg_5_0")))]
|
||||
fn init_format() {
|
||||
format::register_all();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "format"))]
|
||||
fn init_format() {}
|
||||
|
||||
@ -109,8 +104,6 @@ fn init_filter() {}
|
||||
|
||||
pub fn init() -> Result<(), Error> {
|
||||
init_error();
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
init_format();
|
||||
init_device();
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
init_filter();
|
||||
|
Loading…
x
Reference in New Issue
Block a user