1 #ifndef _output_cscd__hpp__included__
2 #define _output_cscd__hpp__included__
4 #if defined(__linux__) && !defined(BOOST_THREADS) && !defined(NO_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
;
23 #include <condition_variable>
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
;
36 template<typename T
, typename args
>
37 thread_class(T obj
, args a
) {}
41 typedef struct mutex_class
49 void wait(umutex_class
& m
) {}
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
;
63 #error "Please define 64bit types."
72 struct avi_file_structure
;
75 * Dump AVI using CSCD for video and PCM for audio.
81 * AVI dumper parameters.
83 struct global_parameters
86 * Sound sampling rate.
88 unsigned long sampling_rate
;
90 * Sound channel count.
92 unsigned channel_count
;
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. */
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.
141 * Framerate denominator.
147 enum pixelformat dataformat
;
157 * If TRUE, always use default stride (bytes-per-pixel * width)
161 * Picture stride in bytes.
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
;
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
);
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();
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
,
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
);
274 void set_capture_error(const std::string
& err
);
276 //Information about buffered frame.
277 struct buffered_frame
279 std::vector
<unsigned char> data
;
281 unsigned compression_level
;
282 unsigned mode
; //1 => 15 bit, 2 => 24 bit, 3 => 32 bit.
291 std::string dump_prefix
;
292 unsigned long gp_sampling_rate
;
293 unsigned gp_channel_count
;
295 //Current segment parameters.
296 unsigned long sp_fps_n
;
297 unsigned long sp_fps_d
;
298 enum pixelformat sp_dataformat
;
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
;
309 enum pixelformat spn_dataformat
;
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
);
345 void request_flush_buffers(bool forced
);
346 void _video(const void* framedata
);
348 //Multithreading stuff.
349 thread_class
* frame_thread
;
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
;