OpenShot Library | libopenshot 0.2.7
VideoCacheThread.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @brief Source file for VideoCacheThread class
4 * @author Jonathan Thomas <jonathan@openshot.org>
5 *
6 * @ref License
7 */
8
9/* LICENSE
10 *
11 * Copyright (c) 2008-2019 OpenShot Studios, LLC
12 * <http://www.openshotstudios.com/>. This file is part of
13 * OpenShot Library (libopenshot), an open-source project dedicated to
14 * delivering high quality video editing and animation solutions to the
15 * world. For more information visit <http://www.openshot.org/>.
16 *
17 * OpenShot Library (libopenshot) is free software: you can redistribute it
18 * and/or modify it under the terms of the GNU Lesser General Public License
19 * as published by the Free Software Foundation, either version 3 of the
20 * License, or (at your option) any later version.
21 *
22 * OpenShot Library (libopenshot) is distributed in the hope that it will be
23 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public License
28 * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29 */
30
31#include "VideoCacheThread.h"
32#include "Exceptions.h"
33#include <algorithm>
34
35#include <thread> // for std::this_thread::sleep_for
36#include <chrono> // for std::chrono::milliseconds
37
38namespace openshot
39{
40 // Constructor
42 : Thread("video-cache"), speed(1), is_playing(false), position(1)
43 , reader(NULL), max_concurrent_frames(OPEN_MP_NUM_PROCESSORS * 4), current_display_frame(1)
44 {
45 }
46
47 // Destructor
49 {
50 }
51
52 // Get the currently playing frame number (if any)
54 {
55 if (frame)
56 return frame->number;
57 else
58 return 0;
59 }
60
61 // Set the currently playing frame number (if any)
62 void VideoCacheThread::setCurrentFramePosition(int64_t current_frame_number)
63 {
64 current_display_frame = current_frame_number;
65 }
66
67 // Seek the reader to a particular frame number
68 void VideoCacheThread::Seek(int64_t new_position)
69 {
70 position = new_position;
71 }
72
73 // Play the video
75 // Start playing
76 is_playing = true;
77 }
78
79 // Stop the audio
81 // Stop playing
82 is_playing = false;
83 }
84
85 // Start the thread
87 {
88 // Types for storing time durations in whole and fractional milliseconds
89 using ms = std::chrono::milliseconds;
90 using double_ms = std::chrono::duration<double, ms::period>;
91
92 // Calculate on-screen time for a single frame in milliseconds
93 const auto frame_duration = double_ms(1000.0 / reader->info.fps.ToDouble());
94
95 while (!threadShouldExit() && is_playing) {
96
97 // Cache frames before the other threads need them
98 // Cache frames up to the max frames. Reset to current position
99 // if cache gets too far away from display frame. Cache frames
100 // even when player is paused (i.e. speed 0).
101 while (((position - current_display_frame) < max_concurrent_frames) && is_playing)
102 {
103 // Only cache up till the max_concurrent_frames amount... then sleep
104 try
105 {
106 if (reader) {
107 ZmqLogger::Instance()->AppendDebugMethod("VideoCacheThread::run (cache frame)", "position", position, "current_display_frame", current_display_frame, "max_concurrent_frames", max_concurrent_frames, "needed_frames", (position - current_display_frame));
108
109 // Force the frame to be generated
110 if (reader->GetCache()->GetSmallestFrame()) {
111 int64_t smallest_cached_frame = reader->GetCache()->GetSmallestFrame()->number;
112 if (smallest_cached_frame > current_display_frame) {
113 // Cache position has gotten too far away from current display frame.
114 // Reset the position to the current display frame.
115 position = current_display_frame;
116 }
117 }
118 reader->GetFrame(position);
119 }
120
121 }
122 catch (const OutOfBoundsFrame & e)
123 {
124 // Ignore out of bounds frame exceptions
125 }
126
127 // Increment frame number
128 position++;
129 }
130
131 // Sleep for 1 frame length
132 std::this_thread::sleep_for(frame_duration);
133 }
134
135 return;
136 }
137}
Header file for all Exception classes.
#define OPEN_MP_NUM_PROCESSORS
Source file for VideoCacheThread class.
virtual std::shared_ptr< openshot::Frame > GetSmallestFrame()=0
Get the smallest frame number.
double ToDouble() const
Return this fraction as a double (i.e. 1/2 = 0.5)
Definition: Fraction.cpp:59
Exception for frames that are out of bounds.
Definition: Exceptions.h:286
openshot::ReaderInfo info
Information about the current media file.
Definition: ReaderBase.h:111
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
virtual openshot::CacheBase * GetCache()=0
Get the cache object used by this reader (note: not all readers use cache)
std::shared_ptr< Frame > frame
void Play()
Play the video.
int64_t getCurrentFramePosition()
Get the currently playing frame number (if any)
void Stop()
Stop the audio playback.
void Seek(int64_t new_position)
Seek the reader to a particular frame number.
void setCurrentFramePosition(int64_t current_frame_number)
Set the currently displaying frame number.
void run()
Start the thread.
void AppendDebugMethod(std::string method_name, std::string arg1_name="", float arg1_value=-1.0, std::string arg2_name="", float arg2_value=-1.0, std::string arg3_name="", float arg3_value=-1.0, std::string arg4_name="", float arg4_value=-1.0, std::string arg5_name="", float arg5_value=-1.0, std::string arg6_name="", float arg6_value=-1.0)
Append debug information.
Definition: ZmqLogger.cpp:190
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method)
Definition: ZmqLogger.cpp:52
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:47
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: ReaderBase.h:70