📄 vidrendf.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 ***** */
#ifdef ENABLE_TRACE
#define HX_TRACE_THINGY(x, m, l) \
{ \
FILE* f1; \
f1 = ::fopen(x, "a+"); \
(f1)?(::fprintf(f1, "%ld - %s = %ld \n", HX_GET_BETTERTICKCOUNT(), m, l), ::fclose(f1)):(0);\
}
#define STAMPBUF(x, m) \
{ \
FILE* f1; \
f1 = ::fopen(x, "a+"); \
(f1)?(::fprintf(f1, "%ld - %s\n", HX_GET_BETTERTICKCOUNT(), m), ::fclose(f1)):(0);\
}
#else // ENABLE_TRACE
#define HX_TRACE_THINGY(x, m, l)
#ifdef MEASURE_PERF
#define LOGBUFFSIZE 100000
char textmem[LOGBUFFSIZE];
char *textptr = textmem;
#define STAMPBUF(x, txt) { if (textptr - textmem < LOGBUFFSIZE) textptr += SafeSprintf(textptr, LOGBUFFSIZE - (textptr - textmem), "%s: %ld*\n", txt, HX_GET_BETTERTICKCOUNT()); }
#else // MEASURE_PERF
#define STAMPBUF(x, txt)
#endif // MEASURE_PERF
#endif // ENABLE_TRACE
/****************************************************************************
* Defines
*/
#if !defined(HELIX_FEATURE_MIN_HEAP)
#define MAX_BUFFERED_DECODED_FRAMES 12
#else // HELIX_FEATURE_MIN_HEAP
#define MAX_BUFFERED_DECODED_FRAMES 2
#endif // HELIX_FEATURE_MIN_HEAP
#if defined(HELIX_FEATURE_MIN_HEAP)
#define FORMAT_MINIMUM_PREROLL 1000
#define FORMAT_DEFAULT_PREROLL 2000
#define FORMAT_MAXIMUM_PREROLL 3000
#else
#define FORMAT_MINIMUM_PREROLL 3000
#define FORMAT_DEFAULT_PREROLL 5000
#define FORMAT_MAXIMUM_PREROLL 15000
#endif
#define MAX_DECODE_SPIN 100
/****************************************************************************
* Includes
*/
#include "vidrendf.h"
#include "vidrend.h"
#include "hxtick.h"
#include "hxassert.h"
#include "hxstrutl.h"
/****************************************************************************
* Debug
*/
#ifdef ENABLE_FRAME_TRACE
#define MAX_FRAME_TRACE_ENTRIES 100000
ULONG32 ulFrameTraceIdx = 0;
LONG32 frameTraceArray[MAX_FRAME_TRACE_ENTRIES][3];
void DumpFrameEntries(void)
{
FILE* pFile = NULL;
ULONG32 ulIdx;
if (ulFrameTraceIdx > 0)
{
pFile = fopen("c:\\buf.txt", "wb");
}
if (pFile)
{
for (ulIdx = 0; ulIdx < ulFrameTraceIdx; ulIdx++)
{
fprintf(pFile, "%c(%d) = %x\n", (char) frameTraceArray[ulIdx][1],
frameTraceArray[ulIdx][2],
frameTraceArray[ulIdx][0]);
}
fclose(pFile);
}
ulFrameTraceIdx = 0;
}
#endif // ENABLE_FRAME_TRACE
/****************************************************************************
* Method:
* CVideoFormat::CVideoFormat
*
*/
CVideoFormat::CVideoFormat(IHXCommonClassFactory* pCommonClassFactory,
CVideoRenderer* pVideoRenderer)
: m_pCommonClassFactory(pCommonClassFactory)
, m_pVideoRenderer(pVideoRenderer)
, m_pMutex(NULL)
, m_pAssemblerMutex(NULL)
, m_pOutputQueue(NULL)
, m_pFramePool(NULL)
, m_lMaxBufferedDecodedFrames(MAX_BUFFERED_DECODED_FRAMES)
, m_pHeader(NULL)
, m_ulStartTime(0)
, m_bDecodeSuspended(FALSE)
, m_bRawPacketsDone(FALSE)
, m_lRefCount(0)
, m_LastError(HXR_OK)
{
HX_ASSERT(m_pCommonClassFactory);
m_pCommonClassFactory->AddRef();
m_pVideoRenderer->AddRef();
#ifdef THREADS_SUPPORTED
HXMutex::MakeMutex(m_pMutex);
HXMutex::MakeMutex(m_pAssemblerMutex);
HXMutex::MakeMutex(m_pDecoderMutex);
#else
HXMutex::MakeStubMutex(m_pMutex);
HXMutex::MakeStubMutex(m_pAssemblerMutex);
HXMutex::MakeStubMutex(m_pDecoderMutex);
#endif
}
/****************************************************************************
* Method:
* CVideoFormat::~CVideoFormat
*
*/
CVideoFormat::~CVideoFormat()
{
_Reset();
HX_DELETE(m_pFramePool);
HX_DELETE(m_pOutputQueue);
HX_DELETE(m_pMutex);
HX_DELETE(m_pAssemblerMutex);
HX_DELETE(m_pDecoderMutex);
HX_RELEASE(m_pHeader);
HX_RELEASE(m_pVideoRenderer);
HX_RELEASE(m_pCommonClassFactory);
#ifdef ENABLE_FRAME_TRACE
DumpFrameEntries();
#endif // ENABLE_FRAME_TRACE
}
/****************************************************************************
* Method:
* CVideoFormat::Init
*
*/
HX_RESULT CVideoFormat::Init(IHXValues* pHeader)
{
HX_RESULT retVal = HXR_OK;
HX_RELEASE(m_pHeader);
m_pHeader = pHeader;
if (m_pHeader)
{
m_pHeader->AddRef();
}
if (SUCCEEDED(retVal))
{
m_pFramePool = CreateBufferPool();
}
if (SUCCEEDED(retVal))
{
m_lMaxBufferedDecodedFrames = GetMaxDecodedFrames();
FlushOutputQueue();
HX_DELETE(m_pOutputQueue);
m_pOutputQueue = new CRingBuffer(m_lMaxBufferedDecodedFrames);
retVal = HXR_OUTOFMEMORY;
if (m_pOutputQueue)
{
retVal = HXR_OK;
}
}
return retVal;
}
/****************************************************************************
* Method:
* CVideoFormat::CreateBufferPool
*
*/
CHXBufferPool* CVideoFormat::CreateBufferPool(void)
{
return new CHXBufferPool(
(BufferSizeFunc) CMediaPacket::GetBufferSize,
(BufferKillerFunc) CMediaPacket::DeletePacket);
}
/****************************************************************************
* Method:
* CVideoFormat::CreateAssembledPacket
*
*/
CMediaPacket* CVideoFormat::CreateAssembledPacket(IHXPacket* pPayloadData)
{
CMediaPacket* pFramePacket = NULL;
BOOL bIsKeyframe = FALSE;
if (pPayloadData->IsLost())
{
pFramePacket = NULL;
}
else
{
IHXBuffer* pBuffer = pPayloadData->GetBuffer();
if (pBuffer)
{
pFramePacket = new CMediaPacket(pBuffer->GetBuffer(),
pBuffer->GetBuffer(),
pBuffer->GetSize(),
pBuffer->GetSize(),
pPayloadData->GetTime(),
MDPCKT_USES_IHXBUFFER_FLAG,
NULL);
pBuffer->Release();
}
}
return pFramePacket;
}
/****************************************************************************
* Method:
* CVideoFormat::ReturnAssembledPacket
*
*/
void CVideoFormat::ReturnAssembledPacket(CMediaPacket* pFramePacket)
{
if (pFramePacket)
{
m_pMutex->Lock();
m_InputQueue.AddTail(pFramePacket);
m_pMutex->Unlock();
}
}
/****************************************************************************
* Method:
* CVideoFormat::Enqueue
*
*/
BOOL CVideoFormat::Enqueue(IHXPacket* pPayloadData)
{
BOOL bEnqueued = FALSE;
CMediaPacket* pFramePacket = NULL;
m_pAssemblerMutex->Lock();
pFramePacket = CreateAssembledPacket(pPayloadData);
if (pFramePacket != NULL)
{
m_pMutex->Lock();
m_InputQueue.AddTail(pFramePacket);
m_pMutex->Unlock();
bEnqueued = TRUE;
}
m_pAssemblerMutex->Unlock();
return bEnqueued;
}
/****************************************************************************
* Method:
* CVideoFormat::Requeue
*
*/
HX_RESULT CVideoFormat::Requeue(CMediaPacket* pFramePacket)
{
if (pFramePacket != NULL)
{
m_pMutex->Lock();
m_InputQueue.AddHead(pFramePacket);
m_pMutex->Unlock();
}
return HXR_OK;
}
/****************************************************************************
* Method:
* CVideoFormat::Dequeue
*
*/
CMediaPacket* CVideoFormat::Dequeue(void)
{
CMediaPacket* pPacket = (CMediaPacket*) m_pOutputQueue->Get();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -