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

record.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "assets.h"
00003 #include "audiodevice.h"
00004 #include "batch.h"
00005 #include "channel.h"
00006 #include "channeldb.h"
00007 #include "channelpicker.h"
00008 #include "clip.h"
00009 #include "defaults.h"
00010 #include "edl.h"
00011 #include "edlsession.h"
00012 #include "errorbox.h"
00013 #include "file.h"
00014 #include "filexml.h"
00015 #include "filemov.h"
00016 #include "filesystem.h"
00017 #include "filethread.h"
00018 #include "formatcheck.h"
00019 #include "indexfile.h"
00020 #include "language.h"
00021 #include "localsession.h"
00022 #include "mainundo.h"
00023 #include "mwindow.h"
00024 #include "mwindowgui.h"
00025 #include "picture.h"
00026 #include "playbackengine.h"
00027 #include "preferences.h"
00028 #include "quicktime.h"
00029 #include "record.h"
00030 #include "recordaudio.h"
00031 #include "recordconfig.h"
00032 #include "recordgui.h"
00033 #include "recordlabel.h"
00034 #include "recordmonitor.h"
00035 #include "recordthread.h"
00036 #include "recordvideo.h"
00037 #include "recordwindow.h"
00038 #include "mainsession.h"
00039 #include "sighandler.h"
00040 #include "testobject.h"
00041 #include "theme.h"
00042 #include "timebar.h"
00043 #include "tracks.h"
00044 #include "videoconfig.h"
00045 #include "videodevice.h"
00046 
00047 #include <string.h>
00048 
00049 
00050 
00051 RecordMenuItem::RecordMenuItem(MWindow *mwindow)
00052  : BC_MenuItem(_("Record..."), "r", 'r')
00053 {
00054         this->mwindow = mwindow;
00055         thread = new Record(mwindow, this);
00056         current_state = RECORD_NOTHING;
00057 }
00058 
00059 RecordMenuItem::~RecordMenuItem()
00060 {
00061         delete thread;
00062 }
00063 
00064 int RecordMenuItem::handle_event()
00065 {
00066         if(thread->running()) 
00067         {
00068                 switch(current_state)
00069                 {
00070                         case RECORD_INTRO:
00071                                 thread->window_lock->lock("RecordMenuItem::handle_event 1");
00072                                 if(thread->record_window)
00073                                 {
00074                                         thread->record_window->lock_window("RecordMenuItem::handle_event 1");
00075                                         thread->record_window->raise_window();
00076                                         thread->record_window->unlock_window();
00077                                 }
00078                                 thread->window_lock->unlock();
00079                                 break;
00080                         
00081                         case RECORD_CAPTURING:
00082                                 thread->window_lock->lock("RecordMenuItem::handle_event 2");
00083                                 if(thread->record_gui)
00084                                 {
00085                                         thread->record_gui->lock_window("RecordMenuItem::handle_event 2");
00086                                         thread->record_gui->raise_window();
00087                                         thread->record_gui->unlock_window();
00088                                 }
00089                                 thread->window_lock->unlock();
00090                                 break;
00091                 }
00092                 return 0;
00093         }
00094 
00095         thread->start();
00096         return 1;
00097 }
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 Record::Record(MWindow *mwindow, RecordMenuItem *menu_item)
00109  : Thread()
00110 {
00111         this->mwindow = mwindow;
00112         this->menu_item = menu_item;
00113         script = 0;
00114         capture_state = IS_DONE;
00115         adevice = 0;
00116         vdevice = 0;
00117         file = 0;
00118         editing_batch = 0;
00119         current_batch = 0;
00120         picture = new PictureConfig(mwindow);
00121         channeldb = new ChannelDB;
00122         master_channel = new Channel;
00123         window_lock = new Mutex("Record::window_lock");
00124 }
00125 
00126 Record::~Record()
00127 {
00128         delete picture;
00129         delete channeldb;
00130         delete master_channel;
00131         delete window_lock;
00132 }
00133 
00134 
00135 int Record::load_defaults()
00136 {
00137         char string[BCTEXTLEN];
00138         Defaults *defaults = mwindow->defaults;
00139 
00140 // Load default asset
00141         default_asset->load_defaults(defaults, 
00142                 "RECORD_", 
00143                 1,
00144                 1,
00145                 1,
00146                 1,
00147                 1);
00148 
00149 
00150 
00151 
00152 
00153 
00154         default_asset->sample_rate = mwindow->edl->session->aconfig_in->in_samplerate;
00155         default_asset->frame_rate = mwindow->edl->session->vconfig_in->in_framerate;
00156         default_asset->width = mwindow->edl->session->vconfig_in->w;
00157         default_asset->height = mwindow->edl->session->vconfig_in->h;
00158         default_asset->channels = defaults->get("RECORD_CHANNELS", 2);
00159         default_asset->layers = 1;
00160 
00161 
00162 // These are locked by a specific driver.
00163         if(mwindow->edl->session->vconfig_in->driver == CAPTURE_LML ||
00164                 mwindow->edl->session->vconfig_in->driver == CAPTURE_BUZ ||
00165                 mwindow->edl->session->vconfig_in->driver == VIDEO4LINUX2JPEG)
00166                 strncpy(default_asset->vcodec, QUICKTIME_MJPA, 4);
00167         else
00168         if(mwindow->edl->session->vconfig_in->driver == CAPTURE_FIREWIRE ||
00169                 mwindow->edl->session->vconfig_in->driver == CAPTURE_IEC61883)
00170         {
00171                 strncpy(default_asset->vcodec, QUICKTIME_DVSD, 4);
00172         }
00173 
00174 
00175 
00176 
00177 // Load batches
00178         int total_batches = defaults->get("TOTAL_BATCHES", 1);
00179         if(total_batches < 1) total_batches = 1;
00180         for(int i = 0; i < total_batches; i++)
00181         {
00182                 Batch *batch = new_batch();
00183                 Asset *asset = batch->assets.values[0];
00184 
00185                 sprintf(string, "RECORD_PATH_%d", i);
00186                 defaults->get(string, asset->path);
00187                 sprintf(string, "RECORD_CHANNEL_%d", i);
00188                 batch->channel = defaults->get(string, batch->channel);
00189                 sprintf(string, "RECORD_STARTTYPE_%d", i);
00190                 batch->start_type = defaults->get(string, batch->start_type);
00191                 sprintf(string, "RECORD_STARTDAY_%d", i);
00192                 batch->start_day = defaults->get(string, batch->start_day);
00193                 sprintf(string, "RECORD_STARTTIME_%d", i);
00194                 batch->start_time = defaults->get(string, batch->start_time);
00195                 sprintf(string, "RECORD_DURATION_%d", i);
00196                 batch->duration = defaults->get(string, batch->duration);
00197                 sprintf(string, "RECORD_MODE_%d", i);
00198                 batch->record_mode = defaults->get(string, batch->record_mode);
00199                 sprintf(string, "BATCH_ENABLED_%d", i);
00200                 batch->enabled = defaults->get(string, batch->enabled);
00201         }
00202 
00203 
00204         load_mode = defaults->get("RECORD_LOADMODE", LOAD_PASTE);
00205 
00206         monitor_audio = defaults->get("RECORD_MONITOR_AUDIO", 1);
00207         monitor_video = defaults->get("RECORD_MONITOR_VIDEO", 1);
00208         video_window_open = defaults->get("RECORD_MONITOR_OPEN", 1);
00209         video_x = defaults->get("RECORD_VIDEO_X", 0);
00210         video_y = defaults->get("RECORD_VIDEO_Y", 0);
00211         video_zoom = defaults->get("RECORD_VIDEO_Z", (float)1);
00212 
00213         picture->load_defaults();
00214 
00215         reverse_interlace = defaults->get("REVERSE_INTERLACE", 0);
00216         for(int i = 0; i < MAXCHANNELS; i++) 
00217         {
00218                 sprintf(string, "RECORD_DCOFFSET_%d", i);
00219                 dc_offset[i] = defaults->get(string, 0);
00220         }
00221         fill_frames = defaults->get("FILL_DROPPED_FRAMES", 0);
00222         return 0;
00223 }
00224 
00225 int Record::save_defaults()
00226 {
00227         char string[BCTEXTLEN];
00228         Defaults *defaults = mwindow->defaults;
00229         editing_batch = 0;
00230 
00231 // Save default asset
00232         default_asset->save_defaults(defaults,
00233                 "RECORD_",
00234                 1,
00235                 !fixed_compression,
00236                 1,
00237                 1,
00238                 1);
00239 
00240         defaults->update("RECORD_CHANNELS", default_asset->channels);
00241 
00242 
00243 
00244 
00245 
00246 
00247         defaults->update("TOTAL_BATCHES", batches.total);
00248         for(int i = 0; i < batches.total; i++)
00249         {
00250                 Batch *batch = batches.values[i];
00251                 Asset *asset = batch->assets.values[0];
00252 
00253                 sprintf(string, "RECORD_PATH_%d", i);
00254                 defaults->update(string, asset->path);
00255                 sprintf(string, "RECORD_CHANNEL_%d", i);
00256                 defaults->update(string, batch->channel);
00257                 sprintf(string, "RECORD_STARTTYPE_%d", i);
00258                 defaults->update(string, batch->start_type);
00259                 sprintf(string, "RECORD_STARTDAY_%d", i);
00260                 defaults->update(string, batch->start_day);
00261                 sprintf(string, "RECORD_STARTTIME_%d", i);
00262                 defaults->update(string, batch->start_time);
00263                 sprintf(string, "RECORD_DURATION_%d", i);
00264                 defaults->update(string, batch->duration);
00265                 sprintf(string, "RECORD_MODE_%d", i);
00266                 defaults->update(string, batch->record_mode);
00267                 sprintf(string, "BATCH_ENABLED_%d", i);
00268                 defaults->update(string, batch->enabled);
00269         }
00270 
00271 
00272         defaults->update("RECORD_LOADMODE", load_mode);
00273         defaults->update("RECORD_MONITOR_AUDIO", monitor_audio);
00274         defaults->update("RECORD_MONITOR_VIDEO", monitor_video);
00275         defaults->update("RECORD_MONITOR_OPEN", video_window_open);
00276         defaults->update("RECORD_VIDEO_X", video_x);
00277         defaults->update("RECORD_VIDEO_Y", video_y);
00278         defaults->update("RECORD_VIDEO_Z", video_zoom);
00279         
00280         picture->save_defaults();
00281         defaults->update("REVERSE_INTERLACE", reverse_interlace);
00282         for(int i = 0; i < MAXCHANNELS; i++)
00283         {
00284                 sprintf(string, "RECORD_DCOFFSET_%d", i);
00285                 defaults->update(string, dc_offset[i]);
00286         }
00287         defaults->update("FILL_DROPPED_FRAMES", fill_frames);
00288 
00289         return 0;
00290 }
00291 
00292 void Record::configure_batches()
00293 {
00294         strcpy(batches.values[0]->assets.values[0]->path, default_asset->path);
00295         for(int i = 0; i < batches.total; i++)
00296         {
00297                 Batch *batch = batches.values[i];
00298 // Update format
00299                 batch->get_current_asset()->copy_format(default_asset);
00300 
00301 // Update news
00302                 batch->calculate_news();
00303         }
00304 }
00305 
00306 void Record::source_to_text(char *string, Batch *batch)
00307 {
00308 // Update source
00309         strcpy(string, "Record::source_to_text: not implemented");
00310         switch(mwindow->edl->session->vconfig_in->driver)
00311         {
00312                 case VIDEO4LINUX:
00313                 case VIDEO4LINUX2:
00314                 case CAPTURE_BUZ:
00315                 case VIDEO4LINUX2JPEG:
00316                         if(batch->channel < 0 || batch->channel >= channeldb->size())
00317                                 sprintf(string, _("None"));
00318                         else
00319                                 sprintf(string, channeldb->get(batch->channel)->title);
00320                         break;
00321         }
00322 }
00323 
00324 
00325 char* Record::get_channeldb_prefix()
00326 {
00327         char *path = "";
00328         switch(mwindow->edl->session->vconfig_in->driver)
00329         {
00330                 case VIDEO4LINUX:
00331                         path = "channels_v4l";
00332                         break;
00333                 case VIDEO4LINUX2:
00334                         path = "channels_v4l2";
00335                         break;
00336                 case VIDEO4LINUX2JPEG:
00337                         path = "channels_v4l2jpeg";
00338                         break;
00339                 case CAPTURE_BUZ:
00340                         path = "channels_buz";
00341                         break;
00342         }
00343 
00344         return path;
00345 }
00346 
00347 void Record::run()
00348 {
00349         int result = 0, format_error = 0;
00350         int64_t start, end;
00351         record_gui = 0;
00352 
00353 // Default asset forms the first path in the batch capture
00354 // and the file format for all operations.
00355         default_asset = new Asset;
00356         prompt_cancel = 0;
00357 
00358 // Determine information about the device.
00359         channeldb->load(get_channeldb_prefix());
00360         fixed_compression = VideoDevice::is_compressed(
00361                 mwindow->edl->session->vconfig_in->driver,
00362                 0,
00363                 1);
00364         load_defaults();
00365 
00366         if(fixed_compression)
00367         {
00368                 strcpy(default_asset->vcodec, 
00369                         VideoDevice::get_vcodec(mwindow->edl->session->vconfig_in->driver));
00370         }
00371 
00372 
00373         menu_item->current_state = RECORD_INTRO;
00374 
00375 // Get information about the file format
00376         do
00377         {
00378                 int x = mwindow->gui->get_root_w(0, 1) / 2 - RECORD_WINDOW_WIDTH / 2;
00379                 int y = mwindow->gui->get_root_h(1) / 2 - RECORD_WINDOW_HEIGHT / 2;
00380                 
00381                 window_lock->lock("Record::run 1");
00382                 record_window = new RecordWindow(mwindow, this, x, y);
00383                 record_window->create_objects();
00384                 window_lock->unlock();
00385 
00386 
00387                 result = record_window->run_window();
00388                 window_lock->lock("Record::run 2");
00389                 delete record_window;
00390                 record_window = 0;
00391                 window_lock->unlock();
00392 
00393 
00394 
00395                 if(!result)
00396                 {
00397                         FormatCheck check_format(default_asset);
00398                         format_error = check_format.check_format();
00399                 }
00400         }while(format_error && !result);
00401 
00402         channeldb->save(get_channeldb_prefix());
00403         save_defaults();
00404         mwindow->save_defaults();
00405 
00406         configure_batches();
00407         current_batch = 0;
00408         editing_batch = 0;
00409 
00410 // Run recordgui
00411         if(!result)
00412         {
00413                 edl = new EDL;
00414                 edl->create_objects();
00415                 edl->session->output_w = default_asset->width;
00416                 edl->session->output_h = default_asset->height;
00417                 edl->session->aspect_w = mwindow->edl->session->aspect_w;
00418                 edl->session->aspect_h = mwindow->edl->session->aspect_h;
00419 
00420                 window_lock->lock("Record::run 3");
00421 SET_TRACE
00422                 record_gui = new RecordGUI(mwindow, this);
00423 SET_TRACE
00424                 record_gui->load_defaults();
00425 SET_TRACE
00426                 record_gui->create_objects();
00427 SET_TRACE
00428 
00429                 record_monitor = new RecordMonitor(mwindow, this);
00430 SET_TRACE
00431                 record_monitor->create_objects();
00432 SET_TRACE
00433                 record_gui->update_batch_sources();
00434 SET_TRACE
00435 
00436                 menu_item->current_state = RECORD_CAPTURING;
00437 SET_TRACE
00438                 record_engine = new RecordThread(mwindow, this);
00439 SET_TRACE
00440                 record_engine->create_objects();
00441 SET_TRACE
00442                 monitor_engine = new RecordThread(mwindow, this);
00443 SET_TRACE
00444                 monitor_engine->create_objects();
00445 SET_TRACE
00446 
00447 
00448                 record_gui->show_window();
00449 SET_TRACE
00450                 record_gui->flush();
00451 SET_TRACE
00452                 if(video_window_open)
00453                 {
00454                         record_monitor->window->show_window();
00455                         record_monitor->window->raise_window();
00456                         record_monitor->window->flush();
00457                 }
00458 SET_TRACE
00459 
00460                 start_monitor();
00461 SET_TRACE
00462 
00463                 window_lock->unlock();
00464 
00465                 result = record_gui->run_window();
00466 
00467 // Force monitor to quit without resuming
00468                 if(monitor_engine->record_video) 
00469                         monitor_engine->record_video->batch_done = 1;
00470                 else
00471                         monitor_engine->record_audio->batch_done = 1;
00472 
00473                 stop_operation(0);;
00474 
00475                 close_output_file();
00476 
00477                 window_lock->lock("Record::run 4");
00478                 delete record_monitor;
00479                 record_monitor = 0;
00480 
00481                 record_gui->save_defaults();
00482 
00483 TRACE("Record::run 1");
00484                 delete record_gui;
00485                 record_gui = 0;
00486                 window_lock->unlock();
00487 
00488 TRACE("Record::run 2");
00489                 delete edl;
00490 
00491 TRACE("Record::run 3");
00492         }
00493 
00494         menu_item->current_state = RECORD_NOTHING;
00495 
00496 // Save everything again
00497         save_defaults();
00498 
00499 
00500 
00501 
00502 
00503 // Paste into EDL
00504         if(!result && load_mode != LOAD_NOTHING)
00505         {
00506                 mwindow->gui->lock_window("Record::run");
00507                 ArrayList<EDL*> new_edls;
00508 
00509 
00510 // Paste assets
00511                 for(int i = 0; i < batches.total; i++)
00512                 {
00513                         Batch *batch = batches.values[i];
00514                         Asset *asset = batch->get_current_asset();
00515 
00516                         if(batch->recorded)
00517                         {
00518                                 for(int j = 0; j < batch->assets.total; j++)
00519                                 {
00520                                         EDL *new_edl = new EDL;
00521                                         new_edl->create_objects();
00522                                         new_edl->copy_session(mwindow->edl);
00523                                         mwindow->asset_to_edl(new_edl, 
00524                                                 batch->assets.values[j], 
00525                                                 batch->labels);
00526                                         new_edls.append(new_edl);
00527                                 }
00528                         }
00529                 }
00530 
00531                 if(new_edls.total)
00532                 {
00533 
00534 // For pasting, clear the active region
00535                         if(load_mode == LOAD_PASTE)
00536                         {
00537                                 mwindow->clear(0);
00538                         }
00539 
00540                         mwindow->paste_edls(&new_edls, 
00541                                 load_mode,
00542                                 0,
00543                                 -1,
00544                                 mwindow->edl->session->labels_follow_edits,
00545                                 mwindow->edl->session->plugins_follow_edits);
00546 //printf("Record::run 7\n");
00547 
00548                         new_edls.remove_all_objects();
00549 //printf("Record::run 8\n");
00550 
00551                         mwindow->save_backup();
00552                         mwindow->undo->update_undo(_("record"), LOAD_ALL);
00553                         mwindow->restart_brender();
00554                         mwindow->update_plugin_guis();
00555                         mwindow->gui->update(1, 
00556                                 2,
00557                                 1,
00558                                 1,
00559                                 1,
00560                                 1,
00561                                 0);
00562                         mwindow->sync_parameters(CHANGE_ALL);
00563                 }
00564                 mwindow->gui->unlock_window();
00565         }
00566 
00567 // Delete everything
00568         script = 0;
00569         batches.remove_all_objects();
00570         delete default_asset;
00571 }
00572 
00573 void Record::activate_batch(int number, int stop_operation)
00574 {
00575         if(number != current_batch)
00576         {
00577                 if(stop_operation) this->stop_operation(1);
00578                 close_output_file();
00579                 get_current_batch()->calculate_news();
00580 
00581                 current_batch = number;
00582                 record_gui->update_batches();
00583                 record_gui->update_position(current_display_position());
00584                 record_gui->update_batch_tools();
00585         }
00586 }
00587 
00588 void Record::delete_batch()
00589 {
00590 // Abort if one batch left
00591         if(batches.total > 1)
00592         {
00593 // Stop operation if active batch
00594                 if(current_batch == editing_batch)
00595                 {
00596                         if(current_batch < batches.total - 1)
00597                                 activate_batch(current_batch + 1, 1);
00598                         else
00599                                 activate_batch(current_batch - 1, 1);
00600 
00601                         delete batches.values[editing_batch];
00602                         batches.remove_number(editing_batch);
00603                         editing_batch = current_batch;
00604                 }
00605                 else
00606                 {
00607                         if(current_batch > editing_batch) current_batch--;
00608                         delete batches.values[editing_batch];
00609                         batches.remove_number(editing_batch);
00610                         if(editing_batch >= batches.total) editing_batch--;
00611                 }
00612                 record_gui->update_batch_tools();
00613         }
00614 }
00615 
00616 void Record::change_editing_batch(int number)
00617 {
00618         this->editing_batch = number;
00619         record_gui->update_batch_tools();
00620 }
00621 
00622 Batch* Record::new_batch()
00623 {
00624         Batch *result = new Batch(mwindow, this);
00625 //printf("Record::new_batch 1\n");
00626         result->create_objects();
00627         batches.append(result);
00628         result->get_current_asset()->copy_format(default_asset);
00629         
00630 //printf("Record::new_batch 1\n");
00631 
00632         result->create_default_path();
00633         result->calculate_news();
00634         if(get_editing_batch()) result->copy_from(get_editing_batch());
00635         editing_batch = batches.total - 1;
00636 //printf("Record::new_batch 1\n");
00637 // Update GUI if created yet
00638         if(record_gui) record_gui->update_batch_tools();
00639 //printf("Record::new_batch 2\n");
00640         return result;
00641 }
00642 
00643 int Record::delete_output_file()
00644 {
00645         FILE *test;
00646 
00647 
00648 
00649 // Delete old file
00650         if(!file)
00651         {
00652                 Batch *batch = get_current_batch();
00653                 if(batch && (test = fopen(batch->get_current_asset()->path, "r")))
00654                 {
00655                         fclose(test);
00656 
00657                         record_gui->lock_window("Record::delete_output_file");
00658 
00659 // Update GUI
00660                         sprintf(batch->news, _("Deleting"));
00661                         record_gui->update_batches();
00662 
00663 // Remove it
00664                         remove(batch->get_current_asset()->path);
00665 
00666 // Update GUI
00667                         sprintf(batch->news, _("OK"));
00668                         record_gui->update_batches();
00669 
00670                         record_gui->unlock_window();
00671                 }
00672         }
00673         return 0;
00674 }
00675 
00676 int Record::open_output_file()
00677 {
00678         int result = 0;
00679 // Create initial file for the batch
00680         if(!file)
00681         {
00682                 Batch *batch = get_current_batch();
00683                 delete_output_file();
00684 
00685                 file = new File;
00686                 result = file->open_file(mwindow->preferences, 
00687                         batch->get_current_asset(), 
00688                         0, 
00689                         1, 
00690                         default_asset->sample_rate, 
00691                         default_asset->frame_rate);
00692 //printf("Record::open_output_file 1\n");
00693 
00694                 if(result)
00695                 {
00696                         delete file;
00697                         file = 0;
00698                 }
00699                 else
00700                 {
00701                         mwindow->sighandler->push_file(file);
00702                         IndexFile::delete_index(mwindow->preferences, 
00703                                 batch->get_current_asset());
00704                         file->set_processors(mwindow->preferences->processors);
00705                         batch->calculate_news();
00706                         record_gui->lock_window("Record::open_output_file");
00707                         record_gui->update_batches();
00708                         record_gui->unlock_window();
00709                 }
00710 //printf("Record::open_output_file 1\n");
00711         }
00712 //printf("Record::open_output_file 2\n");
00713         return result;
00714 }
00715 
00716 int Record::init_next_file()
00717 {
00718         Batch *batch = get_current_batch();
00719         Asset *asset;
00720 
00721         if(file)
00722         {
00723                 mwindow->sighandler->pull_file(file);
00724                 file->close_file();
00725                 delete file;
00726                 file = 0;
00727         }
00728 
00729         batch->current_asset++;
00730         batch->assets.append(asset = new Asset);
00731         *asset = *default_asset;
00732         sprintf(asset->path, "%s%03d", asset->path, batch->current_asset);
00733         int result = open_output_file();
00734         return result;
00735 }
00736 
00737 // Rewind file at the end of a loop.
00738 // This is called by RecordThread.
00739 void Record::rewind_file()
00740 {
00741         if(file)
00742         {
00743                 if(default_asset->audio_data) 
00744                         file->set_audio_position(0, default_asset->frame_rate);
00745                 if(default_asset->video_data)
00746                         file->set_video_position(0, default_asset->frame_rate);
00747         }
00748 
00749         get_current_batch()->current_sample = 0;
00750         get_current_batch()->current_frame = 0;
00751         record_gui->lock_window("Record::rewind_file");
00752         record_gui->update_position(0);
00753         record_gui->unlock_window();
00754 }
00755 
00756 void Record::start_over()
00757 {
00758         stop_operation(1);
00759 
00760         Batch *batch = get_current_batch();
00761         if(file)
00762         {
00763                 mwindow->sighandler->pull_file(file);
00764                 file->close_file();
00765                 delete file;
00766                 file = 0;
00767         }
00768 
00769         get_current_batch()->start_over();
00770 
00771         record_gui->lock_window("Record::start_over");
00772         record_gui->update_position(0);
00773         record_gui->update_batches();
00774         record_gui->unlock_window();
00775 }
00776 
00777 void Record::close_output_file()
00778 {
00779 // Can't close until recordmonitor is done
00780 //printf("Record::close_output_file 1\n");
00781         if(file)
00782         {
00783                 mwindow->sighandler->pull_file(file);
00784                 file->close_file();
00785                 delete file;
00786                 file = 0;
00787         }
00788 //printf("Record::close_output_file 2\n");
00789 }
00790 
00791 void Record::toggle_label()
00792 {
00793         get_current_batch()->toggle_label(current_display_position());
00794         record_gui->update_labels(current_display_position());
00795 }
00796 
00797 void Record::get_audio_write_length(int &buffer_size, 
00798         int &fragment_size)
00799 {
00800         fragment_size = 1;
00801         while(fragment_size < default_asset->sample_rate / mwindow->edl->session->record_speed) 
00802                 fragment_size *= 2;
00803         fragment_size /= 2;
00804         CLAMP(fragment_size, 1024, 32768);
00805 
00806         for(buffer_size = fragment_size; 
00807                 buffer_size < mwindow->edl->session->record_write_length; 
00808                 buffer_size += fragment_size)
00809                 ;
00810 }
00811 
00812 Batch* Record::get_current_batch()
00813 {
00814         if(batches.total)
00815                 return batches.values[current_batch];
00816         else
00817                 return 0;
00818 }
00819 
00820 int Record::get_next_batch()
00821 {
00822         int i = current_batch;
00823         while(i < batches.total - 1)
00824         {
00825                 i++;
00826                 if(batches.values[i]->enabled) return i;
00827         }
00828         return -1;
00829 }
00830 
00831 
00832 Batch* Record::get_editing_batch()
00833 {
00834 //printf("Record::get_editing_batch %d %d\n", batches.total, editing_batch);
00835 
00836         if(batches.total)
00837                 return batches.values[editing_batch];
00838         else
00839                 return 0;
00840 }
00841 
00842 char* Record::current_mode()
00843 {
00844         return Batch::mode_to_text(get_current_batch()->record_mode);
00845 }
00846 
00847 int64_t Record::batch_video_offset()
00848 {
00849         return (int64_t)((double)get_current_batch()->file_offset * 
00850                 default_asset->frame_rate + 0.5);
00851 }
00852 
00853 int64_t Record::current_audio_position()
00854 {
00855         if(file)
00856         {
00857                 return (int64_t)(file->get_audio_position(default_asset->sample_rate) + 
00858                         get_current_batch()->file_offset + 0.5);
00859         }
00860         return 0;
00861 }
00862 
00863 int64_t Record::current_video_position()
00864 {
00865         if(file)
00866         {
00867                 return file->get_video_position(default_asset->frame_rate) + 
00868                         (int64_t)((double)get_current_batch()->file_offset / 
00869                                 default_asset->sample_rate * 
00870                                 default_asset->frame_rate + 
00871                                 0.5);
00872         }
00873         return 0;
00874 }
00875 
00876 double Record::current_display_position()
00877 {
00878 //printf("Record::current_display_position %d %d\n", get_current_batch()->current_sample, get_current_batch()->file_offset);
00879 
00880 
00881         if(default_asset->video_data)
00882                 return (double)get_current_batch()->current_frame / 
00883                         default_asset->frame_rate + 
00884                         get_current_batch()->file_offset;
00885         else
00886                 return (double)get_current_batch()->current_sample / 
00887                         default_asset->sample_rate + 
00888                         get_current_batch()->file_offset;
00889         return 0;
00890 }
00891 
00892 char* Record::current_source()
00893 {
00894         return get_current_batch()->get_source_text();
00895 }
00896 
00897 char* Record::current_news()
00898 {
00899         return batches.values[current_batch]->news;
00900 }
00901 
00902 Asset* Record::current_asset()
00903 {
00904         return batches.values[current_batch]->get_current_asset();
00905 }
00906 
00907 double* Record::current_start()
00908 {
00909         return &batches.values[current_batch]->start_time;
00910 }
00911 
00912 int Record::get_current_channel()
00913 {
00914         return get_current_batch()->channel;
00915 }
00916 
00917 int Record::get_editing_channel()
00918 {
00919         return get_editing_batch()->channel;
00920 }
00921 
00922 Channel* Record::get_current_channel_struct()
00923 {
00924         int channel = get_current_channel();
00925         if(channel >= 0 && channel < channeldb->size())
00926         {
00927                 return channeldb->get(channel);
00928         }
00929         return 0;
00930 }
00931 
00932 double* Record::current_duration()
00933 {
00934         return &batches.values[current_batch]->duration;
00935 }
00936 
00937 int64_t Record::current_duration_samples()
00938 {
00939         return (int64_t)((float)batches.values[current_batch]->duration * default_asset->sample_rate + 0.5);
00940 }
00941 
00942 int64_t Record::current_duration_frames()
00943 {
00944         return (int64_t)((float)batches.values[current_batch]->duration * default_asset->frame_rate + 0.5);
00945 }
00946 
00947 int* Record::current_offset_type()
00948 {
00949         return &batches.values[current_batch]->start_type;
00950 }
00951 
00952 ArrayList<Channel*>* Record::get_video_inputs() 
00953 { 
00954         if(default_asset->video_data && vdevice) 
00955                 return vdevice->get_inputs();
00956         else
00957                 return 0;
00958 }
00959 
00960 int64_t Record::sync_position()
00961 {
00962         switch(capture_state)
00963         {
00964                 case IS_DONE:
00965                         return -1;
00966                         break;    
00967                 case IS_MONITORING:
00968                         return monitor_engine->sync_position();
00969                         break;    
00970                 case IS_DUPLEXING: 
00971                 case IS_RECORDING: 
00972                         return record_engine->sync_position();
00973                         break;    
00974         }
00975         return 0;
00976 }
00977 
00978 
00979 int Record::open_input_devices(int duplex, int context)
00980 {
00981         int audio_opened = 0;
00982         int video_opened = 0;
00983         AudioInConfig *aconfig_in = mwindow->edl->session->aconfig_in;
00984 
00985 // Create devices
00986         if(default_asset->audio_data && context != CONTEXT_SINGLEFRAME)
00987                 adevice = new AudioDevice;
00988         else
00989                 adevice = 0;
00990 
00991         if(default_asset->video_data)
00992                 vdevice = new VideoDevice(mwindow);
00993         else
00994                 vdevice = 0;
00995 
00996 // Initialize sharing
00997         if(adevice && vdevice)
00998         {
00999                 vdevice->set_adevice(adevice);
01000                 adevice->set_vdevice(vdevice);
01001         }
01002 
01003 // Configure audio
01004         if(adevice)
01005         {
01006                 adevice->set_software_positioning(mwindow->edl->session->record_software_position);
01007                 adevice->set_record_dither(default_asset->dither);
01008 
01009                 for(int i = 0; i < default_asset->channels; i++)
01010                 {
01011                         adevice->set_dc_offset(dc_offset[i], i);
01012                 }
01013 
01014 // Initialize full duplex
01015 // Duplex is only needed if the timeline and the recording have audio
01016                 if(duplex && mwindow->edl->tracks->playable_audio_tracks())
01017                 {
01018 // Case 1: duplex device is identical to input device
01019                         if(AudioInConfig::is_duplex(aconfig_in, mwindow->edl->session->aconfig_duplex))
01020                         {
01021                                 adevice->open_duplex(mwindow->edl->session->aconfig_duplex,
01022                                                         default_asset->sample_rate,
01023                                                         get_in_length(),
01024                                                         mwindow->edl->session->real_time_playback);
01025                                 audio_opened = 1;
01026                         }
01027                         else
01028 // Case 2: two separate devices
01029                         {
01030                                 adevice->open_output(mwindow->edl->session->aconfig_duplex,
01031                                                 default_asset->sample_rate,
01032                                                 mwindow->edl->session->playback_buffer,
01033                                                 mwindow->edl->session->real_time_playback);
01034                         }
01035                 }
01036 
01037                 if(!audio_opened)
01038                 {
01039                         adevice->open_input(mwindow->edl->session->aconfig_in, 
01040                                 mwindow->edl->session->vconfig_in, 
01041                                 default_asset->sample_rate, 
01042                                 get_in_length());
01043                 }
01044         }
01045 
01046 
01047 // Initialize video
01048         if(vdevice)
01049         {
01050                 vdevice->set_quality(default_asset->jpeg_quality);
01051                 vdevice->open_input(mwindow->edl->session->vconfig_in, 
01052                         video_x, 
01053                         video_y, 
01054                         video_zoom,
01055                         default_asset->frame_rate);
01056 
01057 // Get configuration parameters from device probe
01058                 color_model = vdevice->get_best_colormodel(default_asset);
01059                 master_channel->copy_usage(vdevice->channel);
01060                 picture->copy_usage(vdevice->picture);
01061                 vdevice->set_field_order(reverse_interlace);
01062 
01063 // Set the device configuration
01064                 set_channel(get_current_channel());
01065         }
01066 
01067         return 0;
01068 }
01069 
01070 int Record::close_input_devices()
01071 {
01072         if(vdevice)
01073         {
01074                 vdevice->close_all();
01075                 delete vdevice;
01076                 vdevice = 0;
01077         }
01078 
01079         if(adevice)
01080         {
01081                 adevice->close_all();
01082                 delete adevice;
01083                 adevice = 0;
01084         }
01085 
01086         return 0;
01087 }
01088 
01089 int Record::start_recording(int duplex, int context)
01090 {
01091         if(capture_state != IS_RECORDING)
01092         {
01093                 pause_monitor();
01094 
01095 // Want the devices closed during file deletion to avoid buffer overflow
01096                 delete_output_file();
01097 
01098 // These two contexts need to open the device here to allow full duplex.  
01099 // Batch context opens them in RecordThread::run
01100                 if(context == CONTEXT_INTERACTIVE ||
01101                         context == CONTEXT_SINGLEFRAME)
01102                         open_input_devices(duplex, context);
01103 
01104                 prompt_cancel = 1;
01105 
01106 // start the duplex engine if necessary
01107 // OSS < 3.9 crashes if recording starts before playback
01108 // OSS >= 3.9 crashes if playback starts before recording
01109                 if(duplex)
01110                 {
01111                         capture_state = IS_DUPLEXING;
01112                 }
01113                 else
01114                         capture_state = IS_RECORDING;
01115 
01116 // Toggle once to cue the user that we're not dead.
01117                 if(context == CONTEXT_BATCH)
01118                 {
01119                         record_gui->lock_window("Record::start_recording");
01120                         record_gui->flash_batch();
01121                         record_gui->unlock_window();
01122                 }
01123                 record_engine->start_recording(0, context);
01124         }
01125         return 0;
01126 }
01127 
01128 int Record::start_monitor()
01129 {
01130         monitor_timer.update();
01131         open_input_devices(0, CONTEXT_INTERACTIVE);
01132         monitor_engine->start_recording(1, CONTEXT_INTERACTIVE);
01133         capture_state = IS_MONITORING;
01134         return 0;
01135 }
01136 
01137 int Record::stop_monitor()
01138 {
01139         monitor_engine->stop_recording(0);
01140         return 0;
01141 }
01142 
01143 int Record::pause_monitor()
01144 {
01145         if(capture_state == IS_MONITORING)
01146         {
01147                 monitor_engine->pause_recording();
01148         }
01149         return 0;
01150 }
01151 
01152 int Record::resume_monitor()
01153 {
01154         if(capture_state != IS_MONITORING)
01155         {
01156                 capture_state = IS_MONITORING;
01157                 monitor_timer.update();
01158                 open_input_devices(0, CONTEXT_INTERACTIVE);
01159                 monitor_engine->resume_recording();
01160         }
01161         return 0;
01162 }
01163 
01164 int Record::stop_duplex()
01165 {
01166         return 0;
01167 }
01168 
01169 int Record::stop_operation(int resume_monitor)
01170 {
01171         switch(capture_state)
01172         {
01173                 case IS_MONITORING:
01174                         if(!resume_monitor) monitor_engine->stop_recording(0);
01175                         break;
01176                 case IS_RECORDING:
01177                         record_engine->stop_recording(resume_monitor);
01178                         break;
01179                 case IS_DUPLEXING:
01180                         break;
01181                 case IS_PREVIEWING:
01182                         break;
01183         }
01184         return 0;
01185 }
01186 
01187 
01188 // Remember to change meters if you change this.
01189 // Return the size of the fragments to read from the audio device.
01190 int Record::get_in_length() 
01191 {
01192         int64_t fragment_size = 1;
01193         while(fragment_size < default_asset->sample_rate / mwindow->edl->session->record_speed) fragment_size *= 2;
01194         fragment_size /= 2;
01195         return fragment_size;
01196 }
01197 
01198 int Record::set_video_picture()
01199 {
01200         if(default_asset->video_data && vdevice)
01201                 vdevice->set_picture(picture);
01202         return 0;
01203 }
01204 
01205 void Record::set_translation(int x, int y)
01206 {
01207         video_x = x;
01208         video_y = y;
01209         if(default_asset->video_data && vdevice)
01210                 vdevice->set_translation(video_x, video_y);
01211 }
01212 
01213 
01214 int Record::set_channel(int channel)
01215 {
01216         if(channel >= 0 && channel < channeldb->size())
01217         {
01218                 char string[BCTEXTLEN];
01219                 get_editing_batch()->channel = channel;
01220                 source_to_text(string, get_editing_batch());
01221 
01222 
01223                 record_gui->lock_window("Record::set_channel");
01224                 record_gui->batch_source->update(string);
01225                 record_monitor->window->channel_picker->channel_text->update(string);
01226                 record_gui->update_batches();
01227                 record_gui->unlock_window();
01228 
01229 
01230                 if(vdevice)
01231                 {
01232                         vdevice->set_channel(channeldb->get(channel));
01233                         set_video_picture();
01234                 }
01235         }
01236         return 0;
01237 }
01238 
01239 // Change to a channel not in the db for editing
01240 void Record::set_channel(Channel *channel)
01241 {
01242         if(vdevice) vdevice->set_channel(channel);
01243 }
01244 
01245 int Record::has_signal()
01246 {
01247         if(vdevice) return vdevice->has_signal();
01248         return 0;
01249 }
01250 
01251 void Record::get_current_time(double &seconds, int &day)
01252 {
01253         time_t result = time(0) + 1;
01254         struct tm *struct_tm = localtime(&result);
01255         day = struct_tm->tm_wday;
01256         seconds = struct_tm->tm_hour * 3600 + struct_tm->tm_min * 60 + struct_tm->tm_sec;
01257 }
01258 
01259 
01260 
01261 
01262 
01263 
01264 
01265 
01266 
01267 
01268 
01269 
01270 int Record::get_time_format()
01271 {
01272         return mwindow->edl->session->time_format;
01273 }
01274 
01275 float Record::get_frame_rate()
01276 {
01277         return 0.0;
01278 //      return mwindow->session->frame_rate;
01279 }
01280 
01281 int Record::set_loop_duration(int64_t value)
01282 {
01283         loop_duration = value; 
01284         return 0;
01285 }
01286 
01287 int Record::get_vu_format() { return mwindow->edl->session->meter_format; }
01288 float Record::get_min_db() { return mwindow->edl->session->min_meter_db; }
01289 
01290 int Record::get_rec_mode() { return record_mode; }
01291 int Record::set_rec_mode(int value) { record_mode = value; }
01292 
01293 int Record::get_video_buffersize() { return mwindow->edl->session->video_write_length; }
01294 int Record::get_everyframe() { return mwindow->edl->session->video_every_frame; }
01295 
01296 int Record::get_out_length() { return mwindow->edl->session->playback_buffer; }
01297 int Record::get_software_positioning() { return mwindow->edl->session->record_software_position; }
01298 int64_t Record::get_out_buffersize() { return mwindow->edl->session->playback_buffer; }
01299 int64_t Record::get_in_buffersize() { return mwindow->edl->session->record_write_length; }
01300 int Record::get_realtime() { return realtime; }
01301 int Record::get_meter_speed() { return mwindow->edl->session->record_speed; }
01302 
01303 int Record::enable_duplex() { return mwindow->edl->session->enable_duplex; }
01304 int64_t Record::get_playback_buffer() { return mwindow->edl->session->playback_buffer; }

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