mp4apyld.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,014 行 · 第 1/2 页
CPP
1,014 行
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 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 ***** */
/****************************************************************************
* Defines
*/
#define _OVERALLOC_CODEC_DATA 3
#define FLUSH_ALL_PACKETS 0xFFFFFFFF
#define CHAR_LF 0x0a
#define CHAR_CR 0x0d
/****************************************************************************
* Includes
*/
#include "hxtypes.h"
#include "hxwintyp.h"
#include "hxcom.h"
#include "hxcomm.h"
#include "hxassert.h"
#include "hxslist.h"
#include "hxstrutl.h"
#include "hxcomm.h"
#include "ihxpckts.h"
#include "hxformt.h"
#include "hxrendr.h"
#include "hxformt.h"
#include "hxengin.h"
#include "mp4-latm-depack.h"
#include "mp4desc.h"
#include "mp4apyld.h"
#include "mp4pyldutil.h"
MP4APayloadFormat::MP4APayloadFormat()
: m_lRefCount (0)
, m_pClassFactory (NULL)
, m_pStreamHeader (NULL)
, m_bFlushed (FALSE)
, m_bUsesRTPPackets (FALSE)
, m_bRTPPacketTested (FALSE)
, m_bPacketize (FALSE)
, m_pAudioConfig (NULL)
, m_ulAudioConfigSize (0)
, m_unAudioConfigType (2)
, m_ulSamplesPerSecond (1000)
, m_ulRTPSamplesPerSecond(0)
, m_PayloadID (PYID_X_HX_MP4_RAWAU)
, m_bPriorLoss (FALSE)
, m_pLATMDepack (NULL)
{
;
}
MP4APayloadFormat::~MP4APayloadFormat()
{
FlushPackets(FLUSH_ALL_PACKETS);
HX_VECTOR_DELETE(m_pAudioConfig);
HX_DELETE(m_pLATMDepack);
HX_RELEASE(m_pClassFactory);
HX_RELEASE(m_pStreamHeader);
}
HX_RESULT MP4APayloadFormat::Build(REF(IMP4APayloadFormat*) pFmt)
{
pFmt = new MP4APayloadFormat();
HX_RESULT res = HXR_OUTOFMEMORY;
if (pFmt)
{
pFmt->AddRef();
res = HXR_OK;
}
return res;
}
// *** IUnknown methods ***
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP
MP4APayloadFormat::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), this },
{ GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
MP4APayloadFormat::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32)
MP4APayloadFormat::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHODIMP
MP4APayloadFormat::Init(IUnknown* pContext,
BOOL bPacketize)
{
HX_RESULT retVal = HXR_OK;
HX_RELEASE(m_pClassFactory);
m_bPacketize = bPacketize;
if (SUCCEEDED(retVal))
{
retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**) &m_pClassFactory);
}
return retVal;
}
STDMETHODIMP
MP4APayloadFormat::Reset()
{
// Release all input packets we have stored
FlushPackets(FLUSH_ALL_PACKETS);
m_bFlushed = FALSE;
m_bPriorLoss = FALSE;
if (m_pLATMDepack)
{
m_pLATMDepack->Reset();
}
m_TSConverter.Reset();
return HXR_OK;
}
STDMETHODIMP
MP4APayloadFormat::SetStreamHeader(IHXValues* pHeader)
{
HX_RESULT retVal;
if (pHeader)
{
m_pStreamHeader = pHeader;
m_pStreamHeader->AddRef();
}
if (m_bPacketize)
{
retVal = SetPacketizerHeader(pHeader);
}
else
{
retVal = SetAssemblerHeader(pHeader);
}
return retVal;
}
HX_RESULT MP4APayloadFormat::SetPacketizerHeader(IHXValues* pHeader)
{
return HXR_OK;
}
HX_RESULT MP4APayloadFormat::SetAssemblerHeader(IHXValues* pHeader)
{
IHXBuffer* pMimeType = NULL;
const char* pMimeTypeData = NULL;
HX_RESULT retVal = HXR_INVALID_PARAMETER;
if (pHeader)
{
retVal = HXR_OK;
}
if (SUCCEEDED(retVal))
{
retVal = pHeader->GetPropertyCString("MimeType", pMimeType);
}
if (SUCCEEDED(retVal))
{
pMimeTypeData = (char*) pMimeType->GetBuffer();
retVal = HXR_FAIL;
if (pMimeTypeData)
{
retVal = HXR_OK;
}
}
// Determine payload type here based on mime type
if (SUCCEEDED(retVal))
{
if (strcasecmp(pMimeTypeData, "audio/X-RN-MP4-RAWAU") == 0)
{
m_PayloadID = PYID_X_HX_MP4_RAWAU;
}
else if (strcasecmp(pMimeTypeData, "audio/mpeg4-simple-A2") == 0)
{
m_PayloadID = PYID_MPEG4_SIMPLE_A2;
}
else if (strcasecmp(pMimeTypeData, "audio/MP4A-LATM") == 0)
{
m_PayloadID = PYID_MP4A_LATM;
}
else if (strcasecmp(pMimeTypeData, "audio/X-HX-AAC-GENERIC") == 0)
{
m_PayloadID = PYID_X_HX_AAC_GENERIC;
}
else
{
retVal = HXR_FAIL;
}
}
if (SUCCEEDED(retVal))
{
switch (m_PayloadID)
{
case PYID_X_HX_MP4_RAWAU:
retVal = SetAssemblerHXHeader(pHeader);
break;
case PYID_MP4A_LATM:
retVal = SetAssemblerLATMHeader(pHeader);
break;
case PYID_X_HX_AAC_GENERIC:
retVal = SetAssemblerAACGenericHeader(pHeader);
break;
default:
retVal = HXR_NOTIMPL;
break;
}
}
if (SUCCEEDED(retVal))
{
m_ulSamplesPerSecond = 0;
m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
m_ulRTPSamplesPerSecond);
}
HX_RELEASE(pMimeType);
return retVal;
}
HX_RESULT MP4APayloadFormat::SetAssemblerAACGenericHeader(IHXValues* pHeader)
{
IHXBuffer *pBuffer = NULL;
UCHAR *pBuf = NULL;
HX_RESULT retVal = HXR_FAIL;
retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
pBuffer);
if (SUCCEEDED(retVal))
{
m_pAudioConfig = NULL;
m_ulAudioConfigSize = pBuffer->GetSize();
if (m_ulAudioConfigSize)
{
pBuf = pBuffer->GetBuffer();
m_unAudioConfigType = pBuf[0];
if (--m_ulAudioConfigSize)
{
m_pAudioConfig = new UINT8[m_ulAudioConfigSize];
if (!m_pAudioConfig)
{
retVal = HXR_OUTOFMEMORY;
}
else
{
memcpy(m_pAudioConfig, &pBuf[1], m_ulAudioConfigSize);
}
}
}
else
{
m_unAudioConfigType = 0;
}
}
HX_RELEASE(pBuffer);
return retVal;
}
HX_RESULT MP4APayloadFormat::SetAssemblerHXHeader(IHXValues* pHeader)
{
ES_Descriptor ESDesc;
DecoderConfigDescriptor* pDCDesc = NULL;
DecoderSpecifcInfo* pDSIDesc = NULL;
IHXBuffer* pESDescriptor = NULL;
UINT8* pESDescData;
ULONG32 ulESDescSize;
HX_RESULT retVal = HXR_OK;
HX_VECTOR_DELETE(m_pAudioConfig);
m_ulAudioConfigSize = 0;
retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
pESDescriptor);
if (SUCCEEDED(retVal))
{
retVal = HXR_INVALID_PARAMETER;
if (pESDescriptor)
{
retVal = HXR_OK;
}
}
if (SUCCEEDED(retVal))
{
pESDescData = pESDescriptor->GetBuffer();
ulESDescSize = pESDescriptor->GetSize();
retVal = ESDesc.Unpack(pESDescData, ulESDescSize);
}
HX_RELEASE(pESDescriptor);
if (SUCCEEDED(retVal))
{
retVal = HXR_FAIL;
pDCDesc = ESDesc.m_pDecConfigDescr;
if (pDCDesc)
{
pDSIDesc = pDCDesc->m_pDecSpecificInfo;
retVal = HXR_OK;
}
}
if (SUCCEEDED(retVal) && pDSIDesc)
{
m_ulAudioConfigSize = pDSIDesc->m_ulLength;
if (m_ulAudioConfigSize > 0)
{
m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];
if (m_pAudioConfig == NULL)
{
m_ulAudioConfigSize = 0;
retVal = HXR_OUTOFMEMORY;
}
}
}
if (SUCCEEDED(retVal))
{
if (m_ulAudioConfigSize > 0)
{
memcpy(m_pAudioConfig, pDSIDesc->m_pData, m_ulAudioConfigSize); /* Flawfinder: ignore */
}
}
return retVal;
}
HX_RESULT MP4APayloadFormat::SetAssemblerLATMHeader(IHXValues* pHeader)
{
HX_RESULT retVal = SetAssemblerLATMConfig(pHeader);
if (SUCCEEDED(retVal))
{
m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
m_ulRTPSamplesPerSecond);
}
return retVal;
}
HX_RESULT MP4APayloadFormat::SetAssemblerLATMConfig(IHXValues* pFMTParams)
{
IHXBuffer* pConfigBuffer = NULL;
ULONG32 ulObject = 0;
ULONG32 ulProfileID = 0;
ULONG32 ulBitrate = 0;
ULONG32 bConfigPresent = TRUE;
HX_RESULT retVal = HXR_OK;
HX_ASSERT(pFMTParams);
// Obtain Required parameters
retVal = CHXMP4PayloadUtil::GetFMTPConfig(pFMTParams, m_pClassFactory,
pConfigBuffer);
// Obtain optional parameters
if (SUCCEEDED(retVal))
{
ULONG32 ulVal = 0;
pFMTParams->GetPropertyULONG32("FMTPobject", ulObject);
pFMTParams->GetPropertyULONG32("FMTPprofile-level-id", ulProfileID);
if (SUCCEEDED(pFMTParams->GetPropertyULONG32("FMTPcpresent", ulVal)))
{
bConfigPresent = (ulVal != 0);
}
pFMTParams->GetPropertyULONG32("FMTPbitrate", ulBitrate);
}
// Create and initialize the MP4A-LATM depacketizer
if (SUCCEEDED(retVal))
{
HX_DELETE(m_pLATMDepack);
m_pLATMDepack = new MP4LATMDepack;
retVal = HXR_OUTOFMEMORY;
if (m_pLATMDepack)
{
retVal = HXR_OK;
}
}
if (SUCCEEDED(retVal))
{
UINT8* pStreamMuxConfig = NULL;
ULONG32 ulMuxConfigSize = 0;
const UINT8* pCodecConfig = NULL;
ULONG32 ulConfigSize = 0;
if (pConfigBuffer)
{
pStreamMuxConfig = pConfigBuffer->GetBuffer();
ulMuxConfigSize = pConfigBuffer->GetSize();
}
retVal = HXR_FAIL;
if (m_pLATMDepack->Init(ulProfileID,
ulObject,
ulBitrate,
bConfigPresent,
pStreamMuxConfig,
ulMuxConfigSize,
OnFrameCallback,
this))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?