[datatype-dev] CR:Case ou1cimx1#259923 Helix Cannot play MPEG4 avi with 5.1ch AC3

[datatype-dev] CR:Case ou1cimx1#259923 Helix Cannot play MPEG4 avi with 5.1ch AC3

Gang.Jia at nokia.com Gang.Jia at nokia.com
Mon Mar 1 13:22:08 PST 2010


Skipped content of type multipart/alternative-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: $Id$
 *  
 * Portions Copyright (c) 1995-2010 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#ifndef DD_DEPACK_H
#define DD_DEPACK_H

#include "hxtypes.h"
#include "mp4a-mux-cfg.h"

typedef void (*OnFrameCB)(void* pUserData, ULONG32 ulTime, 
			  const UINT8* pData, ULONG32 ulSize,
			  HXBOOL bPreviousLoss);

class DDDepack
{
public:
    DDDepack();
    ~DDDepack();

    HXBOOL Init(OnFrameCB pFrameCB,
	      void* pUserData,
          HXBOOL bIsDDPlus);
    
    HXBOOL Reset(); // Completely reset the depacketizer state

    HXBOOL Flush(); // Indicates end of stream

    HXBOOL OnPacket(ULONG32 ulTime, const UINT8* pData,
		  ULONG32 ulSize);

    HXBOOL OnLoss(ULONG32 ulNumPackets); // called to indicate lost packets

protected:
    HXBOOL FindSyncWord(UINT8* pBuffer, ULONG32& ulOffset, ULONG32 ulSize);
    HXBOOL ProcessStagingBuffer(UINT8* pBuffer, ULONG32 ulSize);


private:
    void* m_pUserData;
    OnFrameCB m_pCallback;

    ULONG32 m_ulCurrentTime;

    UINT8* m_pStagingBuf;
    ULONG32 m_ulStagingBufSize;
    ULONG32 m_ulBytesStaged;
    
    UINT8* m_pPayloadBuf;
    ULONG32 m_ulPayloadBufSize;

    HXBOOL m_bHadLoss;
    HXBOOL m_bNeedNextPkt;
    HXBOOL m_bIsDDPlus;
};

#endif // DD_DEPACK_H
-------------- next part --------------
Index: Umakefil
===================================================================
RCS file: /cvsroot/datatype/mp4/payload/Umakefil,v
retrieving revision 1.14.2.2
diff -u -w -r1.14.2.2 Umakefil
--- Umakefil	7 Mar 2006 20:03:35 -0000	1.14.2.2
+++ Umakefil	26 Feb 2010 16:19:48 -0000
@@ -72,6 +72,7 @@
                    "mp4-latm-depack.cpp",
                    "qclppyld.cpp",
                    "qcelp-depack.cpp",
+                   "dd-depack.cpp",
                    "fmtfact.cpp",
                    "hxamrpack.cpp")
 
Index: mp4apyld.cpp
===================================================================
RCS file: /cvsroot/datatype/mp4/payload/mp4apyld.cpp,v
retrieving revision 1.14.6.5
diff -u -w -r1.14.6.5 mp4apyld.cpp
--- mp4apyld.cpp	26 Jan 2010 18:48:30 -0000	1.14.6.5
+++ mp4apyld.cpp	26 Feb 2010 16:19:48 -0000
@@ -62,6 +62,7 @@
 #include "hxengin.h"
 
 #include "mp4-latm-depack.h"
+#include "dd-depack.h"
 
 #include "mp4desc.h"
 #include "mp4apyld.h"
@@ -79,6 +80,7 @@
 #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM)
     , m_pLATMDepack	    (NULL)
 #endif /* #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM) */
+    , m_pDDDepack	    (NULL)
     , m_pAudioConfig	    (NULL)
     , m_ulAudioConfigSize   (0)
     , m_unAudioConfigType   (2)
@@ -98,6 +100,7 @@
 #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM)
     HX_DELETE(m_pLATMDepack);
 #endif /* #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM) */
+    HX_DELETE(m_pDDDepack);
     HX_RELEASE(m_pClassFactory);
     HX_RELEASE(m_pStreamHeader);
 }
@@ -203,6 +206,10 @@
 	m_pLATMDepack->Reset();
     }
 #endif /* #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM) */
+    if (m_pDDDepack)
+    {
+    m_pDDDepack->Reset();
+    }
     m_TSConverter.Reset();
 
     return HXR_OK;
@@ -288,7 +295,7 @@
 	}
     else if (strcasecmp(pMimeTypeData, "audio/EAC3") == 0)
     {
-        m_PayloadID = PYID_DOLBYDIGITAL;
+        m_PayloadID = PYID_DOLBYDIGITALPLUS;
     }
     else if (strcasecmp(pMimeTypeData, "audio/AC3") == 0)
     {
@@ -317,7 +324,10 @@
         retVal = SetAssemblerQCELPHeader(pHeader);
         break;
     case PYID_DOLBYDIGITAL:
-        retVal = SetAssemblerDDHeader(pHeader);
+        retVal = SetAssemblerDDHeader(pHeader, FALSE);
+        break;
+    case PYID_DOLBYDIGITALPLUS:
+        retVal = SetAssemblerDDHeader(pHeader, TRUE);
         break;
 	default:
 	    retVal = HXR_NOTIMPL;
@@ -477,10 +487,14 @@
     return retVal;
 }
 
-HX_RESULT MP4APayloadFormat::SetAssemblerDDHeader(IHXValues* pHeader)
+HX_RESULT MP4APayloadFormat::SetAssemblerDDHeader(IHXValues* pHeader, HXBOOL bIsDDPlus)
 {
     HX_RESULT retVal = HXR_OK;
 
+    retVal = SetAssemblerDDConfig(bIsDDPlus);
+
+    if (SUCCEEDED(retVal))
+    {
     m_ulAudioConfigSize = 12;
 
     m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
@@ -505,6 +519,35 @@
     {
         retVal = HXR_OUTOFMEMORY;
     }
+    }
+    return retVal;
+}
+
+HX_RESULT MP4APayloadFormat::SetAssemblerDDConfig(HXBOOL bIsDDPlus)
+{
+    HX_RESULT retVal = HXR_OK;
+
+    // Create and initialize the DD depacketizer
+    HX_DELETE(m_pDDDepack);
+    m_pDDDepack = new DDDepack;
+
+    retVal = HXR_OUTOFMEMORY;
+    if (m_pDDDepack)
+    {
+        retVal = HXR_OK;
+    }
+
+    if (SUCCEEDED(retVal))
+    {
+
+        retVal = HXR_FAIL;
+        if (m_pDDDepack->Init(OnFrameCallback, this, bIsDDPlus))
+        {
+            retVal = HXR_OK;
+        }
+
+    }
+
     return retVal;
 }
 
@@ -678,11 +721,42 @@
     case PYID_X_HX_3GPP_QCELP:
     case PYID_X_HX_MP4_RAWAU:
     case PYID_X_HX_AAC_GENERIC:
-    case PYID_DOLBYDIGITAL:
 	pPacket->AddRef();
 	m_InputPackets.AddTail(pPacket);
 	break;
 
+
+    case PYID_DOLBYDIGITAL:
+    case PYID_DOLBYDIGITALPLUS:
+        retVal = HXR_FAIL;
+        if (m_pDDDepack)
+        {
+            if (pPacket->IsLost())
+            {
+                if (m_pDDDepack->OnLoss(1))
+                {
+                    retVal = HXR_OK;
+                }
+            }
+            else
+            {
+                IHXBuffer* pBuffer = pPacket->GetBuffer();
+
+                if (pBuffer)
+                {
+                    if (m_pDDDepack->OnPacket(GetPacketTime(pPacket),
+                                              pBuffer->GetBuffer(),
+                                              pBuffer->GetSize()))
+                    {
+                        retVal = HXR_OK;
+                    }
+
+                    pBuffer->Release();
+                }
+            }
+        }
+    break;
+
     case PYID_MP4A_LATM:
 	retVal = HXR_FAIL;
 #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM)
@@ -837,10 +911,11 @@
     {
     case PYID_X_HX_AAC_GENERIC:
     case PYID_X_HX_MP4_RAWAU:
-    case PYID_DOLBYDIGITAL:
 	retVal = CreateRawAUMediaPacket(pOutMediaPacket);
 	break;
 
+    case PYID_DOLBYDIGITAL:
+    case PYID_DOLBYDIGITALPLUS:
     case PYID_MP4A_LATM:
 	if (m_OutMediaPacketQueue.IsEmpty())
 	{
@@ -1043,6 +1118,10 @@
 	m_pLATMDepack->Flush();
     }
 #endif /* #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM) */
+    if (m_pDDDepack)
+    {
+        m_pDDDepack->Flush();
+    }
     m_bFlushed = TRUE;
 
     return HXR_OK;
     
Index: pub/mp4apyld.h
===================================================================
RCS file: /cvsroot/datatype/mp4/payload/pub/mp4apyld.h,v
retrieving revision 1.7.8.1
diff -u -w -r1.7.8.1 mp4apyld.h
--- pub/mp4apyld.h	13 Nov 2009 19:33:44 -0000	1.7.8.1
+++ pub/mp4apyld.h	26 Feb 2010 16:19:48 -0000
@@ -43,6 +43,7 @@
 #include "tsconvrt.h"
 
 class MP4LATMDepack;
+class DDDepack;
 
 /****************************************************************************
  *  MP4APayloadFormat
@@ -103,7 +104,8 @@
 	PYID_MP4A_LATM,
 	PYID_X_HX_AAC_GENERIC,
 	PYID_X_HX_3GPP_QCELP,
-    PYID_DOLBYDIGITAL
+    PYID_DOLBYDIGITAL,
+    PYID_DOLBYDIGITALPLUS
     } PayloadID;
 
     inline HX_RESULT CreateRawAUMediaPacket(CMediaPacket* &pOutMediaPacket);
@@ -117,7 +119,8 @@
     HX_RESULT SetAssemblerQCELPHeader(IHXValues* pHeader);
 
     HX_RESULT SetAssemblerLATMConfig(IHXValues* pHeader);
-    HX_RESULT SetAssemblerDDHeader(IHXValues* pHeader);
+    HX_RESULT SetAssemblerDDHeader(IHXValues* pHeader, HXBOOL bIsDDPlus);
+    HX_RESULT SetAssemblerDDConfig(HXBOOL bIsDDPlus);
     HX_RESULT OnFrame(ULONG32 ulTime, 
 		      const UINT8* pData, 
 		      ULONG32 ulSize,
@@ -154,6 +157,7 @@
     MP4LATMDepack*		m_pLATMDepack;
 #endif /* #if defined(HELIX_FEATURE_AUDIO_MPEG4_DEPACK_LATM) */
 
+    DDDepack*		m_pDDDepack;
     UINT8*			m_pAudioConfig;
     ULONG32			m_ulAudioConfigSize;
     UINT8                       m_unAudioConfigType;
-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: $Id$ 
 *  
 * Portions Copyright (c) 1995-2010 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#include "hlxclib/string.h"
#include "dd-depack.h"

#define DEFAULT_PAYLOAD_BUF_SIZE 5120
#define DEFAULT_STAGING_BUF_SIZE 5120

//Dolby Digital frame size table, the first column is framesizecode, it is the lower 6 bits
// of the 4th byte, the 2nd column is the norminal bit rate, the 3rd, 4th and 5th columns are
// the framesizes(in 16bit word) for sample rate at 32K, 44.1K and 48K respectively
/*
frmsizecode     nominal bit rate 16-bit words per syncframe     Fs=32K Fs=44.1K Fs=48K 
000000 32Kbps 96 69 64 
000001 32Kbps 96 70 64 
000010 40Kbps 120 87 80 
000011 40Kbps 120 88 80 
000100 48Kbps 144 104 96 
000101 48Kbps 144 105 96 
000110 56Kbps 168 121 112 
000111 56Kbps 168 122 112 
001000 64Kbps 192 139 128 
001001 64Kbps 192 140 128 
001010 80Kbps 240 174 160 
001011 80Kbps 240 175 160 
001100 96Kbps 288 208 192 
001101 96Kbps 288 209 192 
001110 112Kbps 336 243 224 
001111 112Kbps 336 244 224 
010000 128Kbps 384 278 256 
010001 128Kbps 384 279 256 
010010 160Kbps 480 348 320 
010011 160Kbps 480 349 320 
010100 192Kbps 576 417 384 
010101 192Kbps 576 418 384 
010110 224Kbps 672 487 448 
010111 224Kbps 672 488 448 
011000 256Kbps 768 557 512 
011001 256Kbps 768 558 512 
011010 320Kbps 960 696 640 
011011 320Kbps 960 697 640 
011100 384Kbps 1152 835 768 
011101 384Kbps 1152 836 768 
011110 448Kbps 1344 975 896 
011111 448Kbps 1344 976 896 
100000 512Kbps 1536 1114 1024 
100001 512Kbps 1536 1115 1024 
100010 576Kbps 1728 1253 1152 
100011 576Kbps 1728 1254 1152 
100100 640Kbps 1920 1393 1280 
100101 640Kbps 1920 1394 1280 
100110 to 111111 reserved   */

//Dolby Digital frame size (in bytes) table used to parse the frame header
const UINT32 uDDFrameSizetTbl [38][3] =
{
    128,  138,  192,
    128,  140,  192,
    160,  174,  240,
    160,  176,  240,
    192,  208,  288,
    192,  210,  288,
    224,  242,  336,
    224,  244,  336,
    256,  278,  384,
    256,  280,  384,
    320,  348,  480,
    320,  350,  480,
    384,  416,  576,
    384,  418,  576,
    448,  486,  672,
    448,  488,  672,
    512,  556,  768,
    512,  558,  768,
    640,  696,  960,
    640,  698,  960,
    768,  834,  1152,
    768,  836,  1152,
    896,  974,  1344,
    896,  976,  1344,
    1024, 1114, 1536,
    1024, 1116, 1536,
    1280, 1392, 1920,
    1280, 1394, 1920,
    1536, 1670, 2304,
    1536, 1672, 2304,
    1792, 1950, 2688,
    1792, 1952, 2688,
    2048, 2228, 3072,
    2048, 2230, 3072,
    2304, 2506, 3456,
    2304, 2508, 3456,
    2560, 2786, 3840,
    2560, 2788, 3840,
};

DDDepack::DDDepack() :
    m_pUserData(0),
    m_pCallback(0),
    m_ulCurrentTime(0),
    m_ulBytesStaged(0),
    m_bHadLoss(FALSE),
    m_bNeedNextPkt(FALSE)
{}

DDDepack::~DDDepack()
{
    if(m_pStagingBuf)
    {
        delete [] m_pStagingBuf;
    }
    m_pStagingBuf = 0;

    if(m_pPayloadBuf)
    {
        delete [] m_pPayloadBuf;
    }
    m_ulPayloadBufSize = 0;
}

HXBOOL DDDepack::Init(OnFrameCB pFrameCB, void* pUserData, HXBOOL bIsDDPlus)
{
    HXBOOL ret = FALSE;
    m_pCallback = pFrameCB;
    m_pUserData = pUserData;
    m_bIsDDPlus = bIsDDPlus;

    m_pStagingBuf = new UINT8[DEFAULT_STAGING_BUF_SIZE];
    if(m_pStagingBuf)
    {
        ret = TRUE;
    }
    m_ulStagingBufSize = DEFAULT_PAYLOAD_BUF_SIZE;

    m_pPayloadBuf = new UINT8[DEFAULT_PAYLOAD_BUF_SIZE];
    if(ret && m_pPayloadBuf)
    {
        ret = TRUE;
    }
    m_ulPayloadBufSize = DEFAULT_PAYLOAD_BUF_SIZE;

    return TRUE;
}

HXBOOL DDDepack::Reset() // Completely reset the depacketizer state
{

    m_ulBytesStaged = 0;
    m_bHadLoss = FALSE;
    m_bNeedNextPkt = FALSE;

    return FALSE;
}

HXBOOL DDDepack::Flush() // Indicates end of stream
{
    return FALSE;
}

HXBOOL DDDepack::FindSyncWord(UINT8* pBuffer, ULONG32& ulOffset, ULONG32 ulSize)
{
    HXBOOL ret = FALSE;

    if( !(*pBuffer == 0x0b) || !(*(pBuffer+1) == 0x77))
    {
        //Discard data until the first sync word
        for(ULONG32 i=1; i<ulSize-1; i++)
        {
            if( (*(pBuffer+i) == 0x0b) && (*(pBuffer+i+1) == 0x77))
            {
                ulOffset = i;
                ret=TRUE;
                break;
            }
        }
    }
    else
    {
        ulOffset = 0;
        ret=TRUE;
    }
    return ret;
}


HXBOOL DDDepack::OnPacket(ULONG32 ulTime, const UINT8* pData, 
           ULONG32 ulSize)
{
    HXBOOL ret = TRUE;

    UINT8* pBuffer = (UINT8*)pData;
    m_ulCurrentTime = ulTime;

    if (!m_bNeedNextPkt)
    {
        ULONG32 ulOffset = 0;
        ret = FindSyncWord(pBuffer, ulOffset, ulSize);

        if (ret)
        {
            ULONG32 ulPayloadLen = ulSize - ulOffset;
            if (ulPayloadLen > m_ulStagingBufSize)
            {
                // We need to make the staging buffer larger
                UINT8* pNewBuf = new UINT8[ulPayloadLen];
                if(!pNewBuf)
                {
                    m_ulBytesStaged = 0;
                    m_bNeedNextPkt = FALSE;
                    ret = FALSE;
                }
                else
                {
                    delete [] m_pStagingBuf;
                    m_pStagingBuf = pNewBuf;
                    m_ulStagingBufSize = ulPayloadLen;
                }
            }
            if(ret)
            {
                memcpy(m_pStagingBuf, &pBuffer[ulOffset], ulPayloadLen);
                m_ulBytesStaged += ulPayloadLen;
            }
        }
    }
    else   //continue to the previous pkt
    {
        if ((m_ulBytesStaged + ulSize) > m_ulStagingBufSize)
        {
            // We need to make the staging buffer larger
            UINT8* pNewBuf = new UINT8[m_ulBytesStaged + ulSize];
            if(!pNewBuf)
            {
                m_ulBytesStaged = 0;
                m_bNeedNextPkt = FALSE;
                ret = FALSE;
            }
            else
            {
                memcpy(pNewBuf, m_pStagingBuf, m_ulBytesStaged);

                delete [] m_pStagingBuf;
                m_pStagingBuf = pNewBuf;
                m_ulStagingBufSize = m_ulBytesStaged + ulSize;
            }
        }

        if(ret)
        {
            memcpy(&m_pStagingBuf[m_ulBytesStaged], pData, ulSize);
            m_ulBytesStaged += ulSize;
        }
    }

    if(ret)
    {
        ret = ProcessStagingBuffer(m_pStagingBuf,m_ulBytesStaged);	
    }

    return ret;
}

HXBOOL DDDepack::OnLoss(ULONG32 ulNumPackets) // called to indicate lost 
                                                 // packets
{
    m_bHadLoss = TRUE;

    m_ulBytesStaged = 0;

    return TRUE;
}

HXBOOL DDDepack::ProcessStagingBuffer(UINT8* pBuffer, ULONG32 ulSize)
{

    ULONG32 ulFrameTime = m_ulCurrentTime;

    ULONG32 ulOffset = 0;
    UINT32 uFrameLen = 0;
    UINT8* pPayloadBuf;
    ULONG32 ulPayloadLen = 0;

    if(m_ulPayloadBufSize < ulSize)
    {
        // We need to make the payload buffer larger
        UINT8* pNewBuf = new UINT8[ulSize];

        if(!pNewBuf)
        {
            m_ulBytesStaged = 0;
            m_bNeedNextPkt = FALSE;
            return FALSE;
        }
        delete [] m_pPayloadBuf;
        m_pPayloadBuf = pNewBuf;
        m_ulPayloadBufSize = ulSize;
    }
    do
    {

        pPayloadBuf =  pBuffer + ulOffset;
        //Audio data need to start with a valid Dolby Digital frame, check Syncword 0x0b77
        if( *pPayloadBuf == 0x0b && *(pPayloadBuf+1) == 0x77)
        {
            if(m_bIsDDPlus)
            {
                //Get Dolby Digital Plus frame length
                /*First 2 byte of the PayloadData block contains the Syncword (0x0b77)
                      Word       Size
                bsi()
                {
                  strmtyp         2
                  substreamid     3
                  frmsiz          11
                  ...
                  ..
                }  
                To extract the framesize we need last 3 bits from the third byte of PayloadData block and the next byte
                of PayloadData block.   
                'frmsiz' field indicates a value one less than the overall size of the coded frame in 16-bit words. That
                is, this field may assume a value ranging from 0 to 2047, and these values correspond to frame
                sizes ranging from 1 to 2048.  */

                uFrameLen = ((((*(pPayloadBuf+2)&0x07)<<8) | *(pPayloadBuf+3)) + 1) * 2;

                if( uFrameLen+ulOffset > ulSize )
                {
                    //The frame is fragmented, need more data
                    break;
                }

                memcpy(m_pPayloadBuf + ulOffset, pPayloadBuf, uFrameLen);
                ulPayloadLen+=uFrameLen;
                ulOffset+= uFrameLen;
            }
            else
            {
                //Get Dolby Digital frame length
                UINT8 uFrameInfoByte = *(pPayloadBuf+4);
                UINT8 uFameSizeCode = uFrameInfoByte & 0x3f;
                UINT8 uSampleRateCode = uFrameInfoByte >> 6;
                if ( uFameSizeCode < 38 && uSampleRateCode < 3 )
                {
                    uFrameLen = uDDFrameSizetTbl[uFameSizeCode][uSampleRateCode];
                    if( uFrameLen+ulOffset > ulSize )
                        {
                            //The frame is fragmented, need more data
                            break;
                        }
                    memcpy(m_pPayloadBuf + ulOffset, pPayloadBuf, uFrameLen);
                    ulPayloadLen+=uFrameLen;
                    ulOffset+= uFrameLen;
                }
                else
                {
                    //This is not a real sync word, try to find the next sync word
                    *pPayloadBuf = 0;
                }
            }
        }
        else
        {
            //Lost sync, try to find the next sync word in the buffer
            ULONG32 ulNextSyncOffset = 0;
            if((ulSize - ulOffset)>1 && FindSyncWord(pPayloadBuf, ulNextSyncOffset, ulSize - ulOffset))
            {
                ulOffset+= ulNextSyncOffset;
                continue;
            }
            else
            {
                //can not find sync word in the buffer, discard the buffer
                ulOffset = ulSize;
                break;
            }
        }
    }while(ulOffset < ulSize);

    if(ulPayloadLen)
    {
        m_pCallback( m_pUserData, m_ulCurrentTime, 
                 m_pPayloadBuf,
                 ulPayloadLen,
                 m_bHadLoss);

        m_bHadLoss = FALSE;
    }

    if(ulOffset < ulSize)
    {

        //Frame fragmented, need next pkt to reassemble the frame
        m_ulBytesStaged = ulSize - ulOffset;
        memcpy(m_pStagingBuf, pBuffer+ulOffset, m_ulBytesStaged);

        m_bNeedNextPkt = TRUE;
    }
    else
    {
        //End of buffer reached
        m_ulBytesStaged = 0;
        m_bNeedNextPkt = FALSE;
    }

    return TRUE;
}




More information about the Datatype-dev mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.