5 #include "edlsession.h"
8 #include "filethread.h"
10 #include "mwindowgui.h"
11 #include "preferences.h"
12 #include "quicktime.h"
14 #include "recordaudio.h"
15 #include "recordgui.h"
16 #include "recordthread.h"
17 #include "recordvideo.h"
18 #include "recordmonitor.h"
21 #include "videodevice.h"
26 #define _(String) gettext(String)
27 #define gettext_noop(String) String
28 #define N_(String) gettext_noop (String)
30 RecordVideo::RecordVideo(MWindow *mwindow,
32 RecordThread *record_thread)
36 this->mwindow = mwindow;
37 this->record = record;
38 this->record_thread = record_thread;
39 this->gui = record->record_gui;
42 RecordVideo::~RecordVideo()
46 void RecordVideo::reset_parameters()
50 total_dropped_frames = 0;
52 last_dropped_frames = 0;
58 int RecordVideo::arm_recording()
61 // Resume next file in a series by incrementing existing counters
62 if(record_thread->monitor)
65 buffer_size = mwindow->edl->session->video_write_length;
74 void RecordVideo::start_recording()
76 trigger_lock.unlock();
79 int RecordVideo::stop_recording()
81 // Device won't exist if interrupting a cron job
84 //printf("RecordVideo::stop_recording 1 %p\n", record->vdevice);
85 // Interrupt IEEE1394 crashes
86 record->vdevice->interrupt_crash();
87 //printf("RecordVideo::stop_recording 1\n");
89 // Interrupt video4linux crashes
90 if(record->vdevice->get_failed())
92 //printf("RecordVideo::stop_recording 2\n");
95 //printf("RecordVideo::stop_recording 3\n");
98 //printf("RecordVideo::stop_recording 4\n");
101 //printf("RecordVideo::stop_recording 5\n");
106 int RecordVideo::cleanup_recording()
108 if(!record_thread->monitor)
110 //printf("RecordVideo::cleanup_recording 1\n");
114 //printf("RecordVideo::cleanup_recording 2\n");
118 delete [] frame_ptr[0];
120 delete capture_frame;
125 void RecordVideo::get_capture_frame()
127 if(record->fixed_compression)
129 capture_frame = new VFrame;
133 capture_frame = new VFrame(0,
134 record->default_asset->width,
135 record->default_asset->height,
136 record->vdevice->get_best_colormodel(record->default_asset));
137 //printf("RecordVideo::get_capture_frame %d %d\n", capture_frame->get_w(), capture_frame->get_h());
139 frame_ptr = new VFrame**[1];
140 frame_ptr[0] = new VFrame*[1];
141 frame_ptr[0][0] = capture_frame;
145 void RecordVideo::run()
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 //printf("RecordVideo::run 4\n");
223 capture_frame = frame_ptr[0][buffer_position];
224 //printf("RecordVideo::run 5 %d\n", capture_frame->get_color_model());
225 record->vdevice->set_field_order(record->reverse_interlace);
226 //printf("RecordVideo::run 6\n");
228 //printf("RecordVideo::run 7\n");
229 record->get_current_batch()->current_frame++;
230 record->get_current_batch()->total_frames =
231 MAX(record->get_current_batch()->current_frame, record->get_current_batch()->total_frames);
232 record->get_current_batch()->session_frames++;
233 //printf("RecordVideo::run 4\n");
234 if(!grab_result) buffer_position++;
235 //printf("RecordVideo::run 5 %ld\n", record_thread->session_frames);
237 // Update the position indicator
238 gui->update_position(record->current_display_position(),
239 record->current_display_length());
242 // Grab frame for monitoring
243 if(record->monitor_video)
245 record->vdevice->set_field_order(record->reverse_interlace);
246 record->get_current_batch()->session_frames++;
248 //printf("RecordVideo::run 4\n");
250 //printf("RecordVideo::run 5\n");
253 // Brief pause to keep CPU from burning up
260 //printf("RecordVideo::run 10\n");
261 // Monitor the frame if monitoring
262 if(capture_frame->get_data() &&
263 record->monitor_video &&
266 record->record_monitor->update(capture_frame);
267 // printf("RecordVideo::run 11 %d %d %d %d\n", record_thread->monitor,
268 // record->fill_frames,
272 // Duplicate a frame if behind
273 if(!record_thread->monitor &&
274 record->fill_frames &&
278 VFrame *last_frame = capture_frame;
280 if(buffer_position >= buffer_size) write_buffer(0);
282 capture_frame = frame_ptr[0][buffer_position];
283 capture_frame->copy_from(last_frame);
284 record->get_current_batch()->current_frame++;
285 record->get_current_batch()->total_frames =
286 MAX(record->get_current_batch()->current_frame, record->get_current_batch()->total_frames);
287 record->get_current_batch()->session_frames++;
291 // Compress a batch of frames or write the second frame if filling
292 if(!record_thread->monitor && buffer_position >= buffer_size)
296 //printf("RecordVideo::run 12\n");
297 //printf("RecordVideo::run 12 %d %f %f\n", record->get_current_batch()->record_mode, record->current_display_position(), *record->current_duration());
299 if(!record_thread->monitor &&
303 // Handle recording contexts
304 if(record_thread->context == CONTEXT_SINGLEFRAME)
309 // Handle recording modes delegated to the thread
310 switch(record->get_current_batch()->record_mode)
313 if(record->current_display_position() > *record->current_duration())
317 if(record->current_display_position() > *record->current_duration())
320 case RECORD_SCENETOSCENE:
324 //printf("RecordVideo::run 13 %d\n", write_result);
331 //printf("RecordVideo::run 14 %d\n", write_result);
333 // Update dependant threads
334 if(record->default_asset->audio_data)
336 record_thread->record_audio->batch_done = 1;
337 // Interrupt driver for IEEE1394
338 record_thread->record_audio->stop_recording();
340 //printf("RecordVideo::run 15 %d\n", write_result);
344 if(!record_thread->monitor)
346 ErrorBox error_box(PROGRAM_NAME ": Error",
347 mwindow->gui->get_abs_cursor_x(),
348 mwindow->gui->get_abs_cursor_y());
349 error_box.create_objects(_("No space left on disk."));
350 error_box.run_window();
356 //printf("RecordVideo::run 16 %p %d\n", this, write_result);
359 void RecordVideo::read_buffer()
361 //printf("RecordVideo::read_buffer 1\n");
363 grab_result = record->vdevice->read_buffer(capture_frame);
365 //printf("RecordVideo::read_buffer 10\n");
367 if(!strncmp(record->default_asset->vcodec, QUICKTIME_MJPA, 4) &&
368 record->vdevice->is_compressed())
370 unsigned char *data = capture_frame->get_data();
371 int64_t size = capture_frame->get_compressed_size();
372 int64_t allocation = capture_frame->get_compressed_allocated();
374 //printf("RecordVideo::read_buffer 20 %d\n", size);
377 int64_t field2_offset = mjpeg_get_field2(data, size);
378 // Markers are added in the file in direct copy more.
379 // mjpeg_insert_quicktime_markers(&data,
384 capture_frame->set_compressed_size(size);
385 capture_frame->set_field2_offset(field2_offset);
387 //printf("RecordVideo::read_buffer 30\n");
389 //printf("RecordVideo::read_buffer 100\n");
392 void RecordVideo::write_buffer(int skip_new)
394 write_result = record->file->write_video_buffer(buffer_position);
396 if(!skip_new && !write_result)
397 frame_ptr = record->file->get_video_buffer();
400 void RecordVideo::rewind_file()
403 record->file->stop_video_thread();
404 record->file->set_video_position(0, record->default_asset->frame_rate);
405 record->file->start_video_thread(buffer_size,
406 record->vdevice->get_best_colormodel(record->default_asset),
408 record->vdevice->is_compressed());
409 frame_ptr = record->file->get_video_buffer();
410 record->get_current_batch()->current_frame = 0;
411 record->get_current_batch()->current_sample = 0;
412 record->get_current_batch()->session_frames = 0;
413 record->get_current_batch()->session_samples = 0;
414 gui->update_position(0, record->current_display_length());
417 int RecordVideo::unhang_thread()
419 printf("RecordVideo::unhang_thread\n");