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