Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

recordmonitor.C

Go to the documentation of this file.
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 // Configure the output for record monitoring
00069                 VideoOutConfig config;
00070                 device = new VideoDevice;
00071 
00072 
00073 
00074 // Override default device for X11 drivers
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 //      return 240;
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 //printf("%d %d\n", mwindow->session->rmonitor_w, mwindow->theme->rmonitor_meter_x);
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 // y offset for video canvas if we have the transport controls
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 // Right button
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 //printf("MWindowGUI::translation_event 1 %d %d\n", get_x(), get_y());
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 //      record_transport->reposition_window(mwindow->theme->rmonitor_tx_x,
00493 //              mwindow->theme->rmonitor_tx_y);
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 //              bitmap = canvas->new_bitmap(get_w(), thread->get_canvas_height());
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 //printf("RecordMonitorCanvas::RecordMonitorCanvas 1 %d\n", mwindow->edl->session->vconfig_in->driver);
00613 //printf("RecordMonitorCanvas::RecordMonitorCanvas 2\n");
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 // ================================== slippery playback ============================
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 //printf("RecordMonitorThread::init_output_format 1\n");
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 //printf("RecordMonitorThread::init_output_format 2 %d\n", output_colormodel);
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 //printf("RecordMonitorThread::stop_playback 1\n");
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 //printf("RecordMonitorThread::stop_playback 4\n");
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 // Need to wait until after Record creates the input device before starting monitor
00853 // because the input device deterimes the output format.
00854 // First time
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 //printf("RecordMonitorThread::render_jpeg 1\n");
00879         jpeg_engine->render_frame(input_frame, input_frame->get_compressed_size());
00880 //printf("RecordMonitorThread::render_jpeg 2\n");
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 // printf("RecordMonitorThread::render_uncompressed 1 %p %p %p %p %p %p %p\n", 
00893 //      output_frame[0],
00894 //      output_frame[0]->get_y(), 
00895 //      output_frame[0]->get_u(), 
00896 //      output_frame[0]->get_v(),
00897 //      input_frame->get_y(),
00898 //      input_frame->get_u(),
00899 //      input_frame->get_v());
00900 
00901         output_frame[0]->copy_from(input_frame);
00902 
00903 //printf("RecordMonitorThread::render_uncompressed 2\n");
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 //printf("RecordMonitorThread::new_output_frame %d %p %p\n", output_colormodel, record_monitor, record_monitor->device);
00942         record_monitor->device->new_output_buffers(output_frame, output_colormodel);
00943 //printf("RecordMonitorThread::new_output_frame 2\n");
00944 }
00945 
00946 void RecordMonitorThread::run()
00947 {
00948 //printf("RecordMonitorThread::run 1 %d\n", getpid());
00949         while(!done)
00950         {
00951 // Wait for next frame
00952                 output_lock->lock("RecordMonitorThread::run");
00953                 if(done)
00954                 {
00955                         unlock_input();
00956                         return;
00957                 }
00958 //printf("RecordMonitorThread::run 1\n");
00959                 new_output_frame();
00960 //printf("RecordMonitorThread::run 2\n");
00961                 render_frame();
00962 //printf("RecordMonitorThread::run 3\n");
00963                 show_output_frame();
00964 //printf("RecordMonitorThread::run 4\n");
00965                 unlock_input();
00966 // Get next frame
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 //printf("RecVideoMJPGThread::start_rendering 1 %p\n", mjpeg);
00990         return 0;
00991 }
00992 
00993 int RecVideoMJPGThread::stop_rendering()
00994 {
00995 //printf("RecVideoMJPGThread::stop_rendering 1 %p\n", mjpeg);
00996         if(mjpeg) mjpeg_delete(mjpeg);
00997 //printf("RecVideoMJPGThread::stop_rendering 2\n");
00998         return 0;
00999 }
01000 
01001 int RecVideoMJPGThread::render_frame(VFrame *frame, long size)
01002 {
01003 // printf("RecVideoMJPGThread::render_frame %d %02x%02x %02x%02x\n", 
01004 // frame->get_field2_offset(), 
01005 // frame->get_data()[0], 
01006 // frame->get_data()[1], 
01007 // frame->get_data()[frame->get_field2_offset()], 
01008 // frame->get_data()[frame->get_field2_offset() + 1]);
01009 //frame->set_field2_offset(0);
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 }

Generated on Sun Jan 8 13:38:59 2006 for Cinelerra-svn by  doxygen 1.4.4