Fix deadlocks, due to thread cancel inside omx_emptythisbuffer
authorMarten Richter <marten.richter@freenet.de>
Sat, 8 Sep 2012 10:35:25 +0000 (12:35 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sat, 8 Sep 2012 10:35:25 +0000 (12:35 +0200)
audioomx.cc
videoomx.cc
videoomx.h

index 2d8ec88ad10c6a9ac01408898b4368cec637d2d7..aa8da5b9d24799dbd70bb234e6ba0d82246c7e20 100644 (file)
@@ -951,11 +951,11 @@ int AudioOMX::DeAllocateCodecsOMX()
         Log::getInstance()->log("Audio", Log::DEBUG, "enter deallocatecodecsomx");
 
 
-   video->LockClock();
+
    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 1");
    if (cur_input_buf_omx) {
                cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
-               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
+               OMX_ERRORTYPE error=video->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,cur_input_buf_omx);
                if (error!=OMX_ErrorNone) {
                        Log::getInstance()->log("Audio", Log::DEBUG, "OMX_EmptyThisBuffer 6 failed %x", error);
                }
@@ -964,6 +964,7 @@ int AudioOMX::DeAllocateCodecsOMX()
        }
    Log::getInstance()->log("Audio", Log::DEBUG, "deallocatecodecsomx mark 2");
 
+   video->LockClock();
        if (omx_aud_rend/*dec*/) {
                // first stop the omx elements
        /*      if (!video->ChangeComponentState(omx_aud_dec,OMX_StateIdle)) {
@@ -1299,7 +1300,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
        if (packet.disconti) {
                firstsynched = false;
                if (cur_input_buf_omx) {
-                       OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_aud_rend/*dec*/,
+                       OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
                                        cur_input_buf_omx);
                        if (error != OMX_ErrorNone) {
                                Log::getInstance()->log("Audio", Log::DEBUG,
@@ -1315,7 +1316,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
                lastAType = packet.type;
 
                if (cur_input_buf_omx) {
-                       OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_aud_rend/*dec*/,
+                       OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
                                        cur_input_buf_omx);
                        if (error != OMX_ErrorNone) {
                                Log::getInstance()->log("Audio", Log::DEBUG,
@@ -1339,7 +1340,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
                if (packet.synched) {
                        if (cur_input_buf_omx) {
                                cur_input_buf_omx->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
-                               OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_aud_rend/*dec*/,
+                               OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
                                                cur_input_buf_omx);
                                if (error != OMX_ErrorNone) {
                                        Log::getInstance()->log("Audio", Log::DEBUG,
@@ -1490,7 +1491,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
                                        // I doubt that this will ever happen
                                        Log::getInstance()->log("Audio", Log::DEBUG,
                                                                                "P 2 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
-                                       OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_aud_rend/*dec*/,
+                                       OMX_ERRORTYPE error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/,
                                                        cur_input_buf_omx);
                                        if (error != OMX_ErrorNone) {
                                                Log::getInstance()->log("Audio", Log::DEBUG,
@@ -1540,7 +1541,7 @@ UINT AudioOMX::DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer,
        if (cur_input_buf_omx->nFilledLen) {
                Log::getInstance()->log("Audio", Log::DEBUG,
                                                                                        "P 3 Time code %lld pts %lld", lastreftimeOMX, packet.pts);
-               error = OMX_EmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
+               error = vw->ProtOMXEmptyThisBuffer(omx_aud_rend/*dec*/, cur_input_buf_omx);
                if (error != OMX_ErrorNone) {
                        Log::getInstance()->log("Audio", Log::DEBUG,
                                        "OMX_EmptyThisBuffer 5 failed %x", error);
index f15779b3096ac34109684cef4eca643339ee26f4..ddd0b55bedc01546e111c81ad4cbf53a395206da 100644 (file)
@@ -1194,17 +1194,17 @@ int VideoOMX::DeAllocateCodecsOMX()
        omx_running=false;
          Log::getInstance()->log("Video", Log::DEBUG, "enter deallocatecodecsomx");
 
-   clock_mutex.Lock();
+
    if (cur_input_buf_omx) {
                cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_EOS;
-               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
+               OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
                if (error!=OMX_ErrorNone) {
                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
                }
 
                cur_input_buf_omx=NULL;//write out old data
        }
-
+   clock_mutex.Lock();
        if (omx_vid_dec) {
                // first stop the omx elements
                if (!ChangeComponentState(omx_vid_dec,OMX_StateIdle)) {
@@ -1680,6 +1680,23 @@ void VideoOMX::AdjustAudioPTS(long long pts)
        //}
 }
 
+OMX_ERRORTYPE VideoOMX::ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer)
+{
+       // protect the call to empty this buffer
+       int oldcancelstate;
+       int oldcanceltype;
+       pthread_testcancel();
+       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldcancelstate);
+       pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldcanceltype);
+       clock_mutex.Lock();
+       OMX_ERRORTYPE ret_val;
+       ret_val=OMX_EmptyThisBuffer(handle,buffer);
+       clock_mutex.Unlock();
+       pthread_setcancelstate(oldcancelstate, NULL);
+       pthread_setcanceltype(oldcanceltype, NULL);
+       pthread_testcancel();
+       return ret_val;
+}
 
 void VideoOMX::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
 {
@@ -1742,7 +1759,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
        if (packet.disconti) {
                firstsynched=false;
                if (cur_input_buf_omx) {
-                       OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
+                       OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
                        if (error!=OMX_ErrorNone){
                                Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
                        }
@@ -1764,7 +1781,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                if ( packet.synched ) {
                        if (cur_input_buf_omx) {
                                cur_input_buf_omx->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;
-                               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
+                               OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
                                if (error!=OMX_ErrorNone){
                                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
                                }
@@ -1842,7 +1859,7 @@ UINT VideoOMX::DeliverMediaPacket(MediaPacket packet,
                *samplepos+=cancopy;
                // push old buffer out
 
-               OMX_ERRORTYPE error=OMX_EmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
+               OMX_ERRORTYPE error=ProtOMXEmptyThisBuffer(omx_vid_dec,cur_input_buf_omx);
                if (error!=OMX_ErrorNone){
                        Log::getInstance()->log("Video", Log::DEBUG, "OMX_EmptyThisBuffer failed %x", error);
                }
@@ -1935,7 +1952,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
 
                                        }
                                        cur_input_buf_omx->nTimeStamp = 0;
-                                       OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
+                                       OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec,
                                                        cur_input_buf_omx);
                                        if (error != OMX_ErrorNone) {
                                                Log::getInstance()->log("Video", Log::DEBUG,
@@ -1995,7 +2012,7 @@ bool VideoOMX::displayIFrame(const UCHAR* buffer, UINT length) {
 
        }
        cur_input_buf_omx->nTimeStamp = 0;
-       OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
+       OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec, cur_input_buf_omx);
        if (error != OMX_ErrorNone) {
                Log::getInstance()->log("Video", Log::DEBUG,
                                "OMX_EmptyThisBuffer failed %x", error);
@@ -2011,8 +2028,10 @@ int VideoOMX::EnterIframePlayback()
 {
        clock_mutex.Lock();
        if (cur_input_buf_omx) {
-               OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_vid_dec,
+               clock_mutex.Unlock();
+               OMX_ERRORTYPE error = ProtOMXEmptyThisBuffer(omx_vid_dec,
                                cur_input_buf_omx);
+               clock_mutex.Lock();
                if (error != OMX_ErrorNone) {
                        Log::getInstance()->log("Video", Log::DEBUG,
                                        "OMX_EmptyThisBuffer failed %x", error);
index b006f88e516dec3259284bfa236b2caabd254750..72c52b9367e96386d4748f8416ae077b96dfd1cb 100644 (file)
@@ -186,6 +186,7 @@ class VideoOMX : public Video
        int getClockVideoandInit();\r
        void LockClock() {clock_mutex.Lock();};\r
        void UnlockClock() {clock_mutex.Unlock();};\r
+       OMX_ERRORTYPE ProtOMXEmptyThisBuffer(OMX_HANDLETYPE handle, OMX_BUFFERHEADERTYPE* buffer);\r
        void clockPause();\r
        void clockUnpause();\r
 \r