Skip to content

Commit 764ec83

Browse files
authored
Refactor format::{Input, Output} (shssoichiro#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
1 parent ef14631 commit 764ec83

File tree

9 files changed

+89
-107
lines changed

9 files changed

+89
-107
lines changed

src/device/input.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,60 @@ use std::ptr;
33
use crate::ffi::*;
44
use crate::format;
55

6-
pub struct AudioIter(*mut AVInputFormat);
6+
pub struct AudioIter(*const AVInputFormat);
77

88
impl Iterator for AudioIter {
99
type Item = format::Input;
1010

1111
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
1212
unsafe {
13-
let ptr = av_input_audio_device_next(self.0) as *mut AVInputFormat;
13+
let inner = self.0;
1414

15-
if ptr.is_null() && !self.0.is_null() {
16-
None
17-
} else {
18-
self.0 = ptr;
15+
// Pre-5.0 FFmpeg uses a non-const pointer here
16+
#[cfg(not(feature = "ffmpeg_5_0"))]
17+
let inner = inner as *mut _;
18+
19+
let ptr = av_input_audio_device_next(inner);
1920

20-
Some(format::Input::wrap(ptr))
21+
if let Some(input) = format::Input::from_raw(ptr) {
22+
self.0 = ptr;
23+
Some(input)
24+
} else {
25+
None
2126
}
2227
}
2328
}
2429
}
2530

2631
pub fn audio() -> AudioIter {
27-
AudioIter(ptr::null_mut())
32+
AudioIter(ptr::null())
2833
}
2934

30-
pub struct VideoIter(*mut AVInputFormat);
35+
pub struct VideoIter(*const AVInputFormat);
3136

3237
impl Iterator for VideoIter {
3338
type Item = format::Input;
3439

3540
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
3641
unsafe {
37-
let ptr = av_input_video_device_next(self.0) as *mut AVInputFormat;
42+
let inner = self.0;
3843

39-
if ptr.is_null() && !self.0.is_null() {
40-
None
41-
} else {
42-
self.0 = ptr;
44+
// Pre-5.0 FFmpeg uses a non-const pointer here
45+
#[cfg(not(feature = "ffmpeg_5_0"))]
46+
let inner = inner as *mut _;
47+
48+
let ptr = av_input_video_device_next(inner);
4349

44-
Some(format::Input::wrap(ptr))
50+
if let Some(input) = format::Input::from_raw(ptr) {
51+
self.0 = ptr;
52+
Some(input)
53+
} else {
54+
None
4555
}
4656
}
4757
}
4858
}
4959

5060
pub fn video() -> VideoIter {
51-
VideoIter(ptr::null_mut())
61+
VideoIter(ptr::null())
5262
}

src/device/output.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@ use std::ptr;
33
use crate::ffi::*;
44
use crate::format;
55

6-
pub struct AudioIter(*mut AVOutputFormat);
6+
pub struct AudioIter(*const AVOutputFormat);
77

88
impl Iterator for AudioIter {
99
type Item = format::Output;
1010

1111
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
1212
unsafe {
13-
let ptr = av_output_audio_device_next(self.0) as *mut AVOutputFormat;
13+
let inner = self.0;
1414

15-
if ptr.is_null() && !self.0.is_null() {
16-
None
17-
} else {
18-
self.0 = ptr as *mut AVOutputFormat;
15+
// Pre-5.0 FFmpeg uses a non-const pointer here
16+
#[cfg(not(feature = "ffmpeg_5_0"))]
17+
let inner = inner as *mut _;
18+
19+
let ptr = av_output_audio_device_next(inner);
1920

20-
Some(format::Output::wrap(ptr))
21+
if let Some(output) = format::Output::from_raw(ptr) {
22+
self.0 = ptr;
23+
Some(output)
24+
} else {
25+
None
2126
}
2227
}
2328
}
@@ -27,21 +32,26 @@ pub fn audio() -> AudioIter {
2732
AudioIter(ptr::null_mut())
2833
}
2934

30-
pub struct VideoIter(*mut AVOutputFormat);
35+
pub struct VideoIter(*const AVOutputFormat);
3136

3237
impl Iterator for VideoIter {
3338
type Item = format::Output;
3439

3540
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
3641
unsafe {
37-
let ptr = av_output_video_device_next(self.0) as *mut AVOutputFormat;
42+
let inner = self.0;
3843

39-
if ptr.is_null() && !self.0.is_null() {
40-
None
41-
} else {
42-
self.0 = ptr as *mut AVOutputFormat;
44+
// Pre-5.0 FFmpeg uses a non-const pointer here
45+
#[cfg(not(feature = "ffmpeg_5_0"))]
46+
let inner = inner as *mut _;
47+
48+
let ptr = av_output_video_device_next(inner);
4349

44-
Some(format::Output::wrap(ptr))
50+
if let Some(output) = format::Output::from_raw(ptr) {
51+
self.0 = ptr;
52+
Some(output)
53+
} else {
54+
None
4555
}
4656
}
4757
}

src/format/context/input.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl Input {
3636

3737
impl Input {
3838
pub fn format(&self) -> format::Input {
39-
unsafe { format::Input::wrap((*self.as_ptr()).iformat as *mut AVInputFormat) }
39+
unsafe { format::Input::from_raw((*self.as_ptr()).iformat).expect("iformat is non-null") }
4040
}
4141

4242
#[cfg(not(feature = "ffmpeg_5_0"))]

src/format/context/output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Output {
3535

3636
impl Output {
3737
pub fn format(&self) -> format::Output {
38-
unsafe { format::Output::wrap((*self.as_ptr()).oformat as *mut AVOutputFormat) }
38+
unsafe { format::Output::from_raw((*self.as_ptr()).oformat).expect("oformat is non-null") }
3939
}
4040

4141
pub fn write_header(&mut self) -> Result<(), Error> {

src/format/format/input.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1+
use std::ptr::NonNull;
2+
13
use crate::ffi::*;
24
use crate::utils;
35

6+
use super::Flags;
7+
8+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49
pub struct Input {
5-
ptr: *mut AVInputFormat,
10+
ptr: NonNull<AVInputFormat>,
611
}
712

813
impl Input {
9-
pub unsafe fn wrap(ptr: *mut AVInputFormat) -> Self {
10-
Input { ptr }
11-
}
12-
13-
pub unsafe fn as_ptr(&self) -> *const AVInputFormat {
14-
self.ptr as *const _
14+
pub unsafe fn from_raw(ptr: *const AVInputFormat) -> Option<Self> {
15+
NonNull::new(ptr as *mut _).map(|ptr| Self { ptr })
1516
}
1617

17-
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVInputFormat {
18-
self.ptr
18+
pub fn as_ptr(self) -> *const AVInputFormat {
19+
self.ptr.as_ptr()
1920
}
20-
}
2121

22-
impl Input {
23-
pub fn name(&self) -> &str {
22+
pub fn name(self) -> &'static str {
2423
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
2524
}
2625

27-
pub fn description(&self) -> &str {
26+
pub fn description(self) -> &'static str {
2827
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
2928
}
3029

31-
pub fn extensions(&self) -> Vec<&str> {
30+
pub fn flags(self) -> Flags {
31+
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
32+
}
33+
34+
pub fn extensions(self) -> Vec<&'static str> {
3235
unsafe {
3336
let ptr = (*self.as_ptr()).extensions;
3437

@@ -40,7 +43,7 @@ impl Input {
4043
}
4144
}
4245

43-
pub fn mime_types(&self) -> Vec<&str> {
46+
pub fn mime_types(self) -> Vec<&'static str> {
4447
unsafe {
4548
let ptr = (*self.as_ptr()).mime_type;
4649

src/format/format/iter.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@ impl Iterator for DemuxerIter {
2626
fn next(&mut self) -> Option<Self::Item> {
2727
unsafe {
2828
let next = av_demuxer_iterate(&mut self.ptr);
29-
if next.is_null() {
30-
None
31-
} else {
32-
Some(Input::wrap(next as _))
33-
}
29+
Input::from_raw(next)
3430
}
3531
}
3632
}
@@ -57,11 +53,7 @@ impl Iterator for MuxerIter {
5753
fn next(&mut self) -> Option<Self::Item> {
5854
unsafe {
5955
let next = av_muxer_iterate(&mut self.ptr);
60-
if next.is_null() {
61-
None
62-
} else {
63-
Some(Output::wrap(next as _))
64-
}
56+
Output::from_raw(next)
6557
}
6658
}
6759
}

src/format/format/output.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,39 @@
11
use std::path::Path;
22

33
use std::ffi::CString;
4-
use std::ptr;
4+
use std::ptr::{self, NonNull};
55

66
use super::Flags;
77
use crate::ffi::*;
88
use crate::{codec, media, utils};
99

10+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1011
pub struct Output {
11-
ptr: *mut AVOutputFormat,
12+
ptr: NonNull<AVOutputFormat>,
1213
}
1314

1415
impl Output {
15-
pub unsafe fn wrap(ptr: *mut AVOutputFormat) -> Self {
16-
Output { ptr }
16+
pub unsafe fn from_raw(ptr: *const AVOutputFormat) -> Option<Self> {
17+
NonNull::new(ptr as *mut _).map(|ptr| Self { ptr })
1718
}
1819

19-
pub unsafe fn as_ptr(&self) -> *const AVOutputFormat {
20-
self.ptr as *const _
20+
pub fn as_ptr(self) -> *const AVOutputFormat {
21+
self.ptr.as_ptr()
2122
}
2223

23-
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVOutputFormat {
24-
self.ptr
25-
}
26-
}
27-
28-
impl Output {
29-
pub fn name(&self) -> &str {
24+
pub fn name(self) -> &'static str {
3025
unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
3126
}
3227

33-
pub fn description(&self) -> &str {
28+
pub fn description(self) -> &'static str {
3429
unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
3530
}
3631

37-
pub fn extensions(&self) -> Vec<&str> {
32+
pub fn flags(self) -> Flags {
33+
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
34+
}
35+
36+
pub fn extensions(self) -> Vec<&'static str> {
3837
unsafe {
3938
let ptr = (*self.as_ptr()).extensions;
4039

@@ -46,7 +45,7 @@ impl Output {
4645
}
4746
}
4847

49-
pub fn mime_types(&self) -> Vec<&str> {
48+
pub fn mime_types(self) -> Vec<&'static str> {
5049
unsafe {
5150
let ptr = (*self.as_ptr()).mime_type;
5251

@@ -58,9 +57,9 @@ impl Output {
5857
}
5958
}
6059

61-
pub fn codec<P: AsRef<Path>>(&self, path: &P, kind: media::Type) -> codec::Id {
60+
pub fn codec<P: AsRef<Path>>(self, path: &P, kind: media::Type) -> codec::Id {
6261
// XXX: use to_cstring when stable
63-
let path = CString::new(path.as_ref().as_os_str().to_str().unwrap()).unwrap();
62+
let path = CString::new(path.as_ref().to_str().unwrap()).unwrap();
6463

6564
unsafe {
6665
codec::Id::from(av_guess_codec(
@@ -72,8 +71,4 @@ impl Output {
7271
))
7372
}
7473
}
75-
76-
pub fn flags(&self) -> Flags {
77-
unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) }
78-
}
7974
}

src/format/mod.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,6 @@ use crate::ffi::*;
2323
use crate::utils;
2424
use crate::{Dictionary, Error};
2525

26-
#[cfg(not(feature = "ffmpeg_5_0"))]
27-
pub fn register_all() {
28-
unsafe {
29-
av_register_all();
30-
}
31-
}
32-
33-
#[cfg(not(feature = "ffmpeg_5_0"))]
34-
pub fn register_input(mut format: Input) {
35-
unsafe {
36-
av_register_input_format(format.as_mut_ptr());
37-
}
38-
}
39-
40-
#[cfg(not(feature = "ffmpeg_5_0"))]
41-
pub fn register_output(mut format: Output) {
42-
unsafe {
43-
av_register_output_format(format.as_mut_ptr());
44-
}
45-
}
46-
4726
pub fn version() -> u32 {
4827
unsafe { avformat_version() }
4928
}

src/lib.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ fn init_error() {
8383
util::error::register_all();
8484
}
8585

86-
#[cfg(all(feature = "format", not(feature = "ffmpeg_5_0")))]
87-
fn init_format() {
88-
format::register_all();
89-
}
90-
9186
#[cfg(not(feature = "format"))]
9287
fn init_format() {}
9388

@@ -109,8 +104,6 @@ fn init_filter() {}
109104

110105
pub fn init() -> Result<(), Error> {
111106
init_error();
112-
#[cfg(not(feature = "ffmpeg_5_0"))]
113-
init_format();
114107
init_device();
115108
#[cfg(not(feature = "ffmpeg_5_0"))]
116109
init_filter();

0 commit comments

Comments
 (0)