lsnes rr1-Δ5ε1
[lsnes.git] / avi / cscd.hpp
blob1c1cc2ee63896b913b5c6c43718401f536f669b9
1 #ifndef _output_cscd__hpp__included__
2 #define _output_cscd__hpp__included__
4 #if defined(__linux__) && !defined(BOOST_THREADS) && !defined(NO_THREADS)
5 #define STD_THREADS 1
6 #endif
10 #ifdef BOOST_THREADS
11 #include <boost/thread.hpp>
12 #include <boost/thread/locks.hpp>
14 #define ACTUALLY_USE_THREADS
15 typedef boost::thread thread_class;
16 typedef boost::condition_variable cv_class;
17 typedef boost::mutex mutex_class;
18 typedef boost::unique_lock<boost::mutex> umutex_class;
20 #else
21 #ifdef STD_THREADS
22 #include <thread>
23 #include <condition_variable>
24 #include <mutex>
26 #define ACTUALLY_USE_THREADS
27 typedef std::thread thread_class;
28 typedef std::condition_variable cv_class;
29 typedef std::mutex mutex_class;
30 typedef std::unique_lock<std::mutex> umutex_class;
32 #else
34 struct thread_class
36 template<typename T, typename args>
37 thread_class(T obj, args a) {}
38 void join() {}
41 typedef struct mutex_class
43 void lock() {}
44 void unlock() {}
45 } umutex_class;
47 struct cv_class
49 void wait(umutex_class& m) {}
50 void notify_all() {}
53 #endif
54 #endif
56 #ifdef __GNUC__
57 typedef unsigned long long Uint64;
58 typedef unsigned long long Sint64;
59 #elif defined(_MSC_VER)
60 typedef unsigned __int64 Uint64;
61 typedef signed __int64 Sint64;
62 #else
63 #error "Please define 64bit types."
64 #endif
66 #include <stdexcept>
67 #include <cstdlib>
68 #include <vector>
69 #include <fstream>
70 #include <list>
72 struct avi_file_structure;
74 /**
75 * Dump AVI using CSCD for video and PCM for audio.
77 class avi_cscd_dumper
79 public:
80 /**
81 * AVI dumper parameters.
83 struct global_parameters
85 /**
86 * Sound sampling rate.
88 unsigned long sampling_rate;
89 /**
90 * Sound channel count.
92 unsigned channel_count;
93 /**
94 * 16-bit audio flag.
96 bool audio_16bit;
99 /**
100 * Pixel formats
102 enum pixelformat
104 PIXFMT_RGB15_LE, /* Little-endian 15-bit RGB. */
105 PIXFMT_RGB15_BE, /* Big-endian 15-bit RGB. */
106 PIXFMT_RGB15_NE, /* Native-endian 15-bit RGB. */
107 PIXFMT_RGB24, /* 24-bit RGB, RGB order. */
108 PIXFMT_BGR24, /* 24-bit RGB, BGR order. */
109 PIXFMT_RGBX, /* 32-bit RGB, RGBx order. */
110 PIXFMT_BGRX, /* 32-bit RGB, BGRx order. */
111 PIXFMT_XRGB, /* 32-bit RGB, BGRx order. */
112 PIXFMT_XBGR /* 32-bit RGB, xBGR order. */
116 * Sound formats.
118 enum soundformat
120 SNDFMT_SILENCE, /* No data, silence. */
121 SNDFMT_SIGNED_8, /* 8-bit signed. */
122 SNDFMT_UNSIGNED_8, /* 8-bit unsigned. */
123 SNDFMT_SIGNED_16LE, /* 16-bit signed little-endian. */
124 SNDFMT_UNSIGNED_16LE, /* 16-bit unsigned little-endian. */
125 SNDFMT_SIGNED_16BE, /* 16-bit signed big-endian. */
126 SNDFMT_UNSIGNED_16BE, /* 16-bit unsigned big-endian. */
127 SNDFMT_SIGNED_16NE, /* 16-bit signed native-endian. */
128 SNDFMT_UNSIGNED_16NE /* 16-bit unsigned native-endian. */
132 * AVI per-segment parameters
134 struct segment_parameters
137 * Framerate numerator.
139 unsigned long fps_n;
141 * Framerate denominator.
143 unsigned long fps_d;
145 * Pixel format.
147 enum pixelformat dataformat;
149 * Picture width
151 unsigned width;
153 * Picture height
155 unsigned height;
157 * If TRUE, always use default stride (bytes-per-pixel * width)
159 bool default_stride;
161 * Picture stride in bytes.
163 size_t stride;
165 * Keyframe distance (1 => every frame is keyframe).
167 unsigned keyframe_distance;
169 * Deflate compression level (0-9)
171 unsigned deflate_level;
173 * Maximum number of frames per major segment.
175 unsigned long max_segment_frames;
179 * Create new dumper.
181 * Parameter prefix: Prefix for dumped files.
182 * Parameter global: Global dumper parameters.
183 * Parameter segment: Dumper segment parameters.
184 * Throws std::bad_alloc: Not enough memory.
185 * Throws std::runtime_error: Illegal parameters.
187 * Note: Segment parameters have to be sane, but altering those before dumping the first frame does not cause
188 * extraneous segment.
190 avi_cscd_dumper(const std::string& prefix, const global_parameters& global, const segment_parameters& segment)
191 throw(std::bad_alloc, std::runtime_error);
194 * Try to close the dump.
196 ~avi_cscd_dumper() throw();
199 * Get current segment parameters.
201 * Returns: The segment parameters
203 segment_parameters get_segment_parameters() throw();
206 * Set segment parameters.
208 * Parameter segment: New segment parameters.
209 * Throws std::bad_alloc: Not enough memory.
210 * Throws std::runtime_error: Illegal parameters.
212 * Note: If parameters change in incompatible manner, next dumped frame will cause segment change. The following
213 * changes are incompatible:
214 * - Changing the framerate.
215 * - Changing data format between 15 and 24/32 bit formats.
216 * - Changing with and height.
218 void set_segment_parameters(const segment_parameters& segment) throw(std::bad_alloc, std::runtime_error);
221 * Dump a frame.
223 * Parameter framedata: The frame data, in left-to-right, top-to-bottom order. Pixel format is as specified in
224 * segment parameters. If NULL, a black frame is dumped. Needs to be held stable until fully read in MT mode.
225 * Throws std::bad_alloc: Not enough memory.
226 * Throws std::runtime_error: Can't write frame.
228 void video(const void* framedata) throw(std::bad_alloc, std::runtime_error);
231 * Is there frame being processed?
233 bool is_frame_processing() throw();
236 * Wait until frame has processed.
238 void wait_frame_processing() throw();
241 * Dump audio.
243 * Parameter audio: Audio, first to last channel, first to last sample order.
244 * Parameter samples: Number of samples to add. Note: Number of samples, not number of channels*samples.
245 * Parameter format: Sound sample format.
246 * Throws std::bad_alloc: Not enough memory.
247 * Throws std::runtime_error: Can't write sound data.
249 void audio(const void* audio, size_t samples, enum soundformat format) throw(std::bad_alloc,
250 std::runtime_error);
253 * Dump audio (stereo).
255 * Parameter laudio: Audio for left channel.
256 * Parameter raudio: Audio for right channel.
257 * Parameter samples: Number of samples to add.
258 * Parameter format: Sound sample format.
259 * Throws std::bad_alloc: Not enough memory.
260 * Throws std::runtime_error: Can't write sound data or not stereo sound.
262 void audio(const void* laudio, const void* raudio, size_t samples, enum soundformat format)
263 throw(std::bad_alloc, std::runtime_error);
266 * Signal end of dump.
268 * Throws std::bad_alloc: Not enough memory.
269 * Throws std::runtime_error: Can't flush the last segment.
271 void end() throw(std::bad_alloc, std::runtime_error);
273 int encode_thread();
274 void set_capture_error(const std::string& err);
275 private:
276 //Information about buffered frame.
277 struct buffered_frame
279 std::vector<unsigned char> data;
280 bool keyframe;
281 unsigned compression_level;
282 unsigned mode; //1 => 15 bit, 2 => 24 bit, 3 => 32 bit.
283 bool forcebreak;
284 unsigned long fps_n;
285 unsigned long fps_d;
286 unsigned width;
287 unsigned height;
290 //Global parameters.
291 std::string dump_prefix;
292 unsigned long gp_sampling_rate;
293 unsigned gp_channel_count;
294 bool gp_audio_16bit;
295 //Current segment parameters.
296 unsigned long sp_fps_n;
297 unsigned long sp_fps_d;
298 enum pixelformat sp_dataformat;
299 unsigned sp_width;
300 unsigned sp_height;
301 size_t sp_stride;
302 unsigned sp_keyframe_distance;
303 unsigned sp_deflate_level;
304 unsigned long sp_max_segment_frames;
305 //Next segment parameters (some parameters can switch immediately).
306 bool switch_segments_on_next_frame;
307 unsigned spn_fps_n;
308 unsigned spn_fps_d;
309 enum pixelformat spn_dataformat;
310 unsigned spn_width;
311 unsigned spn_height;
313 //Current segment.
314 unsigned current_major_segment;
315 unsigned next_minor_segment;
316 unsigned long current_major_segment_frames;
317 unsigned frames_since_last_keyframe;
318 unsigned long frame_period_counter;
319 std::vector<unsigned char> previous_frame;
320 std::vector<unsigned char> compression_input;
321 std::vector<unsigned char> compression_output;
322 avi_file_structure* avifile_structure;
323 std::ofstream avifile;
325 //Sound&frame buffer.
326 std::vector<unsigned short> sound_buffer;
327 size_t buffered_sound_samples;
328 std::list<buffered_frame> frame_buffer;
330 //Fills compression_output with frame/sound packet and returns the total size.
331 size_t emit_frame(const std::vector<unsigned char>& data, bool keyframe, unsigned level, unsigned mode);
332 size_t emit_sound(size_t samples);
333 //Write a frame/sound packet in compression_output into stream.
334 void emit_frame_stream(size_t size, bool keyframe);
335 void emit_sound_stream(size_t size, size_t samples);
336 //Read next frame from queue with associated sound of given length. Also handles splits.
337 void write_frame_av(size_t samples);
339 size_t samples_for_next_frame();
340 bool restart_segment_if_needed(bool force_break);
341 void flush_buffers(bool forced);
342 void start_segment(unsigned major_seg, unsigned minor_seg);
343 void end_segment();
345 void request_flush_buffers(bool forced);
346 void _video(const void* framedata);
348 //Multithreading stuff.
349 thread_class* frame_thread;
350 cv_class frame_cond;
351 mutex_class frame_mutex;
352 volatile bool quit_requested;
353 volatile bool flush_requested;
354 volatile bool flush_requested_forced;
355 volatile bool frame_processing;
356 volatile const void* frame_pointer;
357 volatile bool exception_error_present;
358 std::string exception_error;
361 #endif