🐛 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 struct Decoder {
|
||||||
pub input_ctx: DemuxContext,
|
pub input_ctx: DemuxContext,
|
||||||
best_stream_idx: usize,
|
|
||||||
pub decoder: DecodeContext,
|
pub decoder: DecodeContext,
|
||||||
pub resampler: ResamplingContext,
|
pub resampler: ResamplingContext,
|
||||||
|
|
||||||
|
best_stream_idx: usize,
|
||||||
|
dummy_frame: Option <AudioFrame>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder {
|
impl Decoder {
|
||||||
|
@ -107,9 +109,11 @@ impl Decoder {
|
||||||
|
|
||||||
Ok (Self {
|
Ok (Self {
|
||||||
input_ctx,
|
input_ctx,
|
||||||
best_stream_idx,
|
|
||||||
decoder,
|
decoder,
|
||||||
resampler,
|
resampler,
|
||||||
|
|
||||||
|
best_stream_idx,
|
||||||
|
dummy_frame: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +137,8 @@ impl Decoder {
|
||||||
if actual_bytes > expected_bytes {
|
if actual_bytes > expected_bytes {
|
||||||
let extra_bytes = actual_bytes - expected_bytes;
|
let extra_bytes = actual_bytes - expected_bytes;
|
||||||
let extra_samples = extra_bytes / 4 / 2;
|
let extra_samples = extra_bytes / 4 / 2;
|
||||||
tracing::debug! ("Extra bytes: {}", extra_bytes);
|
// tracing::debug! ("Extra bytes: {}", extra_bytes);
|
||||||
tracing::debug! ("Extra samples: {}", extra_samples);
|
// tracing::debug! ("Extra samples: {}", extra_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some (frame)
|
Some (frame)
|
||||||
|
@ -175,26 +179,18 @@ impl Decoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pump_resampler (&mut self) -> Result <Option <AudioFrame>> {
|
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),
|
None => return Ok (None),
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut frame_src = AudioFrame::new (
|
|
||||||
Sample::F32 (sample::Type::Planar),
|
|
||||||
0,
|
|
||||||
ChannelLayout::STEREO
|
|
||||||
);
|
|
||||||
let mut frame_resampled = Self::new_frame ();
|
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)?;
|
let _rc = self.resampler.run (&frame_src, &mut frame_resampled)?;
|
||||||
// dbg! (&frame_resampled, rc);
|
// dbg! (&frame_resampled, rc);
|
||||||
|
|
||||||
Ok (if frame_resampled.samples () > 0 {
|
Ok (if frame_resampled.samples () > 0 {
|
||||||
|
// tracing::trace! ("Pulled from resampler FIFO");
|
||||||
Some (frame_resampled)
|
Some (frame_resampled)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -203,28 +199,31 @@ impl Decoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pump_decoder (&mut self) -> Result <Option <AudioFrame>> {
|
pub fn pump_decoder (&mut self) -> Result <Option <AudioFrame>> {
|
||||||
let mut frame_src = ffmpeg_next::util::frame::Audio::empty ();
|
let mut frame_src = AudioFrame::empty ();
|
||||||
let rc = self.decoder.receive_frame (&mut frame_src);
|
if let Err (_) = self.decoder.receive_frame (&mut frame_src) {
|
||||||
// dbg! (&rc);
|
return Ok (None);
|
||||||
Ok (if rc.is_ok () {
|
};
|
||||||
// dbg! (&frame_src);
|
|
||||||
|
if self.dummy_frame.is_none () {
|
||||||
//let nb_output_samples = frame_src.samples () * SAMPLE_RATE as usize / frame_src.rate () as usize;
|
let mut dummy_frame = AudioFrame::new (
|
||||||
|
frame_src.format (),
|
||||||
let nb_output_samples = frame_src.samples ();
|
0,
|
||||||
|
frame_src.channel_layout (),
|
||||||
let mut frame_resampled = AudioFrame::new (
|
|
||||||
Sample::F32 (sample::Type::Packed),
|
|
||||||
nb_output_samples,
|
|
||||||
ChannelLayout::STEREO
|
|
||||||
);
|
);
|
||||||
|
dummy_frame.set_rate (frame_src.rate ());
|
||||||
self.resampler.run (&frame_src, &mut frame_resampled)?;
|
self.dummy_frame = Some (dummy_frame);
|
||||||
Some (frame_resampled)
|
|
||||||
}
|
}
|
||||||
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> {
|
pub fn pump_demuxer (&mut self) -> Result <bool> {
|
||||||
|
|
Loading…
Reference in New Issue