📄 smppkfdr.cpp
字号:
/* ***** 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 ***** */
/****************************************************************************
* Includes
*/
#include "raformat.h"
#include "smppkfdr.h"
/****************************************************************************
* Defines
*/
/****************************************************************************
* CRealAudioSimplePacketFeeder
*/
/****************************************************************************
* Constructor & Destructor
*/
CRealAudioSimplePacketFeeder::CRealAudioSimplePacketFeeder
(
CStreamParam& refStreamParam,
CInterleaveBufs& refIBufs,
UINT16* pRuleToFlagMap,
UINT16 uStreamNumber
)
: m_StreamParam(refStreamParam)
, m_IBufs(refIBufs)
, m_pRuleToFlagMap(pRuleToFlagMap)
, m_pPendingPacketQueue(NULL)
, m_ulContinueDiscardUntilTime(NO_TIME_SET)
, m_ulSequence(0)
, m_uStreamNumber(uStreamNumber)
, m_bEndOfPackets(FALSE)
, m_ulLastPacketTime(NO_TIME_SET)
{
m_pPendingPacketQueue = new CHXSimpleList;
}
CRealAudioSimplePacketFeeder::~CRealAudioSimplePacketFeeder(void)
{
_Reset();
HX_DELETE(m_pPendingPacketQueue);
}
/****************************************************************************
* Interface methods
*/
HX_RESULT CRealAudioSimplePacketFeeder::OnPacket(IHXPacket* pPacket,
LONG32 lTimeOffset,
UINT16* rule_to_flag_map)
{
HX_RESULT retVal = HXR_OK;
if (m_ulContinueDiscardUntilTime != NO_TIME_SET)
{
// when we find the superblock that contins the discard until time
// we are done and should start putting packets into the queue again
if (pPacket &&
(!pPacket->IsLost()))
{
if (IsTimeGreater(pPacket->GetTime() + GetSuperBlockTime(),
m_ulContinueDiscardUntilTime) &&
((rule_to_flag_map == NULL) ||
(rule_to_flag_map[pPacket->GetASMRuleNumber()] & HX_KEYFRAME_FLAG)))
{
m_ulContinueDiscardUntilTime = NO_TIME_SET;
}
}
if (m_ulContinueDiscardUntilTime != NO_TIME_SET)
{
// Discard this packet
pPacket = NULL;
}
}
if (pPacket)
{
if (!pPacket->IsLost())
{
m_ulLastPacketTime = pPacket->GetTime();
}
m_pPendingPacketQueue->AddTail(pPacket);
pPacket->AddRef();
}
// fill up the interleave buffer from the packet queue
FillISuperBlock();
return retVal;
}
void CRealAudioSimplePacketFeeder::LossOccured(void)
{
;
}
void CRealAudioSimplePacketFeeder::Reset(void)
{
_Reset();
}
void CRealAudioSimplePacketFeeder::OnEndOfPackets(void)
{
m_bEndOfPackets = TRUE;
}
BOOL CRealAudioSimplePacketFeeder::IsActive(void)
{
BOOL bRetVal = (!m_pPendingPacketQueue->IsEmpty());
return bRetVal;
}
BOOL
CRealAudioSimplePacketFeeder::FillISuperBlock(void)
{
BOOL bIsLost;
UINT16 usFlag;
UINT32 ulDataSize;
UINT8* pPacketData;
IHXBuffer* pPacketBuffer;
IHXPacket* pPacket;
HX_RESULT status;
while ((!m_IBufs.IsISuperBlockDone()) &&
(!m_pPendingPacketQueue->IsEmpty()))
{
pPacket = (IHXPacket*) m_pPendingPacketQueue->RemoveHead();
pPacketBuffer = pPacket->GetBuffer();
bIsLost = TRUE;
ulDataSize = 0;
pPacketData = NULL;
usFlag = 0;
if ((!pPacket->IsLost()) && pPacketBuffer)
{
bIsLost = FALSE;
ulDataSize = pPacketBuffer->GetSize();
pPacketData = pPacketBuffer->GetBuffer();
if (m_pRuleToFlagMap)
{
usFlag = m_pRuleToFlagMap[pPacket->GetASMRuleNumber()];
}
}
status = m_IBufs.OnPacket(pPacketData,
ulDataSize,
m_ulSequence,
pPacket->GetTime(),
bIsLost,
usFlag);
if (SUCCEEDED(status))
{
m_ulSequence++;
}
else
{
if (m_IBufs.IsISuperBlockDone())
{
m_pPendingPacketQueue->AddHead(pPacket);
pPacket = NULL;
pPacketBuffer = NULL;
}
else
{
// Packet was rejected and did not accomplish completion
// of a super-block. Throw it away.
m_ulSequence++;
}
}
HX_RELEASE(pPacketBuffer);
HX_RELEASE(pPacket);
}
return m_IBufs.IsISuperBlockFilled();
}
BOOL
CRealAudioSimplePacketFeeder::IsCurrentTimeRangeEnded(void)
{
BOOL bTimeRangeEnded = m_bEndOfPackets;
return bTimeRangeEnded;
}
BOOL
CRealAudioSimplePacketFeeder::IsCurrentTimeRangeEmpty(void)
{
BOOL bTimeRangeEmpty = m_pPendingPacketQueue->IsEmpty();
return bTimeRangeEmpty;
}
UINT32
CRealAudioSimplePacketFeeder::GetCurrentTimeRangeEnd(void)
{
UINT32 ulPacketEndTime = m_ulLastPacketTime + ((UINT32) GetMSPerBlock());
UINT32 ulBufferEndTime = m_IBufs.m_IBlockTimeRange.m_ulEnd;
UINT32 ulRet = (((ulBufferEndTime != NO_TIME_SET) &&
IsTimeGreater(ulBufferEndTime, ulPacketEndTime)) ?
ulBufferEndTime : ulPacketEndTime);
return ulRet;
}
BOOL
CRealAudioSimplePacketFeeder::SetCrossFadeEndTime(UINT32 ulTimestamp)
{
// move data forward if we can
FillISuperBlock();
return Discard(ulTimestamp, FALSE); // Discard after time
}
BOOL
CRealAudioSimplePacketFeeder::Discard(UINT32 ulTimestamp, BOOL bBefore)
{
IHXPacket* pPacket;
BOOL bDone = FALSE;
BOOL bDiscard = FALSE;
if (!m_pPendingPacketQueue->IsEmpty())
{
// Remove from the unregistration queue if in there
LISTPOSITION currentPosition = NULL;
LISTPOSITION nextPosition = m_pPendingPacketQueue->GetHeadPosition();
do
{
currentPosition = nextPosition;
pPacket = (IHXPacket*) m_pPendingPacketQueue->GetNext(nextPosition);
if ((!bDiscard && !bBefore) || (bDiscard && bBefore))
{
if (!pPacket->IsLost())
{
if (bBefore)
{
bDiscard = IsTimeLess(pPacket->GetTime(), ulTimestamp);
}
else
{
bDiscard = IsTimeGreaterOrEqual(pPacket->GetTime(), ulTimestamp);
}
if (!bDone)
{
// We are done if packets exist preceeding the discard point
bDone = (!bDiscard);
}
}
}
if (bDiscard)
{
m_pPendingPacketQueue->RemoveAt(currentPosition);
HX_RELEASE(pPacket);
}
} while (nextPosition);
}
return bDone;
}
BOOL
CRealAudioSimplePacketFeeder::DiscardTillEndOfCrossFade(UINT32 ulTimestamp,
BOOL bHandled)
{
m_ulContinueDiscardUntilTime = NO_TIME_SET;
if (!bHandled)
{
bHandled = Discard(ulTimestamp, TRUE); // Discard before time
}
// if still not done, continue discard until done
if (!bHandled)
{
// this means we have to watch packets coming into the format
// and toss out blocks for superblocks that are earlier than
// this time
m_ulContinueDiscardUntilTime = ulTimestamp;
}
return bHandled;
}
HX_RESULT
CRealAudioSimplePacketFeeder::SetupForNextTimeRange(void)
{
m_ulContinueDiscardUntilTime = NO_TIME_SET;
return HXR_OK;
}
/****************************************************************************
* Protected methods
*/
void
CRealAudioSimplePacketFeeder::_Reset(void)
{
IHXPacket* pPacket;
if (m_pPendingPacketQueue != NULL)
{
while (!m_pPendingPacketQueue->IsEmpty())
{
pPacket = (IHXPacket*)m_pPendingPacketQueue->RemoveHead();
HX_RELEASE(pPacket);
}
}
m_ulContinueDiscardUntilTime = NO_TIME_SET;
m_ulLastPacketTime = NO_TIME_SET;
m_bEndOfPackets = FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -