Clean up some header files
[lsnes.git] / videodumper.hpp
blob42fd1e28981738c2be19a3f99ca94a686b93d745
1 #ifndef _videodumper__hpp__included__
2 #define _videodumper__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 drop counter increments by this much every frame.
148 uint64_t audio_drop_counter_inc;
151 * Audio drop counter modulus (when audio drop counter warps around, sample is dropped).
153 uint64_t audio_drop_counter_max;
156 * Audio sampling rate to write to AVI.
158 uint32_t audio_sampling_rate;
161 * Native audio sampling rate to write to auxillary SOX file.
163 double audio_native_sampling_rate;
166 * Interval of keyframes (WARNING: >1 gives non-keyframes which AVISource() doesn't like).
168 uint32_t keyframe_interval;
172 * The actual AVI dumper.
174 class avidumper
176 public:
177 avidumper(const std::string& _prefix, struct avi_info parameters);
178 ~avidumper() throw();
181 * Waits for the encode thread. Not needed: Operations that need to synchronize synchronize themselves.
183 void wait_idle() throw();
186 * Dump a frame (new segment starts if needed). Pixel byte order is BGRx.
188 * parameter data: The frame data.
189 * parameter width: Width of frame.
190 * parameter height: Height of frame.
191 * parameter fps_n: Numerator of fps value.
192 * parameter fps_d: Denomerator of fps value.
193 * throws std::bad_alloc: Not enough memory.
194 * throws std::runtime_error: Error dumping frame.
196 void on_frame(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
197 throw(std::bad_alloc, std::runtime_error);
200 * Dump an audio sample
202 * parameter left: Signed sample for left channel (-32768 - 327678).
203 * parameter right: Signed sample for right channel (-32768 - 327678).
204 * throws std::bad_alloc: Not enough memory.
205 * throws std::runtime_error: Error dumping sample.
207 void on_sample(short left, short right) throw(std::bad_alloc, std::runtime_error);
210 * Notify end of dump.
212 * throws std::bad_alloc: Not enough memory.
213 * throws std::runtime_error: Error closing dump.
215 void on_end() throw(std::bad_alloc, std::runtime_error);
218 * Causes current thread to become encode thread. Do not call this, the code internally uses it.
220 * returns: Return status for the thread.
222 int encode_thread();
225 * Set capture errored flag.
227 * parameter err: The error message.
229 void set_capture_error(const char* err) throw();
230 private:
231 void print_summary(std::ostream& str);
232 void on_frame_threaded(const uint32_t* data, uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d)
233 throw(std::bad_alloc, std::runtime_error);
234 void flush_audio_to(unsigned commit_ptr);
235 void open_and_write_avi_header(uint16_t width, uint16_t height, uint32_t fps_n, uint32_t fps_d);
236 void fixup_avi_header_and_close();
237 std::ofstream sox_stream;
238 std::ofstream avi_stream;
239 bool capture_error;
240 std::string capture_error_str;
241 bool sox_open;
242 bool avi_open;
243 //Global settings.
244 unsigned compression_level;
245 uint64_t audio_drop_counter_inc;
246 uint64_t audio_drop_counter_max;
247 uint32_t audio_sampling_rate;
248 double audio_native_sampling_rate;
249 uint32_t keyframe_interval;
250 //Previous frame.
251 uint16_t pwidth;
252 uint16_t pheight;
253 uint32_t pfps_n;
254 uint32_t pfps_d;
255 //Current segment.
256 uint32_t segment_movi_ptr;
257 uint32_t segment_frames;
258 uint32_t segment_samples;
259 uint32_t segment_last_keyframe;
260 uint32_t current_segment;
261 uint32_t fixup_avi_size;
262 uint32_t fixup_avi_frames;
263 uint32_t fixup_avi_length;
264 uint32_t fixup_avi_a_length;
265 uint32_t fixup_movi_size;
266 std::list<avi_frame> segment_chunks;
267 //Global info.
268 std::string prefix;
269 uint64_t total_data;
270 uint64_t total_frames;
271 uint64_t total_samples;
272 uint64_t raw_samples;
273 uint64_t audio_drop_counter;
274 //Temporary buffers.
275 std::vector<uint8_t> pframe;
276 std::vector<uint8_t> tframe;
277 std::vector<uint8_t> cframe;
278 short audio_buffer[AVIDUMPER_AUDIO_BUFFER];
279 unsigned audio_put_ptr;
280 unsigned audio_get_ptr;
281 volatile unsigned audio_commit_ptr; //Protected by frame_mutex.
282 //Multithreading stuff.
283 thread_class* frame_thread;
284 cv_class frame_cond;
285 mutex_class frame_mutex;
286 const uint32_t* mt_data;
287 volatile uint16_t mt_width;
288 volatile uint16_t mt_height;
289 volatile uint32_t mt_fps_n;
290 volatile uint32_t mt_fps_d;
291 volatile bool sigquit;
294 #endif