mirror of
https://github.com/encounter/rust-ffmpeg-zmwangx.git
synced 2026-07-10 21:18:40 -07:00
Bump version to use ffmpeg 5
This commit is contained in:
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod packet;
|
||||
|
||||
pub mod subtitle;
|
||||
|
||||
#[cfg(not(feature = "ffmpeg_5_0"))]
|
||||
pub mod picture;
|
||||
|
||||
pub mod discard;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user