bool OMXClock::OMXWaitStart(double pts, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); OMXSetClockPorts(&clock); clock.nStartTime = ToOMXTime((uint64_t)pts); omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXWaitStart error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } if(lock) UnLock(); return true; }
bool OMXClock::OMXWaitStart(double pts, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); if(pts == DVD_NOPTS_VALUE) pts = 0; clock.nStartTime = ToOMXTime((uint64_t)pts); if(pts == DVD_NOPTS_VALUE) { clock.eState = OMX_TIME_ClockStateRunning; clock.nWaitMask = 0; } else { clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); if(m_has_audio) { clock.nWaitMask |= OMX_CLOCKPORT0; } if(m_has_video) { clock.nWaitMask |= OMX_CLOCKPORT1; clock.nWaitMask |= OMX_CLOCKPORT2; } } omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXWaitStart error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } if(lock) UnLock(); return true; }
bool OMXClock::Stop(bool lock) { if (!GetComponent()) return false; if (lock) Lock(); OMX_ERRORTYPE omxErr = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateStopped; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); omxErr = SetConfig(OMX_IndexConfigTimeClockState, &clock); if (omxErr != OMX_ErrorNone) { if (lock) Unlock(); return false; } m_eState = clock.eState; m_lastMediaTime = 0.0f; if (lock) Unlock(); return true; }
bool OMXClock::OMXUpdateClock(double pts) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_TIMESTAMPTYPE ts; OMX_INIT_STRUCTURE(ts); ts.nPortIndex = OMX_ALL; ts.nTimestamp = ToOMXTime((uint64_t)pts); if(m_has_audio) { omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeCurrentAudioReference, &ts); if(omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "OMXClock::OMXUpdateClock error setting OMX_IndexConfigTimeCurrentAudioReference\n"); } else { omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeCurrentVideoReference, &ts); if(omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "OMXClock::OMXUpdateClock error setting OMX_IndexConfigTimeCurrentVideoReference\n"); } return true; }
bool OMXClock::OMXStart(double pts, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateRunning; clock.nStartTime = ToOMXTime((uint64_t)pts); omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Start error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } if(lock) UnLock(); return true; }
bool OMXClock::OMXStart(bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); CLog::Log(LOGDEBUG, "OMXClock::OMXStart\n"); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateRunning; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Start error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } if(lock) UnLock(); return true; }
bool OMXClock::OMXStop(bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); LOG_TRACE_2 << "OMXClock::OMXStop"; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateStopped; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { LOG_ERROR << "OMXClock::Stop error setting OMX_IndexConfigTimeClockState"; if(lock) UnLock(); return false; } m_eState = clock.eState; m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
void COMXVideo::SubmitEOS() { if(!m_is_open) return; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "%s::%s - buffer error 0x%08x", CLASSNAME, __func__, omx_err); return; } omx_buffer->nOffset = 0; omx_buffer->nFilledLen = 0; omx_buffer->nTimeStamp = ToOMXTime(0LL); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_TIME_UNKNOWN; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return; } CLog::Log(LOGDEBUG, "%s::%s\n", CLASSNAME, __func__); }
void COMXVideo::SubmitEOS() { CSingleLock lock (m_critSection); if(!m_is_open) return; m_submitted_eos = true; m_failed_eos = false; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(1000); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "%s::%s - buffer error 0x%08x", CLASSNAME, __func__, omx_err); m_failed_eos = true; return; } omx_buffer->nOffset = 0; omx_buffer->nFilledLen = 0; omx_buffer->nTimeStamp = ToOMXTime(0LL); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_TIME_UNKNOWN; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); m_omx_decoder.DecoderEmptyBufferDone(m_omx_decoder.GetComponent(), omx_buffer); return; } CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); }
bool OMXClock::OMXUpdateClock(double pts, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_TIMESTAMPTYPE ts; OMX_INIT_STRUCTURE(ts); ts.nPortIndex = OMX_ALL; ts.nTimestamp = ToOMXTime((uint64_t)pts); CLog::Log(LOGDEBUG, "OMXClock::OMXUpdateClock %f", pts / DVD_TIME_BASE); if(m_has_audio) { omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeCurrentAudioReference, &ts); if(omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "OMXClock::OMXUpdateClock error setting OMX_IndexConfigTimeCurrentAudioReference\n"); } else { omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeCurrentVideoReference, &ts); if(omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "OMXClock::OMXUpdateClock error setting OMX_IndexConfigTimeCurrentVideoReference\n"); } if(lock) UnLock(); return true; }
bool OMXClock::OMXReset(bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); m_audio_buffer = false; OMX_ERRORTYPE omx_err = OMX_ErrorNone; if(!OMXSetReferenceClock(false)) { if(lock) UnLock(); return false; } OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); omx_err = m_omx_clock.GetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXReset error getting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); OMXSetClockPorts(&clock); if(clock.nWaitMask) { omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXReset error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } } CLog::Log(LOGDEBUG, "OMXClock::OMXReset audio / video : %d / %d start audio / video : %d / %d wait mask %d\n", m_has_audio, m_has_video, m_audio_start, m_video_start, clock.nWaitMask); if(lock) UnLock(); return true; }
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; }
bool OMXClock::OMXInitialize(bool has_video, bool has_audio) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; std::string componentName = ""; m_has_video = has_video; m_has_audio = has_audio; componentName = "OMX.broadcom.clock"; if(!m_omx_clock.Initialize(componentName, OMX_IndexParamOtherInit)) return false; #if 0 OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); if(m_has_audio) { clock.nWaitMask |= OMX_CLOCKPORT0; } if(m_has_video) { clock.nWaitMask |= OMX_CLOCKPORT1; clock.nWaitMask |= OMX_CLOCKPORT2; } omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Initialize error setting OMX_IndexConfigTimeClockState\n"); return false; } #endif OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); if(m_has_audio) refClock.eClock = OMX_TIME_RefClockAudio; else refClock.eClock = OMX_TIME_RefClockVideo; omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeActiveRefClock, &refClock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Initialize error setting OMX_IndexConfigTimeCurrentAudioReference\n"); return false; } return true; }
// Set the media time, so calls to get media time use the updated value, // useful after a seek so mediatime is updated immediately (rather than waiting for first decoded packet) bool OMXClock::OMXMediaTime(double pts, bool lock /* = true*/) { if(m_omx_clock.GetComponent() == NULL) { return false; } if(lock) { Lock(); } OMX_ERRORTYPE error = OMX_ErrorNone; OMX_INDEXTYPE index; OMX_TIME_CONFIG_TIMESTAMPTYPE timeStamp; OMX_INIT_STRUCTURE(timeStamp); timeStamp.nPortIndex = m_omx_clock.GetInputPort(); if(m_has_audio) { index = OMX_IndexConfigTimeCurrentAudioReference; } else { index = OMX_IndexConfigTimeCurrentVideoReference; } timeStamp.nTimestamp = ToOMXTime(pts); error = m_omx_clock.SetConfig(index, &timeStamp); if(error != OMX_ErrorNone) { ofLog(OF_LOG_ERROR, "OMXClock::OMXMediaTime error setting %s", index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference"); ofLogError(__func__) << COMXCore::getOMXError(error); if(lock) { UnLock(); } return false; } ofLog(OF_LOG_VERBOSE, "OMXClock::OMXMediaTime set config %s = %.2f (%.2f)", index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference", pts, OMXMediaTime(false)); if(lock) { UnLock(); } return true; }
bool OMXClock::OMXReset(bool has_video, bool has_audio, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); if(!OMXSetReferenceClock(has_audio, false)) { if(lock) UnLock(); return false; } if (m_eState == OMX_TIME_ClockStateStopped) { OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); OMXSetClockPorts(&clock, has_video, has_audio); if(clock.nWaitMask) { OMX_ERRORTYPE omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { LOG_ERROR << "OMXClock::OMXReset error setting OMX_IndexConfigTimeClockState"; if(lock) UnLock(); return false; } sprintf(g_log_buf, "OMXClock::OMXReset audio / video : %d / %d wait mask %d->%d state : %d->%d\n", has_audio, has_video, m_WaitMask, clock.nWaitMask, m_eState, clock.eState); LOG_TRACE_2 << g_log_buf; if (m_eState != OMX_TIME_ClockStateStopped) m_WaitMask = clock.nWaitMask; m_eState = clock.eState; } } m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
unsigned int CAESinkPi::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking) { unsigned int sent = 0; if (!m_Initialized) return frames; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = NULL; while (sent < frames) { int timeout = blocking ? 1000 : 0; // delay compared to maximum we'd like (to keep lag low) double delay = GetDelay(); bool too_laggy = delay - AUDIO_PLAYBUFFER > 0.0; omx_buffer = too_laggy ? NULL : m_omx_render.GetInputBuffer(timeout); if (omx_buffer == NULL) { if (too_laggy) { Sleep((int)((delay - AUDIO_PLAYBUFFER) * 1000.0)); continue; } if (blocking) CLog::Log(LOGERROR, "COMXAudio::Decode timeout"); break; } omx_buffer->nFilledLen = std::min(omx_buffer->nAllocLen, (frames - sent) * m_format.m_frameSize); omx_buffer->nTimeStamp = ToOMXTime(0); omx_buffer->nFlags = 0; memcpy(omx_buffer->pBuffer, (uint8_t *)data + sent * m_format.m_frameSize, omx_buffer->nFilledLen); sent += omx_buffer->nFilledLen / m_format.m_frameSize; if (sent == frames) omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; if (delay <= 0.0 && m_submitted) CLog::Log(LOGERROR, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames); omx_err = m_omx_render.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err); m_submitted += omx_buffer->nFilledLen; } return sent; }
bool OMXClock::Reset(bool hasVideo, bool hasAudio, bool lock) { if (!GetComponent()) return false; if (lock) Lock(); if (!SetReferenceClock(hasAudio, false)) { if (lock) Unlock(); return false; } if (m_eState == OMX_TIME_ClockStateStopped) { OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); SetClockPorts(&clock, hasVideo, hasAudio); if (clock.nWaitMask) { OMX_ERRORTYPE omxErr = SetConfig(OMX_IndexConfigTimeClockState, &clock); if (omxErr != OMX_ErrorNone) { if (lock) Unlock(); return false; } if (m_eState != OMX_TIME_ClockStateStopped) m_waitMask = clock.nWaitMask; m_eState = clock.eState; } } m_lastMediaTime = 0.0f; if (lock) Unlock(); return true; }
void COMXVideo::WaitCompletion() { if(!m_is_open) return; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "%s::%s - buffer error 0x%08x", CLASSNAME, __func__, omx_err); return; } omx_buffer->nOffset = 0; omx_buffer->nFilledLen = 0; omx_buffer->nTimeStamp = ToOMXTime(0LL); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_TIME_UNKNOWN; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return; } unsigned int nTimeOut = 30000; while(nTimeOut) { if(m_omx_render.IsEOS()) { CLog::Log(LOGDEBUG, "%s::%s - got eos\n", CLASSNAME, __func__); break; } if(nTimeOut == 0) { CLog::Log(LOGERROR, "%s::%s - wait for eos timed out\n", CLASSNAME, __func__); break; } Sleep(50); nTimeOut -= 50; } m_omx_render.ResetEos(); return; }
bool OMXClock::OMXReset(bool lock /* = true */) { if(lock) Lock(); m_iCurrentPts = DVD_NOPTS_VALUE; m_video_clock = DVD_NOPTS_VALUE; m_audio_clock = DVD_NOPTS_VALUE; if(m_omx_clock.GetComponent() != NULL) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); OMXStop(false); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; clock.nOffset = ToOMXTime(-1000LL * OMX_PRE_ROLL); if(m_has_audio) { clock.nWaitMask |= OMX_CLOCKPORT0; } if(m_has_video) { clock.nWaitMask |= OMX_CLOCKPORT1; clock.nWaitMask |= OMX_CLOCKPORT2; } omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeClockState, &clock); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Reset error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } OMXStart(0.0, false); } if(lock) UnLock(); return true; }
void COMXVideo::WaitCompletion() { if(!m_is_open) return; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(); struct timespec starttime, endtime; if(omx_buffer == NULL) { CLog::Log(LOGERROR, "%s::%s - buffer error 0x%08x", CLASSNAME, __func__, omx_err); return; } omx_buffer->nOffset = 0; omx_buffer->nFilledLen = 0; omx_buffer->nTimeStamp = ToOMXTime(0LL); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_TIME_UNKNOWN; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return; } clock_gettime(CLOCK_REALTIME, &starttime); while(true) { if(m_omx_render.IsEOS()) break; clock_gettime(CLOCK_REALTIME, &endtime); if((endtime.tv_sec - starttime.tv_sec) > 5) { CLog::Log(LOGERROR, "%s::%s - wait for eos timed out\n", CLASSNAME, __func__); break; } OMXClock::OMXSleep(50); } return; }
void OMXEGLImage::WaitCompletion() { ofLogVerbose() << "OMXEGLImage::WaitCompletion"; if(!m_is_open) return; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(); if(omx_buffer == NULL) { ofLog(OF_LOG_VERBOSE, "%s::%s - buffer error 0x%08x", CLASSNAME, __func__, omx_err); return; } omx_buffer->nOffset = 0; omx_buffer->nFilledLen = 0; omx_buffer->nTimeStamp = ToOMXTime(0LL); omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS | OMX_BUFFERFLAG_TIME_UNKNOWN; omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err != OMX_ErrorNone) { ofLog(OF_LOG_VERBOSE, "\n%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return; } while(true) { if(m_omx_render.IsEOS()) { ofLogVerbose() << "OMXVideo reached End of Stream"; m_omx_render.SetEOS(false); break; } OMXClock::OMXSleep(50); } return; }
// Set the media time, so calls to get media time use the updated value, // useful after a seek so mediatime is updated immediately (rather than waiting for first decoded packet) bool OMXClock::OMXMediaTime(double pts, bool fixPreroll /* = true*/, bool lock /* = true*/) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_INDEXTYPE index; OMX_TIME_CONFIG_TIMESTAMPTYPE timeStamp; OMX_INIT_STRUCTURE(timeStamp); timeStamp.nPortIndex = m_omx_clock.GetInputPort(); if(g_guiSettings.GetBool("videoplayer.usedisplayasclock") && m_has_video) index = OMX_IndexConfigTimeCurrentVideoReference; else if(m_has_audio) index = OMX_IndexConfigTimeCurrentAudioReference; else index = OMX_IndexConfigTimeCurrentVideoReference; if(fixPreroll) pts -= (OMX_PRE_ROLL * 1000); timeStamp.nTimestamp = ToOMXTime(pts); omx_err = m_omx_clock.SetConfig(index, &timeStamp); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXMediaTime error setting %s", index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference"); if(lock) UnLock(); return false; } CLog::Log(LOGDEBUG, "OMXClock::OMXMediaTime set config %s = %.2f", index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference", pts); if(lock) UnLock(); return true; }
// Set the media time, so calls to get media time use the updated value, // useful after a seek so mediatime is updated immediately (rather than waiting for first decoded packet) bool OMXClock::OMXMediaTime(double pts, bool lock /* = true*/) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_INDEXTYPE index; OMX_TIME_CONFIG_TIMESTAMPTYPE timeStamp; OMX_INIT_STRUCTURE(timeStamp); timeStamp.nPortIndex = m_omx_clock.GetInputPort(); if(m_eClock == OMX_TIME_RefClockAudio) index = OMX_IndexConfigTimeCurrentAudioReference; else index = OMX_IndexConfigTimeCurrentVideoReference; timeStamp.nTimestamp = ToOMXTime(pts); omx_err = m_omx_clock.SetConfig(index, &timeStamp); if(omx_err != OMX_ErrorNone) { LOG_ERROR << "OMXClock::OMXMediaTime error setting " << (index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference"); if(lock) UnLock(); return false; } sprintf(g_log_buf, "OMXClock::OMXMediaTime set config %s = %.2f", index == OMX_IndexConfigTimeCurrentAudioReference ? "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference", pts); LOG_TRACE_2 << g_log_buf; m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
bool OMXClock::OMXStart(double pts, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) { return false; } if(lock) { Lock(); } ofLogNotice(__func__) << "at pts: " << pts; OMX_ERRORTYPE error = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateRunning; clock.nStartTime = ToOMXTime((uint64_t)pts); error = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock); if(error != OMX_ErrorNone) { ofLogError(__func__) << "SetConfig OMX_IndexConfigTimeClockState FAIL: " << COMXCore::getOMXError(error); if(lock) { UnLock(); } return false; } if(lock) { UnLock(); } return true; }
bool OMXClock::SetMediaTime(double pts, bool lock) { if (!GetComponent()) return false; if (lock) Lock(); OMX_ERRORTYPE omxErr = OMX_ErrorNone; OMX_INDEXTYPE index; OMX_TIME_CONFIG_TIMESTAMPTYPE timestamp; OMX_INIT_STRUCTURE(timestamp); timestamp.nPortIndex = GetInputPort(); if (m_eClock == OMX_TIME_RefClockAudio) index = OMX_IndexConfigTimeCurrentAudioReference; else index = OMX_IndexConfigTimeCurrentVideoReference; timestamp.nTimestamp = ToOMXTime(pts); omxErr = SetConfig(index, ×tamp); if (omxErr != OMX_ErrorNone) { if (lock) Unlock(); return false; } m_lastMediaTime = 0.0f; if (lock) Unlock(); return true; }
int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) { OMX_ERRORTYPE omx_err; if (pData || iSize > 0) { unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; while(demuxer_bytes) { // 500ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(500); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "OMXVideo::Decode timeout\n"); printf("COMXVideo::Decode timeout\n"); return false; } /* CLog::Log(DEBUG, "COMXVideo::Video VDec : pts %lld omx_buffer 0x%08x buffer 0x%08x number %d\n", pts, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); printf("VDec : pts %f omx_buffer 0x%08x buffer 0x%08x number %d\n", (float)pts / AV_TIME_BASE, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); */ omx_buffer->nFlags = 0; omx_buffer->nOffset = 0; // 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_setStartTime) { // only send dts on first frame to get nearly correct starttime if(pts == DVD_NOPTS_VALUE) pts = dts; 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_setStartTime = false; } if(pts == DVD_NOPTS_VALUE) omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; omx_buffer->nTimeStamp = ToOMXTime(pts == DVD_NOPTS_VALUE ? 0 : pts); omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes; memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; if(demuxer_bytes == 0) omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; int nRetry = 0; while(true) { omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err == OMX_ErrorNone) { break; } else { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); nRetry++; } if(nRetry == 5) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() finally failed\n", CLASSNAME, __func__); printf("%s::%s - OMX_EmptyThisBuffer() finaly failed\n", CLASSNAME, __func__); return false; } } omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, 0); if (omx_err == OMX_ErrorNone) { if(!PortSettingsChanged()) { CLog::Log(LOGERROR, "%s::%s - error PortSettingsChanged omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } } omx_err = m_omx_decoder.WaitForEvent(OMX_EventParamOrConfigChanged, 0); if (omx_err == OMX_ErrorNone) { if(!PortSettingsChanged()) { CLog::Log(LOGERROR, "%s::%s - error PortSettingsChanged (EventParamOrConfigChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } } } return true; } return false; }
int COMXVideo::DecodeText(uint8_t *pData, int iSize, double dts, double pts) { OMX_ERRORTYPE omx_err; if (pData || iSize > 0) { unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; while(demuxer_bytes) { // 10 ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_text.GetInputBuffer(10); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "OMXVideo::DecodeText timeout\n"); printf("COMXVideo::DecodeText timeout\n"); return false; } omx_buffer->nFlags = 0; uint64_t val = (uint64_t)(pts == DVD_NOPTS_VALUE) ? 0 : pts; if(m_setStartTimeText) { omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME; m_setStartTimeText = false; } else { if(pts == DVD_NOPTS_VALUE) omx_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; } omx_buffer->nTimeStamp = ToOMXTime(val); omx_buffer->nFilledLen = (demuxer_bytes > (omx_buffer->nAllocLen - 1)) ? (omx_buffer->nAllocLen - 1) : demuxer_bytes; memset(omx_buffer->pBuffer, 0x0, omx_buffer->nAllocLen); memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); /* printf("VDec : pts %lld omx_buffer 0x%08x buffer 0x%08x number %d text : %s\n", pts, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate, omx_buffer->pBuffer); */ demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; omx_buffer->nFlags |= OMX_BUFFERFLAG_EOS; omx_err = m_omx_text.EmptyThisBuffer(omx_buffer); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); printf("%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return false; } if(m_first_text) { m_omx_text.DisablePort(m_omx_text.GetInputPort(), false); m_omx_text.DisablePort(m_omx_text.GetOutputPort(), false); m_omx_text.EnablePort(m_omx_text.GetOutputPort(), false); m_omx_text.EnablePort(m_omx_text.GetInputPort(), false); m_first_text = false; } } return true; } return false; }
int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) { OMX_ERRORTYPE omx_err; if (pData || iSize > 0) { unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; if(m_video_convert) { m_converter->Convert(pData, iSize); demuxer_bytes = m_converter->GetConvertSize(); demuxer_content = m_converter->GetConvertBuffer(); if(!demuxer_bytes && demuxer_bytes < 1) { return false; } } while(demuxer_bytes) { // 500ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(500); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "OMXVideo::Decode timeout\n"); printf("COMXVideo::Decode timeout\n"); return false; } /* CLog::Log(DEBUG, "COMXVideo::Video VDec : pts %lld omx_buffer 0x%08x buffer 0x%08x number %d\n", pts, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); printf("VDec : pts %f omx_buffer 0x%08x buffer 0x%08x number %d\n", (float)pts / AV_TIME_BASE, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); */ omx_buffer->nFlags = 0; omx_buffer->nOffset = 0; uint64_t val = (uint64_t)(pts == DVD_NOPTS_VALUE) ? 0 : pts; if(m_setStartTime) { omx_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME; m_setStartTime = false; } else { if(pts == DVD_NOPTS_VALUE) omx_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; } omx_buffer->nTimeStamp = ToOMXTime(val); omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes; memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; if(demuxer_bytes == 0) omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; int nRetry = 0; while(true) { omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err == OMX_ErrorNone) { break; } else { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); nRetry++; } if(nRetry == 5) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() finaly failed\n", CLASSNAME, __func__); printf("%s::%s - OMX_EmptyThisBuffer() finaly failed\n", CLASSNAME, __func__); return false; } } /* omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); printf("%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); return false; } */ if(m_first_frame && m_deinterlace) { OMX_PARAM_PORTDEFINITIONTYPE port_image; OMX_INIT_STRUCTURE(port_image); port_image.nPortIndex = m_omx_decoder.GetOutputPort(); omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 1 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } /* we assume when the sizes equal we have the first decoded frame */ if(port_image.format.video.nFrameWidth == m_decoded_width && port_image.format.video.nFrameHeight == m_decoded_height) { m_first_frame = false; omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); if(omx_err == OMX_ErrorStreamCorrupt) { CLog::Log(LOGERROR, "%s::%s - image not unsupported\n", CLASSNAME, __func__); return false; } m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), false); m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), false); m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), false); m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), false); port_image.nPortIndex = m_omx_image_fx.GetInputPort(); omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 2 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error OMX_IndexParamPortDefinition 3 omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), false); m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), false); m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), false); m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), false); } } } return true; } return false; }
int COMXVideo::Decode(uint8_t *pData, int iSize, double dts, double pts) { OMX_ERRORTYPE omx_err; if( m_drop_state ) return true; unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; if (demuxer_content && demuxer_bytes > 0) { while(demuxer_bytes) { // 500ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(500); if(omx_buffer == NULL) { CLog::Log(LOGERROR, "OMXVideo::Decode timeout\n"); return false; } /* CLog::Log(DEBUG, "COMXVideo::Video VDec : pts %lld omx_buffer 0x%08x buffer 0x%08x number %d\n", pts, omx_buffer, omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); if(pts == DVD_NOPTS_VALUE) { CLog::Log(LOGDEBUG, "VDec : pts %f omx_buffer 0x%08x buffer 0x%08x number %d\n", (float)pts / AV_TIME_BASE, (int)omx_buffer, (int)omx_buffer->pBuffer, (int)omx_buffer->pAppPrivate); } */ omx_buffer->nFlags = 0; omx_buffer->nOffset = 0; // 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); } else { 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; memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; if(demuxer_bytes == 0) omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; int nRetry = 0; while(true) { omx_err = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (omx_err == OMX_ErrorNone) { break; } else { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", CLASSNAME, __func__, omx_err); nRetry++; } if(nRetry == 5) { CLog::Log(LOGERROR, "%s::%s - OMX_EmptyThisBuffer() finaly failed\n", CLASSNAME, __func__); return false; } } omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged, 0); if (omx_err == OMX_ErrorNone) { OMX_PARAM_PORTDEFINITIONTYPE port_image; OMX_INIT_STRUCTURE(port_image); port_image.nPortIndex = m_omx_decoder.GetOutputPort(); omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } // let OMXPlayerVideo know about resolution so it can inform RenderManager if (m_res_callback) m_res_callback(m_res_ctx, port_image.format.video.nFrameWidth, port_image.format.video.nFrameHeight); m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true); m_omx_sched.DisablePort(m_omx_sched.GetInputPort(), true); OMX_CONFIG_INTERLACETYPE interlace; OMX_INIT_STRUCTURE(interlace); interlace.nPortIndex = m_omx_decoder.GetOutputPort(); omx_err = m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace, &interlace); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetConfig(OMX_IndexConfigCommonInterlace) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } if (m_deinterlace) { m_omx_image_fx.DisablePort(m_omx_image_fx.GetInputPort(), true); port_image.nPortIndex = m_omx_image_fx.GetInputPort(); omx_err = m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } omx_err = m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } port_image.nPortIndex = m_omx_image_fx.GetOutputPort(); omx_err = m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_image_fx.GetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } m_omx_image_fx.EnablePort(m_omx_image_fx.GetInputPort(), true); m_omx_image_fx.DisablePort(m_omx_image_fx.GetOutputPort(), true); } port_image.nPortIndex = m_omx_sched.GetInputPort(); omx_err = m_omx_sched.SetParameter(OMX_IndexParamPortDefinition, &port_image); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.SetParameter(OMX_IndexParamPortDefinition) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } omx_err = m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_sched.WaitForEvent(OMX_EventPortSettingsChanged) omx_err(0x%08x)\n", CLASSNAME, __func__, omx_err); } if (m_deinterlace) { m_omx_image_fx.EnablePort(m_omx_image_fx.GetOutputPort(), true); } m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true); m_omx_sched.EnablePort(m_omx_sched.GetInputPort(), true); } } return true; } return false; }
int OMXEGLImage::Decode(uint8_t *pData, int iSize, double dts, double pts) { OMX_ERRORTYPE error; if (pData || iSize > 0) { unsigned int demuxer_bytes = (unsigned int)iSize; uint8_t *demuxer_content = pData; while(demuxer_bytes) { // 500ms timeout OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_decoder.GetInputBuffer(500); if(omx_buffer == NULL) { ofLog(OF_LOG_VERBOSE, "OMXEGLImage::Decode timeout\n"); return false; } omx_buffer->nFlags = 0; omx_buffer->nOffset = 0; // 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_setStartTime) { // only send dts on first frame to get nearly correct starttime if(pts == DVD_NOPTS_VALUE) { pts = dts; } omx_buffer->nFlags |= OMX_BUFFERFLAG_STARTTIME; ofLog(OF_LOG_VERBOSE, "OMXVideo::Decode VDec : setStartTime %f\n", (pts == DVD_NOPTS_VALUE ? 0.0 : pts) / DVD_TIME_BASE); m_setStartTime = false; } if(pts == DVD_NOPTS_VALUE) { omx_buffer->nFlags |= OMX_BUFFERFLAG_TIME_UNKNOWN; } omx_buffer->nTimeStamp = ToOMXTime(pts == DVD_NOPTS_VALUE ? 0 : pts); omx_buffer->nFilledLen = (demuxer_bytes > omx_buffer->nAllocLen) ? omx_buffer->nAllocLen : demuxer_bytes; memcpy(omx_buffer->pBuffer, demuxer_content, omx_buffer->nFilledLen); demuxer_bytes -= omx_buffer->nFilledLen; demuxer_content += omx_buffer->nFilledLen; if(demuxer_bytes == 0) { omx_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; } int nRetry = 0; while(true) { error = m_omx_decoder.EmptyThisBuffer(omx_buffer); if (error == OMX_ErrorNone) { break; } else { ofLog(OF_LOG_VERBOSE, "\n%s::%s - OMX_EmptyThisBuffer() failed with result(0x%x)\n", "OMXEGLImage", __func__, error); nRetry++; } if(nRetry == 5) { ofLog(OF_LOG_VERBOSE, "\n%s::%s - OMX_EmptyThisBuffer() finaly failed\n", "OMXEGLImage", __func__); return false; } } } return true; } return false; }