Bump version to use ffmpeg 5

This commit is contained in:
Polochon-street 2022-01-24 21:03:47 +01:00
parent 5ed41c84ff
commit 22ad8b9598
43 changed files with 310 additions and 102 deletions

View File

@ -11,7 +11,7 @@ jobs:
container: jrottenberg/ffmpeg:${{ matrix.ffmpeg_version }}-ubuntu
strategy:
matrix:
ffmpeg_version: ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4"]
ffmpeg_version: ["3.4", "4.0", "4.1", "4.2", "4.3", "4.4", "5.0"]
fail-fast: false
steps:
- uses: actions/checkout@v2

View File

@ -1,6 +1,6 @@
[package]
name = "ffmpeg-next"
version = "4.4.0-next.2"
version = "5.0.0"
build = "build.rs"
authors = ["meh. <meh@schizofreni.co>", "Zhiming Wang <i@zhimingwang.org>"]
@ -113,5 +113,5 @@ version = "0.23"
optional = true
[dependencies.ffmpeg-sys-next]
version = "4.4.0-next.2"
version = "5.0.0"
default-features = false

View File

@ -18,7 +18,8 @@ fn main() -> Result<(), ffmpeg::Error> {
.ok_or(ffmpeg::Error::StreamNotFound)?;
let video_stream_index = input.index();
let mut decoder = input.codec().decoder().video()?;
let context_decoder = ffmpeg::codec::context::Context::from_parameters(input.parameters())?;
let mut decoder = context_decoder.decoder().video()?;
let mut scaler = Context::get(
decoder.format(),

View File

@ -2,7 +2,7 @@ extern crate ffmpeg_next as ffmpeg;
use std::env;
fn main() {
fn main() -> Result<(), ffmpeg::Error> {
ffmpeg::init().unwrap();
match ffmpeg::format::input(&env::args().nth(1).expect("missing file")) {
@ -42,7 +42,7 @@ fn main() {
println!("\tdiscard: {:?}", stream.discard());
println!("\trate: {}", stream.rate());
let codec = stream.codec();
let codec = ffmpeg::codec::context::Context::from_parameters(stream.parameters())?;
println!("\tmedium: {:?}", codec.medium());
println!("\tid: {:?}", codec.id());
@ -78,7 +78,6 @@ fn main() {
println!("\taudio.frames: {}", audio.frames());
println!("\taudio.align: {}", audio.align());
println!("\taudio.channel_layout: {:?}", audio.channel_layout());
println!("\taudio.frame_start: {:?}", audio.frame_start());
}
}
}
@ -86,4 +85,5 @@ fn main() {
Err(error) => println!("error: {}", error),
}
Ok(())
}

View File

@ -18,7 +18,7 @@ fn main() {
let mut ist_time_bases = vec![Rational(0, 1); ictx.nb_streams() as _];
let mut ost_index = 0;
for (ist_index, ist) in ictx.streams().enumerate() {
let ist_medium = ist.codec().medium();
let ist_medium = ist.parameters().medium();
if ist_medium != media::Type::Audio
&& ist_medium != media::Type::Video
&& ist_medium != media::Type::Subtitle

View File

@ -72,7 +72,8 @@ fn transcoder<P: AsRef<Path>>(
.streams()
.best(media::Type::Audio)
.expect("could not find best audio stream");
let mut decoder = input.codec().decoder().audio()?;
let context = ffmpeg::codec::context::Context::from_parameters(input.parameters())?;
let mut decoder = context.decoder().audio()?;
let codec = ffmpeg::encoder::find(octx.format().codec(path, media::Type::Audio))
.expect("failed to find encoder")
.audio()?;
@ -84,7 +85,8 @@ fn transcoder<P: AsRef<Path>>(
decoder.set_parameters(input.parameters())?;
let mut output = octx.add_stream(codec)?;
let mut encoder = output.codec().encoder().audio()?;
let context = ffmpeg::codec::context::Context::from_parameters(output.parameters())?;
let mut encoder = context.encoder().audio()?;
let channel_layout = codec
.channel_layouts()

View File

@ -47,9 +47,13 @@ impl Transcoder {
enable_logging: bool,
) -> Result<Self, ffmpeg::Error> {
let global_header = octx.format().flags().contains(format::Flags::GLOBAL_HEADER);
let decoder = ist.codec().decoder().video()?;
let decoder = ffmpeg::codec::context::Context::from_parameters(ist.parameters())?
.decoder()
.video()?;
let mut ost = octx.add_stream(encoder::find(codec::Id::H264))?;
let mut encoder = ost.codec().encoder().video()?;
let mut encoder = codec::context::Context::from_parameters(ost.parameters())?
.encoder()
.video()?;
encoder.set_height(decoder.height());
encoder.set_width(decoder.width());
encoder.set_aspect_ratio(decoder.aspect_ratio());
@ -59,15 +63,20 @@ impl Transcoder {
if global_header {
encoder.set_flags(codec::Flags::GLOBAL_HEADER);
}
encoder
.open_with(x264_opts)
.expect("error opening libx264 encoder with supplied settings");
encoder = ost.codec().encoder().video()?;
ost.set_parameters(encoder);
encoder = codec::context::Context::from_parameters(ost.parameters())?
.encoder()
.video()?;
ost.set_parameters(&encoder);
Ok(Self {
ost_index,
decoder,
encoder: ost.codec().encoder().video()?,
encoder: codec::context::Context::from_parameters(ost.parameters())?
.encoder()
.video()?,
logging_enabled: enable_logging,
frame_count: 0,
last_log_frame_count: 0,
@ -184,7 +193,7 @@ fn main() {
let mut transcoders = HashMap::new();
let mut ost_index = 0;
for (ist_index, ist) in ictx.streams().enumerate() {
let ist_medium = ist.codec().medium();
let ist_medium = ist.parameters().medium();
if ist_medium != media::Type::Audio
&& ist_medium != media::Type::Video
&& ist_medium != media::Type::Subtitle

View File

@ -88,7 +88,7 @@ impl Codec {
}
pub fn max_lowres(&self) -> i32 {
unsafe { av_codec_get_max_lowres(self.as_ptr()) }
unsafe { (*self.as_ptr()).max_lowres.into() }
}
pub fn capabilities(&self) -> Capabilities {

View File

@ -41,6 +41,18 @@ impl Context {
}
}
pub fn from_parameters<P: Into<Parameters>>(parameters: P) -> Result<Self, Error> {
let parameters = parameters.into();
let mut context = Self::new();
unsafe {
match avcodec_parameters_to_context(context.as_mut_ptr(), parameters.as_ptr()) {
e if e < 0 => Err(Error::from(e)),
_ => Ok(context),
}
}
}
pub fn decoder(self) -> Decoder {
Decoder(self)
}
@ -131,6 +143,7 @@ impl Drop for Context {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
impl Clone for Context {
fn clone(&self) -> Self {
let mut ctx = Context::new();
@ -141,6 +154,7 @@ impl Clone for Context {
fn clone_from(&mut self, source: &Self) {
unsafe {
// Removed in ffmpeg >= 5.0.
avcodec_copy_context(self.as_mut_ptr(), source.as_ptr());
}
}

View File

@ -1,13 +1,18 @@
use std::ops::{Deref, DerefMut};
#[cfg(not(feature = "ffmpeg_5_0"))]
use ffi::*;
#[cfg(not(feature = "ffmpeg_5_0"))]
use libc::c_int;
use super::Opened;
use codec::Context;
#[cfg(not(feature = "ffmpeg_5_0"))]
use frame;
use util::format;
use {packet, AudioService, ChannelLayout, Error};
#[cfg(not(feature = "ffmpeg_5_0"))]
use {packet, Error};
use {AudioService, ChannelLayout};
pub struct Audio(pub Opened);
@ -17,6 +22,7 @@ impl Audio {
note = "Underlying API avcodec_decode_audio4 has been deprecated since FFmpeg 3.1; \
consider switching to send_packet() and receive_frame()"
)]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn decode<P: packet::Ref>(
&mut self,
packet: &P,
@ -91,8 +97,11 @@ impl Audio {
unsafe { (*self.as_ptr()).frame_size as u32 }
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn frame_start(&self) -> Option<usize> {
unsafe {
// Removed in ffmpeg >= 5.0 in favor of using encoder
// private options.
match (*self.as_ptr()).timecode_frame_start {
-1 => None,
n => Some(n as usize),

View File

@ -34,7 +34,7 @@ pub fn new() -> Decoder {
pub fn find(id: Id) -> Option<Codec> {
unsafe {
let ptr = avcodec_find_decoder(id.into());
let ptr = avcodec_find_decoder(id.into()) as *mut AVCodec;
if ptr.is_null() {
None
@ -47,7 +47,7 @@ pub fn find(id: Id) -> Option<Codec> {
pub fn find_by_name(name: &str) -> Option<Codec> {
unsafe {
let name = CString::new(name).unwrap();
let ptr = avcodec_find_decoder_by_name(name.as_ptr());
let ptr = avcodec_find_decoder_by_name(name.as_ptr()) as *mut AVCodec;
if ptr.is_null() {
None

View File

@ -1,15 +1,19 @@
use std::ops::{Deref, DerefMut};
#[cfg(not(feature = "ffmpeg_5_0"))]
use ffi::*;
use libc::c_int;
use super::{slice, Opened};
use codec::Context;
use color;
#[cfg(not(feature = "ffmpeg_5_0"))]
use frame;
use util::chroma;
use util::format;
use {packet, Error, FieldOrder, Rational};
#[cfg(not(feature = "ffmpeg_5_0"))]
use {packet, Error};
use {FieldOrder, Rational};
pub struct Video(pub Opened);
@ -19,6 +23,7 @@ impl Video {
note = "Underlying API avcodec_decode_video2 has been deprecated since FFmpeg 3.1; \
consider switching to send_packet() and receive_frame()"
)]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn decode<P: packet::Ref>(
&mut self,
packet: &P,

View File

@ -2,12 +2,15 @@ use std::ops::{Deref, DerefMut};
use std::ptr;
use ffi::*;
#[cfg(not(feature = "ffmpeg_5_0"))]
use libc::c_int;
use super::Encoder as Super;
use codec::{traits, Context};
use util::format;
use {frame, packet, ChannelLayout, Dictionary, Error};
#[cfg(not(feature = "ffmpeg_5_0"))]
use {frame, packet};
use {ChannelLayout, Dictionary, Error};
pub struct Audio(pub Super);
@ -145,6 +148,7 @@ impl Encoder {
note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \
consider switching to send_frame() and receive_packet()"
)]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn encode<P: packet::Mut>(
&mut self,
frame: &frame::Audio,
@ -174,6 +178,7 @@ impl Encoder {
note = "Underlying API avcodec_encode_audio2 has been deprecated since FFmpeg 3.1; \
consider switching to send_eof() and receive_packet()"
)]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> {
unsafe {
let mut got: c_int = 0;

View File

@ -13,7 +13,9 @@ pub use self::subtitle::Encoder as Subtitle;
pub mod motion_estimation;
pub use self::motion_estimation::MotionEstimation;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub mod prediction;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub use self::prediction::Prediction;
pub mod comparison;
@ -35,7 +37,7 @@ pub fn new() -> Encoder {
pub fn find(id: Id) -> Option<Codec> {
unsafe {
let ptr = avcodec_find_encoder(id.into());
let ptr = avcodec_find_encoder(id.into()) as *mut AVCodec;
if ptr.is_null() {
None
@ -48,7 +50,7 @@ pub fn find(id: Id) -> Option<Codec> {
pub fn find_by_name(name: &str) -> Option<Codec> {
unsafe {
let name = CString::new(name).unwrap();
let ptr = avcodec_find_encoder_by_name(name.as_ptr());
let ptr = avcodec_find_encoder_by_name(name.as_ptr()) as *mut AVCodec;
if ptr.is_null() {
None

View File

@ -5,9 +5,13 @@ use ffi::*;
use libc::{c_float, c_int};
use super::Encoder as Super;
use super::{Comparison, Decision, MotionEstimation, Prediction};
use super::{Comparison, Decision};
#[cfg(not(feature = "ffmpeg_5_0"))]
use super::{MotionEstimation, Prediction};
use codec::{traits, Context};
use {color, format, frame, packet, Dictionary, Error, Rational};
use {color, format, Dictionary, Error, Rational};
#[cfg(not(feature = "ffmpeg_5_0"))]
use {frame, packet};
pub struct Video(pub Super);
@ -196,6 +200,7 @@ impl Video {
}
#[inline]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn set_prediction(&mut self, value: Prediction) {
unsafe {
(*self.as_mut_ptr()).prediction_method = value.into();
@ -252,6 +257,7 @@ impl Video {
}
#[inline]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn set_pre_me(&mut self, value: MotionEstimation) {
unsafe {
(*self.as_mut_ptr()).pre_me = value.into();
@ -421,6 +427,7 @@ impl Encoder {
consider switching to send_frame() and receive_packet()"
)]
#[inline]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn encode<P: packet::Mut>(
&mut self,
frame: &frame::Video,
@ -454,6 +461,7 @@ impl Encoder {
consider switching to send_frame() and receive_packet()"
)]
#[inline]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn flush<P: packet::Mut>(&mut self, out: &mut P) -> Result<bool, Error> {
unsafe {
let mut got: c_int = 0;

View File

@ -595,6 +595,13 @@ pub enum Id {
ADPCM_IMA_MOFLEX,
#[cfg(feature = "ffmpeg_4_4")]
FASTAUDIO,
#[cfg(feature = "ffmpeg_5_0")]
GEM,
#[cfg(feature = "ffmpeg_5_0")]
ADPCM_IMA_ACORN,
#[cfg(feature = "ffmpeg_5_0")]
MSNSIREN,
}
impl Id {
@ -1197,6 +1204,13 @@ impl From<AVCodecID> for Id {
AV_CODEC_ID_ADPCM_IMA_MOFLEX => Id::ADPCM_IMA_MOFLEX,
#[cfg(feature = "ffmpeg_4_4")]
AV_CODEC_ID_FASTAUDIO => Id::FASTAUDIO,
#[cfg(feature = "ffmpeg_5_0")]
AV_CODEC_ID_GEM => Id::GEM,
#[cfg(feature = "ffmpeg_5_0")]
AV_CODEC_ID_ADPCM_IMA_ACORN => Id::ADPCM_IMA_ACORN,
#[cfg(feature = "ffmpeg_5_0")]
AV_CODEC_ID_MSNSIREN => Id::MSNSIREN,
}
}
}
@ -1791,6 +1805,13 @@ impl From<Id> for AVCodecID {
Id::ADPCM_IMA_MOFLEX => AV_CODEC_ID_ADPCM_IMA_MOFLEX,
#[cfg(feature = "ffmpeg_4_4")]
Id::FASTAUDIO => AV_CODEC_ID_FASTAUDIO,
#[cfg(feature = "ffmpeg_5_0")]
Id::GEM => AV_CODEC_ID_GEM,
#[cfg(feature = "ffmpeg_5_0")]
Id::ADPCM_IMA_ACORN => AV_CODEC_ID_ADPCM_IMA_ACORN,
#[cfg(feature = "ffmpeg_5_0")]
Id::MSNSIREN => AV_CODEC_ID_MSNSIREN,
}
}
}

View File

@ -8,6 +8,7 @@ pub mod packet;
pub mod subtitle;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub mod picture;
pub mod discard;

View File

@ -45,7 +45,7 @@ impl<'a> Drop for Borrow<'a> {
self.packet.data = ptr::null_mut();
self.packet.size = 0;
av_free_packet(&mut self.packet);
av_packet_unref(&mut self.packet);
}
}
}

View File

@ -169,6 +169,7 @@ impl Packet {
}
#[inline]
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn convergence(&self) -> isize {
self.0.convergence_duration as isize
}
@ -263,6 +264,12 @@ impl Clone for Packet {
#[inline]
fn clone_from(&mut self, source: &Self) {
#[cfg(feature = "ffmpeg_4_0")]
unsafe {
av_packet_ref(&mut self.0, &source.0);
av_packet_make_writable(&mut self.0);
}
#[cfg(not(feature = "ffmpeg_4_0"))]
unsafe {
av_copy_packet(&mut self.0, &source.0);
}

View File

@ -51,6 +51,9 @@ pub enum Type {
#[cfg(feature = "ffmpeg_4_4")]
S12M_TIMECODE,
#[cfg(feature = "ffmpeg_5_0")]
DYNAMIC_HDR10_PLUS,
}
impl From<AVPacketSideDataType> for Type {
@ -100,6 +103,9 @@ impl From<AVPacketSideDataType> for Type {
#[cfg(feature = "ffmpeg_4_4")]
AV_PKT_DATA_S12M_TIMECODE => Type::S12M_TIMECODE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PKT_DATA_DYNAMIC_HDR10_PLUS => Type::DYNAMIC_HDR10_PLUS,
}
}
}
@ -151,6 +157,9 @@ impl From<Type> for AVPacketSideDataType {
#[cfg(feature = "ffmpeg_4_4")]
Type::S12M_TIMECODE => AV_PKT_DATA_S12M_TIMECODE,
#[cfg(feature = "ffmpeg_5_0")]
Type::DYNAMIC_HDR10_PLUS => AV_PKT_DATA_DYNAMIC_HDR10_PLUS,
}
}
}

View File

@ -4,6 +4,7 @@ use std::str::from_utf8_unchecked;
use super::{Flags, Type};
use ffi::*;
#[cfg(not(feature = "ffmpeg_5_0"))]
use {format, Picture};
pub enum Rect<'a> {
@ -87,6 +88,7 @@ impl<'a> Bitmap<'a> {
}
// XXX: must split Picture and PictureMut
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn picture(&self, format: format::Pixel) -> Picture<'a> {
unsafe {
Picture::wrap(

View File

@ -11,7 +11,7 @@ impl Iterator for AudioIter {
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
let ptr = av_input_audio_device_next(self.0);
let ptr = av_input_audio_device_next(self.0) as *mut AVInputFormat;
if ptr.is_null() && !self.0.is_null() {
None
@ -35,7 +35,7 @@ impl Iterator for VideoIter {
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
let ptr = av_input_video_device_next(self.0);
let ptr = av_input_video_device_next(self.0) as *mut AVInputFormat;
if ptr.is_null() && !self.0.is_null() {
None

View File

@ -11,12 +11,12 @@ impl Iterator for AudioIter {
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
let ptr = av_output_audio_device_next(self.0);
let ptr = av_output_audio_device_next(self.0) as *mut AVOutputFormat;
if ptr.is_null() && !self.0.is_null() {
None
} else {
self.0 = ptr;
self.0 = ptr as *mut AVOutputFormat;
Some(Format::Output(format::Output::wrap(ptr)))
}
@ -35,12 +35,12 @@ impl Iterator for VideoIter {
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
let ptr = av_output_video_device_next(self.0);
let ptr = av_output_video_device_next(self.0) as *mut AVOutputFormat;
if ptr.is_null() && !self.0.is_null() {
None
} else {
self.0 = ptr;
self.0 = ptr as *mut AVOutputFormat;
Some(Format::Output(format::Output::wrap(ptr)))
}

View File

@ -17,14 +17,17 @@ use std::ffi::{CStr, CString};
use std::str::from_utf8_unchecked;
use ffi::*;
#[cfg(not(feature = "ffmpeg_5_0"))]
use Error;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn register_all() {
unsafe {
avfilter_register_all();
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn register(filter: &Filter) -> Result<(), Error> {
unsafe {
match avfilter_register(filter.as_ptr() as *mut _) {
@ -65,6 +68,7 @@ mod tests {
#[test]
fn test_paditer() {
#[cfg(not(feature = "ffmpeg_5_0"))]
register_all();
assert_eq!(
find("overlay")

View File

@ -25,8 +25,8 @@ impl<'a> Chapter<'a> {
self.index
}
pub fn id(&self) -> i32 {
unsafe { (*self.as_ptr()).id }
pub fn id(&self) -> i64 {
unsafe { (*self.as_ptr()).id as i64 }
}
pub fn time_base(&self) -> Rational {

View File

@ -31,9 +31,9 @@ impl<'a> ChapterMut<'a> {
}
impl<'a> ChapterMut<'a> {
pub fn set_id(&mut self, value: i32) {
pub fn set_id(&mut self, value: i64) {
unsafe {
(*self.as_mut_ptr()).id = value;
(*self.as_mut_ptr()).id = value as _;
}
}

View File

@ -166,13 +166,13 @@ impl<'a> Best<'a> {
'a: 'b,
{
unsafe {
let mut decoder = ptr::null_mut();
let decoder = ptr::null_mut();
let index = av_find_best_stream(
self.context.ptr,
kind.into(),
self.wanted as c_int,
self.related as c_int,
&mut decoder,
decoder,
0,
);

View File

@ -6,7 +6,9 @@ use super::common::Context;
use super::destructor;
use ffi::*;
use util::range::Range;
use {format, Codec, Error, Packet, Stream};
#[cfg(not(feature = "ffmpeg_5_0"))]
use Codec;
use {format, Error, Packet, Stream};
pub struct Input {
ptr: *mut AVFormatContext,
@ -34,12 +36,13 @@ impl Input {
impl Input {
pub fn format(&self) -> format::Input {
unsafe { format::Input::wrap((*self.as_ptr()).iformat) }
unsafe { format::Input::wrap((*self.as_ptr()).iformat as *mut AVInputFormat) }
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn video_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_video_codec(self.as_ptr());
let ptr = (*self.as_ptr()).video_codec;
if ptr.is_null() {
None
@ -49,9 +52,10 @@ impl Input {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn audio_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_audio_codec(self.as_ptr());
let ptr = (*self.as_ptr()).audio_codec;
if ptr.is_null() {
None
@ -61,9 +65,10 @@ impl Input {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn subtitle_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_subtitle_codec(self.as_ptr());
let ptr = (*self.as_ptr()).subtitle_codec;
if ptr.is_null() {
None
@ -73,9 +78,10 @@ impl Input {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn data_codec(&self) -> Option<Codec> {
unsafe {
let ptr = av_format_get_data_codec(self.as_ptr());
let ptr = (*self.as_ptr()).data_codec;
if ptr.is_null() {
None
@ -86,7 +92,7 @@ impl Input {
}
pub fn probe_score(&self) -> i32 {
unsafe { av_format_get_probe_score(self.as_ptr()) }
unsafe { (*self.as_ptr()).probe_score }
}
pub fn packets(&mut self) -> PacketIter {

View File

@ -37,7 +37,7 @@ impl Output {
impl Output {
pub fn format(&self) -> format::Output {
unsafe { format::Output::wrap((*self.as_ptr()).oformat) }
unsafe { format::Output::wrap((*self.as_ptr()).oformat as *mut AVOutputFormat) }
}
pub fn write_header(&mut self) -> Result<(), Error> {
@ -88,7 +88,7 @@ impl Output {
pub fn add_chapter<R: Into<Rational>, S: AsRef<str>>(
&mut self,
id: i32,
id: i64,
time_base: R,
start: i64,
end: i64,

View File

@ -7,7 +7,9 @@ pub use self::input::Input;
mod output;
pub use self::output::Output;
#[cfg(not(feature = "ffmpeg_5_0"))]
mod iter;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub use self::iter::Iter;
pub enum Format {
@ -45,6 +47,7 @@ impl Format {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn list() -> Iter {
Iter::new()
}

View File

@ -10,8 +10,10 @@ pub mod context;
pub use self::context::Context;
pub mod format;
#[cfg(not(feature = "ffmpeg_5_0"))]
pub use self::format::list;
pub use self::format::{flag, Flags};
pub use self::format::{list, Input, Output};
pub use self::format::{Input, Output};
pub mod network;
@ -23,12 +25,14 @@ use std::str::from_utf8_unchecked;
use ffi::*;
use {Dictionary, Error, Format};
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn register_all() {
unsafe {
av_register_all();
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn register(format: &Format) {
match *format {
Format::Input(ref format) => unsafe {

View File

@ -26,6 +26,7 @@ impl<'a> Stream<'a> {
unsafe { (*self.as_ptr()).id }
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn codec(&self) -> codec::Context {
unsafe { codec::Context::wrap((*self.as_ptr()).codec, Some(self.context.destructor())) }
}
@ -69,7 +70,7 @@ impl<'a> Stream<'a> {
}
pub fn rate(&self) -> Rational {
unsafe { Rational::from(av_stream_get_r_frame_rate(self.as_ptr())) }
unsafe { Rational::from((*self.as_ptr()).r_frame_rate) }
}
pub fn avg_frame_rate(&self) -> Rational {

View File

@ -37,7 +37,7 @@ impl<'a> StreamMut<'a> {
pub fn set_rate<R: Into<Rational>>(&mut self, value: R) {
unsafe {
av_stream_set_r_frame_rate(self.as_mut_ptr(), value.into().into());
(*self.as_mut_ptr()).r_frame_rate = value.into().into();
}
}

View File

@ -52,7 +52,7 @@ pub use codec::discard::Discard;
pub use codec::field_order::FieldOrder;
#[cfg(feature = "codec")]
pub use codec::packet::{self, Packet};
#[cfg(feature = "codec")]
#[cfg(all(feature = "codec", not(feature = "ffmpeg_5_0")))]
pub use codec::picture::Picture;
#[cfg(feature = "codec")]
pub use codec::subtitle::{self, Subtitle};
@ -75,7 +75,7 @@ fn init_error() {
util::error::register_all();
}
#[cfg(feature = "format")]
#[cfg(all(feature = "format", not(feature = "ffmpeg_5_0")))]
fn init_format() {
format::register_all();
}
@ -91,7 +91,7 @@ fn init_device() {
#[cfg(not(feature = "device"))]
fn init_device() {}
#[cfg(feature = "filter")]
#[cfg(all(feature = "filter", not(feature = "ffmpeg_5_0")))]
fn init_filter() {
filter::register_all();
}
@ -108,8 +108,10 @@ 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();
Ok(())

View File

@ -142,7 +142,9 @@ impl Context {
input: &frame::Audio,
output: &mut frame::Audio,
) -> Result<Option<Delay>, Error> {
output.set_rate(self.output.rate);
unsafe {
(*output.as_mut_ptr()).sample_rate = self.output.rate as i32;
}
unsafe {
if output.is_empty() {
@ -165,7 +167,9 @@ impl Context {
///
/// When there are no more internal frames `Ok(None)` will be returned.
pub fn flush(&mut self, output: &mut frame::Audio) -> Result<Option<Delay>, Error> {
output.set_rate(self.output.rate);
unsafe {
(*output.as_mut_ptr()).sample_rate = self.output.rate as i32;
}
unsafe {
match swr_convert_frame(self.as_mut_ptr(), output.as_mut_ptr(), ptr::null()) {

View File

@ -13,7 +13,7 @@ impl frame::Audio {
Context::get(
self.format(),
self.channel_layout(),
self.rate(),
unsafe { (*self.as_ptr()).sample_rate as u32 },
format,
channel_layout,
rate,

View File

@ -1,7 +1,10 @@
use super::{Context, Flags};
use util::format;
use {decoder, frame, Error, Picture};
#[cfg(not(feature = "ffmpeg_5_0"))]
use Picture;
use {decoder, frame, Error};
#[cfg(not(feature = "ffmpeg_5_0"))]
impl<'a> Picture<'a> {
#[inline]
pub fn scaler(&self, width: u32, height: u32, flags: Flags) -> Result<Context, Error> {

View File

@ -50,6 +50,7 @@ impl<'a> Vector<'a> {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn value(value: f64, length: usize) -> Self {
unsafe {
Vector {
@ -60,6 +61,7 @@ impl<'a> Vector<'a> {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn identity() -> Self {
unsafe {
Vector {
@ -82,24 +84,28 @@ impl<'a> Vector<'a> {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn conv(&mut self, other: &Vector) {
unsafe {
sws_convVec(self.as_mut_ptr(), other.as_ptr() as *mut _);
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn add(&mut self, other: &Vector) {
unsafe {
sws_addVec(self.as_mut_ptr(), other.as_ptr() as *mut _);
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn sub(&mut self, other: &Vector) {
unsafe {
sws_subVec(self.as_mut_ptr(), other.as_ptr() as *mut _);
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
pub fn shift(&mut self, value: usize) {
unsafe {
sws_shiftVec(self.as_mut_ptr(), value as c_int);
@ -117,6 +123,7 @@ impl<'a> Vector<'a> {
}
}
#[cfg(not(feature = "ffmpeg_5_0"))]
impl<'a> Clone for Vector<'a> {
fn clone(&self) -> Self {
unsafe {

View File

@ -73,13 +73,13 @@ pub enum Pixel {
BGR555BE,
BGR555LE,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
VAAPI_MOCO,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
VAAPI_IDCT,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
VAAPI_VLD,
#[cfg(not(feature = "ff_api_vaapi"))]
#[cfg(any(not(feature = "ff_api_vaapi"), feature = "ffmpeg_5_0"))]
VAAPI,
YUV420P16LE,
@ -347,6 +347,27 @@ pub enum Pixel {
#[cfg(feature = "ffmpeg_4_4")]
X2RGB10BE,
#[cfg(feature = "ffmpeg_5_0")]
X2BGR10LE,
#[cfg(feature = "ffmpeg_5_0")]
X2BGR10BE,
#[cfg(feature = "ffmpeg_5_0")]
P210BE,
#[cfg(feature = "ffmpeg_5_0")]
P210LE,
#[cfg(feature = "ffmpeg_5_0")]
P410BE,
#[cfg(feature = "ffmpeg_5_0")]
P410LE,
#[cfg(feature = "ffmpeg_5_0")]
P216BE,
#[cfg(feature = "ffmpeg_5_0")]
P216LE,
#[cfg(feature = "ffmpeg_5_0")]
P416BE,
#[cfg(feature = "ffmpeg_5_0")]
P416LE,
#[cfg(feature = "rpi")]
RPI,
#[cfg(feature = "rpi")]
@ -478,12 +499,14 @@ impl From<AVPixelFormat> for Pixel {
AV_PIX_FMT_BGR555BE => Pixel::BGR555BE,
AV_PIX_FMT_BGR555LE => Pixel::BGR555LE,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
AV_PIX_FMT_VAAPI_MOCO => Pixel::VAAPI_MOCO,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
AV_PIX_FMT_VAAPI_IDCT => Pixel::VAAPI_IDCT,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
AV_PIX_FMT_VAAPI_VLD => Pixel::VAAPI_VLD,
#[cfg(any(not(feature = "ff_api_vaapi"), feature = "ffmpeg_5_0"))]
AV_PIX_FMT_VAAPI => Pixel::VAAPI,
AV_PIX_FMT_YUV420P16LE => Pixel::YUV420P16LE,
AV_PIX_FMT_YUV420P16BE => Pixel::YUV420P16BE,
@ -686,6 +709,27 @@ impl From<AVPixelFormat> for Pixel {
#[cfg(feature = "ffmpeg_4_4")]
AV_PIX_FMT_X2RGB10BE => Pixel::X2RGB10BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_X2BGR10LE => Pixel::X2BGR10LE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_X2BGR10BE => Pixel::X2BGR10BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P210BE => Pixel::P210BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P210LE => Pixel::P210LE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P410BE => Pixel::P410BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P410LE => Pixel::P410LE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P216BE => Pixel::P216BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P216LE => Pixel::P216LE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P416BE => Pixel::P416BE,
#[cfg(feature = "ffmpeg_5_0")]
AV_PIX_FMT_P416LE => Pixel::P416LE,
#[cfg(feature = "rpi")]
AV_PIX_FMT_RPI => Pixel::RPI,
#[cfg(feature = "rpi")]
@ -771,11 +815,11 @@ impl From<Pixel> for AVPixelFormat {
Pixel::BGR555BE => AV_PIX_FMT_BGR555BE,
Pixel::BGR555LE => AV_PIX_FMT_BGR555LE,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
Pixel::VAAPI_MOCO => AV_PIX_FMT_VAAPI_MOCO,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
Pixel::VAAPI_IDCT => AV_PIX_FMT_VAAPI_IDCT,
#[cfg(feature = "ff_api_vaapi")]
#[cfg(all(feature = "ff_api_vaapi", not(feature = "ffmpeg_5_0")))]
Pixel::VAAPI_VLD => AV_PIX_FMT_VAAPI_VLD,
#[cfg(not(feature = "ff_api_vaapi"))]
Pixel::VAAPI => AV_PIX_FMT_VAAPI,
@ -1045,6 +1089,27 @@ impl From<Pixel> for AVPixelFormat {
#[cfg(feature = "ffmpeg_4_4")]
Pixel::X2RGB10BE => AV_PIX_FMT_X2RGB10BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::X2BGR10LE => AV_PIX_FMT_X2BGR10LE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::X2BGR10BE => AV_PIX_FMT_X2BGR10BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P210BE => AV_PIX_FMT_P210BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P210LE => AV_PIX_FMT_P210LE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P410BE => AV_PIX_FMT_P410BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P410LE => AV_PIX_FMT_P410LE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P216BE => AV_PIX_FMT_P216BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P216LE => AV_PIX_FMT_P216LE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P416BE => AV_PIX_FMT_P416BE,
#[cfg(feature = "ffmpeg_5_0")]
Pixel::P416LE => AV_PIX_FMT_P416LE,
#[cfg(feature = "rpi")]
Pixel::RPI => AV_PIX_FMT_RPI,
#[cfg(feature = "rpi")]

View File

@ -63,41 +63,37 @@ impl Audio {
#[inline]
pub fn channel_layout(&self) -> ChannelLayout {
unsafe {
ChannelLayout::from_bits_truncate(
av_frame_get_channel_layout(self.as_ptr()) as c_ulonglong
)
}
unsafe { ChannelLayout::from_bits_truncate((*self.as_ptr()).channel_layout as c_ulonglong) }
}
#[inline]
pub fn set_channel_layout(&mut self, value: ChannelLayout) {
unsafe {
av_frame_set_channel_layout(self.as_mut_ptr(), value.bits() as i64);
(*self.as_mut_ptr()).channel_layout = value.bits() as u64;
}
}
#[inline]
pub fn channels(&self) -> u16 {
unsafe { av_frame_get_channels(self.as_ptr()) as u16 }
unsafe { (*self.as_ptr()).channels as u16 }
}
#[inline]
pub fn set_channels(&mut self, value: u16) {
unsafe {
av_frame_set_channels(self.as_mut_ptr(), i32::from(value));
(*self.as_mut_ptr()).channels = i32::from(value);
}
}
#[inline]
pub fn rate(&self) -> u32 {
unsafe { av_frame_get_sample_rate(self.as_ptr()) as u32 }
unsafe { (*self.as_ptr()).sample_rate as u32 }
}
#[inline]
pub fn set_rate(&mut self, value: u32) {
unsafe {
av_frame_set_sample_rate(self.as_mut_ptr(), value as c_int);
(*self.as_mut_ptr()).sample_rate = value as c_int;
}
}
@ -144,7 +140,7 @@ impl Audio {
panic!("out of bounds");
}
if !<T as Sample>::is_valid(self.format(), self.channels()) {
if !<T as Sample>::is_valid(self.format(), self.channels() as u16) {
panic!("unsupported type");
}
@ -157,7 +153,7 @@ impl Audio {
panic!("out of bounds");
}
if !<T as Sample>::is_valid(self.format(), self.channels()) {
if !<T as Sample>::is_valid(self.format(), self.channels() as u16) {
panic!("unsupported type");
}

View File

@ -11,7 +11,6 @@ pub mod flag;
pub use self::flag::Flags;
use ffi::*;
use libc::c_int;
use {Dictionary, DictionaryRef};
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
@ -20,6 +19,7 @@ pub struct Packet {
pub position: i64,
pub size: usize,
#[cfg(not(feature = "ffmpeg_5_0"))]
pub pts: i64,
pub dts: i64,
}
@ -79,10 +79,11 @@ impl Frame {
pub fn packet(&self) -> Packet {
unsafe {
Packet {
duration: av_frame_get_pkt_duration(self.as_ptr()) as i64,
position: av_frame_get_pkt_pos(self.as_ptr()) as i64,
size: av_frame_get_pkt_size(self.as_ptr()) as usize,
duration: (*self.as_ptr()).pkt_duration as i64,
position: (*self.as_ptr()).pkt_pos as i64,
size: (*self.as_ptr()).pkt_size as usize,
#[cfg(not(feature = "ffmpeg_5_0"))]
pts: (*self.as_ptr()).pkt_pts,
dts: (*self.as_ptr()).pkt_dts,
}
@ -109,7 +110,7 @@ impl Frame {
#[inline]
pub fn timestamp(&self) -> Option<i64> {
unsafe {
match av_frame_get_best_effort_timestamp(self.as_ptr()) {
match (*self.as_ptr()).best_effort_timestamp {
AV_NOPTS_VALUE => None,
t => Some(t as i64),
}
@ -128,14 +129,12 @@ impl Frame {
#[inline]
pub fn metadata(&self) -> DictionaryRef {
unsafe { DictionaryRef::wrap(av_frame_get_metadata(self.as_ptr())) }
unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) }
}
#[inline]
pub fn set_metadata(&mut self, value: Dictionary) {
unsafe {
av_frame_set_metadata(self.as_mut_ptr(), value.disown());
}
unsafe { (*self.as_mut_ptr()).metadata = value.disown() }
}
#[inline]
@ -154,7 +153,7 @@ impl Frame {
#[inline]
pub fn new_side_data(&mut self, kind: side_data::Type, size: usize) -> Option<SideData> {
unsafe {
let ptr = av_frame_new_side_data(self.as_mut_ptr(), kind.into(), size as c_int);
let ptr = av_frame_new_side_data(self.as_mut_ptr(), kind.into(), size as _);
if ptr.is_null() {
None

View File

@ -28,9 +28,9 @@ pub enum Type {
ContentLightLevel,
IccProfile,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
QPTableProperties,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
QPTableData,
#[cfg(feature = "ffmpeg_4_1")]
@ -48,6 +48,13 @@ pub enum Type {
SEI_UNREGISTERED,
#[cfg(feature = "ffmpeg_4_4")]
FILM_GRAIN_PARAMS,
#[cfg(feature = "ffmpeg_5_0")]
DETECTION_BBOXES,
#[cfg(feature = "ffmpeg_5_0")]
DOVI_RPU_BUFFER,
#[cfg(feature = "ffmpeg_5_0")]
DOVI_METADATA,
}
impl Type {
@ -81,11 +88,10 @@ impl From<AVFrameSideDataType> for Type {
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL => Type::ContentLightLevel,
AV_FRAME_DATA_ICC_PROFILE => Type::IccProfile,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
AV_FRAME_DATA_QP_TABLE_PROPERTIES => Type::QPTableProperties,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
AV_FRAME_DATA_QP_TABLE_DATA => Type::QPTableData,
#[cfg(feature = "ffmpeg_4_1")]
AV_FRAME_DATA_S12M_TIMECODE => Type::S12M_TIMECODE,
@ -101,6 +107,13 @@ impl From<AVFrameSideDataType> for Type {
AV_FRAME_DATA_SEI_UNREGISTERED => Type::SEI_UNREGISTERED,
#[cfg(feature = "ffmpeg_4_4")]
AV_FRAME_DATA_FILM_GRAIN_PARAMS => Type::FILM_GRAIN_PARAMS,
#[cfg(feature = "ffmpeg_5_0")]
AV_FRAME_DATA_DETECTION_BBOXES => Type::DETECTION_BBOXES,
#[cfg(feature = "ffmpeg_5_0")]
AV_FRAME_DATA_DOVI_RPU_BUFFER => Type::DOVI_RPU_BUFFER,
#[cfg(feature = "ffmpeg_5_0")]
AV_FRAME_DATA_DOVI_METADATA => Type::DOVI_METADATA,
}
}
}
@ -127,11 +140,10 @@ impl From<Type> for AVFrameSideDataType {
Type::ContentLightLevel => AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
Type::IccProfile => AV_FRAME_DATA_ICC_PROFILE,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
Type::QPTableProperties => AV_FRAME_DATA_QP_TABLE_PROPERTIES,
#[cfg(feature = "ffmpeg_4_0")]
#[cfg(all(feature = "ffmpeg_4_0", not(feature = "ffmpeg_5_0")))]
Type::QPTableData => AV_FRAME_DATA_QP_TABLE_DATA,
#[cfg(feature = "ffmpeg_4_1")]
Type::S12M_TIMECODE => AV_FRAME_DATA_S12M_TIMECODE,
@ -147,6 +159,13 @@ impl From<Type> for AVFrameSideDataType {
Type::SEI_UNREGISTERED => AV_FRAME_DATA_SEI_UNREGISTERED,
#[cfg(feature = "ffmpeg_4_4")]
Type::FILM_GRAIN_PARAMS => AV_FRAME_DATA_FILM_GRAIN_PARAMS,
#[cfg(feature = "ffmpeg_5_0")]
Type::DETECTION_BBOXES => AV_FRAME_DATA_DETECTION_BBOXES,
#[cfg(feature = "ffmpeg_5_0")]
Type::DOVI_RPU_BUFFER => AV_FRAME_DATA_DOVI_RPU_BUFFER,
#[cfg(feature = "ffmpeg_5_0")]
Type::DOVI_METADATA => AV_FRAME_DATA_DOVI_METADATA,
}
}
}

View File

@ -117,25 +117,25 @@ impl Video {
#[inline]
pub fn color_space(&self) -> color::Space {
unsafe { color::Space::from(av_frame_get_colorspace(self.as_ptr())) }
unsafe { color::Space::from((*self.as_ptr()).colorspace) }
}
#[inline]
pub fn set_color_space(&mut self, value: color::Space) {
unsafe {
av_frame_set_colorspace(self.as_mut_ptr(), value.into());
(*self.as_mut_ptr()).colorspace = value.into();
}
}
#[inline]
pub fn color_range(&self) -> color::Range {
unsafe { color::Range::from(av_frame_get_color_range(self.as_ptr())) }
unsafe { color::Range::from((*self.as_ptr()).color_range) }
}
#[inline]
pub fn set_color_range(&mut self, value: color::Range) {
unsafe {
av_frame_set_color_range(self.as_mut_ptr(), value.into());
(*self.as_mut_ptr()).color_range = value.into();
}
}