mp4vdfmt.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 719 行 · 第 1/2 页

CPP
719
字号
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0 and Exhibits. 
 * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM 
 * 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 Community Source 
 * License Version 1.0 (the "RCSL"), including Attachments A though H, 
 * all available at http://www.helixcommunity.org/content/rcsl. 
 * You may also obtain the license terms directly from RealNetworks. 
 * You may not use this file except in compliance with the RCSL and 
 * its Attachments. There are no redistribution rights for the source 
 * code of this file. Please see the applicable 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: 
 * https://rarvcode-tck.helixcommunity.org 
 * 
 * Contributor(s): 
 * 
 * ***** END LICENSE BLOCK ***** */ 


/****************************************************************************
 *  Defines
 */
#define _IGNORE_UNSUPPORTED

#define NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD  33		// in milliseconds
#if defined(HELIX_FEATURE_MIN_HEAP)
#define MP4V_DEFAULT_PREROLL		    2000	// in milliseconds
#else
#define MP4V_DEFAULT_PREROLL		    3500	// in milliseconds
#endif

#define MAX_NONKEY_CODED_FRAME_FALLBEHIND -800

/****************************************************************************
 *  Includes
 */
#include "mp4vdfmt.h"

#include "hxasm.h"
#include "hxwin.h"
#include "hxvsurf.h"
#include "hxvctrl.h"
#include "hxsite2.h"
#include "hxthread.h"

#include "hxtick.h"
#include "hxassert.h"
#include "hxstrutl.h"
#include "unkimp.h"
#include "timeval.h"
#include "cttime.h"
#include "hxcodec.h"

#include "mp4video.h"

/****************************************************************************
 *  Locals
 */


/****************************************************************************
 *  Method:
 *    CMP4VideoFormat::CQTVideoFormat
 *
 */
CMP4VideoFormat::CMP4VideoFormat(IHXCommonClassFactory* pCommonClassFactory,
				 CMP4VideoRenderer* pMP4VideoRenderer,
				 BOOL bSecure)
    : CVideoFormat(pCommonClassFactory, pMP4VideoRenderer)
    , m_pMP4VideoRenderer(pMP4VideoRenderer)
    , m_pRssm(NULL)
    , m_pDecoder(NULL)
    , m_pInputAllocator(NULL)
    , m_ulMaxDecodedFrames(0)
{
    HX_ASSERT(m_pCommonClassFactory);
    HX_ASSERT(pMP4VideoRenderer);

    m_DecodedPacket.dataLength = 0;
    m_DecodedPacket.data = NULL;

    m_DecoderDims.cx = 0;
    m_DecoderDims.cy = 0;

    m_pMP4VideoRenderer->AddRef();
}


/****************************************************************************
 *  Method:
 *    CMP4VideoFormat::~CQTVideoFormat
 *
 */
CMP4VideoFormat::~CMP4VideoFormat()
{
    CVideoFormat::Reset();

    HX_RELEASE(m_pMP4VideoRenderer);

    if (m_pRssm)
    {
	m_pRssm->Close();
	m_pRssm->Release();
	m_pRssm = NULL;
    }

    HX_DELETE(m_pDecoder);

    _Reset();

    HX_DELETE(m_pInputAllocator);
}


/****************************************************************************
 *  Method:
 *    CMP4VideoFormat::Init
 */
HX_RESULT CMP4VideoFormat::Init(IHXValues* pHeader)
{
    HX_RESULT retVal = CVideoFormat::Init(pHeader);

    // Create memory allocators
    if (SUCCEEDED(retVal))
    {
	retVal = CreateAllocators();
    }

    // Create Packet Assembler
    if (SUCCEEDED(retVal))
    {
	retVal = HXR_OUTOFMEMORY;
	m_pRssm = new MP4VPayloadFormat(m_pInputAllocator);
	if (m_pRssm)
	{
	    m_pRssm->AddRef();
	    retVal = HXR_OK;
	}
    }
    
    // Create Decoder
    if (SUCCEEDED(retVal))
    {
	retVal = HXR_OUTOFMEMORY;
    m_pDecoder = CreateDecoder();
	if (m_pDecoder)
	{
	    retVal = HXR_OK;
	}
    }

    // Initialize Assembler
    if (SUCCEEDED(retVal) && m_pRssm)
    {
	retVal = m_pRssm->Init(m_pCommonClassFactory, FALSE);
    }
    
    if (SUCCEEDED(retVal) && m_pRssm)
    {
	retVal = m_pRssm->SetStreamHeader(pHeader);

	if (retVal == HXR_NO_DATA)
	{
	    retVal = HXR_OK;
	}

#ifdef _IGNORE_UNSUPPORTED
	if (FAILED(retVal))
	{
	    HXxSize nullViewFrame = {1, 1};
	    m_pMP4VideoRenderer->ResizeViewFrame(nullViewFrame);
	    HX_RELEASE(m_pRssm);
	    retVal = HXR_OK;
	}
#endif	// _IGNORE_UNSUPPORTED

    }

    // Initialize Decoder
    if (SUCCEEDED(retVal) && m_pRssm)
    {
	retVal = m_pDecoder->Init(m_pMP4VideoRenderer->GetContext(),
				  this,
				  NULL,
				  m_pInputAllocator,
				  m_pMP4VideoRenderer->m_pOutputAllocator);
	
#ifdef _IGNORE_UNSUPPORTED
	if (FAILED(retVal))
	{
	    HXxSize nullViewFrame = {1, 1};
	    m_pMP4VideoRenderer->ResizeViewFrame(nullViewFrame);
	    HX_RELEASE(m_pRssm);
	    retVal = HXR_OK;
	}
#endif	// _IGNORE_UNSUPPORTED
    }

    m_DecoderDims.cx = 0;
    m_DecoderDims.cy = 0;

    m_ulMaxDecodedFrames = GetMaxDecodedFrames();

    return retVal;
}


/****************************************************************************
 *  Method:
 *    CVideoFormat::GetDefaultPreroll
 *
 */
ULONG32 CMP4VideoFormat::GetDefaultPreroll(IHXValues* pValues)
{
    return MP4V_DEFAULT_PREROLL;
}


/****************************************************************************
 *  Method:
 *    CQTVideoFormat::GetBitstreamHeaderSize
 */
ULONG32 CMP4VideoFormat::GetBitstreamHeaderSize(void)
{
    ULONG32 ulSize = 0;

    if (m_pRssm)
    {
	ulSize = m_pRssm->GetBitstreamHeaderSize();
    }

    return ulSize;
}


/****************************************************************************
 *  Method:
 *    CQTVideoFormat::GetBitstreamHeader
 */
const UINT8* CMP4VideoFormat::GetBitstreamHeader(void)
{
    const UINT8* pHeader = NULL;

    if (m_pRssm)
    {
	pHeader = m_pRssm->GetBitstreamHeader();
    }

    return pHeader;
}


/****************************************************************************
 *  Method:
 *    CQTVideoFormat::CreateAssembledPacket
 */
CMediaPacket* CMP4VideoFormat::CreateAssembledPacket(IHXPacket* pCodecData)
{
    ULONG32* pCodecPacketRaw = NULL;
    HXCODEC_DATA* pCodecPacket;
    CMediaPacket* pFramePacket = NULL;
    IHXPacket* pPacket = NULL;

#ifdef _IGNORE_UNSUPPORTED
    if (!m_pRssm)
    {
	return NULL;
    }
#endif // _IGNORE_UNSUPPORTED

    m_pMP4VideoRenderer->BltIfNeeded();

    m_LastError = m_pRssm->SetPacket(pCodecData);
    if( m_LastError == HXR_OUTOFMEMORY )
    {
        return NULL;
    }
    m_pRssm->CreateHXCodecPacket(pCodecPacketRaw);
    pCodecPacket = (HXCODEC_DATA*) pCodecPacketRaw;
    
    if (pCodecPacket)
    {
	pFramePacket = new CMediaPacket(
				pCodecPacket,
				(UINT8*) pCodecPacket, 
				pCodecPacket->dataLength,
				pCodecPacket->dataLength,
				pCodecPacket->timestamp,
				pCodecPacket->flags, //0,
				NULL);
	
	if (pFramePacket == NULL)
	{
	    HX_ASSERT(HXR_OUTOFMEMORY == HXR_OK);
	    KillInputBuffer(pCodecPacket, this);
            m_LastError == HXR_OUTOFMEMORY;
            return NULL;
	}
	else
	{
	    pFramePacket->SetBufferKiller(KillInputBuffer);
	    pFramePacket->m_pUserData = this;
	}
	
	m_pMP4VideoRenderer->BltIfNeeded();
    }
    
    return pFramePacket;
}


/****************************************************************************
 *  Method:
 *    CMP4VideoFormat::Reset
 */
void CMP4VideoFormat::Reset()
{
    _Reset();
    CVideoFormat::Reset();
}

void CMP4VideoFormat::_Reset(void)
{
    ReleaseDecodedPacket(&m_DecodedPacket);

    if (m_pRssm)
    {
	m_pRssm->Reset();
	m_pRssm->SetTimeAnchor(GetStartTime());
    }

    m_DecoderDims.cx = 0;
    m_DecoderDims.cy = 0;
}

void CMP4VideoFormat::ReleaseDecodedPacket(HXCODEC_DATA* pDecodedPacket)
{
    HX_ASSERT(pDecodedPacket);

    if (pDecodedPacket->data && 
	m_pMP4VideoRenderer && 
	m_pMP4VideoRenderer->m_pOutputAllocator)
    {
	m_pMP4VideoRenderer->m_pOutputAllocator->ReleasePacketPtr(pDecodedPacket->data);
	pDecodedPacket->data = NULL;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?