/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- _clockSource
- setState
- toggleState
- advanceIfConsumed
- seekTo
// PlayHead.cpp: media playback controller
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 Free Software Foundation, Inc
//
// 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 3 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 St, Fifth Floor, Boston, MA 02110-1301 USA
//
#include "PlayHead.h"
#include "VirtualClock.h" // for use
#include <cassert>
namespace gnash {
PlayHead::PlayHead(VirtualClock* clockSource)
:
_position(0),
_state(PLAY_PAUSED),
_availableConsumers(0),
_positionConsumers(0),
_clockSource(clockSource)
{
// NOTE: we construct in PAUSE mode so do not
// really *need* to query _clockSource here.
// We initialize it to an arbitrary value just
// to be polite.
_clockOffset = 0; // _clockSource->elapsed();
}
PlayHead::PlaybackStatus
PlayHead::setState(PlaybackStatus newState)
{
if ( _state == newState ) return _state; // nothing to do
if ( _state == PLAY_PAUSED )
{
assert(newState == PLAY_PLAYING);
_state = PLAY_PLAYING;
// if we go from PAUSED to PLAYING, reset
// _clockOffset to yank current position
// when querying clock source *now*
boost::uint64_t now = _clockSource->elapsed();
_clockOffset = ( now - _position );
// check if we did the right thing
// TODO: wrap this in PARANOIA_LEVEL > 1
assert( now-_clockOffset == _position );
return PLAY_PAUSED;
}
else
{
// TODO: wrap these in PARANOIA_LEVEL > 1 (or > 2)
assert(_state == PLAY_PLAYING);
assert(newState == PLAY_PAUSED);
_state = PLAY_PAUSED;
// When going from PLAYING to PAUSED
// we do nothing with _clockOffset
// as we'll update it when getting back to PLAYING
return PLAY_PLAYING;
}
}
PlayHead::PlaybackStatus
PlayHead::toggleState()
{
if ( _state == PLAY_PAUSED ) return setState(PLAY_PLAYING);
else return setState(PLAY_PAUSED);
}
void
PlayHead::advanceIfConsumed()
{
if ( (_positionConsumers & _availableConsumers) != _availableConsumers)
{
// not all available consumers consumed current position,
// won't advance
#if 0
log_debug("PlayHead::advance(): "
"not all consumers consumed current position, "
"won't advance");
#endif
return;
}
// Advance position
boost::uint64_t now = _clockSource->elapsed();
_position = now-_clockOffset;
// Reset consumers state
_positionConsumers = 0;
}
void
PlayHead::seekTo(boost::uint64_t position)
{
boost::uint64_t now = _clockSource->elapsed();
_position = position;
_clockOffset = ( now - _position );
assert( now-_clockOffset == _position ); // check if we did the right thing
// Reset consumers state
_positionConsumers = 0;
}
} // end of gnash namespace