ClipRenderer.cpp 6.75 KB
Newer Older
Christophe Courtaut's avatar
Christophe Courtaut committed
1
/*****************************************************************************
2
 * ClipRenderer.cpp: Render from a Clip (mainly for previewing purpose)
Christophe Courtaut's avatar
Christophe Courtaut committed
3
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
Christophe Courtaut's avatar
Christophe Courtaut committed
5
 *
6
 * Authors: Geoffroy Lacarrière <geoffroylaca@gmail.com>
7
 *          Hugo Beauzee-Luyssen <hugo@vlmc.org>
Christophe Courtaut's avatar
Christophe Courtaut committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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.
 *****************************************************************************/

24
#include <QtDebug>
25
#include <QtGlobal>
26

27
#include "Clip.h"
28
#include "ClipRenderer.h"
29
#include "Library.h"
30
#include "Media.h"
31
#include "MainWorkflow.h"
32
#include "VLCMediaPlayer.h"
33
#include "VLCMedia.h"
geoff's avatar
geoff committed
34

35 36 37
ClipRenderer::ClipRenderer() :
    GenericRenderer(),
    m_clipLoaded( false ),
38
    m_vlcMedia( NULL ),
39
    m_selectedClip( NULL ),
40 41
    m_begin( 0 ),
    m_end( -1 ),
42
    m_mediaChanged( false )
geoff's avatar
geoff committed
43
{
44
    connect( m_mediaPlayer,     SIGNAL( stopped() ),            this,   SLOT( __videoStopped() ) );
45 46
    connect( m_mediaPlayer,     SIGNAL( paused() ),             this,   SIGNAL( paused() ) );
    connect( m_mediaPlayer,     SIGNAL( playing() ),            this,   SIGNAL( playing() ) );
47
    connect( m_mediaPlayer,     SIGNAL( timeChanged( qint64 ) ),        this,   SLOT( __timeChanged( qint64 ) ) );
48
    connect( m_mediaPlayer,     SIGNAL( endReached() ),         this,   SLOT( __endReached() ) );
geoff's avatar
geoff committed
49 50
}

51
ClipRenderer::~ClipRenderer()
geoff's avatar
geoff committed
52
{
53 54
    if ( m_vlcMedia )
        delete m_vlcMedia;
55
    stop();
geoff's avatar
geoff committed
56
}
57

58
void
59
ClipRenderer::setClip( Clip* clip )
60
{
61 62 63 64

    if ( m_selectedClip != NULL && clip != NULL &&
         clip->uuid() != m_selectedClip->uuid() )
        clipUnloaded( m_selectedClip->uuid() );
65
    if ( clip == NULL )
66
    {
67
        m_selectedClip = NULL;
68
        m_clipLoaded = false;
69 70
        return ;
    }
71
    m_selectedClip = clip;
72 73 74 75 76 77 78 79
    if ( clip->length() == 0 )
        return ;
    updateInfos( clip );
}

void
ClipRenderer::updateInfos( Clip* clip )
{
80 81
    m_begin = clip->begin();
    m_end = clip->end();
82 83 84 85
    if ( m_isRendering == true )
        m_mediaChanged = true;
    else
        m_clipLoaded = false;
86 87
}

88 89
void
ClipRenderer::startPreview()
90
{
91
    if ( m_selectedClip == NULL )
92
        return ;
93
    updateInfos( m_selectedClip );
94

95
    //If an old media is found, we delete it, and disconnect
96 97
    if ( m_vlcMedia != NULL )
        delete m_vlcMedia;
98
    m_vlcMedia = new LibVLCpp::Media( m_selectedClip->getMedia()->fileInfo()->absoluteFilePath() );
99

100
    m_mediaPlayer->setKeyInput( false );
101
    m_mediaPlayer->setMedia( m_vlcMedia );
102

103
    m_mediaPlayer->play();
104
    m_mediaPlayer->setPosition( (double)m_begin / (double)m_selectedClip->getMedia()->nbFrames() );
105
    m_clipLoaded = true;
106
    m_isRendering = true;
107
    m_paused = false;
108
    m_mediaChanged = false;
109 110
}

111 112
void
ClipRenderer::stop()
113
{
114
    if ( m_clipLoaded == true && m_isRendering == true )
115
    {
116
        m_isRendering = false;
117
        m_mediaPlayer->stop();
118
        m_paused = false;
119 120
        if ( m_mediaChanged == true )
            m_clipLoaded = false;
121 122 123
    }
}

124 125
void
ClipRenderer::togglePlayPause( bool forcePause )
126
{
127
    if ( m_clipLoaded == false )
128
    {
129
        emit frameChanged( 0, Vlmc::Renderer );
130
        startPreview();
131 132
        return ;
    }
133
    if ( m_paused == false && m_isRendering == true )
134
    {
135
        m_mediaPlayer->pause();
136 137
        m_paused = true;
    }
138
    else if ( forcePause == false )
139
    {
140
        if ( m_isRendering == false )
141 142
        {
            m_mediaPlayer->play();
143
            m_mediaPlayer->setPosition( m_begin / ( m_end - m_begin ) );
144
            m_isRendering = true;
145 146 147
        }
        else
            m_mediaPlayer->play();
148 149
        m_paused = false;
    }
150
}
151

152 153
void
ClipRenderer::nextFrame()
154
{
155
    if ( m_isRendering == true )
156
    {
157
        m_mediaPlayer->nextFrame();
158 159 160
    }
}

161 162
void
ClipRenderer::previousFrame()
163
{
164
    if ( m_isRendering == true )
165
    {
166 167
        if ( m_paused == false )
            togglePlayPause( true );
chouquette's avatar
chouquette committed
168
        qint64   interval =  static_cast<qint64>( (1.0f / m_mediaPlayer->getFps()) * 1000.0f );
169 170 171 172
        m_mediaPlayer->setTime( m_mediaPlayer->getTime() - interval );
    }
}

173
qint64
174
ClipRenderer::length() const
175 176 177 178
{
    return m_end - m_begin;
}

179 180
qint64
ClipRenderer::getLengthMs() const
181
{
182 183
    if ( m_selectedClip )
        return ( qRound64( (qreal)( m_end - m_begin ) / m_selectedClip->getMedia()->fps() * 1000.0 ) );
184 185 186
    return 0;
}

187
void
188
ClipRenderer::clipUnloaded( const QUuid& uuid )
189
{
190
    if ( m_selectedClip != NULL && m_selectedClip->uuid() == uuid )
191 192 193
    {
        m_mediaPlayer->stop();
        m_clipLoaded = false;
194
        m_selectedClip = NULL;
195 196 197 198 199
        m_isRendering = false;
        m_paused = false;
    }
}

200 201
qint64
ClipRenderer::getCurrentFrame() const
202
{
203
    if ( m_clipLoaded == false || m_isRendering == false || m_selectedClip == NULL )
204
        return 0;
205
    return qRound64( (qreal)m_mediaPlayer->getTime() / 1000 *
206
                     (qreal)m_selectedClip->getMedia()->fps() );
207 208
}

209 210
float
ClipRenderer::getFps() const
211
{
212 213
    if ( m_selectedClip != NULL )
        return m_selectedClip->getMedia()->fps();
214 215 216
    return 0.0f;
}

217 218
Clip*
ClipRenderer::getClip()
219
{
220
    return m_selectedClip;
221 222
}

223 224
void
ClipRenderer::previewWidgetCursorChanged( qint64 newFrame )
225 226 227
{
    if ( m_isRendering == true )
    {
228
        newFrame += m_begin;
229
        qint64 nbSeconds = qRound64( (qreal)newFrame / m_selectedClip->getMedia()->fps() );
230
        m_mediaPlayer->setTime( nbSeconds * 1000 );
231 232 233
    }
}

234 235 236 237
/////////////////////////////////////////////////////////////////////
/////SLOTS :
/////////////////////////////////////////////////////////////////////

238 239
void
ClipRenderer::__videoStopped()
240
{
241
    emit frameChanged( 0, Vlmc::Renderer );
242 243 244
    emit stopped();
}

245 246
void
ClipRenderer::__timeChanged( qint64 time )
247
{
248 249
    float   fps = (qreal)m_mediaPlayer->getFps();
    if ( fps < 0.1f )
250
        fps = m_selectedClip->getMedia()->fps();
251
    qint64 f = qRound64( (qreal)time / 1000.0 * fps );
252 253 254 255 256 257
    if ( f >= m_end )
    {
        __endReached();
        return ;
    }
    f = f - m_begin;
258
    emit frameChanged( f, Vlmc::Renderer );
259 260
}

261 262
void
ClipRenderer::__endReached()
263 264
{
    m_mediaPlayer->stop();
265
    m_isRendering = false;
266 267
    if ( m_mediaChanged == true )
        m_clipLoaded = false;
268
    emit endReached();
269
}