m_deinterlace = false;
m_hdmi_clock_sync = false;
m_first_frame = true;
- m_contains_valid_pts= false;
}
COMXVideo::~COMXVideo()
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;
}
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;
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())
// 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);