From c6dd54003ebe734c05812a3fb9d6c358c703ae4b Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Tue, 7 Mar 2023 13:21:39 -0500 Subject: [PATCH] Support ffmpeg 6.0 Closes #6 --- .github/workflows/build.yml | 3 +- Cargo.toml | 2 +- src/codec/capabilities.rs | 6 +++ src/codec/context.rs | 6 ++- src/codec/flag.rs | 1 + src/codec/id.rs | 93 ++++++++++++++++++++++++++++++++++ src/codec/threading.rs | 3 ++ src/filter/filter.rs | 16 ++++-- src/util/format/pixel.rs | 99 +++++++++++++++++++++++++++++++++++++ src/util/frame/side_data.rs | 9 ++++ 10 files changed, 231 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f6823e..97067a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,8 @@ jobs: container: jrottenberg/ffmpeg:${{ matrix.ffmpeg_version }}-ubuntu strategy: matrix: - ffmpeg_version: ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4", "5.0", "5.1"] + ffmpeg_version: + ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4", "5.0", "5.1", "6.0"] fail-fast: false steps: - uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index e8611a2..df936f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,7 +117,7 @@ version = "0.24" optional = true [dependencies.ffmpeg-sys-the-third] -version = "1.0.0" +version = "1.1.0" default-features = false [dependencies.serde] diff --git a/src/codec/capabilities.rs b/src/codec/capabilities.rs index 94493b0..0c5a611 100644 --- a/src/codec/capabilities.rs +++ b/src/codec/capabilities.rs @@ -5,6 +5,7 @@ bitflags! { pub struct Capabilities: c_uint { const DRAW_HORIZ_BAND = AV_CODEC_CAP_DRAW_HORIZ_BAND; const DR1 = AV_CODEC_CAP_DR1; + #[cfg(not(feature = "ffmpeg_6_0"))] const TRUNCATED = AV_CODEC_CAP_TRUNCATED; const DELAY = AV_CODEC_CAP_DELAY; const SMALL_LAST_FRAME = AV_CODEC_CAP_SMALL_LAST_FRAME; @@ -16,9 +17,14 @@ bitflags! { const FRAME_THREADS = AV_CODEC_CAP_FRAME_THREADS; const SLICE_THREADS = AV_CODEC_CAP_SLICE_THREADS; const PARAM_CHANGE = AV_CODEC_CAP_PARAM_CHANGE; + #[cfg(not(feature = "ffmpeg_6_0"))] const AUTO_THREADS = AV_CODEC_CAP_AUTO_THREADS; + #[cfg(feature = "ffmpeg_6_0")] + const OTHER_THREADS = AV_CODEC_CAP_OTHER_THREADS; const VARIABLE_FRAME_SIZE = AV_CODEC_CAP_VARIABLE_FRAME_SIZE; + #[cfg(not(feature = "ffmpeg_6_0"))] const INTRA_ONLY = AV_CODEC_CAP_INTRA_ONLY; + #[cfg(not(feature = "ffmpeg_6_0"))] const LOSSLESS = AV_CODEC_CAP_LOSSLESS; } } diff --git a/src/codec/context.rs b/src/codec/context.rs index a933362..d0dd1aa 100644 --- a/src/codec/context.rs +++ b/src/codec/context.rs @@ -101,7 +101,10 @@ impl Context { unsafe { (*self.as_mut_ptr()).thread_type = config.kind.into(); (*self.as_mut_ptr()).thread_count = config.count as c_int; - (*self.as_mut_ptr()).thread_safe_callbacks = i32::from(config.safe); + #[cfg(not(feature = "ffmpeg_6_0"))] + { + (*self.as_mut_ptr()).thread_safe_callbacks = i32::from(config.safe); + } } } @@ -110,6 +113,7 @@ impl Context { threading::Config { kind: threading::Type::from((*self.as_ptr()).active_thread_type), count: (*self.as_ptr()).thread_count as usize, + #[cfg(not(feature = "ffmpeg_6_0"))] safe: (*self.as_ptr()).thread_safe_callbacks != 0, } } diff --git a/src/codec/flag.rs b/src/codec/flag.rs index 186f5f6..c03e65c 100644 --- a/src/codec/flag.rs +++ b/src/codec/flag.rs @@ -12,6 +12,7 @@ bitflags! { const PASS2 = AV_CODEC_FLAG_PASS2; const GRAY = AV_CODEC_FLAG_GRAY; const PSNR = AV_CODEC_FLAG_PSNR; + #[cfg(not(feature = "ffmpeg_6_0"))] const TRUNCATED = AV_CODEC_FLAG_TRUNCATED; const INTERLACED_DCT = AV_CODEC_FLAG_INTERLACED_DCT; const LOW_DELAY = AV_CODEC_FLAG_LOW_DELAY; diff --git a/src/codec/id.rs b/src/codec/id.rs index 4aefba6..4bb58d6 100644 --- a/src/codec/id.rs +++ b/src/codec/id.rs @@ -616,6 +616,37 @@ pub enum Id { PHM, #[cfg(feature = "ffmpeg_5_1")] DFPWM, + + #[cfg(feature = "ffmpeg_6_0")] + RADIANCE_HDR, + #[cfg(feature = "ffmpeg_6_0")] + WBMP, + #[cfg(feature = "ffmpeg_6_0")] + MEDIA100, + #[cfg(feature = "ffmpeg_6_0")] + VQC, + #[cfg(feature = "ffmpeg_6_0")] + ADPCM_XMD, + #[cfg(feature = "ffmpeg_6_0")] + WADY_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + CBD2_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + BONK, + #[cfg(feature = "ffmpeg_6_0")] + MISC4, + #[cfg(feature = "ffmpeg_6_0")] + APAC, + #[cfg(feature = "ffmpeg_6_0")] + FTR, + #[cfg(feature = "ffmpeg_6_0")] + WAVARC, + #[cfg(feature = "ffmpeg_6_0")] + RKA, + #[cfg(feature = "ffmpeg_6_0")] + VNULL, + #[cfg(feature = "ffmpeg_6_0")] + ANULL, } impl Id { @@ -1237,6 +1268,37 @@ impl From for Id { #[cfg(feature = "ffmpeg_5_1")] AV_CODEC_ID_DFPWM => Id::DFPWM, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_RADIANCE_HDR => Id::RADIANCE_HDR, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_WBMP => Id::WBMP, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_MEDIA100 => Id::MEDIA100, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_VQC => Id::VQC, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_ADPCM_XMD => Id::ADPCM_XMD, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_WADY_DPCM => Id::WADY_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_CBD2_DPCM => Id::CBD2_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_BONK => Id::BONK, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_MISC4 => Id::MISC4, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_APAC => Id::APAC, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_FTR => Id::FTR, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_WAVARC => Id::WAVARC, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_RKA => Id::RKA, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_VNULL => Id::VNULL, + #[cfg(feature = "ffmpeg_6_0")] + AV_CODEC_ID_ANULL => Id::ANULL, + #[cfg(feature = "non-exhaustive-enums")] _ => unimplemented!(), } @@ -1851,6 +1913,37 @@ impl From for AVCodecID { Id::PHM => AV_CODEC_ID_PHM, #[cfg(feature = "ffmpeg_5_1")] Id::DFPWM => AV_CODEC_ID_DFPWM, + + #[cfg(feature = "ffmpeg_6_0")] + Id::RADIANCE_HDR => AV_CODEC_ID_RADIANCE_HDR, + #[cfg(feature = "ffmpeg_6_0")] + Id::WBMP => AV_CODEC_ID_WBMP, + #[cfg(feature = "ffmpeg_6_0")] + Id::MEDIA100 => AV_CODEC_ID_MEDIA100, + #[cfg(feature = "ffmpeg_6_0")] + Id::VQC => AV_CODEC_ID_VQC, + #[cfg(feature = "ffmpeg_6_0")] + Id::ADPCM_XMD => AV_CODEC_ID_ADPCM_XMD, + #[cfg(feature = "ffmpeg_6_0")] + Id::WADY_DPCM => AV_CODEC_ID_WADY_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + Id::CBD2_DPCM => AV_CODEC_ID_CBD2_DPCM, + #[cfg(feature = "ffmpeg_6_0")] + Id::BONK => AV_CODEC_ID_BONK, + #[cfg(feature = "ffmpeg_6_0")] + Id::MISC4 => AV_CODEC_ID_MISC4, + #[cfg(feature = "ffmpeg_6_0")] + Id::APAC => AV_CODEC_ID_APAC, + #[cfg(feature = "ffmpeg_6_0")] + Id::FTR => AV_CODEC_ID_FTR, + #[cfg(feature = "ffmpeg_6_0")] + Id::WAVARC => AV_CODEC_ID_WAVARC, + #[cfg(feature = "ffmpeg_6_0")] + Id::RKA => AV_CODEC_ID_RKA, + #[cfg(feature = "ffmpeg_6_0")] + Id::VNULL => AV_CODEC_ID_VNULL, + #[cfg(feature = "ffmpeg_6_0")] + Id::ANULL => AV_CODEC_ID_ANULL, } } } diff --git a/src/codec/threading.rs b/src/codec/threading.rs index 2a9bc12..1bc6d9e 100644 --- a/src/codec/threading.rs +++ b/src/codec/threading.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; pub struct Config { pub kind: Type, pub count: usize, + #[cfg(not(feature = "ffmpeg_6_0"))] pub safe: bool, } @@ -25,6 +26,7 @@ impl Config { } } + #[cfg(not(feature = "ffmpeg_6_0"))] pub fn safe(value: bool) -> Self { Config { safe: value, @@ -38,6 +40,7 @@ impl Default for Config { Config { kind: Type::None, count: 0, + #[cfg(not(feature = "ffmpeg_6_0"))] safe: false, } } diff --git a/src/filter/filter.rs b/src/filter/filter.rs index 9384189..8140083 100644 --- a/src/filter/filter.rs +++ b/src/filter/filter.rs @@ -47,7 +47,10 @@ impl Filter { if ptr.is_null() { None } else { - Some(PadIter::new((*self.as_ptr()).inputs)) + Some(PadIter::new( + (*self.as_ptr()).inputs, + (*self.as_ptr()).nb_inputs as isize, + )) } } } @@ -59,7 +62,10 @@ impl Filter { if ptr.is_null() { None } else { - Some(PadIter::new((*self.as_ptr()).outputs)) + Some(PadIter::new( + (*self.as_ptr()).outputs, + (*self.as_ptr()).nb_outputs as isize, + )) } } } @@ -71,15 +77,17 @@ impl Filter { pub struct PadIter<'a> { ptr: *const AVFilterPad, + count: isize, cur: isize, _marker: PhantomData<&'a ()>, } impl<'a> PadIter<'a> { - pub fn new(ptr: *const AVFilterPad) -> Self { + pub fn new(ptr: *const AVFilterPad, count: isize) -> Self { PadIter { ptr, + count, cur: 0, _marker: PhantomData, } @@ -91,7 +99,7 @@ impl<'a> Iterator for PadIter<'a> { fn next(&mut self) -> Option { unsafe { - if self.cur >= avfilter_pad_count(self.ptr) as isize { + if self.cur >= self.count { return None; } diff --git a/src/util/format/pixel.rs b/src/util/format/pixel.rs index d9d1cf0..6910fc8 100644 --- a/src/util/format/pixel.rs +++ b/src/util/format/pixel.rs @@ -371,6 +371,39 @@ pub enum Pixel { #[cfg(feature = "ffmpeg_5_0")] P416LE, + #[cfg(feature = "ffmpeg_6_0")] + VUYA, + #[cfg(feature = "ffmpeg_6_0")] + RGBAF16BE, + #[cfg(feature = "ffmpeg_6_0")] + RGBAF16LE, + #[cfg(feature = "ffmpeg_6_0")] + VUYX, + #[cfg(feature = "ffmpeg_6_0")] + P012LE, + #[cfg(feature = "ffmpeg_6_0")] + P012BE, + #[cfg(feature = "ffmpeg_6_0")] + Y212BE, + #[cfg(feature = "ffmpeg_6_0")] + Y212LE, + #[cfg(feature = "ffmpeg_6_0")] + XV30BE, + #[cfg(feature = "ffmpeg_6_0")] + XV30LE, + #[cfg(feature = "ffmpeg_6_0")] + XV36BE, + #[cfg(feature = "ffmpeg_6_0")] + XV36LE, + #[cfg(feature = "ffmpeg_6_0")] + RGBF32BE, + #[cfg(feature = "ffmpeg_6_0")] + RGBF32LE, + #[cfg(feature = "ffmpeg_6_0")] + RGBAF32BE, + #[cfg(feature = "ffmpeg_6_0")] + RGBAF32LE, + #[cfg(feature = "rpi")] RPI, #[cfg(feature = "rpi")] @@ -733,6 +766,39 @@ impl From for Pixel { #[cfg(feature = "ffmpeg_5_0")] AV_PIX_FMT_P416LE => Pixel::P416LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_VUYA => Pixel::VUYA, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBAF16BE => Pixel::RGBAF16BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBAF16LE => Pixel::RGBAF16LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_VUYX => Pixel::VUYX, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_P012LE => Pixel::P012LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_P012BE => Pixel::P012BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_Y212BE => Pixel::Y212BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_Y212LE => Pixel::Y212LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_XV30BE => Pixel::XV30BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_XV30LE => Pixel::XV30LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_XV36BE => Pixel::XV36BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_XV36LE => Pixel::XV36LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBF32BE => Pixel::RGBF32BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBF32LE => Pixel::RGBF32LE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBAF32BE => Pixel::RGBAF32BE, + #[cfg(feature = "ffmpeg_6_0")] + AV_PIX_FMT_RGBAF32LE => Pixel::RGBAF32LE, + #[cfg(feature = "rpi")] AV_PIX_FMT_RPI => Pixel::RPI, #[cfg(feature = "rpi")] @@ -1116,6 +1182,39 @@ impl From for AVPixelFormat { #[cfg(feature = "ffmpeg_5_0")] Pixel::P416LE => AV_PIX_FMT_P416LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::VUYA => AV_PIX_FMT_VUYA, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBAF16BE => AV_PIX_FMT_RGBAF16BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBAF16LE => AV_PIX_FMT_RGBAF16LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::VUYX => AV_PIX_FMT_VUYX, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::P012LE => AV_PIX_FMT_P012LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::P012BE => AV_PIX_FMT_P012BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::Y212BE => AV_PIX_FMT_Y212BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::Y212LE => AV_PIX_FMT_Y212LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::XV30BE => AV_PIX_FMT_XV30BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::XV30LE => AV_PIX_FMT_XV30LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::XV36BE => AV_PIX_FMT_XV36BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::XV36LE => AV_PIX_FMT_XV36LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBF32BE => AV_PIX_FMT_RGBF32BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBF32LE => AV_PIX_FMT_RGBF32LE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBAF32BE => AV_PIX_FMT_RGBAF32BE, + #[cfg(feature = "ffmpeg_6_0")] + Pixel::RGBAF32LE => AV_PIX_FMT_RGBAF32LE, + #[cfg(feature = "rpi")] Pixel::RPI => AV_PIX_FMT_RPI, #[cfg(feature = "rpi")] diff --git a/src/util/frame/side_data.rs b/src/util/frame/side_data.rs index bcf088a..3dcaf93 100644 --- a/src/util/frame/side_data.rs +++ b/src/util/frame/side_data.rs @@ -61,6 +61,9 @@ pub enum Type { #[cfg(feature = "ffmpeg_5_1")] DYNAMIC_HDR_VIVID, + + #[cfg(feature = "ffmpeg_6_0")] + AMBIENT_VIEWING_ENVIRONMENT, } impl Type { @@ -124,6 +127,9 @@ impl From for Type { #[cfg(feature = "ffmpeg_5_1")] AV_FRAME_DATA_DYNAMIC_HDR_VIVID => Type::DYNAMIC_HDR_VIVID, + #[cfg(feature = "ffmpeg_6_0")] + AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT => Type::AMBIENT_VIEWING_ENVIRONMENT, + #[cfg(feature = "non-exhaustive-enums")] _ => unimplemented!(), } @@ -181,6 +187,9 @@ impl From for AVFrameSideDataType { #[cfg(feature = "ffmpeg_5_1")] Type::DYNAMIC_HDR_VIVID => AV_FRAME_DATA_DYNAMIC_HDR_VIVID, + + #[cfg(feature = "ffmpeg_6_0")] + Type::AMBIENT_VIEWING_ENVIRONMENT => AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, } } }