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 
38 namespace 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 openshot::CacheBase * GetCache()=0
Get the cache object used by this reader (note: not all readers use cache)
virtual std::shared_ptr< openshot::Frame > GetFrame(int64_t number)=0
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