r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / recordmonitor.C
blobdc1863f0472b08b8bf0cd2968b10b4cd043710c3
1 #include "assets.h"
2 #include "channelpicker.h"
3 #include "cursors.h"
4 #include "libdv.h"
5 #include "edl.h"
6 #include "edlsession.h"
7 #include "keys.h"
8 #include "meterpanel.h"
9 #include "mwindow.h"
10 #include "playbackconfig.h"
11 #include "preferences.h"
12 #include "record.h"
13 #include "recordconfig.h"
14 #include "recordgui.h"
15 #include "recordtransport.h"
16 #include "recordmonitor.h"
17 #include "mainsession.h"
18 #include "theme.h"
19 #include "videodevice.inc"
20 #include "vframe.h"
21 #include "videodevice.h"
24 #include <libintl.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)
30  : Thread(1)
32         this->mwindow = mwindow;
33         this->record = record;
34         device = 0;
35         thread = 0;
39 RecordMonitor::~RecordMonitor()
41 //printf("RecordMonitor::~RecordMonitor 1\n");
42         if(thread)
43         {
44                 thread->stop_playback();
45                 delete thread;
46         }
47 //printf("RecordMonitor::~RecordMonitor 1\n");
48         window->set_done(0);
49 //printf("RecordMonitor::~RecordMonitor 1\n");
50         Thread::join();
51 //printf("RecordMonitor::~RecordMonitor 1\n");
52         if(device) 
53         {
54                 device->close_all();
55                 delete device;
56         }
57 //printf("RecordMonitor::~RecordMonitor 1\n");
58         delete window;
59 //printf("RecordMonitor::~RecordMonitor 2\n");
62 int RecordMonitor::create_objects()
64 //printf("RecordMonitor::create_objects 1\n");
65         window = new RecordMonitorGUI(mwindow,
66                 record, 
67                 this);
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)
73         {
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,
91                                                 window->canvas,
92                                                 0);
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();
98         }
100         Thread::start();
101         return 0;
105 void RecordMonitor::run()
107         window->run_window();
108         close_threads();
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)
134         w = width_given;
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)
142         {
143                 return (float)w / 
144                         ((float)record->frame_h * 
145                         mwindow->edl->get_aspect_ratio());
146         }
147         else
148         {
149                 return (float)w / record->frame_w;
150         }
153 int RecordMonitor::get_canvas_height()
155         return window->get_h() - get_mbuttons_height();
158 int RecordMonitor::get_channel_x()
160 //      return 240;
161         return 5;
164 int RecordMonitor::get_channel_y()
166         return 2;
178 RecordMonitorGUI::RecordMonitorGUI(MWindow *mwindow,
179         Record *record, 
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, 
186                         150, 
187                         50, 
188                         1, 
189                         1,
190                         1)
192         this->mwindow = mwindow;
193         this->thread = thread;
194         this->record = record;
195         bitmap = 0;
196         channel_picker = 0;
197         reverse_interlace = 0;
198         meters = 0;
199         canvas = 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_recordmonitor_sizes(record->default_asset->audio_data, 
213                 record->default_asset->video_data);
214         mwindow->theme->draw_rmonitor_bg(this);
215 //printf("RecordMonitorGUI::create_objects 1\n");
217         record_transport = new RecordTransport(mwindow, 
218                 record, 
219                 this, 
220                 mwindow->theme->rmonitor_tx_x,
221                 mwindow->theme->rmonitor_tx_y);
222         record_transport->create_objects();
223 //printf("RecordMonitorGUI::create_objects 1\n");
225         if(record->default_asset->video_data)
226         {
227                 canvas = new RecordMonitorCanvas(mwindow, 
228                         this,
229                         record, 
230                         mwindow->theme->rmonitor_canvas_x, 
231                         mwindow->theme->rmonitor_canvas_y, 
232                         mwindow->theme->rmonitor_canvas_w, 
233                         mwindow->theme->rmonitor_canvas_h);
234                 canvas->create_objects(0);
235 //printf("RecordMonitorGUI::create_objects 1\n");
237                 if(mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX ||
238                         mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ)
239                 {
240                         channel_picker = new ChannelPicker(mwindow,
241                                 record,
242                                 thread,
243                                 record->current_channeldb(),
244                                 mwindow->theme->rmonitor_channel_x, 
245                                 mwindow->theme->rmonitor_channel_y);
246                         channel_picker->create_objects();
247                 }
248 //printf("RecordMonitorGUI::create_objects 1\n");
250                 if(mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ)
251                 {
252                         add_subwindow(reverse_interlace = new ReverseInterlace(record,
253                                 mwindow->theme->rmonitor_interlace_x, 
254                                 mwindow->theme->rmonitor_interlace_y));
255                 }
256 //printf("RecordMonitorGUI::create_objects 1\n");
257                 
258                 add_subwindow(monitor_menu = new BC_PopupMenu(0, 
259                         0, 
260                         0, 
261                         "", 
262                         0));
263                 monitor_menu->add_item(new RecordMonitorFullsize(mwindow, 
264                         this));
265 //printf("RecordMonitorGUI::create_objects 1\n");
266         }
267 //printf("RecordMonitorGUI::create_objects 1\n");
269         if(record->default_asset->audio_data)
270         {
271                 meters = new MeterPanel(mwindow, 
272                         this,
273                         mwindow->theme->rmonitor_meter_x,
274                         mwindow->theme->rmonitor_meter_y,
275                         mwindow->theme->rmonitor_meter_h,
276                         record->default_asset->channels,
277                         1);
278                 meters->create_objects();
279         }
280 //printf("RecordMonitorGUI::create_objects 2\n");
281         return 0;
284 int RecordMonitorGUI::button_press()
286         if(get_buttonpress() == 2)
287         {
288                 return 0;
289         }
290         else
291 // Right button
292         if(get_button_down() == 3)
293         {
294                 monitor_menu->activate_menu();
295                 return 1;
296         }
297         return 0;
300 int RecordMonitorGUI::button_release()
302         return 0;
305 int RecordMonitorGUI::get_virtual_center()
309 int RecordMonitorGUI::cursor_motion()
311         return 0;
314 int RecordMonitorGUI::keypress_event()
316         int result = 0;
317         switch(get_keypress())
318         {
319                 case LEFT:
320                         if(!ctrl_down()) 
321                         { 
322                                 record->record_gui->set_translation(--(record->video_x), record->video_y, record->video_zoom);
323                         }
324                         else
325                         {
326                                 record->video_zoom -= 0.1;
327                                 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
328                         }
329                         result = 1;
330                         break;
331                 case RIGHT:
332                         if(!ctrl_down()) 
333                         { 
334                                 record->record_gui->set_translation(++(record->video_x), record->video_y, record->video_zoom);
335                         }
336                         else
337                         {
338                                 record->video_zoom += 0.1;
339                                 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
340                         }
341                         result = 1;
342                         break;
343                 case UP:
344                         if(!ctrl_down()) 
345                         { 
346                                 record->record_gui->set_translation(record->video_x, --(record->video_y), record->video_zoom);
347                         }
348                         else
349                         {
350                                 record->video_zoom -= 0.1;
351                                 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
352                         }
353                         result = 1;
354                         break;
355                 case DOWN:
356                         if(!ctrl_down()) 
357                         { 
358                                 record->record_gui->set_translation(record->video_x, ++(record->video_y), record->video_zoom);
359                         }
360                         else
361                         {
362                                 record->video_zoom += 0.1;
363                                 record->record_gui->set_translation(record->video_x, record->video_y, record->video_zoom);
364                         }
365                         result = 1;
366                         break;
367                 case 'w':
368                         close_event();
369                         break;
370                 default:
371                         result = record_transport->keypress_event();
372                         break;
373         }
374         return result;
378 int RecordMonitorGUI::translation_event()
380 //printf("MWindowGUI::translation_event 1 %d %d\n", get_x(), get_y());
381         mwindow->session->rmonitor_x = get_x();
382         mwindow->session->rmonitor_y = get_y();
383         return 0;
386 int RecordMonitorGUI::resize_event(int w, int h)
388 //printf("RecordMonitorGUI::resize_event %d %d\n", w, h);
389         mwindow->session->rmonitor_x = get_x();
390         mwindow->session->rmonitor_y = get_y();
391         mwindow->session->rmonitor_w = w;
392         mwindow->session->rmonitor_h = h;
394         mwindow->theme->get_recordmonitor_sizes(record->default_asset->audio_data, 
395                 record->default_asset->video_data);
396         mwindow->theme->draw_rmonitor_bg(this);
397         flash();
400         record_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
401                 mwindow->theme->rmonitor_tx_y);
402         if(channel_picker) channel_picker->reposition();
403         if(reverse_interlace) reverse_interlace->reposition_window(reverse_interlace->get_x(),
404                 reverse_interlace->get_y());
405         if(record->default_asset->video_data)
406         {
407                 canvas->reposition_window(0,
408                         mwindow->theme->rmonitor_canvas_x, 
409                         mwindow->theme->rmonitor_canvas_y, 
410                         mwindow->theme->rmonitor_canvas_w, 
411                         mwindow->theme->rmonitor_canvas_h);
412         }
414         if(record->default_asset->audio_data)
415         {
416                 meters->reposition_window(mwindow->theme->rmonitor_meter_x, 
417                         mwindow->theme->rmonitor_meter_y, 
418                         mwindow->theme->rmonitor_meter_h);
419         }
421         set_title();
422         BC_WindowBase::resize_event(w, h);
423         flash();
424         flush();
425         return 1;
428 int RecordMonitorGUI::set_title()
430 return 0;
431         char string[1024];
432         int scale;
434         scale = (int)(thread->get_scale(thread->record->video_window_w) * 100 + 0.5);
436         sprintf(string, PROGRAM_NAME ": Video in %d%%", scale);
437         BC_Window::set_title(string);
438         return 0;
441 int RecordMonitorGUI::close_event()
443         thread->record->monitor_video = 0;
444         thread->record->monitor_audio = 0;
445         thread->record->video_window_open = 0;
446         if(record->record_gui->monitor_video) record->record_gui->monitor_video->update(0);
447         if(record->record_gui->monitor_audio) record->record_gui->monitor_audio->update(0);
448         hide_window();
449         record->record_gui->flush();
450         return 0;
453 int RecordMonitorGUI::create_bitmap()
455         if(bitmap && 
456                 (bitmap->get_w() != get_w() || 
457                         bitmap->get_h() != thread->get_canvas_height()))
458         {
459                 delete bitmap;
460                 bitmap = 0;
461         }
463         if(!bitmap)
464         {
465 //              bitmap = canvas->new_bitmap(get_w(), thread->get_canvas_height());
466         }
467         return 0;
470 ReverseInterlace::ReverseInterlace(Record *record, int x, int y)
471  : BC_CheckBox(x, y, record->reverse_interlace, _("Swap fields"))
473         this->record = record;
476 ReverseInterlace::~ReverseInterlace()
480 int ReverseInterlace::handle_event()
482         record->reverse_interlace = get_value();
483         return 0;
486 RecordMonitorCanvas::RecordMonitorCanvas(MWindow *mwindow, 
487         RecordMonitorGUI *window, 
488         Record *record, 
489         int x, 
490         int y, 
491         int w, 
492         int h)
493  : Canvas(window, 
494         x, 
495         y, 
496         w, 
497         h, 
498         record->default_asset->width,
499         record->default_asset->height,
500         0,
501         0,
502         1)
504         this->window = window;
505         this->mwindow = mwindow;
506         this->record = record;
507 //printf("RecordMonitorCanvas::RecordMonitorCanvas 1 %d\n", mwindow->edl->session->vconfig_in->driver);
508 //printf("RecordMonitorCanvas::RecordMonitorCanvas 2\n");
511 RecordMonitorCanvas::~RecordMonitorCanvas()
515 int RecordMonitorCanvas::get_output_w()
517         return record->default_asset->width;
520 int RecordMonitorCanvas::get_output_h()
522         return record->default_asset->height;
526 int RecordMonitorCanvas::button_press_event()
528         if(Canvas::button_press_event()) return 1;
529         
530         if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
531         {
532                 window->current_operation = MONITOR_TRANSLATE;
533                 window->translate_x_origin = record->video_x;
534                 window->translate_y_origin = record->video_y;
535                 window->cursor_x_origin = get_cursor_x();
536                 window->cursor_y_origin = get_cursor_y();
537         }
539         return 0;
542 void RecordMonitorCanvas::zoom_resize_window(float percentage)
544         int canvas_w, canvas_h;
545         calculate_sizes(mwindow->edl->get_aspect_ratio(), 
546                 record->default_asset->width, 
547                 record->default_asset->height, 
548                 percentage,
549                 canvas_w,
550                 canvas_h);
551         int new_w, new_h;
552         new_w = canvas_w + (window->get_w() - mwindow->theme->rmonitor_canvas_w);
553         new_h = canvas_h + (window->get_h() - mwindow->theme->rmonitor_canvas_h);
554         window->resize_window(new_w, new_h);
555         window->resize_event(new_w, new_h);
558 int RecordMonitorCanvas::button_release_event()
560         window->current_operation = MONITOR_NONE;
561         return 0;
564 int RecordMonitorCanvas::cursor_motion_event()
566         if(window->current_operation == MONITOR_TRANSLATE)
567         {
568                 record->set_translation(
569                         get_cursor_x() - window->cursor_x_origin + window->translate_x_origin,
570                         get_cursor_y() - window->cursor_y_origin + window->translate_y_origin);
571         }
573         return 0;
576 int RecordMonitorCanvas::cursor_enter_event()
578         if(mwindow->edl->session->vconfig_in->driver == SCREENCAPTURE)
579                 set_cursor(MOVE_CURSOR);
580         return 0;
583 void RecordMonitorCanvas::reset_translation()
585         record->set_translation(0, 0);
588 int RecordMonitorCanvas::keypress_event()
590         int result = 0;
591         switch(canvas->get_keypress())
592         {
593                 case LEFT:
594                         record->set_translation(--record->video_x, record->video_y);
595                         break;
596                 case RIGHT:
597                         record->set_translation(++record->video_x, record->video_y);
598                         break;
599                 case UP:
600                         record->set_translation(record->video_x, --record->video_y);
601                         break;
602                 case DOWN:
603                         record->set_translation(record->video_x, ++record->video_y);
604                         break;
605         }
606         return result;
610 RecordMonitorFullsize::RecordMonitorFullsize(MWindow *mwindow, 
611         RecordMonitorGUI *window)
612  : BC_MenuItem(_("Zoom 100%"))
614         this->mwindow = mwindow;
615         this->window = window;
617 int RecordMonitorFullsize::handle_event()
619         return 1;
629 // ================================== slippery playback ============================
632 RecordMonitorThread::RecordMonitorThread(MWindow *mwindow, 
633         Record *record, 
634         RecordMonitor *record_monitor)
635  : Thread()
637         this->mwindow = mwindow;
638         this->record_monitor = record_monitor;
639         this->record = record;
640         reset_parameters();
644 void RecordMonitorThread::reset_parameters()
646         input_frame = 0;
647         output_frame[0] = 0;
648         shared_data = 0;
649         jpeg_engine = 0;
650         dv_engine = 0;
654 RecordMonitorThread::~RecordMonitorThread()
656         if(input_frame && !shared_data) delete input_frame;
659 void RecordMonitorThread::init_output_format()
661         long offset;
663 //printf("RecordMonitorThread::init_output_format 1\n");
664         switch(mwindow->edl->session->vconfig_in->driver)
665         {
666                 case SCREENCAPTURE:
667                         output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
668                         break;
669         
670         
671                 case CAPTURE_BUZ:
672                         jpeg_engine = new RecVideoMJPGThread(record, this);
673                         jpeg_engine->start_rendering();
674                         output_colormodel = BC_YUV422P;
675                         break;
677                 case CAPTURE_FIREWIRE:
678                         dv_engine = new RecVideoDVThread(record, this);
679                         dv_engine->start_rendering();
680                         output_colormodel = BC_YUV422P;
681                         break;
683                 case VIDEO4LINUX:
684                         output_colormodel = record->vdevice->get_best_colormodel(record->default_asset);
685 //printf("RecordMonitorThread::init_output_format 2 %d\n", output_colormodel);
686                         break;
687         }
690 int RecordMonitorThread::start_playback()
692         set_synchronous(1);
693         ready = 1;
694         done = 0;
695         output_lock.lock();
696         Thread::start();
697         return 0;
700 int RecordMonitorThread::stop_playback()
702         done = 1;
703         output_lock.unlock();
704         Thread::join();
705 //printf("RecordMonitorThread::stop_playback 1\n");
707         switch(mwindow->edl->session->vconfig_in->driver)
708         {
709                 case CAPTURE_BUZ:
710 //printf("RecordMonitorThread::stop_playback 2\n");
711                         if(jpeg_engine) 
712                         {
713                                 jpeg_engine->stop_rendering();
714 //printf("RecordMonitorThread::stop_playback 2\n");
715                                 delete jpeg_engine;
716                         }
717 //printf("RecordMonitorThread::stop_playback 3\n");
718                         break;
720                 case CAPTURE_FIREWIRE:
721                         if(dv_engine)
722                         {
723                                 dv_engine->stop_rendering();
724                                 delete dv_engine;
725                         }
726                         break;
727         }
728 //printf("RecordMonitorThread::stop_playback 4\n");
730         return 0;
733 int RecordMonitorThread::write_frame(VFrame *new_frame)
735         if(ready)
736         {
737                 ready = 0;
738                 shared_data = (new_frame->get_color_model() != BC_COMPRESSED);
739 // Need to wait until after Record creates the input device before starting monitor
740 // because the input device deterimes the output format.
741 // First time
742                 if(!output_frame[0]) init_output_format();
743                 if(!shared_data)
744                 {
745                         if(!input_frame) input_frame = new VFrame;
746                         input_frame->allocate_compressed_data(new_frame->get_compressed_size());
747                         memcpy(input_frame->get_data(), 
748                                 new_frame->get_data(), 
749                                 new_frame->get_compressed_size());
750                         input_frame->set_compressed_size(new_frame->get_compressed_size());
751                         input_frame->set_field2_offset(new_frame->get_field2_offset());
752                 }
753                 else
754                 {
755                         input_lock.lock();
756                         input_frame = new_frame;
757                 }
758                 output_lock.unlock();
759         }
760         return 0;
763 int RecordMonitorThread::render_jpeg()
765 //printf("RecordMonitorThread::render_jpeg 1\n");
766         jpeg_engine->render_frame(input_frame, input_frame->get_compressed_size());
767 //printf("RecordMonitorThread::render_jpeg 2\n");
768         return 0;
771 int RecordMonitorThread::render_dv()
773         dv_engine->render_frame(input_frame, input_frame->get_compressed_size());
774         return 0;
777 void RecordMonitorThread::render_uncompressed()
779 // printf("RecordMonitorThread::render_uncompressed 1 %p %p %p %p %p %p %p\n", 
780 //      output_frame[0],
781 //      output_frame[0]->get_y(), 
782 //      output_frame[0]->get_u(), 
783 //      output_frame[0]->get_v(),
784 //      input_frame->get_y(),
785 //      input_frame->get_u(),
786 //      input_frame->get_v());
788         output_frame[0]->copy_from(input_frame);
790 //printf("RecordMonitorThread::render_uncompressed 2\n");
793 void RecordMonitorThread::show_output_frame()
795         record_monitor->device->write_buffer(output_frame, record->edl);
798 void RecordMonitorThread::unlock_input()
800         if(shared_data) input_lock.unlock();
803 int RecordMonitorThread::render_frame()
805         switch(mwindow->edl->session->vconfig_in->driver)
806         {
807                 case CAPTURE_BUZ:
808                         render_jpeg();
809                         break;
811                 case CAPTURE_FIREWIRE:
812                         render_dv();
813                         break;
815                 default:
816                         render_uncompressed();
817                         break;
818         }
820         return 0;
823 void RecordMonitorThread::new_output_frame()
825         long offset;
826 //printf("RecordMonitorThread::new_output_frame %d %p %p\n", output_colormodel, record_monitor, record_monitor->device);
827         record_monitor->device->new_output_buffers(output_frame, output_colormodel);
828 //printf("RecordMonitorThread::new_output_frame 2\n");
831 void RecordMonitorThread::run()
833         while(!done)
834         {
835 // Wait for next frame
836                 output_lock.lock();
837                 if(done)
838                 {
839                         unlock_input();
840                         return;
841                 }
842 //printf("RecordMonitorThread::run 1\n");
843                 new_output_frame();
844 //printf("RecordMonitorThread::run 2\n");
845                 render_frame();
846 //printf("RecordMonitorThread::run 3\n");
847                 show_output_frame();
848 //printf("RecordMonitorThread::run 4\n");
849                 unlock_input();
850 // Get next frame
851                 ready = 1;
852         }
857 RecVideoMJPGThread::RecVideoMJPGThread(Record *record, RecordMonitorThread *thread)
859         this->record = record;
860         this->thread = thread;
861         mjpeg = 0;
864 RecVideoMJPGThread::~RecVideoMJPGThread()
868 int RecVideoMJPGThread::start_rendering()
870         mjpeg = mjpeg_new(record->default_asset->width, 
871                 record->default_asset->height, 
872                 2);
873 //printf("RecVideoMJPGThread::start_rendering 1 %p\n", mjpeg);
874         return 0;
877 int RecVideoMJPGThread::stop_rendering()
879 //printf("RecVideoMJPGThread::stop_rendering 1 %p\n", mjpeg);
880         if(mjpeg) mjpeg_delete(mjpeg);
881 //printf("RecVideoMJPGThread::stop_rendering 2\n");
882         return 0;
885 int RecVideoMJPGThread::render_frame(VFrame *frame, long size)
887 // printf("RecVideoMJPGThread::render_frame %d %02x%02x %02x%02x\n", frame->get_field2_offset(), 
888 //      frame->get_data()[0], 
889 //      frame->get_data()[1], 
890 //      frame->get_data()[frame->get_field2_offset()], 
891 //      frame->get_data()[frame->get_field2_offset() + 1]);
892 //frame->set_field2_offset(0);
893         mjpeg_decompress(mjpeg, 
894                 frame->get_data(), 
895                 frame->get_compressed_size(), 
896                 frame->get_field2_offset(), 
897                 thread->output_frame[0]->get_rows(), 
898                 thread->output_frame[0]->get_y(), 
899                 thread->output_frame[0]->get_u(), 
900                 thread->output_frame[0]->get_v(),
901                 thread->output_frame[0]->get_color_model(),
902                 record->mwindow->edl->session->smp + 1);
903         return 0;
909 RecVideoDVThread::RecVideoDVThread(Record *record, RecordMonitorThread *thread)
911         this->record = record;
912         this->thread = thread;
913         dv = 0;
916 RecVideoDVThread::~RecVideoDVThread()
921 int RecVideoDVThread::start_rendering()
923         ((dv_t*)dv) = dv_new();
924         return 0;
927 int RecVideoDVThread::stop_rendering()
929         if(dv) dv_delete(((dv_t*)dv));
930         return 0;
933 int RecVideoDVThread::render_frame(VFrame *frame, long size)
935         unsigned char *yuv_planes[3];
936         yuv_planes[0] = thread->output_frame[0]->get_y();
937         yuv_planes[1] = thread->output_frame[0]->get_u();
938         yuv_planes[2] = thread->output_frame[0]->get_v();
939         dv_read_video(((dv_t*)dv), 
940                 yuv_planes, 
941                 frame->get_data(), 
942                 frame->get_compressed_size(),
943                 thread->output_frame[0]->get_color_model());
944         return 0;