Jonathan Thomas
d70e80eac4
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.
2026-02-11 20:11:47 -06:00
Jonathan Thomas
57c1fb2ec3
Merge pull request #1034 from OpenShot/sparse-vfr-support
...
Fix sparse-VFR stall and stabilize missing-frame image fallback
2026-02-10 12:02:07 -06:00
Jonathan Thomas
2e4e12d2c7
Setting a minimum # of frames (floor) in Timeline, FFmpegReader, and FrameMapper - so low cpu/thread systems don't end up with a tiny # that makes passing our unit tests difficult.
2026-02-09 22:10:32 -06:00
Jonathan Thomas
6f63254c08
More changes to seek logic to pass unit tests on Windows.
2026-02-09 21:35:06 -06:00
Jonathan Thomas
d6b54091d7
Adding minimum cache size floor, for systems with very few cores. This is required to fix a failure running unit tests on our GitLab runners.
2026-02-09 21:14:45 -06:00
Jonathan Thomas
367d21affe
Fix FFmpeg seek fallback to avoid overshoot frame mismatches. Harden FFmpegReader::CheckSeek() when seek retries are exhausted.
2026-02-09 20:51:24 -06:00
Jonathan Thomas
01e60463db
FFmpegReader: fix sparse-VFR stall and stabilize missing-frame image fallback
...
- prevent ReadStream() infinite loop when packet counters stall at EOF with no packet/hold state by detecting no-progress and forcing EOF completion
- improve missing-frame handling on sparse timelines by preferring chronological image sources:
- previous finalized frame (f->number - 1)
- last finalized video frame (last_final_video_frame)
- last decoded video frame only if not from the future
- black frame only as last resort
- use the same finalized/decoded fallback when largest_frame_processed is no longer cached
- track/reset last_final_video_frame across finalize/seek/close lifecycle
Fixes:
- hard stall around gap frames
- black flashing from cache churn on sparse streams
- out-of-order jitter caused by reusing future-decoded frames
2026-02-07 22:40:43 -06:00
Jonathan Thomas
f3c4504662
Improve benchmark regression caused by aggressive memory trimming, and caches that were too small. A new debounce strategy for memory trimming (1 time max per 30 seconds).
2026-02-06 23:11:00 -06:00
Jonathan Thomas
de012ac6c8
Improve seek retry fallback and clean up hw decode logging
...
- add adaptive seek fallback and switch fprintf to ZmqLogger
- improves seeking on certain files by up to 30% (faster)
- avoids situations where seeking too far would sometimes freeze on certain videos
2026-02-06 16:46:40 -06:00
Jonathan Thomas
43f9ed89ae
VideoCacheThread: add directional preroll
...
- start cache rebuilds with a preroll offset (settings-based)
- tighten isReady to require frames ahead/behind playhead add unit tests for preroll clamping and readiness
2026-02-05 12:39:06 -06:00
Jonathan Thomas
16f791a55a
Adding missing <sstream> includes for older compilers, and because it should be included anyway
2025-12-16 18:23:57 -06:00
Jonathan Thomas
2a82bed607
Adding upscaling for crop effect + resize property - so cropping into higher resolution content does not become blurry.
2025-12-15 23:34:48 -06:00
Jonathan Thomas
bd59e6bb37
Fix mixing licensing headers
2025-12-15 21:13:34 -06:00
Jonathan Thomas
7fdd145dc2
Adding new memory trimming to more forcefully return memory to the OS after major memory clearing events (i.e. clearing all cache, closing readers, or large amounts of cache cleared). Also, refactoring default cache sizes in Timeline, FrameMapper, and FFmpegReader to better support high frame rate and high resolution videos (i.e. 4k 60 fps) so we don't immediately run out of memory.
2025-12-14 23:53:36 -06:00
Jonathan Thomas
94fab00048
Updating video_length and duration calculations to be consistent on image readers also (QtImageReader, ImageReader)
2025-12-08 18:33:23 -06:00
Jonathan Thomas
eea55982fd
FFmpegReader: add duration strategy modes and unify duration/frame calculations. This is a potentially breaking change, where we ensure all durations and video_length calculations coming from FFmpegReader are now fully consistent - even if we must slightly adjust a duration from the video or audio stream. This keeps the 2 attributes identical in meaning (video_length X FPS == duration, no exceptions). Unknown durations are no longer -1 video_length but 0, and 0 duration.
2025-12-08 17:07:21 -06:00
Jonathan Thomas
af9a4893ed
Fixing regression inside AudioWaveformer so it uses a proper detached reader, and no longer mutates the Clip's reader (preventing a bug which caused our video to disappear when waveforms were used on the clip)
2025-11-24 18:33:25 -06:00
Jonathan Thomas
d4647b5525
Refactoring the AudioWaveformer again, this time to de-couple it from the actual clip object passed to it, and to no longer iterate over the potential longer time keyframes using GetFrame alone. Now, we only decode audio-streams, and only get the original samples (reduced sample rate drastically), and finally we apply keyframes (volume and time) to modify our original samples. This is a HUGE speed-up boost for waveform generation.
2025-11-23 14:11:53 -06:00
Jonathan Thomas
e25763d089
Adding awareness of DOMAIN_MIN and DOMAIN_MAX properties of LUT Color Map files and new unit tests to validate them
2025-11-18 17:36:30 -06:00
Jonathan Thomas
2f82e7d27b
Adding support for 1D and 3D LUT Color Map files. Also added new unit tests to verify 1D and 3D LUT files.
2025-11-18 14:26:59 -06:00
Jonathan Thomas
355bea44d9
Fixing small regression on initial rotation keyframes from our previous commit.
2025-11-18 13:43:40 -06:00
Jonathan Thomas
a7dfc596ca
Fixing regression in Clip::init_reader_rotation() function, which could sometimes override scale_x and scale_y, when a rotation keyframe contained more than 1 point.
2025-11-13 16:18:18 -06:00
Jonathan Thomas
5596344575
Fixing AudioWaveformer::ExtractSamples to pause temporarily when a clip's reader is closed, and resume extracting when it's open again. This prevents a very common crash / bug when generating waveforms for longer audio clips and continuing to make chagnes on the timeline (which closes all clips temporarily - interrupting the waveform extracting).
2025-11-06 14:51:57 -06:00
Jonathan Thomas
7e29fc0935
Improving audio directionality, with new function: SetAudioDirection(), so we can safely flip audio buffer direction when needed (i.e. time curves, reversed time). Also adding a new SetDirectionHint function to FrameMapper class - so our Clip class can inform the FrameMapper of its direction at any given moment. Also, clear resampler when changing directions inside a Time curve (since the audio buffer will be flipped - the resampler internal cache must be cleared).
2025-10-11 16:29:11 -05:00
Jonathan Thomas
fd2952752d
Improving audio directionality, with new function: SetAudioDirection(), so we can safely flip audio buffer direction when needed (i.e. time curves, reversed time). Also adding a new SetDirectionHint function to FrameMapper class - so our Clip class can inform the FrameMapper of its direction at any given moment. Also, clear resampler when changing directions inside a Time curve (since the audio buffer will be flipped - the resampler internal cache must be cleared).
2025-10-11 13:43:15 -05:00