CAVAPA-GUI  30.5.2014
 All Classes Namespaces Functions Variables Typedefs Enumerations Pages
recorder.h
1 /****************************************************************************
2  * Copyright (c) 2014, Joel Kivelä, Erkki Koskenkorva, Oskari Leppäaho,
3  * Mika Lehtinen and Petri Partanen.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ****************************************************************************/
30 #ifndef RECORDER_H
31 #define RECORDER_H
32 
33 #include <condition_variable>
34 #include <chrono>
35 #include <deque>
36 #include <mutex>
37 #include <thread>
38 
39 #include "../common.h"
40 
41 namespace cavapa_gui
42 {
49 {
54  unsigned int missed_frames;
55 
59  unsigned int written_frames;
60 };
61 
62 // Empty statistics that can be used for zeroing.
63 static const RecorderStats EMPTY_RECORDER_STATS = {0, 0};
64 
91 class Recorder {
92 public:
93  Recorder() {}
94  ~Recorder();
95 
100 
105  unsigned int countBuffered();
106 
117  static void detach(std::unique_ptr<Recorder>&& ptr)
118  { detached_recorders.push_back(std::move(ptr)); }
119 
130  unsigned int getMissedFrames();
131 
137  unsigned int getRecordedFrames();
138 
144  bool isOpen() { return is_open; }
145 
151  bool isTerminated();
152 
166  bool open(const std::string& filename, int fourcc,
167  double fps, cv::Size frameSize, bool isColor = true);
168 
175  RecorderStats push(const cv::Mat& image);
176 
182  bool repush();
183 
195  void stop();
196 
197 private:
204  enum class RecorderStatus { ALIVE, STOP, TERMINATE };
205 
213  inline bool fetch(std::unique_lock<std::mutex>& guard);
214 
219  static void flushDetached();
220 
226  inline cv::Mat pop();
227 
234  inline void setStatus(RecorderStatus new_status);
235 
241  void work();
242 
243  bool is_open = false; // For the main thread to use without a mutex!
244 
245  // These class members are accessed only with a mutex:
246  std::deque<cv::Mat> buffer; // Buffer for images.
247  std::mutex buffer_mutex; // General buffer mutex.
248  cv::Mat latest_image; // Will hold the last image for repushing.
249  RecorderStats statistics = EMPTY_RECORDER_STATS;
250  RecorderStatus status = RecorderStatus::ALIVE; // Current status
251  std::condition_variable wake_worker;// Buffer status change signal
252  std::unique_ptr<std::thread> worker = nullptr; // Thread for writing
253 
254  // OpenCV writer, the main thread should not access this if the
255  // worker thread exists! No mutex is used for this, in order to retrieve
256  // without the main thread waiting.
257  std::unique_ptr<cv::VideoWriter> writer = nullptr;
258 
259  // List of terminating recorders.
260  static std::vector<std::unique_ptr<Recorder>> detached_recorders;
261 };
262 } // namespace
263 
264 #endif // RECORDER_H
unsigned int missed_frames
The number of the frames that have missed the recording.
Definition: recorder.h:54
bool open(const std::string &filename, int fourcc, double fps, cv::Size frameSize, bool isColor=true)
Opens the video recorder.
Definition: recorder.cpp:116
unsigned int getRecordedFrames()
Returns the recorded frames.
Definition: recorder.cpp:103
unsigned int countBuffered()
Counts the currently buffered images.
Definition: recorder.cpp:60
bool repush()
Repushes the last image again to the buffer.
Definition: recorder.cpp:189
The buffered recorder class creates the video file from the images.
Definition: recorder.h:91
void stop()
Softly stops the recording.
Definition: recorder.cpp:224
bool isTerminated()
Retrieves the recorder status.
Definition: recorder.cpp:109
unsigned int written_frames
The frames that have been written by the recorder.
Definition: recorder.h:59
RecorderStats push(const cv::Mat &image)
Pushes the new image to the buffer.
Definition: recorder.cpp:163
Statistics structure used for Recorder.
Definition: recorder.h:48
static void detach(std::unique_ptr< Recorder > &&ptr)
Detaches the recorder.
Definition: recorder.h:117
unsigned int getMissedFrames()
Returns the count of the missed frames.
Definition: recorder.cpp:97
bool isOpen()
Returns the initialization status of the recorder.
Definition: recorder.h:144
DISALLOW_COPY_AND_ASSIGN(Recorder)
Copy and assign of the class is not allowed.