🐛 bug: popping is gone
It was a combination of two bugs: 1. For some reason, libswresample sometimes returns more data than you need. Like, it'll return X samples but _more than_ 8X bytes, for f32 stereo. 2. I wasn't supposed to be calling `flush`. I should have been calling `run` with a dummy frame. This isn't intuitive to me, and it required me to construct a dummy frame and keep it around in my code. I think this is pretty inelegant. And looking at the ffmpeg code, I think it's a flaw in the API design of the `ffmpeg_next` crate. I may ask them about it in the future.main
parent
9c3368f28b
commit
68461866d8
|
@ -84,9 +84,11 @@ pub struct SharedState {
|
|||
|
||||
pub struct Decoder {
|
||||
pub input_ctx: DemuxContext,
|
||||
best_stream_idx: usize,
|
||||
pub decoder: DecodeContext,
|
||||
pub resampler: ResamplingContext,
|
||||
|
||||
best_stream_idx: usize,
|
||||
dummy_frame: Option <AudioFrame>,
|
||||
}
|
||||
|
||||
impl Decoder {
|
||||
|
@ -107,9 +109,11 @@ impl Decoder {
|
|||
|
||||
Ok (Self {
|
||||
input_ctx,
|
||||
best_stream_idx,
|
||||
decoder,
|
||||
resampler,
|
||||
|
||||
best_stream_idx,
|
||||
dummy_frame: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -133,8 +137,8 @@ impl Decoder {
|
|||
if actual_bytes > expected_bytes {
|
||||
let extra_bytes = actual_bytes - expected_bytes;
|
||||
let extra_samples = extra_bytes / 4 / 2;
|
||||
tracing::debug! ("Extra bytes: {}", extra_bytes);
|
||||
tracing::debug! ("Extra samples: {}", extra_samples);
|
||||
// tracing::debug! ("Extra bytes: {}", extra_bytes);
|
||||
// tracing::debug! ("Extra samples: {}", extra_samples);
|
||||
}
|
||||
|
||||
Some (frame)
|
||||
|
@ -175,26 +179,18 @@ impl Decoder {
|
|||
}
|
||||
|
||||
pub fn pump_resampler (&mut self) -> Result <Option <AudioFrame>> {
|
||||
let delay = match self.resampler.delay () {
|
||||
let frame_src = match self.dummy_frame.as_ref () {
|
||||
None => return Ok (None),
|
||||
Some (x) => x,
|
||||
};
|
||||
|
||||
let mut frame_src = AudioFrame::new (
|
||||
Sample::F32 (sample::Type::Planar),
|
||||
0,
|
||||
ChannelLayout::STEREO
|
||||
);
|
||||
let mut frame_resampled = Self::new_frame ();
|
||||
|
||||
frame_src.set_rate (44100);
|
||||
|
||||
tracing::trace! ("Flushing resampler");
|
||||
tracing::trace! ("delay: {:?}", delay);
|
||||
let _rc = self.resampler.run (&frame_src, &mut frame_resampled)?;
|
||||
// dbg! (&frame_resampled, rc);
|
||||
|
||||
Ok (if frame_resampled.samples () > 0 {
|
||||
// tracing::trace! ("Pulled from resampler FIFO");
|
||||
Some (frame_resampled)
|
||||
}
|
||||
else {
|
||||
|
@ -203,28 +199,31 @@ impl Decoder {
|
|||
}
|
||||
|
||||
pub fn pump_decoder (&mut self) -> Result <Option <AudioFrame>> {
|
||||
let mut frame_src = ffmpeg_next::util::frame::Audio::empty ();
|
||||
let rc = self.decoder.receive_frame (&mut frame_src);
|
||||
// dbg! (&rc);
|
||||
Ok (if rc.is_ok () {
|
||||
// dbg! (&frame_src);
|
||||
|
||||
//let nb_output_samples = frame_src.samples () * SAMPLE_RATE as usize / frame_src.rate () as usize;
|
||||
|
||||
let nb_output_samples = frame_src.samples ();
|
||||
|
||||
let mut frame_resampled = AudioFrame::new (
|
||||
Sample::F32 (sample::Type::Packed),
|
||||
nb_output_samples,
|
||||
ChannelLayout::STEREO
|
||||
let mut frame_src = AudioFrame::empty ();
|
||||
if let Err (_) = self.decoder.receive_frame (&mut frame_src) {
|
||||
return Ok (None);
|
||||
};
|
||||
|
||||
if self.dummy_frame.is_none () {
|
||||
let mut dummy_frame = AudioFrame::new (
|
||||
frame_src.format (),
|
||||
0,
|
||||
frame_src.channel_layout (),
|
||||
);
|
||||
|
||||
self.resampler.run (&frame_src, &mut frame_resampled)?;
|
||||
Some (frame_resampled)
|
||||
dummy_frame.set_rate (frame_src.rate ());
|
||||
self.dummy_frame = Some (dummy_frame);
|
||||
}
|
||||
else {
|
||||
None
|
||||
})
|
||||
|
||||
let nb_output_samples = frame_src.samples ();
|
||||
|
||||
let mut frame_resampled = AudioFrame::new (
|
||||
Sample::F32 (sample::Type::Packed),
|
||||
nb_output_samples,
|
||||
ChannelLayout::STEREO
|
||||
);
|
||||
|
||||
self.resampler.run (&frame_src, &mut frame_resampled)?;
|
||||
Ok (Some (frame_resampled))
|
||||
}
|
||||
|
||||
pub fn pump_demuxer (&mut self) -> Result <bool> {
|
||||
|
|
Loading…
Reference in New Issue