diff options
author | huceke <ebsi4711@gmail.com> | 2013-01-16 07:38:32 -0800 |
---|---|---|
committer | huceke <ebsi4711@gmail.com> | 2013-01-16 07:38:32 -0800 |
commit | 0cfa24e20985d376c4fe4fe41c9e54b4599c6013 (patch) | |
tree | c3f982b2de519726c09528ab849e046ec30a1ce3 | |
parent | 99a536c4670690758da512e2434a88abc3259ed8 (diff) | |
parent | 5f33482f3bd2993576c6f7f616df68a9d6846d81 (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.cpp | 2 | ||||
-rw-r--r-- | xbmc/cores/omxplayer/OMXVideo.cpp | 24 | ||||
-rw-r--r-- | xbmc/cores/omxplayer/OMXVideo.h | 2 |
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); }; |