示例#1
0
bool Scene::setProfile( Profile &p )
{
	bool ok = true;
	double duration = profile.getVideoFrameDuration();
	profile = p;
	double margin = profile.getVideoFrameDuration() / 4.0;
	
	if ( duration != profile.getVideoFrameDuration() ) {
		duration = profile.getVideoFrameDuration();
		for ( int i = 0; i < tracks.count(); ++i ) {
			Track *t = tracks[i];
			for ( int j = 0; j < t->clipCount(); ++j ) {
				Clip *c = t->clipAt( j );
				c->setFrameDuration( duration );
				double newPos = nearestPTS( c->position(), duration );
				if ( !c->getTransition() && j > 0 ) {
					Clip *prev = t->clipAt( j - 1 );
					if ( newPos < prev->position() + prev->length() - margin )
						newPos = prev->position() + prev->length();
					c->setPosition( newPos );
				}
				else if ( canMove( c, c->length(), newPos, i ) )
					move( c, i, newPos, i );
				else
					ok = false;
			}
		}
	}
	
	return ok;
}
示例#2
0
double Scene::nextEdge(double pts)
{
	double margin = profile.getVideoFrameDuration() / 4.0;
	double npts = 0, max = 0;
	
	for ( int i = 0; i < tracks.count(); ++i ) {
		if ( !tracks[ i ]->clipCount() )
			continue;
		Clip *c = tracks[ i ]->clipAt( tracks[ i ]->clipCount() - 1 );
		double d = c->position() + c->length();
		if ( d > max )
			max = d;
	}
	
	npts = max;
	
	for ( int i = 0; i < tracks.count(); ++i ) {
		Track *t = tracks[ i ];
		for ( int j = 0; j < t->clipCount(); ++j ) {
			Clip *c = t->clipAt( j );
			double pos = c->position() - margin;
			if ( pos > pts && pos < npts ) {
				npts = pos + margin;
			}
			else {
				pos += c->length();
				if ( pos > pts && pos < npts ) {
					npts = pos + margin;
				}
			}
		}
	}
	
	return (qAbs(npts - max) < 1) ? max - profile.getVideoFrameDuration() : npts;
}
示例#3
0
bool Scene::canMoveMulti( Clip *clip, double clipLength, double &newPos, int track )
{
	newPos = nearestPTS( newPos, profile.getVideoFrameDuration() );
	double margin = profile.getVideoFrameDuration() / 4.0;
	Track *t = tracks[track];
	int count = t->clipCount();
	
	if ( newPos >= clip->position() )
		return true;

	if ( t->clipAt( 0 ) == clip )
		return true;
	
	Clip *c;
	int k = 0;
	while ( k < count ) {
		c = t->clipAt( k );
		// find clip
		if ( c == clip ) {
			break;
		}
		++k;
	}
	if ( k == count )
		return false;
	
	int clipIndex = k;
	c = t->clipAt( --k );
	if ( newPos - margin < c->position() )
			return false;
	// we are clipB, we can't end before clipA
	if ( newPos + clipLength < c->position() + c->length() - margin )
		return false;
	// we can't overlap with clip before clipA
	if ( --k >= 0 ) {
		Clip *prevA = t->clipAt( k );
		if ( newPos < prevA->position() + prevA->length() - margin )
			return false; 
	}
	// and clipC can't overlap with clipA
	if ( clipIndex < count - 1 ) {
		Clip *clipC = t->clipAt( clipIndex + 1 );
		// clipC has moved with us, calculate its new position
		double cpos = clipC->position() + ( newPos - clip->position() );
		if ( cpos < c->position() + c->length() - margin ) {
			newPos = c->position() + c->length() + clip->position() - clipC->position();
			return true;
		}
	}
	
	return true;
}
示例#4
0
void Scene::removeTransitions( Clip *clip, int oldTrack, int newTrack, int newIndex, double clipPos, double clipLength, double margin, bool multi )
{
	Track *ot = tracks[oldTrack];

	int index = ot->indexOf( clip );
	if ( newTrack != oldTrack || index != newIndex ) {
		clip->removeTransition();
		if ( index < ot->clipCount() - 1 ) {
			Clip *c = ot->clipAt( index + 1 );
			c->removeTransition();
		}
	}
	else {
		if ( !multi && index < ot->clipCount() - 1 ) {
			Clip *c = ot->clipAt( index + 1 );
			if ( clipPos + clipLength - margin < c->position() )
				c->removeTransition();
		}
		if ( index > 0 ) {
			Clip *c = ot->clipAt( index - 1 );
			if ( c->position() + c->length() - margin < clipPos )
				clip->removeTransition();
		}
	}
}
示例#5
0
void Scene::updateTransitions( Clip *clip, int track, double margin )
{
	Track *t = tracks[track];
	int index = t->indexOf( clip );
	
	if ( index > 0 ) {
		Clip *c = t->clipAt( index - 1 );
		if ( clip->position() < c->position() + c->length() - margin )
			clip->setTransition( c->position() + c->length() - clip->position() );
	}
	if ( index < t->clipCount() - 1 ) {
		Clip *c = t->clipAt( index + 1 );
		if ( c->position() < clip->position() + clip->length() - margin )
			c->setTransition( clip->position() + clip->length() - c->position() );
	}
}
示例#6
0
double Scene::previousEdge(double pts)
{
	double margin = profile.getVideoFrameDuration() / 4.0;
	double npts = 0;
	
	for ( int i = 0; i < tracks.count(); ++i ) {
		Track *t = tracks[ i ];
		for ( int j = t->clipCount() -1; j > -1; --j ) {
			Clip *c = t->clipAt( j );
			double pos = c->position() + c->length() + margin;
			if ( pos < pts && pos > npts ) {
				npts = pos;
			}
			else {
				pos -= c->length();
				if ( pos < pts && pos > npts ) {
					npts = pos;
				}
			}
		}
	}
	
	return npts;
}
示例#7
0
bool Scene::checkPlacement( Clip *clip, int track, double clipPos, double clipLength )
{
	double margin = profile.getVideoFrameDuration() / 4.0;
	Track *t = tracks[track];
	int count = t->clipCount();
	
	// no clip in track yet
	if ( !count )
		return true;
	if ( count == 1 && t->clipAt( 0 ) == clip )
		return true;
	
	Clip *c;
	int k = 0;
	while ( k < count ) {
		c = t->clipAt( k );
		// obviously, don't check clip against itself
		if ( clip && c == clip ) {
			++k;
			continue;
		}
		// Track is ordered by Clip::position()
		// so 2 clips can't start at same pts on the same track.
		if ( qAbs( c->position() - clipPos ) < margin )
			return false;
		if ( !clipLessThan( margin, c->position(), c->length(), clipPos ) )
			break;
		++k;
	}
	// we are the last clip in track and don't overlap with anything
	if ( k == count )
		return true;
	// we are clipA
	if ( clipPos < c->position() ) {
		// we can't end after clipB
		if ( c->position() + c->length() < clipPos + clipLength - margin )
			return false;
		// and we can't overlap with clipC
		int j = k + 1;
		while ( j < count ) {
			Clip *next = t->clipAt( j++ );
			if ( clip && next == clip )
				continue;
			if ( next->position() < clipPos + clipLength - margin )
				return false;
			break;
		}
	}
	else {
		// we are clipB, we can't end before clipA
		if ( clipPos + clipLength < c->position() + c->length() - margin )
			return false;
		int j = k + 1;
		while ( j < count ) {
			Clip *next = t->clipAt( j++ );
			if ( clip && next == clip )
				continue;
			// clipC can't overlap with clipA
			if ( next->position() < c->position() + c->length() - margin )
				return false;
			// we can't end after clipC
			if ( next->position() + next->length() < clipPos + clipLength - margin )
				return false;
			// and we can't overlap with clipD
			if ( j < count ) {
				Clip *d = t->clipAt( j );
				if ( d->position() < clipPos + clipLength - margin )
					return false;
			}
			break;
		}
	}

	return true;
}
示例#8
0
Clip* Scene::sceneSplitClip( Clip *clip, int track, double pts )
{
	pts = nearestPTS( pts, profile.getVideoFrameDuration() );
	
	double start = clip->position();
	if (clip->getTransition()) {
		start += clip->getTransition()->length();
	}
	double end = clip->position() + clip->length();
	Track *t = tracks[track];
	int cc = t->clipCount();
	int index = t->indexOf(clip);
	Transition *tail = NULL;
	Clip *next = NULL;
	if (index > -1 && index < cc - 1) {
		next = t->clipAt(index + 1);
		if (next->getTransition()) {
			end -= next->getTransition()->length() + profile.getVideoFrameDuration();
			tail = new Transition(next->getTransition());
		}
	}

	double oldLength = clip->length();
	double newLength = pts - clip->position();
	
	resize( clip, newLength, track );
	Clip *nc = createClip( clip->getSource(), pts, clip->start() + newLength, oldLength - newLength );
	double newPos = nc->position();
	nc->setPosition( newPos );
	FilterCollection *fc = FilterCollection::getGlobalInstance();
	for ( int i = 0; i < clip->videoFilters.count(); ++i ) {
		QSharedPointer<GLFilter> f = clip->videoFilters.at( i );
		for ( int j = 0; j < fc->videoFilters.count(); ++j ) {
			if ( fc->videoFilters[ j ].identifier == f->getIdentifier() ) {
				QSharedPointer<Filter> nf = fc->videoFilters[ j ].create();
				GLFilter *gf = (GLFilter*)nf.data();
				if ( nf->getIdentifier() == "GLCustom" ) {
					GLCustom *gc = (GLCustom*)gf;
					gc->setCustomParams( f->getParameters().last()->value.toString() );
				}
				else if ( nf->getIdentifier() == "GLStabilize"  ) {
					GLStabilize *gs = (GLStabilize*)gf;
					gs->setSource( nc->getSource() );
				}
				f->splitParameters( gf, newLength );
				nf->setPosition( nc->position() );
				nf->setLength( nc->length() );
				nc->videoFilters.append( nf.staticCast<GLFilter>() );
				break;
			}
		}
	}
	for ( int i = 0; i < clip->audioFilters.count(); ++i ) {
		QSharedPointer<AudioFilter> f = clip->audioFilters.at( i );
		for ( int j = 0; j < fc->audioFilters.count(); ++j ) {
			if ( fc->audioFilters[ j ].identifier == f->getIdentifier() ) {
				QSharedPointer<Filter> nf = fc->audioFilters[ j ].create();
				AudioFilter *af = (AudioFilter*)nf.data();
				f->splitParameters( af, newLength );
				nf->setPosition( nc->position() );
				nf->setLength( nc->length() );
				nc->audioFilters.append( nf.staticCast<AudioFilter>() );
				break;
			}
		}
	}
	addClip( nc, track );
	if (tail) {
		next->setTransition(tail);
	}

	return nc;
}