MCPcopy Create free account
hub / github.com/FFMS/ffms2 / FillAudioGaps

Method FillAudioGaps

src/core/track.cpp:273–340  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

271}
272
273void FFMS_Track::FillAudioGaps() {
274 frame_vec &Frames = Data->Frames;
275 // There may not be audio data for the entire duration of the audio track,
276 // as some formats support gaps between the end time of one packet and the
277 // PTS of the next audio packet, and we should zero-fill those gaps.
278 // However, garbage or missing timestamps for audio tracks are very common,
279 // so we only want to trust them if they're all present, monotonically
280 // increasing, and result in a total duration meaningfully longer than the
281 // samples we have would cover.
282 if (size() < 2 || !HasTS || front().PTS == AV_NOPTS_VALUE || back().PTS == AV_NOPTS_VALUE)
283 return;
284
285 const auto DurationToSamples = [this](int64_t Dur) {
286 auto Num = TB.Num * SampleRate;
287 auto Den = TB.Den * 1000;
288 return av_rescale(Dur, Num, Den);
289 };
290
291 const auto SamplesToDuration = [this](int64_t Samples) {
292 auto Num = TB.Den * 1000;
293 auto Den = TB.Num * SampleRate;
294 return av_rescale(Samples, Num, Den);
295 };
296
297 if (HasDiscontTS) {
298 int64_t shift = 0;
299 Frames[0].OriginalPTS = Frames[0].PTS;
300 for (size_t i = 1; i < size(); i++) {
301 Frames[i].OriginalPTS = Frames[i].PTS;
302 if (Frames[i].PTS != AV_NOPTS_VALUE && Frames[i].OriginalPTS <= Frames[i-1].OriginalPTS)
303 shift = -(Frames[i].PTS) + Frames[i-1].PTS + SamplesToDuration(Frames[i-1].SampleCount);
304 Frames[i].PTS += shift;
305 }
306 }
307
308 const auto ActualSamples = back().SampleStart + back().SampleCount;
309 const auto ExpectedSamples = DurationToSamples(back().PTS - front().PTS) + back().SampleCount;
310 if (ActualSamples + 5 > ExpectedSamples) // arbitrary threshold to cover rounding/not worth adjusting
311 return;
312
313 // Verify that every frame has a timestamp and that they monotonically
314 // increase, as otherwise we can't trust them
315 auto PrevPTS = front().PTS - 1;
316 for (auto const& frame : *this) {
317 if (frame.PTS == AV_NOPTS_VALUE || frame.PTS <= PrevPTS)
318 return;
319 PrevPTS = frame.PTS;
320 }
321
322 // There are some missing samples and the timestamps appear to all be valid,
323 // so go ahead and extend the frames to cover the gaps
324 const auto FirstPTS = front().PTS;
325 auto PrevFrame = &Frames.front();
326 int32_t Shift = 0;
327 for (auto& Frame : Frames) {
328 if (Shift > 0)
329 Frame.SampleStart += Shift;
330

Callers 1

FFMS_AudioSourceMethod · 0.80

Calls 1

frontMethod · 0.80

Tested by

no test coverage detected