[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-datatype-cvs
Subject:    [Datatype-cvs] omx/video/decoder rv20strm.cpp, 1.5, 1.6 rv20strm.h,
From:       sfu () helixcommunity ! org
Date:       2009-05-28 14:33:38
Message-ID: 200905281538.n4SFcOeV030718 () mailer ! progressive-comp ! com
[Download RAW message or body]

Update of /cvsroot/datatype/omx/video/decoder
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv18588

Modified Files:
	rv20strm.cpp rv20strm.h 
Log Message:
implement input data queue to avoid deadlock

Index: rv20strm.h
===================================================================
RCS file: /cvsroot/datatype/omx/video/decoder/rv20strm.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- rv20strm.h	26 May 2009 19:58:16 -0000	1.2
+++ rv20strm.h	28 May 2009 14:33:35 -0000	1.3
@@ -66,6 +66,7 @@
 #include "hlxclib/stdio.h"
 #include "hxcodec.h"
 #include "dllaccesbridge.h"
+#include "hxslist.h"
 
 #define WIDTHBYTES(i)	((unsigned long)((i+31)&(~31))/8)  /* ULONG aligned ! */
 
@@ -153,6 +154,7 @@
     /* OMX CODEC handle */
     COMXVideoDec* m_hDecoder;
     HX_RESULT ProcessOutput(void);
+    HX_RESULT ProcessInput(void);
 
     // whether OMXVStream will use omx decoder allocated decoded frame buffers 
     HXBOOL  m_bHWMEM_MGT;
@@ -166,6 +168,9 @@
     //  CPU scalability variables
     HX_OQS	    m_currentOQS;
     HX_OQS2	    m_currentOQS2;
+    
+    // input data queue
+    CHXSimpleList* m_pInputQueue;
 
 public:
     /* Helix Codec Interface */

Index: rv20strm.cpp
===================================================================
RCS file: /cvsroot/datatype/omx/video/decoder/rv20strm.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- rv20strm.cpp	26 May 2009 19:58:16 -0000	1.5
+++ rv20strm.cpp	28 May 2009 14:33:35 -0000	1.6
@@ -93,7 +93,6 @@
 ENABLE_DLLACCESS_PATHS(omxv);
 #endif	// HELIX_FEATURE_DLLACCESS_CLIENT
 
-
 OMXVDecoder::OMXVDecoder():
 m_uRefCount(0)
 {
@@ -446,18 +445,18 @@
 }
 
 OMXVStream::OMXVStream()
+ :m_bWidthHeightKnown(FALSE)
+ ,m_hDecoder(NULL)
+ ,m_mofYUV(NULL)
+ ,m_pInputQueue(NULL)
 {
-    m_bWidthHeightKnown = FALSE;
-    m_hDecoder = 0;
-    m_mofYUV = NULL;
 }
 
 OMXVStream::~OMXVStream()
 {
-    if(m_hDecoder)
-    {
-        delete m_hDecoder;
-    }
+    HX_DELETE(m_hDecoder);
+    HX_ASSERT(m_pInputQueue->GetCount() == 0);
+    HX_DELETE(m_pInputQueue);
 }
 
 HX_RESULT 
@@ -512,58 +511,109 @@
     // renderer that agrees to do so     
     m_bHWMEM_MGT = FALSE;
     
+    //create the input queue object
+    m_pInputQueue = new CHXSimpleList; 
+    
     return HXR_OK;
 }
 
-
 HX_RESULT 
 OMXVStream::PNStream_Input(HXSTREAM fromStreamRef, HXCODEC_DATA *pData)
 {
     HX_ASSERT_VALID_PTR(pData);
-    HX_RESULT theErr = HXR_OK;
-    
+        
     if (!m_bStreamInConnected)
     {
         return HXSTREAM_BAD_STATE;
     }
 
-    unsigned char *pBytes = NULL;
-    unsigned int numBytes = 0;
+    // add data to input queue
     if (pData->data && pData->dataLength)
     {
-        pBytes = pData->data;
-        numBytes = pData->dataLength;
+        HXCODEC_DATA* myData = new HXCODEC_DATA;
+        if (myData == NULL)
+        {
+           return HXR_OUTOFMEMORY;
+        }
+        memcpy(myData, pData, sizeof(HXCODEC_DATA));
+        m_pInputQueue->AddTail((void*)myData);
     }
 
-    while((theErr == HXR_OK) || numBytes)
+    //we will run in the loop as long as we processed either some input data or some output data
+    HX_RESULT ri, ro;
+    do
     {
-        //We will try decode only if we have free input buffer
-        if(numBytes && m_hDecoder->GotFreeBuffer())
-        {       
-            UINT32 used = 0;
-            
-            theErr = m_hDecoder->Decode(pBytes, numBytes, pData->timestamp, used);
-            if(FAILED(theErr))
-            {
-                break;    
-            }
-            numBytes-=used;
-            pBytes+=used;
-        }
-        theErr = ProcessOutput();
-        //We will wait for buffer if we have no Decoded data & we have some thing to decode
-        if(numBytes && FAILED(theErr))
-        {
-            m_hDecoder->BufferWait();
-        }
+       ri = ProcessInput();
+       ro = ProcessOutput();
     }
-    theErr = HXR_OK;
-    // release our reference to the input data since we are done with it
-    if (m_RecieveAllocator != NULL && pData->data)
+    while (ri == HXR_OK || ro == HXR_OK);
+
+    return HXR_OK;       
+}
+
+HX_RESULT 
+OMXVStream::ProcessInput(void)
+{
+    HXBOOL bInputProcessed = FALSE;
+
+    //if we have data but no more omx input buffers, wait a bit to see
+    //if some can free up. This helps keeps the input queue length smaller
+    if (m_pInputQueue->GetCount() > 0 && !m_hDecoder->GotFreeBuffer())
     {
-        m_RecieveAllocator->ReleasePacketPtr(pData->data);
+        m_hDecoder->BufferWait(10);
     }
-    return(theErr);       
+
+    //we'll try to process as much as possible from input queue
+    //as long as there are free OMX input buffers
+    while (m_pInputQueue->GetCount() > 0 && m_hDecoder->GotFreeBuffer())
+    {
+       HXCODEC_DATA *pData = (HXCODEC_DATA *)m_pInputQueue->RemoveHead();        
+       if (pData->data && pData->dataLength)
+       {
+           unsigned char* pBytes = pData->data + pData->Segments[0].ulSegmentOffset;
+           unsigned int numBytes = pData->dataLength;
+
+           UINT32 totalUsed = 0;
+           while (numBytes > 0 && m_hDecoder->GotFreeBuffer())
+           {       
+              UINT32 used = 0;
+              HX_RESULT theErr = m_hDecoder->Decode(pBytes, numBytes, pData->timestamp, used);
+              if(FAILED(theErr))
+              {
+                break;    
+              }
+              numBytes-=used;
+              pBytes+=used;
+              totalUsed += used;
+
+           }
+           
+           if (totalUsed > 0)
+           {
+              bInputProcessed = TRUE;
+           }
+           
+           if (numBytes > 0)
+           {
+              //run out of buffers before processed all data
+              //put it back to queue
+              pData->Segments[0].ulSegmentOffset += totalUsed;
+              pData->dataLength -= totalUsed;
+              m_pInputQueue->AddHead((void*)pData);
+           }
+           else
+           {
+              //done with this data segment
+             if (m_RecieveAllocator != NULL && pData->data)
+             {
+                 m_RecieveAllocator->ReleasePacketPtr(pData->data);
+             }
+             HX_DELETE(pData);
+           }
+        }
+    }
+              
+    return bInputProcessed ? HXR_OK : HXR_FAIL;      
 }
 
 HX_RESULT 
@@ -586,12 +636,12 @@
             {
                 // directly return the omx decoder allocated buffer,
                 // which will be released/reused in PNStream_ReleaseFrame
-                pDecodedFrameBuffer = (pBuffer->pBuffer + pBuffer->nOffset);
+                pDecodedFrameBuffer = (pBuffer->pBuffer + pBuffer->nOffset);
             }
             else 
             {
-                // the allocation and memcpy here could hurt performance
-                theErr = m_SendAllocator->SetProperties(&allocRequest, &allocActual);       
+                // the allocation and memcpy here could hurt performance
+                theErr = m_SendAllocator->SetProperties(&allocRequest, &allocActual);       
                 pDecodedFrameBuffer = m_SendAllocator->GetPacketBuffer(&pUnk);
                 if(pDecodedFrameBuffer != NULL)
                 {
@@ -601,7 +651,6 @@
            
             if (pDecodedFrameBuffer != NULL)
             {            
-
 	            // setup output data 
 	            HXCODEC_DATA *pcdOutData;
 	            pcdOutData = (HXCODEC_DATA *) new UCHAR[HXCODEC_DATA_SIZE + 2 * HXCODEC_SEGMENTINFO_SIZE];
@@ -628,7 +677,7 @@
         
         // if we are not returning direct memory buffer, send it back to decoder now
         if(!m_bHWMEM_MGT)
-        {
+        {
             m_hDecoder->ReUse(pBuffer);
         }
    }
@@ -782,6 +831,18 @@
 OMXVStream::PNStream_Close()
 {
     HX_RESULT theErr = HXR_OK;
+    
+    //free all input data in the queue
+    while (m_pInputQueue->GetCount() > 0)
+    {
+       HXCODEC_DATA *pData = (HXCODEC_DATA *)m_pInputQueue->RemoveHead();        
+       if (m_RecieveAllocator != NULL && pData->data)
+       {
+          m_RecieveAllocator->ReleasePacketPtr(pData->data);
+       }
+       HX_DELETE(pData);
+    }
+    
     Release();
     return(theErr);
 }


_______________________________________________
Datatype-cvs mailing list
Datatype-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/datatype-cvs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic