lsnes rr0-β21
[lsnes.git] / avi / cscd.hpp
blobb84e2c395d4ff0d4bf2800b6aec996d163d4e762
1 #ifndef _output_cscd__hpp__included__
2 #define _output_cscd__hpp__included__
4 #ifdef USE_THREADS
5 #define REALLY_USE_THREADS 1
6 #endif
7 #ifndef NO_THREADS
8 #ifdef __linux__
9 #define REALLY_USE_THREADS 1
10 #endif
11 #endif
13 #ifdef REALLY_USE_THREADS
14 #include <thread>
15 #include <condition_variable>
16 #include <mutex>
18 /**
19 * Class of thread.
21 typedef std::thread thread_class;
23 /**
24 * Class of condition variables.
26 typedef std::condition_variable cv_class;
28 /**
29 * Class of mutexes.
31 typedef std::mutex mutex_class;
33 /**
34 * Class of unique mutexes (for condition variable waiting).
36 typedef std::unique_lock<std::mutex> umutex_class;
38 #else
40 /**
41 * Class of thread.
43 struct thread_class
45 /**
46 * Does nothing.
48 template<typename T, typename args>
49 thread_class(T obj, args a) {}
50 /**
51 * Does nothing.
53 void join() {}
56 /**
57 * Class of mutexes.
59 typedef struct mutex_class
61 /**
62 * Does nothing.
64 void lock() {}
65 /**
66 * Does nothing.
68 void unlock() {}
69 } umutex_class;
71 /**
72 * Class of condition variables.
74 struct cv_class
76 /**
77 * Does nothing.
79 void wait(umutex_class& m) {}
80 /**
81 * Does nothing.
83 void notify_all() {}
86 #endif
88 #ifdef __GNUC__
89 typedef unsigned long long Uint64;
90 typedef unsigned long long Sint64;
91 #elif defined(_MSC_VER)
92 typedef unsigned __int64 Uint64;
93 typedef signed __int64 Sint64;
94 #else
95 #error "Please define 64bit types."
96 #endif
98 #include <stdexcept>
99 #include <cstdlib>
100 #include <vector>
101 #include <fstream>
102 #include <list>
104 struct avi_file_structure;
107 * Dump AVI using CSCD for video and PCM for audio.
109 class avi_cscd_dumper
111 public:
113 * AVI dumper parameters.
115 struct global_parameters
118 * Sound sampling rate.
120 unsigned long sampling_rate;
122 * Sound channel count.
124 unsigned channel_count;
126 * 16-bit audio flag.
128 bool audio_16bit;
132 * Pixel formats
134 enum pixelformat
136 PIXFMT_RGB15_LE, /* Little-endian 15-bit RGB. */
137 PIXFMT_RGB15_BE, /* Big-endian 15-bit RGB. */
138 PIXFMT_RGB15_NE, /* Native-endian 15-bit RGB. */
139 PIXFMT_RGB24, /* 24-bit RGB, RGB order. */
140 PIXFMT_BGR24, /* 24-bit RGB, BGR order. */
141 PIXFMT_RGBX, /* 32-bit RGB, RGBx order. */
142 PIXFMT_BGRX, /* 32-bit RGB, BGRx order. */
143 PIXFMT_XRGB, /* 32-bit RGB, BGRx order. */
144 PIXFMT_XBGR /* 32-bit RGB, xBGR order. */
148 * Sound formats.
150 enum soundformat
152 SNDFMT_SILENCE, /* No data, silence. */
153 SNDFMT_SIGNED_8, /* 8-bit signed. */
154 SNDFMT_UNSIGNED_8, /* 8-bit unsigned. */
155 SNDFMT_SIGNED_16LE, /* 16-bit signed little-endian. */
156 SNDFMT_UNSIGNED_16LE, /* 16-bit unsigned little-endian. */
157 SNDFMT_SIGNED_16BE, /* 16-bit signed big-endian. */
158 SNDFMT_UNSIGNED_16BE, /* 16-bit unsigned big-endian. */
159 SNDFMT_SIGNED_16NE, /* 16-bit signed native-endian. */
160 SNDFMT_UNSIGNED_16NE /* 16-bit unsigned native-endian. */
164 * AVI per-segment parameters
166 struct segment_parameters
169 * Framerate numerator.
171 unsigned long fps_n;
173 * Framerate denominator.
175 unsigned long fps_d;
177 * Pixel format.
179 enum pixelformat dataformat;
181 * Picture width
183 unsigned width;
185 * Picture height
187 unsigned height;
189 * If TRUE, always use default stride (bytes-per-pixel * width)
191 bool default_stride;
193 * Picture stride in bytes.
195 size_t stride;
197 * Keyframe distance (1 => every frame is keyframe).
199 unsigned keyframe_distance;
201 * Deflate compression level (0-9)
203 unsigned deflate_level;
205 * Maximum number of frames per major segment.
207 unsigned long max_segment_frames;
211 * Create new dumper.
213 * Parameter prefix: Prefix for dumped files.
214 * Parameter global: Global dumper parameters.
215 * Parameter segment: Dumper segment parameters.
216 * Throws std::bad_alloc: Not enough memory.
217 * Throws std::runtime_error: Illegal parameters.
219 * Note: Segment parameters have to be sane, but altering those before dumping the first frame does not cause
220 * extraneous segment.
222 avi_cscd_dumper(const std::string& prefix, const global_parameters& global, const segment_parameters& segment)
223 throw(std::bad_alloc, std::runtime_error);
226 * Try to close the dump.
228 ~avi_cscd_dumper() throw();
231 * Get current segment parameters.
233 * Returns: The segment parameters
235 segment_parameters get_segment_parameters() throw();
238 * Set segment parameters.
240 * Parameter segment: New segment parameters.
241 * Throws std::bad_alloc: Not enough memory.
242 * Throws std::runtime_error: Illegal parameters.
244 * Note: If parameters change in incompatible manner, next dumped frame will cause segment change. The following
245 * changes are incompatible:
246 * - Changing the framerate.
247 * - Changing data format between 15 and 24/32 bit formats.
248 * - Changing with and height.
250 void set_segment_parameters(const segment_parameters& segment) throw(std::bad_alloc, std::runtime_error);
253 * Dump a frame.
255 * Parameter framedata: The frame data, in left-to-right, top-to-bottom order. Pixel format is as specified in
256 * segment parameters. If NULL, a black frame is dumped. Needs to be held stable until fully read in MT mode.
257 * Throws std::bad_alloc: Not enough memory.
258 * Throws std::runtime_error: Can't write frame.
260 void video(const void* framedata) throw(std::bad_alloc, std::runtime_error);
263 * Is there frame being processed?
265 bool is_frame_processing() throw();
268 * Wait until frame has processed.
270 void wait_frame_processing() throw();
273 * Dump audio.
275 * Parameter audio: Audio, first to last channel, first to last sample order.
276 * Parameter samples: Number of samples to add. Note: Number of samples, not number of channels*samples.
277 * Parameter format: Sound sample format.
278 * Throws std::bad_alloc: Not enough memory.
279 * Throws std::runtime_error: Can't write sound data.
281 void audio(const void* audio, size_t samples, enum soundformat format) throw(std::bad_alloc,
282 std::runtime_error);
285 * Dump audio (stereo).
287 * Parameter laudio: Audio for left channel.
288 * Parameter raudio: Audio for right channel.
289 * Parameter samples: Number of samples to add.
290 * Parameter format: Sound sample format.
291 * Throws std::bad_alloc: Not enough memory.
292 * Throws std::runtime_error: Can't write sound data or not stereo sound.
294 void audio(const void* laudio, const void* raudio, size_t samples, enum soundformat format)
295 throw(std::bad_alloc, std::runtime_error);
298 * Signal end of dump.
300 * Throws std::bad_alloc: Not enough memory.
301 * Throws std::runtime_error: Can't flush the last segment.
303 void end() throw(std::bad_alloc, std::runtime_error);
305 int encode_thread();
306 void set_capture_error(const std::string& err);
307 private:
308 //Information about buffered frame.
309 struct buffered_frame
311 std::vector<unsigned char> data;
312 bool keyframe;
313 unsigned compression_level;
314 unsigned mode; //1 => 15 bit, 2 => 24 bit, 3 => 32 bit.
315 bool forcebreak;
316 unsigned long fps_n;
317 unsigned long fps_d;
318 unsigned width;
319 unsigned height;
322 //Global parameters.
323 std::string dump_prefix;
324 unsigned long gp_sampling_rate;
325 unsigned gp_channel_count;
326 bool gp_audio_16bit;
327 //Current segment parameters.
328 unsigned long sp_fps_n;
329 unsigned long sp_fps_d;
330 enum pixelformat sp_dataformat;
331 unsigned sp_width;
332 unsigned sp_height;
333 size_t sp_stride;
334 unsigned sp_keyframe_distance;
335 unsigned sp_deflate_level;
336 unsigned long sp_max_segment_frames;
337 //Next segment parameters (some parameters can switch immediately).
338 bool switch_segments_on_next_frame;
339 unsigned spn_fps_n;
340 unsigned spn_fps_d;
341 enum pixelformat spn_dataformat;
342 unsigned spn_width;
343 unsigned spn_height;
345 //Current segment.
346 unsigned current_major_segment;
347 unsigned next_minor_segment;
348 unsigned long current_major_segment_frames;
349 unsigned frames_since_last_keyframe;
350 unsigned long frame_period_counter;
351 std::vector<unsigned char> previous_frame;
352 std::vector<unsigned char> compression_input;
353 std::vector<unsigned char> compression_output;
354 avi_file_structure* avifile_structure;
355 std::ofstream avifile;
357 //Sound&frame buffer.
358 std::vector<unsigned short> sound_buffer;
359 size_t buffered_sound_samples;
360 std::list<buffered_frame> frame_buffer;
362 //Fills compression_output with frame/sound packet and returns the total size.
363 size_t emit_frame(const std::vector<unsigned char>& data, bool keyframe, unsigned level, unsigned mode);
364 size_t emit_sound(size_t samples);
365 //Write a frame/sound packet in compression_output into stream.
366 void emit_frame_stream(size_t size, bool keyframe);
367 void emit_sound_stream(size_t size, size_t samples);
368 //Read next frame from queue with associated sound of given length. Also handles splits.
369 void write_frame_av(size_t samples);
371 size_t samples_for_next_frame();
372 bool restart_segment_if_needed(bool force_break);
373 void flush_buffers(bool forced);
374 void start_segment(unsigned major_seg, unsigned minor_seg);
375 void end_segment();
377 void request_flush_buffers(bool forced);
378 void _video(const void* framedata);
380 //Multithreading stuff.
381 thread_class* frame_thread;
382 cv_class frame_cond;
383 mutex_class frame_mutex;
384 volatile bool quit_requested;
385 volatile bool flush_requested;
386 volatile bool flush_requested_forced;
387 volatile bool frame_processing;
388 volatile const void* frame_pointer;
389 volatile bool exception_error_present;
390 std::string exception_error;
393 #endif