Skip to content

Commit

Permalink
Merge pull request zmwangx#164 from encounter/updates
Browse files Browse the repository at this point in the history
Improve time_base support & additions for ffmpeg 5-6
  • Loading branch information
Polochon-street authored Apr 1, 2024
2 parents c53730e + 18c05b7 commit ac918ef
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 41 deletions.
2 changes: 1 addition & 1 deletion examples/transcode-audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ struct Transcoder {
out_time_base: ffmpeg::Rational,
}

fn transcoder<P: AsRef<Path>>(
fn transcoder<P: AsRef<Path> + ?Sized>(
ictx: &mut format::context::Input,
octx: &mut format::context::Output,
path: &P,
Expand Down
8 changes: 2 additions & 6 deletions src/codec/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,20 @@ use {media, Error};

#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Codec {
ptr: *mut AVCodec,
ptr: *const AVCodec,
}

unsafe impl Send for Codec {}
unsafe impl Sync for Codec {}

impl Codec {
pub unsafe fn wrap(ptr: *mut AVCodec) -> Self {
pub unsafe fn wrap(ptr: *const AVCodec) -> Self {
Codec { ptr }
}

pub unsafe fn as_ptr(&self) -> *const AVCodec {
self.ptr as *const _
}

pub unsafe fn as_mut_ptr(&mut self) -> *mut AVCodec {
self.ptr
}
}

impl Codec {
Expand Down
36 changes: 35 additions & 1 deletion src/codec/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{threading, Compliance, Debug, Flags, Id, Parameters};
use ffi::*;
use libc::c_int;
use media;
use {Codec, Error};
use {Codec, Error, Rational};

pub struct Context {
ptr: *mut AVCodecContext,
Expand Down Expand Up @@ -41,6 +41,15 @@ impl Context {
}
}

pub fn new_with_codec(codec: Codec) -> Self {
unsafe {
Context {
ptr: avcodec_alloc_context3(codec.as_ptr()),
owner: None,
}
}
}

pub fn from_parameters<P: Into<Parameters>>(parameters: P) -> Result<Self, Error> {
let parameters = parameters.into();
let mut context = Self::new();
Expand Down Expand Up @@ -129,6 +138,31 @@ impl Context {
}
}
}

pub fn time_base(&self) -> Rational {
unsafe { Rational::from((*self.as_ptr()).time_base) }
}

pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) {
unsafe {
(*self.as_mut_ptr()).time_base = value.into().into();
}
}

pub fn frame_rate(&self) -> Rational {
unsafe { Rational::from((*self.as_ptr()).framerate) }
}

pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) {
unsafe {
if let Some(value) = value {
(*self.as_mut_ptr()).framerate = value.into().into();
} else {
(*self.as_mut_ptr()).framerate.num = 0;
(*self.as_mut_ptr()).framerate.den = 1;
}
}
}
}

impl Default for Context {
Expand Down
10 changes: 8 additions & 2 deletions src/codec/decoder/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ impl Decoder {
}
}

pub fn time_base(&self) -> Rational {
unsafe { Rational::from((*self.as_ptr()).time_base) }
pub fn packet_time_base(&self) -> Rational {
unsafe { Rational::from((*self.as_ptr()).pkt_timebase) }
}

pub fn set_packet_time_base<R: Into<Rational>>(&mut self, value: R) {
unsafe {
(*self.as_mut_ptr()).pkt_timebase = value.into().into();
}
}
}

Expand Down
19 changes: 1 addition & 18 deletions src/codec/encoder/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use libc::c_int;

use super::{audio, subtitle, video};
use codec::Context;
use {media, packet, Error, Frame, Rational};
use {media, packet, Error, Frame};

pub struct Encoder(pub Context);

Expand Down Expand Up @@ -116,23 +116,6 @@ impl Encoder {
}
}
}

pub fn set_time_base<R: Into<Rational>>(&mut self, value: R) {
unsafe {
(*self.as_mut_ptr()).time_base = value.into().into();
}
}

pub fn set_frame_rate<R: Into<Rational>>(&mut self, value: Option<R>) {
unsafe {
if let Some(value) = value {
(*self.as_mut_ptr()).framerate = value.into().into();
} else {
(*self.as_mut_ptr()).framerate.num = 0;
(*self.as_mut_ptr()).framerate.den = 1;
}
}
}
}

impl Deref for Encoder {
Expand Down
12 changes: 12 additions & 0 deletions src/codec/packet/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ impl Packet {
self.0.dts = value.unwrap_or(AV_NOPTS_VALUE);
}

#[inline]
#[cfg(feature = "ffmpeg_5_0")]
pub fn time_base(&self) -> Rational {
self.0.time_base.into()
}

#[inline]
#[cfg(feature = "ffmpeg_5_0")]
pub fn set_time_base(&mut self, value: Rational) {
self.0.time_base = value.into();
}

#[inline]
pub fn size(&self) -> usize {
self.0.size as usize
Expand Down
6 changes: 5 additions & 1 deletion src/filter/context/sink.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::Context;
use ffi::*;
use libc::c_int;
use {Error, Frame};
use {Error, Frame, Rational};

pub struct Sink<'a> {
ctx: &'a mut Context<'a>,
Expand Down Expand Up @@ -41,4 +41,8 @@ impl<'a> Sink<'a> {
av_buffersink_set_frame_size(self.ctx.as_mut_ptr(), value);
}
}

pub fn time_base(&self) -> Rational {
unsafe { av_buffersink_get_time_base(self.ctx.as_ptr()) }.into()
}
}
21 changes: 20 additions & 1 deletion src/format/context/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::common::Context;
use super::destructor;
use codec::traits;
use ffi::*;
use {format, ChapterMut, Dictionary, Error, Rational, StreamMut};
use {codec, format, ChapterMut, Dictionary, Error, Rational, StreamMut};

pub struct Output {
ptr: *mut AVFormatContext,
Expand Down Expand Up @@ -90,6 +90,25 @@ impl Output {
}
}

pub fn add_stream_with(&mut self, context: &codec::Context) -> Result<StreamMut, Error> {
unsafe {
let ptr = avformat_new_stream(self.as_mut_ptr(), ptr::null());

if ptr.is_null() {
return Err(Error::Unknown);
}

match avcodec_parameters_from_context((*ptr).codecpar, context.as_ptr()) {
0 => (),
e => return Err(Error::from(e)),
}

let index = (*self.ctx.as_ptr()).nb_streams - 1;

Ok(StreamMut::wrap(&mut self.ctx, index as usize))
}
}

pub fn add_chapter<R: Into<Rational>, S: AsRef<str>>(
&mut self,
id: i64,
Expand Down
2 changes: 1 addition & 1 deletion src/format/format/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl Output {
}
}

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

Expand Down
23 changes: 13 additions & 10 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ pub fn license() -> &'static str {
}

// XXX: use to_cstring when stable
fn from_path<P: AsRef<Path>>(path: &P) -> CString {
fn from_path<P: AsRef<Path> + ?Sized>(path: &P) -> CString {
CString::new(path.as_ref().as_os_str().to_str().unwrap()).unwrap()
}

// NOTE: this will be better with specialization or anonymous return types
pub fn open<P: AsRef<Path>>(path: &P, format: &Format) -> Result<Context, Error> {
pub fn open<P: AsRef<Path> + ?Sized>(path: &P, format: &Format) -> Result<Context, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = from_path(path);
Expand Down Expand Up @@ -100,7 +100,7 @@ pub fn open<P: AsRef<Path>>(path: &P, format: &Format) -> Result<Context, Error>
}
}

pub fn open_with<P: AsRef<Path>>(
pub fn open_with<P: AsRef<Path> + ?Sized>(
path: &P,
format: &Format,
options: Dictionary,
Expand Down Expand Up @@ -148,7 +148,7 @@ pub fn open_with<P: AsRef<Path>>(
}
}

pub fn input<P: AsRef<Path>>(path: &P) -> Result<context::Input, Error> {
pub fn input<P: AsRef<Path> + ?Sized>(path: &P) -> Result<context::Input, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = from_path(path);
Expand All @@ -167,7 +167,7 @@ pub fn input<P: AsRef<Path>>(path: &P) -> Result<context::Input, Error> {
}
}

pub fn input_with_dictionary<P: AsRef<Path>>(
pub fn input_with_dictionary<P: AsRef<Path> + ?Sized>(
path: &P,
options: Dictionary,
) -> Result<context::Input, Error> {
Expand All @@ -193,7 +193,7 @@ pub fn input_with_dictionary<P: AsRef<Path>>(
}
}

pub fn input_with_interrupt<P: AsRef<Path>, F>(
pub fn input_with_interrupt<P: AsRef<Path> + ?Sized, F>(
path: &P,
closure: F,
) -> Result<context::Input, Error>
Expand All @@ -219,7 +219,7 @@ where
}
}

pub fn output<P: AsRef<Path>>(path: &P) -> Result<context::Output, Error> {
pub fn output<P: AsRef<Path> + ?Sized>(path: &P) -> Result<context::Output, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = from_path(path);
Expand All @@ -235,7 +235,7 @@ pub fn output<P: AsRef<Path>>(path: &P) -> Result<context::Output, Error> {
}
}

pub fn output_with<P: AsRef<Path>>(
pub fn output_with<P: AsRef<Path> + ?Sized>(
path: &P,
options: Dictionary,
) -> Result<context::Output, Error> {
Expand Down Expand Up @@ -267,7 +267,10 @@ pub fn output_with<P: AsRef<Path>>(
}
}

pub fn output_as<P: AsRef<Path>>(path: &P, format: &str) -> Result<context::Output, Error> {
pub fn output_as<P: AsRef<Path> + ?Sized>(
path: &P,
format: &str,
) -> Result<context::Output, Error> {
unsafe {
let mut ps = ptr::null_mut();
let path = from_path(path);
Expand All @@ -289,7 +292,7 @@ pub fn output_as<P: AsRef<Path>>(path: &P, format: &str) -> Result<context::Outp
}
}

pub fn output_as_with<P: AsRef<Path>>(
pub fn output_as_with<P: AsRef<Path> + ?Sized>(
path: &P,
format: &str,
options: Dictionary,
Expand Down

0 comments on commit ac918ef

Please sign in to comment.