void CAESinkPi::Drain() { AEDelayStatus status; GetDelay(status); int delay = (int)(status.GetDelay() * 1000.0); if (delay) Sleep(delay); CLog::Log(LOGDEBUG, "%s:%s delay:%dms now:%dms", CLASSNAME, __func__, delay, (int)(status.GetDelay() * 1000.0)); }
unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset) { if (!m_Initialized || !m_omx_output || !frames) { Sleep(10); return frames; } OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = NULL; unsigned int channels = m_format.m_channelLayout.Count(); unsigned int sample_size = CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3; const int planes = AE_IS_PLANAR(m_format.m_dataFormat) ? channels : 1; const int chans = AE_IS_PLANAR(m_format.m_dataFormat) ? 1 : channels; const int pitch = chans * sample_size; AEDelayStatus status; GetDelay(status); double delay = status.GetDelay(); if (delay <= 0.0 && m_submitted) CLog::Log(LOGNOTICE, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames); omx_buffer = m_omx_output->GetInputBuffer(1000); if (omx_buffer == NULL) { CLog::Log(LOGERROR, "CAESinkPi::AddPackets timeout"); return 0; } omx_buffer->nFilledLen = frames * m_format.m_frameSize; // must be true assert(omx_buffer->nFilledLen <= omx_buffer->nAllocLen); omx_buffer->nTimeStamp = ToOMXTime(0); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; if (omx_buffer->nFilledLen) { int planesize = omx_buffer->nFilledLen / planes; for (int i=0; i < planes; i++) memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, data[i] + offset * pitch, planesize); } omx_err = m_omx_output->EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err); m_omx_output->DecoderEmptyBufferDone(m_omx_output->GetComponent(), omx_buffer); } m_submitted++; GetDelay(status); delay = status.GetDelay(); if (delay > m_latency) Sleep((int)(1000.0f * (delay - m_latency))); return frames; }
double CActiveAEStream::GetDelay() { AEDelayStatus status; AE.GetDelay(status, this); return status.GetDelay(); }