--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon, 2009,2014 Marten Richter
+
+ This file is part of VOMP.
+
+ VOMP 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 of the License, or
+ (at your option) any later version.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "imageomx.h"
+#include "videoomx.h"
+#include "log.h"
+#include "vdr.h"
+#include "woptionpane.h"
+
+#include "osdopenvg.h"
+#include <bcm_host.h>
+
+ImageOMX::ImageOMX(OsdVector::PictureReader * treader):OsdVector::PictureDecoder(treader)
+{
+ initted = 0;
+
+ omx_running=false;
+ pictInfValid=false;
+}
+
+ImageOMX::~ImageOMX()
+{
+
+}
+
+void ImageOMX::init()
+{
+ AllocateCodecsOMX();
+}
+
+void ImageOMX::shutdown()
+{
+ Log::getInstance()->log("ImageOMX", Log::DEBUG, "shutdown");
+ DeAllocateCodecsOMX();
+}
+
+
+
+
+
+OMX_ERRORTYPE ImageOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
+
+ //Log::getInstance()->log("Image", Log::NOTICE, "EmptyBufferDone");
+ ImageOMX *image=(ImageOMX *)buffer->pAppPrivate;
+ image->ReturnEmptyOMXBuffer(buffer);
+ return OMX_ErrorNone;
+
+}
+
+void ImageOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
+ input_bufs_omx_mutex.Lock();
+ if (buffer->pBuffer) {
+ free(buffer->pBuffer);
+ buffer->pBuffer = NULL;
+ }
+ buffer->nAllocLen= 0;
+ //Log::getInstance()->log("Image", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
+ input_bufs_omx_free.push_back(buffer);
+ //Log::getInstance()->log("Image", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size());
+ input_bufs_omx_mutex.Unlock();
+}
+
+ OMX_ERRORTYPE ImageOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
+ Log::getInstance()->log("ImageOmx", Log::NOTICE, "FillBufferDone");
+ ImageOMX *image=(ImageOMX *)buffer->pAppPrivate;
+ image->ReturnFillOMXBuffer(buffer);
+ return OMX_ErrorNone;
+}
+
+ void ImageOMX::ReturnFillOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
+ //input_bufs_omx_mutex.Lock();
+ omx_egl_filled = true;
+ //output_bufs_omx_full.push_back(buffer);
+ //input_bufs_omx_mutex.Unlock();
+ }
+
+
+/*
+
+int ImageOMX::play() {
+ if (!initted)
+ return 0;
+ lastAType=MPTYPE_MPEG_Image;
+ Log::getInstance()->log("Image", Log::DEBUG, "enter play");
+
+ ((VideoOMX*)Video::getInstance())->interlaceSwitch4Demux(); // switch resolution if necessary
+
+ if (!AllocateCodecsOMX()) {
+ return 0;
+ }
+ return 1;
+}*/
+
+
+
+
+
+int ImageOMX::AllocateCodecsOMX()
+{
+ OMX_ERRORTYPE error;
+ static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX};
+
+ Log::getInstance()->log("Image", Log::NOTICE, "Allocate Codecs OMX");
+ //Clock, move later to Image
+ VideoOMX *video=(VideoOMX*)Video::getInstance();
+
+ OMX_PORT_PARAM_TYPE p_param;
+ memset(&p_param,0,sizeof(p_param));
+ p_param.nSize=sizeof(p_param);
+ p_param.nVersion.nVersion=OMX_VERSION;
+
+
+ video->LockClock();
+
+
+ error = OMX_GetHandle(&omx_imag_decode, VPE_OMX_IMAGE_DECODER, NULL, &callbacks);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "Init OMX Image decoder failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+ error = OMX_GetParameter(omx_imag_decode, OMX_IndexParamImageInit, &p_param);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "Init OMX Image rend OMX_GetParameter failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+ omx_image_input_port = p_param.nStartPortNumber;
+ omx_image_output_port = p_param.nStartPortNumber+1;
+
+ error=OMX_GetHandle(&omx_egl_render,VPE_OMX_EGL_REND,NULL,&callbacks);
+
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Init OMX EGL renderer failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ error=OMX_GetParameter(omx_egl_render,OMX_IndexParamVideoInit,&p_param);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Init OMX EGL renderer OMX_GetParameter failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+ omx_egl_input_port=p_param.nStartPortNumber;
+ omx_egl_output_port=p_param.nStartPortNumber+1;
+
+ if (!video->DisablePort(omx_imag_decode,omx_image_input_port) || !video->DisablePort(omx_imag_decode,omx_image_output_port)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Disable Ports OMX Image decoder failed");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ if (!video->DisablePort(omx_egl_render,omx_egl_input_port) || !video->DisablePort(omx_egl_render,omx_egl_output_port)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Disable Ports OMX Image decoder failed");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "image decode idle ChangeComponentState");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "egl render idle ChangeComponentState");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+ //Setuo chain
+
+
+
+
+ error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,omx_egl_render,omx_egl_input_port);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel decode to egl rend failed %x ");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!video->EnablePort(omx_imag_decode,omx_image_output_port,false) || !video->EnablePort(omx_egl_render,omx_egl_input_port,false)
+ ) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Enable Ports OMXdecoder rend failed");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ OMX_IMAGE_PARAM_PORTFORMATTYPE ft_type;
+ memset(&ft_type,0,sizeof(ft_type));
+ ft_type.nSize=sizeof(ft_type);
+ ft_type.nVersion.nVersion=OMX_VERSION;
+
+ ft_type.nPortIndex=omx_image_input_port;
+
+ ft_type.eCompressionFormat=OMX_IMAGE_CodingJPEG;
+
+ error=OMX_SetParameter(omx_imag_decode,OMX_IndexParamImagePortFormat,&ft_type);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Init OMX_IndexParamVImagePortFormat failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortEnable,omx_egl_input_port)) {
+ video->UnlockClock();
+ Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end eip");
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortEnable,omx_image_output_port)) {
+ video->UnlockClock();
+ Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end iop");
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+
+
+
+ if (!PrepareInputBufsOMX(true)) {
+ video->UnlockClock();
+ Log::getInstance()->log("Image", Log::DEBUG, "prepare input bufs failed");
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+/* error=OMX_SetupTunnel(omx_aud_dec,omx_codec_output_port,omx_aud_rend,omx_rend_input_port);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel dec to render failed %x", error);
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }*/
+
+
+
+/* if (!video->EnablePort(omx_aud_dec,omx_codec_output_port,false) || !video->EnablePort(omx_aud_rend,omx_rend_input_port,false)
+ ) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Enable Ports OMX codec rend failed");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }*/
+
+/* if ( !video->CommandFinished(omx_aud_dec,OMX_CommandPortEnable,omx_codec_output_port)
+ || !video->CommandFinished(omx_aud_rend,OMX_CommandPortEnable,omx_rend_input_port)) {
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }*/
+
+ if (!video->ChangeComponentState(omx_imag_decode,OMX_StateExecuting)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "omx_image_decode ChangeComponentState Execute");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ if (!video->ChangeComponentState(omx_egl_render,OMX_StateExecuting)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_rendd ChangeComponentState Execute");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ if (!video->EnablePort(omx_imag_decode,omx_image_input_port,false)
+ ) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Enable Ports OMXdecoder inputfailed");
+ video->UnlockClock();
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+
+
+ video->UnlockClock();
+ omx_running=true;
+
+
+
+ Log::getInstance()->log("Image", Log::NOTICE, "Allocate Codecs OMX finished");
+
+ return 1;
+}
+
+
+bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length)
+{
+ if (pictInfValid) return false; // does support only one image at a Time;
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 1");
+ EGLPictureCreator * pictcreat =dynamic_cast<EGLPictureCreator*>(Osd::getInstance());
+ if (buffer[0]!= 0xff || buffer[1] !=0xd8) return false; // Jpeg magic numbers
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 2");
+ VideoOMX *video=(VideoOMX*)Video::getInstance();
+
+
+
+ if (!pictcreat) return false;
+
+ // Use Buffer
+ OMX_BUFFERHEADERTYPE * bufhead;
+
+ input_bufs_omx_mutex.Lock();
+ int count =0;
+ while (input_bufs_omx_free.size()==0) {
+ input_bufs_omx_mutex.Unlock();
+ //Log::getInstance()->log("Image", Log::DEBUG, "DMP mark 6");
+ //Log::getInstance()->log("Image", Log::DEBUG, "Deliver MediaPacket no free sample");
+ //return 0; // we do not have a free media sample
+
+ count++;
+ if (count>100) return false;
+ MILLISLEEP(10);
+
+ input_bufs_omx_mutex.Lock();
+
+ }
+ bufhead=input_bufs_omx_free.front();
+ bufhead->nFilledLen=length;
+ bufhead->nAllocLen= length;
+ bufhead->nOffset=0;
+ bufhead->nTimeStamp=VideoOMX::intToOMXTicks(0);
+ bufhead->pBuffer=buffer;
+ bufhead->pAppPrivate=this;
+ input_bufs_omx_free.pop_front();
+ input_bufs_omx_mutex.Unlock();
+
+
+ bufhead->nFilledLen=bufhead->nAllocLen;
+ video->ProtOMXEmptyThisBuffer(omx_imag_decode, bufhead);
+
+ int oldcancelstate;
+ int oldcanceltype;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
+
+ video->LockClock();
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 3");
+
+ video->WaitForEvent(omx_imag_decode,OMX_EventPortSettingsChanged);
+
+ OMX_ERRORTYPE error;
+
+ OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
+ memset(&port_def_type,0,sizeof(port_def_type));
+ port_def_type.nSize=sizeof(port_def_type);
+ port_def_type.nVersion.nVersion=OMX_VERSION;
+ port_def_type.nPortIndex=omx_image_output_port;
+
+ error=OMX_GetParameter(omx_imag_decode,OMX_IndexParamPortDefinition, &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "OMX_IndexParamPortDefinition fix failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 4");
+
+
+
+
+
+
+
+ video->DisablePort(omx_egl_render,omx_egl_output_port,true);
+ video->DisablePort(omx_egl_render,omx_egl_input_port,false);
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 6");
+ video->DisablePort(omx_imag_decode,omx_image_output_port,false);
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 5");
+
+
+ if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortDisable,omx_egl_input_port)) {
+ video->UnlockClock();
+ Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end eip");
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+
+ if ( !video->CommandFinished(omx_imag_decode,OMX_CommandPortDisable,omx_image_output_port)) {
+ video->UnlockClock();
+ Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end iop");
+ DeAllocateCodecsOMX();
+ return 0;
+ }
+
+ port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
+ port_def_type.format.image.nSliceHeight = 16;
+ port_def_type.format.image.nStride = 0;
+ error = OMX_SetParameter(omx_imag_decode, OMX_IndexParamPortDefinition,
+ &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "Set OMX_IndexParamPortDefinition1 failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 5 6");
+
+
+/* port_def_type.nPortIndex=omx_egl_input_port;
+ error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
+ &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "Set OMX_IndexParamPortDefinition3 failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }*/
+
+ pictInf.width = port_def_type.format.image.nFrameWidth;
+ pictInf.height = port_def_type.format.image.nFrameHeight;
+ pictInf.decoder = this;
+ pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
+ pictInf.lindex = index;
+
+
+ port_def_type.nPortIndex=omx_egl_output_port;
+
+ error=OMX_GetParameter(omx_egl_render,OMX_IndexParamPortDefinition, &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "OMX_IndexParamPortDefinition fix failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+
+
+
+ port_def_type.nBufferCountActual = 1;
+ EGLDisplay egl_display;
+ if (!pictcreat->getEGLPicture(pictInf, &egl_display)) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "getEGLPict failed");
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+
+ port_def_type.format.video.pNativeWindow = egl_display;
+ error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition,
+ &port_def_type);
+ if (error != OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "Set OMX_IndexParamPortDefinition3 failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+
+
+
+
+
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 7");
+ video->WaitForEvent(omx_egl_render,OMX_EventPortSettingsChanged);
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 8");
+
+ error=OMX_SendCommand(omx_egl_render/*dec*/,OMX_CommandPortEnable,omx_egl_output_port/*codec*/,0);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Prepare omx_egl_output_port Send Command to enable port %x", error);
+ return 0;
+ }
+
+ OMX_BUFFERHEADERTYPE *buf_head_egl=NULL;
+ error=OMX_UseEGLImage(omx_egl_render/*dec*/,&buf_head_egl,omx_egl_output_port/*codec*/, this, pictInf.reference);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_UseEGLImage failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+ buf_head_egl->pAppPrivate=this;
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 8 a");
+
+
+
+
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 8 end");
+
+ video->EnablePort(omx_imag_decode,omx_image_output_port,false);
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 9");
+ //video->EnablePort(omx_egl_render,omx_egl_output_port,false);
+
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture 10");
+
+ omx_egl_filled = false;
+ error = OMX_FillThisBuffer(omx_egl_render, buf_head_egl);
+
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_FillThisBuffer failed %x", error);
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+ count =1;
+ video->UnlockClock();
+ while (!omx_egl_filled) {
+
+ count++;
+ if (count>100) {
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ Log::getInstance()->log("Image", Log::DEBUG, "No one filled my buffer");
+ return false;
+ }
+ MILLISLEEP(10);
+
+
+ }
+ omx_egl_filled = false;
+ video->LockClock();
+
+ error=OMX_FreeBuffer(omx_egl_render/*dec*/, omx_egl_output_port/*codec*/,buf_head_egl);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_FreeBuffer 2 failed %x", error);
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ return false;
+ }
+
+
+
+ video->UnlockClock();
+ pthread_setcancelstate(oldcancelstate, NULL);
+ pthread_setcanceltype(oldcanceltype, NULL);
+ Log::getInstance()->log("Image", Log::DEBUG,
+ "decodePicture left");
+
+ pictInfValid=true;
+ return true;
+
+}
+
+bool ImageOMX::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
+{
+ if (!pictInfValid) return false;
+ pict_inf=pictInf;
+ pictInfValid = false;
+ return true;
+}
+
+void ImageOMX::freeReference(void * ref)
+{
+
+}
+
+
+int ImageOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex
+{
+ VideoOMX *video=(VideoOMX*)Video::getInstance();
+ OMX_ERRORTYPE error;
+ OMX_PARAM_PORTDEFINITIONTYPE port_def_type;
+ memset(&port_def_type,0,sizeof(port_def_type));
+ port_def_type.nSize=sizeof(port_def_type);
+ port_def_type.nVersion.nVersion=OMX_VERSION;
+ port_def_type.nPortIndex=omx_image_input_port;//omx_codec_input_port;
+
+ error=OMX_GetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
+
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Get OMX OMX_IndexParamPortDefinition failed %x", error);
+ }
+
+
+ if (setportdef) {
+ port_def_type.nBufferCountActual=10;
+ port_def_type.nBufferSize=max(port_def_type.nBufferSize,1000000); // for transcoder important
+
+ error=OMX_SetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type);
+
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Set OMX OMX_IndexParamPortDefinition failed %x", error);
+ }
+ }
+
+
+ error=OMX_SendCommand(omx_imag_decode/*dec*/,OMX_CommandPortEnable,omx_image_input_port/*codec*/,0);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Prepare Input bufs Send Command to enable port %x", error);
+ return 0;
+ }
+
+ input_bufs_omx_mutex.Lock();
+ for (unsigned int i=0; i< port_def_type.nBufferCountActual;i++) {
+ OMX_BUFFERHEADERTYPE *buf_head=NULL;
+ error=OMX_UseBuffer(omx_imag_decode/*dec*/,&buf_head,omx_image_input_port/*codec*/,this,port_def_type.nBufferSize, NULL);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_UseBuffer failed %x", error);
+ input_bufs_omx_mutex.Unlock();
+ return 0;
+ }
+ input_bufs_omx_all.push_back(buf_head);
+ input_bufs_omx_free.push_back(buf_head);
+ }
+ omx_first_frame=true;
+
+
+ input_bufs_omx_mutex.Unlock();
+
+ if (!video->CommandFinished(omx_imag_decode/*dec*/,OMX_CommandPortEnable, omx_image_input_port /*codec*/)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int ImageOMX::DestroyInputBufsOMX() //call with clock mutex locked
+{
+ OMX_ERRORTYPE error;
+
+ input_bufs_omx_mutex.Lock();
+ for (int i=0; i< input_bufs_omx_all.size();i++) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_FreeBuffer mark");
+ if (input_bufs_omx_all[i]->pBuffer) free(input_bufs_omx_all[i]->pBuffer);
+ error=OMX_FreeBuffer(omx_imag_decode/*dec*/,omx_image_input_port/*codec*/,input_bufs_omx_all[i]);
+ if (error!=OMX_ErrorNone){
+ Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_FreeBuffer failed %x", error);
+ input_bufs_omx_mutex.Unlock();
+ return 0;
+ }
+
+ }
+ input_bufs_omx_all.clear();
+ input_bufs_omx_free.clear();
+ input_bufs_omx_mutex.Unlock();
+
+}
+
+int ImageOMX::DestroyInputBufsOMXwhilePlaying() //call with clock mutex locked
+{
+ OMX_ERRORTYPE error;
+
+ input_bufs_omx_mutex.Lock();
+ while (input_bufs_omx_all.size()>0) {
+ if (input_bufs_omx_free.size()>0) {
+ // Destroy one buffer
+ vector<OMX_BUFFERHEADERTYPE*>::iterator itty=input_bufs_omx_all.begin();
+ OMX_BUFFERHEADERTYPE* cur_buf=input_bufs_omx_free.front();
+ for (; itty!= input_bufs_omx_all.end();itty++) {
+ if ((*itty)==cur_buf) {
+ input_bufs_omx_all.erase(itty);
+ input_bufs_omx_free.pop_front();
+ break;
+ }
+ }
+ } else {
+ input_bufs_omx_mutex.Unlock();
+ MILLISLEEP(5);
+ input_bufs_omx_mutex.Lock();
+ }
+ }
+
+ Log::getInstance()->log("Image", Log::DEBUG, "DestroyInputBufsOMXwhilePlaying %d %d", input_bufs_omx_all.size(),input_bufs_omx_free.size());
+ input_bufs_omx_mutex.Unlock();
+ return 1;
+}
+
+
+int ImageOMX::DeAllocateCodecsOMX()
+{
+ OMX_ERRORTYPE error;
+ omx_running=false;
+ VideoOMX *video=(VideoOMX*)Video::getInstance();
+ Log::getInstance()->log("Image", Log::DEBUG, "enter deallocatecodecsomx");
+
+
+
+ Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 1");
+
+ Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 2");
+
+ video->LockClock();
+ if (omx_imag_decode/*dec*/) {
+
+
+ if (!video->ChangeComponentState(omx_imag_decode,OMX_StateIdle)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "omx_imag_decode ChangeComponentState");
+ }
+
+ if (!video->ChangeComponentState(omx_egl_render,OMX_StateIdle)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_render ChangeComponentState");
+ }
+
+ // TODO proper deinit sequence
+ // first flush all buffers
+
+ error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_input_port, NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
+
+ }
+
+ error=OMX_SendCommand(omx_imag_decode,OMX_CommandFlush, omx_image_output_port, NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
+
+ }
+
+ error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_input_port, NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
+
+ }
+
+ error=OMX_SendCommand(omx_egl_render,OMX_CommandFlush, omx_egl_output_port, NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Flush rend in failed %x", error);
+
+ }
+
+
+
+
+ Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 6");
+
+ if (!video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_input_port) ||
+ !video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_input_port) ||
+ !video->CommandFinished(omx_imag_decode,OMX_CommandFlush,omx_image_output_port) ||
+ !video->CommandFinished(omx_egl_render,OMX_CommandFlush,omx_egl_output_port)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "flush cmd clock shed failed");
+ }
+
+
+ DestroyInputBufsOMX(); //We have to make sure that no buffers are in use
+
+ Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 7");
+
+ //todo flushing
+ if (!video->DisablePort(omx_imag_decode,omx_image_output_port,true)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Disable Tunnel Port failed 1");
+ }
+
+
+ if (!video->DisablePort(omx_egl_render,omx_egl_input_port,true)) {
+ Log::getInstance()->log("Image", Log::DEBUG, "Disable Tunnel Port failed 4");
+ }
+
+
+
+
+ error=OMX_SetupTunnel(omx_imag_decode,omx_image_output_port,NULL,NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
+
+ }
+
+ error=OMX_SetupTunnel(omx_egl_render,omx_egl_input_port,NULL,NULL);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "OMX_Setup tunnel teardown failed %x", error);
+
+ }
+
+
+ Log::getInstance()->log("Image", Log::DEBUG, "deallocatecodecsomx mark 8");
+
+
+ //error=OMX_FreeHandle(omx_aud_dec);
+ error=OMX_FreeHandle(omx_imag_decode);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "FreeHandle failed %d", error);
+ }
+ error=OMX_FreeHandle(omx_egl_render);
+ if (error!=OMX_ErrorNone) {
+ Log::getInstance()->log("Image", Log::DEBUG, "FreeHandle failed %d", error);
+ }
+ video->UnlockClock();
+
+ omx_imag_decode/*dec*/=NULL;
+ omx_egl_render/*dec*/=NULL;
+
+ } else {
+
+ video->UnlockClock();
+ }
+ Log::getInstance()->log("Image", Log::DEBUG, "leave deallocate codecs OMX");
+
+ return 1;
+}