[datatype-dev] CR:Case ou1cimx1#259923 Helix Cannot play MPEG4 avi with 5.1ch AC3
Gang.Jia at nokia.com Gang.Jia at nokia.comSkipped 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; }