6 #include "edlsession.h"
9 #include "filethread.h"
12 #include "mwindowgui.h"
13 #include "preferences.h"
14 #include "quicktime.h"
16 #include "recordaudio.h"
17 #include "recordgui.h"
18 #include "recordthread.h"
19 #include "recordvideo.h"
20 #include "recordmonitor.h"
23 #include "videodevice.h"
28 RecordVideo::RecordVideo(MWindow *mwindow,
30 RecordThread *record_thread)
34 this->mwindow = mwindow;
35 this->record = record;
36 this->record_thread = record_thread;
37 this->gui = record->record_gui;
40 RecordVideo::~RecordVideo()
44 void RecordVideo::reset_parameters()
48 total_dropped_frames = 0;
50 last_dropped_frames = 0;
56 int RecordVideo::arm_recording()
59 // Resume next file in a series by incrementing existing counters
60 if(record_thread->monitor)
63 buffer_size = mwindow->edl->session->video_write_length;
72 void RecordVideo::start_recording()
74 trigger_lock.unlock();
77 int RecordVideo::stop_recording()
79 // Device won't exist if interrupting a cron job
82 //printf("RecordVideo::stop_recording 1 %p\n", record->vdevice);
83 // Interrupt IEEE1394 crashes
84 record->vdevice->interrupt_crash();
85 //printf("RecordVideo::stop_recording 1\n");
87 // Interrupt video4linux crashes
88 if(record->vdevice->get_failed())
90 //printf("RecordVideo::stop_recording 2\n");
93 //printf("RecordVideo::stop_recording 3\n");
96 //printf("RecordVideo::stop_recording 4\n");
99 //printf("RecordVideo::stop_recording 5\n");
104 int RecordVideo::cleanup_recording()
106 if(!record_thread->monitor)
108 //printf("RecordVideo::cleanup_recording 1\n");
112 //printf("RecordVideo::cleanup_recording 2\n");
116 delete [] frame_ptr[0];
118 delete capture_frame;
123 void RecordVideo::get_capture_frame()
125 if(record->fixed_compression)
127 capture_frame = new VFrame;
131 capture_frame = new VFrame(0,
132 record->default_asset->width,
133 record->default_asset->height,
134 record->vdevice->get_best_colormodel(record->default_asset));
135 //printf("RecordVideo::get_capture_frame %d %d\n", capture_frame->get_w(), capture_frame->get_h());
137 frame_ptr = new VFrame**[1];
138 frame_ptr[0] = new VFrame*[1];
139 frame_ptr[0][0] = capture_frame;
143 void RecordVideo::run()
148 //printf("RecordVideo::run 1 %d\n", getpid());
150 // Thread out the I/O
151 if(!record_thread->monitor)
153 record_start = record->file->get_video_position(record->default_asset->frame_rate);
154 frame_ptr = record->file->get_video_buffer();
161 // Number of frames for user to know about.
162 gui->total_dropped_frames = 0;
163 gui->update_dropped_frames(0);
168 trigger_lock.unlock();
170 //printf("RecordVideo::run 1 %d\n", record_thread->monitor);
175 // Synchronize with audio or timer
176 //printf("RecordVideo::run 1 %d\n", batch_done);
178 next_sample = (int64_t)((float)record->get_current_batch()->session_frames /
179 record->default_asset->frame_rate *
180 record->default_asset->sample_rate);
181 //printf("RecordVideo::run 1\n");
182 current_sample = record->sync_position();
184 //printf("RecordVideo::run 2\n");
187 if(current_sample < next_sample && current_sample > 0)
190 delay = (int64_t)((float)(next_sample - current_sample) /
191 record->default_asset->sample_rate *
195 // Sanity check and delay.
196 if(delay < 2000 && delay > 0) delayer.delay(delay);
197 gui->update_dropped_frames(0);
198 last_dropped_frames = 0;
201 if(current_sample > 0 && !record_thread->monitor)
204 dropped_frames = (int64_t)((float)(current_sample - next_sample) /
205 record->default_asset->sample_rate *
206 record->default_asset->frame_rate);
207 if(dropped_frames != last_dropped_frames)
209 gui->update_dropped_frames(dropped_frames);
210 last_dropped_frames = dropped_frames;
212 last_dropped_frames = dropped_frames;
215 //printf("RecordVideo::run 3\n");
219 // Grab frame for recording
220 if(!record_thread->monitor)
222 capture_frame = frame_ptr[0][buffer_position];
223 record->vdevice->set_field_order(record->reverse_interlace);
225 record->get_current_batch()->current_frame++;
226 record->get_current_batch()->total_frames =
227 MAX(record->get_current_batch()->current_frame, record->get_current_batch()->total_frames);
228 record->get_current_batch()->session_frames++;
229 if(!grab_result) buffer_position++;
231 // Update the position indicator
232 gui->update_position(record->current_display_position(),
233 record->current_display_length());
236 // Grab frame for monitoring
237 if(record->monitor_video)
239 record->vdevice->set_field_order(record->reverse_interlace);
240 record->get_current_batch()->session_frames++;
245 // Brief pause to keep CPU from burning up
252 // Monitor the frame if monitoring
253 if(capture_frame->get_data() &&
254 record->monitor_video &&
257 record->record_monitor->update(capture_frame);
259 // Duplicate a frame if behind
260 if(!record_thread->monitor &&
261 record->fill_frames &&
265 VFrame *last_frame = capture_frame;
267 if(buffer_position >= buffer_size) write_buffer(0);
269 capture_frame = frame_ptr[0][buffer_position];
270 capture_frame->copy_from(last_frame);
271 record->get_current_batch()->current_frame++;
272 record->get_current_batch()->total_frames =
273 MAX(record->get_current_batch()->current_frame, record->get_current_batch()->total_frames);
274 record->get_current_batch()->session_frames++;
278 // Compress a batch of frames or write the second frame if filling
279 if(!record_thread->monitor && buffer_position >= buffer_size)
284 if(!record_thread->monitor &&
288 // Handle recording contexts
289 if(record_thread->context == CONTEXT_SINGLEFRAME)
294 // Handle recording modes delegated to the thread
295 switch(record->get_current_batch()->record_mode)
298 if(record->current_display_position() > *record->current_duration())
302 if(record->current_display_position() > *record->current_duration())
305 case RECORD_SCENETOSCENE:
316 TRACE("RecordVideo::run 1");
317 // Update dependant threads
318 if(record->default_asset->audio_data)
320 record_thread->record_audio->batch_done = 1;
321 // Interrupt driver for IEEE1394
322 record_thread->record_audio->stop_recording();
324 TRACE("RecordVideo::run 2");
328 if(!record_thread->monitor)
330 ErrorBox error_box(PROGRAM_NAME ": Error",
331 mwindow->gui->get_abs_cursor_x(),
332 mwindow->gui->get_abs_cursor_y());
333 error_box.create_objects(_("No space left on disk."));
334 error_box.run_window();
342 void RecordVideo::read_buffer()
345 grab_result = record->vdevice->read_buffer(capture_frame);
348 if(!strncmp(record->default_asset->vcodec, QUICKTIME_MJPA, 4) &&
349 record->vdevice->is_compressed())
351 unsigned char *data = capture_frame->get_data();
352 int64_t size = capture_frame->get_compressed_size();
353 int64_t allocation = capture_frame->get_compressed_allocated();
357 int64_t field2_offset = mjpeg_get_field2(data, size);
358 capture_frame->set_compressed_size(size);
359 capture_frame->set_field2_offset(field2_offset);
364 void RecordVideo::write_buffer(int skip_new)
366 write_result = record->file->write_video_buffer(buffer_position);
368 if(!skip_new && !write_result)
369 frame_ptr = record->file->get_video_buffer();
372 void RecordVideo::rewind_file()
375 record->file->stop_video_thread();
376 record->file->set_video_position(0, record->default_asset->frame_rate);
377 record->file->start_video_thread(buffer_size,
378 record->vdevice->get_best_colormodel(record->default_asset),
380 record->vdevice->is_compressed());
381 frame_ptr = record->file->get_video_buffer();
382 record->get_current_batch()->current_frame = 0;
383 record->get_current_batch()->current_sample = 0;
384 record->get_current_batch()->session_frames = 0;
385 record->get_current_batch()->session_samples = 0;
386 gui->update_position(0, record->current_display_length());
389 int RecordVideo::unhang_thread()
391 printf("RecordVideo::unhang_thread\n");