]> git.vomp.tv Git - vompclient.git/commitdiff
Add files missing in last commit, is still not working
authorMarten Richter <marten.richter@freenet.de>
Sun, 27 Jul 2014 18:15:18 +0000 (20:15 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 27 Jul 2014 18:15:18 +0000 (20:15 +0200)
imageomx.cc [new file with mode: 0644]
imageomx.h [new file with mode: 0644]

diff --git a/imageomx.cc b/imageomx.cc
new file mode 100644 (file)
index 0000000..d3c57a0
--- /dev/null
@@ -0,0 +1,859 @@
+/*
+    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;
+}
diff --git a/imageomx.h b/imageomx.h
new file mode 100644 (file)
index 0000000..31e0da7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+    Copyright 2004-2005 Chris Tallon, 2009,2012, 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.
+*/
+
+#ifndef IMAGEOMX_H
+#define IMAGEOMX_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "defines.h"
+#include "osdvector.h"
+#include "videoomx.h"
+
+
+class EGLPictureCreator {
+public:
+       virtual bool getEGLPicture(struct OsdVector::PictureInfo & info, EGLDisplay * display ) = 0;
+};
+
+
+
+class ImageOMX : public OsdVector::PictureDecoder
+{
+  friend class VideoOMX;
+  public:
+    ImageOMX(OsdVector::PictureReader * treader);
+    virtual ~ImageOMX();
+
+    void init();
+    void shutdown();
+
+    bool decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length);
+    bool getDecodedPicture(struct OsdVector::PictureInfo& pict_inf);
+    void freeReference(void * ref);
+
+  private:
+
+    static OMX_ERRORTYPE EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);
+       static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver);
+
+
+    void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver);
+    void ReturnFillOMXBuffer(OMX_BUFFERHEADERTYPE* buffer);
+
+
+       OMX_HANDLETYPE omx_imag_decode;
+       OMX_HANDLETYPE omx_egl_render;
+
+       OMX_U32 omx_image_input_port;
+       OMX_U32 omx_image_output_port;
+
+       OMX_U32 omx_egl_input_port;
+       OMX_U32 omx_egl_output_port;
+
+
+       int AllocateCodecsOMX();
+       int DeAllocateCodecsOMX();
+
+       int PrepareInputBufsOMX(bool setportdef);
+       int DestroyInputBufsOMX();
+       int DestroyInputBufsOMXwhilePlaying();
+
+
+
+       vector<OMX_BUFFERHEADERTYPE*> input_bufs_omx_all;
+       list<OMX_BUFFERHEADERTYPE*> input_bufs_omx_free;
+       //list<OMX_BUFFERHEADERTYPE*> output_bufs_omx_full;
+       Mutex input_bufs_omx_mutex;
+
+    bool omx_running;
+    bool omx_first_frame;
+    bool omx_egl_filled;
+
+    int initted;
+
+  protected:
+      OsdVector::PictureInfo pictInf;
+         bool pictInfValid;
+
+};
+
+#endif