fix: resample with frame_size

This commit is contained in:
kieran 2024-11-13 16:41:15 +00:00
parent d966232e34
commit dc778d12a9
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
5 changed files with 37 additions and 18 deletions

View File

@ -24,11 +24,23 @@ macro_rules! bail_ffmpeg {
anyhow::bail!($crate::get_ffmpeg_error_msg($x)) 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) => { ($x:expr,$msg:expr) => {
if $x < 0 { if $x < 0 {
anyhow::bail!(format!("{}: {}", $msg, $crate::get_ffmpeg_error_msg($x))) 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] #[macro_export]

View File

@ -1,12 +1,11 @@
use crate::{bail_ffmpeg, cstr, set_opts, Encoder, AVIO_BUFFER_SIZE}; use crate::{bail_ffmpeg, cstr, set_opts, Encoder, AVIO_BUFFER_SIZE};
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use ffmpeg_sys_the_third::{ use ffmpeg_sys_the_third::{
av_free, av_interleaved_write_frame, av_mallocz, av_packet_rescale_ts, av_free, av_interleaved_write_frame, av_mallocz, av_packet_rescale_ts, av_write_trailer,
av_write_trailer, avcodec_parameters_copy, avcodec_parameters_from_context, avcodec_parameters_copy, avcodec_parameters_from_context, avformat_alloc_output_context2,
avformat_alloc_output_context2, avformat_free_context, avformat_new_stream, avformat_free_context, avformat_new_stream, avformat_write_header, avio_alloc_context,
avformat_write_header, avio_alloc_context, avio_open, AVFormatContext, AVIOContext, AVPacket, avio_open, AVFormatContext, AVIOContext, AVPacket, AVStream, AVERROR_EOF, AVFMT_GLOBALHEADER,
AVStream, AVERROR_EOF, AVFMT_GLOBALHEADER, AVFMT_NOFILE, AVIO_FLAG_DIRECT, AVIO_FLAG_WRITE, AVFMT_NOFILE, AVIO_FLAG_DIRECT, AVIO_FLAG_WRITE, AV_CODEC_FLAG_GLOBAL_HEADER,
AV_CODEC_FLAG_GLOBAL_HEADER,
}; };
use slimbox::{slimbox_unsize, SlimBox, SlimMut}; use slimbox::{slimbox_unsize, SlimBox, SlimMut};
use std::collections::HashMap; use std::collections::HashMap;

View File

@ -1,5 +1,4 @@
use crate::bail_ffmpeg; use crate::bail_ffmpeg;
use crate::get_ffmpeg_error_msg;
use anyhow::Error; use anyhow::Error;
use ffmpeg_sys_the_third::{ use ffmpeg_sys_the_third::{
av_channel_layout_default, av_frame_alloc, av_frame_copy_props, av_frame_free, av_channel_layout_default, av_frame_alloc, av_frame_copy_props, av_frame_free,
@ -63,7 +62,12 @@ impl Resample {
Ok(()) 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() { if !(*frame).hw_frames_ctx.is_null() {
anyhow::bail!("Hardware frames are not supported in this software re-sampler"); 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); av_frame_copy_props(out_frame, frame);
(*out_frame).sample_rate = self.sample_rate as libc::c_int; (*out_frame).sample_rate = self.sample_rate as libc::c_int;
(*out_frame).format = transmute(self.format); (*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); 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); let ret = swr_convert_frame(self.ctx, out_frame, frame);
if ret < 0 { bail_ffmpeg!(ret, {
av_frame_free(&mut out_frame); av_frame_free(&mut out_frame);
return Err(Error::msg(get_ffmpeg_error_msg(ret))); });
}
Ok(out_frame) Ok(out_frame)
} }

View File

@ -4,8 +4,8 @@ use std::ptr;
use crate::{bail_ffmpeg, rstr}; use crate::{bail_ffmpeg, rstr};
use anyhow::{bail, Error}; use anyhow::{bail, Error};
use ffmpeg_sys_the_third::{ use ffmpeg_sys_the_third::{
av_frame_alloc, av_frame_copy_props, av_get_pix_fmt_name, sws_freeContext, sws_getContext, av_frame_alloc, av_frame_copy_props, av_frame_free, av_get_pix_fmt_name, sws_freeContext,
sws_scale_frame, AVFrame, AVPixelFormat, SwsContext, SWS_BILINEAR, sws_getContext, sws_scale_frame, AVFrame, AVPixelFormat, SwsContext, SWS_BILINEAR,
}; };
use log::trace; use log::trace;
@ -108,12 +108,16 @@ impl Scaler {
self.setup_scaler(frame, width, height, format)?; 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); 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); 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) Ok(dst_frame)
} }

View File

@ -128,7 +128,8 @@ impl Transcoder {
// resample audio frame before encoding // resample audio frame before encoding
let mut frame = if let Some(swr) = self.resampler.get_mut(&src_index) { 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 { } else {
frame frame
}; };