[vlmc-devel] Add Track.cpp
Yikai Lu
git at videolan.org
Mon Aug 7 19:18:27 CEST 2017
vlmc | branch: master | Yikai Lu <luyikei.qmltu at gmail.com> | Tue Aug 8 01:06:49 2017 +0900| [27a1cee094441120211d4f4feabb721cffc71601] | committer: Yikai Lu
Add Track.cpp
> https://code.videolan.org/videolan/vlmc/commit/27a1cee094441120211d4f4feabb721cffc71601
---
Makefile.am | 1 +
src/Workflow/Track.cpp | 221 +++++++++++++++++++++++++++++++++++++++++++++++++
src/Workflow/Track.h | 57 +++++++++++++
3 files changed, 279 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index d7b20f3a..8baea3c3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,6 +40,7 @@ vlmc_SOURCES = \
src/Workflow/Helper.cpp \
src/Workflow/MainWorkflow.cpp \
src/Workflow/SequenceWorkflow.cpp \
+ src/Workflow/Track.cpp \
$(NULL)
vlmc_SOURCES += \
diff --git a/src/Workflow/Track.cpp b/src/Workflow/Track.cpp
new file mode 100644
index 00000000..49de8b69
--- /dev/null
+++ b/src/Workflow/Track.cpp
@@ -0,0 +1,221 @@
+#include "Track.h"
+
+#include "Backend/MLT/MLTTrack.h"
+#include "Backend/MLT/MLTMultiTrack.h"
+#include "Transition/Transition.h"
+#include "Tools/VlmcDebug.h"
+
+Track::Track( Workflow::TrackType type )
+ : m_type( type )
+ , m_multitrack( new Backend::MLT::MLTMultiTrack )
+{
+ track( 1 ); // Prepare the first two tracks so that transitions could be inserted
+}
+
+Track::~Track()
+{
+
+}
+
+Workflow::TrackType
+Track::type() const
+{
+ return m_type;
+}
+
+bool
+Track::addClip( QSharedPointer<SequenceWorkflow::ClipInstance> clipInstance, qint64 pos )
+{
+ auto index = insertableTrackIndex( clipInstance, pos );
+ if ( track( index )->insertAt( *clipInstance->clip->input(), pos ) == true )
+ {
+ clipInstance->pos = pos;
+ m_clips[clipInstance->uuid] = QSharedPointer<ClipInstance>::create( clipInstance, index );
+ return true;
+ }
+ return false;
+}
+
+bool
+Track::moveClip( const QUuid& uuid, qint64 pos )
+{
+ auto c = clip( uuid );
+ if ( !c )
+ return false;
+ auto index = insertableTrackIndex( c, pos );
+ if ( index == internalTrackId( uuid ) )
+ {
+ bool ret = track( uuid )->move( c->pos, pos );
+ if ( ret == false )
+ return false;
+ c->pos = pos;
+ return true;
+ }
+ else
+ {
+ bool ret = removeClip( uuid );
+ if ( ret == false )
+ return false;
+ return addClip( c, pos );
+ }
+}
+
+bool
+Track::resizeClip( const QUuid& uuid, qint64 newBegin, qint64 newEnd, qint64 newPos )
+{
+ auto c = clip( uuid );
+ if ( !c )
+ return false;
+ auto index = insertableTrackIndex( c, newPos, newBegin, newEnd );
+ if ( index == internalTrackId( uuid ) )
+ {
+ auto t = track( internalTrackId( uuid ) );
+ bool ret = t->resizeClip( t->clipIndexAt( c->pos ), newBegin, newEnd );
+ if ( ret == false )
+ return false;
+ ret = t->move( c->pos, newPos );
+ if ( ret == false )
+ return false;
+ c->pos = newPos;
+ return true;
+ }
+ else
+ {
+ bool ret = removeClip( uuid );
+ if ( ret == false )
+ return false;
+ c->clip->setBoundaries( newBegin, newEnd );
+ return addClip( c, newPos );
+ }
+}
+
+bool
+Track::removeClip( const QUuid& uuid )
+{
+ auto it = m_clips.find( uuid );
+ if ( it == m_clips.end() )
+ {
+ vlmcCritical() << "Track: Couldn't find a clip:" << uuid;
+ return false;
+ }
+ auto t = track( it.value()->internalTrackId );
+ t->remove( t->clipIndexAt( it.value()->clip->pos ) );
+ m_clips.erase( it );
+ return true;
+}
+
+bool
+Track::addTransition( QSharedPointer<Transition> transition )
+{
+ m_transitions.insert( transition->uuid(), transition );
+ transition->apply( *m_multitrack );
+ return true;
+}
+
+bool
+Track::moveTransition( const QUuid& uuid, qint64 begin, qint64 end )
+{
+ auto it = m_transitions.find( uuid );
+ if ( it == m_transitions.end() )
+ return false;
+ auto transition = it.value();
+ if ( m_multitrack->length() - 1 < end )
+ return false;
+ transition->setBoundaries( begin, end );
+ return true;
+}
+
+QSharedPointer<Transition>
+Track::removeTransition( const QUuid& uuid )
+{
+ auto it = m_transitions.find( uuid );
+ if ( it == m_transitions.end() )
+ return {};
+ auto transition = it.value();
+ m_transitions.erase( it );
+ return transition;
+}
+
+Backend::IInput&
+Track::input()
+{
+ return *m_multitrack.get();
+}
+
+quint32
+Track::internalTrackId( const QUuid& uuid )
+{
+ auto it = m_clips.find( uuid );
+ if ( it == m_clips.end() )
+ {
+ vlmcCritical() << "Track: Couldn't find a clip:" << uuid;
+ return {};
+ }
+ return it.value()->internalTrackId;
+}
+
+QSharedPointer<SequenceWorkflow::ClipInstance>
+Track::clip( const QUuid& uuid )
+{
+ auto it = m_clips.find( uuid );
+ if ( it == m_clips.end() )
+ {
+ vlmcCritical() << "Track: Couldn't find a clip:" << uuid;
+ return {};
+ }
+ return it.value()->clip;
+}
+
+QSharedPointer<Backend::ITrack>
+Track::track( quint32 trackId )
+{
+ int index = static_cast<int>( trackId );
+ while ( m_tracks.size() - 1 < index )
+ {
+ auto t = QSharedPointer<Backend::ITrack>( new Backend::MLT::MLTTrack );
+ if ( m_type == Workflow::AudioTrack )
+ t->hide( Backend::HideType::Video );
+ else
+ t->hide( Backend::HideType::Audio );
+ m_multitrack->setTrack( *t, m_tracks.size() );
+ m_tracks << t;
+ }
+ for ( auto& transition : m_transitions )
+ transition->setTracks( 0, index );
+ return m_tracks[index];
+}
+
+QSharedPointer<Backend::ITrack>
+Track::track( const QUuid& uuid )
+{
+ return track( internalTrackId( uuid ) );
+}
+
+quint32
+Track::insertableTrackIndex( QSharedPointer<SequenceWorkflow::ClipInstance> clip,
+ qint64 pos, qint64 begin, qint64 end )
+{
+ quint32 index = 0;
+ pos = pos == -1 ? clip->pos : pos;
+ auto length = ( begin == -1 || end == -1 ) ? clip->clip->length() : end - begin + 1;
+ for ( const auto& c : m_clips )
+ {
+ if ( c->clip->uuid == clip->uuid )
+ continue;
+ // Collision detection
+ if ( c->clip->pos <= pos + length - 1 &&
+ pos <= c->clip->pos + c->clip->clip->length() - 1 )
+ {
+ index = qMax( index, c->internalTrackId + 1 );
+ }
+ }
+ return index;
+}
+
+Track::ClipInstance::ClipInstance( QSharedPointer<SequenceWorkflow::ClipInstance> clip,
+ quint32 internalTrackId )
+ : clip( clip )
+ , internalTrackId( internalTrackId )
+{
+
+}
diff --git a/src/Workflow/Track.h b/src/Workflow/Track.h
new file mode 100644
index 00000000..2ec4c0d2
--- /dev/null
+++ b/src/Workflow/Track.h
@@ -0,0 +1,57 @@
+#ifndef TRACK_H
+#define TRACK_H
+
+#include <QUuid>
+#include <QSharedPointer>
+
+#include "SequenceWorkflow.h"
+
+class Transition;
+
+class Track
+{
+public:
+ explicit Track( Workflow::TrackType type );
+ ~Track();
+
+ Workflow::TrackType type() const;
+
+ bool addClip( QSharedPointer<SequenceWorkflow::ClipInstance> clipInstance, qint64 pos );
+ bool moveClip( const QUuid& uuid, qint64 pos );
+ bool resizeClip( const QUuid& uuid, qint64 newBegin, qint64 newEnd, qint64 newPos );
+ bool removeClip( const QUuid& uuid );
+
+
+ bool addTransition( QSharedPointer<Transition> transition );
+ bool moveTransition( const QUuid& uuid, qint64 begin, qint64 end );
+ QSharedPointer<Transition> removeTransition( const QUuid& uuid );
+
+ Backend::IInput& input();
+
+private:
+ struct ClipInstance {
+ ClipInstance() = default;
+ ClipInstance( QSharedPointer<SequenceWorkflow::ClipInstance> clip,
+ quint32 internalTrackId );
+ QSharedPointer<SequenceWorkflow::ClipInstance> clip;
+ quint32 internalTrackId;
+ };
+
+ quint32 internalTrackId( const QUuid& uuid );
+ QSharedPointer<SequenceWorkflow::ClipInstance> clip( const QUuid& uuid );
+
+ QSharedPointer<Backend::ITrack> track( quint32 trackId );
+ inline QSharedPointer<Backend::ITrack> track( const QUuid& uuid );
+ quint32 insertableTrackIndex( QSharedPointer<SequenceWorkflow::ClipInstance> clip,
+ qint64 pos = -1, qint64 begin = -1, qint64 end = -1 );
+
+ Workflow::TrackType m_type;
+
+ QMap<QUuid, QSharedPointer<ClipInstance>> m_clips;
+ QMap<QUuid, QSharedPointer<Transition>> m_transitions;
+
+ QList<QSharedPointer<Backend::ITrack>> m_tracks;
+ std::unique_ptr<Backend::IMultiTrack> m_multitrack;
+};
+
+#endif // TRACK_H
More information about the Vlmc-devel
mailing list