1 #ifndef _output_cscd__hpp__included__
2 #define _output_cscd__hpp__included__
5 #define REALLY_USE_THREADS 1
9 #define REALLY_USE_THREADS 1
13 #ifdef REALLY_USE_THREADS
15 #include <condition_variable>
21 typedef std::thread thread_class
;
24 * Class of condition variables.
26 typedef std::condition_variable cv_class
;
31 typedef std::mutex mutex_class
;
34 * Class of unique mutexes (for condition variable waiting).
36 typedef std::unique_lock
<std::mutex
> umutex_class
;
48 template<typename T
, typename args
>
49 thread_class(T obj
, args a
) {}
59 typedef struct mutex_class
72 * Class of condition variables.
79 void wait(umutex_class
& m
) {}
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
;
95 #error "Please define 64bit types."
104 struct avi_file_structure
;
107 * Dump AVI using CSCD for video and PCM for audio.
109 class avi_cscd_dumper
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
;
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. */
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.
173 * Framerate denominator.
179 enum pixelformat dataformat
;
189 * If TRUE, always use default stride (bytes-per-pixel * width)
193 * Picture stride in bytes.
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
;
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
);
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();
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
,
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
);
306 void set_capture_error(const std::string
& err
);
308 //Information about buffered frame.
309 struct buffered_frame
311 std::vector
<unsigned char> data
;
313 unsigned compression_level
;
314 unsigned mode
; //1 => 15 bit, 2 => 24 bit, 3 => 32 bit.
323 std::string dump_prefix
;
324 unsigned long gp_sampling_rate
;
325 unsigned gp_channel_count
;
327 //Current segment parameters.
328 unsigned long sp_fps_n
;
329 unsigned long sp_fps_d
;
330 enum pixelformat sp_dataformat
;
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
;
341 enum pixelformat spn_dataformat
;
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
);
377 void request_flush_buffers(bool forced
);
378 void _video(const void* framedata
);
380 //Multithreading stuff.
381 thread_class
* frame_thread
;
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
;