Commit Graph

3118 Commits

Author SHA1 Message Date
Jonathan Thomas
6c1f687afc Merge branch 'develop' into qt6-support 2026-02-13 23:07:53 -06:00
Jonathan Thomas
22c808c2bb Merge pull request #1035 from OpenShot/caching-protections
Harden playback/cache path for malformed media and concurrent timeline updates
2026-02-13 20:25:15 -06:00
Jonathan Thomas
a7e9ba1d55 - src/FFmpegReader.cpp
- Disable audio when decoder sample format is invalid (AV_SAMPLE_FMT_NONE).
      - Only synthesize channel layout when reported channels are actually valid (> 0).
  - src/AudioReaderSource.cpp
      - Added progress/validity guards in getNextAudioBlock() to prevent infinite loops on corrupt/empty audio frames.
2026-02-13 12:13:44 -06:00
Jonathan Thomas
429826be36 Fixing a few nitpicks in caching function to use local variables when available (instead of the atomic ones) 2026-02-13 11:48:33 -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
8c4db9ac0b Merge pull request #1036 from OpenShot/timeline-playback-length
Fix VideoCacheThread::isReady() when near the max frame of a timeline
2026-02-13 11:01:34 -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
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
149456d13f Merge pull request #1032 from OpenShot/cache-before-playhead
VideoCacheThread: Add Directional Pre-roll
2026-02-10 11:51:21 -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
c7b36d9215 Slight refactor to our Python swig bindings to better support Arm64 pointer address space (required for Android) 2026-02-03 11:20:12 -06:00
Jonathan Thomas
44f92a0387 Improving swig to wrap pointers as PyLong_AsVoidPtr - to avoid Android memory addresses overflowing as an int. 2026-02-02 21:14:01 -06:00
Jonathan Thomas
23b4e748ea Improving swig bindings for Python, Java, and Ruby for access direct pixel byte array:
Example Code Snippets:
Python:
import openshot

r = openshot.FFmpegReader("/home/jonathan/Pictures/ChatGPT Image Mar 27, 2025, 09_50_56 AM.png")
r.Open()
f = r.GetFrame(1)
buf = f.GetPixelsBytes()
w, h = f.GetWidth(), f.GetHeight()
stride = f.GetBytesPerLine()

Ruby:
require "openshot"

r = Openshot::FFmpegReader.new("/home/jonathan/Pictures/ChatGPT Image Mar 27, 2025, 09_50_56 AM.png")
r.Open()
f = r.GetFrame(1)
buf = f.GetPixelsBytes
w = f.GetWidth
h = f.GetHeight
stride = f.GetBytesPerLine
2025-12-22 13:46:41 -06:00
Jonathan Thomas
a26ed32424 Adding missing packages to our linux install instructions doc:
python3-zmq python3-pyqt5.qtwebengine
2025-12-22 13:44:54 -06:00
Jonathan Thomas
bfca7ee8ad Adding Qt6 detection and compatibility, without breaking Qt5. -DUSE_QT6=AUTO|ON|OFF (default: AUTO; prefers Qt6 when available and CMake ≥3.16, ON forces Qt6, OFF forces Qt5). Also, a few version specific changes for API changes on Qt6, but it appears to work well. 2025-12-17 22:59:25 -06:00
Jonathan Thomas
47b308122f Merge pull request #1026 from OpenShot/install-prefix-python
Take 2: Trying again to fix the python fallback directory detection f…
2025-12-16 23:23:44 -06:00
Jonathan Thomas
3f60f601ca Take 2: Trying again to fix the python fallback directory detection for Launchpad build servers 2025-12-16 23:23:07 -06:00