🐛 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
_ 2021-11-13 11:23:10 -06:00
parent 9c3368f28b
commit 68461866d8
2 changed files with 33 additions and 36 deletions

View File

@ -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 mut frame_src = AudioFrame::empty ();
if let Err (_) = self.decoder.receive_frame (&mut frame_src) {
return Ok (None);
};
//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
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> {

View File

@ -1,3 +1 @@
# Critical
- Popping every 1-3 seconds-ish