00001 #include "asset.h"
00002 #include "bcsignals.h"
00003 #include "channelpicker.h"
00004 #include "condition.h"
00005 #include "cursors.h"
00006 #include "libdv.h"
00007 #include "edl.h"
00008 #include "edlsession.h"
00009 #include "keys.h"
00010 #include "language.h"
00011 #include "meterpanel.h"
00012 #include "mwindow.h"
00013 #include "playbackconfig.h"
00014 #include "preferences.h"
00015 #include "record.h"
00016 #include "recordconfig.h"
00017 #include "recordgui.h"
00018 #include "recordtransport.h"
00019 #include "recordmonitor.h"
00020 #include "mainsession.h"
00021 #include "theme.h"
00022 #include "videodevice.inc"
00023 #include "vframe.h"
00024 #include "videodevice.h"
00025
00026
00027 RecordMonitor::RecordMonitor(MWindow *mwindow, Record *record)
00028 : Thread(1)
00029 {
00030 this->mwindow = mwindow;
00031 this->record = record;
00032 device = 0;
00033 thread = 0;
00034 }
00035
00036
00037 RecordMonitor::~RecordMonitor()
00038 {
00039 if(thread)
00040 {
00041 thread->stop_playback();
00042 delete thread;
00043 }
00044 window->set_done(0);
00045 Thread::join();
00046 if(device)
00047 {
00048 device->close_all();
00049 delete device;
00050 }
00051 delete window;
00052 }
00053
00054 int RecordMonitor::create_objects()
00055 {
00056 int min_w = 150;
00057 mwindow->session->rwindow_fullscreen = 0;
00058
00059 if(!record->default_asset->video_data)
00060 min_w = MeterPanel::get_meters_width(
00061 record->default_asset->channels, 1);
00062 SET_TRACE
00063 window = new RecordMonitorGUI(mwindow,
00064 record,
00065 this,
00066 min_w);
00067 SET_TRACE
00068 window->create_objects();
00069 SET_TRACE
00070
00071 if(record->default_asset->video_data)
00072 {
00073
00074 VideoOutConfig config;
00075 SET_TRACE
00076 device = new VideoDevice;
00077 SET_TRACE
00078
00079
00080
00081
00082 if(mwindow->edl->session->playback_config->vconfig->driver ==
00083 PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV;
00084 config.x11_use_fields = 0;
00085
00086 SET_TRACE
00087
00088 device->open_output(&config,
00089 record->default_asset->frame_rate,
00090 record->default_asset->width,
00091 record->default_asset->height,
00092 window->canvas,
00093 0);
00094 SET_TRACE
00095
00096 thread = new RecordMonitorThread(mwindow, record, this);
00097 SET_TRACE
00098 thread->start_playback();
00099 SET_TRACE
00100 }
00101 SET_TRACE
00102
00103 Thread::start();
00104 return 0;
00105 }
00106
00107
00108 void RecordMonitor::run()
00109 {
00110 window->run_window();
00111 close_threads();
00112 }
00113
00114 int RecordMonitor::close_threads()
00115 {
00116 if(window->channel_picker) window->channel_picker->close_threads();
00117 }
00118
00119 int RecordMonitor::update(VFrame *vframe)
00120 {
00121 return thread->write_frame(vframe);
00122 }
00123
00124 void RecordMonitor::update_channel(char *text)
00125 {
00126 if(window->channel_picker)
00127 window->channel_picker->channel_text->update(text);
00128 }
00129
00130 int RecordMonitor::get_mbuttons_height()
00131 {
00132 return RECBUTTON_HEIGHT;
00133 }
00134
00135 int RecordMonitor::fix_size(int &w, int &h, int width_given, float aspect_ratio)
00136 {
00137 w = width_given;
00138 h = (int)((float)width_given / aspect_ratio);
00139 }
00140
00141 float RecordMonitor::get_scale(int w)
00142 {
00143 if(mwindow->edl->get_aspect_ratio() >
00144 (float)record->frame_w / record->frame_h)
00145 {
00146 return (float)w /
00147 ((float)record->frame_h *
00148 mwindow->edl->get_aspect_ratio());
00149 }
00150 else
00151 {
00152 return (float)w / record->frame_w;
00153 }
00154 }
00155
00156 int RecordMonitor::get_canvas_height()
00157 {
00158 return window->get_h() - get_mbuttons_height();
00159 }
00160
00161 int RecordMonitor::get_channel_x()
00162 {
00163
00164 return 5;
00165 }
00166
00167 int RecordMonitor::get_channel_y()
00168 {
00169 return 2;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow,
00182 Record *record,
00183 RecordMonitor *thread,
00184 int min_w)
00185 : BC_Window(PROGRAM_NAME ": Video in",
00186 mwindow->session->rmonitor_x,
00187 mwindow->session->rmonitor_y,
00188 mwindow->session->rmonitor_w,
00189 mwindow->session->rmonitor_h,
00190 min_w,
00191 50,
00192 1,
00193 1,
00194 1)
00195 {
00196
00197 this->mwindow = mwindow;
00198 this->thread = thread;
00199 this->record = record;
00200 #ifdef HAVE_FIREWIRE
00201 avc = 0;
00202 avc1394_transport = 0;
00203 avc1394transport_title = 0;
00204 avc1394transport_timecode = 0;
00205 avc1394transport_thread = 0;
00206 #endif
00207 bitmap = 0;
00208 channel_picker = 0;
00209 reverse_interlace = 0;
00210 meters = 0;
00211 canvas = 0;
00212 current_operation = MONITOR_NONE;
00213 }
00214
00215 RecordMonitorGUI::~RecordMonitorGUI()
00216 {
00217 delete canvas;
00218 if(bitmap) delete bitmap;
00219 if(channel_picker) delete channel_picker;
00220 #ifdef HAVE_FIREWIRE
00221 if(avc1394transport_thread)
00222 delete avc1394transport_thread;
00223 if(avc)
00224 {
00225 delete avc;
00226 }
00227 if(avc1394_transport)
00228 {
00229 delete avc1394_transport;
00230 }
00231 if(avc1394transport_title)
00232 delete avc1394transport_title;
00233 #endif
00234 }
00235
00236 int RecordMonitorGUI::create_objects()
00237 {
00238
00239 int do_channel = (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
00240 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
00241 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2 ||
00242 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
00243 int do_interlace = (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
00244 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
00245 int background_done = 0;
00246
00247 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
00248 record->default_asset->video_data,
00249 do_channel,
00250 do_interlace,
00251 0,
00252 record->default_asset->channels);
00253
00254
00255
00256
00257
00258
00259 if(record->default_asset->video_data)
00260 {
00261 int driver = mwindow->edl->session->vconfig_in->driver;
00262
00263 #ifdef HAVE_FIREWIRE
00264 if(driver == CAPTURE_FIREWIRE ||
00265 driver == CAPTURE_IEC61883)
00266 {
00267 avc = new AVC1394Control;
00268 if(avc->device > -1)
00269 {
00270 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
00271 record->default_asset->video_data,
00272 do_channel,
00273 do_interlace,
00274 1,
00275 record->default_asset->channels);
00276 mwindow->theme->draw_rmonitor_bg(this);
00277 background_done = 1;
00278
00279 avc1394_transport = new AVC1394Transport(mwindow,
00280 avc,
00281 this,
00282 mwindow->theme->rmonitor_tx_x,
00283 mwindow->theme->rmonitor_tx_y);
00284 avc1394_transport->create_objects();
00285
00286 add_subwindow(avc1394transport_timecode =
00287 new BC_Title(avc1394_transport->x_end,
00288 mwindow->theme->rmonitor_tx_y + 10,
00289 _("00:00:00:00"),
00290 MEDIUM_7SEGMENT,
00291 BLACK));
00292
00293 avc1394transport_thread =
00294 new AVC1394TransportThread(avc1394transport_timecode,
00295 avc);
00296
00297 avc1394transport_thread->start();
00298
00299 }
00300 }
00301 #endif
00302
00303
00304 if(!background_done)
00305 {
00306 mwindow->theme->draw_rmonitor_bg(this);
00307 background_done = 1;
00308 }
00309
00310 mwindow->theme->rmonitor_canvas_w = MAX(10, mwindow->theme->rmonitor_canvas_w);
00311 mwindow->theme->rmonitor_canvas_h = MAX(10, mwindow->theme->rmonitor_canvas_h);
00312 canvas = new RecordMonitorCanvas(mwindow,
00313 this,
00314 record,
00315 mwindow->theme->rmonitor_canvas_x,
00316 mwindow->theme->rmonitor_canvas_y,
00317 mwindow->theme->rmonitor_canvas_w,
00318 mwindow->theme->rmonitor_canvas_h);
00319 canvas->create_objects(0);
00320
00321 if(driver == VIDEO4LINUX ||
00322 driver == CAPTURE_BUZ ||
00323 driver == VIDEO4LINUX2 ||
00324 driver == VIDEO4LINUX2JPEG)
00325 {
00326 channel_picker = new RecordChannelPicker(mwindow,
00327 record,
00328 thread,
00329 this,
00330 record->channeldb,
00331 mwindow->theme->rmonitor_channel_x,
00332 mwindow->theme->rmonitor_channel_y);
00333 channel_picker->create_objects();
00334 }
00335
00336 if(driver == CAPTURE_BUZ ||
00337 driver == VIDEO4LINUX2JPEG)
00338 {
00339 add_subwindow(reverse_interlace = new ReverseInterlace(record,
00340 mwindow->theme->rmonitor_interlace_x,
00341 mwindow->theme->rmonitor_interlace_y));
00342 }
00343
00344 add_subwindow(monitor_menu = new BC_PopupMenu(0,
00345 0,
00346 0,
00347 "",
00348 0));
00349 monitor_menu->add_item(new RecordMonitorFullsize(mwindow,
00350 this));
00351 }
00352
00353
00354 if(!background_done)
00355 {
00356 mwindow->theme->draw_rmonitor_bg(this);
00357 background_done = 1;
00358 }
00359
00360 if(record->default_asset->audio_data)
00361 {
00362 meters = new MeterPanel(mwindow,
00363 this,
00364 mwindow->theme->rmonitor_meter_x,
00365 mwindow->theme->rmonitor_meter_y,
00366 mwindow->theme->rmonitor_meter_h,
00367 record->default_asset->channels,
00368 1,
00369 1);
00370 meters->create_objects();
00371 }
00372 return 0;
00373 }
00374
00375 int RecordMonitorGUI::button_press_event()
00376 {
00377 if(mwindow->session->rwindow_fullscreen && canvas && canvas->get_canvas())
00378 return canvas->button_press_event_base(canvas->get_canvas());
00379
00380 if(get_buttonpress() == 2)
00381 {
00382 return 0;
00383 }
00384 else
00385
00386 if(get_buttonpress() == 3)
00387 {
00388 monitor_menu->activate_menu();
00389 return 1;
00390 }
00391 return 0;
00392 }
00393
00394 int RecordMonitorGUI::cursor_leave_event()
00395 {
00396 if(canvas && canvas->get_canvas())
00397 return canvas->cursor_leave_event_base(canvas->get_canvas());
00398 return 0;
00399 }
00400
00401 int RecordMonitorGUI::cursor_enter_event()
00402 {
00403 if(canvas && canvas->get_canvas())
00404 return canvas->cursor_enter_event_base(canvas->get_canvas());
00405 return 0;
00406 }
00407
00408 int RecordMonitorGUI::button_release_event()
00409 {
00410 if(canvas && canvas->get_canvas())
00411 return canvas->button_release_event();
00412 return 0;
00413 }
00414
00415 int RecordMonitorGUI::cursor_motion_event()
00416 {
00417 SET_TRACE
00418 if(canvas && canvas->get_canvas())
00419 {
00420 SET_TRACE
00421 canvas->get_canvas()->unhide_cursor();
00422 SET_TRACE
00423 return canvas->cursor_motion_event();
00424 }
00425 return 0;
00426 }
00427
00428 int RecordMonitorGUI::keypress_event()
00429 {
00430 int result = 0;
00431 switch(get_keypress())
00432 {
00433 case LEFT:
00434 if(!ctrl_down())
00435 {
00436 record->record_gui->set_translation(--(record->video_x), record->video_y, record->video_zoom);
00437 }
00438 else
00439 {
00440 record->video_zoom -= 0.1;
00441 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
00442 }
00443 result = 1;
00444 break;
00445 case RIGHT:
00446 if(!ctrl_down())
00447 {
00448 record->record_gui->set_translation(++(record->video_x), record->video_y, record->video_zoom);
00449 }
00450 else
00451 {
00452 record->video_zoom += 0.1;
00453 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
00454 }
00455 result = 1;
00456 break;
00457 case UP:
00458 if(!ctrl_down())
00459 {
00460 record->record_gui->set_translation(record->video_x, --(record->video_y), record->video_zoom);
00461 }
00462 else
00463 {
00464 record->video_zoom -= 0.1;
00465 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
00466 }
00467 result = 1;
00468 break;
00469 case DOWN:
00470 if(!ctrl_down())
00471 {
00472 record->record_gui->set_translation(record->video_x, ++(record->video_y), record->video_zoom);
00473 }
00474 else
00475 {
00476 record->video_zoom += 0.1;
00477 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
00478 }
00479 result = 1;
00480 break;
00481 case 'w':
00482 close_event();
00483 break;
00484 default:
00485 result = canvas->keypress_event(this);
00486 #ifdef HAVE_FIREWIRE
00487 if(!result && avc1394_transport)
00488 result = avc1394_transport->keypress_event(get_keypress());
00489 #endif
00490 break;
00491 }
00492 return result;
00493 }
00494
00495
00496 int RecordMonitorGUI::translation_event()
00497 {
00498
00499 mwindow->session->rmonitor_x = get_x();
00500 mwindow->session->rmonitor_y = get_y();
00501 return 0;
00502 }
00503
00504 int RecordMonitorGUI::resize_event(int w, int h)
00505 {
00506 int do_channel = (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
00507 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
00508 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2 ||
00509 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
00510 int do_interlace = (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
00511 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
00512 int do_avc = 0;
00513 #ifdef HAVE_FIREWIRE
00514 do_avc = avc1394_transport ? 1 : 0;
00515 #endif
00516
00517 mwindow->session->rmonitor_x = get_x();
00518 mwindow->session->rmonitor_y = get_y();
00519 mwindow->session->rmonitor_w = w;
00520 mwindow->session->rmonitor_h = h;
00521
00522 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
00523 record->default_asset->video_data,
00524 do_channel,
00525 do_interlace,
00526 do_avc,
00527 record->default_asset->channels);
00528 mwindow->theme->draw_rmonitor_bg(this);
00529 flash();
00530
00531
00532
00533
00534 #ifdef HAVE_FIREWIRE
00535 if(avc1394_transport)
00536 {
00537 avc1394_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
00538 mwindow->theme->rmonitor_tx_y);
00539 }
00540 #endif
00541
00542 if(channel_picker) channel_picker->reposition();
00543 if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(),
00544 reverse_interlace->get_y());
00545 if(canvas && record->default_asset->video_data)
00546 {
00547 canvas->reposition_window(0,
00548 mwindow->theme->rmonitor_canvas_x,
00549 mwindow->theme->rmonitor_canvas_y,
00550 mwindow->theme->rmonitor_canvas_w,
00551 mwindow->theme->rmonitor_canvas_h);
00552 }
00553
00554 if(record->default_asset->audio_data)
00555 {
00556 meters->reposition_window(mwindow->theme->rmonitor_meter_x,
00557 mwindow->theme->rmonitor_meter_y,
00558 mwindow->theme->rmonitor_meter_h);
00559 }
00560
00561 set_title();
00562 BC_WindowBase::resize_event(w, h);
00563 flash();
00564 flush();
00565 return 1;
00566 }
00567
00568 int RecordMonitorGUI::set_title()
00569 {
00570 return 0;
00571 char string[1024];
00572 int scale;
00573
00574 scale = (int)(thread->get_scale(thread->record->video_window_w) * 100 + 0.5);
00575
00576 sprintf(string, PROGRAM_NAME ": Video in %d%%", scale);
00577 BC_Window::set_title(string);
00578 return 0;
00579 }
00580
00581 int RecordMonitorGUI::close_event()
00582 {
00583 thread->record->monitor_video = 0;
00584 thread->record->monitor_audio = 0;
00585 thread->record->video_window_open = 0;
00586 unlock_window();
00587
00588 record->record_gui->lock_window("RecordMonitorGUI::close_event");
00589 if(record->record_gui->monitor_video) record->record_gui->monitor_video->update(0);
00590 if(record->record_gui->monitor_audio) record->record_gui->monitor_audio->update(0);
00591 record->record_gui->flush();
00592 record->record_gui->unlock_window();
00593
00594
00595 lock_window("RecordMonitorGUI::close_event");
00596 hide_window();
00597 return 0;
00598 }
00599
00600 int RecordMonitorGUI::create_bitmap()
00601 {
00602 if(bitmap &&
00603 (bitmap->get_w() != get_w() ||
00604 bitmap->get_h() != thread->get_canvas_height()))
00605 {
00606 delete bitmap;
00607 bitmap = 0;
00608 }
00609
00610 if(!bitmap && canvas)
00611 {
00612
00613 }
00614 return 0;
00615 }
00616
00617 ReverseInterlace::ReverseInterlace(Record *record, int x, int y)
00618 : BC_CheckBox(x, y, record->reverse_interlace, _("Swap fields"))
00619 {
00620 this->record = record;
00621 }
00622
00623 ReverseInterlace::~ReverseInterlace()
00624 {
00625 }
00626
00627 int ReverseInterlace::handle_event()
00628 {
00629 record->reverse_interlace = get_value();
00630 return 0;
00631 }
00632
00633 RecordMonitorCanvas::RecordMonitorCanvas(MWindow *mwindow,
00634 RecordMonitorGUI *window,
00635 Record *record,
00636 int x,
00637 int y,
00638 int w,
00639 int h)
00640 : Canvas(mwindow,
00641 window,
00642 x,
00643 y,
00644 w,
00645 h,
00646 record->default_asset->width,
00647 record->default_asset->height,
00648 0,
00649 0,
00650 1)
00651 {
00652 this->window = window;
00653 this->mwindow = mwindow;
00654 this->record = record;
00655 printf("RecordMonitorCanvas::RecordMonitorCanvas 1 %d %d %d %d\n",
00656 x, y, w, h);
00657
00658 }
00659
00660 RecordMonitorCanvas::~RecordMonitorCanvas()
00661 {
00662 }
00663
00664 int RecordMonitorCanvas::get_output_w()
00665 {
00666 return record->default_asset->width;
00667 }
00668
00669 int RecordMonitorCanvas::get_output_h()
00670 {
00671 return record->default_asset->height;
00672 }
00673
00674
00675 int RecordMonitorCanvas::button_press_event()
00676 {
00677
00678 if(Canvas::button_press_event()) return 1;
00679
00680 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
00681 {
00682 window->current_operation = MONITOR_TRANSLATE;
00683 window->translate_x_origin = record->video_x;
00684 window->translate_y_origin = record->video_y;
00685 window->cursor_x_origin = get_cursor_x();
00686 window->cursor_y_origin = get_cursor_y();
00687 }
00688
00689 return 0;
00690 }
00691
00692 void RecordMonitorCanvas::zoom_resize_window(float percentage)
00693 {
00694 int canvas_w, canvas_h;
00695 calculate_sizes(mwindow->edl->get_aspect_ratio(),
00696 record->default_asset->width,
00697 record->default_asset->height,
00698 percentage,
00699 canvas_w,
00700 canvas_h);
00701 int new_w, new_h;
00702 new_w = canvas_w + (window->get_w() - mwindow->theme->rmonitor_canvas_w);
00703 new_h = canvas_h + (window->get_h() - mwindow->theme->rmonitor_canvas_h);
00704 window->resize_window(new_w, new_h);
00705 window->resize_event(new_w, new_h);
00706 }
00707
00708 int RecordMonitorCanvas::get_fullscreen()
00709 {
00710 return mwindow->session->rwindow_fullscreen;
00711 }
00712
00713 void RecordMonitorCanvas::set_fullscreen(int value)
00714 {
00715 mwindow->session->rwindow_fullscreen = value;
00716 }
00717
00718
00719 int RecordMonitorCanvas::button_release_event()
00720 {
00721 window->current_operation = MONITOR_NONE;
00722 return 0;
00723 }
00724
00725 int RecordMonitorCanvas::cursor_motion_event()
00726 {
00727 SET_TRACE
00728 if(window->current_operation == MONITOR_TRANSLATE)
00729 {
00730 SET_TRACE
00731 record->set_translation(
00732 get_cursor_x() - window->cursor_x_origin + window->translate_x_origin,
00733 get_cursor_y() - window->cursor_y_origin + window->translate_y_origin);
00734 SET_TRACE
00735 }
00736
00737 return 0;
00738 }
00739
00740 int RecordMonitorCanvas::cursor_enter_event()
00741 {
00742 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
00743 set_cursor(MOVE_CURSOR);
00744 return 0;
00745 }
00746
00747 void RecordMonitorCanvas::reset_translation()
00748 {
00749 record->set_translation(0, 0);
00750 }
00751
00752 int RecordMonitorCanvas::keypress_event()
00753 {
00754 int result = 0;
00755 switch(get_canvas() && get_canvas()->get_keypress())
00756 {
00757 case LEFT:
00758 record->set_translation(--record->video_x, record->video_y);
00759 break;
00760 case RIGHT:
00761 record->set_translation(++record->video_x, record->video_y);
00762 break;
00763 case UP:
00764 record->set_translation(record->video_x, --record->video_y);
00765 break;
00766 case DOWN:
00767 record->set_translation(record->video_x, ++record->video_y);
00768 break;
00769 }
00770 return result;
00771 }
00772
00773
00774 RecordMonitorFullsize::RecordMonitorFullsize(MWindow *mwindow,
00775 RecordMonitorGUI *window)
00776 : BC_MenuItem(_("Zoom 100%"))
00777 {
00778 this->mwindow = mwindow;
00779 this->window = window;
00780 }
00781 int RecordMonitorFullsize::handle_event()
00782 {
00783 return 1;
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 RecordMonitorThread::RecordMonitorThread(MWindow *mwindow,
00797 Record *record,
00798 RecordMonitor *record_monitor)
00799 : Thread(1, 0, 0)
00800 {
00801 this->mwindow = mwindow;
00802 this->record_monitor = record_monitor;
00803 this->record = record;
00804 reset_parameters();
00805 output_lock = new Condition(1, "RecordMonitor::output_lock");
00806 input_lock = new Condition(1, "RecordMonitor::input_lock");
00807 }
00808
00809
00810 void RecordMonitorThread::reset_parameters()
00811 {
00812 input_frame = 0;
00813 output_frame = 0;
00814 shared_data = 0;
00815 jpeg_engine = 0;
00816 dv_engine = 0;
00817 ready = 0;
00818 }
00819
00820
00821 RecordMonitorThread::~RecordMonitorThread()
00822 {
00823 if(input_frame && !shared_data) delete input_frame;
00824 delete output_lock;
00825 delete input_lock;
00826 }
00827
00828 void RecordMonitorThread::init_output_format()
00829 {
00830 long offset;
00831
00832
00833 switch(mwindow->edl->session->vconfig_in->driver)
00834 {
00835 case SCREENCAPTURE:
00836 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
00837 break;
00838
00839
00840 case CAPTURE_BUZ:
00841 case VIDEO4LINUX2JPEG:
00842 jpeg_engine = new RecVideoMJPGThread(record, this);
00843 jpeg_engine->start_rendering();
00844 output_colormodel = BC_YUV422P;
00845 break;
00846
00847 case CAPTURE_FIREWIRE:
00848 case CAPTURE_IEC61883:
00849 dv_engine = new RecVideoDVThread(record, this);
00850 dv_engine->start_rendering();
00851 output_colormodel = BC_YUV422P;
00852 break;
00853
00854 case VIDEO4LINUX:
00855 case VIDEO4LINUX2:
00856 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
00857
00858 break;
00859 }
00860 }
00861
00862 int RecordMonitorThread::start_playback()
00863 {
00864 ready = 1;
00865 done = 0;
00866 output_lock->lock("RecordMonitorThread::start_playback");
00867 Thread::start();
00868 return 0;
00869 }
00870
00871 int RecordMonitorThread::stop_playback()
00872 {
00873 done = 1;
00874 output_lock->unlock();
00875 Thread::join();
00876
00877
00878 switch(mwindow->edl->session->vconfig_in->driver)
00879 {
00880 case CAPTURE_BUZ:
00881 case VIDEO4LINUX2JPEG:
00882 if(jpeg_engine)
00883 {
00884 jpeg_engine->stop_rendering();
00885 delete jpeg_engine;
00886 }
00887 break;
00888
00889 case CAPTURE_FIREWIRE:
00890 case CAPTURE_IEC61883:
00891 if(dv_engine)
00892 {
00893 dv_engine->stop_rendering();
00894 delete dv_engine;
00895 }
00896 break;
00897 }
00898
00899
00900 return 0;
00901 }
00902
00903 int RecordMonitorThread::write_frame(VFrame *new_frame)
00904 {
00905 if(ready)
00906 {
00907 ready = 0;
00908 shared_data = (new_frame->get_color_model() != BC_COMPRESSED);
00909
00910
00911
00912
00913
00914 if(!output_frame) init_output_format();
00915 if(!shared_data)
00916 {
00917 if(!input_frame) input_frame = new VFrame;
00918 input_frame->allocate_compressed_data(new_frame->get_compressed_size());
00919 memcpy(input_frame->get_data(),
00920 new_frame->get_data(),
00921 new_frame->get_compressed_size());
00922 input_frame->set_compressed_size(new_frame->get_compressed_size());
00923 input_frame->set_field2_offset(new_frame->get_field2_offset());
00924 }
00925 else
00926 {
00927 input_lock->lock("RecordMonitorThread::write_frame");
00928 input_frame = new_frame;
00929 }
00930 output_lock->unlock();
00931 }
00932 return 0;
00933 }
00934
00935 int RecordMonitorThread::render_jpeg()
00936 {
00937
00938 jpeg_engine->render_frame(input_frame, input_frame->get_compressed_size());
00939
00940 return 0;
00941 }
00942
00943 int RecordMonitorThread::render_dv()
00944 {
00945 dv_engine->render_frame(input_frame, input_frame->get_compressed_size());
00946 return 0;
00947 }
00948
00949 void RecordMonitorThread::render_uncompressed()
00950 {
00951 output_frame->copy_from(input_frame);
00952 }
00953
00954 void RecordMonitorThread::show_output_frame()
00955 {
00956 record_monitor->device->write_buffer(output_frame, record->edl);
00957 }
00958
00959 void RecordMonitorThread::unlock_input()
00960 {
00961 if(shared_data) input_lock->unlock();
00962 }
00963
00964 int RecordMonitorThread::render_frame()
00965 {
00966 switch(mwindow->edl->session->vconfig_in->driver)
00967 {
00968 case CAPTURE_BUZ:
00969 case VIDEO4LINUX2JPEG:
00970 render_jpeg();
00971 break;
00972
00973 case CAPTURE_FIREWIRE:
00974 case CAPTURE_IEC61883:
00975 render_dv();
00976 break;
00977
00978 default:
00979 render_uncompressed();
00980 break;
00981 }
00982
00983 return 0;
00984 }
00985
00986 void RecordMonitorThread::new_output_frame()
00987 {
00988 long offset;
00989 record_monitor->device->new_output_buffer(&output_frame, output_colormodel);
00990 }
00991
00992 void RecordMonitorThread::run()
00993 {
00994
00995 while(!done)
00996 {
00997
00998 SET_TRACE
00999 output_lock->lock("RecordMonitorThread::run");
01000
01001 if(done)
01002 {
01003 unlock_input();
01004 return;
01005 }
01006
01007 SET_TRACE
01008 new_output_frame();
01009 SET_TRACE
01010 render_frame();
01011 SET_TRACE
01012 show_output_frame();
01013 SET_TRACE
01014 unlock_input();
01015
01016 ready = 1;
01017 }
01018 }
01019
01020
01021
01022 RecVideoMJPGThread::RecVideoMJPGThread(Record *record, RecordMonitorThread *thread)
01023 {
01024 this->record = record;
01025 this->thread = thread;
01026 mjpeg = 0;
01027 }
01028
01029 RecVideoMJPGThread::~RecVideoMJPGThread()
01030 {
01031 }
01032
01033 int RecVideoMJPGThread::start_rendering()
01034 {
01035 mjpeg = mjpeg_new(record->default_asset->width,
01036 record->default_asset->height,
01037 2);
01038
01039 return 0;
01040 }
01041
01042 int RecVideoMJPGThread::stop_rendering()
01043 {
01044
01045 if(mjpeg) mjpeg_delete(mjpeg);
01046
01047 return 0;
01048 }
01049
01050 int RecVideoMJPGThread::render_frame(VFrame *frame, long size)
01051 {
01052
01053
01054
01055
01056
01057
01058
01059 mjpeg_decompress(mjpeg,
01060 frame->get_data(),
01061 frame->get_compressed_size(),
01062 frame->get_field2_offset(),
01063 thread->output_frame->get_rows(),
01064 thread->output_frame->get_y(),
01065 thread->output_frame->get_u(),
01066 thread->output_frame->get_v(),
01067 thread->output_frame->get_color_model(),
01068 record->mwindow->preferences->processors);
01069 return 0;
01070 }
01071
01072
01073
01074
01075 RecVideoDVThread::RecVideoDVThread(Record *record, RecordMonitorThread *thread)
01076 {
01077 this->record = record;
01078 this->thread = thread;
01079 dv = 0;
01080 }
01081
01082 RecVideoDVThread::~RecVideoDVThread()
01083 {
01084 }
01085
01086
01087 int RecVideoDVThread::start_rendering()
01088 {
01089 dv = dv_new();
01090 return 0;
01091 }
01092
01093 int RecVideoDVThread::stop_rendering()
01094 {
01095 if(dv) dv_delete(((dv_t*)dv));
01096 return 0;
01097 }
01098
01099 int RecVideoDVThread::render_frame(VFrame *frame, long size)
01100 {
01101 unsigned char *yuv_planes[3];
01102 yuv_planes[0] = thread->output_frame->get_y();
01103 yuv_planes[1] = thread->output_frame->get_u();
01104 yuv_planes[2] = thread->output_frame->get_v();
01105 dv_read_video(((dv_t*)dv),
01106 yuv_planes,
01107 frame->get_data(),
01108 frame->get_compressed_size(),
01109 thread->output_frame->get_color_model());
01110
01111 return 0;
01112 }