]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Flush/Reset video decoder pipeline, in case decoder has stalled buffers
authorMarten Richter <marten.richter@freenet.de>
Sun, 28 Jul 2013 10:00:47 +0000 (12:00 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 28 Jul 2013 10:00:47 +0000 (12:00 +0200)
videoomx.cc
videoomx.h

index 7a56cc06025db322e975d9d17dae17f340b93782..fd8a1335f43df9d1b8a2dcc56311ce365f18ce5b 100644 (file)
@@ -46,6 +46,8 @@ VideoOMX::VideoOMX() {
        omx_h264 = omx_mpeg2 = true;
        clock_references = 0;
 
+       omx_vid_stalled = false;
+
        offsetnotset = true;
        offsetvideonotset = true;
        offsetaudionotset = true;
@@ -167,7 +169,7 @@ void VideoOMX::AddOmxEvent(VPE_OMX_EVENT  new_event)
 
 OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer){
 
-       //Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
+//     Log::getInstance()->log("Video", Log::NOTICE, "EmptyBufferDone");
        VideoOMX *video=(VideoOMX *)getInstance();
 /*     long long temp =buffer->nTimeStamp.nLowPart
                                                                | ((long long) buffer->nTimeStamp.nHighPart << 32);
@@ -179,14 +181,14 @@ OMX_ERRORTYPE VideoOMX::EmptyBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp,OMX_IN O
 
 void VideoOMX::ReturnEmptyOMXBuffer(OMX_BUFFERHEADERTYPE* buffer){
        input_bufs_omx_mutex.Lock();
-       //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d %d",input_bufs_omx_free.size(),input_bufs_omx_present.size(),input_bufs_omx_all.size());
+       //Log::getInstance()->log("Video", Log::NOTICE, "ReturnEmptyOMXBuffer %d %d",input_bufs_omx_free.size(),input_bufs_omx_all.size());
        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_ERRORTYPE VideoOMX::FillBufferDone_OMX(OMX_IN OMX_HANDLETYPE hcomp, OMX_IN OMX_PTR appdata,OMX_IN OMX_BUFFERHEADERTYPE* buffer) {
-        Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
+        //Log::getInstance()->log("Video", Log::NOTICE, "FillBufferDone");
        return OMX_ErrorNone;
 }
 
@@ -1276,6 +1278,37 @@ int VideoOMX::AllocateCodecsOMX()
                return 0;
        }
 
+       OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
+       memset(&stall_conf,0,sizeof(stall_conf));
+       stall_conf.nSize=sizeof(stall_conf);
+       stall_conf.nVersion.nVersion=OMX_VERSION;
+       stall_conf.nPortIndex=omx_codec_output_port;
+       stall_conf.nDelay=1500*1000;
+       error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
+       if (error!=OMX_ErrorNone){
+               Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigBufferStall failed %x", error);
+               clock_mutex.Unlock();
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+       omx_vid_stalled = false;
+
+       OMX_CONFIG_REQUESTCALLBACKTYPE req_callback;
+       memset(&req_callback,0,sizeof(req_callback));
+       req_callback.nSize=sizeof(req_callback);
+       req_callback.nVersion.nVersion=OMX_VERSION;
+       req_callback.nPortIndex=omx_codec_output_port;
+       req_callback.nIndex=OMX_IndexConfigBufferStall;
+       req_callback.bEnable=OMX_TRUE;
+       error=OMX_SetConfig(omx_vid_dec,OMX_IndexConfigRequestCallback,&req_callback);
+       if (error!=OMX_ErrorNone){
+               Log::getInstance()->log("Video", Log::DEBUG, "Init OMX_IndexConfigRequestCallback  failed %x", error);
+               clock_mutex.Unlock();
+               DeAllocateCodecsOMX();
+               return 0;
+       }
+
+
 
        if (!PrepareInputBufsOMX()) {
                clock_mutex.Unlock();
@@ -1698,6 +1731,48 @@ int VideoOMX::clearEvents()
        return 1;
 }
 
+void VideoOMX::checkForStalledBuffers()
+{
+       //Log::getInstance()->log("Video", Log::DEBUG, "Check stalled");
+       omx_event_mutex.Lock();
+       list<VPE_OMX_EVENT>::iterator itty=omx_events.begin();
+       while (itty!=omx_events.end()) {
+               VPE_OMX_EVENT current=*itty;
+               if (current.event_type==OMX_EventParamOrConfigChanged && current.data1==omx_codec_output_port
+                               && current.handle==omx_vid_dec && current.data2==OMX_IndexConfigBufferStall) {
+                       OMX_ERRORTYPE error;
+                       OMX_CONFIG_BUFFERSTALLTYPE stall_conf;
+                       memset(&stall_conf,0,sizeof(stall_conf));
+                       stall_conf.nSize=sizeof(stall_conf);
+                       stall_conf.nVersion.nVersion=OMX_VERSION;
+                       stall_conf.nPortIndex=omx_codec_output_port;
+                       stall_conf.nDelay=200000;
+                       clock_mutex.Lock();
+                       error=OMX_GetConfig(omx_vid_dec,OMX_IndexConfigBufferStall,&stall_conf);
+                       if (error!=OMX_ErrorNone){
+                                       Log::getInstance()->log("Video", Log::DEBUG, "Get OMX_IndexConfigBufferStall failed %x", error);
+                                       clock_mutex.Unlock();
+                                       omx_event_mutex.Unlock();
+                                       return ;
+                               }
+                       clock_mutex.Unlock();
+                       if (stall_conf.bStalled==OMX_TRUE) {
+                               omx_vid_stalled=true;
+                               Log::getInstance()->log("Video", Log::DEBUG, "Video decoder stalled! %d", stall_conf.nDelay);
+                       } else {
+                               omx_vid_stalled=false;
+                               Log::getInstance()->log("Video", Log::DEBUG, "Video decoder unstalled! %d",stall_conf.nDelay);
+                       }
+                       omx_events.erase(itty);
+                       break;
+               }
+               itty++;
+       }
+       omx_event_mutex.Unlock();
+}
+
+
+
 
 int VideoOMX::CommandFinished(OMX_HANDLETYPE handle,OMX_U32 command,OMX_U32 data2) //needs to be called with locked mutex
 {
@@ -1756,7 +1831,7 @@ int VideoOMX::PrepareInputBufsOMX() //needs to be called with locked mutex
                        port_def_type.bBuffersContiguous,port_def_type.nBufferAlignment);*/
 
        port_def_type.nBufferCountActual=100;
-       port_def_type.nBufferSize=max(port_def_type.nBufferSize,200000); // for transcoder important
+       port_def_type.nBufferSize=max(port_def_type.nBufferSize,150000); // for transcoder important
 
        error=OMX_SetParameter(omx_vid_dec,OMX_IndexParamPortDefinition, &port_def_type);
 
@@ -1831,6 +1906,7 @@ int VideoOMX::DestroyInputBufsOMX() //need s to be called with locked mutex
 }
 
 
+
 int VideoOMX::FlushRenderingPipe()
 {
        OMX_ERRORTYPE error;
@@ -2667,6 +2743,15 @@ bool VideoOMX::DrainTargetBufferFull()
        input_bufs_omx_mutex.Lock();
        full=(input_bufs_omx_free.size()==0);
        input_bufs_omx_mutex.Unlock();
+       checkForStalledBuffers(); // check if the decoder has a problem
+       if (full && omx_vid_stalled && !omx_first_frame) {
+               omx_vid_stalled=false;
+               Log::getInstance()->log("Video", Log::DEBUG, "Decoder is stalled, do a reset!");
+               clock_mutex.Lock();
+               FlushRenderingPipe();
+               omx_first_frame=true;
+               clock_mutex.Unlock();
+       }
        return full;
 
 }
@@ -2718,12 +2803,14 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
 
 
        if (!omx_running) return 0; // if we are not runnig do not do this
+
        if (isClockPaused()) return 0; //Block if we pause
 
 //     Log::getInstance()->log("Video", Log::DEBUG, "DMP mark 1");
        //Log::getInstance()->log("Video", Log::DEBUG, "DeliverMediaPacketOMX time %lld",packet.presentation_time);
 
 
+
        OMX_ERRORTYPE error;
 
        /*First Check, if we have an video sample*/
index 400b084edd40d510de3c046164438691a810ad03..66a901c94cc7fd0763bb42331be839471a128e5e 100644 (file)
@@ -206,6 +206,7 @@ class VideoOMX : public Video
           int EnablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait);
           int DisablePort(OMX_HANDLETYPE handle,OMX_U32 port,bool wait=true);
           int clearEvents();
+          void checkForStalledBuffers();
 
 
        int setClockExecutingandRunning();
@@ -249,6 +250,9 @@ class VideoOMX : public Video
           OMX_U32 omx_shed_clock_port;
           OMX_U32 omx_clock_output_port;
         //  OMX_NALUFORMATSTYPE omx_nalu_format;
+          bool omx_vid_stalled;
+
+