Skip to content

Commit

Permalink
[omxplayer] Update to new VideoPlayer sync scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix authored and FernetMenta committed Oct 9, 2015
1 parent a8239b1 commit 25b9a81
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 102 deletions.
19 changes: 5 additions & 14 deletions xbmc/cores/VideoPlayer/VideoPlayer.cpp
Expand Up @@ -1881,6 +1881,11 @@ void CVideoPlayer::HandlePlaySpeed()
{
clock = m_CurrentVideo.starttime - m_CurrentVideo.cachetotal;
}
if (m_omxplayer_mode)
{
CLog::Log(LOGDEBUG, "%s::%s player started RESET", "CVideoPlayer", __FUNCTION__);
m_OmxPlayerState.av_clock.OMXReset(m_CurrentVideo.id >= 0, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false: (m_CurrentAudio.id >= 0));
}
m_clock.Discontinuity(clock);
m_CurrentAudio.syncState = IDVDStreamPlayer::SYNC_INSYNC;
m_CurrentVideo.syncState = IDVDStreamPlayer::SYNC_INSYNC;
Expand Down Expand Up @@ -2678,20 +2683,6 @@ void CVideoPlayer::HandleMessages()
m_CurrentVideo.starttime = msg.timestamp;
}
CLog::Log(LOGDEBUG, "CVideoPlayer::HandleMessages - player started %d", msg.player);

if (m_omxplayer_mode)
{
if ((msg.player == VideoPlayer_AUDIO || msg.player == VideoPlayer_VIDEO) &&
((m_playSpeed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_NORMAL) || !m_HasAudio ||
m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_INSYNC) &&
(!m_HasVideo || m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_INSYNC))
{
CLog::Log(LOGDEBUG, "%s::%s player started RESET", "CVideoPlayer", __FUNCTION__);
m_OmxPlayerState.av_clock.OMXReset(m_HasVideo, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false:m_HasAudio);
}
CLog::Log(LOGDEBUG, "%s::%s player started %d (s:%d a:%d v:%d)", "CVideoPlayer", __FUNCTION__, msg.player, m_playSpeed,
m_CurrentAudio.syncState, m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_INSYNC);
}
}
else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
{
Expand Down
9 changes: 2 additions & 7 deletions xbmc/cores/omxplayer/OMXAudio.cpp
Expand Up @@ -1098,13 +1098,7 @@ bool COMXAudio::ApplyVolume(void)
}

//***********************************************************************************************
unsigned int COMXAudio::AddPackets(const void* data, unsigned int len)
{
return AddPackets(data, len, 0, 0, 0);
}

//***********************************************************************************************
unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dts, double pts, unsigned int frame_size)
unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dts, double pts, unsigned int frame_size, bool &settings_changed)
{
CSingleLock lock (m_critSection);

Expand Down Expand Up @@ -1240,6 +1234,7 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt
m_submitted += (float)demuxer_samples / m_SampleRate;
if (m_amplification != 1.0)
UpdateAttenuation();
settings_changed = m_settings_changed;
return len;
}

Expand Down
3 changes: 1 addition & 2 deletions xbmc/cores/omxplayer/OMXAudio.h
Expand Up @@ -64,8 +64,7 @@ class COMXAudio
bool PortSettingsChanged();
~COMXAudio();

unsigned int AddPackets(const void* data, unsigned int len);
unsigned int AddPackets(const void* data, unsigned int len, double dts, double pts, unsigned int frame_size);
unsigned int AddPackets(const void* data, unsigned int len, double dts, double pts, unsigned int frame_size, bool &settings_changed);
unsigned int GetSpace();
bool Deinitialize();

Expand Down
87 changes: 49 additions & 38 deletions xbmc/cores/omxplayer/OMXPlayerAudio.cpp
Expand Up @@ -40,7 +40,6 @@
#include "settings/Settings.h"
#include "utils/TimeUtils.h"

#include "VideoPlayer.h"
#include "linux/RBP.h"
#include "cores/AudioEngine/AEFactory.h"
#include "cores/DataCacheCore.h"
Expand Down Expand Up @@ -216,18 +215,23 @@ bool OMXPlayerAudio::CodecChange()
return false;
}

bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay)
{
if(!pkt || m_bad_state || !m_pAudioCodec)
return false;

if(pkt->dts != DVD_NOPTS_VALUE)
m_audioClock = pkt->dts;

bool settings_changed = false;
const uint8_t *data_dec = pkt->pData;
int data_len = pkt->iSize;

if(!OMX_IS_RAW(m_format.m_dataFormat) && !bDropPacket)
if (bTrickPlay)
{
settings_changed = true;
}
else if(!OMX_IS_RAW(m_format.m_dataFormat) && !bDropPacket)
{
double dts = pkt->dts, pts=pkt->pts;
while(!m_bStop && data_len > 0)
Expand Down Expand Up @@ -277,7 +281,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
if(m_silence)
memset(decoded, 0x0, decoded_size);

ret = m_omxAudio.AddPackets(decoded, decoded_size, dts, pts, m_pAudioCodec->GetFrameSize());
ret = m_omxAudio.AddPackets(decoded, decoded_size, dts, pts, m_pAudioCodec->GetFrameSize(), settings_changed);

if(ret != decoded_size)
{
Expand Down Expand Up @@ -315,7 +319,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
if(m_silence)
memset(pkt->pData, 0x0, pkt->iSize);

m_omxAudio.AddPackets(pkt->pData, pkt->iSize, m_audioClock, m_audioClock, 0);
m_omxAudio.AddPackets(pkt->pData, pkt->iSize, m_audioClock, m_audioClock, 0, settings_changed);
}

m_audioStats.AddSampleBytes(pkt->iSize);
Expand All @@ -324,14 +328,20 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
}
}

if(bDropPacket)
if(bDropPacket || bTrickPlay)
m_stalled = false;

// signal to our parent that we have initialized
if(m_started == false)
if(m_started == false && !bDropPacket && settings_changed)
{
m_started = true;
m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, VideoPlayer_AUDIO));
m_sync = false;
SStartMsg msg;
msg.player = VideoPlayer_AUDIO;
msg.cachetotal = DVD_SEC_TO_TIME(m_omxAudio.GetCacheTotal());
msg.cachetime = DVD_SEC_TO_TIME(m_omxAudio.GetCacheTime());
msg.timestamp = m_audioClock;
m_messageParent.Put(new CDVDMsgType<SStartMsg>(CDVDMsg::PLAYER_STARTED, msg));
}

return true;
Expand All @@ -344,9 +354,27 @@ void OMXPlayerAudio::Process()
while(!m_bStop)
{
CDVDMsg* pMsg;
int priority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0;
int timeout = 1000;

// read next packet and return -1 on error
int priority = 1;
//Do we want a new audio frame?
if (m_started == false || /* when not started */
m_speed == DVD_PLAYSPEED_NORMAL || /* when playing normally */
m_speed < DVD_PLAYSPEED_PAUSE || /* when rewinding */
(m_speed > DVD_PLAYSPEED_NORMAL && m_audioClock < m_av_clock->GetClock())) /* when behind clock in ff */
priority = 0;

if (m_started && !m_sync)
priority = 1;

// consider stream stalled if queue is empty
// we can't sync audio to clock with an empty queue
if (m_speed == DVD_PLAYSPEED_NORMAL)
{
timeout = 0;
}

MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority);

if (ret == MSGQ_TIMEOUT)
Expand All @@ -370,7 +398,7 @@ void OMXPlayerAudio::Process()
CLog::Log(LOGINFO, "Audio: dts:%.0f pts:%.0f size:%d (s:%d f:%d d:%d l:%d) s:%d %d/%d late:%d,%d", pPacket->dts, pPacket->pts,
(int)pPacket->iSize, m_started, m_flush, bPacketDrop, m_stalled, m_speed, 0, 0, (int)m_omxAudio.GetAudioRenderingLatency(), (int)m_hints_current.samplerate);
#endif
if(Decode(pPacket, m_speed > DVD_PLAYSPEED_NORMAL || m_speed < 0 || bPacketDrop))
if(Decode(pPacket, bPacketDrop, m_speed > DVD_PLAYSPEED_NORMAL || m_speed < 0))
{
// we are not running until something is cached in output device
if(m_stalled && m_omxAudio.GetCacheTime() > 0.0)
Expand All @@ -389,18 +417,11 @@ void OMXPlayerAudio::Process()
}
else if (pMsg->IsType(CDVDMsg::GENERAL_RESYNC))
{ //player asked us to set internal clock
CDVDMsgGeneralResync* pMsgGeneralResync = (CDVDMsgGeneralResync*)pMsg;

if (pMsgGeneralResync->m_clock && pMsgGeneralResync->m_timestamp != DVD_NOPTS_VALUE)
{
CLog::Log(LOGDEBUG, "CVideoPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, %f, 1)", m_audioClock, pMsgGeneralResync->m_timestamp);
m_av_clock->Discontinuity(pMsgGeneralResync->m_timestamp);
}
else
CLog::Log(LOGDEBUG, "CVideoPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, 0)", m_audioClock);
double pts = static_cast<CDVDMsgDouble*>(pMsg)->m_value;
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f)", pts);

m_flush = false;
m_audioClock = DVD_NOPTS_VALUE;
m_audioClock = pts;
m_sync = true;
}
else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))
{
Expand All @@ -420,20 +441,16 @@ void OMXPlayerAudio::Process()
if (m_pAudioCodec)
m_pAudioCodec->Reset();
m_audioClock = DVD_NOPTS_VALUE;
}
else if (pMsg->IsType(CDVDMsg::PLAYER_STARTED))
{
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::PLAYER_STARTED %d", m_started);
if(m_started)
m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, VideoPlayer_AUDIO));
m_flush = false;
}
else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
{
CVideoPlayer::SPlayerState& state = ((CDVDMsgType<CVideoPlayer::SPlayerState>*)pMsg)->m_value;
SPlayerState& state = ((CDVDMsgType<SPlayerState>*)pMsg)->m_value;
state.player = VideoPlayer_AUDIO;

if (m_speed != DVD_PLAYSPEED_NORMAL && m_speed != DVD_PLAYSPEED_PAUSE)
{
if(state.time_src == CVideoPlayer::ETIMESOURCE_CLOCK)
if(state.time_src == ETIMESOURCE_CLOCK)
state.time = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
else
state.timestamp = CDVDClock::GetAbsoluteClock();
Expand All @@ -442,27 +459,21 @@ void OMXPlayerAudio::Process()
{
double pts = m_audioClock;
double stamp = m_av_clock->OMXMediaTime();
if(state.time_src == CVideoPlayer::ETIMESOURCE_CLOCK)
if(state.time_src == ETIMESOURCE_CLOCK)
state.time = stamp == 0.0 ? state.time : DVD_TIME_TO_MSEC(stamp + state.time_offset);
else
state.time = stamp == 0.0 || pts == DVD_NOPTS_VALUE ? state.time : state.time + DVD_TIME_TO_MSEC(stamp - pts);
state.timestamp = CDVDClock::GetAbsoluteClock();
if (stamp == 0.0) // cause message to be ignored
state.player = 0;
}
state.player = VideoPlayer_AUDIO;
m_messageParent.Put(pMsg->Acquire());
}
else if (pMsg->IsType(CDVDMsg::GENERAL_EOF))
{
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_EOF");
SubmitEOS();
}
else if (pMsg->IsType(CDVDMsg::GENERAL_DELAY))
{
double timeout = static_cast<CDVDMsgDouble*>(pMsg)->m_value;
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_DELAY(%f)", timeout);
}
else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
{
if (m_speed != static_cast<CDVDMsgInt*>(pMsg)->m_value)
Expand Down Expand Up @@ -491,12 +502,12 @@ void OMXPlayerAudio::Process()
}
}

void OMXPlayerAudio::Flush()
void OMXPlayerAudio::Flush(bool sync)
{
m_flush = true;
m_messageQueue.Flush();
m_messageQueue.Flush(CDVDMsg::GENERAL_EOF);
m_messageQueue.Put( new CDVDMsg(CDVDMsg::GENERAL_FLUSH), 1);
m_messageQueue.Put( new CDVDMsgBool(CDVDMsg::GENERAL_FLUSH, sync), 1);
}

void OMXPlayerAudio::WaitForBuffers()
Expand Down
6 changes: 3 additions & 3 deletions xbmc/cores/omxplayer/OMXPlayerAudio.h
Expand Up @@ -58,6 +58,7 @@ class OMXPlayerAudio : public CThread, public IDVDStreamPlayerAudio

bool m_stalled;
bool m_started;
bool m_sync;

BitstreamStats m_audioStats;

Expand Down Expand Up @@ -87,9 +88,8 @@ class OMXPlayerAudio : public CThread, public IDVDStreamPlayerAudio
void WaitForBuffers();
void CloseStream(bool bWaitForBuffers);
bool CodecChange();
bool Decode(DemuxPacket *pkt, bool bDropPacket);
void Flush();
bool AddPacket(DemuxPacket *pkt);
bool Decode(DemuxPacket *pkt, bool bDropPacket, bool bTrickPlay);
void Flush(bool sync);
AEDataFormat GetDataFormat(CDVDStreamInfo hints);
bool IsPassthrough() const;
bool OpenDecoder();
Expand Down

0 comments on commit 25b9a81

Please sign in to comment.