MainWorkflow.h 15.1 KB
Newer Older
1 2 3 4
/*****************************************************************************
 * MainWorkflow.h : Will query all of the track workflows to render the final
 *                  image
 *****************************************************************************
5
 * Copyright (C) 2008-2014 VideoLAN
6
 *
7
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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.
 *****************************************************************************/

#ifndef MAINWORKFLOW_H
#define MAINWORKFLOW_H

27
#include "EffectsEngine/EffectsEngine.h"
28
#include <QXmlStreamWriter>
29
#include "Project/ILoadSave.h"
30
#include "Types.h"
31

32
class   Clip;
33
class   ClipHelper;
34
class   EffectsEngine;
35
class   Effect;
36
class   ProjectManager;
37
class   TrackHandler;
38
class   TrackWorkflow;
39 40 41
namespace   Workflow
{
    class   Frame;
42
    class   AudioSample;
43
}
44

45 46 47 48 49
class   QDomDocument;
class   QDomElement;
class   QMutex;
class   QReadWriteLock;

50 51 52
#include <QObject>
#include <QUuid>

53 54 55
/**
 *  \class  Represent the Timeline backend.
 */
56
class   MainWorkflow : public QObject, public ILoadSave
57 58 59 60
{
    Q_OBJECT

    public:
61
        MainWorkflow( int trackCount = 64 );
62 63
        ~MainWorkflow();

64 65 66
        /**
         *  \brief      Initialize the workflow for the render.
         *
67 68
         *  \param      width   The width to use with this render session.
         *  \param      height  The height to use with this render session.
69
         *  This will basically activate all the tracks, newLengthso they can render.
70
         */
71
        void                    startRender( quint32 width, quint32 height, double fps );
72 73 74 75 76 77 78 79 80
        /**
         *  \brief      Gets a frame from the workflow
         *
         *  \return A pointer to an output buffer. This pointer must NOT be released.
         *          Both types of this output buffer are not guarantied to be filled.
         *          However, if VideoTrack was passed as trackType, the video member of
         *          the output buffer is guarantied to be filled. The same applies for
         *          AudioTrack
         *  \param  trackType   The type of track you wish to get the render from.
81
         *  \param  paused      The paused state of the renderer
82
         */
83
        const Workflow::OutputBuffer    *getOutput( Workflow::TrackType trackType, bool paused );
84 85 86
        /**
         *  \brief              Set the workflow position by the desired frame
         *  \param              currentFrame: The desired frame to render from
87
         *  \param              reason: The program part which required this frame change
88
                                        (to avoid cyclic events)
89
        */
90
        void                    setCurrentFrame( qint64 currentFrame,
91
                                                Vlmc::FrameChangedReason reason );
92

93
        /**
94
         *  \brief              Get the workflow length in frames.
95 96
         *  \return             Returns the global length of the workflow
         *                      in frames.
97
        */
98
        qint64                  getLengthFrame() const;
99

100
        /**
101
         *  \brief              Get the currently rendered frame.
102 103 104
         *  \param      lock    If true, m_currentFrameLock will be locked for read.
         *                      If false, it won't be locked. This is usefull when calling
         *                      getCurentFrame from underlying workflows
105
         *  \return             Returns the current frame.
106 107
         *  \warning            Locks the m_currentFrameLock ReadWriteLock, unless false is
         *                      passed.
108
         */
109
        qint64                  getCurrentFrame( bool lock = true ) const;
110

111
        /**
112 113 114 115 116
         *  \brief      Stops the rendering.
         *
         *  This will stop every ClipWorkflow that are currently rendering.
         *  Calling this methid will cause the workflow to return to frame 0, and emit
         *  the signal frameChanged(), with the reason: Renderer
117 118 119
         */
        void                    stop();

120 121 122 123 124 125 126
        /**
         *  \brief              Unconditionnaly switch to the next frame.
         *
         *  \param  trackType   The type of the frame counter to increment.
         *                      Though it seems odd to speak about frame for AudioTrack,
         *                      it's mainly a render position used for
         *                      synchronisation purpose.
127
         *  \sa         previousFrame( Workflow::TrackType );
128
         */
129
        void                    nextFrame( Workflow::TrackType trackType );
130 131 132 133 134 135 136
        /**
         *  \brief      Unconditionnaly switch to the previous frame.
         *
         *  \param      trackType   The type of the frame counter to decrement.
         *                          Though it seems odd to speak about frame for
         *                          AudioTrack, it's mainly a render position used for
         *                          synchronisation purpose.
137
         *  \sa         nextFrame( Workflow::TrackType );
138
         */
139
        void                    previousFrame( Workflow::TrackType trackType );
140

141 142 143 144 145 146 147 148 149 150
        /**
         *  \brief              Return the given clip position.
         *
         *  \param      uuid        The clip uuid
         *  \param      trackId     The track containing the clip
         *  \param      trackType   The type of the track containing the clip
         *  \return                 The given clip position, in frame. If not found, -1
         *                          is returned.
         */
        qint64                  getClipPosition( const QUuid& uuid, unsigned int trackId,
151
                                                Workflow::TrackType trackType ) const;
152

153 154 155 156 157 158 159
        /**
         *  \brief      Mute a track.
         *
         *  A muted track will not be asked for render. It won't even emit endReached
         *  signal. To summerize, a mutted track is an hard deactivated track.
         *  \param  trackId     The id of the track to mute
         *  \param  trackType   The type of the track to mute.
160
         *  \sa     unmuteTrack( unsigned int, Workflow::TrackType );
161 162
         */
        void                    muteTrack( unsigned int trackId,
163
                                           Workflow::TrackType trackType );
164 165 166 167 168
        /**
         *  \brief      Unmute a track.
         *
         *  \param  trackId     The id of the track to unmute
         *  \param  trackType   The type of the track to unmute.
169
         *  \sa     muteTrack( unsigned int, Workflow::TrackType );
170 171
         */
        void                    unmuteTrack( unsigned int trackId,
172
                                             Workflow::TrackType trackType );
173

174 175 176 177 178 179 180 181
        /**
         *  \brief      Mute a clip.
         *
         *  \param  uuid        The clip's uuid.
         *  \param  trackId     The id of the track containing the clip.
         *  \param  trackType   The type of the track containing the clip.
         */
        void                    muteClip( const QUuid& uuid, unsigned int trackId,
182
                                          Workflow::TrackType trackType );
183 184 185 186 187 188 189 190 191

        /**
         *  \brief      Unmute a clip.
         *
         *  \param  uuid        The clip's uuid.
         *  \param  trackId     The id of the track containing the clip.
         *  \param  trackType   The type of the track containing the clip.
         */
        void                    unmuteClip( const QUuid& uuid, unsigned int trackId,
192
                                          Workflow::TrackType trackType );
193

194 195 196 197 198 199
        /**
         *  \brief              Get the number of track for a specific type
         *
         *  \param  trackType   The type of the tracks to count
         *  \return             The number of track for the type trackType
         */
200
        int                     getTrackCount( Workflow::TrackType trackType ) const;
201

202 203 204 205 206 207 208 209 210
        /**
         *  \brief      Get the width used for rendering.
         *
         *  This value is used by the ClipWorkflow that generates the frames.
         *  If this value is edited in the preferences, it will only change after the
         *  current render has been stopped.
         *  \return     The width (in pixels) of the currently rendered frames
         *  \sa         getHeight()
         */
211
        quint32                getWidth() const;
212 213 214 215 216 217 218 219 220
        /**
         *  \brief      Get the height used for rendering.
         *
         *  This value is used by the ClipWorkflow that generates the frames.
         *  If this value is edited in the preferences, it will only change after the
         *  current render has been stopped.
         *  \return     The height (in pixels) of the currently rendered frames
         *  \sa         getWidth()
         */
221
        quint32                getHeight() const;
222

223 224 225 226 227 228 229 230
        /**
         *  \brief          Will render one frame only
         *
         *  It will change the ClipWorkflow frame getting mode from Get to Pop, just for
         *  one frame
         */
        void                    renderOneFrame();

231 232 233 234 235 236 237 238 239
        /**
         *  \brief              Set the render speed.
         *
         *  This will activate or deactivate vlc's pace-control
         *  \param  val         If true, ClipWorkflow will use no-pace-control
         *                      else, pace-control.
         */
        void                    setFullSpeedRender( bool val );

240 241 242 243 244 245 246 247
        /**
         *  \return     true if the current workflow contains the clip which the uuid was
         *              passed. Falsed otherwise.
         *
         *  \param      uuid    The Clip uuid, not the ClipHelper's.
         */
        bool                    contains( const QUuid& uuid ) const;

248 249 250 251 252 253 254 255
        /**
         *  \brief      Stop the frame computing process.
         *
         *  This will stop all the currently running ClipWorkflow.
         *  This is meant to be called just before the stop() method.
         */
        void                    stopFrameComputing();

256 257
        TrackWorkflow           *track( Workflow::TrackType type, quint32 trackId );

258
        const Workflow::Frame   *blackOutput() const;
259

260 261 262 263 264
        /**
         * \brief   Return the number of track for each track type.
         */
        quint32                 trackCount() const;

265
    private:
266 267 268 269 270 271 272
        /**
         *  \brief  Compute the length of the workflow.
         *
         *  This is meant to be used internally, after an operation occurs on the workflow
         *  such as adding a clip, removing it...
         *  This method will update the attribute m_lengthFrame
         */
273 274
        void                    computeLength();

275
        /**
276 277 278 279
         *  \param      uuid : The clip helper's uuid.
         *  \param      trackId : the track id
         *  \param      trackType : the track type (audio or video)
         *  \returns    The clip helper that matches the given UUID, or NULL.
280
         */
281 282
        ClipHelper*             getClipHelper( const QUuid& uuid, unsigned int trackId,
                                               Workflow::TrackType trackType );
283

284 285 286
        bool                    load( const QDomDocument& project );
        bool                    save( QXmlStreamWriter& project );

287
    private:
288 289 290
        /// Pre-filled buffer used when there's nothing to render
        Workflow::Frame         *m_blackOutput;

291
        /// Lock for the m_currentFrame atribute.
292
        QReadWriteLock*                 m_currentFrameLock;
293 294 295
        /**
         *  \brief  An array of currently rendered frame.
         *
296
         *  This must be indexed with Workflow::TrackType.
297 298 299 300 301 302
         *  The Audio array entry is designed to synchronize the renders internally, as it
         *  is not actually a frame.
         *  If you wish to know which frame is really rendered, you must use
         *  m_currentFrame[MainWorkflow::VideoTrack], which is the value that will be used
         *  when setCurrentFrame() is called.
         */
303
        qint64*                         m_currentFrame;
304
        /// The workflow length, in frame.
305
        qint64                          m_lengthFrame;
306
        /// This boolean describe is a render has been started
307
        bool                            m_renderStarted;
308

309
        /// Contains the trackhandler, indexed by Workflow::TrackType
310 311
        TrackHandler**                  m_tracks;

312
        /// Width used for the render
313
        quint32                         m_width;
314
        /// Height used for the render
315
        quint32                         m_height;
316 317
        /// Store the number of track for each track type.
        const quint32                   m_trackCount;
318

319
    private slots:
320 321 322 323 324 325 326
        /**
         *  \brief  Called when a track end is reached
         *
         *  If all track has reached end, the mainWorkflowEndReached() signal will be
         *  emitted;
         *  \sa     mainWorkflowEndReached()
         */
327
        void                            tracksEndReached();
328

329
    public slots:
330 331 332 333 334 335
        /**
         *  \brief      Clear the workflow.
         *
         *  Calling this method will cause every clip workflow to be deleted, along with
         *  the associated Clip.
         *  This method will emit cleared() signal once finished.
336
         *  \sa     reCip( const QUuid&, unsigned int, Workflow::TrackType )
337 338
         *  \sa     cleared()
         */
339
        void                            clear();
340

341 342
        void                            lengthUpdated( qint64 lengthUpdated );

343
    signals:
344
        /**
345 346 347 348 349
         *  \brief      Used to notify a change to the timeline and preview widget cursor
         *
         *  \param      newFrame    The new rendered frame
         *  \param      reason      The reason for changing frame. Usually, if emitted
         *                          from the MainWorkflow, this should be "Renderer"
350
         */
351
        void                    frameChanged( qint64 newFrame,
352
                                              Vlmc::FrameChangedReason reason );
353

354 355 356 357 358 359
        /**
         *  \brief  Emitted when workflow end is reached
         *
         *  Workflow end is reached when tracksEndReached() is called, and no more tracks
         *  are activated (ie. they all reached end)
         */
360
        void                    mainWorkflowEndReached();
361

362 363 364 365 366
        /**
         *  \brief  Emitted when the workflow is cleared.
         *
         *  \sa     clear();
         */
367
        void                    cleared();
368 369 370 371 372 373 374

        /**
         *  \brief  Emitted when the global length of the workflow changes.
         *
         *  \param  newLength   The new length, in frames
         */
        void                    lengthChanged( qint64 );
375 376 377
};

#endif // MAINWORKFLOW_H