3 #include "channelpicker.h"
8 #include "edlsession.h"
11 #include "meterpanel.h"
13 #include "playbackconfig.h"
14 #include "preferences.h"
16 #include "recordconfig.h"
17 #include "recordgui.h"
18 #include "recordtransport.h"
19 #include "recordmonitor.h"
20 #include "mainsession.h"
22 #include "videodevice.inc"
24 #include "videodevice.h"
27 RecordMonitor::RecordMonitor(MWindow *mwindow, Record *record)
30 this->mwindow = mwindow;
31 this->record = record;
37 RecordMonitor::~RecordMonitor()
41 thread->stop_playback();
54 int RecordMonitor::create_objects()
57 mwindow->session->rwindow_fullscreen = 0;
59 if(!record->default_asset->video_data)
60 min_w = MeterPanel::get_meters_width(
61 record->default_asset->channels, 1);
63 window = new RecordMonitorGUI(mwindow,
68 window->create_objects();
71 if(record->default_asset->video_data)
73 // Configure the output for record monitoring
74 VideoOutConfig config;
76 device = new VideoDevice;
81 // Override default device for X11 drivers
82 if(mwindow->edl->session->playback_config->vconfig->driver ==
83 PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV;
84 config.x11_use_fields = 0;
88 device->open_output(&config,
89 record->default_asset->frame_rate,
90 record->default_asset->width,
91 record->default_asset->height,
96 thread = new RecordMonitorThread(mwindow, record, this);
98 thread->start_playback();
108 void RecordMonitor::run()
110 window->run_window();
114 int RecordMonitor::close_threads()
116 if(window->channel_picker) window->channel_picker->close_threads();
119 int RecordMonitor::update(VFrame *vframe)
121 return thread->write_frame(vframe);
124 void RecordMonitor::update_channel(char *text)
126 if(window->channel_picker)
127 window->channel_picker->channel_text->update(text);
130 int RecordMonitor::get_mbuttons_height()
132 return RECBUTTON_HEIGHT;
135 int RecordMonitor::fix_size(int &w, int &h, int width_given, float aspect_ratio)
138 h = (int)((float)width_given / aspect_ratio);
141 float RecordMonitor::get_scale(int w)
143 if(mwindow->edl->get_aspect_ratio() >
144 (float)record->frame_w / record->frame_h)
147 ((float)record->frame_h *
148 mwindow->edl->get_aspect_ratio());
152 return (float)w / record->frame_w;
156 int RecordMonitor::get_canvas_height()
158 return window->get_h() - get_mbuttons_height();
161 int RecordMonitor::get_channel_x()
167 int RecordMonitor::get_channel_y()
181 RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow,
183 RecordMonitor *thread,
185 : BC_Window(PROGRAM_NAME ": Video in",
186 mwindow->session->rmonitor_x,
187 mwindow->session->rmonitor_y,
188 mwindow->session->rmonitor_w,
189 mwindow->session->rmonitor_h,
196 //printf("%d %d\n", mwindow->session->rmonitor_w, mwindow->theme->rmonitor_meter_x);
197 this->mwindow = mwindow;
198 this->thread = thread;
199 this->record = record;
202 avc1394_transport = 0;
203 avc1394transport_title = 0;
204 avc1394transport_timecode = 0;
205 avc1394transport_thread = 0;
209 reverse_interlace = 0;
212 current_operation = MONITOR_NONE;
215 RecordMonitorGUI::~RecordMonitorGUI()
218 if(bitmap) delete bitmap;
219 if(channel_picker) delete channel_picker;
221 if(avc1394transport_thread)
222 delete avc1394transport_thread;
227 if(avc1394_transport)
229 delete avc1394_transport;
231 if(avc1394transport_title)
232 delete avc1394transport_title;
236 int RecordMonitorGUI::create_objects()
238 // y offset for video canvas if we have the transport controls
239 int do_channel = (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
240 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
241 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2 ||
242 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
243 int do_interlace = (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
244 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
245 int background_done = 0;
247 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
248 record->default_asset->video_data,
252 record->default_asset->channels);
259 if(record->default_asset->video_data)
261 int driver = mwindow->edl->session->vconfig_in->driver;
264 if(driver == CAPTURE_FIREWIRE ||
265 driver == CAPTURE_IEC61883)
267 avc = new AVC1394Control;
270 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
271 record->default_asset->video_data,
275 record->default_asset->channels);
276 mwindow->theme->draw_rmonitor_bg(this);
279 avc1394_transport = new AVC1394Transport(mwindow,
282 mwindow->theme->rmonitor_tx_x,
283 mwindow->theme->rmonitor_tx_y);
284 avc1394_transport->create_objects();
286 add_subwindow(avc1394transport_timecode =
287 new BC_Title(avc1394_transport->x_end,
288 mwindow->theme->rmonitor_tx_y + 10,
293 avc1394transport_thread =
294 new AVC1394TransportThread(avc1394transport_timecode,
297 avc1394transport_thread->start();
306 mwindow->theme->draw_rmonitor_bg(this);
310 canvas = new RecordMonitorCanvas(mwindow,
313 mwindow->theme->rmonitor_canvas_x,
314 mwindow->theme->rmonitor_canvas_y,
315 mwindow->theme->rmonitor_canvas_w,
316 mwindow->theme->rmonitor_canvas_h);
317 canvas->create_objects(0);
319 if(driver == VIDEO4LINUX ||
320 driver == CAPTURE_BUZ ||
321 driver == VIDEO4LINUX2 ||
322 driver == VIDEO4LINUX2JPEG)
324 channel_picker = new ChannelPicker(mwindow,
328 mwindow->theme->rmonitor_channel_x,
329 mwindow->theme->rmonitor_channel_y);
330 channel_picker->create_objects();
333 if(driver == CAPTURE_BUZ ||
334 driver == VIDEO4LINUX2JPEG)
336 add_subwindow(reverse_interlace = new ReverseInterlace(record,
337 mwindow->theme->rmonitor_interlace_x,
338 mwindow->theme->rmonitor_interlace_y));
341 add_subwindow(monitor_menu = new BC_PopupMenu(0,
346 monitor_menu->add_item(new RecordMonitorFullsize(mwindow,
353 mwindow->theme->draw_rmonitor_bg(this);
357 if(record->default_asset->audio_data)
359 meters = new MeterPanel(mwindow,
361 mwindow->theme->rmonitor_meter_x,
362 mwindow->theme->rmonitor_meter_y,
363 mwindow->theme->rmonitor_meter_h,
364 record->default_asset->channels,
367 meters->create_objects();
372 int RecordMonitorGUI::button_press_event()
374 if(mwindow->session->rwindow_fullscreen && canvas && canvas->get_canvas())
375 return canvas->button_press_event_base(canvas->get_canvas());
377 if(get_buttonpress() == 2)
383 if(get_buttonpress() == 3)
385 monitor_menu->activate_menu();
391 int RecordMonitorGUI::cursor_leave_event()
393 if(canvas && canvas->get_canvas())
394 return canvas->cursor_leave_event_base(canvas->get_canvas());
398 int RecordMonitorGUI::cursor_enter_event()
400 if(canvas && canvas->get_canvas())
401 return canvas->cursor_enter_event_base(canvas->get_canvas());
405 int RecordMonitorGUI::button_release_event()
407 if(canvas && canvas->get_canvas())
408 return canvas->button_release_event();
412 int RecordMonitorGUI::cursor_motion_event()
415 if(canvas && canvas->get_canvas())
418 canvas->get_canvas()->unhide_cursor();
420 return canvas->cursor_motion_event();
425 int RecordMonitorGUI::keypress_event()
428 switch(get_keypress())
433 record->record_gui->set_translation(--(record->video_x), record->video_y, record->video_zoom);
437 record->video_zoom -= 0.1;
438 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
445 record->record_gui->set_translation(++(record->video_x), record->video_y, record->video_zoom);
449 record->video_zoom += 0.1;
450 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
457 record->record_gui->set_translation(record->video_x, --(record->video_y), record->video_zoom);
461 record->video_zoom -= 0.1;
462 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
469 record->record_gui->set_translation(record->video_x, ++(record->video_y), record->video_zoom);
473 record->video_zoom += 0.1;
474 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
482 result = canvas->keypress_event(this);
484 if(!result && avc1394_transport)
485 result = avc1394_transport->keypress_event(get_keypress());
493 int RecordMonitorGUI::translation_event()
495 //printf("MWindowGUI::translation_event 1 %d %d\n", get_x(), get_y());
496 mwindow->session->rmonitor_x = get_x();
497 mwindow->session->rmonitor_y = get_y();
501 int RecordMonitorGUI::resize_event(int w, int h)
503 int do_channel = (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
504 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
505 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2 ||
506 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
507 int do_interlace = (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
508 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG);
511 do_avc = avc1394_transport ? 1 : 0;
514 mwindow->session->rmonitor_x = get_x();
515 mwindow->session->rmonitor_y = get_y();
516 mwindow->session->rmonitor_w = w;
517 mwindow->session->rmonitor_h = h;
519 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
520 record->default_asset->video_data,
524 record->default_asset->channels);
525 mwindow->theme->draw_rmonitor_bg(this);
529 // record_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
530 // mwindow->theme->rmonitor_tx_y);
532 if(avc1394_transport)
534 avc1394_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
535 mwindow->theme->rmonitor_tx_y);
539 if(channel_picker) channel_picker->reposition();
540 if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(),
541 reverse_interlace->get_y());
542 if(canvas && record->default_asset->video_data)
544 canvas->reposition_window(0,
545 mwindow->theme->rmonitor_canvas_x,
546 mwindow->theme->rmonitor_canvas_y,
547 mwindow->theme->rmonitor_canvas_w,
548 mwindow->theme->rmonitor_canvas_h);
551 if(record->default_asset->audio_data)
553 meters->reposition_window(mwindow->theme->rmonitor_meter_x,
554 mwindow->theme->rmonitor_meter_y,
555 mwindow->theme->rmonitor_meter_h);
559 BC_WindowBase::resize_event(w, h);
565 int RecordMonitorGUI::set_title()
571 scale = (int)(thread->get_scale(thread->record->video_window_w) * 100 + 0.5);
573 sprintf(string, PROGRAM_NAME ": Video in %d%%", scale);
574 BC_Window::set_title(string);
578 int RecordMonitorGUI::close_event()
580 thread->record->monitor_video = 0;
581 thread->record->monitor_audio = 0;
582 thread->record->video_window_open = 0;
585 record->record_gui->lock_window("RecordMonitorGUI::close_event");
586 if(record->record_gui->monitor_video) record->record_gui->monitor_video->update(0);
587 if(record->record_gui->monitor_audio) record->record_gui->monitor_audio->update(0);
588 record->record_gui->flush();
589 record->record_gui->unlock_window();
592 lock_window("RecordMonitorGUI::close_event");
597 int RecordMonitorGUI::create_bitmap()
600 (bitmap->get_w() != get_w() ||
601 bitmap->get_h() != thread->get_canvas_height()))
607 if(!bitmap && canvas)
609 // bitmap = canvas->new_bitmap(get_w(), thread->get_canvas_height());
614 ReverseInterlace::ReverseInterlace(Record *record, int x, int y)
615 : BC_CheckBox(x, y, record->reverse_interlace, _("Swap fields"))
617 this->record = record;
620 ReverseInterlace::~ReverseInterlace()
624 int ReverseInterlace::handle_event()
626 record->reverse_interlace = get_value();
630 RecordMonitorCanvas::RecordMonitorCanvas(MWindow *mwindow,
631 RecordMonitorGUI *window,
643 record->default_asset->width,
644 record->default_asset->height,
649 this->window = window;
650 this->mwindow = mwindow;
651 this->record = record;
652 printf("RecordMonitorCanvas::RecordMonitorCanvas 1 %d %d %d %d\n",
654 //printf("RecordMonitorCanvas::RecordMonitorCanvas 2\n");
657 RecordMonitorCanvas::~RecordMonitorCanvas()
661 int RecordMonitorCanvas::get_output_w()
663 return record->default_asset->width;
666 int RecordMonitorCanvas::get_output_h()
668 return record->default_asset->height;
672 int RecordMonitorCanvas::button_press_event()
675 if(Canvas::button_press_event()) return 1;
677 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
679 window->current_operation = MONITOR_TRANSLATE;
680 window->translate_x_origin = record->video_x;
681 window->translate_y_origin = record->video_y;
682 window->cursor_x_origin = get_cursor_x();
683 window->cursor_y_origin = get_cursor_y();
689 void RecordMonitorCanvas::zoom_resize_window(float percentage)
691 int canvas_w, canvas_h;
692 calculate_sizes(mwindow->edl->get_aspect_ratio(),
693 record->default_asset->width,
694 record->default_asset->height,
699 new_w = canvas_w + (window->get_w() - mwindow->theme->rmonitor_canvas_w);
700 new_h = canvas_h + (window->get_h() - mwindow->theme->rmonitor_canvas_h);
701 window->resize_window(new_w, new_h);
702 window->resize_event(new_w, new_h);
705 int RecordMonitorCanvas::get_fullscreen()
707 return mwindow->session->rwindow_fullscreen;
710 void RecordMonitorCanvas::set_fullscreen(int value)
712 mwindow->session->rwindow_fullscreen = value;
716 int RecordMonitorCanvas::button_release_event()
718 window->current_operation = MONITOR_NONE;
722 int RecordMonitorCanvas::cursor_motion_event()
725 if(window->current_operation == MONITOR_TRANSLATE)
728 record->set_translation(
729 get_cursor_x() - window->cursor_x_origin + window->translate_x_origin,
730 get_cursor_y() - window->cursor_y_origin + window->translate_y_origin);
737 int RecordMonitorCanvas::cursor_enter_event()
739 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
740 set_cursor(MOVE_CURSOR);
744 void RecordMonitorCanvas::reset_translation()
746 record->set_translation(0, 0);
749 int RecordMonitorCanvas::keypress_event()
752 switch(get_canvas() && get_canvas()->get_keypress())
755 record->set_translation(--record->video_x, record->video_y);
758 record->set_translation(++record->video_x, record->video_y);
761 record->set_translation(record->video_x, --record->video_y);
764 record->set_translation(record->video_x, ++record->video_y);
771 RecordMonitorFullsize::RecordMonitorFullsize(MWindow *mwindow,
772 RecordMonitorGUI *window)
773 : BC_MenuItem(_("Zoom 100%"))
775 this->mwindow = mwindow;
776 this->window = window;
778 int RecordMonitorFullsize::handle_event()
790 // ================================== slippery playback ============================
793 RecordMonitorThread::RecordMonitorThread(MWindow *mwindow,
795 RecordMonitor *record_monitor)
798 this->mwindow = mwindow;
799 this->record_monitor = record_monitor;
800 this->record = record;
802 output_lock = new Condition(1, "RecordMonitor::output_lock");
803 input_lock = new Condition(1, "RecordMonitor::input_lock");
807 void RecordMonitorThread::reset_parameters()
818 RecordMonitorThread::~RecordMonitorThread()
820 if(input_frame && !shared_data) delete input_frame;
825 void RecordMonitorThread::init_output_format()
829 //printf("RecordMonitorThread::init_output_format 1\n");
830 switch(mwindow->edl->session->vconfig_in->driver)
833 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
838 case VIDEO4LINUX2JPEG:
839 jpeg_engine = new RecVideoMJPGThread(record, this);
840 jpeg_engine->start_rendering();
841 output_colormodel = BC_YUV422P;
844 case CAPTURE_FIREWIRE:
845 case CAPTURE_IEC61883:
846 dv_engine = new RecVideoDVThread(record, this);
847 dv_engine->start_rendering();
848 output_colormodel = BC_YUV422P;
853 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
854 //printf("RecordMonitorThread::init_output_format 2 %d\n", output_colormodel);
859 int RecordMonitorThread::start_playback()
863 output_lock->lock("RecordMonitorThread::start_playback");
868 int RecordMonitorThread::stop_playback()
871 output_lock->unlock();
873 //printf("RecordMonitorThread::stop_playback 1\n");
875 switch(mwindow->edl->session->vconfig_in->driver)
878 case VIDEO4LINUX2JPEG:
881 jpeg_engine->stop_rendering();
886 case CAPTURE_FIREWIRE:
887 case CAPTURE_IEC61883:
890 dv_engine->stop_rendering();
895 //printf("RecordMonitorThread::stop_playback 4\n");
900 int RecordMonitorThread::write_frame(VFrame *new_frame)
905 shared_data = (new_frame->get_color_model() != BC_COMPRESSED);
908 // Need to wait until after Record creates the input device before starting monitor
909 // because the input device deterimes the output format.
911 if(!output_frame[0]) init_output_format();
914 if(!input_frame) input_frame = new VFrame;
915 input_frame->allocate_compressed_data(new_frame->get_compressed_size());
916 memcpy(input_frame->get_data(),
917 new_frame->get_data(),
918 new_frame->get_compressed_size());
919 input_frame->set_compressed_size(new_frame->get_compressed_size());
920 input_frame->set_field2_offset(new_frame->get_field2_offset());
924 input_lock->lock("RecordMonitorThread::write_frame");
925 input_frame = new_frame;
927 output_lock->unlock();
932 int RecordMonitorThread::render_jpeg()
934 //printf("RecordMonitorThread::render_jpeg 1\n");
935 jpeg_engine->render_frame(input_frame, input_frame->get_compressed_size());
936 //printf("RecordMonitorThread::render_jpeg 2\n");
940 int RecordMonitorThread::render_dv()
942 dv_engine->render_frame(input_frame, input_frame->get_compressed_size());
946 void RecordMonitorThread::render_uncompressed()
948 output_frame[0]->copy_from(input_frame);
951 void RecordMonitorThread::show_output_frame()
953 record_monitor->device->write_buffer(output_frame, record->edl);
956 void RecordMonitorThread::unlock_input()
958 if(shared_data) input_lock->unlock();
961 int RecordMonitorThread::render_frame()
963 switch(mwindow->edl->session->vconfig_in->driver)
966 case VIDEO4LINUX2JPEG:
970 case CAPTURE_FIREWIRE:
971 case CAPTURE_IEC61883:
976 render_uncompressed();
983 void RecordMonitorThread::new_output_frame()
986 record_monitor->device->new_output_buffers(output_frame, output_colormodel);
989 void RecordMonitorThread::run()
991 //printf("RecordMonitorThread::run 1 %d\n", getpid());
994 // Wait for next frame
996 output_lock->lock("RecordMonitorThread::run");
1009 show_output_frame();
1019 RecVideoMJPGThread::RecVideoMJPGThread(Record *record, RecordMonitorThread *thread)
1021 this->record = record;
1022 this->thread = thread;
1026 RecVideoMJPGThread::~RecVideoMJPGThread()
1030 int RecVideoMJPGThread::start_rendering()
1032 mjpeg = mjpeg_new(record->default_asset->width,
1033 record->default_asset->height,
1035 //printf("RecVideoMJPGThread::start_rendering 1 %p\n", mjpeg);
1039 int RecVideoMJPGThread::stop_rendering()
1041 //printf("RecVideoMJPGThread::stop_rendering 1 %p\n", mjpeg);
1042 if(mjpeg) mjpeg_delete(mjpeg);
1043 //printf("RecVideoMJPGThread::stop_rendering 2\n");
1047 int RecVideoMJPGThread::render_frame(VFrame *frame, long size)
1049 // printf("RecVideoMJPGThread::render_frame %d %02x%02x %02x%02x\n",
1050 // frame->get_field2_offset(),
1051 // frame->get_data()[0],
1052 // frame->get_data()[1],
1053 // frame->get_data()[frame->get_field2_offset()],
1054 // frame->get_data()[frame->get_field2_offset() + 1]);
1055 //frame->set_field2_offset(0);
1056 mjpeg_decompress(mjpeg,
1058 frame->get_compressed_size(),
1059 frame->get_field2_offset(),
1060 thread->output_frame[0]->get_rows(),
1061 thread->output_frame[0]->get_y(),
1062 thread->output_frame[0]->get_u(),
1063 thread->output_frame[0]->get_v(),
1064 thread->output_frame[0]->get_color_model(),
1065 record->mwindow->preferences->processors);
1072 RecVideoDVThread::RecVideoDVThread(Record *record, RecordMonitorThread *thread)
1074 this->record = record;
1075 this->thread = thread;
1079 RecVideoDVThread::~RecVideoDVThread()
1084 int RecVideoDVThread::start_rendering()
1090 int RecVideoDVThread::stop_rendering()
1092 if(dv) dv_delete(((dv_t*)dv));
1096 int RecVideoDVThread::render_frame(VFrame *frame, long size)
1098 unsigned char *yuv_planes[3];
1099 yuv_planes[0] = thread->output_frame[0]->get_y();
1100 yuv_planes[1] = thread->output_frame[0]->get_u();
1101 yuv_planes[2] = thread->output_frame[0]->get_v();
1102 dv_read_video(((dv_t*)dv),
1105 frame->get_compressed_size(),
1106 thread->output_frame[0]->get_color_model());