concatpyld.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 368 行
CPP
368 行
/* ***** 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 ***** */
#include "concatpyld.h"
const UINT32 MinPacketDuration = 200;
HXConcatenatePayloadFormat::HXConcatenatePayloadFormat() :
m_lRefCount(0),
m_pCCF(NULL),
m_pHeader(NULL),
m_pFinishedPkt(NULL),
m_bHaveFirstPkt(FALSE),
m_ulTimestamp(0),
m_uStream(0),
m_uASMFlags(0),
m_uASMRule(0),
m_ulByteCount(0),
m_bPendingFlush(FALSE)
{}
HXConcatenatePayloadFormat::~HXConcatenatePayloadFormat()
{
Close();
}
HX_RESULT
HXConcatenatePayloadFormat::CreateInstance(REF(IHXPayloadFormatObject*) pPyld)
{
HX_RESULT res = HXR_OUTOFMEMORY;
pPyld = new HXConcatenatePayloadFormat();
if (pPyld)
{
pPyld->AddRef();
res = HXR_OK;
}
return res;
}
/*
* IUnknown methods
*/
STDMETHODIMP HXConcatenatePayloadFormat::QueryInterface(THIS_
REFIID riid,
void** ppvObj)
{
HX_RESULT retVal = HXR_NOINTERFACE;
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), this },
{ GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
};
if (ppvObj)
{
*ppvObj = NULL;
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
return retVal;
}
STDMETHODIMP_(ULONG32) HXConcatenatePayloadFormat::AddRef(THIS)
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHODIMP_(ULONG32) HXConcatenatePayloadFormat::Release(THIS)
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/*
* IHXPayloadFormatObject methods
*/
STDMETHODIMP HXConcatenatePayloadFormat::Init(THIS_
IUnknown* pContext,
BOOL bPacketize)
{
HX_RESULT res = HXR_UNEXPECTED;
if (bPacketize && pContext)
{
res = pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**)&m_pCCF);
}
return res;
}
STDMETHODIMP HXConcatenatePayloadFormat::Close(THIS)
{
Reset();
HX_RELEASE(m_pCCF);
return HXR_OK;
}
STDMETHODIMP HXConcatenatePayloadFormat::Reset(THIS)
{
HX_RELEASE(m_pFinishedPkt);
m_bHaveFirstPkt = FALSE;
ClearBufferList();
return HXR_OK;
}
STDMETHODIMP HXConcatenatePayloadFormat::SetStreamHeader(THIS_
IHXValues* pHeader)
{
HX_RESULT res = HXR_FAILED;
HX_RELEASE(m_pHeader);
if (pHeader)
{
m_pHeader = pHeader;
m_pHeader->AddRef();
res = HXR_OK;
}
return res;
}
STDMETHODIMP HXConcatenatePayloadFormat::GetStreamHeader(THIS_
REF(IHXValues*) pHeader)
{
pHeader = m_pHeader;
return (m_pHeader) ? HXR_OK : HXR_FAILED;
}
STDMETHODIMP HXConcatenatePayloadFormat::SetPacket(THIS_
IHXPacket* pPacket)
{
HX_RESULT res = HXR_OK;
if (!pPacket)
{
res = HXR_UNEXPECTED;
}
else if (m_bHaveFirstPkt)
{
UINT32 ulTimeDelta = pPacket->GetTime() - m_ulTimestamp;
if (!MatchesFirstPacket(pPacket) || (ulTimeDelta >= MinPacketDuration))
{
HX_RESULT tmpRes = CreateFinishedPkt();
if (HXR_OK == tmpRes)
{
OnFirstPacket(pPacket);
}
else if (HXR_OUTOFMEMORY == tmpRes)
{
res = HXR_OUTOFMEMORY;
}
else
{
/* Any other errors will just
* cause this packet to get
* queued in the buffer list.
*/
}
}
}
else
{
OnFirstPacket(pPacket);
}
if (HXR_OK == res)
{
res = AddToBufferList(pPacket);
}
return res;
}
STDMETHODIMP HXConcatenatePayloadFormat::GetPacket(THIS_
REF(IHXPacket*) pPacket)
{
HX_RESULT res = HXR_OK;
if (m_bPendingFlush && !m_pFinishedPkt)
{
/* Handle the pending flush*/
res = CreateFinishedPkt();
}
if (m_pFinishedPkt)
{
/* Transfering ownership here */
pPacket = m_pFinishedPkt;
m_pFinishedPkt = NULL;
}
else if (HXR_OK == res)
{
/* We don't have a finished
* packet here. We need more
* packets.
*/
res = HXR_INCOMPLETE;
}
return res;
}
STDMETHODIMP HXConcatenatePayloadFormat::Flush(THIS)
{
HX_RESULT res = HXR_OK;
if (m_pFinishedPkt)
{
m_bPendingFlush = TRUE;
}
else
{
res = CreateFinishedPkt();
}
return res;
}
HX_RESULT HXConcatenatePayloadFormat::CreateFinishedPkt()
{
HX_RESULT res = HXR_UNEXPECTED;
if (!m_pFinishedPkt && m_pCCF && m_bHaveFirstPkt)
{
IHXPacket* pNewPkt = NULL;
IHXBuffer* pBuf = NULL;
if ((HXR_OK == m_pCCF->CreateInstance(CLSID_IHXPacket,
(void**)&pNewPkt)) &&
(HXR_OK == m_pCCF->CreateInstance(CLSID_IHXBuffer,
(void**)&pBuf)) &&
(HXR_OK == pBuf->SetSize(m_ulByteCount)))
{
UCHAR* pCurPos = pBuf->GetBuffer();
/* Copy the buffers in the buffer list */
LISTPOSITION pos = m_bufferList.GetHeadPosition();
while(pos)
{
IHXBuffer* pTmpBuf = (IHXBuffer*)m_bufferList.GetNext(pos);
memcpy(pCurPos, pTmpBuf->GetBuffer(), pTmpBuf->GetSize());
pCurPos += pTmpBuf->GetSize();
}
res = pNewPkt->Set(pBuf, m_ulTimestamp, m_uStream, m_uASMFlags,
m_uASMRule);
if (HXR_OK == res)
{
m_bPendingFlush = FALSE;
m_pFinishedPkt = pNewPkt;
m_pFinishedPkt->AddRef();
m_bHaveFirstPkt = FALSE;
ClearBufferList();
}
}
HX_RELEASE(pNewPkt);
HX_RELEASE(pBuf);
}
return res;
}
HX_RESULT HXConcatenatePayloadFormat::AddToBufferList(IHXPacket* pPacket)
{
IHXBuffer* pBuf = pPacket->GetBuffer();
if (pBuf)
{
m_ulByteCount += pBuf->GetSize();
/* Transfering ownership here.
* We don't need to call HX_RELEASE()
* on pBuf
*/
m_bufferList.AddTail(pBuf);
}
return HXR_OK;
}
void HXConcatenatePayloadFormat::ClearBufferList()
{
while(!m_bufferList.IsEmpty())
{
IHXBuffer* pBuf = (IHXBuffer*)m_bufferList.RemoveHead();
HX_RELEASE(pBuf);
}
m_ulByteCount = 0;
}
BOOL HXConcatenatePayloadFormat::MatchesFirstPacket(IHXPacket* pPacket)
{
BOOL bRet = FALSE;
if (m_bHaveFirstPkt && pPacket &&
(pPacket->GetStreamNumber() == m_uStream) &&
(pPacket->GetASMRuleNumber() == m_uASMRule) &&
(pPacket->GetASMFlags() == m_uASMFlags))
{
bRet = TRUE;
}
return bRet;
}
void HXConcatenatePayloadFormat::OnFirstPacket(IHXPacket* pPacket)
{
m_bHaveFirstPkt = TRUE;
m_ulTimestamp = pPacket->GetTime();
m_uStream = pPacket->GetStreamNumber();
m_uASMFlags = pPacket->GetASMFlags();
m_uASMRule = pPacket->GetASMRuleNumber();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?