2012-02-06 02:49:54 +01:00
/*
Timings - timing specifications for a frame quantised data stream
Copyright ( C ) Lumiera . org
2012 , Hermann Vosseler < Ichthyostega @ web . de >
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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "proc/play/timings.hpp"
2013-01-12 12:38:33 +01:00
# include "backend/engine/engine-config.h"
2012-02-06 02:49:54 +01:00
# include "lib/time/formats.hpp"
# include "lib/time/timequant.hpp"
namespace proc {
namespace play {
2013-01-12 12:38:33 +01:00
using backend : : engine : : EngineConfig ;
2012-02-06 02:49:54 +01:00
using lib : : time : : PQuant ;
2012-02-09 04:52:09 +01:00
using lib : : time : : Time ;
2013-01-12 12:38:33 +01:00
using lib : : time : : TimeVar ;
2012-02-06 02:49:54 +01:00
namespace { // hidden local details of the service implementation....
inline PQuant
buildStandardGridForFramerate ( FrameRate fps )
{
return PQuant ( new lib : : time : : FixedFrameQuantiser ( fps ) ) ;
} //////TODO maybe caching these quantisers? they are immutable and threadsafe
} // (End) hidden service impl details
2013-01-12 12:38:33 +01:00
2012-02-06 02:49:54 +01:00
/** Create a default initialised Timing constraint record.
* Using the standard optimistic settings for most values ,
* no latency , no special requirements . The frame grid is
* rooted at the " natural " time origin ; it is not related
* in any way to the current session .
* @ remarks this ctor is intended rather for testing purposes !
* Usually , when creating a play / render process ,
* the actual timings \ em are related to the timeline
* and the latency / speed requirements of the output .
*/
Timings : : Timings ( FrameRate fps )
: grid_ ( buildStandardGridForFramerate ( fps ) )
, playbackUrgency ( ASAP )
2013-01-11 18:12:40 +01:00
, playbackSpeed ( 1 )
2013-01-12 08:36:35 +01:00
, scheduledDelivery ( Time : : NEVER )
2012-03-19 01:03:14 +01:00
, outputLatency ( Duration : : NIL )
2012-02-09 04:52:09 +01:00
{
ENSURE ( grid_ ) ;
}
2013-01-12 12:38:33 +01:00
//////////////////////////////////////////////////////////////////TODO ctors for use in the real player/engine?
2013-01-12 08:36:35 +01:00
2012-02-09 04:52:09 +01:00
2013-06-15 04:02:48 +02:00
/** a special marker Timings record,
* indicating disabled or halted output */
Timings Timings : : DISABLED ( FrameRate : : HALTED ) ;
2012-02-09 04:52:09 +01:00
2013-08-18 03:16:49 +02:00
Time
2012-02-09 04:52:09 +01:00
Timings : : getOrigin ( ) const
{
2013-08-18 03:16:49 +02:00
return Time ( grid_ - > timeOf ( 0 ) ) ;
2012-02-09 04:52:09 +01:00
}
2013-08-18 03:16:49 +02:00
Time
2013-01-12 12:38:33 +01:00
Timings : : getFrameStartAt ( int64_t frameNr ) const
{
2013-08-18 03:16:49 +02:00
return Time ( grid_ - > timeOf ( frameNr ) ) ;
2013-01-12 12:38:33 +01:00
}
2012-02-09 04:52:09 +01:00
Offset
Timings : : getFrameOffsetAt ( TimeValue refPoint ) const
{
return 1 * getFrameDurationAt ( refPoint ) ; /////////////////TODO implement a speed factor here
}
Duration
Timings : : getFrameDurationAt ( TimeValue refPoint ) const
{
int64_t frameNr = grid_ - > gridPoint ( refPoint ) ;
2012-03-02 01:33:57 +01:00
return getFrameDurationAt ( frameNr ) ;
}
Duration
Timings : : getFrameDurationAt ( int64_t refFrameNr ) const
{
2012-03-19 01:03:14 +01:00
return Offset ( grid_ - > timeOf ( refFrameNr ) , grid_ - > timeOf ( refFrameNr + 1 ) ) ;
2012-02-09 04:52:09 +01:00
}
2012-03-02 01:33:57 +01:00
2012-02-09 04:52:09 +01:00
/** @remarks the purpose of this function is to support scheduling
* and frame handling even in case the frame rate isn ' t constant .
* To indicate the case the frame rate is changing right now ,
2012-07-01 03:42:50 +02:00
* this function might return Duration : : NIL
2012-02-09 04:52:09 +01:00
* @ todo implement real support for variable frame rates
*/ ////////////////////////////////////////////////////////TICKET #236
Duration
2013-01-12 12:38:33 +01:00
Timings : : constantFrameTimingsInterval ( TimeValue ) const
2012-02-09 04:52:09 +01:00
{
return Duration ( Time : : ANYTIME ) ;
}
2012-02-06 02:49:54 +01:00
2012-03-02 01:33:57 +01:00
Time
2013-01-12 08:36:35 +01:00
Timings : : getTimeDue ( int64_t frameOffset ) const
2012-03-02 01:33:57 +01:00
{
if ( TIMEBOUND = = playbackUrgency )
{
2013-01-12 08:36:35 +01:00
REQUIRE ( scheduledDelivery ! = Time : : NEVER ) ;
return scheduledDelivery
+ getRealOffset ( frameOffset ) ;
2012-03-02 01:33:57 +01:00
}
else
return Time : : NEVER ;
}
2013-01-11 18:12:40 +01:00
Offset
Timings : : getRealOffset ( int64_t frameOffset ) const
{
Offset nominalOffset ( grid_ - > timeOf ( 0 ) , grid_ - > timeOf ( frameOffset ) ) ;
return isOriginalSpeed ( ) ? nominalOffset
: nominalOffset * playbackSpeed ;
////////////////////////TICKET #902 for full-featured variable speed playback, we need to integrate (sum up step wise) instead of just using a fixed factor
}
2013-01-12 08:36:35 +01:00
Duration
Timings : : getPlanningChunkDuration ( ) const
2012-04-20 04:05:41 +02:00
{
2013-01-12 12:38:33 +01:00
return EngineConfig : : get ( ) . currentJobPlanningRhythm ( ) ;
}
int64_t
Timings : : establishNextPlanningChunkStart ( int64_t currentAnchorFrame ) const
{
TimeVar breakingPoint = grid_ - > timeOf ( currentAnchorFrame ) ;
breakingPoint + = getPlanningChunkDuration ( ) ;
int64_t nextFrame = grid_ - > gridPoint ( breakingPoint ) ;
ASSERT ( breakingPoint < = grid_ - > timeOf ( nextFrame ) ) ;
ASSERT ( breakingPoint > grid_ - > timeOf ( nextFrame - 1 ) ) ;
if ( grid_ - > timeOf ( nextFrame ) = = breakingPoint )
return nextFrame ;
else
return nextFrame + 1 ;
2012-04-20 04:05:41 +02:00
}
2013-01-12 12:38:33 +01:00
Duration
Timings : : currentEngineLatency ( ) const
{
return EngineConfig : : get ( ) . currentEngineLatency ( ) ;
}
2012-03-02 01:33:57 +01:00
Timings
Timings : : constrainedBy ( Timings additionalConditions )
{
UNIMPLEMENTED ( " how to combine timing constraints " ) ;
}
2012-02-06 02:49:54 +01:00
} } // namespace proc::play