Add new (4.0+) API for av_[de]muxer_iterate (#52)

* Add new MuxerIter/DemuxerIter for 4.0+

* Add Default impls for MuxerIter/DemuxerIter

* Add tests for MuxerIter/DemuxerIter

* Use mutable reference over addr_of_mut!

* Don't dereference long_name if nullptr

This happens if FFmpeg is configured with `--enable-small`
This commit is contained in:
FreezyLemon 2024-05-17 14:44:21 +02:00 committed by GitHub
parent be7340c39a
commit 44e101406d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 126 additions and 2 deletions

View File

@ -27,7 +27,15 @@ impl Input {
}
pub fn description(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).long_name).to_bytes()) }
unsafe {
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
}
pub fn extensions(&self) -> Vec<&str> {

View File

@ -12,6 +12,11 @@ mod iter;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub use self::iter::Iter;
#[cfg(feature = "ffmpeg_4_0")]
mod new_iter;
#[cfg(feature = "ffmpeg_4_0")]
pub use self::new_iter::{DemuxerIter, MuxerIter};
pub enum Format {
Input(Input),
Output(Output),
@ -51,3 +56,13 @@ impl Format {
pub fn list() -> Iter {
Iter::new()
}
#[cfg(feature = "ffmpeg_4_0")]
pub fn list_demuxers() -> DemuxerIter {
DemuxerIter::new()
}
#[cfg(feature = "ffmpeg_4_0")]
pub fn list_muxers() -> MuxerIter {
MuxerIter::new()
}

View File

@ -0,0 +1,93 @@
use std::ptr::null_mut;
use crate::ffi::*;
use crate::format::format::{Input, Output};
use crate::format::Format;
use libc::c_void;
pub struct DemuxerIter {
ptr: *mut c_void,
}
impl DemuxerIter {
pub fn new() -> Self {
Self { ptr: null_mut() }
}
}
impl Default for DemuxerIter {
fn default() -> Self {
Self::new()
}
}
impl Iterator for DemuxerIter {
type Item = Format;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
let next = av_demuxer_iterate(&mut self.ptr);
if next.is_null() {
None
} else {
Some(Format::Input(Input::wrap(next as _)))
}
}
}
}
pub struct MuxerIter {
ptr: *mut c_void,
}
impl MuxerIter {
pub fn new() -> Self {
Self { ptr: null_mut() }
}
}
impl Default for MuxerIter {
fn default() -> Self {
Self::new()
}
}
impl Iterator for MuxerIter {
type Item = Format;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
let next = av_muxer_iterate(&mut self.ptr);
if next.is_null() {
None
} else {
Some(Format::Output(Output::wrap(next as _)))
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn muxer_iter() {
for f in MuxerIter::new() {
println!("{}:", f.name());
println!("\t{}", f.description());
println!("\t{:?}", f.extensions());
println!("\t{:?}", f.mime_types());
}
}
#[test]
fn demuxer_iter() {
for f in DemuxerIter::new() {
println!("{}:", f.name());
println!("\t{}", f.description());
println!("\t{:?}", f.extensions());
println!("\t{:?}", f.mime_types());
}
}
}

View File

@ -32,7 +32,15 @@ impl Output {
}
pub fn description(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).long_name).to_bytes()) }
unsafe {
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
}
pub fn extensions(&self) -> Vec<&str> {