2 #include "audiodevice.h"
6 #include "edlsession.h"
10 #include "recordaudio.h"
11 #include "recordgui.h"
12 #include "recordthread.h"
13 #include "recordvideo.h"
15 #include "videodevice.h"
18 RecordThread::RecordThread(MWindow *mwindow, Record *record)
21 this->mwindow = mwindow;
22 this->record = record;
23 quit_when_completed = 0;
24 record_timer = new Timer;
29 RecordThread::~RecordThread()
34 int RecordThread::create_objects()
36 if(record->default_asset->audio_data)
37 record_audio = new RecordAudio(mwindow,
41 if(record->default_asset->video_data)
42 record_video = new RecordVideo(mwindow,
49 int RecordThread::start_recording(int monitor, int context)
51 //printf("RecordThread::start_recording 1\n");
53 this->monitor = monitor;
54 this->context = context;
55 resume_monitor = !monitor;
59 completion_lock.lock();
65 startup_lock.unlock();
66 //printf("RecordThread::start_recording 10\n");
70 int RecordThread::stop_recording(int resume_monitor)
72 // Stop RecordThread while waiting for batch
76 this->resume_monitor = resume_monitor;
77 // In the monitor engine, stops the engine.
78 // In the recording engine, causes the monitor engine not to be restarted.
79 // Video thread stops the audio thread itself
80 // printf("RecordThread::stop_recording 1\n");
83 record_video->batch_done = 1;
85 record_video->stop_recording();
88 if(record_audio && context != CONTEXT_SINGLEFRAME)
90 //printf("RecordThread::stop_recording 3\n");
91 record_audio->batch_done = 1;
93 //printf("RecordThread::stop_recording 4\n");
94 record_audio->stop_recording();
95 //printf("RecordThread::stop_recording 5\n");
99 //printf("RecordThread::stop_recording 6\n");
100 completion_lock.lock();
101 completion_lock.unlock();
102 //printf("RecordThread::stop_recording 100\n");
106 int RecordThread::pause_recording()
108 // Stop the thread before finishing the loop
109 //printf("RecordThread::pause_recording 1\n");
111 //printf("RecordThread::pause_recording 1\n");
114 if(record->default_asset->video_data)
116 record_video->batch_done = 1;
120 record_audio->batch_done = 1;
123 //printf("RecordThread::pause_recording 1\n");
124 // Stop the recordings
125 if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
126 record_audio->stop_recording();
127 if(record->default_asset->video_data)
128 record_video->stop_recording();
129 //printf("RecordThread::pause_recording 1\n");
131 // Wait for thread to stop before closing devices
134 //printf("RecordThread::pause_recording 1\n");
138 record->close_input_devices();
139 //printf("RecordThread::pause_recording 2\n");
140 record->capture_state = IS_DONE;
144 int RecordThread::resume_recording()
146 //printf("RecordThread::resume_recording 1\n");
149 record_video->batch_done = 0;
153 record_audio->batch_done = 0;
157 //printf("RecordThread::resume_recording 2\n");
161 int64_t RecordThread::sync_position()
163 if(record->default_asset->audio_data)
164 return record_audio->sync_position();
166 return (int64_t)((float)record_timer->get_difference() /
168 record->default_asset->sample_rate + 0.5);
171 void RecordThread::do_cron()
174 double position = record->current_display_position();
179 // Batch already started
185 // Delay until start of batch
187 record->get_current_time(seconds, day);
190 if(record->get_current_batch()->start_day == 7)
191 day = record->get_current_batch()->start_day;
193 if(record->get_current_batch()->start_day == day &&
194 record->get_current_batch()->start_time >= last_seconds &&
195 record->get_current_batch()->start_time <= seconds)
200 // record->record_gui->lock_window();
201 // record->record_gui->flash_batch();
202 // record->record_gui->unlock_window();
205 last_seconds = seconds;
207 if(!engine_done) usleep(BATCH_DELAY);
210 record->record_gui->lock_window();
211 record->record_gui->flash_batch();
212 record->record_gui->unlock_window();
214 }while(!engine_done);
219 void RecordThread::run()
221 int rewinding_loop = 0;
222 startup_lock.unlock();
223 record->get_current_time(last_seconds, last_day);
228 // Prepare next batch
229 if(context == CONTEXT_BATCH &&
236 // Test for stopped while waiting
241 //printf("RecordThread::run 6\n");
243 // Batch context needs to open the device here. Interactive and singleframe
244 // contexts need to open in Record::start_recording to allow full duplex.
245 if(context == CONTEXT_BATCH)
247 // Delete output file before opening the devices to avoid buffer overflow.
248 record->delete_output_file();
249 record->open_input_devices(0, context);
251 //printf("RecordThread::run 7 %d\n", monitor);
253 // Switch interactive recording to batch recording
254 // to get delay before next batch
255 if(!monitor && context == CONTEXT_INTERACTIVE)
256 context = CONTEXT_BATCH;
260 // This draws to RecordGUI, incidentally
261 record->open_output_file();
262 if(mwindow->edl->session->record_sync_drives)
264 drivesync = new DriveSync;
270 record->get_current_batch()->recorded = 1;
272 // Open file threads here to keep loop synchronized
273 if(record->default_asset->audio_data &&
274 context != CONTEXT_SINGLEFRAME)
276 int64_t buffer_size, fragment_size;
277 record->get_audio_write_length(buffer_size, fragment_size);
278 record->file->start_audio_thread(buffer_size, RING_BUFFERS);
281 if(record->default_asset->video_data)
282 record->file->start_video_thread(mwindow->edl->session->video_write_length,
283 record->vdevice->get_best_colormodel(record->default_asset),
285 record->vdevice->is_compressed());
287 //printf("RecordThread::run 8\n");
289 // Reset synchronization counters
290 record->get_current_batch()->session_samples = 0;
291 record->get_current_batch()->session_frames = 0;
292 record_timer->update();
295 if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
296 record_audio->arm_recording();
297 if(record->default_asset->video_data)
298 record_video->arm_recording();
299 //printf("RecordThread::run 9\n");
304 if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
305 record_audio->start_recording();
306 if(record->default_asset->video_data)
307 record_video->start_recording();
309 //printf("RecordThread::run 10\n");
311 if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
312 record_audio->join();
313 //printf("RecordThread::run 10\n");
314 if(record->default_asset->video_data)
315 record_video->join();
316 //printf("RecordThread::run 11\n");
318 // Stop file threads here to keep loop synchronized
321 if(drivesync) drivesync->done = 1;
322 if(record->default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
323 record->file->stop_audio_thread();
324 if(record->default_asset->video_data)
325 record->file->stop_video_thread();
328 record->get_current_batch()->get_current_asset()->audio_length =
329 record->get_current_batch()->total_samples;
330 record->get_current_batch()->get_current_asset()->video_length =
331 record->get_current_batch()->total_frames;
333 // Reset the loop flag and rewind files for the next loop
336 // Rewind loop if in loop mode
337 if(record->get_current_batch()->record_mode == RECORD_LOOP)
339 // Don't close devices when rewinding a loop
340 record->rewind_file();
341 record->get_current_batch()->session_samples = 0;
342 record->get_current_batch()->session_frames = 0;
346 // Advance batch if not terminated by user and not single frame and continue loop
347 if(record->get_next_batch() >= 0 && context != CONTEXT_SINGLEFRAME)
349 record->activate_batch(record->get_next_batch(), 0);
350 record->close_input_devices();
359 if(drivesync) delete drivesync;
361 //printf("RecordThread::run 12\n");
368 // Wait for thread to stop before closing devices
372 // Pause until monitor is resumed
376 }while(!engine_done);
378 //printf("RecordThread::run 13\n");
379 record->close_input_devices();
381 // Resume monitoring only if not a monitor ourselves
384 record->stop_duplex();
385 if(resume_monitor) record->resume_monitor();
389 record->capture_state = IS_DONE;
391 completion_lock.unlock();