| 271 | } |
| 272 | |
| 273 | void 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 | |