Allow variable arguments to command functions
[lsnes.git] / avidump / avidump.hpp
blobacd53c40b9798452c2a672ce4a3b81002bee0e7c
1 #ifndef _avidump__hpp__included__
2 #define _avidump__hpp__included__
4 #include <cstdint>
5 #include <iostream>
6 #include <fstream>
7 #include <vector>
8 #include <list>
9 #include <stdexcept>
12 #ifndef NO_THREADS
13 #include <thread>
14 #include <condition_variable>
15 #include <mutex>
17 /**
18 * Class of thread.
20 typedef std::thread thread_class;
22 /**
23 * Class of condition variables.
25 typedef std::condition_variable cv_class;
27 /**
28 * Class of mutexes.
30 typedef std::mutex mutex_class;
32 /**
33 * Class of unique mutexes (for condition variable waiting).
35 typedef std::unique_lock<std::mutex> umutex_class;
37 #else
39 /**
40 * Class of thread.
42 struct thread_class
44 /**
45 * Does nothing.
47 template<typename T, typename... args>
48 thread_class(T obj, args... a) {}
49 /**
50 * Does nothing.
52 void join() {}
55 /**
56 * Class of mutexes.
58 typedef struct mutex_class
60 /**
61 * Does nothing.
63 void lock() {}
64 /**
65 * Does nothing.
67 void unlock() {}
68 } umutex_class;
70 /**
71 * Class of condition variables.
73 struct cv_class
75 /**
76 * Does nothing.
78 void wait(umutex_class& m) {}
79 /**
80 * Does nothing.
82 void notify_all() {}
85 #endif
87 /**
88 * Size of audio buffer (enough to buffer 3 frames).
90 #define AVIDUMPER_AUDIO_BUFFER 4096
92 /**
93 * Information about frame in AVI.
95 struct avi_frame
97 /**
98 * Constructor.
100 * parameter _flags: Flags for frame.
101 * parameter _type: AVI type for frame (big-endian!).
102 * parameter _offset: Offset of frame from start of MOVI.
103 * parameter _size: Size of frame data.
105 avi_frame(uint32_t _flags, uint32_t _type, uint32_t _offset, uint32_t _size);
108 * Write the index entry for frame.
110 * parameter buf: Buffer to write to.
112 void write(uint8_t* buf);
115 * Flags.
117 uint32_t flags;
120 * Chunk type.
122 uint32_t type;
125 * Chunk offset.
127 uint32_t offset;
130 * Chunk size.
132 uint32_t size;
136 * Parameters for AVI dumping.
138 struct avi_info
141 * Zlib compression level (0-9).
143 unsigned compression_level;
146 * Audio sampling rate to write to AVI.
148 uint32_t audio_sampling_rate;
151 * Interval of keyframes (WARNING: >1 gives non-keyframes which AVISource() doesn't like).
153 uint32_t keyframe_interval;
155 * Maximum number of frames per segement (0 => infinite)
157 uint32_t max_frames_per_segment;
161 * The actual AVI dumper.
163 class avidumper
165 public:
166 avidumper(const std::string& _prefix, struct avi_info parameters);
167 ~avidumper() throw();
170 * Waits for the encode thread. Not needed: Operations that need to synchronize synchronize themselves.
172 void wait_idle() throw();
175 * Dump a frame (new segment starts if needed). Pixel byte order is BGRx.
177 * parameter data: The frame data.
178 * parameter width: Width of frame.
179 * parameter height: Height of frame.
180 * parameter fps_n: Numerator of fps value.
181 * parameter fps_d: Denomerator of fps value.
182 * throws std::bad_alloc: Not enough memory.
183 * throws std::runtime_error: Error dumping frame.
185 void on_frame(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
186 throw(std::bad_alloc, std::runtime_error);
189 * Dump an audio sample
191 * parameter left: Signed sample for left channel (-32768 - 327678).
192 * parameter right: Signed sample for right channel (-32768 - 327678).
193 * throws std::bad_alloc: Not enough memory.
194 * throws std::runtime_error: Error dumping sample.
196 void on_sample(short left, short right) throw(std::bad_alloc, std::runtime_error);
199 * Notify end of dump.
201 * throws std::bad_alloc: Not enough memory.
202 * throws std::runtime_error: Error closing dump.
204 void on_end() throw(std::bad_alloc, std::runtime_error);
207 * Causes current thread to become encode thread. Do not call this, the code internally uses it.
209 * returns: Return status for the thread.
211 int encode_thread();
214 * Set capture errored flag.
216 * parameter err: The error message.
218 void set_capture_error(const char* err) throw();
219 private:
220 void print_summary(std::ostream& str);
221 void on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
222 throw(std::bad_alloc, std::runtime_error);
223 void flush_audio_to(unsigned commit_ptr);
224 void open_and_write_avi_header(uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d);
225 void fixup_avi_header_and_close();
226 std::ofstream avi_stream;
227 bool capture_error;
228 std::string capture_error_str;
229 bool avi_open;
230 //Global settings.
231 unsigned compression_level;
232 uint32_t audio_sampling_rate;
233 uint32_t keyframe_interval;
234 uint32_t maxframes;
235 //Previous frame.
236 uint16_t pwidth;
237 uint16_t pheight;
238 uint32_t pfps_n;
239 uint32_t pfps_d;
240 //Current segment.
241 uint32_t segment_movi_ptr;
242 uint32_t segment_frames;
243 uint32_t segment_samples;
244 uint32_t segment_last_keyframe;
245 uint32_t current_segment;
246 uint32_t fixup_avi_size;
247 uint32_t fixup_avi_frames;
248 uint32_t fixup_avi_length;
249 uint32_t fixup_avi_a_length;
250 uint32_t fixup_movi_size;
251 std::list<avi_frame> segment_chunks;
252 //Global info.
253 std::string prefix;
254 uint64_t total_data;
255 uint64_t total_frames;
256 uint64_t total_samples;
257 //Temporary buffers.
258 std::vector<uint8_t> pframe;
259 std::vector<uint8_t> tframe;
260 std::vector<uint8_t> cframe;
261 short audio_buffer[AVIDUMPER_AUDIO_BUFFER];
262 unsigned audio_put_ptr;
263 unsigned audio_get_ptr;
264 volatile unsigned audio_commit_ptr; //Protected by frame_mutex.
265 //Multithreading stuff.
266 thread_class* frame_thread;
267 cv_class frame_cond;
268 mutex_class frame_mutex;
269 const uint32_t* mt_data;
270 volatile uint16_t mt_width;
271 volatile uint16_t mt_height;
272 volatile uint32_t mt_fps_n;
273 volatile uint32_t mt_fps_d;
274 volatile bool sigquit;
277 #endif