OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port, bool wait) { Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_PARAM_PORTDEFINITIONTYPE portFormat; OMX_INIT_STRUCTURE(portFormat); portFormat.nPortIndex = port; omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::EnablePort - Error get port %d status on component %s omx_err(0x%08x)", port, m_componentName.c_str(), (int)omx_err); } if(portFormat.bEnabled == OMX_FALSE) { omx_err = OMX_SendCommand(m_handle, OMX_CommandPortEnable, port, NULL); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::EnablePort - Error enable port %d on component %s omx_err(0x%08x)", port, m_componentName.c_str(), (int)omx_err); { UnLock(); return omx_err; } } else { if(wait) omx_err = WaitForCommand(OMX_CommandPortEnable, port); } } UnLock(); return omx_err; }
double OMXClock::OMXClockAdjustment(bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) { return 0; } if(lock) { Lock(); } OMX_ERRORTYPE error = OMX_ErrorNone; double pts = 0; OMX_TIME_CONFIG_TIMESTAMPTYPE timeStamp; OMX_INIT_STRUCTURE(timeStamp); timeStamp.nPortIndex = m_omx_clock.GetInputPort(); error = m_omx_clock.GetConfig(OMX_IndexConfigClockAdjustment, &timeStamp); if(error != OMX_ErrorNone) { ofLogError(__func__) << "GetConfig OMX_IndexConfigClockAdjustment FAIL: " << COMXCore::getOMXError(error); if(lock) { UnLock(); } return 0; } pts = (double)FromOMXTime(timeStamp.nTimestamp); //ofLogVerbose(__func__) << "nTimestamp: " << (double)FromOMXTime(timeStamp.nTimestamp) << " pts " << pts; if(lock) { UnLock(); } return pts; }
// 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) { 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); m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume /* = false */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); sprintf(g_log_buf, "OMXClock::OMXSetSpeed(%.2f) pause_resume:%d", (float)speed / (float)DVD_PLAYSPEED_NORMAL, pause_resume); LOG_TRACE_2 << g_log_buf; if (pause_resume) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); if (TP(speed)) scaleType.xScale = 0; // for trickplay we just pause, and single step else scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL; omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType); if(omx_err != OMX_ErrorNone) { LOG_ERROR << "OMXClock::OMXSetSpeed error setting OMX_IndexConfigTimeClockState"; if(lock) UnLock(); return false; } } if (!pause_resume) m_omx_speed = speed; m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
int32_t ilctts_set_dest(TTSRENDER_STATE_T *st, const char *name) { OMX_ERRORTYPE omx_err; OMX_CONFIG_BRCMAUDIODESTINATIONTYPE dest; char device[8]; if ( (strcmp(name, "local") != 0) && (strcmp(name, "hdmi") != 0) ) strcpy(device, "local"); else strcpy(device, name); OMX_INIT_STRUCTURE(dest); strcpy((char *)dest.sName, device); omx_err = OMX_SetConfig(ILC_GET_HANDLE(st->audio_render), OMX_IndexConfigBrcmAudioDestination, &dest); if (omx_err != OMX_ErrorNone) { ERROR("OMX_SetConfig returned error in ilctts_set_dest: %d", omx_err); return -1; } SHOW(LOGLEVEL_3, "Audio device set to: %s", device); return 0; } // end ilctts_set_dest
bool OMXClock::OMXSpeed(int speed) { if(m_omx_clock.GetComponent() == NULL) return false; OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); scaleType.xScale = (speed << 16); m_play_speed = speed; omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeScale, &scaleType); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Speed error setting OMX_IndexConfigTimeClockState\n"); return false; } return true; }
bool OMXClock::OMXStart() { if(m_omx_clock.GetComponent() == NULL) { return false; } OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_CLOCKSTATETYPE clock; OMX_INIT_STRUCTURE(clock); clock.eState = OMX_TIME_ClockStateRunning; 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"); return false; } 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 COMXVideo::GetPlayerInfo(double &match, double &phase, double &pll) { CSingleLock lock (m_critSection); OMX_ERRORTYPE omx_err; OMX_CONFIG_BRCMRENDERSTATSTYPE renderstats; if (!m_hdmi_clock_sync || !m_omx_render.IsInitialized()) return false; OMX_INIT_STRUCTURE(renderstats); renderstats.nPortIndex = m_omx_render.GetInputPort(); omx_err = m_omx_render.GetParameter(OMX_IndexConfigBrcmRenderStats, &renderstats); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::GetPlayerInfo error GetParameter OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } match = renderstats.nMatch * 1e-6; phase = (double)renderstats.nPhase / (double)renderstats.nPeriod; pll = (double)renderstats.nPixelClock / (double)renderstats.nPixelClockNominal; return true; }
bool OMXClock::OMXReset() { 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(); clock.eState = OMX_TIME_ClockStateWaitingForStartTime; 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"); return false; } OMXStart(); } return true; }
bool OMXClock::SetSpeed(int speed, bool lock, bool pause_resume) { if (!GetComponent()) return false; if (lock) Lock(); if (pause_resume) { OMX_ERRORTYPE omxErr = OMX_ErrorNone; OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); if (TP(speed)) scaleType.xScale = 0; else scaleType.xScale = (speed << 16) / CLOCK_PLAYSPEED_NORMAL; omxErr = SetConfig(OMX_IndexConfigTimeScale, &scaleType); if (omxErr != OMX_ErrorNone) { if (lock) Unlock(); return false; } } else m_omxSpeed = speed; m_lastMediaTime = 0.0f; if (lock) Unlock(); return true; }
void CAESinkPi::GetDelay(AEDelayStatus& status) { OMX_PARAM_U32TYPE param; OMX_INIT_STRUCTURE(param); if (!m_Initialized) { status.SetDelay(0); return; } param.nPortIndex = m_omx_render.GetInputPort(); OMX_ERRORTYPE omx_err = m_omx_render.GetConfig(OMX_IndexConfigAudioRenderingLatency, ¶m); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error getting OMX_IndexConfigAudioRenderingLatency error 0x%08x", CLASSNAME, __func__, omx_err); } double sinkbuffer_seconds_to_empty = m_sinkbuffer_sec_per_byte * param.nU32 * m_format.m_frameSize; status.SetDelay(sinkbuffer_seconds_to_empty); }
OMX_ERRORTYPE COpenMaxVideo::AllocOMXInputBuffers(void) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; // Obtain the information about the decoder input port. OMX_PARAM_PORTDEFINITIONTYPE port_format; OMX_INIT_STRUCTURE(port_format); port_format.nPortIndex = m_omx_input_port; OMX_GetParameter(m_omx_decoder, OMX_IndexParamPortDefinition, &port_format); #if defined(OMX_DEBUG_VERBOSE) CLog::Log(LOGDEBUG, "%s::%s - iport(%d), nBufferCountMin(%lu), nBufferSize(%lu)\n", CLASSNAME, __func__, m_omx_input_port, port_format.nBufferCountMin, port_format.nBufferSize); #endif for (size_t i = 0; i < port_format.nBufferCountMin; i++) { OMX_BUFFERHEADERTYPE *buffer = NULL; // use an external buffer that's sized according to actual demux // packet size, start at internal's buffer size, will get deleted when // we start pulling demuxer packets and using demux packet sized buffers. OMX_U8* data = new OMX_U8[port_format.nBufferSize]; omx_err = OMX_UseBuffer(m_omx_decoder, &buffer, m_omx_input_port, NULL, port_format.nBufferSize, data); if (omx_err) { CLog::Log(LOGERROR, "%s::%s - OMX_UseBuffer failed with omx_err(0x%x)\n", CLASSNAME, __func__, omx_err); return(omx_err); } m_omx_input_buffers.push_back(buffer); // don't have to lock/unlock here, we are not decoding m_omx_input_avaliable.push(buffer); } m_omx_input_eos = false; return(omx_err); }
bool OMXClock::OMXStep(int steps /* = 1 */, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) { return false; } if(lock) { Lock(); } OMX_ERRORTYPE error = OMX_ErrorNone; OMX_PARAM_U32TYPE param; OMX_INIT_STRUCTURE(param); param.nPortIndex = OMX_ALL; param.nU32 = steps; error = m_omx_clock.SetConfig(OMX_IndexConfigSingleStep, ¶m); if(error != OMX_ErrorNone) { ofLogError(__func__) << "SetConfig OMX_IndexConfigSingleStep 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; }
bool OMXClock::OMXInitialize(bool has_video, bool has_audio) { OMX_ERRORTYPE error = OMX_ErrorNone; const std::string componentName = "OMX.broadcom.clock"; m_has_video = has_video; m_has_audio = has_audio; m_pause = false; if(!m_omx_clock.Initialize(componentName, OMX_IndexParamOtherInit)) { return false; } OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); if(m_has_audio) { refClock.eClock = OMX_TIME_RefClockAudio; } else { refClock.eClock = OMX_TIME_RefClockVideo; } error = m_omx_clock.SetConfig(OMX_IndexConfigTimeActiveRefClock, &refClock); if(error != OMX_ErrorNone) { ofLogError(__func__) << " setting OMX_IndexConfigTimeCurrentAudioReference"; return false; } return true; }
bool OMXClock::HDMIClockSync(bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_CONFIG_LATENCYTARGETTYPE latencyTarget; OMX_INIT_STRUCTURE(latencyTarget); latencyTarget.nPortIndex = OMX_ALL; latencyTarget.bEnabled = OMX_TRUE; latencyTarget.nFilter = 10; latencyTarget.nTarget = 0; latencyTarget.nShift = 3; latencyTarget.nSpeedFactor = -60; latencyTarget.nInterFactor = 100; latencyTarget.nAdjCap = 100; omx_err = m_omx_clock.SetConfig(OMX_IndexConfigLatencyTarget, &latencyTarget); if(omx_err != OMX_ErrorNone) { LOG_ERROR << "OMXClock::Speed error setting OMX_IndexConfigLatencyTarget"; if(lock) UnLock(); return false; } m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
OMX_ERRORTYPE Component::enablePort(unsigned int port)//default: wait=false { lock(); OMX_ERRORTYPE error; error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, NULL); OMX_TRACE(error); unlock(); return error; #if 0 OMX_PARAM_PORTDEFINITIONTYPE portFormat; OMX_INIT_STRUCTURE(portFormat); portFormat.nPortIndex = port; OMX_ERRORTYPE error = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &portFormat); OMX_TRACE(error); #ifdef DEBUG_PORTS ofLogVerbose(__func__) << componentName << " port: " << port; #endif if(portFormat.bEnabled == OMX_FALSE) { error = OMX_SendCommand(handle, OMX_CommandPortEnable, port, NULL); OMX_TRACE(error); if(error != OMX_ErrorNone) { unlock(); return error; } } unlock(); return error; #endif }
bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume /* = false */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); CLog::Log(LOGDEBUG, "OMXClock::OMXSetSpeed(%.3f) pause_resume:%d", (float)speed / (float)DVD_PLAYSPEED_NORMAL * (1.0 + m_speedAdjust), pause_resume); if (pause_resume) { OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL; scaleType.xScale += scaleType.xScale * m_speedAdjust; OMX_ERRORTYPE omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::OMXSetSpeed error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } } if (!pause_resume) m_omx_speed = speed; m_last_media_time = 0.0f; if(lock) UnLock(); return true; }
bool OMXClock::HDMIClockSync(bool lock) { if (!GetComponent()) return false; if (lock) Lock(); OMX_ERRORTYPE omxErr = OMX_ErrorNone; OMX_CONFIG_LATENCYTARGETTYPE latencyTarget; OMX_INIT_STRUCTURE(latencyTarget); latencyTarget.nPortIndex = OMX_ALL; latencyTarget.bEnabled = OMX_TRUE; latencyTarget.nFilter = 10; latencyTarget.nTarget = 0; latencyTarget.nShift = 3; latencyTarget.nSpeedFactor = -60; latencyTarget.nInterFactor = 100; latencyTarget.nAdjCap = 100; omxErr = SetConfig(OMX_IndexConfigLatencyTarget, &latencyTarget); if (omxErr != OMX_ErrorNone) { if (lock) Unlock(); return false; } m_lastMediaTime = 0.0f; if (lock) Unlock(); return true; }
bool OMXClock::OMXSpeed(int speed, bool lock /* = true */) { if(m_omx_clock.GetComponent() == NULL) return false; if(lock) Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); // Modification to adjust the scale accordingly, depending on video playback speed range being in normal or slow motion speed range. if (speed > OMX_SLOMO_MULTIPLIER) // Normal speed range scaleType.xScale = ((speed / OMX_SLOMO_MULTIPLIER) << 16); // The number 16 here has nothing to do with OMX_SLOMO_MULTIPLIER else if (speed >= 1) // Slow Motion range scaleType.xScale = (1 << (int64_t)(12 + log2(speed))); // This avoids "switch/case" statements but only works well for multiples of 2 else scaleType.xScale = (speed << 16); // Kept like this for history. Same as "sacleType.xScale = 0;" m_play_speed = speed; omx_err = OMX_SetConfig(m_omx_clock.GetComponent(), OMX_IndexConfigTimeScale, &scaleType); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "OMXClock::Speed error setting OMX_IndexConfigTimeClockState\n"); if(lock) UnLock(); return false; } if(lock) UnLock(); return true; }
OMX_ERRORTYPE COMXCoreComponent::DisableAllPorts() { Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; if(!m_handle) { UnLock(); return OMX_ErrorUndefined; } OMX_INDEXTYPE idxTypes[] = { OMX_IndexParamAudioInit, OMX_IndexParamImageInit, OMX_IndexParamVideoInit, OMX_IndexParamOtherInit }; OMX_PORT_PARAM_TYPE ports; OMX_INIT_STRUCTURE(ports); int i; for(i=0; i < 4; i++) { omx_err = OMX_GetParameter(m_handle, idxTypes[i], &ports); if(omx_err == OMX_ErrorNone) { uint32_t j; for(j=0; j<ports.nPorts; j++) { OMX_PARAM_PORTDEFINITIONTYPE portFormat; OMX_INIT_STRUCTURE(portFormat); portFormat.nPortIndex = ports.nStartPortNumber+j; omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat); if(omx_err != OMX_ErrorNone) { if(portFormat.bEnabled == OMX_FALSE) continue; } omx_err = OMX_SendCommand(m_handle, OMX_CommandPortDisable, ports.nStartPortNumber+j, NULL); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::DisableAllPorts - Error disable port %d on component %s omx_err(0x%08x)", (int)(ports.nStartPortNumber) + j, m_componentName.c_str(), (int)omx_err); } omx_err = WaitForCommand(OMX_CommandPortDisable, ports.nStartPortNumber+j); if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState) { UnLock(); return omx_err; } } } } UnLock(); return OMX_ErrorNone; }
static void setup_tunnel(rpi_pixmap_decoder_t *rpd) { int dst_width, dst_height; OMX_PARAM_PORTDEFINITIONTYPE portdef; if(rpd->rpd_tunnel != NULL) return; OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = rpd->rpd_decoder->oc_outport; omxchk(OMX_GetParameter(rpd->rpd_decoder->oc_handle, OMX_IndexParamPortDefinition, &portdef)); pixmap_compute_rescale_dim(rpd->rpd_im, portdef.format.image.nFrameWidth, portdef.format.image.nFrameHeight, &dst_width, &dst_height); portdef.nPortIndex = rpd->rpd_resizer->oc_inport; omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); rpd->rpd_tunnel = omx_tunnel_create(rpd->rpd_decoder, rpd->rpd_decoder->oc_outport, rpd->rpd_resizer, rpd->rpd_resizer->oc_inport, "decoder -> resizer"); OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = rpd->rpd_resizer->oc_outport; omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); int stride = (dst_width * 4 + PIXMAP_ROW_ALIGN - 1) & ~(PIXMAP_ROW_ALIGN - 1); portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused; portdef.format.image.eColorFormat = OMX_COLOR_Format32bitABGR8888; portdef.format.image.nFrameWidth = dst_width; portdef.format.image.nFrameHeight = dst_height; portdef.format.image.nStride = stride; portdef.format.image.nSliceHeight = 0; portdef.format.image.bFlagErrorConcealment = OMX_FALSE; omxchk(OMX_SetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omxchk(OMX_GetParameter(rpd->rpd_resizer->oc_handle, OMX_IndexParamPortDefinition, &portdef)); omx_set_state(rpd->rpd_resizer, OMX_StateExecuting); omx_port_enable(rpd->rpd_resizer, rpd->rpd_resizer->oc_outport); pixmap_t *pm = rpd->rpd_pm = calloc(1, sizeof(pixmap_t)); pm->pm_refcount = 1; pm->pm_width = portdef.format.image.nFrameWidth; pm->pm_height = portdef.format.image.nFrameHeight; pm->pm_linesize = portdef.format.image.nStride; pm->pm_type = PIXMAP_BGR32; pm->pm_data = mymemalign(portdef.nBufferAlignment, portdef.nBufferSize); pm->pm_aspect = (float)pm->pm_width / (float)pm->pm_height; omxchk(OMX_UseBuffer(rpd->rpd_resizer->oc_handle, &rpd->rpd_buf, rpd->rpd_resizer->oc_outport, NULL, portdef.nBufferSize, pm->pm_data)); omx_wait_command(rpd->rpd_resizer); omxchk(OMX_FillThisBuffer(rpd->rpd_resizer->oc_handle, rpd->rpd_buf)); }
OMX_ERRORTYPE COMXCoreTunel::Establish(bool portSettingsChanged) { if(!m_DllOMXOpen) return OMX_ErrorUndefined; Lock(); OMX_ERRORTYPE omx_err = OMX_ErrorNone; OMX_PARAM_U32TYPE param; OMX_INIT_STRUCTURE(param); if(!m_src_component || !m_dst_component) { UnLock(); return OMX_ErrorUndefined; } if(m_src_component->GetState() == OMX_StateLoaded) { omx_err = m_src_component->SetStateForComponent(OMX_StateIdle); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error setting state to idle %s omx_err(0x%08x)", m_src_component->GetName().c_str(), (int)omx_err); UnLock(); return omx_err; } } if(portSettingsChanged) { omx_err = m_src_component->WaitForEvent(OMX_EventPortSettingsChanged); if(omx_err != OMX_ErrorNone) { UnLock(); return omx_err; } } if(m_src_component->GetComponent()) { omx_err = m_src_component->DisablePort(m_src_port, false); if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error disable port %d on component %s omx_err(0x%08x)", m_src_port, m_src_component->GetName().c_str(), (int)omx_err); } } if(m_dst_component->GetComponent()) { omx_err = m_dst_component->DisablePort(m_dst_port, false); if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error disable port %d on component %s omx_err(0x%08x)", m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err); } } if(m_src_component->GetComponent() && m_dst_component->GetComponent()) { omx_err = m_DllOMX->OMX_SetupTunnel(m_src_component->GetComponent(), m_src_port, m_dst_component->GetComponent(), m_dst_port); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - could not setup tunnel src %s port %d dst %s port %d omx_err(0x%08x)\n", m_src_component->GetName().c_str(), m_src_port, m_dst_component->GetName().c_str(), m_dst_port, (int)omx_err); UnLock(); return omx_err; } } else { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - could not setup tunnel\n"); UnLock(); return OMX_ErrorUndefined; } if(m_src_component->GetComponent()) { omx_err = m_src_component->EnablePort(m_src_port, false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error enable port %d on component %s omx_err(0x%08x)", m_src_port, m_src_component->GetName().c_str(), (int)omx_err); UnLock(); return omx_err; } } if(m_dst_component->GetComponent()) { omx_err = m_dst_component->EnablePort(m_dst_port, false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error enable port %d on component %s omx_err(0x%08x)", m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err); UnLock(); return omx_err; } } if(m_dst_component->GetComponent()) { if(m_dst_component->GetState() == OMX_StateLoaded) { omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port); if(omx_err != OMX_ErrorNone) { UnLock(); return omx_err; } omx_err = m_dst_component->SetStateForComponent(OMX_StateIdle); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Establish - Error setting state to idle %s omx_err(0x%08x)", m_src_component->GetName().c_str(), (int)omx_err); UnLock(); return omx_err; } } else { omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port); if(omx_err != OMX_ErrorNone) { UnLock(); return omx_err; } } } if(m_src_component->GetComponent()) { omx_err = m_src_component->WaitForCommand(OMX_CommandPortEnable, m_src_port); if(omx_err != OMX_ErrorNone) { UnLock(); return omx_err; } } m_portSettingsChanged = portSettingsChanged; UnLock(); return OMX_ErrorNone; }
OMX_ERRORTYPE COMXCoreComponent::AllocOutputBuffers(bool use_buffers /* = false */) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; if(!m_handle) return OMX_ErrorUndefined; m_omx_output_use_buffers = use_buffers; OMX_PARAM_PORTDEFINITIONTYPE portFormat; OMX_INIT_STRUCTURE(portFormat); portFormat.nPortIndex = m_output_port; omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat); if(omx_err != OMX_ErrorNone) return omx_err; if(GetState() != OMX_StateIdle) { if(GetState() != OMX_StateLoaded) SetStateForComponent(OMX_StateLoaded); SetStateForComponent(OMX_StateIdle); } omx_err = EnablePort(m_output_port, false); if(omx_err != OMX_ErrorNone) return omx_err; m_output_alignment = portFormat.nBufferAlignment; m_output_buffer_count = portFormat.nBufferCountActual; m_output_buffer_size = portFormat.nBufferSize; CLog::Log(LOGDEBUG, "COMXCoreComponent::AllocOutputBuffers component(%s) - port(%d), nBufferCountMin(%lu), nBufferCountActual(%lu), nBufferSize(%lu) nBufferAlignmen(%lu)\n", m_componentName.c_str(), m_output_port, portFormat.nBufferCountMin, portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment); for (size_t i = 0; i < portFormat.nBufferCountActual; i++) { OMX_BUFFERHEADERTYPE *buffer = NULL; OMX_U8* data = NULL; if(m_omx_output_use_buffers) { data = (OMX_U8*)_aligned_malloc(portFormat.nBufferSize, m_output_alignment); omx_err = OMX_UseBuffer(m_handle, &buffer, m_output_port, NULL, portFormat.nBufferSize, data); } else { omx_err = OMX_AllocateBuffer(m_handle, &buffer, m_output_port, NULL, portFormat.nBufferSize); } if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::AllocOutputBuffers component(%s) - OMX_UseBuffer failed with omx_err(0x%x)\n", m_componentName.c_str(), omx_err); if(m_omx_output_use_buffers && data) _aligned_free(data); return omx_err; } buffer->nOutputPortIndex = m_output_port; buffer->nFilledLen = 0; buffer->nOffset = 0; buffer->pAppPrivate = (void*)i; m_omx_output_buffers.push_back(buffer); m_omx_output_available.push(buffer); } omx_err = WaitForCommand(OMX_CommandPortEnable, m_output_port); m_flush_output = false; return omx_err; }
bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEXTYPE index) { OMX_ERRORTYPE omx_err; if(!m_DllOMX->Load()) return false; m_DllOMXOpen = true; m_componentName = component_name; m_callbacks.EventHandler = &COMXCoreComponent::DecoderEventHandlerCallback; m_callbacks.EmptyBufferDone = &COMXCoreComponent::DecoderEmptyBufferDoneCallback; m_callbacks.FillBufferDone = &COMXCoreComponent::DecoderFillBufferDoneCallback; // Get video component handle setting up callbacks, component is in loaded state on return. omx_err = m_DllOMX->OMX_GetHandle(&m_handle, (char*)component_name.c_str(), this, &m_callbacks); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Initialize - could not get component handle for %s omx_err(0x%08x)\n", component_name.c_str(), (int)omx_err); Deinitialize(); return false; } OMX_PORT_PARAM_TYPE port_param; OMX_INIT_STRUCTURE(port_param); omx_err = OMX_GetParameter(m_handle, index, &port_param); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Initialize - could not get port_param for component %s omx_err(0x%08x)\n", component_name.c_str(), (int)omx_err); } omx_err = DisableAllPorts(); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::Initialize - error disable ports on component %s omx_err(0x%08x)\n", component_name.c_str(), (int)omx_err); } m_input_port = port_param.nStartPortNumber; m_output_port = m_input_port + 1; if(m_componentName == "OMX.broadcom.audio_mixer") { m_input_port = port_param.nStartPortNumber + 1; m_output_port = port_param.nStartPortNumber; } if (m_output_port > port_param.nStartPortNumber+port_param.nPorts-1) m_output_port = port_param.nStartPortNumber+port_param.nPorts-1; CLog::Log(LOGDEBUG, "COMXCoreComponent::Initialize %s input port %d output port %d\n", m_componentName.c_str(), m_input_port, m_output_port); m_exit = false; m_flush_input = false; m_flush_output = false; return true; }
static int Open(vlc_object_t *p_this) { vout_display_t *vd = (vout_display_t *)p_this; vout_display_t *p_dec = vd; char ppsz_components[MAX_COMPONENTS_LIST_SIZE][OMX_MAX_STRINGNAME_SIZE]; picture_t** pictures = NULL; OMX_PARAM_PORTDEFINITIONTYPE *def; static OMX_CALLBACKTYPE callbacks = { OmxEventHandler, OmxEmptyBufferDone, OmxFillBufferDone }; if (InitOmxCore(p_this) != VLC_SUCCESS) return VLC_EGENERIC; int components = CreateComponentsList(p_this, "iv_renderer", ppsz_components); if (components <= 0) { DeinitOmxCore(); return VLC_EGENERIC; } /* Allocate structure */ vout_display_sys_t *p_sys = (struct vout_display_sys_t*) calloc(1, sizeof(*p_sys)); if (!p_sys) { DeinitOmxCore(); return VLC_ENOMEM; } vd->sys = p_sys; strcpy(p_sys->psz_component, ppsz_components[0]); /* Load component */ OMX_ERRORTYPE omx_error = pf_get_handle(&p_sys->omx_handle, p_sys->psz_component, vd, &callbacks); CHECK_ERROR(omx_error, "OMX_GetHandle(%s) failed (%x: %s)", p_sys->psz_component, omx_error, ErrorToString(omx_error)); InitOmxEventQueue(&p_sys->event_queue); OMX_FIFO_INIT(&p_sys->port.fifo, pOutputPortPrivate); p_sys->port.b_direct = false; p_sys->port.b_flushed = true; OMX_PORT_PARAM_TYPE param; OMX_INIT_STRUCTURE(param); omx_error = OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamVideoInit, ¶m); CHECK_ERROR(omx_error, "OMX_GetParameter(OMX_IndexParamVideoInit) failed (%x: %s)", omx_error, ErrorToString(omx_error)); p_sys->port.i_port_index = param.nStartPortNumber; p_sys->port.b_valid = true; p_sys->port.omx_handle = p_sys->omx_handle; def = &p_sys->port.definition; OMX_INIT_STRUCTURE(*def); def->nPortIndex = p_sys->port.i_port_index; omx_error = OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, def); CHECK_ERROR(omx_error, "OMX_GetParameter(OMX_IndexParamPortDefinition) failed (%x: %s)", omx_error, ErrorToString(omx_error)); #define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1)) def->format.video.nFrameWidth = vd->fmt.i_width; def->format.video.nFrameHeight = vd->fmt.i_height; def->format.video.nStride = 0; def->format.video.nSliceHeight = 0; p_sys->port.definition.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; if (!strcmp(p_sys->psz_component, "OMX.broadcom.video_render")) { def->format.video.nSliceHeight = ALIGN(def->format.video.nFrameHeight, 16); } omx_error = OMX_SetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, &p_sys->port.definition); CHECK_ERROR(omx_error, "OMX_SetParameter(OMX_IndexParamPortDefinition) failed (%x: %s)", omx_error, ErrorToString(omx_error)); OMX_GetParameter(p_sys->omx_handle, OMX_IndexParamPortDefinition, &p_sys->port.definition); if (def->format.video.nStride < (int) def->format.video.nFrameWidth) def->format.video.nStride = def->format.video.nFrameWidth; if (def->format.video.nSliceHeight < def->format.video.nFrameHeight) def->format.video.nSliceHeight = def->format.video.nFrameHeight; p_sys->port.pp_buffers = malloc(p_sys->port.definition.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE*)); p_sys->port.i_buffers = p_sys->port.definition.nBufferCountActual; omx_error = OMX_SendCommand(p_sys->omx_handle, OMX_CommandStateSet, OMX_StateIdle, 0); CHECK_ERROR(omx_error, "OMX_CommandStateSet Idle failed (%x: %s)", omx_error, ErrorToString(omx_error)); unsigned int i; for (i = 0; i < p_sys->port.i_buffers; i++) { omx_error = OMX_AllocateBuffer(p_sys->omx_handle, &p_sys->port.pp_buffers[i], p_sys->port.i_port_index, 0, p_sys->port.definition.nBufferSize); if (omx_error != OMX_ErrorNone) break; OMX_FIFO_PUT(&p_sys->port.fifo, p_sys->port.pp_buffers[i]); } if (omx_error != OMX_ErrorNone) { p_sys->port.i_buffers = i; for (i = 0; i < p_sys->port.i_buffers; i++) OMX_FreeBuffer(p_sys->omx_handle, p_sys->port.i_port_index, p_sys->port.pp_buffers[i]); msg_Err(vd, "OMX_AllocateBuffer failed (%x: %s)", omx_error, ErrorToString(omx_error)); goto error; } omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0); CHECK_ERROR(omx_error, "Wait for Idle failed (%x: %s)", omx_error, ErrorToString(omx_error)); omx_error = OMX_SendCommand(p_sys->omx_handle, OMX_CommandStateSet, OMX_StateExecuting, 0); CHECK_ERROR(omx_error, "OMX_CommandStateSet Executing failed (%x: %s)", omx_error, ErrorToString(omx_error)); omx_error = WaitForSpecificOmxEvent(&p_sys->event_queue, OMX_EventCmdComplete, 0, 0, 0); CHECK_ERROR(omx_error, "Wait for Executing failed (%x: %s)", omx_error, ErrorToString(omx_error)); if (!strcmp(p_sys->psz_component, "OMX.broadcom.video_render")) { OMX_CONFIG_DISPLAYREGIONTYPE config_display; OMX_INIT_STRUCTURE(config_display); config_display.nPortIndex = p_sys->port.i_port_index; config_display.set = OMX_DISPLAY_SET_SRC_RECT; config_display.src_rect.width = vd->cfg->display.width; config_display.src_rect.height = vd->cfg->display.height; OMX_SetConfig(p_sys->omx_handle, OMX_IndexConfigDisplayRegion, &config_display); config_display.set = OMX_DISPLAY_SET_FULLSCREEN; config_display.fullscreen = OMX_TRUE; OMX_SetConfig(p_sys->omx_handle, OMX_IndexConfigDisplayRegion, &config_display); UpdateDisplaySize(vd, vd->cfg); } /* Setup chroma */ video_format_t fmt = vd->fmt; fmt.i_chroma = VLC_CODEC_I420; video_format_FixRgb(&fmt); /* Setup vout_display */ vd->fmt = fmt; vd->pool = Pool; vd->display = Display; vd->control = Control; vd->prepare = NULL; vd->manage = NULL; /* Create the associated picture */ pictures = calloc(p_sys->port.i_buffers, sizeof(*pictures)); if (!pictures) goto error; for (unsigned int i = 0; i < p_sys->port.i_buffers; i++) { picture_sys_t *picsys = malloc(sizeof(*picsys)); if (unlikely(picsys == NULL)) goto error; picsys->sys = p_sys; picture_resource_t resource = { .p_sys = picsys }; picture_t *picture = picture_NewFromResource(&fmt, &resource); if (unlikely(picture == NULL)) { free(picsys); goto error; } pictures[i] = picture; } /* Wrap it into a picture pool */ picture_pool_configuration_t pool_cfg; memset(&pool_cfg, 0, sizeof(pool_cfg)); pool_cfg.picture_count = p_sys->port.i_buffers; pool_cfg.picture = pictures; pool_cfg.lock = LockSurface; pool_cfg.unlock = UnlockSurface; p_sys->pool = picture_pool_NewExtended(&pool_cfg); if (!p_sys->pool) { for (unsigned int i = 0; i < p_sys->port.i_buffers; i++) picture_Release(pictures[i]); goto error; } /* Fix initial state */ vout_display_SendEventFullscreen(vd, true); free(pictures); return VLC_SUCCESS; error: free(pictures); Close(p_this); return VLC_EGENERIC; }
bool COMXVideo::Open(COMXStreamInfo &hints, OMXClock *clock, const CRect &DestRect, float display_aspect, int deinterlace, bool hdmi_clock_sync, float fifo_size) { OMX_ERRORTYPE omx_err = OMX_ErrorNone; std::string decoder_name; m_settings_changed = false; m_src_rect.SetRect(0, 0, 0, 0); m_dst_rect = DestRect; m_video_codec_name = ""; m_codingType = OMX_VIDEO_CodingUnused; m_decoded_width = hints.width; m_decoded_height = hints.height; m_deinterlace_request = deinterlace; m_hdmi_clock_sync = hdmi_clock_sync; if(!m_decoded_width || !m_decoded_height) return false; if(hints.extrasize > 0 && hints.extradata != NULL) { m_extrasize = hints.extrasize; m_extradata = (uint8_t *)malloc(m_extrasize); memcpy(m_extradata, hints.extradata, hints.extrasize); } switch (hints.codec) { case CODEC_ID_H264: { switch(hints.profile) { case FF_PROFILE_H264_BASELINE: // (role name) video_decoder.avc // H.264 Baseline profile decoder_name = OMX_H264BASE_DECODER; m_codingType = OMX_VIDEO_CodingAVC; m_video_codec_name = "omx-h264"; break; case FF_PROFILE_H264_MAIN: // (role name) video_decoder.avc // H.264 Main profile decoder_name = OMX_H264MAIN_DECODER; m_codingType = OMX_VIDEO_CodingAVC; m_video_codec_name = "omx-h264"; break; case FF_PROFILE_H264_HIGH: // (role name) video_decoder.avc // H.264 Main profile decoder_name = OMX_H264HIGH_DECODER; m_codingType = OMX_VIDEO_CodingAVC; m_video_codec_name = "omx-h264"; break; case FF_PROFILE_UNKNOWN: decoder_name = OMX_H264HIGH_DECODER; m_codingType = OMX_VIDEO_CodingAVC; m_video_codec_name = "omx-h264"; break; default: decoder_name = OMX_H264HIGH_DECODER; m_codingType = OMX_VIDEO_CodingAVC; m_video_codec_name = "omx-h264"; break; } } break; case CODEC_ID_MPEG4: // (role name) video_decoder.mpeg4 // MPEG-4, DivX 4/5 and Xvid compatible decoder_name = OMX_MPEG4_DECODER; m_codingType = OMX_VIDEO_CodingMPEG4; m_video_codec_name = "omx-mpeg4"; break; case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: // (role name) video_decoder.mpeg2 // MPEG-2 decoder_name = OMX_MPEG2V_DECODER; m_codingType = OMX_VIDEO_CodingMPEG2; m_video_codec_name = "omx-mpeg2"; break; case CODEC_ID_H263: // (role name) video_decoder.mpeg4 // MPEG-4, DivX 4/5 and Xvid compatible decoder_name = OMX_MPEG4_DECODER; m_codingType = OMX_VIDEO_CodingMPEG4; m_video_codec_name = "omx-h263"; break; case CODEC_ID_VP6: case CODEC_ID_VP6F: case CODEC_ID_VP6A: // (role name) video_decoder.vp6 // VP6 decoder_name = OMX_VP6_DECODER; m_codingType = OMX_VIDEO_CodingVP6; m_video_codec_name = "omx-vp6"; break; case CODEC_ID_VP8: // (role name) video_decoder.vp8 // VP8 decoder_name = OMX_VP8_DECODER; m_codingType = OMX_VIDEO_CodingVP8; m_video_codec_name = "omx-vp8"; break; case CODEC_ID_THEORA: // (role name) video_decoder.theora // theora decoder_name = OMX_THEORA_DECODER; m_codingType = OMX_VIDEO_CodingTheora; m_video_codec_name = "omx-theora"; break; case CODEC_ID_MJPEG: case CODEC_ID_MJPEGB: // (role name) video_decoder.mjpg // mjpg decoder_name = OMX_MJPEG_DECODER; m_codingType = OMX_VIDEO_CodingMJPEG; m_video_codec_name = "omx-mjpeg"; break; case CODEC_ID_VC1: case CODEC_ID_WMV3: // (role name) video_decoder.vc1 // VC-1, WMV9 decoder_name = OMX_VC1_DECODER; m_codingType = OMX_VIDEO_CodingWMV; m_video_codec_name = "omx-vc1"; break; default: printf("Vcodec id unknown: %x\n", hints.codec); return false; break; } std::string componentName = ""; componentName = decoder_name; if(!m_omx_decoder.Initialize(componentName, OMX_IndexParamVideoInit)) return false; componentName = "OMX.broadcom.text_scheduler"; if(!m_omx_text.Initialize(componentName, OMX_IndexParamOtherInit)) return false; if(clock == NULL) return false; m_av_clock = clock; m_omx_clock = m_av_clock->GetOMXClock(); if(m_omx_clock->GetComponent() == NULL) { m_av_clock = NULL; m_omx_clock = NULL; return false; } omx_err = m_omx_decoder.SetStateForComponent(OMX_StateIdle); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_decoder.SetStateForComponent\n"); return false; } OMX_VIDEO_PARAM_PORTFORMATTYPE formatType; OMX_INIT_STRUCTURE(formatType); formatType.nPortIndex = m_omx_decoder.GetInputPort(); formatType.eCompressionFormat = m_codingType; if (hints.fpsscale > 0 && hints.fpsrate > 0) { formatType.xFramerate = (long long)(1<<16)*hints.fpsrate / hints.fpsscale; } else { formatType.xFramerate = 25 * (1<<16); } omx_err = m_omx_decoder.SetParameter(OMX_IndexParamVideoPortFormat, &formatType); if(omx_err != OMX_ErrorNone) return false; OMX_PARAM_PORTDEFINITIONTYPE portParam; OMX_INIT_STRUCTURE(portParam); portParam.nPortIndex = m_omx_decoder.GetInputPort(); omx_err = m_omx_decoder.GetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } portParam.nPortIndex = m_omx_decoder.GetInputPort(); portParam.nBufferCountActual = fifo_size ? fifo_size * 1024 * 1024 / portParam.nBufferSize : 80; portParam.format.video.nFrameWidth = m_decoded_width; portParam.format.video.nFrameHeight = m_decoded_height; omx_err = m_omx_decoder.SetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } // request portsettingschanged on aspect ratio change OMX_CONFIG_REQUESTCALLBACKTYPE notifications; OMX_INIT_STRUCTURE(notifications); notifications.nPortIndex = m_omx_decoder.GetOutputPort(); notifications.nIndex = OMX_IndexParamBrcmPixelAspectRatio; notifications.bEnable = OMX_TRUE; omx_err = m_omx_decoder.SetParameter((OMX_INDEXTYPE)OMX_IndexConfigRequestCallback, ¬ifications); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open OMX_IndexConfigRequestCallback error (0%08x)\n", omx_err); return false; } OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE concanParam; OMX_INIT_STRUCTURE(concanParam); concanParam.bStartWithValidFrame = OMX_FALSE; omx_err = m_omx_decoder.SetParameter(OMX_IndexParamBrcmVideoDecodeErrorConcealment, &concanParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamBrcmVideoDecodeErrorConcealment omx_err(0x%08x)\n", omx_err); return false; } if (m_deinterlace_request != -1) { // the deinterlace component requires 3 additional video buffers in addition to the DPB (this is normally 2). OMX_PARAM_U32TYPE extra_buffers; OMX_INIT_STRUCTURE(extra_buffers); extra_buffers.nU32 = 3; omx_err = m_omx_decoder.SetParameter(OMX_IndexParamBrcmExtraBuffers, &extra_buffers); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamBrcmExtraBuffers omx_err(0x%08x)\n", omx_err); return false; } } // broadcom omx entension: // When enabled, the timestamp fifo mode will change the way incoming timestamps are associated with output images. // In this mode the incoming timestamps get used without re-ordering on output images. if(hints.ptsinvalid) { OMX_CONFIG_BOOLEANTYPE timeStampMode; OMX_INIT_STRUCTURE(timeStampMode); timeStampMode.bEnabled = OMX_TRUE; omx_err = m_omx_decoder.SetParameter((OMX_INDEXTYPE)OMX_IndexParamBrcmVideoTimestampFifo, &timeStampMode); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open OMX_IndexParamBrcmVideoTimestampFifo error (0%08x)\n", omx_err); return false; } } if(NaluFormatStartCodes(hints.codec, m_extradata, m_extrasize)) { OMX_NALSTREAMFORMATTYPE nalStreamFormat; OMX_INIT_STRUCTURE(nalStreamFormat); nalStreamFormat.nPortIndex = m_omx_decoder.GetInputPort(); nalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodes; omx_err = m_omx_decoder.SetParameter((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, &nalStreamFormat); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open OMX_IndexParamNalStreamFormatSelect error (0%08x)\n", omx_err); return false; } } // Alloc buffers for the omx intput port. omx_err = m_omx_decoder.AllocInputBuffers(); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open AllocOMXInputBuffers error (0%08x)\n", omx_err); return false; } omx_err = m_omx_decoder.SetStateForComponent(OMX_StateExecuting); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error m_omx_decoder.SetStateForComponent\n"); return false; } if(!SendDecoderConfig()) return false; m_omx_tunnel_text.Initialize(m_omx_clock, m_omx_clock->GetInputPort() + 2, &m_omx_text, m_omx_text.GetInputPort() + 2); OMX_INIT_STRUCTURE(portParam); portParam.nPortIndex = m_omx_text.GetInputPort(); omx_err = m_omx_text.GetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } portParam.nBufferCountActual = 100; portParam.nBufferSize = MAX_TEXT_LENGTH; omx_err = m_omx_text.SetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } omx_err = m_omx_text.AllocInputBuffers(); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open AllocOMXInputBuffers\n"); return false; } OMX_INIT_STRUCTURE(portParam); portParam.nPortIndex = m_omx_text.GetOutputPort(); omx_err = m_omx_text.GetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } portParam.eDir = OMX_DirOutput; portParam.format.other.eFormat = OMX_OTHER_FormatText; portParam.format.other.eFormat = OMX_OTHER_FormatText; portParam.nBufferCountActual = 1; portParam.nBufferSize = MAX_TEXT_LENGTH; omx_err = m_omx_text.SetParameter(OMX_IndexParamPortDefinition, &portParam); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexParamPortDefinition omx_err(0x%08x)\n", omx_err); return false; } omx_err = m_omx_text.AllocOutputBuffers(); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open AllocOutputBuffers\n"); return false; } omx_err = m_omx_text.SetStateForComponent(OMX_StateExecuting); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error m_omx_text.SetStateForComponent\n"); return false; } omx_err = m_omx_tunnel_text.Establish(false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_tunnel_text.Establish\n"); return false; } OMX_BUFFERHEADERTYPE *omx_buffer = m_omx_text.GetOutputBuffer(); if(!omx_buffer) return false; omx_err = m_omx_text.FillThisBuffer(omx_buffer); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open FillThisBuffer\n"); return false; } omx_buffer = NULL; m_is_open = true; m_drop_state = false; m_setStartTime = true; m_setStartTimeText = true; CLog::Log(LOGDEBUG, "%s::%s - decoder_component(0x%p), input_port(0x%x), output_port(0x%x) deinterlace %d hdmiclocksync %d\n", CLASSNAME, __func__, m_omx_decoder.GetComponent(), m_omx_decoder.GetInputPort(), m_omx_decoder.GetOutputPort(), deinterlace, m_hdmi_clock_sync); m_first_text = true; // start from assuming all recent frames had valid pts m_history_valid_pts = ~0; float fAspect = (float)hints.aspect / (float)m_decoded_width * (float)m_decoded_height; m_pixel_aspect = hints.aspect ? fAspect/display_aspect : 0.0f; return true; }
bool COMXVideo::PortSettingsChanged() { OMX_ERRORTYPE omx_err = OMX_ErrorNone; std::string componentName = ""; if (m_settings_changed) { m_omx_decoder.DisablePort(m_omx_decoder.GetOutputPort(), true); } 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)", CLASSNAME, __func__, omx_err); } OMX_CONFIG_POINTTYPE pixel_aspect; OMX_INIT_STRUCTURE(pixel_aspect); pixel_aspect.nPortIndex = m_omx_decoder.GetOutputPort(); omx_err = m_omx_decoder.GetParameter(OMX_IndexParamBrcmPixelAspectRatio, &pixel_aspect); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "%s::%s - error m_omx_decoder.GetParameter(OMX_IndexParamBrcmPixelAspectRatio) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); } if (pixel_aspect.nX && pixel_aspect.nY) m_pixel_aspect = (float)pixel_aspect.nX / (float)pixel_aspect.nY; if (m_settings_changed) { SetVideoRect(m_src_rect, m_dst_rect); m_omx_decoder.EnablePort(m_omx_decoder.GetOutputPort(), true); return 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(m_deinterlace_request == 1) m_deinterlace = true; else if(m_deinterlace_request == -1) m_deinterlace = false; else m_deinterlace = interlace.eMode != OMX_InterlaceProgressive; printf("V:PortSettingsChanged: %dx%d@%.2f %s\n", port_image.format.video.nFrameWidth, port_image.format.video.nFrameHeight, port_image.format.video.xFramerate / (float)(1<<16), m_deinterlace ? "interlaced":"progressive"); componentName = "OMX.broadcom.video_render"; if(!m_omx_render.Initialize(componentName, OMX_IndexParamVideoInit)) return false; componentName = "OMX.broadcom.video_scheduler"; if(!m_omx_sched.Initialize(componentName, OMX_IndexParamVideoInit)) return false; if(m_deinterlace) { componentName = "OMX.broadcom.image_fx"; if(!m_omx_image_fx.Initialize(componentName, OMX_IndexParamImageInit)) return false; } m_settings_changed = true; SetVideoRect(m_src_rect, m_dst_rect); if(m_hdmi_clock_sync) { OMX_CONFIG_LATENCYTARGETTYPE latencyTarget; OMX_INIT_STRUCTURE(latencyTarget); latencyTarget.nPortIndex = m_omx_render.GetInputPort(); latencyTarget.bEnabled = OMX_TRUE; latencyTarget.nFilter = 2; latencyTarget.nTarget = 4000; latencyTarget.nShift = 3; latencyTarget.nSpeedFactor = -135; latencyTarget.nInterFactor = 500; latencyTarget.nAdjCap = 20; omx_err = m_omx_render.SetConfig(OMX_IndexConfigLatencyTarget, &latencyTarget); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open OMX_IndexConfigLatencyTarget error (0%08x)\n", omx_err); return false; } } if(m_deinterlace) { OMX_CONFIG_IMAGEFILTERPARAMSTYPE image_filter; OMX_INIT_STRUCTURE(image_filter); image_filter.nPortIndex = m_omx_image_fx.GetOutputPort(); image_filter.nNumParams = 1; image_filter.nParams[0] = 3; image_filter.eImageFilter = OMX_ImageFilterDeInterlaceAdvanced; omx_err = m_omx_image_fx.SetConfig(OMX_IndexConfigCommonImageFilterParameters, &image_filter); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error OMX_IndexConfigCommonImageFilterParameters omx_err(0x%08x)\n", omx_err); return false; } } if(m_deinterlace) { m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_image_fx, m_omx_image_fx.GetInputPort()); m_omx_tunnel_image_fx.Initialize(&m_omx_image_fx, m_omx_image_fx.GetOutputPort(), &m_omx_sched, m_omx_sched.GetInputPort()); } else { m_omx_tunnel_decoder.Initialize(&m_omx_decoder, m_omx_decoder.GetOutputPort(), &m_omx_sched, m_omx_sched.GetInputPort()); } m_omx_tunnel_sched.Initialize(&m_omx_sched, m_omx_sched.GetOutputPort(), &m_omx_render, m_omx_render.GetInputPort()); m_omx_tunnel_clock.Initialize(m_omx_clock, m_omx_clock->GetInputPort() + 1, &m_omx_sched, m_omx_sched.GetOutputPort() + 1); omx_err = m_omx_tunnel_decoder.Establish(false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_tunnel_decoder.Establish\n"); return false; } if(m_deinterlace) { omx_err = m_omx_image_fx.SetStateForComponent(OMX_StateExecuting); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error m_omx_image_fx.SetStateForComponent\n"); return false; } omx_err = m_omx_tunnel_image_fx.Establish(false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_tunnel_image_fx.Establish\n"); return false; } } omx_err = m_omx_sched.SetStateForComponent(OMX_StateExecuting); if (omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error m_omx_sched.SetStateForComponent\n"); return false; } omx_err = m_omx_tunnel_sched.Establish(false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_tunnel_sched.Establish\n"); return false; } omx_err = m_omx_render.SetStateForComponent(OMX_StateExecuting); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open error m_omx_render.SetStateForComponent\n"); return false; } omx_err = m_omx_tunnel_clock.Establish(false); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXVideo::Open m_omx_tunnel_clock.Establish\n"); return false; } return true; }
bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume /* = false */) { ofLog(OF_LOG_VERBOSE, "OMXClock::OMXSetSpeed(%d)", speed); if(m_omx_clock.GetComponent() == NULL) { return false; } if(lock) { Lock(); } OMX_ERRORTYPE error = OMX_ErrorNone; OMX_TIME_CONFIG_SCALETYPE scaleType; OMX_INIT_STRUCTURE(scaleType); OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock; OMX_INIT_STRUCTURE(refClock); if(m_has_audio && !TRICKPLAY(speed)) { refClock.eClock = OMX_TIME_RefClockAudio; } else { refClock.eClock = OMX_TIME_RefClockVideo; } error = m_omx_clock.SetConfig(OMX_IndexConfigTimeActiveRefClock, &refClock); if(error != OMX_ErrorNone) { ofLogError(__func__) << "SetConfig OMX_IndexConfigTimeActiveRefClock FAIL: " << COMXCore::getOMXError(error); return false; } if (TRICKPLAY(speed)) { OMXStep(-1, false); } else { OMXStep(0, false); } if (0 && TRICKPLAY(speed)) { scaleType.xScale = 0; } else { scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL; } error = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType); if(error != OMX_ErrorNone) { ofLogError(__func__) << "SetConfig OMX_IndexConfigTimeScale FAIL: " << COMXCore::getOMXError(error); if(lock) { UnLock(); } return false; } if (!pause_resume) { m_omx_speed = speed; } if(lock) { UnLock(); } return true; }