Skip to content
Browse files

[rbp] Fix for stuttery video when seeking before zero

There are a few issues with seeking I found.
We weren't correctly setting OMX_BUFFERFLAG_TIME_UNKNOWN on the first frame after a seek which could make the GPU think video was at 0 and audio at a much larger offset.
A full video fifo (to GPU) stops any higher priority messages from being received which can stall a seek and the flush message doesn't get through. Use m_flush to discard the video packet that doesn't fit.
We get an audio frame through with unknown pts/dts after the flush, but before the GENERAL_RESYNC when seeking. This was given to GPU and was perhaps 30 seconds out from the following packets and that throws off the timing between audio and video streams. Keeping m_flush true until the GENERAL_RESYNC discards this frame. Hopefully that is safe.
  • Loading branch information...
1 parent fd751b8 commit 632825b71a2bc248eb5705666debc5f7653d6878 @popcornmix popcornmix committed
View
13 xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -369,13 +369,9 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
while(!m_bStop)
{
+ // discard if flushing as clocks may be stopped and we'll never submit it
if(m_flush)
- {
- CSingleLock lock(m_flushLock);
- m_flush = false;
- lock.Leave();
break;
- }
if(m_omxAudio.GetSpace() < (unsigned int)pkt->iSize)
{
@@ -420,12 +416,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
while(!m_bStop)
{
if(m_flush)
- {
- CSingleLock lock(m_flushLock);
- m_flush = false;
- lock.Leave();
break;
- }
if(m_omxAudio.GetSpace() < (unsigned int)pkt->iSize)
{
@@ -544,6 +535,7 @@ void OMXPlayerAudio::Process()
}
else
CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_RESYNC(%f, 0)", m_audioClock);
+ m_flush = false;
}
else if (pMsg->IsType(CDVDMsg::GENERAL_RESET))
{
@@ -627,7 +619,6 @@ void OMXPlayerAudio::Process()
void OMXPlayerAudio::Flush()
{
- CSingleLock lock(m_flushLock);
m_flush = true;
m_messageQueue.Flush();
m_messageQueue.Put( new CDVDMsg(CDVDMsg::GENERAL_FLUSH), 1);
View
1 xbmc/cores/omxplayer/OMXPlayerAudio.h
@@ -42,7 +42,6 @@ using namespace std;
class OMXPlayerAudio : public CThread
{
protected:
- CCriticalSection m_flushLock;
CDVDMessageQueue m_messageQueue;
CDVDMessageQueue &m_messageParent;
View
7 xbmc/cores/omxplayer/OMXPlayerVideo.cpp
@@ -122,6 +122,7 @@ bool OMXPlayerVideo::OpenStream(CDVDStreamInfo &hints)
m_Deinterlace = ( g_settings.m_currentVideoSettings.m_DeinterlaceMode == VS_DEINTERLACEMODE_OFF ) ? false : true;
m_hdmi_clock_sync = (g_guiSettings.GetInt("videoplayer.adjustrefreshrate") != ADJUST_REFRESHRATE_OFF);
m_started = false;
+ m_flush = false;
m_stalled = m_messageQueue.GetPacketCount(CDVDMsg::DEMUXER_PACKET) == 0;
m_autosync = 1;
m_iSleepEndTime = DVD_NOPTS_VALUE;
@@ -593,6 +594,7 @@ void OMXPlayerVideo::Process()
m_omxVideo.Reset();
m_av_clock->OMXReset(false);
m_av_clock->UnLock();
+ m_flush = false;
}
else if (pMsg->IsType(CDVDMsg::PLAYER_SETSPEED))
{
@@ -633,6 +635,10 @@ void OMXPlayerVideo::Process()
while (!m_bStop)
{
+ // discard if flushing as clocks may be stopped and we'll never submit it
+ if (m_flush)
+ break;
+
if((int)m_omxVideo.GetFreeSpace() < pPacket->iSize)
{
Sleep(10);
@@ -697,6 +703,7 @@ void OMXPlayerVideo::Process()
void OMXPlayerVideo::Flush()
{
+ m_flush = true;
m_messageQueue.Flush();
m_messageQueue.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH), 1);
}
View
1 xbmc/cores/omxplayer/OMXPlayerVideo.h
@@ -61,6 +61,7 @@ class OMXPlayerVideo : public CThread
int m_audio_count;
bool m_stalled;
bool m_started;
+ bool m_flush;
std::string m_codecname;
double m_droptime;
double m_dropbase;
View
11 xbmc/cores/omxplayer/OMXVideo.cpp
@@ -809,17 +809,12 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts)
// only send dts on first frame to get nearly correct starttime
if(pts == DVD_NOPTS_VALUE)
pts = dts;
- if(pts == DVD_NOPTS_VALUE)
- omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
- omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME;
+ omx_buffer->nFlags |= OMX_BUFFERFLAG_STARTTIME;
CLog::Log(LOGDEBUG, "OMXVideo::Decode VDec : setStartTime %f\n", (pts == DVD_NOPTS_VALUE ? 0.0 : pts) / DVD_TIME_BASE);
m_av_clock->VideoStart(false);
}
- else
- {
- if(pts == DVD_NOPTS_VALUE)
- omx_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
- }
+ if(pts == DVD_NOPTS_VALUE)
+ omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
omx_buffer->nTimeStamp = ToOMXTime((uint64_t)(pts == DVD_NOPTS_VALUE) ? 0 : pts);
omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes;

0 comments on commit 632825b

Please sign in to comment.
Something went wrong with that request. Please try again.