4 #include "chantables.h"
7 #include "playbackconfig.h"
8 #include "playbackengine.h"
9 #include "preferences.h"
10 #include "quicktime.h"
11 #include "recordconfig.h"
12 #include "recordmonitor.h"
14 #include "vdevice1394.h"
16 #include "vdevicebuz.h"
17 #include "vdevicev4l.h"
18 #include "vdevicev4l2.h"
19 #include "vdevicev4l2jpeg.h"
20 #include "vdevicex11.h"
21 #include "videoconfig.h"
22 #include "videodevice.h"
23 #include "videowindow.h"
24 #include "videowindowgui.h"
30 KeepaliveThread::KeepaliveThread(VideoDevice *device)
37 this->device = device;
39 startup_lock = new Mutex("KeepaliveThread::startup_lock");
42 KeepaliveThread::~KeepaliveThread()
47 int KeepaliveThread::start_keepalive()
49 startup_lock->lock("KeepaliveThread::start_keepalive 1");
51 startup_lock->lock("KeepaliveThread::start_keepalive 2");
52 startup_lock->unlock();
55 void KeepaliveThread::run()
57 startup_lock->unlock();
61 // Give the capture a moment
62 // Should fix the delay in case users want slower frame rates.
63 timer.delay((long)(KEEPALIVE_DELAY * 1000));
65 // See if a capture happened
66 if(still_alive == 0 && capturing)
68 // printf("KeepaliveThread::run: device crashed\n");
76 int KeepaliveThread::reset_keepalive()
81 int KeepaliveThread::get_failed()
83 if(failed) return 1; else return 0;
86 int KeepaliveThread::stop()
90 // Force an immediate exit even if capture_frame worked.
101 VideoDevice::VideoDevice(MWindow *mwindow)
103 this->mwindow = mwindow;
104 in_config = new VideoInConfig;
105 out_config = new VideoOutConfig;
106 channel = new Channel;
107 picture = new PictureConfig(mwindow);
108 sharing_lock = new Mutex("VideoDevice::sharing_lock");
109 channel_lock = new Mutex("VideoDevice::channel_lock");
110 picture_lock = new Mutex("VideoDevice::picture_lock");
115 VideoDevice::~VideoDevice()
117 input_sources.remove_all_objects();
127 int VideoDevice::initialize()
131 sharing_lock->reset();
135 is_playing_back = is_recording = 0;
155 int VideoDevice::open_input(VideoInConfig *config,
163 *this->in_config = *config;
166 this->input_z = -1; // Force initialization.
167 this->frame_rate = frame_rate;
170 switch(in_config->driver)
173 keepalive = new KeepaliveThread(this);
174 keepalive->start_keepalive();
175 input_base = new VDeviceV4L(this);
176 result = input_base->open_input();
180 #ifdef HAVE_VIDEO4LINUX2
182 input_base = new VDeviceV4L2(this);
183 result = input_base->open_input();
185 case VIDEO4LINUX2JPEG:
186 input_base = new VDeviceV4L2JPEG(this);
187 result = input_base->open_input();
192 this->input_x = input_x;
193 this->input_y = input_y;
194 input_base = new VDeviceX11(this, 0);
195 result = input_base->open_input();
198 //printf("VideoDevice 1\n");
199 keepalive = new KeepaliveThread(this);
200 keepalive->start_keepalive();
201 input_base = new VDeviceBUZ(this);
202 result = input_base->open_input();
205 case CAPTURE_FIREWIRE:
206 case CAPTURE_IEC61883:
207 input_base = new VDevice1394(this);
208 result = input_base->open_input();
213 if(!result) capturing = 1;
217 int VideoDevice::is_compressed(int driver, int use_file, int use_fixed)
219 // FileMOV needs to have write_frames called so the start codes get scanned.
220 return ((driver == CAPTURE_BUZ && use_fixed) ||
221 (driver == VIDEO4LINUX2JPEG && use_fixed) ||
222 driver == CAPTURE_LML ||
223 driver == CAPTURE_FIREWIRE ||
224 driver == CAPTURE_IEC61883);
227 int VideoDevice::is_compressed(int use_file, int use_fixed)
229 return is_compressed(in_config->driver, use_file, use_fixed);
233 char* VideoDevice::get_vcodec(int driver)
239 case VIDEO4LINUX2JPEG:
240 return QUICKTIME_MJPA;
243 case CAPTURE_FIREWIRE:
244 case CAPTURE_IEC61883:
245 return QUICKTIME_DVSD;
252 char* VideoDevice::drivertostr(int driver)
257 return PLAYBACK_X11_TITLE;
259 case PLAYBACK_X11_XV:
260 return PLAYBACK_X11_XV_TITLE;
263 return PLAYBACK_BUZ_TITLE;
266 return VIDEO4LINUX_TITLE;
269 return VIDEO4LINUX2_TITLE;
271 case VIDEO4LINUX2JPEG:
272 return VIDEO4LINUX2JPEG_TITLE;
275 return SCREENCAPTURE_TITLE;
278 return CAPTURE_BUZ_TITLE;
281 case CAPTURE_FIREWIRE:
282 return CAPTURE_FIREWIRE_TITLE;
284 case CAPTURE_IEC61883:
285 return CAPTURE_IEC61883_TITLE;
292 int VideoDevice::get_best_colormodel(Asset *asset)
295 return input_base->get_best_colormodel(asset);
300 int VideoDevice::close_all()
304 //printf("VideoDevice::close_all 1\n");
309 output_base->close_all();
314 //printf("VideoDevice::close_all 2\n");
320 input_base->close_all();
332 //printf("VideoDevice::close_all 3\n");
333 input_sources.remove_all_objects();
335 //printf("VideoDevice::close_all 4\n");
338 //printf("VideoDevice::close_all 5\n");
343 int VideoDevice::set_adevice(AudioDevice *adevice)
345 this->adevice = adevice;
350 ArrayList<Channel*>* VideoDevice::get_inputs()
352 return &input_sources;
355 Channel* VideoDevice::new_input_source(char *device_name)
357 for(int i = 0; i < input_sources.total; i++)
359 if(!strcmp(input_sources.values[i]->device_name, device_name))
360 return input_sources.values[i];
362 Channel *item = new Channel;
363 strcpy(item->device_name, device_name);
364 input_sources.append(item);
368 int VideoDevice::get_failed()
371 return keepalive->get_failed();
376 int VideoDevice::interrupt_crash()
378 if(input_base) return input_base->interrupt_crash();
382 int VideoDevice::set_translation(int input_x, int input_y)
384 this->input_x = input_x;
385 this->input_y = input_y;
389 int VideoDevice::set_field_order(int odd_field_first)
391 this->odd_field_first = odd_field_first;
395 int VideoDevice::set_channel(Channel *channel)
399 channel_lock->lock("VideoDevice::set_channel");
400 this->channel->copy_settings(channel);
402 channel_lock->unlock();
404 if(input_base) return input_base->set_channel(channel);
405 if(output_base) return output_base->set_channel(channel);
409 void VideoDevice::set_quality(int quality)
411 this->quality = quality;
414 void VideoDevice::set_cpus(int cpus)
419 int VideoDevice::set_picture(PictureConfig *picture)
423 picture_lock->lock("VideoDevice::set_picture");
424 this->picture->copy_settings(picture);
426 picture_lock->unlock();
428 if(input_base) return input_base->set_picture(picture);
432 int VideoDevice::update_translation()
434 float frame_in_capture_x1f, frame_in_capture_x2f, frame_in_capture_y1f, frame_in_capture_y2f;
435 float capture_in_frame_x1f, capture_in_frame_x2f, capture_in_frame_y1f, capture_in_frame_y2f;
440 input_x = new_input_x;
441 input_y = new_input_y;
443 if(in_config->driver == VIDEO4LINUX || in_config->driver == VIDEO4LINUX2)
445 if(input_z != new_input_z)
447 input_z = new_input_z;
450 capture_w = (int)((float)in_config->w * input_z + 0.5);
451 capture_h = (int)((float)in_config->h * input_z + 0.5);
453 // Need to align to multiple of 4
458 frame_in_capture_x1f = (float)input_x * input_z + capture_w / 2 - in_config->w / 2;
459 frame_in_capture_x2f = (float)input_x * input_z + capture_w / 2 + in_config->w / 2;
460 frame_in_capture_y1f = (float)input_y * input_z + capture_h / 2 - in_config->h / 2;
461 frame_in_capture_y2f = (float)input_y * input_z + capture_h / 2 + in_config->h / 2;
463 capture_in_frame_x1f = 0;
464 capture_in_frame_y1f = 0;
465 capture_in_frame_x2f = in_config->w;
466 capture_in_frame_y2f = in_config->h;
468 if(frame_in_capture_x1f < 0) { capture_in_frame_x1f -= frame_in_capture_x1f; frame_in_capture_x1f = 0; }
469 if(frame_in_capture_y1f < 0) { capture_in_frame_y1f -= frame_in_capture_y1f; frame_in_capture_y1f = 0; }
470 if(frame_in_capture_x2f > capture_w) { capture_in_frame_x2f -= frame_in_capture_x2f - capture_w; frame_in_capture_x2f = capture_w; }
471 if(frame_in_capture_y2f > capture_h) { capture_in_frame_y2f -= frame_in_capture_y2f - capture_h; frame_in_capture_y2f = capture_h; }
473 frame_in_capture_x1 = (int)frame_in_capture_x1f;
474 frame_in_capture_y1 = (int)frame_in_capture_y1f;
475 frame_in_capture_x2 = (int)frame_in_capture_x2f;
476 frame_in_capture_y2 = (int)frame_in_capture_y2f;
478 capture_in_frame_x1 = (int)capture_in_frame_x1f;
479 capture_in_frame_y1 = (int)capture_in_frame_y1f;
480 capture_in_frame_x2 = (int)capture_in_frame_x2f;
481 capture_in_frame_y2 = (int)capture_in_frame_y2f;
489 int VideoDevice::set_latency_counter(int value)
491 latency_counter = value;
495 int VideoDevice::has_signal()
497 if(input_base) return input_base->has_signal();
502 int VideoDevice::read_buffer(VFrame *frame)
505 if(!capturing) return 0;
507 //printf("VideoDevice::read_buffer %p %p\n", frame, input_base);
510 // Reset the keepalive thread
511 if(keepalive) keepalive->capturing = 1;
512 result = input_base->read_buffer(frame);
515 keepalive->capturing = 0;
516 keepalive->reset_keepalive();
525 // ================================= OUTPUT ==========================================
528 int VideoDevice::open_output(VideoOutConfig *config,
536 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
537 *this->out_config = *config;
538 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
542 this->single_frame = single_frame;
544 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
545 switch(out_config->driver)
548 output_base = new VDeviceBUZ(this);
551 case PLAYBACK_X11_XV:
552 output_base = new VDeviceX11(this, output);
556 case PLAYBACK_DV1394:
557 case PLAYBACK_FIREWIRE:
558 case PLAYBACK_IEC61883:
559 output_base = new VDevice1394(this);
563 //printf("VideoDevice::open_output 2 %d\n", out_config->driver);
565 if(output_base->open_output())
570 //printf("VideoDevice::open_output 3 %d\n", out_config->driver);
580 int VideoDevice::start_playback()
582 // arm buffer before doing this
586 if(output_base) return output_base->start_playback();
590 int VideoDevice::stop_playback()
592 if(output_base) output_base->stop_playback();
598 void VideoDevice::goose_input()
600 if(input_base) input_base->goose_input();
603 void VideoDevice::new_output_buffers(VFrame **outputs, int colormodel)
605 for(int i = 0; i < MAX_CHANNELS; i++)
608 if(!output_base) return;
609 output_base->new_output_buffer(outputs, colormodel);
613 int VideoDevice::interrupt_playback()
619 int VideoDevice::write_buffer(VFrame **outputs, EDL *edl)
621 //printf("VideoDevice::write_buffer 1 %p\n", output_base);
622 if(output_base) return output_base->write_buffer(outputs, edl);
626 int VideoDevice::output_visible()
628 if(output_base) return output_base->output_visible();
631 BC_Bitmap* VideoDevice::get_bitmap()
633 if(output_base) return output_base->get_bitmap();
637 int VideoDevice::set_cloexec_flag(int desc, int value)
639 int oldflags = fcntl(desc, F_GETFD, 0);
640 if(oldflags < 0) return oldflags;
642 oldflags |= FD_CLOEXEC;
644 oldflags &= ~FD_CLOEXEC;
645 return fcntl(desc, F_SETFD, oldflags);