chxavplayer.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,374 行 · 第 1/3 页
CPP
1,374 行
m_startupStage = ssPastTimerStarted;
}
m_clipPos = ulPosition;
m_clipDuration = ulLength;
if(ulLength >0)
{
m_playerState.OnNewPos(ulPosition);
}
return HXR_OK;
}
////////////////////////////////
//
TInt CHXAvPlayer::GetPlaylistCurrentIndex() const
{
HX_ASSERT(m_pPlayItr);
return m_pPlayItr->Offset();
}
TInt CHXAvPlayer::GetPlaylistItemCount() const
{
HX_ASSERT(m_pPlaylist);
return m_pPlaylist->Length();
}
////////////////////////////////////////////
// user command to move to next or previous item in playlist
//
// from user request
//
void CHXAvPlayer::AdvancePlaylist(TUint flag)
{
if(!m_pPlayItr)
{
return;
}
// move forward or backward in playlist
HandlePlaylistAdvance(flag);
if( CHXAvPlayerState::Stopped != m_playerState.GetState() )
{
// stop current clip as soon as user moves through playlist
m_bEnableAutoPlayNext = false;
DoStopImp();
}
}
////////////////////////////////////////////
//
// return true if playlist end was reached
//
bool CHXAvPlayer::HandlePlaylistAdvance(TUint flag)
{
HX_ASSERT(m_pPlayItr);
bool bReachedEnd = false;
// temporarily set playlist iter loop mode on so we loop around
m_pPlayItr->Loop( (flag & advanceLoop) != 0 );
if (flag & advanceNext)
{
m_pPlayItr->Next();
}
else
{
HX_ASSERT(flag & advancePrev);
m_pPlayItr->Prev();
}
if(!m_pPlayItr->More())
{
m_pPlayItr->ResetBegin();
bReachedEnd = true;
}
m_playUrl = m_pPlayItr->Current().String();
// restore playlist iter loop mode
m_pPlayItr->Loop(false);
// play url has changed - reset associated state variables
ResetUnloadedClipState();
m_playerState.OnAdvancePlaylist();
return bReachedEnd;
}
/*
* IHXClientAdviseSink
* OnPresentationOpened
* --------------------
*
*/
STDMETHODIMP
CHXAvPlayer::OnPresentationOpened()
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnPresentationOpened()\n"));
HX_ASSERT(m_hxPlayer != NULL);
m_startupStage = ssPastOpenPres;
// now we should be able to obtain all headers for main source (in case of smil
// sub-sources will not be there yet -- see OnBuffering)
m_clipInfo.CacheHeadersL(m_hxPlayer);
// see if we are video-only and/or live
m_clipInfo.CachePresentationInfoL(m_hxPlayer);
// get request headers...
comptr<IHXPlayer2> play2;
play2.From(m_hxPlayer);
HX_ASSERT(play2);
comptr<IHXRequest> req;
play2->GetRequest(req.AsRef());
HX_ASSERT(req);
// possibly save some request info
m_clipInfo.CacheRequestInfo(req);
m_playerState.OnLoadSession(req);
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnPresentationClosed()
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnPresentationClosed()\n"));
HX_ASSERT(CHXAvPlayerState::Stopped == m_playerState.GetState()); // we expect OnStop() first
m_playerState.OnStop(); // just in case
if( m_bEnableAutoPlayNext )
{
// current clip ended by playing out; try to advance to next clip or loop
bool bLoopModeEnabled = prefs::GetBool(m_prefs, CHXAV_LoopMode);
bool bDoPlay = true;
if( m_pPlayItr )
{
TUint af = advanceNext;
if( bLoopModeEnabled )
{
af |= advanceLoop;
}
// advance through playlist
bool bReachedEnd = HandlePlaylistAdvance(af);
if( bReachedEnd && !bLoopModeEnabled )
{
// stop at end of playlist when loop mode is off
bDoPlay = false;
}
}
else
{
bDoPlay = bLoopModeEnabled;
}
if( bDoPlay )
{
// if we call PlayCurrent() here, we get an immediate OnStop() and OnPresentationClosed()
m_cbPlay.Set(10);
}
}
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnStatisticsChanged()
{
#if defined(HELIX_FEATURE_DPRINTF)
char szBuff[100];
for(UINT16 idx = 0; /*NULL*/; ++idx)
{
sprintf(szBuff, "Statistics.Player%u", idx );
if(!dbg::DumpRegistry(m_spEngine->GetEngine(), szBuff))
{
break;
}
}
#endif
return HXR_OK;
}
// IHXClientAdviseSink
//
// called when player object begins seek, just after
// user finishes setting seek target; during this period
// we expect to receive buffer notifications until OnPostSeek()
// is called
STDMETHODIMP
CHXAvPlayer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnPreSeek()\n"));
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnPostSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnPostSeek()\n"));
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnStop()
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnStop()\n"));
m_clipPos = 0;
m_playerState.OnStop();
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnPause(ULONG32 ulTime)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnPause()\n"));
if( m_playerState.GetState() != CHXAvPlayerState::Seeking)
{
m_playerState.OnPause();
}
return HXR_OK;
}
// IHXClientAdviseSink
//
// called a) after renderers are initialized (before open pres) b) after EndSeek
STDMETHODIMP
CHXAvPlayer::OnBegin(ULONG32 ulTime)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnBegin()\n"));
if(m_startupStage >= ssPastFirstBuffer)
{
m_playerState.OnResume();
}
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::OnBuffering(ULONG32 type, UINT16 unPercentComplete)
{
//DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnBuffering(type = %lu('%s'), percent = %u)\n", type, dbg::BufferReason(type), unPercentComplete));
if(m_startupStage < ssPastFirstBuffer)
{
m_startupStage = ssPastFirstBuffer;
dbg::DumpHeaders(m_hxPlayer);
//XXXLCM consider just updating header and presentation info, etc. in call to
// GetClipInfo() (or method such as UpdateClipInfo() that can be called beforehand);
// we'd still have to cache the info when we stop; this will clip info is up to date
// if sources are added and removed as presentation goes along (for smil case)
// for smil all sources should be created by now
m_clipInfo.CacheHeadersL(m_hxPlayer);
m_clipInfo.CacheURLsL(m_hxPlayer);
m_clipInfo.CachePresentationInfoL(m_hxPlayer);
// now is earliest time to get best stream bitrate values (i.e.,
// subscribed surestream bitrate will be known, if applicable)
m_clipInfo.SaveStreamBitrateValuesL(m_hxPlayer);
}
//
// Buffering state is independent of main player state
//
// - cannot assume we get a value of 0 for first buffer
// - can assume we get 100 for buffer complete
// - we often get repeated calls with no change in value from last time
// - sometimes after 100 we get more buffering (re-buffering)
// - we do not get other messages indicating play is resuming
// - if seeking, we do get subsequent OnPostSeek
//
m_playerState.OnBuffering(type, unPercentComplete);
return HXR_OK;
}
// IHXClientAdviseSink
//
// called when about to resolve host name via dns lookup
STDMETHODIMP
CHXAvPlayer::OnContacting(const char* pHostName)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnContacting(): '%s'\n", pHostName));
return HXR_OK;
}
// IHXClientAdviseSink
STDMETHODIMP
CHXAvPlayer::ErrorOccurred(const UINT8 unSeverity,
const ULONG32 ulHXCode,
const ULONG32 ulUserCode,
const char* pUserString,
const char* pMoreInfoURL)
{
// do not continue through playlist or loop after an error
m_bEnableAutoPlayNext = false;
if( m_clipInfo.GetSourceCount() > 0 && m_clipInfo.GetStreamCount(0) == 0 )
{
//
// No stream headers are currently cached for the first source.
// It is possible that they are now available. (This can be the
// case if the error occurs after the request is issued but before
// the presentation opens.) We now try to cache the stream
// headers in order to enable the user to be able to see
// as much clip info as possible after this error.
//
HX_ASSERT(m_hxPlayer);
UINT32 streamCount = player::GetStreamCount(m_hxPlayer, 0);
if(streamCount > 0)
{
m_clipInfo.CacheHeadersL(m_hxPlayer);
}
}
DPRINTF(SYMP_INFO, ("CHXAvPlayer::OnError(): code = 0x%08x(%s), user code = 0x%08x', sev = %u(%s)\n", ulHXCode, dbg::ErrorCode(ulHXCode), ulUserCode, unSeverity, dbg::SevCode(unSeverity)));
if(!m_bAccessPointSetupFailed)
{
m_playerState.OnError(ulHXCode);
}
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::GroupAdded(UINT16 uGroupIndex,IHXGroup* pGroup)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::GroupAdded()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::GroupRemoved(UINT16 uGroupIndex, IHXGroup* pGroup)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::GroupRemoved()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::AllGroupsRemoved()
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::AllGroupsRemoved()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::TrackAdded(UINT16 uGroupIndex, UINT16 uTrackIndex,IHXValues* pTrack)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::TrackAdded(): group idx = %u; track idx = %u\n", uGroupIndex, uTrackIndex));
dbg::DumpObject(pTrack);
if(!m_bAccessPointSetupFailed)
{
// for smil case
if(HasRemoteURL(pTrack))
{
//XXXLCM to be 100% correct we should look at other track notifications
//and deal convoluted cases where we have both network and local links. For
//example, if we have a network source followed by a local source in a smil
//file we will incorrectly advertise that the current source is remote once
//the local source becomes current
OnNetConnect();
}
}
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::TrackRemoved(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pTrack)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::TrackRemoved()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::TrackStarted(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pTrack)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::TrackStarted()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::TrackStopped(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pTrack)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::TrackStopped()\n"));
return HXR_OK;
}
//IHXGroupSink
STDMETHODIMP
CHXAvPlayer::CurrentGroupSet(UINT16 uGroupIndex, IHXGroup* pGroup)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::CurrentGroupSet()\n"));
if(!m_bAccessPointSetupFailed)
{
// look for a non-local url in this group
UINT16 count = pGroup->GetTrackCount();
for(UINT16 idx = 0; idx < count; ++idx)
{
DPRINTF(SYMP_INFO, ("CHXAvPlayer::CurrentGroupSet(): group %u\n", idx));
comptr<IHXValues> val;
pGroup->GetTrack(idx, val.AsRef());
dbg::DumpObject(val); // 'url'
if(HasRemoteURL(val))
{
OnNetConnect();
}
}
}
return HXR_OK;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?