From 5adb551bfcf5a043a7ab22b38b992c83a11d81f4 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Thu, 31 Jul 2014 16:01:04 +0200 Subject: [PATCH] Optimizations in OMX handling towards accelerated image decoding, not working, but no crashes --- audioomx.cc | 4 ++ imageomx.cc | 132 ++++++++++++++++++++++++++++++--------------------- imageomx.h | 6 ++- objects.mk | 2 +- osdopenvg.cc | 11 ++--- osdopenvg.h | 4 +- signal.cc | 80 +++++++++++++++++++++++++++++++ signal.h | 53 +++++++++++++++++++++ videoomx.cc | 14 ++++-- videoomx.h | 19 ++++++-- 10 files changed, 249 insertions(+), 76 deletions(-) create mode 100644 signal.cc create mode 100644 signal.h diff --git a/audioomx.cc b/audioomx.cc index 5653b5e..ef54b81 100644 --- a/audioomx.cc +++ b/audioomx.cc @@ -505,10 +505,14 @@ void AudioOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){ input_bufs_omx_free.push_back(buffer); //Log::getInstance()->log("Audio", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size()); input_bufs_omx_mutex.Unlock(); + VideoOMX *video=(VideoOMX*)Video::getInstance(); + video->signalOmx(); } OMX_ERRORTYPE AudioOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) { Log::getInstance()->log("Audio", Log::NOTICE, "FillBufferDone"); + VideoOMX *video=(VideoOMX*)Video::getInstance(); + video->signalOmx(); return OMX_ErrorNone; } diff --git a/imageomx.cc b/imageomx.cc index d3c57a0..d82599d 100644 --- a/imageomx.cc +++ b/imageomx.cc @@ -42,13 +42,13 @@ ImageOMX::~ImageOMX() void ImageOMX::init() { - AllocateCodecsOMX(); + // AllocateCodecsOMX(); } void ImageOMX::shutdown() { Log::getInstance()->log("ImageOMX", Log::DEBUG, "shutdown"); - DeAllocateCodecsOMX(); + //DeAllocateCodecsOMX(); } @@ -66,15 +66,17 @@ OMX_ERRORTYPE ImageOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN O void ImageOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){ input_bufs_omx_mutex.Lock(); - if (buffer->pBuffer) { + /*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(); + VideoOMX *video=(VideoOMX*)Video::getInstance(); + video->signalOmx(); } OMX_ERRORTYPE ImageOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) { @@ -89,6 +91,8 @@ void ImageOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){ omx_egl_filled = true; //output_bufs_omx_full.push_back(buffer); //input_bufs_omx_mutex.Unlock(); + VideoOMX *video=(VideoOMX*)Video::getInstance(); + video->signalOmx(); } @@ -112,7 +116,7 @@ int ImageOMX::play() { -int ImageOMX::AllocateCodecsOMX() +int ImageOMX::AllocateCodecsOMX(unsigned char * buffer, unsigned int length) { OMX_ERRORTYPE error; static OMX_CALLBACKTYPE callbacks= {&VideoOMX::EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; @@ -262,7 +266,7 @@ int ImageOMX::AllocateCodecsOMX() - if (!PrepareInputBufsOMX(true)) { + if (!PrepareInputBufsOMX(true, buffer, length)) { video->UnlockClock(); Log::getInstance()->log("Image", Log::DEBUG, "prepare input bufs failed"); DeAllocateCodecsOMX(); @@ -304,12 +308,7 @@ int ImageOMX::AllocateCodecsOMX() } - 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) ) { @@ -347,6 +346,30 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i if (!pictcreat) return false; + int oldcancelstate; + int oldcanceltype; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype); + + if (!AllocateCodecsOMX(buffer,length)) { + DeAllocateCodecsOMX(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + return false; + } + bool ret=intDecodePicture(index, buffer, length, pictcreat, video); + DeAllocateCodecsOMX(); + pthread_setcancelstate(oldcancelstate, NULL); + pthread_setcanceltype(oldcanceltype, NULL); + if (ret) free(buffer); + + return ret; +} + + +bool ImageOMX::intDecodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, EGLPictureCreator* pictcreat, VideoOMX *video) +{ + // Use Buffer OMX_BUFFERHEADERTYPE * bufhead; @@ -368,22 +391,20 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i } bufhead=input_bufs_omx_free.front(); bufhead->nFilledLen=length; - bufhead->nAllocLen= length; + //bufhead->nAllocLen= length; bufhead->nOffset=0; bufhead->nTimeStamp=VideoOMX::intToOMXTicks(0); - bufhead->pBuffer=buffer; + //bufhead->pBuffer=buffer; bufhead->pAppPrivate=this; input_bufs_omx_free.pop_front(); input_bufs_omx_mutex.Unlock(); - bufhead->nFilledLen=bufhead->nAllocLen; + bufhead->nFilledLen=length;//bufhead->nAllocLen; + bufhead->nFlags=OMX_BUFFERFLAG_EOS; 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, @@ -398,14 +419,14 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i port_def_type.nSize=sizeof(port_def_type); port_def_type.nVersion.nVersion=OMX_VERSION; port_def_type.nPortIndex=omx_image_output_port; + Log::getInstance()->log("Image", Log::DEBUG, + "decodePicture 3a"); 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, @@ -418,27 +439,30 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i 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"); + "decodePicture 4 a"); + video->DisablePort(omx_imag_decode,omx_image_output_port,false); Log::getInstance()->log("Image", Log::DEBUG, "decodePicture 5"); + video->DisablePort(omx_egl_render,omx_egl_input_port,false); + Log::getInstance()->log("Image", Log::DEBUG, + "decodePicture 6"); + - 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; + return false; + } + + if ( !video->CommandFinished(omx_egl_render,OMX_CommandPortDisable,omx_egl_input_port)) { + video->UnlockClock(); + Log::getInstance()->log("Image", Log::DEBUG, "commandfinishes end eip"); + return false; } port_def_type.format.image.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; @@ -450,8 +474,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "Set OMX_IndexParamPortDefinition1 failed %x", error); video->UnlockClock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); return false; } @@ -486,8 +508,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "OMX_IndexParamPortDefinition fix failed %x", error); video->UnlockClock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); return false; } @@ -499,10 +519,10 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "getEGLPict failed"); video->UnlockClock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); return false; } + Log::getInstance()->log("Image", Log::DEBUG, + "getEGLPict %x",pictInf.reference); port_def_type.format.video.pNativeWindow = egl_display; error = OMX_SetParameter(omx_egl_render, OMX_IndexParamPortDefinition, @@ -511,8 +531,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "Set OMX_IndexParamPortDefinition3 failed %x", error); video->UnlockClock(); - pthread_setcancelstate(oldcancelstate, NULL); - pthread_setcanceltype(oldcanceltype, NULL); return false; } @@ -539,8 +557,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i 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; @@ -548,6 +564,12 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "decodePicture 8 a"); + video->EnablePort(omx_imag_decode,omx_image_output_port,false); + + if (!video->CommandFinished(omx_egl_render/*dec*/,OMX_CommandPortEnable, omx_egl_output_port /*codec*/)) { + video->UnlockClock(); + return false; + } @@ -555,7 +577,13 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i Log::getInstance()->log("Image", Log::DEBUG, "decodePicture 8 end"); - video->EnablePort(omx_imag_decode,omx_image_output_port,false); + if (!video->ChangeComponentState(omx_egl_render,OMX_StateExecuting)) { + Log::getInstance()->log("Image", Log::DEBUG, "omx_egl_rendd ChangeComponentState Execute"); + video->UnlockClock(); + return false; + } + + Log::getInstance()->log("Image", Log::DEBUG, "decodePicture 9"); //video->EnablePort(omx_egl_render,omx_egl_output_port,false); @@ -569,8 +597,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i 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; @@ -579,8 +605,6 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i 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; } @@ -594,19 +618,16 @@ bool ImageOMX::decodePicture(LoadIndex index, unsigned char * buffer, unsigned i 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"); + DeAllocateCodecsOMX(); pictInfValid=true; return true; @@ -626,7 +647,7 @@ void ImageOMX::freeReference(void * ref) } -int ImageOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with locvke omx clock mutex +int ImageOMX::PrepareInputBufsOMX(bool setportdef, unsigned char * buffer, unsigned int length) //needs to be called with locvke omx clock mutex { VideoOMX *video=(VideoOMX*)Video::getInstance(); OMX_ERRORTYPE error; @@ -644,8 +665,8 @@ int ImageOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with loc if (setportdef) { - port_def_type.nBufferCountActual=10; - port_def_type.nBufferSize=max(port_def_type.nBufferSize,1000000); // for transcoder important + port_def_type.nBufferCountActual=port_def_type.nBufferCountMin; + port_def_type.nBufferSize=max(port_def_type.nBufferSize,length); // for transcoder important error=OMX_SetParameter(omx_imag_decode/*dec*/,OMX_IndexParamPortDefinition, &port_def_type); @@ -664,7 +685,7 @@ int ImageOMX::PrepareInputBufsOMX(bool setportdef) //needs to be called with loc 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); + error=OMX_UseBuffer(omx_imag_decode/*dec*/,&buf_head,omx_image_input_port/*codec*/,this,port_def_type.nBufferSize, buffer); if (error!=OMX_ErrorNone){ Log::getInstance()->log("Image", Log::DEBUG, "Use OMX_UseBuffer failed %x", error); input_bufs_omx_mutex.Unlock(); @@ -692,7 +713,8 @@ int ImageOMX::DestroyInputBufsOMX() //call with clock mutex locked 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); + //if (input_bufs_omx_all[i]->pBuffer) free(input_bufs_omx_all[i]->pBuffer); + input_bufs_omx_all[i]->pBuffer=NULL; 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); diff --git a/imageomx.h b/imageomx.h index 31e0da7..292ead1 100644 --- a/imageomx.h +++ b/imageomx.h @@ -61,6 +61,8 @@ class ImageOMX : public OsdVector::PictureDecoder static OMX_ERRORTYPE FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* bulibaver); + bool intDecodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, EGLPictureCreator* egl_pict, VideoOMX *video); + void ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* bulibaver); void ReturnFillOMXBuffer(OMX_BUFFERHEADERTYPE* buffer); @@ -75,10 +77,10 @@ class ImageOMX : public OsdVector::PictureDecoder OMX_U32 omx_egl_output_port; - int AllocateCodecsOMX(); + int AllocateCodecsOMX( unsigned char * buffer, unsigned int length); int DeAllocateCodecsOMX(); - int PrepareInputBufsOMX(bool setportdef); + int PrepareInputBufsOMX(bool setportdef, unsigned char * buffer, unsigned int length); int DestroyInputBufsOMX(); int DestroyInputBufsOMXwhilePlaying(); diff --git a/objects.mk b/objects.mk index e27f749..992ed97 100644 --- a/objects.mk +++ b/objects.mk @@ -1,5 +1,5 @@ OBJECTS1 = command.o tcp.o dsock.o thread.o timers.o i18n.o \ - message.o messagequeue.o udp.o wol.o audio.o video.o log.o mutex.o \ + message.o messagequeue.o udp.o wol.o audio.o video.o log.o mutex.o signal.o \ vdr.o recman.o recording.o recinfo.o channel.o rectimer.o event.o \ directory.o mark.o option.o \ player.o playerradio.o vfeed.o afeed.o \ diff --git a/osdopenvg.cc b/osdopenvg.cc index ece11cd..9868bf5 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -294,8 +294,7 @@ int OsdOpenVG::init(void* device) }*/ InitializeMagick(""); - pthread_cond_init(&vgtaskCond, NULL); - pthread_mutex_init(&vgtaskCondMutex, NULL); + threadStart(); taskmutex.Unlock(); @@ -1232,9 +1231,7 @@ bool OsdOpenVG::processTasks() taskmutex.Unlock(); vgmutex.Unlock(); //threadCheckExit(); - pthread_mutex_lock(&vgtaskCondMutex); - pthread_cond_signal(&vgtaskCond); - pthread_mutex_unlock(&vgtaskCondMutex); + vgtaskSignal.signal(); taskmutex.Lock(); vgmutex.Lock(); worked=true; @@ -1288,9 +1285,7 @@ unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm,bool wait) target_time.tv_nsec-=1000000000L; target_time.tv_sec+=1; } - pthread_mutex_lock(&vgtaskCondMutex); - pthread_cond_timedwait(&vgtaskCond, &vgtaskCondMutex,&target_time); - pthread_mutex_unlock(&vgtaskCondMutex); + vgtaskSignal.waitForSignalTimed(&target_time); } else { return resp; } diff --git a/osdopenvg.h b/osdopenvg.h index ff657f3..bc472c7 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -36,6 +36,7 @@ #include "log.h" #include "threadp.h" #include "mutex.h" +#include "signal.h" #include "videoomx.h" #ifdef PICTURE_DECODER_OMX #include "imageomx.h" @@ -128,8 +129,7 @@ protected: Mutex vgmutex; Mutex taskmutex; - pthread_cond_t vgtaskCond; - pthread_mutex_t vgtaskCondMutex; + Signal vgtaskSignal; deque vgcommands; deque vgresponses; bool processTasks(); diff --git a/signal.cc b/signal.cc new file mode 100644 index 0000000..3479cc9 --- /dev/null +++ b/signal.cc @@ -0,0 +1,80 @@ +/* + Copyright 2004-2005 Chris Tallon + + 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 "signal.h" + + +Signal::Signal() +{ + pthread_cond_init(&cond, NULL); + pthread_mutex_init(&condMutex, NULL); +} + +Signal::~Signal() +{ + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&condMutex); +} + + + +void Signal::signal() +{ +#ifndef WIN32 + pthread_mutex_lock(&condMutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&condMutex); +#else +#error "Not ported yet" +#endif +} + +void Signal::waitForSignal() +{ +#ifndef WIN32 + pthread_mutex_lock(&condMutex); + pthread_cond_wait(&cond, &condMutex); + pthread_mutex_unlock(&condMutex); +#else +#error "Not ported yet" +#endif +} + +void Signal::waitForSignalTimed(struct timespec* ts) +{ +#ifndef WIN32 + pthread_mutex_lock(&condMutex); + pthread_cond_timedwait(&cond, &condMutex, ts); + pthread_mutex_unlock(&condMutex); +#else +#error "Not ported yet" +#endif +} + +void Signal::waitForSignalTimed(unsigned int ts) +{ + struct timespec target_time; + clock_gettime(CLOCK_REALTIME,&target_time); + target_time.tv_nsec+=1000000LL*ts; + if (target_time.tv_nsec>999999999) { + target_time.tv_nsec-=1000000000L; + target_time.tv_sec+=1; + } + waitForSignalTimed(&target_time); +} diff --git a/signal.h b/signal.h new file mode 100644 index 0000000..dd98d93 --- /dev/null +++ b/signal.h @@ -0,0 +1,53 @@ +/* + Copyright 2004-2005 Chris Tallon + + 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 SIGNAL_H +#define SIGNAL_H + +#ifndef WIN32 +#include +#include +#else +#include +#include +#endif + + +class Signal { +public: + Signal(); + ~Signal(); + void signal(); // releases a thread that has called threadWaitForSignal + void waitForSignal(); // pauses thread until dignal() is called + void waitForSignalTimed(struct timespec*); // pauses thread until signal() is called or timer expires + void waitForSignalTimed(unsigned int ts); + +protected: +#ifndef WIN32 + pthread_cond_t cond; + pthread_mutex_t condMutex; +#else +#error "Not ported yet" +#endif + +}; + + +#endif diff --git a/videoomx.cc b/videoomx.cc index 33ce840..b23b4d1 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -164,6 +164,7 @@ void VideoOMX::AddOmxEvent(VPE_OMX_EVENT new_event) omx_event_mutex.Lock(); omx_events.push_back(new_event); omx_event_mutex.Unlock(); + omx_event_ready_signal.signal(); } @@ -185,6 +186,7 @@ void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){ input_bufs_omx_free.push_back(buffer); //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d",input_bufs_omx_free.size()); input_bufs_omx_mutex.Unlock(); + omx_event_ready_signal.signal(); } OMX_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) { @@ -775,7 +777,9 @@ int VideoOMX::initClock() { static OMX_CALLBACKTYPE callbacks= {&EventHandler_OMX,&EmptyBufferDone_OMX,&FillBufferDone_OMX}; + omx_event_mutex.Lock(); omx_events.clear(); + omx_event_mutex.Unlock(); error=OMX_GetHandle(&omx_clock,VPE_OMX_CLOCK,NULL,&callbacks); @@ -1685,7 +1689,7 @@ int VideoOMX::DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait) //needs int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //needs to be called with locked mutex { int i=0; - int iend=wait+1; + int iend=(wait/5+1); while (i::iterator itty=omx_events.begin(); @@ -1710,7 +1714,8 @@ int VideoOMX::WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event, int wait) //need } omx_event_mutex.Unlock(); - MILLISLEEP(2); + omx_event_ready_signal.waitForSignalTimed(10); + //MILLISLEEP(2); i++; } @@ -1774,7 +1779,7 @@ void VideoOMX::checkForStalledBuffers() int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex { int i=0; - while (i<1000) { + while (i<200/*1000*/) { omx_event_mutex.Lock(); list::iterator itty=omx_events.begin(); while (itty!=omx_events.end()) { @@ -1798,7 +1803,8 @@ int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data } omx_event_mutex.Unlock(); - MILLISLEEP(2); + omx_event_ready_signal.waitForSignalTimed(10); + //MILLISLEEP(2); i++; } diff --git a/videoomx.h b/videoomx.h index 6791430..5885e38 100644 --- a/videoomx.h +++ b/videoomx.h @@ -23,6 +23,7 @@ #define VIDEOOMX_H #include "mutex.h" +#include "signal.h" #include @@ -36,10 +37,13 @@ #include #include + #include "defines.h" #include "video.h" #include "threadsystem.h" + + #define OMX_SKIP64BIT #include @@ -203,7 +207,7 @@ class VideoOMX : public Video int ChangeComponentState(OMX_HANDLETYPE handle,OMX_STATETYPE type); int CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2); - int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event,int wait=1000); + int WaitForEvent(OMX_HANDLETYPE handle,OMX_U32 event,int wait=200); int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait); int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true); int clearEvents(); @@ -223,6 +227,8 @@ class VideoOMX : public Video void clockUnpause(); bool isClockPaused() {return clockpaused;}; + void signalOmx() {omx_event_ready_signal.signal();}; + void interlaceSwitch4Demux(); Mutex clock_mutex; //clock mutex is now responsible for all omx stuff @@ -274,6 +280,7 @@ class VideoOMX : public Video bool omx_first_frame; Mutex omx_event_mutex; + Signal omx_event_ready_signal; list omx_events; @@ -292,10 +299,14 @@ class VideoOMX : public Video - bool firstsynched; + bool firstsynched; + + + vector mediapackets; + + + - - vector mediapackets; }; #endif -- 2.39.5