Clip.cpp 5.92 KB
Newer Older
1 2 3
/*****************************************************************************
 * Clip.cpp : Represents a basic container for media informations.
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
5
 *
6
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

/** \file
  * This file contains the Clip class implementation.
  */

#include "Clip.h"
28
#include "ISource.h"
29 30
#include "Library.h"
#include "Media.h"
31
#include "Workspace.h"
32

33 34
const int   Clip::DefaultFPS = 30;

35 36 37 38 39
Clip::Clip( Media *media, qint64 begin /*= 0*/, qint64 end /*= -1*/, const QString& uuid /*= QString()*/ ) :
        m_media( media ),
        m_begin( begin ),
        m_end( end ),
        m_parent( media->baseClip() )
40
{
41 42
    if ( end == -1 )
        m_end = media->nbFrames();
43
    if ( uuid.isEmpty() == true )
44
        m_uuid = QUuid::createUuid();
45
    else
46
        m_uuid = QUuid( uuid );
47 48
    m_childs = new MediaContainer( this );
    m_rootClip = media->baseClip();
49
    computeLength();
50 51
    connect( media, SIGNAL( metaDataComputed() ),
             this, SLOT( mediaMetadataUpdated() ) );
52 53
}

54
Clip::Clip( Clip *parent, qint64 begin /*= -1*/, qint64 end /*= -1*/,
55
            const QString &uuid /*= QString()*/ ) :
56
        m_media( parent->getMedia() ),
57 58
        m_begin( begin ),
        m_end( end ),
59
        m_rootClip( parent->rootClip() ),
60
        m_parent( parent )
61
{
62
    if ( begin < 0 )
63
        m_begin = parent->m_begin;
64
    if ( end < 0 )
65
        m_end = parent->m_end;
66 67 68 69
    if ( uuid.isEmpty() == true )
        m_uuid = QUuid::createUuid();
    else
        m_uuid = QUuid( uuid );
70
    m_childs = new MediaContainer( this );
71 72 73
    computeLength();
}

74
Clip::~Clip()
75
{
76
    emit unloaded( this );
77
    delete m_childs;
78 79
    if ( isRootClip() == true )
        delete m_media;
80 81
}

82
Media*
83
Clip::getMedia()
84
{
85
    return m_media;
86 87
}

88 89 90 91 92 93
const Media*
Clip::getMedia() const
{
    return m_media;
}

94 95
qint64
Clip::length() const
96
{
97
    return m_length;
98 99
}

100 101
qint64
Clip::lengthSecond() const
102 103 104 105
{
    return m_lengthSeconds;
}

106 107
void
Clip::computeLength()
108
{
109 110 111 112 113
    float   fps = m_media->source()->fps();
    if ( fps < 0.1f )
        fps = Clip::DefaultFPS;
    m_length = m_end - m_begin;
    m_lengthSeconds = qRound64( (float)m_length / fps );
114
}
115

116 117
const QStringList&
Clip::metaTags() const
118 119 120 121
{
    return m_metaTags;
}

122 123
void
Clip::setMetaTags( const QStringList &tags )
124 125 126 127
{
    m_metaTags = tags;
}

128 129
bool
Clip::matchMetaTag( const QString &tag ) const
130 131 132
{
    if ( tag.length() == 0 )
        return true;
133
    if ( m_parent && m_parent->matchMetaTag( tag ) == true )
134
        return true;
135 136 137 138 139 140 141 142
    QString metaTag;
    foreach ( metaTag, m_metaTags )
    {
        if ( metaTag.startsWith( tag, Qt::CaseInsensitive ) == true )
            return true;
    }
    return false;
}
143

144 145
const QString&
Clip::notes() const
146 147 148 149
{
    return m_notes;
}

150 151
void
Clip::setNotes( const QString &notes )
152 153 154
{
    m_notes = notes;
}
155

156 157
const QUuid&
Clip::uuid() const
158
{
159 160
    Q_ASSERT( m_uuid.isNull() == false );
    return m_uuid;
161 162
}

163 164 165
void
Clip::setUuid( const QUuid &uuid )
{
166
    m_uuid = uuid;
167 168
}

169 170 171
Clip*
Clip::rootClip()
{
172 173
    if ( m_rootClip == NULL )
        return this;
174 175 176
    return m_rootClip;
}

177
bool
178
Clip::isRootClip() const
179
{
180
    return ( m_rootClip == NULL );
181
}
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

Clip*
Clip::getParent()
{
    return m_parent;
}

const Clip*
Clip::getParent() const
{
    return m_parent;
}

MediaContainer*
Clip::getChilds()
{
    return m_childs;
}

const MediaContainer*
Clip::getChilds() const
{
    return m_childs;
}

207
bool
208 209
Clip::addSubclip( Clip *clip )
{
210
    return m_childs->addClip( clip );
211 212 213 214 215 216 217
}

void
Clip::clear()
{
    m_childs->clear();
}
218 219 220 221 222 223

void
Clip::save( QXmlStreamWriter &project )
{
    project.writeStartElement( "clip" );
    if ( isRootClip() == true )
224 225
    {
        if ( m_media->isInWorkspace() == true )
226
            project.writeAttribute( "media", Workspace::workspacePrefix + Workspace::pathInProjectDir( m_media ) );
227 228 229
        else
            project.writeAttribute( "media", m_media->fileInfo()->absoluteFilePath() );
    }
230 231
    else
    {
232
        project.writeAttribute( "parent", m_parent->uuid().toString() );
233 234
        project.writeAttribute( "begin", QString::number( m_begin ) );
        project.writeAttribute( "end", QString::number( m_end ) );
235 236 237 238 239 240 241 242 243 244 245 246
    }
    project.writeAttribute( "uuid", m_uuid.toString() );
    project.writeAttribute( "metatags", m_metaTags.join( "," ) );
    project.writeAttribute( "notes", m_notes );
    if ( m_childs->count() > 0 )
    {
        project.writeStartElement( "subClips" );
        m_childs->save( project );
        project.writeEndElement();
    }
    project.writeEndElement();
}
247 248 249 250 251 252 253 254 255

QString
Clip::fullId() const
{
    const Clip* c = this;
    QString     id = m_uuid.toString();
    while ( c->isRootClip() == false )
    {
        c = c->getParent();
256
        id = c->uuid().toString() + '/' + id;
257 258 259
    }
    return id;
}
260 261 262 263 264 265 266 267 268 269 270 271 272 273

bool
Clip::isChild( const QUuid &uuid) const
{
    Clip*   c = m_parent;

    while ( c != NULL )
    {
        if ( c->m_uuid == uuid )
            return true;
        c = c->m_parent;
    }
    return false;
}
274 275

void
276
Clip::mediaMetadataUpdated()
277
{
278
    Q_ASSERT ( isRootClip() == true );
279 280 281 282 283 284 285
    if ( m_end == 0 )
    {
        m_begin = 0;
        m_end = m_media->nbFrames();
        computeLength();
    }
}