Skip to content

Commit cc8bf5f

Browse files
authored
Add support for FFmpeg 7.0 (zmwangx#178)
* FFmpeg 7.0 support * Update CI * Add ability to open decoder when `new_with_codec` was used * Add ability to open audio decoder when `new_with_codec` was used
1 parent ac918ef commit cc8bf5f

File tree

36 files changed

+492
-124
lines changed

36 files changed

+492
-124
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
container: jrottenberg/ffmpeg:${{ matrix.ffmpeg_version }}-ubuntu
1212
strategy:
1313
matrix:
14-
ffmpeg_version: ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4", "5.0", "5.1", "6.0"]
14+
ffmpeg_version: ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4", "5.0", "5.1", "6.0", "6.1"]
1515
fail-fast: false
1616
steps:
1717
- uses: actions/checkout@v2
@@ -106,22 +106,23 @@ jobs:
106106
- name: Check format
107107
run: |
108108
cargo fmt -- --check
109-
# Added only because there is no ffmpeg6.1 docker image here yet
109+
# Added only because there is no ffmpeg7.0 docker image here yet
110110
# https://github.com/jrottenberg/ffmpeg
111-
build-test-lint-latest:
112-
name: FFmpeg Latest - build, test and lint
111+
build-test-lint-7-0:
112+
name: FFmpeg 7.0 - build, test and lint
113113
runs-on: ubuntu-latest
114114
strategy:
115115
fail-fast: false
116+
env:
117+
FFMPEG_DIR: /home/runner/work/rust-ffmpeg/rust-ffmpeg/ffmpeg-7.0-linux-clang-default
116118
steps:
117119
- uses: actions/checkout@v2
118120
- name: Install dependencies
119121
run: |
120122
sudo apt update
121-
sudo apt install -y software-properties-common
122-
sudo add-apt-repository ppa:ubuntuhandbook1/ffmpeg6
123-
sudo apt update
124-
sudo apt install -y --no-install-recommends clang curl pkg-config ffmpeg libavutil-dev libavcodec-dev libavformat-dev libavfilter-dev libavfilter-dev libavdevice-dev libswresample-dev
123+
sudo apt install -y --no-install-recommends clang curl pkg-config xz-utils libxv-dev
124+
curl -L https://sourceforge.net/projects/avbuild/files/linux/ffmpeg-7.0-linux-clang-default.tar.xz/download -o ffmpeg.tar.xz
125+
tar -xf ffmpeg.tar.xz
125126
- name: Set up Rust
126127
uses: actions-rs/toolchain@v1
127128
with:

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ffmpeg-next"
3-
version = "6.1.1"
3+
version = "7.0.0"
44
build = "build.rs"
55

66
authors = ["meh. <[email protected]>", "Zhiming Wang <[email protected]>"]
@@ -106,12 +106,12 @@ rpi = []
106106

107107
[dependencies]
108108
libc = "0.2"
109-
bitflags = "1.2"
109+
bitflags = "2.5"
110110

111111
[dependencies.image]
112-
version = "0.23"
112+
version = "0.25"
113113
optional = true
114114

115115
[dependencies.ffmpeg-sys-next]
116-
version = "6.1.0"
116+
version = "7.0.0"
117117
default-features = false

examples/transcode-audio.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ fn transcoder<P: AsRef<Path> + ?Sized>(
9999

100100
encoder.set_rate(decoder.rate() as i32);
101101
encoder.set_channel_layout(channel_layout);
102-
encoder.set_channels(channel_layout.channels());
102+
#[cfg(not(feature = "ffmpeg_7_0"))]
103+
{
104+
encoder.set_channels(channel_layout.channels());
105+
}
103106
encoder.set_format(
104107
codec
105108
.formats()

src/codec/audio.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ impl Audio {
3838

3939
pub fn channel_layouts(&self) -> Option<ChannelLayoutIter> {
4040
unsafe {
41-
if (*self.codec.as_ptr()).channel_layouts.is_null() {
41+
#[cfg(not(feature = "ffmpeg_7_0"))]
42+
let ptr = (*self.codec.as_ptr()).channel_layouts;
43+
44+
#[cfg(feature = "ffmpeg_7_0")]
45+
let ptr = (*self.codec.as_ptr()).ch_layouts;
46+
47+
if ptr.is_null() {
4248
None
4349
} else {
44-
Some(ChannelLayoutIter::new(
45-
(*self.codec.as_ptr()).channel_layouts,
46-
))
50+
Some(ChannelLayoutIter::new(ptr))
4751
}
4852
}
4953
}
@@ -111,18 +115,23 @@ impl Iterator for FormatIter {
111115
}
112116
}
113117

118+
#[cfg(not(feature = "ffmpeg_7_0"))]
119+
type ChannelLayoutType = u64;
120+
#[cfg(feature = "ffmpeg_7_0")]
121+
type ChannelLayoutType = AVChannelLayout;
122+
114123
pub struct ChannelLayoutIter {
115-
ptr: *const u64,
124+
ptr: *const ChannelLayoutType,
116125
}
117126

118127
impl ChannelLayoutIter {
119-
pub fn new(ptr: *const u64) -> Self {
128+
pub fn new(ptr: *const ChannelLayoutType) -> Self {
120129
ChannelLayoutIter { ptr }
121130
}
122131

123132
pub fn best(self, max: i32) -> ChannelLayout {
124133
self.fold(ChannelLayout::MONO, |acc, cur| {
125-
if cur.channels() > acc.channels() && cur.channels() <= max {
134+
if cur.channels() > acc.channels() && cur.channels() <= max as _ {
126135
cur
127136
} else {
128137
acc
@@ -136,11 +145,22 @@ impl Iterator for ChannelLayoutIter {
136145

137146
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
138147
unsafe {
148+
#[cfg(not(feature = "ffmpeg_7_0"))]
139149
if *self.ptr == 0 {
140150
return None;
141151
}
142152

153+
#[cfg(feature = "ffmpeg_7_0")]
154+
if self.ptr.is_null() || (*self.ptr).u.mask == 0 {
155+
return None;
156+
}
157+
158+
#[cfg(not(feature = "ffmpeg_7_0"))]
143159
let layout = ChannelLayout::from_bits_truncate(*self.ptr);
160+
161+
#[cfg(feature = "ffmpeg_7_0")]
162+
let layout = ChannelLayout::from(*self.ptr);
163+
144164
self.ptr = self.ptr.offset(1);
145165

146166
Some(layout)

src/codec/capabilities.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ffi::*;
22
use libc::c_uint;
33

44
bitflags! {
5+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
56
pub struct Capabilities: c_uint {
67
const DRAW_HORIZ_BAND = AV_CODEC_CAP_DRAW_HORIZ_BAND;
78
const DR1 = AV_CODEC_CAP_DR1;

src/codec/debug.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ffi::*;
22
use libc::c_int;
33

44
bitflags! {
5+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
56
pub struct Debug: c_int {
67
const PICT_INFO = FF_DEBUG_PICT_INFO;
78
const RC = FF_DEBUG_RC;

src/codec/decoder/audio.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,15 @@ impl Audio {
4848
}
4949

5050
pub fn channels(&self) -> u16 {
51-
unsafe { (*self.as_ptr()).channels as u16 }
51+
#[cfg(not(feature = "ffmpeg_7_0"))]
52+
unsafe {
53+
(*self.as_ptr()).channels as u16
54+
}
55+
56+
#[cfg(feature = "ffmpeg_7_0")]
57+
{
58+
self.channel_layout().channels() as u16
59+
}
5260
}
5361

5462
pub fn format(&self) -> format::Sample {
@@ -62,23 +70,48 @@ impl Audio {
6270
}
6371

6472
pub fn frames(&self) -> usize {
65-
unsafe { (*self.as_ptr()).frame_number as usize }
73+
#[cfg(not(feature = "ffmpeg_7_0"))]
74+
unsafe {
75+
(*self.as_ptr()).frame_number as usize
76+
}
77+
78+
#[cfg(feature = "ffmpeg_7_0")]
79+
unsafe {
80+
(*self.as_ptr()).frame_num as usize
81+
}
6682
}
6783

6884
pub fn align(&self) -> usize {
6985
unsafe { (*self.as_ptr()).block_align as usize }
7086
}
7187

7288
pub fn channel_layout(&self) -> ChannelLayout {
73-
unsafe { ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout) }
89+
#[cfg(not(feature = "ffmpeg_7_0"))]
90+
unsafe {
91+
ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout)
92+
}
93+
94+
#[cfg(feature = "ffmpeg_7_0")]
95+
unsafe {
96+
ChannelLayout::from((*self.as_ptr()).ch_layout)
97+
}
7498
}
7599

76100
pub fn set_channel_layout(&mut self, value: ChannelLayout) {
77101
unsafe {
78-
(*self.as_mut_ptr()).channel_layout = value.bits();
102+
#[cfg(not(feature = "ffmpeg_7_0"))]
103+
{
104+
(*self.as_mut_ptr()).channel_layout = value.bits();
105+
}
106+
107+
#[cfg(feature = "ffmpeg_7_0")]
108+
{
109+
(*self.as_mut_ptr()).ch_layout = value.into();
110+
}
79111
}
80112
}
81113

114+
#[cfg(not(feature = "ffmpeg_7_0"))]
82115
pub fn request_channel_layout(&mut self, value: ChannelLayout) {
83116
unsafe {
84117
(*self.as_mut_ptr()).request_channel_layout = value.bits();

src/codec/decoder/check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ffi::*;
22
use libc::c_int;
33

44
bitflags! {
5+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
56
pub struct Check: c_int {
67
const CRC = AV_EF_CRCCHECK;
78
const BISTREAM = AV_EF_BITSTREAM;

src/codec/decoder/conceal.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ffi::*;
22
use libc::c_int;
33

44
bitflags! {
5+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
56
pub struct Conceal: c_int {
67
const GUESS_MVS = FF_EC_GUESS_MVS;
78
const DEBLOCK = FF_EC_DEBLOCK;

src/codec/decoder/decoder.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,19 @@ impl Decoder {
5454
}
5555

5656
pub fn video(self) -> Result<Video, Error> {
57-
if let Some(codec) = super::find(self.id()) {
57+
if let Some(codec) = self.codec() {
58+
self.open_as(codec).and_then(|o| o.video())
59+
} else if let Some(codec) = super::find(self.id()) {
5860
self.open_as(codec).and_then(|o| o.video())
5961
} else {
6062
Err(Error::DecoderNotFound)
6163
}
6264
}
6365

6466
pub fn audio(self) -> Result<Audio, Error> {
65-
if let Some(codec) = super::find(self.id()) {
67+
if let Some(codec) = self.codec() {
68+
self.open_as(codec).and_then(|o| o.audio())
69+
} else if let Some(codec) = super::find(self.id()) {
6670
self.open_as(codec).and_then(|o| o.audio())
6771
} else {
6872
Err(Error::DecoderNotFound)

0 commit comments

Comments
 (0)