aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhuceke <ebsi4711@gmail.com>2013-01-16 07:38:32 -0800
committerhuceke <ebsi4711@gmail.com>2013-01-16 07:38:32 -0800
commit0cfa24e20985d376c4fe4fe41c9e54b4599c6013 (patch)
treec3f982b2de519726c09528ab849e046ec30a1ce3
parent99a536c4670690758da512e2434a88abc3259ed8 (diff)
parent5f33482f3bd2993576c6f7f616df68a9d6846d81 (diff)
Merge pull request #2080 from popcornmix/timestamp_fix2
[rbp] Fix for audio out of sync part 2
-rw-r--r--xbmc/cores/omxplayer/OMXAudio.cpp2
-rw-r--r--xbmc/cores/omxplayer/OMXVideo.cpp24
-rw-r--r--xbmc/cores/omxplayer/OMXVideo.h2
3 files changed, 21 insertions, 7 deletions
diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp
index a19004ac8f..10c332959f 100644
--- a/xbmc/cores/omxplayer/OMXAudio.cpp
+++ b/xbmc/cores/omxplayer/OMXAudio.cpp
@@ -866,6 +866,8 @@ unsigned int COMXAudio::AddPackets(const void* data, unsigned int len, double dt
if(m_av_clock->AudioStart())
{
omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME;
+ if(pts == DVD_NOPTS_VALUE)
+ omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN;
m_last_pts = pts;
diff --git a/xbmc/cores/omxplayer/OMXVideo.cpp b/xbmc/cores/omxplayer/OMXVideo.cpp
index b11aa22d5c..0464790c4d 100644
--- a/xbmc/cores/omxplayer/OMXVideo.cpp
+++ b/xbmc/cores/omxplayer/OMXVideo.cpp
@@ -84,7 +84,6 @@ COMXVideo::COMXVideo()
m_deinterlace = false;
m_hdmi_clock_sync = false;
m_first_frame = true;
- m_contains_valid_pts= false;
}
COMXVideo::~COMXVideo()
@@ -666,6 +665,9 @@ bool COMXVideo::Open(CDVDStreamInfo &hints, OMXClock *clock, bool deinterlace, b
m_deinterlace, m_hdmi_clock_sync);
m_first_frame = true;
+ // start from assuming all recent frames had valid pts
+ m_history_valid_pts = ~0;
+
return true;
}
@@ -720,6 +722,14 @@ unsigned int COMXVideo::GetSize()
return m_omx_decoder.GetInputBufferSize();
}
+static unsigned count_bits(int32_t value)
+{
+ unsigned bits = 0;
+ for(;value;++bits)
+ value &= value - 1;
+ return bits;
+}
+
int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts)
{
OMX_ERRORTYPE omx_err;
@@ -754,11 +764,11 @@ int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts)
omx_buffer->nFlags = 0;
omx_buffer->nOffset = 0;
-
- // if a stream contains any pts values, then use those with UNKNOWNs. Otherwise try using dts.
- if(pts != DVD_NOPTS_VALUE)
- m_contains_valid_pts = true;
- if(pts == DVD_NOPTS_VALUE && !m_contains_valid_pts)
+ // some packed bitstream AVI files set almost all pts values to DVD_NOPTS_VALUE, but have a scattering of real pts values.
+ // the valid pts values match the dts values.
+ // if a stream has had more than 4 valid pts values in the last 16, the use UNKNOWN, otherwise use dts
+ m_history_valid_pts = (m_history_valid_pts << 1) | (pts != DVD_NOPTS_VALUE);
+ if(pts == DVD_NOPTS_VALUE && count_bits(m_history_valid_pts & 0xffff) < 4)
pts = dts;
if(m_av_clock->VideoStart())
@@ -766,6 +776,8 @@ 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;
CLog::Log(LOGDEBUG, "OMXVideo::Decode VDec : setStartTime %f\n", (pts == DVD_NOPTS_VALUE ? 0.0 : pts) / DVD_TIME_BASE);
m_av_clock->VideoStart(false);
diff --git a/xbmc/cores/omxplayer/OMXVideo.h b/xbmc/cores/omxplayer/OMXVideo.h
index 24cc6c8b56..180c2dbeb8 100644
--- a/xbmc/cores/omxplayer/OMXVideo.h
+++ b/xbmc/cores/omxplayer/OMXVideo.h
@@ -90,7 +90,7 @@ protected:
bool m_deinterlace;
bool m_hdmi_clock_sync;
bool m_first_frame;
- bool m_contains_valid_pts;
+ uint32_t m_history_valid_pts;
bool NaluFormatStartCodes(enum CodecID codec, uint8_t *in_extradata, int in_extrasize);
};