From dc778d12a994f47236cb168b6145a2a563dba1ab Mon Sep 17 00:00:00 2001 From: kieran Date: Wed, 13 Nov 2024 16:41:15 +0000 Subject: [PATCH] fix: resample with frame_size --- src/lib.rs | 12 ++++++++++++ src/mux.rs | 11 +++++------ src/resample.rs | 15 +++++++++------ src/scale.rs | 14 +++++++++----- src/transcode.rs | 3 ++- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d134285..7034130 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,11 +24,23 @@ macro_rules! bail_ffmpeg { anyhow::bail!($crate::get_ffmpeg_error_msg($x)) } }; + ($x:expr,$clean:block) => { + if $x < 0 { + $clean; + anyhow::bail!($crate::get_ffmpeg_error_msg($x)) + } + }; ($x:expr,$msg:expr) => { if $x < 0 { anyhow::bail!(format!("{}: {}", $msg, $crate::get_ffmpeg_error_msg($x))) } }; + ($x:expr,$msg:expr,$clean:block) => { + if $x < 0 { + $clean; + anyhow::bail!(format!("{}: {}", $msg, $crate::get_ffmpeg_error_msg($x))) + } + }; } #[macro_export] diff --git a/src/mux.rs b/src/mux.rs index 30e813a..b1588d5 100644 --- a/src/mux.rs +++ b/src/mux.rs @@ -1,12 +1,11 @@ use crate::{bail_ffmpeg, cstr, set_opts, Encoder, AVIO_BUFFER_SIZE}; use anyhow::{bail, Result}; use ffmpeg_sys_the_third::{ - av_free, av_interleaved_write_frame, av_mallocz, av_packet_rescale_ts, - av_write_trailer, avcodec_parameters_copy, avcodec_parameters_from_context, - avformat_alloc_output_context2, avformat_free_context, avformat_new_stream, - avformat_write_header, avio_alloc_context, avio_open, AVFormatContext, AVIOContext, AVPacket, - AVStream, AVERROR_EOF, AVFMT_GLOBALHEADER, AVFMT_NOFILE, AVIO_FLAG_DIRECT, AVIO_FLAG_WRITE, - AV_CODEC_FLAG_GLOBAL_HEADER, + av_free, av_interleaved_write_frame, av_mallocz, av_packet_rescale_ts, av_write_trailer, + avcodec_parameters_copy, avcodec_parameters_from_context, avformat_alloc_output_context2, + avformat_free_context, avformat_new_stream, avformat_write_header, avio_alloc_context, + avio_open, AVFormatContext, AVIOContext, AVPacket, AVStream, AVERROR_EOF, AVFMT_GLOBALHEADER, + AVFMT_NOFILE, AVIO_FLAG_DIRECT, AVIO_FLAG_WRITE, AV_CODEC_FLAG_GLOBAL_HEADER, }; use slimbox::{slimbox_unsize, SlimBox, SlimMut}; use std::collections::HashMap; diff --git a/src/resample.rs b/src/resample.rs index d31853e..0169967 100644 --- a/src/resample.rs +++ b/src/resample.rs @@ -1,5 +1,4 @@ use crate::bail_ffmpeg; -use crate::get_ffmpeg_error_msg; use anyhow::Error; use ffmpeg_sys_the_third::{ av_channel_layout_default, av_frame_alloc, av_frame_copy_props, av_frame_free, @@ -63,7 +62,12 @@ impl Resample { Ok(()) } - pub unsafe fn process_frame(&mut self, frame: *mut AVFrame) -> Result<*mut AVFrame, Error> { + /// Resample an audio frame + pub unsafe fn process_frame( + &mut self, + frame: *mut AVFrame, + frame_size: i32, + ) -> Result<*mut AVFrame, Error> { if !(*frame).hw_frames_ctx.is_null() { anyhow::bail!("Hardware frames are not supported in this software re-sampler"); } @@ -73,15 +77,14 @@ impl Resample { av_frame_copy_props(out_frame, frame); (*out_frame).sample_rate = self.sample_rate as libc::c_int; (*out_frame).format = transmute(self.format); - (*out_frame).time_base = (*frame).time_base; + (*out_frame).nb_samples = frame_size; av_channel_layout_default(&mut (*out_frame).ch_layout, self.channels as libc::c_int); let ret = swr_convert_frame(self.ctx, out_frame, frame); - if ret < 0 { + bail_ffmpeg!(ret, { av_frame_free(&mut out_frame); - return Err(Error::msg(get_ffmpeg_error_msg(ret))); - } + }); Ok(out_frame) } diff --git a/src/scale.rs b/src/scale.rs index e0de96d..262cb6d 100644 --- a/src/scale.rs +++ b/src/scale.rs @@ -4,8 +4,8 @@ use std::ptr; use crate::{bail_ffmpeg, rstr}; use anyhow::{bail, Error}; use ffmpeg_sys_the_third::{ - av_frame_alloc, av_frame_copy_props, av_get_pix_fmt_name, sws_freeContext, sws_getContext, - sws_scale_frame, AVFrame, AVPixelFormat, SwsContext, SWS_BILINEAR, + av_frame_alloc, av_frame_copy_props, av_frame_free, av_get_pix_fmt_name, sws_freeContext, + sws_getContext, sws_scale_frame, AVFrame, AVPixelFormat, SwsContext, SWS_BILINEAR, }; use log::trace; @@ -108,12 +108,16 @@ impl Scaler { self.setup_scaler(frame, width, height, format)?; - let dst_frame = av_frame_alloc(); + let mut dst_frame = av_frame_alloc(); let ret = av_frame_copy_props(dst_frame, frame); - bail_ffmpeg!(ret); + bail_ffmpeg!(ret, { + av_frame_free(&mut dst_frame); + }); let ret = sws_scale_frame(self.ctx, dst_frame, frame); - bail_ffmpeg!(ret); + bail_ffmpeg!(ret, { + av_frame_free(&mut dst_frame); + }); Ok(dst_frame) } diff --git a/src/transcode.rs b/src/transcode.rs index 579418e..1ce5a2e 100644 --- a/src/transcode.rs +++ b/src/transcode.rs @@ -128,7 +128,8 @@ impl Transcoder { // resample audio frame before encoding let mut frame = if let Some(swr) = self.resampler.get_mut(&src_index) { - swr.process_frame(frame)? + let frame_size = (*enc.codec_context()).frame_size; + swr.process_frame(frame, frame_size)? } else { frame };