4 #include "chantables.h"
5 #include "playbackconfig.h"
6 #include "playbackengine.h"
7 #include "preferences.h"
8 #include "recordconfig.h"
9 #include "recordmonitor.h"
10 #include "vdevice1394.h"
11 #include "vdevicebuz.h"
12 #include "vdevicev4l.h"
13 #include "vdevicex11.h"
14 #include "videoconfig.h"
15 #include "videodevice.h"
16 #include "videowindow.h"
17 #include "videowindowgui.h"
21 KeepaliveThread::KeepaliveThread(VideoDevice *device) : Thread()
27 this->device = device;
31 KeepaliveThread::~KeepaliveThread()
35 int KeepaliveThread::start_keepalive()
40 startup_lock.unlock();
43 void KeepaliveThread::run()
45 startup_lock.unlock();
49 // Give the capture a moment
50 // Should fix the delay in case users want slower frame rates.
51 timer.delay((long)(KEEPALIVE_DELAY * 1000));
53 // See if a capture happened
54 if(still_alive == 0 && capturing)
56 // printf("KeepaliveThread::run: device crashed\n");
64 int KeepaliveThread::reset_keepalive()
69 int KeepaliveThread::get_failed()
71 if(failed) return 1; else return 0;
74 int KeepaliveThread::stop()
78 // Force an immediate exit even if capture_frame worked.
89 VideoDevice::VideoDevice()
91 in_config = new VideoInConfig;
92 out_config = new VideoOutConfig(0, 0);
96 VideoDevice::~VideoDevice()
98 input_sources.remove_all_objects();
103 int VideoDevice::initialize()
107 sharing_lock.reset();
111 is_playing_back = is_recording = 0;
129 int VideoDevice::open_input(VideoInConfig *config,
137 *this->in_config = *config;
140 this->input_z = -1; // Force initialization.
141 this->frame_rate = frame_rate;
143 switch(in_config->driver)
146 keepalive = new KeepaliveThread(this);
147 keepalive->start_keepalive();
148 input_base = new VDeviceV4L(this);
149 result = input_base->open_input();
152 this->input_x = input_x;
153 this->input_y = input_y;
154 input_base = new VDeviceX11(this, 0);
155 result = input_base->open_input();
158 //printf("VideoDevice 1\n");
159 keepalive = new KeepaliveThread(this);
160 keepalive->start_keepalive();
161 input_base = new VDeviceBUZ(this);
162 result = input_base->open_input();
165 case CAPTURE_FIREWIRE:
166 input_base = new VDevice1394(this);
167 result = input_base->open_input();
172 if(!result) capturing = 1;
176 int VideoDevice::is_compressed(int driver)
178 return (driver == CAPTURE_BUZ ||
179 driver == CAPTURE_LML ||
180 driver == CAPTURE_FIREWIRE);
183 char* VideoDevice::get_vcodec(int driver)
189 return QUICKTIME_MJPA;
192 case CAPTURE_FIREWIRE:
199 char* VideoDevice::drivertostr(int driver)
204 return PLAYBACK_X11_TITLE;
206 case PLAYBACK_X11_XV:
207 return PLAYBACK_X11_XV_TITLE;
210 return PLAYBACK_BUZ_TITLE;
213 return VIDEO4LINUX_TITLE;
216 return SCREENCAPTURE_TITLE;
219 return CAPTURE_BUZ_TITLE;
221 case CAPTURE_FIREWIRE:
222 return CAPTURE_FIREWIRE_TITLE;
228 int VideoDevice::is_compressed()
230 return is_compressed(in_config->driver);
233 int VideoDevice::get_best_colormodel(Asset *asset)
236 return input_base->get_best_colormodel(asset);
241 int VideoDevice::close_all()
245 //printf("VideoDevice::close_all 1\n");
250 output_base->close_all();
255 //printf("VideoDevice::close_all 2\n");
261 input_base->close_all();
273 //printf("VideoDevice::close_all 3\n");
274 input_sources.remove_all_objects();
276 //printf("VideoDevice::close_all 4\n");
279 //printf("VideoDevice::close_all 5\n");
284 int VideoDevice::set_adevice(AudioDevice *adevice)
286 this->adevice = adevice;
291 // int VideoDevice::stop_sharing()
295 // sharing_lock.lock();
297 // if(input_base) input_base->stop_sharing();
303 // int VideoDevice::get_shared_data(unsigned char *data, long size)
307 // input_base->get_shared_data(data, size);
312 void VideoDevice::create_channeldb(ArrayList<Channel*> *channeldb)
315 input_base->create_channeldb(channeldb);
318 ArrayList<char *>* VideoDevice::get_inputs()
320 return &input_sources;
323 int VideoDevice::get_failed()
326 return keepalive->get_failed();
331 int VideoDevice::interrupt_crash()
333 if(input_base) return input_base->interrupt_crash();
337 int VideoDevice::set_translation(int input_x, int input_y)
339 this->input_x = input_x;
340 this->input_y = input_y;
344 int VideoDevice::set_field_order(int odd_field_first)
346 this->odd_field_first = odd_field_first;
350 int VideoDevice::set_channel(Channel *channel)
352 if(input_base) return input_base->set_channel(channel);
353 if(output_base) return output_base->set_channel(channel);
356 void VideoDevice::set_quality(int quality)
358 this->quality = quality;
361 void VideoDevice::set_cpus(int cpus)
366 int VideoDevice::set_picture(int brightness,
372 if(input_base) return input_base->set_picture(brightness,
379 int VideoDevice::update_translation()
381 float frame_in_capture_x1f, frame_in_capture_x2f, frame_in_capture_y1f, frame_in_capture_y2f;
382 float capture_in_frame_x1f, capture_in_frame_x2f, capture_in_frame_y1f, capture_in_frame_y2f;
387 input_x = new_input_x;
388 input_y = new_input_y;
390 if(in_config->driver == VIDEO4LINUX || in_config->driver == VIDEO4LINUX2)
392 if(input_z != new_input_z)
394 input_z = new_input_z;
397 capture_w = (int)((float)in_config->w * input_z + 0.5);
398 capture_h = (int)((float)in_config->h * input_z + 0.5);
400 // Need to align to multiple of 4
405 frame_in_capture_x1f = (float)input_x * input_z + capture_w / 2 - in_config->w / 2;
406 frame_in_capture_x2f = (float)input_x * input_z + capture_w / 2 + in_config->w / 2;
407 frame_in_capture_y1f = (float)input_y * input_z + capture_h / 2 - in_config->h / 2;
408 frame_in_capture_y2f = (float)input_y * input_z + capture_h / 2 + in_config->h / 2;
410 capture_in_frame_x1f = 0;
411 capture_in_frame_y1f = 0;
412 capture_in_frame_x2f = in_config->w;
413 capture_in_frame_y2f = in_config->h;
415 if(frame_in_capture_x1f < 0) { capture_in_frame_x1f -= frame_in_capture_x1f; frame_in_capture_x1f = 0; }
416 if(frame_in_capture_y1f < 0) { capture_in_frame_y1f -= frame_in_capture_y1f; frame_in_capture_y1f = 0; }
417 if(frame_in_capture_x2f > capture_w) { capture_in_frame_x2f -= frame_in_capture_x2f - capture_w; frame_in_capture_x2f = capture_w; }
418 if(frame_in_capture_y2f > capture_h) { capture_in_frame_y2f -= frame_in_capture_y2f - capture_h; frame_in_capture_y2f = capture_h; }
420 frame_in_capture_x1 = (int)frame_in_capture_x1f;
421 frame_in_capture_y1 = (int)frame_in_capture_y1f;
422 frame_in_capture_x2 = (int)frame_in_capture_x2f;
423 frame_in_capture_y2 = (int)frame_in_capture_y2f;
425 capture_in_frame_x1 = (int)capture_in_frame_x1f;
426 capture_in_frame_y1 = (int)capture_in_frame_y1f;
427 capture_in_frame_x2 = (int)capture_in_frame_x2f;
428 capture_in_frame_y2 = (int)capture_in_frame_y2f;
436 int VideoDevice::set_latency_counter(int value)
438 latency_counter = value;
442 int VideoDevice::read_buffer(VFrame *frame)
445 if(!capturing) return 0;
447 //printf("VideoDevice::read_buffer %p %p\n", frame, input_base);
450 // Reset the keepalive thread
451 if(keepalive) keepalive->capturing = 1;
452 result = input_base->read_buffer(frame);
455 keepalive->capturing = 0;
456 keepalive->reset_keepalive();
465 // ================================= OUTPUT ==========================================
468 int VideoDevice::open_output(VideoOutConfig *config,
476 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
477 *this->out_config = *config;
478 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
482 this->single_frame = single_frame;
484 //printf("VideoDevice::open_output 1 %d\n", out_config->driver);
485 switch(out_config->driver)
488 output_base = new VDeviceBUZ(this);
491 case PLAYBACK_X11_XV:
492 output_base = new VDeviceX11(this, output);
495 case PLAYBACK_FIREWIRE:
496 output_base = new VDevice1394(this);
499 //printf("VideoDevice::open_output 2 %d\n", out_config->driver);
501 if(output_base->open_output())
506 //printf("VideoDevice::open_output 3 %d\n", out_config->driver);
516 int VideoDevice::start_playback()
518 // arm buffer before doing this
522 if(output_base) return output_base->start_playback();
526 int VideoDevice::stop_playback()
528 if(output_base) output_base->stop_playback();
534 void VideoDevice::goose_input()
536 if(input_base) input_base->goose_input();
539 void VideoDevice::new_output_buffers(VFrame **outputs, int colormodel)
541 for(int i = 0; i < MAX_CHANNELS; i++)
544 if(!output_base) return;
545 output_base->new_output_buffer(outputs, colormodel);
549 int VideoDevice::interrupt_playback()
555 int VideoDevice::write_buffer(VFrame **outputs, EDL *edl)
557 //printf("VideoDevice::write_buffer 1 %p\n", output_base);
558 if(output_base) return output_base->write_buffer(outputs, edl);
562 int VideoDevice::output_visible()
564 if(output_base) return output_base->output_visible();
567 BC_Bitmap* VideoDevice::get_bitmap()
569 if(output_base) return output_base->get_bitmap();