Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
// 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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, &param);

  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);
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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, &param);
	if(error != OMX_ErrorNone)
	{
		ofLogError(__func__) << "SetConfig OMX_IndexConfigSingleStep FAIL: " << COMXCore::getOMXError(error);
		if(lock)
		{
			UnLock();
		}
		return false;
	}

	if(lock)
	{
		UnLock();
	}

	return true;
}
Esempio n. 15
0
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, &timestamp);
	if (omxErr != OMX_ErrorNone)
	{
		if (lock)
			Unlock();

		return false;
	}

	m_lastMediaTime = 0.0f;

	if (lock)
		Unlock();

	return true;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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));
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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, &param);
    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;
}
Esempio n. 28
0
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, &notifications);
  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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
0
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;
}