Harden playback/cache path for malformed media and concurrent timeline updates

- Invalidate timeline cache on ApplyJsonDiff() clip insert (remove affected frame range).
  - Add lock in Timeline::ClearAllCache() for safe concurrent access.
  - Make VideoCacheThread cross-thread state safe (atomics + seek-state mutex).
  - Lock CacheMemory::Contains() to avoid races.
  - Handle malformed audio streams in FFmpegReader by disabling invalid audio and continuing video-only.
  - Add FPS/timebase safety fallbacks in FFmpeg frame/PTS math.
  - Guard Frame::GetSamplesPerFrame() against invalid inputs.
  - Add/adjust regression tests for cache invalidation and invalid rate handling.
This commit is contained in:
Jonathan Thomas
2026-02-11 20:11:47 -06:00
parent 57c1fb2ec3
commit d70e80eac4
9 changed files with 238 additions and 83 deletions

View File

@@ -138,6 +138,14 @@ TEST_CASE( "Copy_Constructor", "[libopenshot][frame]" )
CHECK(f1.GetAudioSamplesCount() == f2.GetAudioSamplesCount());
}
TEST_CASE( "GetSamplesPerFrame invalid rate inputs", "[libopenshot][frame]" )
{
CHECK(Frame::GetSamplesPerFrame(/*frame_number=*/1, Fraction(0, 1), /*sample_rate=*/44100, /*channels=*/2) == 0);
CHECK(Frame::GetSamplesPerFrame(/*frame_number=*/1, Fraction(30, 0), /*sample_rate=*/44100, /*channels=*/2) == 0);
CHECK(Frame::GetSamplesPerFrame(/*frame_number=*/1, Fraction(30, 1), /*sample_rate=*/0, /*channels=*/2) == 0);
CHECK(Frame::GetSamplesPerFrame(/*frame_number=*/1, Fraction(30, 1), /*sample_rate=*/44100, /*channels=*/0) == 0);
}
#ifdef USE_OPENCV
TEST_CASE( "Convert_Image", "[libopenshot][opencv][frame]" )
{