00001 #include "assets.h"
00002 #include "bccapture.h"
00003 #include "channel.h"
00004 #include "chantables.h"
00005 #include "mutex.h"
00006 #include "picture.h"
00007 #include "playbackconfig.h"
00008 #include "playbackengine.h"
00009 #include "preferences.h"
00010 #include "recordconfig.h"
00011 #include "recordmonitor.h"
00012 #include "vdevice1394.h"
00013 #include "vdevicebuz.h"
00014 #include "vdevicev4l.h"
00015 #include "vdevicev4l2.h"
00016 #include "vdevicev4l2jpeg.h"
00017 #include "vdevicex11.h"
00018 #include "videoconfig.h"
00019 #include "videodevice.h"
00020 #include "videowindow.h"
00021 #include "videowindowgui.h"
00022 #include "vframe.h"
00023
00024 #include <unistd.h>
00025 #include <fcntl.h>
00026
00027 KeepaliveThread::KeepaliveThread(VideoDevice *device)
00028 : Thread()
00029 {
00030 still_alive = 1;
00031 failed = 0;
00032 interrupted = 0;
00033 set_synchronous(1);
00034 this->device = device;
00035 capturing = 0;
00036 startup_lock = new Mutex("KeepaliveThread::startup_lock");
00037 }
00038
00039 KeepaliveThread::~KeepaliveThread()
00040 {
00041 delete startup_lock;
00042 }
00043
00044 int KeepaliveThread::start_keepalive()
00045 {
00046 startup_lock->lock("KeepaliveThread::start_keepalive 1");
00047 start();
00048 startup_lock->lock("KeepaliveThread::start_keepalive 2");
00049 startup_lock->unlock();
00050 }
00051
00052 void KeepaliveThread::run()
00053 {
00054 startup_lock->unlock();
00055 while(!interrupted)
00056 {
00057 still_alive = 0;
00058
00059
00060 timer.delay((long)(KEEPALIVE_DELAY * 1000));
00061
00062
00063 if(still_alive == 0 && capturing)
00064 {
00065
00066 failed++;
00067 }
00068 else
00069 failed = 0;
00070 }
00071 }
00072
00073 int KeepaliveThread::reset_keepalive()
00074 {
00075 still_alive = 1;
00076 }
00077
00078 int KeepaliveThread::get_failed()
00079 {
00080 if(failed) return 1; else return 0;
00081 }
00082
00083 int KeepaliveThread::stop()
00084 {
00085 interrupted = 1;
00086
00087
00088 Thread::end();
00089 Thread::join();
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 VideoDevice::VideoDevice(MWindow *mwindow)
00099 {
00100 this->mwindow = mwindow;
00101 in_config = new VideoInConfig;
00102 out_config = new VideoOutConfig;
00103 channel = new Channel;
00104 picture = new PictureConfig(mwindow);
00105 sharing_lock = new Mutex("VideoDevice::sharing_lock");
00106 channel_lock = new Mutex("VideoDevice::channel_lock");
00107 picture_lock = new Mutex("VideoDevice::picture_lock");
00108 initialize();
00109 }
00110
00111
00112 VideoDevice::~VideoDevice()
00113 {
00114 input_sources.remove_all_objects();
00115 delete in_config;
00116 delete out_config;
00117 delete channel;
00118 delete picture;
00119 delete sharing_lock;
00120 delete channel_lock;
00121 delete picture_lock;
00122 }
00123
00124 int VideoDevice::initialize()
00125 {
00126 sharing = 0;
00127 done_sharing = 0;
00128 sharing_lock->reset();
00129 orate = irate = 0;
00130 out_w = out_h = 0;
00131 r = w = 0;
00132 is_playing_back = is_recording = 0;
00133 input_x = 0;
00134 input_y = 0;
00135 input_z = 1;
00136 frame_resized = 0;
00137 capturing = 0;
00138 keepalive = 0;
00139 swap_bytes = 0;
00140 input_base = 0;
00141 output_base = 0;
00142 output_format = 0;
00143 interrupt = 0;
00144 adevice = 0;
00145 quality = 80;
00146 cpus = 1;
00147 single_frame = 0;
00148 channel_changed = 0;
00149 picture_changed = 0;
00150 }
00151
00152 int VideoDevice::open_input(VideoInConfig *config,
00153 int input_x,
00154 int input_y,
00155 float input_z,
00156 float frame_rate)
00157 {
00158 int result = 0;
00159
00160 *this->in_config = *config;
00161
00162 r = 1;
00163 this->input_z = -1;
00164 this->frame_rate = frame_rate;
00165
00166
00167 switch(in_config->driver)
00168 {
00169 case VIDEO4LINUX:
00170 keepalive = new KeepaliveThread(this);
00171 keepalive->start_keepalive();
00172 input_base = new VDeviceV4L(this);
00173 result = input_base->open_input();
00174 break;
00175
00176
00177 #ifdef HAVE_VIDEO4LINUX2
00178 case VIDEO4LINUX2:
00179 input_base = new VDeviceV4L2(this);
00180 result = input_base->open_input();
00181 break;
00182 case VIDEO4LINUX2JPEG:
00183 input_base = new VDeviceV4L2JPEG(this);
00184 result = input_base->open_input();
00185 break;
00186 #endif
00187
00188 case SCREENCAPTURE:
00189 this->input_x = input_x;
00190 this->input_y = input_y;
00191 input_base = new VDeviceX11(this, 0);
00192 result = input_base->open_input();
00193 break;
00194 case CAPTURE_BUZ:
00195
00196 keepalive = new KeepaliveThread(this);
00197 keepalive->start_keepalive();
00198 input_base = new VDeviceBUZ(this);
00199 result = input_base->open_input();
00200 break;
00201 #ifdef HAVE_FIREWIRE
00202 case CAPTURE_FIREWIRE:
00203 case CAPTURE_IEC61883:
00204 input_base = new VDevice1394(this);
00205 result = input_base->open_input();
00206 break;
00207 #endif
00208 }
00209
00210 if(!result) capturing = 1;
00211 return 0;
00212 }
00213
00214 int VideoDevice::is_compressed(int driver, int use_file, int use_fixed)
00215 {
00216
00217 return ((driver == CAPTURE_BUZ && use_fixed) ||
00218 (driver == VIDEO4LINUX2JPEG && use_fixed) ||
00219 driver == CAPTURE_LML ||
00220 driver == CAPTURE_FIREWIRE ||
00221 driver == CAPTURE_IEC61883);
00222 }
00223
00224 int VideoDevice::is_compressed(int use_file, int use_fixed)
00225 {
00226 return is_compressed(in_config->driver, use_file, use_fixed);
00227 }
00228
00229
00230 char* VideoDevice::get_vcodec(int driver)
00231 {
00232 switch(driver)
00233 {
00234 case CAPTURE_BUZ:
00235 case CAPTURE_LML:
00236 case VIDEO4LINUX2JPEG:
00237 return QUICKTIME_MJPA;
00238 break;
00239
00240 case CAPTURE_FIREWIRE:
00241 case CAPTURE_IEC61883:
00242 return QUICKTIME_DVSD;
00243 break;
00244 }
00245 return "";
00246 }
00247
00248
00249 char* VideoDevice::drivertostr(int driver)
00250 {
00251 switch(driver)
00252 {
00253 case PLAYBACK_X11:
00254 return PLAYBACK_X11_TITLE;
00255 break;
00256 case PLAYBACK_X11_XV:
00257 return PLAYBACK_X11_XV_TITLE;
00258 break;
00259 case PLAYBACK_BUZ:
00260 return PLAYBACK_BUZ_TITLE;
00261 break;
00262 case VIDEO4LINUX:
00263 return VIDEO4LINUX_TITLE;
00264 break;
00265 case VIDEO4LINUX2:
00266 return VIDEO4LINUX2_TITLE;
00267 break;
00268 case VIDEO4LINUX2JPEG:
00269 return VIDEO4LINUX2JPEG_TITLE;
00270 break;
00271 case SCREENCAPTURE:
00272 return SCREENCAPTURE_TITLE;
00273 break;
00274 case CAPTURE_BUZ:
00275 return CAPTURE_BUZ_TITLE;
00276 break;
00277 case CAPTURE_FIREWIRE:
00278 return CAPTURE_FIREWIRE_TITLE;
00279 break;
00280 case CAPTURE_IEC61883:
00281 return CAPTURE_IEC61883_TITLE;
00282 break;
00283 }
00284 return "";
00285 }
00286
00287 int VideoDevice::get_best_colormodel(Asset *asset)
00288 {
00289 if(input_base)
00290 return input_base->get_best_colormodel(asset);
00291 else
00292 return BC_RGB888;
00293 }
00294
00295 int VideoDevice::close_all()
00296 {
00297 int i;
00298
00299
00300 if(w)
00301 {
00302 if(output_base)
00303 {
00304 output_base->close_all();
00305 delete output_base;
00306 }
00307 }
00308
00309
00310 if(r && capturing)
00311 {
00312 capturing = 0;
00313 if(input_base)
00314 {
00315 input_base->close_all();
00316 delete input_base;
00317 input_base = 0;
00318 }
00319
00320 if(keepalive)
00321 {
00322 keepalive->stop();
00323 delete keepalive;
00324 }
00325 }
00326
00327
00328 input_sources.remove_all_objects();
00329
00330
00331 initialize();
00332
00333
00334 return 0;
00335 }
00336
00337
00338 int VideoDevice::set_adevice(AudioDevice *adevice)
00339 {
00340 this->adevice = adevice;
00341 return 0;
00342 }
00343
00344
00345 ArrayList<Channel*>* VideoDevice::get_inputs()
00346 {
00347 return &input_sources;
00348 }
00349
00350 Channel* VideoDevice::new_input_source(char *device_name)
00351 {
00352 for(int i = 0; i < input_sources.total; i++)
00353 {
00354 if(!strcmp(input_sources.values[i]->device_name, device_name))
00355 return input_sources.values[i];
00356 }
00357 Channel *item = new Channel;
00358 strcpy(item->device_name, device_name);
00359 input_sources.append(item);
00360 return item;
00361 }
00362
00363 int VideoDevice::get_failed()
00364 {
00365 if(keepalive)
00366 return keepalive->get_failed();
00367 else
00368 return 0;
00369 }
00370
00371 int VideoDevice::interrupt_crash()
00372 {
00373 if(input_base) return input_base->interrupt_crash();
00374 return 0;
00375 }
00376
00377 int VideoDevice::set_translation(int input_x, int input_y)
00378 {
00379 this->input_x = input_x;
00380 this->input_y = input_y;
00381 return 0;
00382 }
00383
00384 int VideoDevice::set_field_order(int odd_field_first)
00385 {
00386 this->odd_field_first = odd_field_first;
00387 return 0;
00388 }
00389
00390 int VideoDevice::set_channel(Channel *channel)
00391 {
00392 if(channel)
00393 {
00394 channel_lock->lock("VideoDevice::set_channel");
00395 this->channel->copy_settings(channel);
00396 channel_changed = 1;
00397 channel_lock->unlock();
00398
00399 if(input_base) return input_base->set_channel(channel);
00400 if(output_base) return output_base->set_channel(channel);
00401 }
00402 }
00403
00404 void VideoDevice::set_quality(int quality)
00405 {
00406 this->quality = quality;
00407 }
00408
00409 void VideoDevice::set_cpus(int cpus)
00410 {
00411 this->cpus = cpus;
00412 }
00413
00414 int VideoDevice::set_picture(PictureConfig *picture)
00415 {
00416 if(picture)
00417 {
00418 picture_lock->lock("VideoDevice::set_picture");
00419 this->picture->copy_settings(picture);
00420 picture_changed = 1;
00421 picture_lock->unlock();
00422
00423 if(input_base) return input_base->set_picture(picture);
00424 }
00425 }
00426
00427 int VideoDevice::update_translation()
00428 {
00429 float frame_in_capture_x1f, frame_in_capture_x2f, frame_in_capture_y1f, frame_in_capture_y2f;
00430 float capture_in_frame_x1f, capture_in_frame_x2f, capture_in_frame_y1f, capture_in_frame_y2f;
00431 int z_changed = 0;
00432
00433 if(frame_resized)
00434 {
00435 input_x = new_input_x;
00436 input_y = new_input_y;
00437
00438 if(in_config->driver == VIDEO4LINUX || in_config->driver == VIDEO4LINUX2)
00439 {
00440 if(input_z != new_input_z)
00441 {
00442 input_z = new_input_z;
00443 z_changed = 1;
00444
00445 capture_w = (int)((float)in_config->w * input_z + 0.5);
00446 capture_h = (int)((float)in_config->h * input_z + 0.5);
00447
00448
00449 capture_w &= ~3;
00450 capture_h &= ~3;
00451 }
00452
00453 frame_in_capture_x1f = (float)input_x * input_z + capture_w / 2 - in_config->w / 2;
00454 frame_in_capture_x2f = (float)input_x * input_z + capture_w / 2 + in_config->w / 2;
00455 frame_in_capture_y1f = (float)input_y * input_z + capture_h / 2 - in_config->h / 2;
00456 frame_in_capture_y2f = (float)input_y * input_z + capture_h / 2 + in_config->h / 2;
00457
00458 capture_in_frame_x1f = 0;
00459 capture_in_frame_y1f = 0;
00460 capture_in_frame_x2f = in_config->w;
00461 capture_in_frame_y2f = in_config->h;
00462
00463 if(frame_in_capture_x1f < 0) { capture_in_frame_x1f -= frame_in_capture_x1f; frame_in_capture_x1f = 0; }
00464 if(frame_in_capture_y1f < 0) { capture_in_frame_y1f -= frame_in_capture_y1f; frame_in_capture_y1f = 0; }
00465 if(frame_in_capture_x2f > capture_w) { capture_in_frame_x2f -= frame_in_capture_x2f - capture_w; frame_in_capture_x2f = capture_w; }
00466 if(frame_in_capture_y2f > capture_h) { capture_in_frame_y2f -= frame_in_capture_y2f - capture_h; frame_in_capture_y2f = capture_h; }
00467
00468 frame_in_capture_x1 = (int)frame_in_capture_x1f;
00469 frame_in_capture_y1 = (int)frame_in_capture_y1f;
00470 frame_in_capture_x2 = (int)frame_in_capture_x2f;
00471 frame_in_capture_y2 = (int)frame_in_capture_y2f;
00472
00473 capture_in_frame_x1 = (int)capture_in_frame_x1f;
00474 capture_in_frame_y1 = (int)capture_in_frame_y1f;
00475 capture_in_frame_x2 = (int)capture_in_frame_x2f;
00476 capture_in_frame_y2 = (int)capture_in_frame_y2f;
00477
00478 frame_resized = 0;
00479 }
00480 }
00481 return 0;
00482 }
00483
00484 int VideoDevice::set_latency_counter(int value)
00485 {
00486 latency_counter = value;
00487 return 0;
00488 }
00489
00490 int VideoDevice::has_signal()
00491 {
00492 if(input_base) return input_base->has_signal();
00493 return 0;
00494 }
00495
00496
00497 int VideoDevice::read_buffer(VFrame *frame)
00498 {
00499 int result = 0;
00500 if(!capturing) return 0;
00501
00502
00503 if(input_base)
00504 {
00505
00506 if(keepalive) keepalive->capturing = 1;
00507 result = input_base->read_buffer(frame);
00508 if(keepalive)
00509 {
00510 keepalive->capturing = 0;
00511 keepalive->reset_keepalive();
00512 }
00513 return result;
00514 }
00515
00516 return 0;
00517 }
00518
00519
00520
00521
00522
00523 int VideoDevice::open_output(VideoOutConfig *config,
00524 float rate,
00525 int out_w,
00526 int out_h,
00527 Canvas *output,
00528 int single_frame)
00529 {
00530 w = 1;
00531
00532 *this->out_config = *config;
00533
00534 this->out_w = out_w;
00535 this->out_h = out_h;
00536 this->orate = rate;
00537 this->single_frame = single_frame;
00538
00539
00540 switch(out_config->driver)
00541 {
00542 case PLAYBACK_BUZ:
00543 output_base = new VDeviceBUZ(this);
00544 break;
00545 case PLAYBACK_X11:
00546 case PLAYBACK_X11_XV:
00547 output_base = new VDeviceX11(this, output);
00548 break;
00549
00550 case PLAYBACK_DV1394:
00551 case PLAYBACK_FIREWIRE:
00552 case PLAYBACK_IEC61883:
00553 output_base = new VDevice1394(this);
00554 break;
00555 }
00556
00557
00558 if(output_base->open_output())
00559 {
00560 delete output_base;
00561 output_base = 0;
00562 }
00563
00564
00565 if(output_base)
00566 return 0;
00567 else
00568 return 1;
00569 }
00570
00571
00572
00573 int VideoDevice::start_playback()
00574 {
00575
00576 is_playing_back = 1;
00577 interrupt = 0;
00578
00579 if(output_base) return output_base->start_playback();
00580 return 1;
00581 }
00582
00583 int VideoDevice::stop_playback()
00584 {
00585 if(output_base) output_base->stop_playback();
00586 is_playing_back = 0;
00587 interrupt = 0;
00588 return 0;
00589 }
00590
00591 void VideoDevice::goose_input()
00592 {
00593 if(input_base) input_base->goose_input();
00594 }
00595
00596 void VideoDevice::new_output_buffers(VFrame **outputs, int colormodel)
00597 {
00598 for(int i = 0; i < MAX_CHANNELS; i++)
00599 outputs[i] = 0;
00600
00601 if(!output_base) return;
00602 output_base->new_output_buffer(outputs, colormodel);
00603 }
00604
00605
00606 int VideoDevice::interrupt_playback()
00607 {
00608 interrupt = 1;
00609 return 0;
00610 }
00611
00612 int VideoDevice::write_buffer(VFrame **outputs, EDL *edl)
00613 {
00614
00615 if(output_base) return output_base->write_buffer(outputs, edl);
00616 return 1;
00617 }
00618
00619 int VideoDevice::output_visible()
00620 {
00621 if(output_base) return output_base->output_visible();
00622 }
00623
00624 BC_Bitmap* VideoDevice::get_bitmap()
00625 {
00626 if(output_base) return output_base->get_bitmap();
00627 }
00628
00629
00630 int VideoDevice::set_cloexec_flag(int desc, int value)
00631 {
00632 int oldflags = fcntl(desc, F_GETFD, 0);
00633 if(oldflags < 0) return oldflags;
00634 if(value != 0)
00635 oldflags |= FD_CLOEXEC;
00636 else
00637 oldflags &= ~FD_CLOEXEC;
00638 return fcntl(desc, F_SETFD, oldflags);
00639 }
00640