Beispiel #1
0
KeyFrame* Plugin::get_keyframe()
{
// Search for keyframe on or before selection
	KeyFrame *result = 
		get_prev_keyframe(track->to_units(edl->local_session->get_selectionstart(1), 0), 
			PLAY_FORWARD);

// Return nearest keyframe if not in automatic keyframe generation
	if(!edl->session->auto_keyframes)
	{
		return result;
	}
	else
// Return new keyframe
	if(result == (KeyFrame*)keyframes->default_auto || 
		result->position != track->to_units(edl->local_session->get_selectionstart(1), 0))
	{
		return (KeyFrame*)keyframes->insert_auto(track->to_units(edl->local_session->get_selectionstart(1), 0));
	}
	else
// Return existing keyframe
	{
		return result;
	}

	return 0;
}
Beispiel #2
0
int Overlay::load_configuration()
{
	KeyFrame *prev_keyframe;
	prev_keyframe = get_prev_keyframe(get_source_position());
	read_data(prev_keyframe);
	return 0;
}
Beispiel #3
0
int RGB601Main::load_configuration()
{
	KeyFrame *prev_keyframe;

	prev_keyframe = get_prev_keyframe(get_source_position());
// Must also switch between interpolation between keyframes and using first keyframe
	read_data(prev_keyframe);
	return 1;
}
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 DelayAudio::load_configuration()
{
	KeyFrame *prev_keyframe;
	prev_keyframe = get_prev_keyframe(get_source_position());
	
	DelayAudioConfig old_config;
	old_config.copy_from(config);
 	read_data(prev_keyframe);

 	if(!old_config.equivalent(config))
 	{
// Reconfigure
		need_reconfigure = 1;
		return 1;
	}
	return 0;
}
int ShapeWipeMain::load_configuration()
{
	read_data(get_prev_keyframe(get_source_position()));
	return 1;
}
int SelTempAvgMain::load_configuration()
{
	KeyFrame *prev_keyframe;
	KeyFrame *temp_keyframe;

	SelTempAvgConfig old_config;
	old_config.copy_from(&config);

	int64_t curpos = get_source_position();
	prev_keyframe = get_prev_keyframe(curpos);
	read_data(prev_keyframe);

	if (curpos == prev_keyframe->position) 
		onakeyframe = 1; 
	else 
		onakeyframe = 0;

	int64_t next_restart_keyframe     = curpos + config.frames;
	int64_t prev_restart_keyframe     = curpos - config.frames;

	for (int i = curpos; i < curpos + config.frames; i++) 
	{
		temp_keyframe = get_next_keyframe(i);
		if ( 
			(temp_keyframe->position < curpos + config.frames/2) && 
			(temp_keyframe->position > curpos) &&
			nextkeyframeisoffsetrestart(temp_keyframe) 
			) 
		{
			next_restart_keyframe = temp_keyframe->position; 
			i = curpos + config.frames;
		} else if (temp_keyframe->position > i)
			i = temp_keyframe->position;
	}
	
	for (int i = curpos; i > curpos - config.frames; i--) 
	{
		temp_keyframe = get_prev_keyframe(i);
		if ( 
			(temp_keyframe->position > curpos - config.frames/2) && 
			(temp_keyframe->position < curpos) && 
			nextkeyframeisoffsetrestart(temp_keyframe) 
			) 
		{
			prev_restart_keyframe = temp_keyframe->position; 
			i = curpos - config.frames;
		} else if (temp_keyframe->position < i)
			i = temp_keyframe->position;
	}

	restartoffset = -config.frames/2;
	
	if (onakeyframe && config.offset_restartmarker_keyframe)
		restartoffset = 0;
	else if ((curpos - prev_restart_keyframe) < config.frames/2) 
		restartoffset = prev_restart_keyframe - curpos;
	else if ((next_restart_keyframe - curpos) < config.frames/2) {
		restartoffset = (next_restart_keyframe - curpos) - config.frames;
		// Probably should put another if in here, (when two "restart" keyframes are close together
	}

	return !old_config.equivalent(&config);
}
Beispiel #8
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;
}