1819 lines
55 KiB
C++
1819 lines
55 KiB
C++
/*
|
|
* Copyright (C) 2010-2013 Team XBMCn
|
|
* http://xbmc.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with XBMC; see the file COPYING. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
|
|
#include "config.h"
|
|
#elif defined(TARGET_WINDOWS)
|
|
#include "system.h"
|
|
#endif
|
|
|
|
#include <math.h>
|
|
#include <sys/time.h>
|
|
|
|
#if defined(HAVE_OMXLIB)
|
|
#include "OMXCore.h"
|
|
#include "utils/log.h"
|
|
|
|
#include "OMXClock.h"
|
|
|
|
#ifdef TARGET_LINUX
|
|
#include "XMemUtils.h"
|
|
#endif
|
|
|
|
//#define OMX_DEBUG_EVENTS
|
|
//#define OMX_DEBUG_EVENTHANDLER
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
#define CLASSNAME "COMXCoreComponent"
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static void add_timespecs(struct timespec &time, long millisecs)
|
|
{
|
|
long long nsec = time.tv_nsec + (long long)millisecs * 1000000;
|
|
while (nsec > 1000000000)
|
|
{
|
|
time.tv_sec += 1;
|
|
nsec -= 1000000000;
|
|
}
|
|
time.tv_nsec = nsec;
|
|
}
|
|
|
|
|
|
COMXCoreTunel::COMXCoreTunel()
|
|
{
|
|
m_src_component = NULL;
|
|
m_dst_component = NULL;
|
|
m_src_port = 0;
|
|
m_dst_port = 0;
|
|
m_tunnel_set = false;
|
|
m_DllOMX = DllOMX::GetDllOMX();
|
|
}
|
|
|
|
COMXCoreTunel::~COMXCoreTunel()
|
|
{
|
|
}
|
|
|
|
void COMXCoreTunel::Initialize(COMXCoreComponent *src_component, unsigned int src_port, COMXCoreComponent *dst_component, unsigned int dst_port)
|
|
{
|
|
m_src_component = src_component;
|
|
m_src_port = src_port;
|
|
m_dst_component = dst_component;
|
|
m_dst_port = dst_port;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreTunel::Deestablish(bool noWait)
|
|
{
|
|
if(!m_src_component || !m_dst_component || !IsInitialized())
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
if(m_src_component->GetComponent())
|
|
{
|
|
omx_err = m_src_component->DisablePort(m_src_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - 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)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - 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())
|
|
{
|
|
omx_err = m_src_component->WaitForCommand(OMX_CommandPortDisable, m_src_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
|
|
m_dst_port, m_src_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_dst_component->GetComponent())
|
|
{
|
|
omx_err = m_dst_component->WaitForCommand(OMX_CommandPortDisable, m_dst_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
|
|
m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_src_component->GetComponent())
|
|
{
|
|
omx_err = m_DllOMX->OMX_SetupTunnel(m_src_component->GetComponent(), m_src_port, NULL, 0);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - could not unset tunnel on comp src %s port %d omx_err(0x%08x)\n",
|
|
m_src_component->GetName().c_str(), m_src_port, (int)omx_err);
|
|
}
|
|
}
|
|
|
|
if(m_dst_component->GetComponent())
|
|
{
|
|
omx_err = m_DllOMX->OMX_SetupTunnel(m_dst_component->GetComponent(), m_dst_port, NULL, 0);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Deestablish - could not unset tunnel on comp dst %s port %d omx_err(0x%08x)\n",
|
|
m_dst_component->GetName().c_str(), m_dst_port, (int)omx_err);
|
|
}
|
|
}
|
|
|
|
m_tunnel_set = false;
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreTunel::Establish(bool enable_ports /* = true */, bool disable_ports /* = false */)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
OMX_PARAM_U32TYPE param;
|
|
OMX_INIT_STRUCTURE(param);
|
|
|
|
if(!m_src_component || !m_dst_component)
|
|
{
|
|
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, "COMXCoreTunel::Establish - Error setting state to idle %s omx_err(0x%08x)",
|
|
m_src_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_src_component->GetComponent() && disable_ports)
|
|
{
|
|
omx_err = m_src_component->DisablePort(m_src_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::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() && disable_ports)
|
|
{
|
|
omx_err = m_dst_component->DisablePort(m_dst_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::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() && disable_ports)
|
|
{
|
|
omx_err = m_src_component->WaitForCommand(OMX_CommandPortDisable, m_src_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Establish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
|
|
m_dst_port, m_src_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_dst_component->GetComponent() && disable_ports)
|
|
{
|
|
omx_err = m_dst_component->WaitForCommand(OMX_CommandPortDisable, m_dst_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Establish - Error WaitForCommand port %d on component %s omx_err(0x%08x)",
|
|
m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
|
|
return 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, "COMXCoreTunel::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);
|
|
return omx_err;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Establish - could not setup tunnel\n");
|
|
return OMX_ErrorUndefined;
|
|
}
|
|
|
|
m_tunnel_set = true;
|
|
|
|
if(m_src_component->GetComponent() && enable_ports)
|
|
{
|
|
omx_err = m_src_component->EnablePort(m_src_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Establish - Error enable port %d on component %s omx_err(0x%08x)",
|
|
m_src_port, m_src_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_dst_component->GetComponent() && enable_ports)
|
|
{
|
|
omx_err = m_dst_component->EnablePort(m_dst_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreTunel::Establish - Error enable port %d on component %s omx_err(0x%08x)",
|
|
m_dst_port, m_dst_component->GetName().c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
if(m_dst_component->GetComponent() && enable_ports)
|
|
{
|
|
omx_err = m_dst_component->WaitForCommand(OMX_CommandPortEnable, m_dst_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
return omx_err;
|
|
}
|
|
|
|
if(m_dst_component->GetState() == OMX_StateLoaded)
|
|
{
|
|
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);
|
|
return omx_err;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(m_src_component->GetComponent() && enable_ports)
|
|
{
|
|
omx_err = m_src_component->WaitForCommand(OMX_CommandPortEnable, m_src_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
COMXCoreComponent::COMXCoreComponent()
|
|
{
|
|
m_input_port = 0;
|
|
m_output_port = 0;
|
|
m_handle = NULL;
|
|
|
|
m_input_alignment = 0;
|
|
m_input_buffer_size = 0;
|
|
m_input_buffer_count = 0;
|
|
|
|
m_output_alignment = 0;
|
|
m_output_buffer_size = 0;
|
|
m_output_buffer_count = 0;
|
|
m_flush_input = false;
|
|
m_flush_output = false;
|
|
m_resource_error = false;
|
|
|
|
m_eos = false;
|
|
|
|
m_exit = false;
|
|
|
|
m_omx_input_use_buffers = false;
|
|
m_omx_output_use_buffers = false;
|
|
|
|
m_omx_events.clear();
|
|
m_ignore_error = OMX_ErrorNone;
|
|
|
|
pthread_mutex_init(&m_omx_input_mutex, NULL);
|
|
pthread_mutex_init(&m_omx_output_mutex, NULL);
|
|
pthread_mutex_init(&m_omx_event_mutex, NULL);
|
|
pthread_mutex_init(&m_omx_eos_mutex, NULL);
|
|
pthread_cond_init(&m_input_buffer_cond, NULL);
|
|
pthread_cond_init(&m_output_buffer_cond, NULL);
|
|
pthread_cond_init(&m_omx_event_cond, NULL);
|
|
|
|
m_DllOMX = DllOMX::GetDllOMX();
|
|
}
|
|
|
|
COMXCoreComponent::~COMXCoreComponent()
|
|
{
|
|
Deinitialize();
|
|
|
|
pthread_mutex_destroy(&m_omx_input_mutex);
|
|
pthread_mutex_destroy(&m_omx_output_mutex);
|
|
pthread_mutex_destroy(&m_omx_event_mutex);
|
|
pthread_mutex_destroy(&m_omx_eos_mutex);
|
|
pthread_cond_destroy(&m_input_buffer_cond);
|
|
pthread_cond_destroy(&m_output_buffer_cond);
|
|
pthread_cond_destroy(&m_omx_event_cond);
|
|
}
|
|
|
|
void COMXCoreComponent::TransitionToStateLoaded()
|
|
{
|
|
if(!m_handle)
|
|
return;
|
|
|
|
if(GetState() != OMX_StateLoaded && GetState() != OMX_StateIdle)
|
|
SetStateForComponent(OMX_StateIdle);
|
|
|
|
if(GetState() != OMX_StateLoaded)
|
|
SetStateForComponent(OMX_StateLoaded);
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::EmptyThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::EmptyThisBuffer component(%s) %p\n", m_componentName.c_str(), omx_buffer);
|
|
#endif
|
|
if(!m_handle || !omx_buffer)
|
|
return OMX_ErrorUndefined;
|
|
|
|
omx_err = OMX_EmptyThisBuffer(m_handle, omx_buffer);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::EmptyThisBuffer component(%s) - failed with result(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::FillThisBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::FillThisBuffer component(%s) %p\n", m_componentName.c_str(), omx_buffer);
|
|
#endif
|
|
if(!m_handle || !omx_buffer)
|
|
return OMX_ErrorUndefined;
|
|
|
|
omx_err = OMX_FillThisBuffer(m_handle, omx_buffer);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FillThisBuffer component(%s) - failed with result(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffer(OMX_BUFFERHEADERTYPE *omx_buffer)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
if(!m_handle || !omx_buffer)
|
|
return OMX_ErrorUndefined;
|
|
|
|
omx_err = OMX_FreeBuffer(m_handle, m_output_port, omx_buffer);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FreeOutputBuffer component(%s) - failed with result(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
void COMXCoreComponent::FlushAll()
|
|
{
|
|
FlushInput();
|
|
FlushOutput();
|
|
}
|
|
|
|
void COMXCoreComponent::FlushInput()
|
|
{
|
|
if(!m_handle || m_resource_error)
|
|
return;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_input_port, NULL);
|
|
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FlushInput - Error on component %s omx_err(0x%08x)",
|
|
m_componentName.c_str(), (int)omx_err);
|
|
}
|
|
omx_err = WaitForCommand(OMX_CommandFlush, m_input_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FlushInput - %s WaitForCommand omx_err(0x%08x)",
|
|
m_componentName.c_str(), (int)omx_err);
|
|
}
|
|
}
|
|
|
|
void COMXCoreComponent::FlushOutput()
|
|
{
|
|
if(!m_handle || m_resource_error)
|
|
return;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_output_port, NULL);
|
|
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FlushOutput - Error on component %s omx_err(0x%08x)",
|
|
m_componentName.c_str(), (int)omx_err);
|
|
}
|
|
omx_err = WaitForCommand(OMX_CommandFlush, m_output_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FlushOutput - %s WaitForCommand omx_err(0x%08x)",
|
|
m_componentName.c_str(), (int)omx_err);
|
|
}
|
|
}
|
|
|
|
// timeout in milliseconds
|
|
OMX_BUFFERHEADERTYPE *COMXCoreComponent::GetInputBuffer(long timeout /*=200*/)
|
|
{
|
|
OMX_BUFFERHEADERTYPE *omx_input_buffer = NULL;
|
|
|
|
if(!m_handle)
|
|
return NULL;
|
|
|
|
pthread_mutex_lock(&m_omx_input_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while (!m_flush_input)
|
|
{
|
|
if (m_resource_error)
|
|
break;
|
|
if(!m_omx_input_avaliable.empty())
|
|
{
|
|
omx_input_buffer = m_omx_input_avaliable.front();
|
|
m_omx_input_avaliable.pop();
|
|
break;
|
|
}
|
|
|
|
int retcode = pthread_cond_timedwait(&m_input_buffer_cond, &m_omx_input_mutex, &endtime);
|
|
if (retcode != 0) {
|
|
if (timeout != 0)
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::GetInputBuffer %s wait event timeout\n", m_componentName.c_str());
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_input_mutex);
|
|
return omx_input_buffer;
|
|
}
|
|
|
|
OMX_BUFFERHEADERTYPE *COMXCoreComponent::GetOutputBuffer(long timeout /*=200*/)
|
|
{
|
|
OMX_BUFFERHEADERTYPE *omx_output_buffer = NULL;
|
|
if(!m_handle)
|
|
return NULL;
|
|
|
|
pthread_mutex_lock(&m_omx_output_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while (!m_flush_output)
|
|
{
|
|
if (m_resource_error)
|
|
break;
|
|
if(!m_omx_output_available.empty())
|
|
{
|
|
omx_output_buffer = m_omx_output_available.front();
|
|
m_omx_output_available.pop();
|
|
break;
|
|
}
|
|
|
|
int retcode = pthread_cond_timedwait(&m_output_buffer_cond, &m_omx_output_mutex, &endtime);
|
|
if (retcode != 0) {
|
|
if (timeout != 0)
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::GetOutputBuffer %s wait event timeout\n", m_componentName.c_str());
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_output_mutex);
|
|
|
|
return omx_output_buffer;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::WaitForInputDone(long timeout /*=200*/)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
pthread_mutex_lock(&m_omx_input_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while (m_input_buffer_count != m_omx_input_avaliable.size())
|
|
{
|
|
if (m_resource_error)
|
|
break;
|
|
int retcode = pthread_cond_timedwait(&m_input_buffer_cond, &m_omx_input_mutex, &endtime);
|
|
if (retcode != 0) {
|
|
if (timeout != 0)
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::WaitForInputDone %s wait event timeout\n", m_componentName.c_str());
|
|
omx_err = OMX_ErrorTimeout;
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_input_mutex);
|
|
return omx_err;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::WaitForOutputDone(long timeout /*=200*/)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
pthread_mutex_lock(&m_omx_output_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while (m_output_buffer_count != m_omx_output_available.size())
|
|
{
|
|
if (m_resource_error)
|
|
break;
|
|
int retcode = pthread_cond_timedwait(&m_output_buffer_cond, &m_omx_output_mutex, &endtime);
|
|
if (retcode != 0) {
|
|
if (timeout != 0)
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::WaitForOutputDone %s wait event timeout\n", m_componentName.c_str());
|
|
omx_err = OMX_ErrorTimeout;
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_output_mutex);
|
|
return omx_err;
|
|
}
|
|
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::AllocInputBuffers(bool use_buffers /* = false **/)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
m_omx_input_use_buffers = use_buffers;
|
|
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_PARAM_PORTDEFINITIONTYPE portFormat;
|
|
OMX_INIT_STRUCTURE(portFormat);
|
|
portFormat.nPortIndex = m_input_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_input_port, false);
|
|
if(omx_err != OMX_ErrorNone)
|
|
return omx_err;
|
|
|
|
m_input_alignment = portFormat.nBufferAlignment;
|
|
m_input_buffer_count = portFormat.nBufferCountActual;
|
|
m_input_buffer_size = portFormat.nBufferSize;
|
|
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::AllocInputBuffers component(%s) - port(%d), nBufferCountMin(%u), nBufferCountActual(%u), nBufferSize(%u), nBufferAlignmen(%u)\n",
|
|
m_componentName.c_str(), GetInputPort(), 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_input_use_buffers)
|
|
{
|
|
data = (OMX_U8*)_aligned_malloc(portFormat.nBufferSize, m_input_alignment);
|
|
omx_err = OMX_UseBuffer(m_handle, &buffer, m_input_port, NULL, portFormat.nBufferSize, data);
|
|
}
|
|
else
|
|
{
|
|
omx_err = OMX_AllocateBuffer(m_handle, &buffer, m_input_port, NULL, portFormat.nBufferSize);
|
|
}
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::AllocInputBuffers component(%s) - OMX_UseBuffer failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
|
|
if(m_omx_input_use_buffers && data)
|
|
_aligned_free(data);
|
|
|
|
return omx_err;
|
|
}
|
|
buffer->nInputPortIndex = m_input_port;
|
|
buffer->nFilledLen = 0;
|
|
buffer->nOffset = 0;
|
|
buffer->pAppPrivate = (void*)i;
|
|
m_omx_input_buffers.push_back(buffer);
|
|
m_omx_input_avaliable.push(buffer);
|
|
}
|
|
|
|
omx_err = WaitForCommand(OMX_CommandPortEnable, m_input_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::AllocInputBuffers WaitForCommand:OMX_CommandPortEnable failed on %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
|
|
m_flush_input = false;
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
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(%u), nBufferCountActual(%u), nBufferSize(%u) nBufferAlignmen(%u)\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);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::AllocOutputBuffers WaitForCommand:OMX_CommandPortEnable failed on %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
|
|
m_flush_output = false;
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::FreeInputBuffers()
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
if(m_omx_input_buffers.empty())
|
|
return OMX_ErrorNone;
|
|
|
|
m_flush_input = true;
|
|
|
|
omx_err = DisablePort(m_input_port, false);
|
|
|
|
pthread_mutex_lock(&m_omx_input_mutex);
|
|
pthread_cond_broadcast(&m_input_buffer_cond);
|
|
|
|
for (size_t i = 0; i < m_omx_input_buffers.size(); i++)
|
|
{
|
|
uint8_t *buf = m_omx_input_buffers[i]->pBuffer;
|
|
|
|
omx_err = OMX_FreeBuffer(m_handle, m_input_port, m_omx_input_buffers[i]);
|
|
|
|
if(m_omx_input_use_buffers && buf)
|
|
_aligned_free(buf);
|
|
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FreeInputBuffers error deallocate omx input buffer on component %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_input_mutex);
|
|
|
|
omx_err = WaitForCommand(OMX_CommandPortDisable, m_input_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FreeInputBuffers WaitForCommand:OMX_CommandPortDisable failed on %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
}
|
|
|
|
WaitForInputDone(1000);
|
|
|
|
pthread_mutex_lock(&m_omx_input_mutex);
|
|
assert(m_omx_input_buffers.size() == m_omx_input_avaliable.size());
|
|
|
|
m_omx_input_buffers.clear();
|
|
|
|
while (!m_omx_input_avaliable.empty())
|
|
m_omx_input_avaliable.pop();
|
|
|
|
m_input_alignment = 0;
|
|
m_input_buffer_size = 0;
|
|
m_input_buffer_count = 0;
|
|
|
|
pthread_mutex_unlock(&m_omx_input_mutex);
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffers()
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
if(m_omx_output_buffers.empty())
|
|
return OMX_ErrorNone;
|
|
|
|
m_flush_output = true;
|
|
|
|
omx_err = DisablePort(m_output_port, false);
|
|
|
|
pthread_mutex_lock(&m_omx_output_mutex);
|
|
pthread_cond_broadcast(&m_output_buffer_cond);
|
|
|
|
for (size_t i = 0; i < m_omx_output_buffers.size(); i++)
|
|
{
|
|
uint8_t *buf = m_omx_output_buffers[i]->pBuffer;
|
|
|
|
omx_err = OMX_FreeBuffer(m_handle, m_output_port, m_omx_output_buffers[i]);
|
|
|
|
if(m_omx_output_use_buffers && buf)
|
|
_aligned_free(buf);
|
|
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FreeOutputBuffers error deallocate omx output buffer on component %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_output_mutex);
|
|
|
|
omx_err = WaitForCommand(OMX_CommandPortDisable, m_output_port);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::FreeOutputBuffers WaitForCommand:OMX_CommandPortDisable failed on %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
|
|
}
|
|
|
|
WaitForOutputDone(1000);
|
|
|
|
pthread_mutex_lock(&m_omx_output_mutex);
|
|
assert(m_omx_output_buffers.size() == m_omx_output_available.size());
|
|
|
|
m_omx_output_buffers.clear();
|
|
|
|
while (!m_omx_output_available.empty())
|
|
m_omx_output_available.pop();
|
|
|
|
m_output_alignment = 0;
|
|
m_output_buffer_size = 0;
|
|
m_output_buffer_count = 0;
|
|
|
|
pthread_mutex_unlock(&m_omx_output_mutex);
|
|
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::DisableAllPorts()
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
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)
|
|
return omx_err;
|
|
}
|
|
}
|
|
}
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
void COMXCoreComponent::RemoveEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2)
|
|
{
|
|
for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); )
|
|
{
|
|
omx_event event = *it;
|
|
|
|
if(event.eEvent == eEvent && event.nData1 == nData1 && event.nData2 == nData2)
|
|
{
|
|
it = m_omx_events.erase(it);
|
|
continue;
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::AddEvent(OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2)
|
|
{
|
|
omx_event event;
|
|
|
|
event.eEvent = eEvent;
|
|
event.nData1 = nData1;
|
|
event.nData2 = nData2;
|
|
|
|
pthread_mutex_lock(&m_omx_event_mutex);
|
|
RemoveEvent(eEvent, nData1, nData2);
|
|
m_omx_events.push_back(event);
|
|
// this allows (all) blocked tasks to be awoken
|
|
pthread_cond_broadcast(&m_omx_event_cond);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::AddEvent %s add event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
// timeout in milliseconds
|
|
OMX_ERRORTYPE COMXCoreComponent::WaitForEvent(OMX_EVENTTYPE eventType, long timeout)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForEvent %s wait event 0x%08x\n",
|
|
m_componentName.c_str(), (int)eventType);
|
|
#endif
|
|
|
|
pthread_mutex_lock(&m_omx_event_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while(true)
|
|
{
|
|
for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); it++)
|
|
{
|
|
omx_event event = *it;
|
|
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForEvent %s inlist event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
|
|
|
|
if(event.eEvent == OMX_EventError && event.nData1 == (OMX_U32)OMX_ErrorSameState && event.nData2 == 1)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForEvent %s remove event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
else if(event.eEvent == OMX_EventError)
|
|
{
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return (OMX_ERRORTYPE)event.nData1;
|
|
}
|
|
else if(event.eEvent == eventType)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForEvent %s remove event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
}
|
|
|
|
if (m_resource_error)
|
|
break;
|
|
int retcode = pthread_cond_timedwait(&m_omx_event_cond, &m_omx_event_mutex, &endtime);
|
|
if (retcode != 0)
|
|
{
|
|
if (timeout > 0)
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::WaitForEvent %s wait event 0x%08x timeout %ld\n",
|
|
m_componentName.c_str(), (int)eventType, timeout);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorTimeout;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
// timeout in milliseconds
|
|
OMX_ERRORTYPE COMXCoreComponent::WaitForCommand(OMX_U32 command, OMX_U32 nData2, long timeout)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForCommand %s wait event.eEvent 0x%08x event.command 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)OMX_EventCmdComplete, (int)command, (int)nData2);
|
|
#endif
|
|
|
|
pthread_mutex_lock(&m_omx_event_mutex);
|
|
struct timespec endtime;
|
|
clock_gettime(CLOCK_REALTIME, &endtime);
|
|
add_timespecs(endtime, timeout);
|
|
while(true)
|
|
{
|
|
for (std::vector<omx_event>::iterator it = m_omx_events.begin(); it != m_omx_events.end(); it++)
|
|
{
|
|
omx_event event = *it;
|
|
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForCommand %s inlist event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
if(event.eEvent == OMX_EventError && event.nData1 == (OMX_U32)OMX_ErrorSameState && event.nData2 == 1)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForCommand %s remove event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
else if(event.eEvent == OMX_EventError)
|
|
{
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return (OMX_ERRORTYPE)event.nData1;
|
|
}
|
|
else if(event.eEvent == OMX_EventCmdComplete && event.nData1 == command && event.nData2 == nData2)
|
|
{
|
|
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::WaitForCommand %s remove event event.eEvent 0x%08x event.nData1 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)event.eEvent, (int)event.nData1, (int)event.nData2);
|
|
#endif
|
|
|
|
m_omx_events.erase(it);
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
}
|
|
|
|
if (m_resource_error)
|
|
break;
|
|
int retcode = pthread_cond_timedwait(&m_omx_event_cond, &m_omx_event_mutex, &endtime);
|
|
if (retcode != 0) {
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::WaitForCommand %s wait timeout event.eEvent 0x%08x event.command 0x%08x event.nData2 %d\n",
|
|
m_componentName.c_str(), (int)OMX_EventCmdComplete, (int)command, (int)nData2);
|
|
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorTimeout;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&m_omx_event_mutex);
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::SetStateForComponent(OMX_STATETYPE state)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
OMX_STATETYPE state_actual = OMX_StateMax;
|
|
|
|
if(state == state_actual)
|
|
return OMX_ErrorNone;
|
|
|
|
omx_err = OMX_SendCommand(m_handle, OMX_CommandStateSet, state, 0);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
if(omx_err == OMX_ErrorSameState)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s same state\n",
|
|
m_componentName.c_str());
|
|
omx_err = OMX_ErrorNone;
|
|
}
|
|
else
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
omx_err = WaitForCommand(OMX_CommandStateSet, state);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::WaitForCommand - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_STATETYPE COMXCoreComponent::GetState() const
|
|
{
|
|
if(!m_handle)
|
|
return (OMX_STATETYPE)0;
|
|
|
|
OMX_STATETYPE state;
|
|
|
|
OMX_ERRORTYPE omx_err = OMX_GetState(m_handle, &state);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::GetState - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::SetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
omx_err = OMX_SetParameter(m_handle, paramIndex, paramStruct);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::SetParameter - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::GetParameter(OMX_INDEXTYPE paramIndex, OMX_PTR paramStruct) const
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
omx_err = OMX_GetParameter(m_handle, paramIndex, paramStruct);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::GetParameter - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::SetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
omx_err = OMX_SetConfig(m_handle, configIndex, configStruct);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::SetConfig - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::GetConfig(OMX_INDEXTYPE configIndex, OMX_PTR configStruct) const
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
omx_err = OMX_GetConfig(m_handle, configIndex, configStruct);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::GetConfig - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::SendCommand(OMX_COMMANDTYPE cmd, OMX_U32 cmdParam, OMX_PTR cmdParamData)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
omx_err = OMX_SendCommand(m_handle, cmd, cmdParam, cmdParamData);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::SendCommand - %s failed with omx_err(0x%x)\n",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port, bool wait)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
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);
|
|
return omx_err;
|
|
}
|
|
else
|
|
{
|
|
if(wait)
|
|
omx_err = WaitForCommand(OMX_CommandPortEnable, port);
|
|
}
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::DisablePort(unsigned int port, bool wait)
|
|
{
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
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::DisablePort - Error get port %d status on component %s omx_err(0x%08x)",
|
|
port, m_componentName.c_str(), (int)omx_err);
|
|
}
|
|
|
|
if(portFormat.bEnabled == OMX_TRUE)
|
|
{
|
|
omx_err = OMX_SendCommand(m_handle, OMX_CommandPortDisable, port, NULL);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::DIsablePort - Error disable port %d on component %s omx_err(0x%08x)",
|
|
port, m_componentName.c_str(), (int)omx_err);
|
|
return omx_err;
|
|
}
|
|
else
|
|
{
|
|
if(wait)
|
|
omx_err = WaitForCommand(OMX_CommandPortDisable, port);
|
|
}
|
|
}
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage)
|
|
{
|
|
if (m_callbacks.FillBufferDone == &COMXCoreComponent::DecoderFillBufferDoneCallback)
|
|
{
|
|
OMX_ERRORTYPE omx_err = OMX_ErrorNone;
|
|
|
|
if(!m_handle)
|
|
return OMX_ErrorUndefined;
|
|
|
|
m_omx_output_use_buffers = false;
|
|
|
|
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)
|
|
{
|
|
CLog::Log(LOGERROR, "%s::%s - %s EnablePort failed with omx_err(0x%x)", CLASSNAME, __func__,
|
|
m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
|
|
m_output_alignment = portFormat.nBufferAlignment;
|
|
m_output_buffer_count = portFormat.nBufferCountActual;
|
|
m_output_buffer_size = portFormat.nBufferSize;
|
|
|
|
if (portFormat.nBufferCountActual != 1)
|
|
{
|
|
CLog::Log(LOGERROR, "%s::%s - %s nBufferCountActual unexpected %d", CLASSNAME, __func__,
|
|
m_componentName.c_str(), portFormat.nBufferCountActual);
|
|
return omx_err;
|
|
}
|
|
|
|
CLog::Log(LOGDEBUG, "%s::%s component(%s) - port(%d), nBufferCountMin(%u), nBufferCountActual(%u), nBufferSize(%u) nBufferAlignmen(%u)\n",
|
|
CLASSNAME, __func__, 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_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "%s::%s - %s failed with omx_err(0x%x)\n",
|
|
CLASSNAME, __func__, m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
|
|
OMX_BUFFERHEADERTYPE *buffer = *ppBufferHdr;
|
|
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);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, " %s::%s - %s EnablePort failed with omx_err(0x%x)\n",
|
|
CLASSNAME, __func__, m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
m_flush_output = false;
|
|
|
|
return omx_err;
|
|
}
|
|
else
|
|
{
|
|
OMX_ERRORTYPE omx_err;
|
|
omx_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage);
|
|
if(omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "%s::%s - %s failed with omx_err(0x%x)\n",
|
|
CLASSNAME, __func__, m_componentName.c_str(), omx_err);
|
|
return omx_err;
|
|
}
|
|
return omx_err;
|
|
}
|
|
}
|
|
|
|
bool COMXCoreComponent::Initialize( const std::string &component_name, OMX_INDEXTYPE index, OMX_CALLBACKTYPE *callbacks)
|
|
{
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
m_input_port = 0;
|
|
m_output_port = 0;
|
|
m_handle = NULL;
|
|
|
|
m_input_alignment = 0;
|
|
m_input_buffer_size = 0;
|
|
m_input_buffer_count = 0;
|
|
|
|
m_output_alignment = 0;
|
|
m_output_buffer_size = 0;
|
|
m_output_buffer_count = 0;
|
|
m_flush_input = false;
|
|
m_flush_output = false;
|
|
m_resource_error = false;
|
|
|
|
m_eos = false;
|
|
|
|
m_exit = false;
|
|
|
|
m_omx_input_use_buffers = false;
|
|
m_omx_output_use_buffers = false;
|
|
|
|
m_omx_events.clear();
|
|
m_ignore_error = OMX_ErrorNone;
|
|
|
|
m_componentName = component_name;
|
|
|
|
m_callbacks.EventHandler = &COMXCoreComponent::DecoderEventHandlerCallback;
|
|
m_callbacks.EmptyBufferDone = &COMXCoreComponent::DecoderEmptyBufferDoneCallback;
|
|
m_callbacks.FillBufferDone = &COMXCoreComponent::DecoderFillBufferDoneCallback;
|
|
|
|
if (callbacks && callbacks->EventHandler)
|
|
m_callbacks.EventHandler = callbacks->EventHandler;
|
|
if (callbacks && callbacks->EmptyBufferDone)
|
|
m_callbacks.EmptyBufferDone = callbacks->EmptyBufferDone;
|
|
if (callbacks && callbacks->FillBufferDone)
|
|
m_callbacks.FillBufferDone = callbacks->FillBufferDone;
|
|
|
|
// Get video component handle setting up callbacks, component is in loaded state on return.
|
|
if(!m_handle)
|
|
{
|
|
omx_err = m_DllOMX->OMX_GetHandle(&m_handle, (char*)component_name.c_str(), this, &m_callbacks);
|
|
if (!m_handle || 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 m_handle %p\n",
|
|
m_componentName.c_str(), m_input_port, m_output_port, m_handle);
|
|
|
|
m_exit = false;
|
|
m_flush_input = false;
|
|
m_flush_output = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void COMXCoreComponent::ResetEos()
|
|
{
|
|
pthread_mutex_lock(&m_omx_eos_mutex);
|
|
m_eos = false;
|
|
pthread_mutex_unlock(&m_omx_eos_mutex);
|
|
}
|
|
|
|
bool COMXCoreComponent::Deinitialize()
|
|
{
|
|
OMX_ERRORTYPE omx_err;
|
|
|
|
m_exit = true;
|
|
|
|
m_flush_input = true;
|
|
m_flush_output = true;
|
|
|
|
if(m_handle)
|
|
{
|
|
FlushAll();
|
|
|
|
FreeOutputBuffers();
|
|
FreeInputBuffers();
|
|
|
|
TransitionToStateLoaded();
|
|
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::Deinitialize : %s handle %p\n",
|
|
m_componentName.c_str(), m_handle);
|
|
omx_err = m_DllOMX->OMX_FreeHandle(m_handle);
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCoreComponent::Deinitialize - failed to free handle for component %s omx_err(0x%08x)",
|
|
m_componentName.c_str(), omx_err);
|
|
}
|
|
m_handle = NULL;
|
|
|
|
m_input_port = 0;
|
|
m_output_port = 0;
|
|
m_componentName = "";
|
|
m_resource_error = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
// DecoderEventHandler -- OMX event callback
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandlerCallback(
|
|
OMX_HANDLETYPE hComponent,
|
|
OMX_PTR pAppData,
|
|
OMX_EVENTTYPE eEvent,
|
|
OMX_U32 nData1,
|
|
OMX_U32 nData2,
|
|
OMX_PTR pEventData)
|
|
{
|
|
if(!pAppData)
|
|
return OMX_ErrorNone;
|
|
|
|
COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
|
|
return ctx->DecoderEventHandler(hComponent, eEvent, nData1, nData2, pEventData);
|
|
}
|
|
|
|
// DecoderEmptyBufferDone -- OMXCore input buffer has been emptied
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderEmptyBufferDoneCallback(
|
|
OMX_HANDLETYPE hComponent,
|
|
OMX_PTR pAppData,
|
|
OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
if(!pAppData)
|
|
return OMX_ErrorNone;
|
|
|
|
COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
|
|
return ctx->DecoderEmptyBufferDone( hComponent, pBuffer);
|
|
}
|
|
|
|
// DecoderFillBufferDone -- OMXCore output buffer has been filled
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderFillBufferDoneCallback(
|
|
OMX_HANDLETYPE hComponent,
|
|
OMX_PTR pAppData,
|
|
OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
if(!pAppData)
|
|
return OMX_ErrorNone;
|
|
|
|
COMXCoreComponent *ctx = static_cast<COMXCoreComponent*>(pAppData);
|
|
return ctx->DecoderFillBufferDone(hComponent, pBuffer);
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderEmptyBufferDone(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
if(m_exit)
|
|
return OMX_ErrorNone;
|
|
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderEmptyBufferDone component(%s) %p %d/%d\n", m_componentName.c_str(), pBuffer, m_omx_input_avaliable.size(), m_input_buffer_count);
|
|
#endif
|
|
pthread_mutex_lock(&m_omx_input_mutex);
|
|
m_omx_input_avaliable.push(pBuffer);
|
|
|
|
// this allows (all) blocked tasks to be awoken
|
|
pthread_cond_broadcast(&m_input_buffer_cond);
|
|
|
|
pthread_mutex_unlock(&m_omx_input_mutex);
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderFillBufferDone(OMX_HANDLETYPE hComponent, OMX_BUFFERHEADERTYPE* pBuffer)
|
|
{
|
|
if(m_exit)
|
|
return OMX_ErrorNone;
|
|
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "COMXCoreComponent::DecoderFillBufferDone component(%s) %p %d/%d\n", m_componentName.c_str(), pBuffer, m_omx_output_available.size(), m_output_buffer_count);
|
|
#endif
|
|
pthread_mutex_lock(&m_omx_output_mutex);
|
|
m_omx_output_available.push(pBuffer);
|
|
|
|
// this allows (all) blocked tasks to be awoken
|
|
pthread_cond_broadcast(&m_output_buffer_cond);
|
|
|
|
pthread_mutex_unlock(&m_omx_output_mutex);
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
// DecoderEmptyBufferDone -- OMXCore input buffer has been emptied
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Component event handler -- OMX event callback
|
|
OMX_ERRORTYPE COMXCoreComponent::DecoderEventHandler(
|
|
OMX_HANDLETYPE hComponent,
|
|
OMX_EVENTTYPE eEvent,
|
|
OMX_U32 nData1,
|
|
OMX_U32 nData2,
|
|
OMX_PTR pEventData)
|
|
{
|
|
#ifdef OMX_DEBUG_EVENTS
|
|
CLog::Log(LOGDEBUG,
|
|
"COMXCoreComponent::%s - %s eEvent(0x%x), nData1(0x%x), nData2(0x%x), pEventData(0x%p)\n",
|
|
__func__, GetName().c_str(), eEvent, nData1, nData2, pEventData);
|
|
#endif
|
|
|
|
// if the error is expected, then we can skip it
|
|
if (eEvent == OMX_EventError && (OMX_S32)nData1 == m_ignore_error)
|
|
{
|
|
CLog::Log(LOGDEBUG,
|
|
"COMXCoreComponent::%s - %s Ignoring expected event: eEvent(0x%x), nData1(0x%x), nData2(0x%x), pEventData(0x%p)\n",
|
|
__func__, GetName().c_str(), eEvent, nData1, nData2, pEventData);
|
|
m_ignore_error = OMX_ErrorNone;
|
|
return OMX_ErrorNone;
|
|
}
|
|
AddEvent(eEvent, nData1, nData2);
|
|
|
|
switch (eEvent)
|
|
{
|
|
case OMX_EventCmdComplete:
|
|
|
|
switch(nData1)
|
|
{
|
|
case OMX_CommandStateSet:
|
|
switch ((int)nData2)
|
|
{
|
|
case OMX_StateInvalid:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateInvalid\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_StateLoaded:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateLoaded\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_StateIdle:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateIdle\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_StateExecuting:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateExecuting\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_StatePause:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StatePause\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_StateWaitForResources:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_StateWaitForResources\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
default:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG,
|
|
"%s::%s %s - Unknown OMX_Statexxxxx, state(%d)\n", CLASSNAME, __func__, GetName().c_str(), (int)nData2);
|
|
#endif
|
|
break;
|
|
}
|
|
break;
|
|
case OMX_CommandFlush:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandFlush, port %d\n", CLASSNAME, __func__, GetName().c_str(), (int)nData2);
|
|
#endif
|
|
break;
|
|
case OMX_CommandPortDisable:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandPortDisable, nData1(0x%x), port %d\n", CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
|
|
#endif
|
|
break;
|
|
case OMX_CommandPortEnable:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandPortEnable, nData1(0x%x), port %d\n", CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
|
|
#endif
|
|
break;
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
case OMX_CommandMarkBuffer:
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_CommandMarkBuffer, nData1(0x%x), port %d\n", CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
|
|
break;
|
|
#endif
|
|
}
|
|
break;
|
|
case OMX_EventBufferFlag:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventBufferFlag(input)\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
if(nData2 & OMX_BUFFERFLAG_EOS)
|
|
{
|
|
pthread_mutex_lock(&m_omx_eos_mutex);
|
|
m_eos = true;
|
|
pthread_mutex_unlock(&m_omx_eos_mutex);
|
|
}
|
|
break;
|
|
case OMX_EventPortSettingsChanged:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventPortSettingsChanged(output)\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
case OMX_EventParamOrConfigChanged:
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventParamOrConfigChanged(output)\n", CLASSNAME, __func__, GetName().c_str());
|
|
#endif
|
|
break;
|
|
#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
case OMX_EventMark:
|
|
CLog::Log(LOGDEBUG, "%s::%s %s - OMX_EventMark\n", CLASSNAME, __func__, GetName().c_str());
|
|
break;
|
|
case OMX_EventResourcesAcquired:
|
|
CLog::Log(LOGDEBUG, "%s::%s %s- OMX_EventResourcesAcquired\n", CLASSNAME, __func__, GetName().c_str());
|
|
break;
|
|
#endif
|
|
case OMX_EventError:
|
|
switch((OMX_S32)nData1)
|
|
{
|
|
case OMX_ErrorSameState:
|
|
//#if defined(OMX_DEBUG_EVENTHANDLER)
|
|
//CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorSameState, same state\n", CLASSNAME, __func__, GetName().c_str());
|
|
//#endif
|
|
break;
|
|
case OMX_ErrorInsufficientResources:
|
|
CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorInsufficientResources, insufficient resources\n", CLASSNAME, __func__, GetName().c_str());
|
|
m_resource_error = true;
|
|
break;
|
|
case OMX_ErrorFormatNotDetected:
|
|
CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorFormatNotDetected, cannot parse input stream\n", CLASSNAME, __func__, GetName().c_str());
|
|
break;
|
|
case OMX_ErrorPortUnpopulated:
|
|
CLog::Log(LOGWARNING, "%s::%s %s - OMX_ErrorPortUnpopulated port %d\n", CLASSNAME, __func__, GetName().c_str(), (int)nData2);
|
|
break;
|
|
case OMX_ErrorStreamCorrupt:
|
|
CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorStreamCorrupt, Bitstream corrupt\n", CLASSNAME, __func__, GetName().c_str());
|
|
m_resource_error = true;
|
|
break;
|
|
case OMX_ErrorUnsupportedSetting:
|
|
CLog::Log(LOGERROR, "%s::%s %s - OMX_ErrorUnsupportedSetting, unsupported setting\n", CLASSNAME, __func__, GetName().c_str());
|
|
break;
|
|
default:
|
|
CLog::Log(LOGERROR, "%s::%s %s - OMX_EventError detected, nData1(0x%x), port %d\n", CLASSNAME, __func__, GetName().c_str(), nData1, (int)nData2);
|
|
break;
|
|
}
|
|
// wake things up
|
|
if (m_resource_error)
|
|
{
|
|
pthread_cond_broadcast(&m_output_buffer_cond);
|
|
pthread_cond_broadcast(&m_input_buffer_cond);
|
|
pthread_cond_broadcast(&m_omx_event_cond);
|
|
}
|
|
break;
|
|
default:
|
|
CLog::Log(LOGWARNING, "%s::%s %s - Unknown eEvent(0x%x), nData1(0x%x), port %d\n", CLASSNAME, __func__, GetName().c_str(), eEvent, nData1, (int)nData2);
|
|
break;
|
|
}
|
|
|
|
return OMX_ErrorNone;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
COMXCore::COMXCore()
|
|
{
|
|
m_is_open = false;
|
|
|
|
m_DllOMX = new DllOMX();
|
|
}
|
|
|
|
COMXCore::~COMXCore()
|
|
{
|
|
delete m_DllOMX;
|
|
}
|
|
|
|
bool COMXCore::Initialize()
|
|
{
|
|
if(!m_DllOMX->Load())
|
|
return false;
|
|
|
|
OMX_ERRORTYPE omx_err = m_DllOMX->OMX_Init();
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCore::Initialize - OMXCore failed to init, omx_err(0x%08x)", omx_err);
|
|
return false;
|
|
}
|
|
|
|
m_is_open = true;
|
|
return true;
|
|
}
|
|
|
|
void COMXCore::Deinitialize()
|
|
{
|
|
if(m_is_open)
|
|
{
|
|
OMX_ERRORTYPE omx_err = m_DllOMX->OMX_Deinit();
|
|
if (omx_err != OMX_ErrorNone)
|
|
{
|
|
CLog::Log(LOGERROR, "COMXCore::Deinitialize - OMXCore failed to deinit, omx_err(0x%08x)", omx_err);
|
|
}
|
|
m_DllOMX->Unload();
|
|
}
|
|
}
|
|
|
|
#endif
|