int FreezeFrameMain::load_configuration() { KeyFrame *prev_keyframe = get_prev_keyframe(get_source_position()); int64_t prev_position = edl_to_local(prev_keyframe->position); if(prev_position < get_source_start()) prev_position = get_source_start(); read_data(prev_keyframe); // Invalidate stored frame if(config.enabled) first_frame_position = prev_position; return 0; }
int TimeStretch::start_loop() { scaled_size = (int64_t)(get_total_len() * scale); if(PluginClient::interactive) { char string[BCTEXTLEN]; sprintf(string, "%s...", plugin_title()); progress = start_progress(string, scaled_size); } current_position = get_source_start(); total_written = 0; total_read = 0; // The FFT case if(use_fft) { pitch = new PitchEngine(this); pitch->initialize(WINDOW_SIZE); resample = new TimeStretchResample(this); } else // The windowing case { // Must be short enough to mask beating but long enough to mask humming. stretch = new TimeStretchEngine(scale, PluginAClient::project_sample_rate, WINDOW_TIME); } return 0; }
int InterpolateVideo::load_configuration() { KeyFrame *prev_keyframe, *next_keyframe; InterpolateVideoConfig old_config; old_config.copy_from(&config); next_keyframe = get_next_keyframe(get_source_position()); prev_keyframe = get_prev_keyframe(get_source_position()); // Previous keyframe stays in config object. read_data(prev_keyframe); int64_t prev_position = edl_to_local(prev_keyframe->position); int64_t next_position = edl_to_local(next_keyframe->position); if(prev_position == 0 && next_position == 0) { next_position = prev_position = get_source_start(); } // printf("InterpolateVideo::load_configuration 1 %lld %lld %lld %lld\n", // prev_keyframe->position, // next_keyframe->position, // prev_position, // next_position); // Get range to average in requested rate range_start = prev_position; range_end = next_position; // Use keyframes to determine range if(config.use_keyframes) { active_input_rate = get_framerate(); // Between keyframe and edge of range or no keyframes if(range_start == range_end) { // Between first keyframe and start of effect if(get_source_position() >= get_source_start() && get_source_position() < range_start) { range_start = get_source_start(); } else // Between last keyframe and end of effect if(get_source_position() >= range_start && get_source_position() < get_source_start() + get_total_len()) { // Last frame should be inclusive of current effect range_end = get_source_start() + get_total_len() - 1; } else { // Should never get here ; } } // Make requested rate equal to input rate for this mode. // Convert requested rate to input rate // printf("InterpolateVideo::load_configuration 2 %lld %lld %f %f\n", // range_start, // range_end, // get_framerate(), // config.input_rate); // range_start = (int64_t)((double)range_start / get_framerate() * active_input_rate + 0.5); // range_end = (int64_t)((double)range_end / get_framerate() * active_input_rate + 0.5); } else // Use frame rate { active_input_rate = config.input_rate; // Convert to input frame rate range_start = (int64_t)(get_source_position() / get_framerate() * active_input_rate); range_end = (int64_t)(get_source_position() / get_framerate() * active_input_rate) + 1; } // printf("InterpolateVideo::load_configuration 1 %lld %lld %lld %lld %lld %lld\n", // prev_keyframe->position, // next_keyframe->position, // prev_position, // next_position, // range_start, // range_end); return !config.equivalent(&old_config); }
int TimeAvgMain::process_buffer(VFrame *frame, int64_t start_position, double frame_rate) { int h = frame->get_h(); int w = frame->get_w(); int color_model = frame->get_color_model(); int reset = load_configuration(); // reset buffer on the keyframes int64_t actual_previous_number = start_position; if(get_direction() == PLAY_FORWARD) { actual_previous_number--; if(actual_previous_number < get_source_start()) reset = 1; else { KeyFrame *keyframe = get_prev_keyframe(start_position, 1); if(keyframe->position > 0 && actual_previous_number < keyframe->position) reset = 1; } } else { actual_previous_number++; if(actual_previous_number >= get_source_start() + get_total_len()) reset = 1; else { KeyFrame *keyframe = get_next_keyframe(start_position, 1); if(keyframe->position > 0 && actual_previous_number >= keyframe->position) reset = 1; } } // Allocate accumulation if(!accumulation || reset) { if(!accumulation) accumulation = new unsigned char[w * h * BC_CModels::components(color_model) * MAX(sizeof(float), sizeof(int))]; reset_accum(w, h, color_model); } if(!config.nosubtract && (config.mode == TimeAvgConfig::AVERAGE || config.mode == TimeAvgConfig::ACCUMULATE || config.mode == TimeAvgConfig::GREATER || config.mode == TimeAvgConfig::LESS)) { // Reallocate history if(history) { if(config.frames != history_size) { VFrame **history2; int64_t *history_frame2; int *history_valid2; history2 = new VFrame*[config.frames]; history_frame2 = new int64_t[config.frames]; history_valid2 = new int[config.frames]; // Copy existing frames over int i, j; for(i = 0, j = 0; i < config.frames && j < history_size; i++, j++) { history2[i] = history[j]; history_frame2[i] = history_frame[i]; history_valid2[i] = history_valid[i]; } // Delete extra previous frames and subtract from accumulation for( ; j < history_size; j++) { subtract_accum(history[j]); delete history[j]; } delete [] history; delete [] history_frame; delete [] history_valid; // Create new frames for( ; i < config.frames; i++) { history2[i] = new VFrame(w, h, color_model); history_frame2[i] = -0x7fffffff; history_valid2[i] = 0; } history = history2; history_frame = history_frame2; history_valid = history_valid2; history_size = config.frames; } } else // Allocate history { history = new VFrame*[config.frames]; for(int i = 0; i < config.frames; i++) history[i] = new VFrame(w, h, color_model); history_size = config.frames; history_frame = new int64_t[config.frames]; bzero(history_frame, sizeof(int64_t) * config.frames); history_valid = new int[config.frames]; bzero(history_valid, sizeof(int) * config.frames); } //printf("TimeAvgMain::process_buffer %d\n", __LINE__); // Create new history frames based on current frame int64_t *new_history_frames = new int64_t[history_size]; for(int i = 0; i < history_size; i++) { new_history_frames[history_size - i - 1] = start_position - i; } // Subtract old history frames from accumulation buffer // which are not in the new vector int no_change = 1; for(int i = 0; i < history_size; i++) { // Old frame is valid if(history_valid[i]) { int got_it = 0; for(int j = 0; j < history_size; j++) { // Old frame is equal to a new frame if(history_frame[i] == new_history_frames[j]) { got_it = 1; break; } } // Didn't find old frame in new frames if(!got_it) { if(config.mode == TimeAvgConfig::AVERAGE || config.mode == TimeAvgConfig::ACCUMULATE) { subtract_accum(history[i]); } history_valid[i] = 0; no_change = 0; } } } // If all frames are still valid, assume tweek occurred upstream and reload. if(config.paranoid && no_change) { for(int i = 0; i < history_size; i++) { history_valid[i] = 0; } if(config.mode == TimeAvgConfig::AVERAGE || config.mode == TimeAvgConfig::ACCUMULATE) { reset_accum(w, h, color_model); } } // Add new history frames which are not in the old vector for(int i = 0; i < history_size; i++) { // Find new frame in old vector int got_it = 0; for(int j = 0; j < history_size; j++) { if(history_valid[j] && history_frame[j] == new_history_frames[i]) { got_it = 1; break; } } // Didn't find new frame in old vector if(!got_it) { // Get first unused entry for(int j = 0; j < history_size; j++) { if(!history_valid[j]) { // Load new frame into it history_frame[j] = new_history_frames[i]; history_valid[j] = 1; read_frame(history[j], 0, history_frame[j], frame_rate); if(config.mode == TimeAvgConfig::AVERAGE || config.mode == TimeAvgConfig::ACCUMULATE) { add_accum(history[j]); } break; } } } } delete [] new_history_frames; } else // No history subtraction { if(history) { for(int i = 0; i < config.frames; i++) delete history[i]; delete [] history; history = 0; } if(history_frame) delete [] history_frame; if(history_valid) delete [] history_valid; history_frame = 0; history_valid = 0; history_size = 0; // Clamp prev_frame to history size prev_frame = MAX(start_position - config.frames + 1, prev_frame); // Force reload if not repositioned or just started if(config.paranoid && prev_frame == start_position || prev_frame < 0) { //printf("TimeAvgMain::process_buffer %d\n", __LINE__); prev_frame = start_position - config.frames + 1; prev_frame = MAX(0, prev_frame); reset_accum(w, h, color_model); } // printf("TimeAvgMain::process_buffer %d prev_frame=%lld start_position=%lld\n", // __LINE__, // prev_frame, // start_position); for(int64_t i = prev_frame; i <= start_position; i++) { read_frame(frame, 0, i, frame_rate); add_accum(frame); printf("TimeAvgMain::process_buffer %d prev_frame=%lld start_position=%lld i=%lld\n", __LINE__, prev_frame, start_position, i); } // If we don't add 1, it rereads the frame again prev_frame = start_position + 1; } // Transfer accumulation to output with division if average is desired. transfer_accum(frame); //printf("TimeAvgMain::process_buffer %d\n", __LINE__); return 0; }