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