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
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
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
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
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
00299 batch->get_current_asset()->copy_format(default_asset);
00300
00301
00302 batch->calculate_news();
00303 }
00304 }
00305
00306 void Record::source_to_text(char *string, Batch *batch)
00307 {
00308
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
00354
00355 default_asset = new Asset;
00356 prompt_cancel = 0;
00357
00358
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
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
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
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
00497 save_defaults();
00498
00499
00500
00501
00502
00503
00504 if(!result && load_mode != LOAD_NOTHING)
00505 {
00506 mwindow->gui->lock_window("Record::run");
00507 ArrayList<EDL*> new_edls;
00508
00509
00510
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
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
00547
00548 new_edls.remove_all_objects();
00549
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
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
00591 if(batches.total > 1)
00592 {
00593
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
00626 result->create_objects();
00627 batches.append(result);
00628 result->get_current_asset()->copy_format(default_asset);
00629
00630
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
00637
00638 if(record_gui) record_gui->update_batch_tools();
00639
00640 return result;
00641 }
00642
00643 int Record::delete_output_file()
00644 {
00645 FILE *test;
00646
00647
00648
00649
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
00660 sprintf(batch->news, _("Deleting"));
00661 record_gui->update_batches();
00662
00663
00664 remove(batch->get_current_asset()->path);
00665
00666
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
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
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
00711 }
00712
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
00738
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
00780
00781 if(file)
00782 {
00783 mwindow->sighandler->pull_file(file);
00784 file->close_file();
00785 delete file;
00786 file = 0;
00787 }
00788
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
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
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
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
00997 if(adevice && vdevice)
00998 {
00999 vdevice->set_adevice(adevice);
01000 adevice->set_vdevice(vdevice);
01001 }
01002
01003
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
01015
01016 if(duplex && mwindow->edl->tracks->playable_audio_tracks())
01017 {
01018
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
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
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
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
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
01096 delete_output_file();
01097
01098
01099
01100 if(context == CONTEXT_INTERACTIVE ||
01101 context == CONTEXT_SINGLEFRAME)
01102 open_input_devices(duplex, context);
01103
01104 prompt_cancel = 1;
01105
01106
01107
01108
01109 if(duplex)
01110 {
01111 capture_state = IS_DUPLEXING;
01112 }
01113 else
01114 capture_state = IS_RECORDING;
01115
01116
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 }