rvxvdfmt.cpp

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

CPP
1,012
字号
/* ***** 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 _IGNORE_UNSUPPORTED

#if !defined(HELIX_FEATURE_MIN_HEAP)
#define MAX_BUFFERED_DECODED_RV_FRAMES		15
#else	// HELIX_FEATURE_MIN_HEAP
#define MAX_BUFFERED_DECODED_RV_FRAMES		2
#endif	// HELIX_FEATURE_MIN_HEAP

#define NON_KEYFRM_DCDE_FALLBEHIND_THRSHLD  66		// in milliseconds
#if defined(HELIX_FEATURE_MIN_HEAP)
#define RVXV_DEFAULT_PREROLL		    2000	// in milliseconds
#else
#define RVXV_DEFAULT_PREROLL		    3500	// in milliseconds
#endif

#define IMG_FORMAT_POSSIBLE_CHANGE	    1
#define IMG_FORMAT_FORCED_CHANGE	    2

#define DECODE_CALLBACK_RNGBUF_SIZE	    10

#define UNINITIALIZED_SEQ_NUMBER	    0xFFFFFFFF

#define MAX_KEY_CODED_FRAME_FALLBEHIND -1200
#define MAX_NONKEY_CODED_FRAME_FALLBEHIND -800


/****************************************************************************
 *  Includes
 */
#include "rvxvdfmt.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 "hxmtypes.h"

#include "rvxvideo.h"

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


/****************************************************************************
 *  Method:
 *    CRVXVideoFormat::CQTVideoFormat
 *
 */
CRVXVideoFormat::CRVXVideoFormat(IHXCommonClassFactory* pCommonClassFactory,
				 CRVXVideoRenderer* pRVXVideoRenderer)
    : CVideoFormat(pCommonClassFactory, pRVXVideoRenderer)
    , m_pRVXVideoRenderer(pRVXVideoRenderer)
    , m_pRssm(NULL)
    , m_pDecoder(NULL)
    , m_pInputAllocator(NULL)
    , m_ulMaxDecodedFrames(0)
    , m_ulWidthContainedInSegment(0)
    , m_ulHeightContainedInSegment(0)
    , m_pCodecOutputBIH(NULL)
    , m_pDecodedRngBuf(NULL)
    , m_bFirstDecode(TRUE)
    , m_ulLastSequenceNumber(UNINITIALIZED_SEQ_NUMBER)
    , m_bFlushingToKeyFrame(FALSE)

{
    HX_ASSERT(m_pCommonClassFactory);
    HX_ASSERT(pRVXVideoRenderer);

    m_sMediaSize.cx = 0;
    m_sMediaSize.cy = 0;

    m_pRVXVideoRenderer->AddRef();

}


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

    HX_RELEASE(m_pRVXVideoRenderer);

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

    FlushDecodedRngBuf();
    HX_DELETE(m_pDecodedRngBuf);

    HX_DELETE(m_pDecoder);

    _Reset();

    if (m_pInputAllocator)
    {
        m_pInputAllocator->Release();
        m_pInputAllocator = NULL;
    }
    HX_DELETE(m_pCodecOutputBIH);

}


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

    m_bFlushingToKeyFrame = FALSE;

    // Create Decode callback to caller ring buffer
    if (SUCCEEDED(retVal))
    {
	m_pDecodedRngBuf = new CRingBuffer(DECODE_CALLBACK_RNGBUF_SIZE);
	retVal = HXR_OUTOFMEMORY;
	if (m_pDecodedRngBuf)
	{
	    retVal = HXR_OK;
	}
    }

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

    // Create Packet Assembler
    if (SUCCEEDED(retVal))
    {
	retVal = HXR_OUTOFMEMORY;
	m_pRssm = new RVXPayloadFormat(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_pRVXVideoRenderer->GetContext(), 
			       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_pRVXVideoRenderer->ResizeViewFrame(nullViewFrame);
	    HX_RELEASE(m_pRssm);
	    retVal = HXR_OK;
	}
#endif	// _IGNORE_UNSUPPORTED

    }

    // Initialize Decoder
    if (SUCCEEDED(retVal) && m_pRssm)
    {
	retVal = m_pDecoder->Init(m_pRVXVideoRenderer->GetContext(),
				  this,
				  NULL,
				  m_pInputAllocator,
				  m_pRVXVideoRenderer->m_pOutputAllocator);

	if (SUCCEEDED(retVal))
	{
	    HX_MOF* pImageInfo;
	    
	    if (m_pDecoder->GetImageInfo(pImageInfo) == HXR_OK)
	    {
		retVal = SetupOutputFormat(pImageInfo, m_pDecoder->GetMofTagIn());

		if (SUCCEEDED(retVal))
		{
		    if ((m_sMediaSize.cx != 0) && (m_sMediaSize.cy != 0))
		    {
			m_pRVXVideoRenderer->ResizeViewFrame(m_sMediaSize);
		    }
		}
	    }
	}
	
#ifdef _IGNORE_UNSUPPORTED
	if (FAILED(retVal))
	{
	    HXxSize nullViewFrame = {1, 1};
	    m_pRVXVideoRenderer->ResizeViewFrame(nullViewFrame);
	    HX_RELEASE(m_pRssm);
	    retVal = HXR_OK;
	}
#endif	// _IGNORE_UNSUPPORTED
    }

    m_bFirstDecode = TRUE;

    m_ulMaxDecodedFrames = GetMaxDecodedFrames();

    return retVal;
}


/****************************************************************************
 *  Method:
 *    CRVXVideoFormat::SetupOutputFormat
 *
 */
HX_RESULT
CRVXVideoFormat::SetupOutputFormat(HX_MOF* pMof, HX_MOFTAG moftagIn)
{
    HX_RESULT pnr = HXR_OK;
    HX_FORMAT_IMAGE* pMofOutI = (HX_FORMAT_IMAGE*) pMof;

    if (!m_pCodecOutputBIH)
    {
	m_pCodecOutputBIH = new HXBitmapInfoHeader;
	if (!m_pCodecOutputBIH)
	{
	    return HXR_OUTOFMEMORY;
	}
    }

    m_pRVXVideoRenderer->m_ulPadWidthLeft = 0;
    m_pRVXVideoRenderer->m_ulPadWidthRight = 0;
    m_pRVXVideoRenderer->m_ulPadHeightTop = 0;
    m_pRVXVideoRenderer->m_ulPadHeightBottom = 0;

    m_sMediaSize.cy = pMofOutI->uiHeight;
    m_sMediaSize.cx = pMofOutI->uiWidth;

    m_pCodecOutputBIH->biWidth = pMofOutI->uiWidth;
    m_pCodecOutputBIH->biHeight = pMofOutI->uiHeight;
    m_pCodecOutputBIH->biPlanes = 1;
 
    switch(pMofOutI->submoftag)
    {
        case HX_RGB3_ID:
        {
            m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
            m_pCodecOutputBIH->biCompression = BI_RGB;
        }
        break;
        case HX_YUV420_ID:
        {
            // fix up CLV1 screwed up bitcount
            if (moftagIn == HX_CLEARVIDEO_ID)
            {
                pMofOutI->uiBitCount = 12;
            }

            HX_ASSERT(pMofOutI->uiBitCount == 12);

            m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
            m_pCodecOutputBIH->biCompression = HX_I420;
        
            if (pMofOutI->moftag == HX_MEDIA_IMAGE2)
            {
                HX_FORMAT_IMAGE2* pMofOutI2 = (HX_FORMAT_IMAGE2*)pMof;

                // if we are getting YUV out, it is a format image 2 struct
                // and we need to include padding in this width and height
		m_pRVXVideoRenderer->m_ulPadWidthLeft = pMofOutI2->uiPadWidthLeft;
		m_pRVXVideoRenderer->m_ulPadWidthRight = pMofOutI2->uiPadWidthRight;
		m_pRVXVideoRenderer->m_ulPadHeightTop = pMofOutI2->uiPadHeightTop;
		m_pRVXVideoRenderer->m_ulPadHeightBottom = pMofOutI2->uiPadHeightBottom;
            }
        }
        break;
#ifdef _WINDOWS
        case HX_RGB555_ID:
        {
            HX_ASSERT(pMofOutI->uiBitCount == 16);
            m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
            m_pCodecOutputBIH->biCompression = BI_BITFIELDS;

            m_pCodecOutputBIH->rcolor =   0x00007C00; // red
            m_pCodecOutputBIH->gcolor =   0x000003E0; // green
            m_pCodecOutputBIH->bcolor =   0x0000001F; // blue
        }
        break;
        case HX_RGB565_ID:
        {
            HX_ASSERT(pMofOutI->uiBitCount == 16);
            m_pCodecOutputBIH->biBitCount = pMofOutI->uiBitCount;
            m_pCodecOutputBIH->biCompression = BI_BITFIELDS;
            m_pCodecOutputBIH->rcolor =    0x0000F800; // red
            m_pCodecOutputBIH->gcolor =    0x000007E0; // green
            m_pCodecOutputBIH->bcolor =    0x0000001F; // blue
        }
        break;
#endif
        default:
            pnr = HXR_DEC_TYPE_MISMATCH;
    }

    m_pCodecOutputBIH->biWidth += (m_pRVXVideoRenderer->m_ulPadWidthLeft + 
				   m_pRVXVideoRenderer->m_ulPadWidthRight);
    m_pCodecOutputBIH->biHeight += (m_pRVXVideoRenderer->m_ulPadHeightTop + 
				    m_pRVXVideoRenderer->m_ulPadHeightBottom);
    m_pCodecOutputBIH->biSizeImage =
	m_pCodecOutputBIH->biWidth * m_pCodecOutputBIH->biBitCount * 
	m_pCodecOutputBIH->biHeight / 8;

    return pnr;
}


/****************************************************************************
 *  Method:
 *    CRVXVideoFormat::GetDefaultPreroll
 *
 */
ULONG32 CRVXVideoFormat::GetDefaultPreroll(IHXValues* pValues)
{
    return RVXV_DEFAULT_PREROLL;
}


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

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

    return ulSize;
}


/****************************************************************************
 *  Method:
 *    CRVXVideoFormat::GetBitstreamHeader
 */
const HX_MOF* CRVXVideoFormat::GetBitstreamHeader(void)
{
    const HX_MOF* pHeader = NULL;

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

    return pHeader;
}


/****************************************************************************
 *  Method:
 *    CVideoFormat::GetMaxDecodedFrames
 *
 */
ULONG32 CRVXVideoFormat::GetMaxDecodedFrames(void)
{
    return MAX_BUFFERED_DECODED_RV_FRAMES;
}


/****************************************************************************
 *  Method:
 *    CRVXVideoFormat::CreateAssembledPacket
 */
CMediaPacket* CRVXVideoFormat::CreateAssembledPacket(IHXPacket* pCodecData)
{
    HXCODEC_DATA* pCodecPacket = NULL;
    CMediaPacket* pFramePacket = NULL;
    IHXPacket* pPacket = NULL;
    HX_RESULT retVal = HXR_OK;

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

    m_pRVXVideoRenderer->BltIfNeeded();

    retVal = m_pRssm->SetPacket(pCodecData);
    if( retVal == HXR_OUTOFMEMORY )
    {
        m_LastError = HXR_OUTOFMEMORY;
        return NULL;
    }
    m_pRssm->CreateHXCodecPacket(pCodecPacket);

    
    while (pCodecPacket)
    {
        CheckPacketBuffer(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;

	    // Report missing frames as dropped
	    if (m_ulLastSequenceNumber != UNINITIALIZED_SEQ_NUMBER)
	    {
		UINT16 uFramesDropped = pCodecPacket->sequenceNum -
					((UINT16) m_ulLastSequenceNumber) - 1;
		if (uFramesDropped != 0)
		{

⌨️ 快捷键说明

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