2 #include "channelpicker.h"
6 #include "edlsession.h"
8 #include "meterpanel.h"
10 #include "playbackconfig.h"
11 #include "preferences.h"
13 #include "recordconfig.h"
14 #include "recordgui.h"
15 #include "recordtransport.h"
16 #include "recordmonitor.h"
17 #include "mainsession.h"
19 #include "videodevice.inc"
21 #include "videodevice.h"
25 #define _(String) gettext(String)
26 #define gettext_noop(String) String
27 #define N_(String) gettext_noop (String)
29 RecordMonitor::RecordMonitor(MWindow *mwindow, Record *record)
32 this->mwindow = mwindow;
33 this->record = record;
39 RecordMonitor::~RecordMonitor()
41 //printf("RecordMonitor::~RecordMonitor 1\n");
44 thread->stop_playback();
47 //printf("RecordMonitor::~RecordMonitor 1\n");
49 //printf("RecordMonitor::~RecordMonitor 1\n");
51 //printf("RecordMonitor::~RecordMonitor 1\n");
57 //printf("RecordMonitor::~RecordMonitor 1\n");
59 //printf("RecordMonitor::~RecordMonitor 2\n");
62 int RecordMonitor::create_objects()
64 //printf("RecordMonitor::create_objects 1\n");
65 window = new RecordMonitorGUI(mwindow,
68 //printf("RecordMonitor::create_objects 2\n");
69 window->create_objects();
70 //printf("RecordMonitor::create_objects 3\n");
72 if(record->default_asset->video_data)
74 // Configure the output for record monitoring
75 VideoOutConfig config(PLAYBACK_LOCALHOST, 0);
76 device = new VideoDevice;
77 //printf("RecordMonitor::create_objects 4\n");
81 // Override default device for X11 drivers
82 if(mwindow->edl->session->playback_config[PLAYBACK_LOCALHOST].values[0]->vconfig->driver ==
83 PLAYBACK_X11_XV) config.driver = PLAYBACK_X11_XV;
84 config.x11_use_fields = 0;
87 device->open_output(&config,
88 record->default_asset->frame_rate,
89 record->default_asset->width,
90 record->default_asset->height,
93 //printf("RecordMonitor::create_objects 5\n");
95 thread = new RecordMonitorThread(mwindow, record, this);
96 //printf("RecordMonitor::create_objects 6\n");
97 thread->start_playback();
105 void RecordMonitor::run()
107 window->run_window();
111 int RecordMonitor::close_threads()
113 if(window->channel_picker) window->channel_picker->close_threads();
116 int RecordMonitor::update(VFrame *vframe)
118 return thread->write_frame(vframe);
121 void RecordMonitor::update_channel(char *text)
123 if(window->channel_picker)
124 window->channel_picker->channel_text->update(text);
127 int RecordMonitor::get_mbuttons_height()
129 return RECBUTTON_HEIGHT;
132 int RecordMonitor::fix_size(int &w, int &h, int width_given, float aspect_ratio)
135 h = (int)((float)width_given / aspect_ratio);
138 float RecordMonitor::get_scale(int w)
140 if(mwindow->edl->get_aspect_ratio() >
141 (float)record->frame_w / record->frame_h)
144 ((float)record->frame_h *
145 mwindow->edl->get_aspect_ratio());
149 return (float)w / record->frame_w;
153 int RecordMonitor::get_canvas_height()
155 return window->get_h() - get_mbuttons_height();
158 int RecordMonitor::get_channel_x()
164 int RecordMonitor::get_channel_y()
178 RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow,
180 RecordMonitor *thread)
181 : BC_Window(PROGRAM_NAME ": Video in",
182 mwindow->session->rmonitor_x,
183 mwindow->session->rmonitor_y,
184 mwindow->session->rmonitor_w,
185 mwindow->session->rmonitor_h,
192 this->mwindow = mwindow;
193 this->thread = thread;
194 this->record = record;
197 reverse_interlace = 0;
200 current_operation = MONITOR_NONE;
203 RecordMonitorGUI::~RecordMonitorGUI()
205 if(bitmap) delete bitmap;
206 if(channel_picker) delete channel_picker;
209 int RecordMonitorGUI::create_objects()
211 //printf("RecordMonitorGUI::create_objects 1\n");
212 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
213 record->default_asset->video_data,
214 (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
215 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ),
216 (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ));
217 mwindow->theme->draw_rmonitor_bg(this);
218 //printf("RecordMonitorGUI::create_objects 1\n");
220 // record_transport = new RecordTransport(mwindow,
223 // mwindow->theme->rmonitor_tx_x,
224 // mwindow->theme->rmonitor_tx_y);
225 // record_transport->create_objects();
226 //printf("RecordMonitorGUI::create_objects 1\n");
228 if(record->default_asset->video_data)
230 canvas = new RecordMonitorCanvas(mwindow,
233 mwindow->theme->rmonitor_canvas_x,
234 mwindow->theme->rmonitor_canvas_y,
235 mwindow->theme->rmonitor_canvas_w,
236 mwindow->theme->rmonitor_canvas_h);
237 canvas->create_objects(0);
238 //printf("RecordMonitorGUI::create_objects 1\n");
240 if(mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
241 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ)
243 channel_picker = new ChannelPicker(mwindow,
246 record->current_channeldb(),
247 mwindow->theme->rmonitor_channel_x,
248 mwindow->theme->rmonitor_channel_y);
249 channel_picker->create_objects();
251 //printf("RecordMonitorGUI::create_objects 1\n");
253 if(mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ)
255 add_subwindow(reverse_interlace = new ReverseInterlace(record,
256 mwindow->theme->rmonitor_interlace_x,
257 mwindow->theme->rmonitor_interlace_y));
259 //printf("RecordMonitorGUI::create_objects 1\n");
261 add_subwindow(monitor_menu = new BC_PopupMenu(0,
266 monitor_menu->add_item(new RecordMonitorFullsize(mwindow,
268 //printf("RecordMonitorGUI::create_objects 1\n");
270 //printf("RecordMonitorGUI::create_objects 1\n");
272 if(record->default_asset->audio_data)
274 meters = new MeterPanel(mwindow,
276 mwindow->theme->rmonitor_meter_x,
277 mwindow->theme->rmonitor_meter_y,
278 mwindow->theme->rmonitor_meter_h,
279 record->default_asset->channels,
281 meters->create_objects();
283 //printf("RecordMonitorGUI::create_objects 2\n");
287 int RecordMonitorGUI::button_press()
289 if(get_buttonpress() == 2)
295 if(get_button_down() == 3)
297 monitor_menu->activate_menu();
303 int RecordMonitorGUI::button_release()
308 int RecordMonitorGUI::get_virtual_center()
312 int RecordMonitorGUI::cursor_motion()
317 int RecordMonitorGUI::keypress_event()
320 switch(get_keypress())
325 record->record_gui->set_translation(--(record->video_x), record->video_y, record->video_zoom);
329 record->video_zoom -= 0.1;
330 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
337 record->record_gui->set_translation(++(record->video_x), record->video_y, record->video_zoom);
341 record->video_zoom += 0.1;
342 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
349 record->record_gui->set_translation(record->video_x, --(record->video_y), record->video_zoom);
353 record->video_zoom -= 0.1;
354 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
361 record->record_gui->set_translation(record->video_x, ++(record->video_y), record->video_zoom);
365 record->video_zoom += 0.1;
366 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
374 // result = record_transport->keypress_event();
381 int RecordMonitorGUI::translation_event()
383 //printf("MWindowGUI::translation_event 1 %d %d\n", get_x(), get_y());
384 mwindow->session->rmonitor_x = get_x();
385 mwindow->session->rmonitor_y = get_y();
389 int RecordMonitorGUI::resize_event(int w, int h)
391 //printf("RecordMonitorGUI::resize_event %d %d\n", w, h);
392 mwindow->session->rmonitor_x = get_x();
393 mwindow->session->rmonitor_y = get_y();
394 mwindow->session->rmonitor_w = w;
395 mwindow->session->rmonitor_h = h;
397 mwindow->theme->get_rmonitor_sizes(record->default_asset->audio_data,
398 record->default_asset->video_data,
399 (mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
400 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ),
401 (mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ));
402 mwindow->theme->draw_rmonitor_bg(this);
406 // record_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
407 // mwindow->theme->rmonitor_tx_y);
408 if(channel_picker) channel_picker->reposition();
409 if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(),
410 reverse_interlace->get_y());
411 if(record->default_asset->video_data)
413 canvas->reposition_window(0,
414 mwindow->theme->rmonitor_canvas_x,
415 mwindow->theme->rmonitor_canvas_y,
416 mwindow->theme->rmonitor_canvas_w,
417 mwindow->theme->rmonitor_canvas_h);
420 if(record->default_asset->audio_data)
422 meters->reposition_window(mwindow->theme->rmonitor_meter_x,
423 mwindow->theme->rmonitor_meter_y,
424 mwindow->theme->rmonitor_meter_h);
428 BC_WindowBase::resize_event(w, h);
434 int RecordMonitorGUI::set_title()
440 scale = (int)(thread->get_scale(thread->record->video_window_w) * 100 + 0.5);
442 sprintf(string, PROGRAM_NAME ": Video in %d%%", scale);
443 BC_Window::set_title(string);
447 int RecordMonitorGUI::close_event()
449 thread->record->monitor_video = 0;
450 thread->record->monitor_audio = 0;
451 thread->record->video_window_open = 0;
452 if(record->record_gui->monitor_video) record->record_gui->monitor_video->update(0);
453 if(record->record_gui->monitor_audio) record->record_gui->monitor_audio->update(0);
455 record->record_gui->flush();
459 int RecordMonitorGUI::create_bitmap()
462 (bitmap->get_w() != get_w() ||
463 bitmap->get_h() != thread->get_canvas_height()))
471 // bitmap = canvas->new_bitmap(get_w(), thread->get_canvas_height());
476 ReverseInterlace::ReverseInterlace(Record *record, int x, int y)
477 : BC_CheckBox(x, y, record->reverse_interlace, _("Swap fields"))
479 this->record = record;
482 ReverseInterlace::~ReverseInterlace()
486 int ReverseInterlace::handle_event()
488 record->reverse_interlace = get_value();
492 RecordMonitorCanvas::RecordMonitorCanvas(MWindow *mwindow,
493 RecordMonitorGUI *window,
504 record->default_asset->width,
505 record->default_asset->height,
510 this->window = window;
511 this->mwindow = mwindow;
512 this->record = record;
513 //printf("RecordMonitorCanvas::RecordMonitorCanvas 1 %d\n", mwindow->edl->session->vconfig_in->driver);
514 //printf("RecordMonitorCanvas::RecordMonitorCanvas 2\n");
517 RecordMonitorCanvas::~RecordMonitorCanvas()
521 int RecordMonitorCanvas::get_output_w()
523 return record->default_asset->width;
526 int RecordMonitorCanvas::get_output_h()
528 return record->default_asset->height;
532 int RecordMonitorCanvas::button_press_event()
534 if(Canvas::button_press_event()) return 1;
536 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
538 window->current_operation = MONITOR_TRANSLATE;
539 window->translate_x_origin = record->video_x;
540 window->translate_y_origin = record->video_y;
541 window->cursor_x_origin = get_cursor_x();
542 window->cursor_y_origin = get_cursor_y();
548 void RecordMonitorCanvas::zoom_resize_window(float percentage)
550 int canvas_w, canvas_h;
551 calculate_sizes(mwindow->edl->get_aspect_ratio(),
552 record->default_asset->width,
553 record->default_asset->height,
558 new_w = canvas_w + (window->get_w() - mwindow->theme->rmonitor_canvas_w);
559 new_h = canvas_h + (window->get_h() - mwindow->theme->rmonitor_canvas_h);
560 window->resize_window(new_w, new_h);
561 window->resize_event(new_w, new_h);
564 int RecordMonitorCanvas::button_release_event()
566 window->current_operation = MONITOR_NONE;
570 int RecordMonitorCanvas::cursor_motion_event()
572 if(window->current_operation == MONITOR_TRANSLATE)
574 record->set_translation(
575 get_cursor_x() - window->cursor_x_origin + window->translate_x_origin,
576 get_cursor_y() - window->cursor_y_origin + window->translate_y_origin);
582 int RecordMonitorCanvas::cursor_enter_event()
584 if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
585 set_cursor(MOVE_CURSOR);
589 void RecordMonitorCanvas::reset_translation()
591 record->set_translation(0, 0);
594 int RecordMonitorCanvas::keypress_event()
597 switch(canvas->get_keypress())
600 record->set_translation(--record->video_x, record->video_y);
603 record->set_translation(++record->video_x, record->video_y);
606 record->set_translation(record->video_x, --record->video_y);
609 record->set_translation(record->video_x, ++record->video_y);
616 RecordMonitorFullsize::RecordMonitorFullsize(MWindow *mwindow,
617 RecordMonitorGUI *window)
618 : BC_MenuItem(_("Zoom 100%"))
620 this->mwindow = mwindow;
621 this->window = window;
623 int RecordMonitorFullsize::handle_event()
635 // ================================== slippery playback ============================
638 RecordMonitorThread::RecordMonitorThread(MWindow *mwindow,
640 RecordMonitor *record_monitor)
643 this->mwindow = mwindow;
644 this->record_monitor = record_monitor;
645 this->record = record;
650 void RecordMonitorThread::reset_parameters()
660 RecordMonitorThread::~RecordMonitorThread()
662 if(input_frame && !shared_data) delete input_frame;
665 void RecordMonitorThread::init_output_format()
669 //printf("RecordMonitorThread::init_output_format 1\n");
670 switch(mwindow->edl->session->vconfig_in->driver)
673 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
678 jpeg_engine = new RecVideoMJPGThread(record, this);
679 jpeg_engine->start_rendering();
680 output_colormodel = BC_YUV422P;
683 case CAPTURE_FIREWIRE:
684 dv_engine = new RecVideoDVThread(record, this);
685 dv_engine->start_rendering();
686 output_colormodel = BC_YUV422P;
690 output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
691 //printf("RecordMonitorThread::init_output_format 2 %d\n", output_colormodel);
696 int RecordMonitorThread::start_playback()
705 int RecordMonitorThread::stop_playback()
708 output_lock.unlock();
710 //printf("RecordMonitorThread::stop_playback 1\n");
712 switch(mwindow->edl->session->vconfig_in->driver)
715 //printf("RecordMonitorThread::stop_playback 2\n");
718 jpeg_engine->stop_rendering();
719 //printf("RecordMonitorThread::stop_playback 2\n");
722 //printf("RecordMonitorThread::stop_playback 3\n");
725 case CAPTURE_FIREWIRE:
728 dv_engine->stop_rendering();
733 //printf("RecordMonitorThread::stop_playback 4\n");
738 int RecordMonitorThread::write_frame(VFrame *new_frame)
743 shared_data = (new_frame->get_color_model() != BC_COMPRESSED);
744 // Need to wait until after Record creates the input device before starting monitor
745 // because the input device deterimes the output format.
747 if(!output_frame[0]) init_output_format();
750 if(!input_frame) input_frame = new VFrame;
751 input_frame->allocate_compressed_data(new_frame->get_compressed_size());
752 memcpy(input_frame->get_data(),
753 new_frame->get_data(),
754 new_frame->get_compressed_size());
755 input_frame->set_compressed_size(new_frame->get_compressed_size());
756 input_frame->set_field2_offset(new_frame->get_field2_offset());
761 input_frame = new_frame;
763 output_lock.unlock();
768 int RecordMonitorThread::render_jpeg()
770 //printf("RecordMonitorThread::render_jpeg 1\n");
771 jpeg_engine->render_frame(input_frame, input_frame->get_compressed_size());
772 //printf("RecordMonitorThread::render_jpeg 2\n");
776 int RecordMonitorThread::render_dv()
778 dv_engine->render_frame(input_frame, input_frame->get_compressed_size());
782 void RecordMonitorThread::render_uncompressed()
784 // printf("RecordMonitorThread::render_uncompressed 1 %p %p %p %p %p %p %p\n",
786 // output_frame[0]->get_y(),
787 // output_frame[0]->get_u(),
788 // output_frame[0]->get_v(),
789 // input_frame->get_y(),
790 // input_frame->get_u(),
791 // input_frame->get_v());
793 output_frame[0]->copy_from(input_frame);
795 //printf("RecordMonitorThread::render_uncompressed 2\n");
798 void RecordMonitorThread::show_output_frame()
800 record_monitor->device->write_buffer(output_frame, record->edl);
803 void RecordMonitorThread::unlock_input()
805 if(shared_data) input_lock.unlock();
808 int RecordMonitorThread::render_frame()
810 switch(mwindow->edl->session->vconfig_in->driver)
816 case CAPTURE_FIREWIRE:
821 render_uncompressed();
828 void RecordMonitorThread::new_output_frame()
831 //printf("RecordMonitorThread::new_output_frame %d %p %p\n", output_colormodel, record_monitor, record_monitor->device);
832 record_monitor->device->new_output_buffers(output_frame, output_colormodel);
833 //printf("RecordMonitorThread::new_output_frame 2\n");
836 void RecordMonitorThread::run()
838 //printf("RecordMonitorThread::run 1 %d\n", getpid());
841 // Wait for next frame
848 //printf("RecordMonitorThread::run 1\n");
850 //printf("RecordMonitorThread::run 2\n");
852 //printf("RecordMonitorThread::run 3\n");
854 //printf("RecordMonitorThread::run 4\n");
863 RecVideoMJPGThread::RecVideoMJPGThread(Record *record, RecordMonitorThread *thread)
865 this->record = record;
866 this->thread = thread;
870 RecVideoMJPGThread::~RecVideoMJPGThread()
874 int RecVideoMJPGThread::start_rendering()
876 mjpeg = mjpeg_new(record->default_asset->width,
877 record->default_asset->height,
879 //printf("RecVideoMJPGThread::start_rendering 1 %p\n", mjpeg);
883 int RecVideoMJPGThread::stop_rendering()
885 //printf("RecVideoMJPGThread::stop_rendering 1 %p\n", mjpeg);
886 if(mjpeg) mjpeg_delete(mjpeg);
887 //printf("RecVideoMJPGThread::stop_rendering 2\n");
891 int RecVideoMJPGThread::render_frame(VFrame *frame, long size)
893 // printf("RecVideoMJPGThread::render_frame %d %02x%02x %02x%02x\n", frame->get_field2_offset(),
894 // frame->get_data()[0],
895 // frame->get_data()[1],
896 // frame->get_data()[frame->get_field2_offset()],
897 // frame->get_data()[frame->get_field2_offset() + 1]);
898 //frame->set_field2_offset(0);
899 mjpeg_decompress(mjpeg,
901 frame->get_compressed_size(),
902 frame->get_field2_offset(),
903 thread->output_frame[0]->get_rows(),
904 thread->output_frame[0]->get_y(),
905 thread->output_frame[0]->get_u(),
906 thread->output_frame[0]->get_v(),
907 thread->output_frame[0]->get_color_model(),
908 record->mwindow->preferences->processors);
915 RecVideoDVThread::RecVideoDVThread(Record *record, RecordMonitorThread *thread)
917 this->record = record;
918 this->thread = thread;
922 RecVideoDVThread::~RecVideoDVThread()
927 int RecVideoDVThread::start_rendering()
929 ((dv_t*)dv) = dv_new();
933 int RecVideoDVThread::stop_rendering()
935 if(dv) dv_delete(((dv_t*)dv));
939 int RecVideoDVThread::render_frame(VFrame *frame, long size)
941 unsigned char *yuv_planes[3];
942 yuv_planes[0] = thread->output_frame[0]->get_y();
943 yuv_planes[1] = thread->output_frame[0]->get_u();
944 yuv_planes[2] = thread->output_frame[0]->get_v();
945 dv_read_video(((dv_t*)dv),
948 frame->get_compressed_size(),
949 thread->output_frame[0]->get_color_model());