Page 1 of 1

OpenMAX fault to decode h.264 more than 320x240

Posted: Wed Apr 09, 2014 6:11 am
by RSS
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;
}
//------------------------------------------------------------------------------

Re: OpenMAX fault to decode h.264 more than 320x240

Posted: Wed Apr 09, 2014 7:50 am
by jamesh
What is your GPU memory split? The GPU may not be supplied with enough memory.

Re: OpenMAX fault to decode h.264 more than 320x240

Posted: Wed Apr 09, 2014 7:56 am
by RSS
I use 64 mb, but I used more it's not helped

Sergey

Re: OpenMAX fault to decode h.264 more than 320x240

Posted: Thu Apr 10, 2014 5:29 am
by RSS
Solved, necessary before change component state set resolution for port 130

int cwidth = 640;
int cheight = 480;

OMX_PARAM_PORTDEFINITIONTYPE srcDefenition;

memset(&srcDefenition, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));

srcDefenition.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
srcDefenition.nVersion.nVersion = OMX_VERSION;
srcDefenition.nPortIndex = 130;

errType = OMX_GetParameter(ILC_GET_HANDLE(videoDecode_),
OMX_IndexParamPortDefinition, &srcDefenition);

if (errType != OMX_ErrorNone) {
std::cout << "OMVideoEncoder::initialize, fault get parameter for port 130"
<< std::endl;

return false;
}

srcDefenition.format.video.nFrameWidth = cwidth;
srcDefenition.format.video.nFrameHeight = cheight;
srcDefenition.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;

errType = OMX_SetParameter(ILC_GET_HANDLE(videoDecode_),
OMX_IndexParamPortDefinition, &srcDefenition);

if (errType != OMX_ErrorNone) {
std::cout << "OMVideoEncoder::initialize, fault set parameter for port 130"
<< std::endl;

return false;
}

Sergey

Re: OpenMAX fault to decode h.264 more than 320x240

Posted: Thu Jan 14, 2016 3:08 pm
by Mikchel
Hello, i also have issue with deadlock trying to stop playing video.
I used hello_video as start example. I'm playing video file in infinite loop and after 10-15 loops video stop playing with error in ilclient_get_input_buffer.
After that i'm quiting from application but first i try to stop video...so i have deadlock in ilclient_flush_tunnels(tunnel, 0);
So seems problem isn't solved from April 2014