26 Commits

Author SHA1 Message Date
Jonathan Thomas
7efc48006a Modify all throw InvalidFile(...) callsites: each now has a distinct message string, and adding unit tests to verify this.
So a crash line will now be more like:
  what(): FFmpegReader could not open media file. for file C:\...\TitleFileName%04d.png
  instead of only File could not be opened.
2026-02-23 16:55:49 -06:00
Jonathan Thomas
c43092eaa5 Merge branch 'develop' into caching-protections
# Conflicts:
#	src/Qt/VideoCacheThread.cpp
2026-02-13 11:29:32 -06:00
Jonathan Thomas
fb41a3c479 • - Fix VideoCacheThread::isReady() so preroll readiness is clamped by frames actually available to the timeline boundary (end/start), preventing playback from stalling in PLAY near the end.
- Add regression coverage in tests/VideoCacheThread.cpp (isReady: clamps preroll requirement at timeline boundaries) for forward-near-end and backward-near-start cases.
2026-02-12 23:41:51 -06:00
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
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
0570ad084b Large timeline clean-up, speed-up, and fix concurrency bugs:
- make Add/Remove Effect methods thread safe
- Fix RemoveClip memory leak
- Improve performance of sorting clips by position and layer, cache some common accessors, and speed up "clip intersection" logic
- Don't resize audio container in loop - do it once
- Large refactor of looping through clips and finding top clip
- Protect ClearAllCache from empty Readers, prevent crash
- Expanded unit tests to include RemoveEffect, and test many of the changes in the commit.
2025-09-11 23:27:41 -05:00
Jonathan Thomas
5977483142 Fixing GetMinFrame() function to correctly + 1, since our starting frames in OpenShot always begin with 1 (not 0) 2024-12-09 23:30:46 -06:00
Jonathan Thomas
959947a3f8 Adding GetMinTime/GetMinFrame functions to timeline, to find the "start" position of a timeline, if it's not 0.0. 2024-09-30 16:23:30 -05:00
Jonathan Thomas
118810f160 Do not add +1 to GetMaxFrame() calculation. This is incorrect math for calculating the max frame of a timeline, and not correct. For example, 1 second long timeline at 30 FPS, should have exactly 30 frames (not 31). 2024-09-24 12:40:37 -05:00
Jonathan Thomas
52a9e3be5d - Clip reader init should consider paths with a % to use FFmpegReader by default (i.e. image sequences)
- FFmpegReader info struct should not be initialized during Open() after it is initially populated - so our SetJson() method can properly override it's values
- FrameMapper Json() method should include it's mapped Reader JSON - even though it is not yet possible to read it back in yet
- New unit tests for Timeline ApplyJsonDiff, and verification that we can override FFmpegReader info struct (i.e. updating FPS, time bases, etc...)
- Some whitespace fixes
2023-02-13 16:42:21 -06:00
Jonathan Thomas
da813e08db Fixing whitespace 2022-10-28 19:02:27 -05:00
Jonathan Thomas
9f3fa0af52 Fixing whitespace 2022-10-28 19:01:27 -05:00
Jonathan Thomas
1547fb1d52 New unit tests around GetMaxFrame / GetMaxTime. Improvemetns to apply_json_to_timeline() to not clear all cache when setting the timeline's "duration" - an optimization for performance 2022-10-28 15:25:30 -05:00
Jonathan Thomas
c12e3fe96e - 2 new unit tests, to verify Reader() ownership and clean-up is correct
- Bug fix for clip, to delete a new Reader, regardless of how it was set (correctly track allocated readers, and ignore FrameMappers pointed to existing allocated reader)
- Bug fix for timeline to correctly wrap Reader with FrameMapper
2022-10-28 11:00:47 -05:00
Jonathan Thomas
389bf33adb - Protect AddClip(), RemoveClip(), update_open_clips(), sort_clips(), sort_effects() methods with mutex, making them thread safe
- Refactor sorting of clips & effects, and only sort these arrays when the arrays change (instead of each call to GetFrame)
- Cache max timeline duration, and make Timeline::GetMaxTime() thread safe
- New multi-threaded unit tests, which are designed to verify no seg faults on multi-threaded calls to Timeline::GetFrame(), Timeline::AddClip(), and Timeline::RemoveClip()
- New public Timeline::SortTimeline() method which is called by child Clips automatically, when certain properties are changed
2022-10-22 22:55:40 -05:00
Jonathan Thomas
d8f8cba27f Do not sort_clips on every call to GetFrame, as this invalidates the internal clips list, and causes crashes in ClearAllCache() and Clear() methods. 2022-10-21 18:11:32 -05:00
Jonathan Thomas
31566a192a Protection for ClearAllCache method, to prevent messing with closed clips. Added a multi-threaded unit tests for Timeline::GetFrame access - to verify nothing crashes. 2022-10-13 00:01:03 -05:00
Jonathan Thomas
934ca786ed Adding new Clear() method to Timeline, to delete all allocated clips, effects, and frame mapeprs (freeing memory). Also, keep track of allocated clips and effects on timeline (when using SetJson to create them), so we can clean them up correctly on Clear() or RemoveClip()/RemoveEffect(). Added new test case for Clear(). 2022-10-06 15:07:31 -05:00
Jonathan Thomas
d093004dcf Fixing timeline tests. Recent FrameMapper bug fixes changed the mapping slightly, for certain tests 2022-07-21 10:07:34 -05:00
FeRD (Frank Dana)
677ed5f591 Tests: Switch test files to openshot_catch.h 2022-06-17 15:37:51 -04:00
Frank Dana
b9833b71ab Merge pull request #687 from ferdnyc/timeline-inheritance
Fix inheritance of TimelineBase::Clips(), and add unit test
2021-10-24 02:19:19 -04:00
Frank Dana
59138ea3e4 Adopt license management via Reuse project/tool (#711)
* reuse-managed license/copyright headers

reuse is a tool for compliance with the REUSE recommendations. See
<https://reuse.software/> for more information, and
<https://reuse.readthedocs.io/> for the online documentation.

* Set jsoncpp license
* Add MIT license for Decklink sources
* Explicitly license examples/
  - Add headers to source files
  - Change blanket licensing in .reuse/dep5 to only cover binary media
  - Import CC-BY-3.0 license and assign to sintel_trailer
2021-10-16 01:26:26 -04:00
FeRD (Frank Dana)
cd12edac5a tests/Timeline: Test TimelineBase::Clips() 2021-06-10 08:17:26 -04:00
FeRD (Frank Dana)
2255852483 Merge branch 'develop' into catch-tests 2021-04-09 06:30:38 -04:00
FeRD (Frank Dana)
d9775d4a5e Port unit tests to Catch2 2021-04-09 04:09:36 -04:00