Hello,
I try to use OpenMax decoder for decode h.264 and display video with using overlay. If I decode video frames with resolution 320x240, it's work perfectly, but if use resolution 640x480 decoding not working. Also I have sometimes deadlock if I try to close decoder. If open video(avi) in omxplayer with resolution 640x480 it's working without problem. Maybe somebody already had this problem and solve it?
My source code bellow
Sergey
bool OMVideoDecoder::initialize(int x, int y, int width, int height) {
OMX_ERRORTYPE errType;
OMX_VIDEO_PARAM_PORTFORMATTYPE srcFormat;
deinitialize();
if (!(client_ = ilclient_init())) {
std::cout << "OMVideoDecoder::initialize, fault to initialize ilclient"
<< std::endl;
return false;
}
memset(tunnel_, 0, sizeof(tunnel_));
memset(cmpList_, 0, sizeof(cmpList_));
errType = ilclient_create_component(client_, &videoDecode_, "video_decode",
ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS);
if (errType != 0) {
ilclient_destroy(client_);
std::cout << "OMVideoDecoder::initialize, fault to create Decode component"
<< std::endl;
return false;
}
cmpList_[0] = videoDecode_;
errType = ilclient_create_component(client_, &videoRender_, "video_render",
ILCLIENT_DISABLE_ALL_PORTS);
if (errType != 0) {
ilclient_destroy(client_);
std::cout << "OMVideoDecoder::initialize, fault to create Render component"
<< std::endl;
return false;
}
cmpList_[1] = videoRender_;
set_tunnel(tunnel_, videoDecode_, 131, videoRender_, 90);
ilclient_setup_tunnel(tunnel_, 0, 0);
memset(&srcFormat, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
srcFormat.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
srcFormat.nVersion.nVersion = OMX_VERSION;
srcFormat.nPortIndex = 130;
srcFormat.eCompressionFormat = OMX_VIDEO_CodingAVC;
errType = OMX_SetParameter(ILC_GET_HANDLE(videoDecode_),
OMX_IndexParamVideoPortFormat, &srcFormat);
if (errType != OMX_ErrorNone) {
std::cout << "OMVideoDecoder::initialize, fault set format for port 130"
<< std::endl;
return false;
}
OMX_CONFIG_DISPLAYREGIONTYPE display;
memset(&display, 0, sizeof(OMX_CONFIG_DISPLAYREGIONTYPE));
display.nVersion.nVersion = OMX_VERSION;
display.nSize = sizeof(OMX_CONFIG_DISPLAYREGIONTYPE);
display.nPortIndex = 90;
display.src_rect.x_offset = 0;
display.src_rect.y_offset = 0;
display.src_rect.width = 0;
display.src_rect.height = 0;
display.dest_rect.x_offset = x;
display.dest_rect.y_offset = y;
display.dest_rect.width = width;
display.dest_rect.height = height;
display.noaspect = OMX_TRUE;
display.fullscreen = OMX_FALSE;
display.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_DEST_RECT |
OMX_DISPLAY_SET_SRC_RECT | OMX_DISPLAY_SET_FULLSCREEN |
OMX_DISPLAY_SET_NOASPECT);
errType = OMX_SetConfig(ILC_GET_HANDLE(videoRender_),
OMX_IndexConfigDisplayRegion, &display);
if (errType != OMX_ErrorNone) {
std::cout << "OMVideoDecoder::initialize, fault set render display"
<< std::endl;
return false;
}
ilclient_change_component_state(videoDecode_, OMX_StateIdle);
ilclient_change_component_state(videoRender_, OMX_StateIdle);
if (ilclient_enable_port_buffers(videoDecode_, 130, 0, 0, 0) != 0) {
std::cout << "OMVideoDecoder::initialize, fault to get src buffer"
<< std::endl;
return false;
}
screenX_ = x;
screenY_ = y;
screenWidth_ = width;
screenHeight_ = height;
ilclient_change_component_state(videoDecode_, OMX_StateExecuting);
ilclient_change_component_state(videoRender_, OMX_StateExecuting);
initialized_ = true;
return true;
}
//------------------------------------------------------------------------------
void OMVideoDecoder::deinitialize() {
if (initialized_) {
std::cout << "OMVideoDecoder::deinit, 1" << std::endl;
ilclient_wait_for_event(videoRender_, OMX_EventBufferFlag, 90, 0,
OMX_BUFFERFLAG_EOS, 0, ILCLIENT_BUFFER_FLAG_EOS, 1000);
std::cout << "OMVideoDecoder::deinit, 2" << std::endl;
ilclient_flush_tunnels(tunnel_, 0);
std::cout << "OMVideoDecoder::deinit, 3" << std::endl;
ilclient_disable_port_buffers(videoDecode_, 130, 0, 0, 0);
std::cout << "OMVideoDecoder::deinit, 4" << std::endl;
ilclient_disable_tunnel(tunnel_);
std::cout << "OMVideoDecoder::deinit, 5" << std::endl;
}
initialized_ = false;
}
//------------------------------------------------------------------------------
bool OMVideoDecoder::decodeFrame(const unsigned char* encBuffer, int encSize,
int x, int y, int width, int height)
{
OMX_ERRORTYPE errType;
OMX_BUFFERHEADERTYPE* srcBuffer = 0;
int bytes = encSize;
unsigned char* buffer = encBuffer;
std::cout << "OMVideoDecoder::DecodeFrame, size: " << encSize << std::endl;
if (!initialized_) {
if (!initialize(x, y, width, height)) {
return false;
}
}
if (screenX_ != x || screenY_ != y || screenWidth_ != width ||
screenHeight_ != height)
{
if (!initialize(x, y, width, height)) {
return false;
}
}
while (bytes > 0) {
srcBuffer = ilclient_get_input_buffer(videoDecode_, 130, 1);
if (!srcBuffer) {
std::cout << "OMVideoDecoder::DecodeFrame, fault to get srcbuffer"
<< std::endl;
return false;
}
if (srcBuffer->nAllocLen < bytes) {
memcpy(srcBuffer->pBuffer, buffer, srcBuffer->nAllocLen);
buffer = buffer + srcBuffer->nAllocLen;
bytes = bytes - srcBuffer->nAllocLen;
srcBuffer->nFilledLen = srcBuffer->nAllocLen;
} else {
memcpy(srcBuffer->pBuffer, buffer, bytes);
srcBuffer->nFilledLen = bytes;
srcBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
bytes = 0;
}
errType = OMX_EmptyThisBuffer(ILC_GET_HANDLE(videoDecode_), srcBuffer);
if (errType != OMX_ErrorNone) {
std::cout << "OMVideoDecoder::DecodeFrame, fault to empty buffer"
<< std::endl;
return false;
}
srcBuffer->nFilledLen = 0;
}
return true;
}
//------------------------------------------------------------------------------
