|
OpenShot Library | libopenshot
0.5.0
|
Go to the documentation of this file.
27 : Thread(
"video-cache")
32 , preroll_on_next_fill(false)
33 , requested_display_frame(1)
34 , current_display_frame(1)
35 , cached_frame_count(0)
37 , timeline_max_frame(0)
39 , force_directional_cache(false)
40 , last_cached_index(0)
68 const int64_t timeline_max = timeline->GetMaxFrame();
69 if (timeline_max > 0) {
70 max_frame = timeline_max;
77 int64_t required_ahead = ready_min;
78 int64_t available_ahead = (dir > 0)
79 ? std::max<int64_t>(0, max_frame - playhead)
80 : std::max<int64_t>(0, playhead - 1);
81 required_ahead = std::min(required_ahead, available_ahead);
84 return (cached_index >= playhead + required_ahead);
86 return (cached_index <= playhead - required_ahead);
94 last_dir.store(new_speed > 0 ? 1 : -1);
96 speed.store(new_speed);
107 int64_t bytes =
static_cast<int64_t
>(width) * height *
sizeof(
char) * 4;
109 bytes += ((sample_rate * channels) / fps) *
sizeof(float);
118 startThread(Priority::high);
119 return isThreadRunning();
125 stopThread(timeoutMs);
126 return !isThreadRunning();
131 bool should_mark_seek =
false;
132 bool should_preroll =
false;
136 should_mark_seek =
true;
139 if (cache && !cache->
Contains(new_position))
143 timeline->ClearAllCache();
145 new_cached_count = 0;
146 should_preroll =
true;
150 new_cached_count = cache->
Count();
167 Seek(new_position,
false);
173 const int current_speed =
speed.load();
174 if (current_speed != 0) {
175 return (current_speed > 0 ? 1 : -1);
188 int64_t timeline_end,
189 int64_t preroll_frames)
191 int64_t preroll_start = playhead;
192 if (preroll_frames > 0) {
194 preroll_start = std::max<int64_t>(1, playhead - preroll_frames);
197 preroll_start = std::min<int64_t>(timeline_end, playhead + preroll_frames);
210 if (min_frames < 0) {
213 if (max_frames > 0 && min_frames > max_frames) {
214 min_frames = max_frames;
223 if (paused && !cache->
Contains(playhead)) {
226 timeline->ClearAllCache();
237 int64_t timeline_end,
238 int64_t& window_begin,
239 int64_t& window_end)
const
243 window_begin = playhead;
244 window_end = playhead + ahead_count;
248 window_begin = playhead - ahead_count;
249 window_end = playhead;
252 window_begin = std::max<int64_t>(window_begin, 1);
253 window_end = std::min<int64_t>(window_end, timeline_end);
257 int64_t window_begin,
262 bool window_full =
true;
266 while ((dir > 0 && next_frame <= window_end) ||
267 (dir < 0 && next_frame >= window_begin))
269 if (threadShouldExit()) {
281 cache->
Add(framePtr);
290 cache->
Touch(next_frame);
302 using micro_sec = std::chrono::microseconds;
303 using double_micro_sec = std::chrono::duration<double, micro_sec::period>;
305 while (!threadShouldExit()) {
313 std::this_thread::sleep_for(double_micro_sec(50000));
322 std::this_thread::sleep_for(double_micro_sec(50000));
327 bool paused = (
speed.load() == 0);
334 if (
speed.load() != 0) {
347 int64_t capacity = 0;
348 if (max_bytes > 0 && bytes_per_frame > 0) {
349 capacity = max_bytes / bytes_per_frame;
356 bool did_user_seek =
false;
357 bool use_preroll =
false;
376 else if (!paused && capacity >= 1) {
380 int64_t window_begin, window_end;
390 bool outside_window =
393 if (outside_window) {
400 std::this_thread::sleep_for(double_micro_sec(50000));
403 int64_t ahead_count =
static_cast<int64_t
>(capacity *
405 int64_t window_size = ahead_count + 1;
406 if (window_size < 1) {
409 int64_t ready_target = window_size - 1;
410 if (ready_target < 0) {
423 int64_t window_begin, window_end;
435 if (paused && window_full) {
436 cache->
Touch(playhead);
440 int64_t sleep_us =
static_cast<int64_t
>(
443 std::this_thread::sleep_for(double_micro_sec(sleep_us));
Header file for global Settings class.
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
VideoCacheThread()
Constructor: initializes member variables and assumes forward direction on first launch.
float ToFloat()
Return this fraction as a float (i.e. 1/2 = 0.5)
float VIDEO_CACHE_PERCENT_AHEAD
Percentage of cache in front of the playhead (0.0 to 1.0)
std::mutex seek_state_mutex
Protects coherent seek state updates/consumption.
int preview_width
Optional preview width of timeline image. If your preview window is smaller than the timeline,...
bool StartThread()
Start the cache thread at high priority. Returns true if it’s actually running.
std::atomic< int > last_speed
Last non-zero speed (for tracking).
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
bool prefetchWindow(CacheBase *cache, int64_t window_begin, int64_t window_end, int dir, ReaderBase *reader)
Prefetch all missing frames in [window_begin ... window_end] or [window_end ... window_begin].
std::atomic< bool > preroll_on_next_fill
True if next cache rebuild should include preroll offset.
This namespace is the default namespace for all code in the openshot library.
int preview_height
Optional preview width of timeline image. If your preview window is smaller than the timeline,...
virtual void Add(std::shared_ptr< openshot::Frame > frame)=0
Add a Frame to the cache.
std::atomic< int64_t > last_cached_index
Index of the most recently cached frame.
int computeDirection() const
ReaderBase * reader
The source reader (e.g., Timeline, FFmpegReader).
openshot::ReaderInfo info
Information about the current media file.
This class is contains settings used by libopenshot (and can be safely toggled at any point)
Header file for Timeline class.
void handleUserSeek(int64_t playhead, int dir)
If userSeeked is true, reset last_cached_index just behind the playhead.
int64_t computePrerollFrames(const Settings *settings) const
Compute preroll frame count from settings.
bool ENABLE_PLAYBACK_CACHING
Enable/Disable the cache thread to pre-fetch and cache video frames before we need them.
int width
The width of the video (in pixesl)
All cache managers in libopenshot are based on this CacheBase class.
int VIDEO_CACHE_MAX_FRAMES
Max number of frames (when paused) to cache for playback.
Header file for CacheBase class.
std::atomic< int64_t > cached_frame_count
Estimated count of frames currently stored in cache.
Exception for frames that are out of bounds.
~VideoCacheThread() override
int64_t video_length
The number of frames in the video stream.
int height
The height of the video (in pixels)
int VIDEO_CACHE_MAX_PREROLL_FRAMES
Max number of frames (ahead of playhead) to cache during playback.
std::atomic< bool > userSeeked
True if Seek(..., true) was called (forces a cache reset).
int VIDEO_CACHE_MIN_PREROLL_FRAMES
Minimum number of frames to cache before playback begins.
This class represents a timeline.
void setSpeed(int new_speed)
Set playback speed/direction. Positive = forward, negative = rewind, zero = pause.
std::atomic< int > speed
Current playback speed (0=paused, >0 forward, <0 backward).
static Settings * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
std::atomic< int64_t > requested_display_frame
Frame index the user requested.
virtual void Touch(int64_t frame_number)=0
Move frame to front of queue (so it lasts longer)
Header file for Frame class.
void run() override
Thread entry point: loops until threadShouldExit() is true.
virtual int64_t Count()=0
Count the frames in the queue.
Header file for VideoCacheThread class.
int64_t getBytes(int width, int height, int sample_rate, int channels, float fps)
Estimate memory usage for a single frame (video + audio).
bool clearCacheIfPaused(int64_t playhead, bool paused, CacheBase *cache)
When paused and playhead is outside current cache, clear all frames.
std::atomic< int > last_dir
Last direction sign (+1 forward, –1 backward).
bool StopThread(int timeoutMs=0)
Stop the cache thread (wait up to timeoutMs ms). Returns true if it stopped.
int64_t GetMaxBytes()
Gets the maximum bytes value.
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
virtual bool Contains(int64_t frame_number)=0
Check if frame is already contained in cache.
This abstract class is the base class, used by all readers in libopenshot.
int64_t GetMaxFrame()
Look up the end frame number of the latest element on the timeline.
void computeWindowBounds(int64_t playhead, int dir, int64_t ahead_count, int64_t timeline_end, int64_t &window_begin, int64_t &window_end) const
Compute the “window” of frames to cache around playhead.
std::atomic< int64_t > min_frames_ahead
Minimum number of frames considered “ready” (pre-roll).
void Seek(int64_t new_position)
Seek to a specific frame (no preroll).
void handleUserSeekWithPreroll(int64_t playhead, int dir, int64_t timeline_end, int64_t preroll_frames)
Reset last_cached_index to start caching with a directional preroll offset.
int channels
The number of audio channels used in the audio stream.
virtual openshot::CacheBase * GetCache()=0
Get the cache object used by this reader (note: not all readers use cache)
Header file for all Exception classes.