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:
FreezyLemon 2024-10-28 10:42:24 +01:00 committed by GitHub
parent ef14631f71
commit 764ec831f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 89 additions and 107 deletions

View File

@ -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())
}

View File

@ -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
}
}
}

View File

@ -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"))]

View File

@ -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> {

View File

@ -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;

View File

@ -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)
}
}
}

View File

@ -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) }
}
}

View File

@ -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() }
}

View File

@ -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();