⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hantrodecoderwrapper.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       This software is confidential and proprietary and may be used        --
--        only as expressly authorized by a licensing agreement from          --
--                                                                            --
--                            Hantro Products Oy.                             --
--                                                                            --
--      In the event of publication, the following notice is applicable:      --
--                                                                            --
--                   (C) COPYRIGHT 2005 HANTRO PRODUCTS OY                    --
--                            ALL RIGHTS RESERVED                             --
--                                                                            --
--         The entire notice above must be reproduced on all copies.          --
--                                                                            --
--------------------------------------------------------------------------------
--
--  Description : Hantro MPEG-4/H.263 Video Decoder DirectX Media Object 
--
------------------------------------------------------------------------------*/


/*------------------------------------------------------------------------------
    1. Include headers
------------------------------------------------------------------------------*/

#include <windows.h>
#include "HantroDecoderWrapper.h"
#include "HantroDecoderGuids.h"

/*------------------------------------------------------------------------------
    2. Module defines
------------------------------------------------------------------------------*/
#define HDW_LOG

#ifdef HDW_LOG
#include <stdio.h>
static FILE* slog = NULL;
static int csum( void* buffer, int len ) {
	unsigned short* ptr = (unsigned short*)buffer;
	unsigned short cs = 0;
	len /= sizeof(unsigned short);
	while( len-- ) cs += *ptr++;
	return cs;
}
#endif

/*------------------------------------------------------------------------------
    3. CHantroDecoderWrapper class
------------------------------------------------------------------------------*/

CHantroDecoderWrapper::CHantroDecoderWrapper(GUID outputColorSpace)
{
	m_pDecInst = NULL;
	m_pPostProcessor = NULL;
	m_prevTimeIncr = 0;
	m_prevVopTime = 0;
	m_OutputColorSpace = outputColorSpace;

	#ifdef HDW_LOG
	char logname[255];
	static int logcount=0;
	sprintf( logname, "/decoder-log-%d.txt", logcount++ );
	slog = fopen( logname, "w" );
	#endif
}

CHantroDecoderWrapper::~CHantroDecoderWrapper(void)
{
	if( NULL != m_pDecInst )
	{
		MP4SwDecRelease(m_pDecInst);
		m_pDecInst = NULL;
	}

	#ifdef HDW_LOG
	fclose(slog);
	#endif
}

HRESULT CHantroDecoderWrapper::StartStream(void)
{
	MP4SwDecRet rv = MP4SWDEC_OK;

	// Initialize the decoder
	rv = MP4SwDecInit(&m_pDecInst);
	if( rv != MP4SWDEC_OK )
		return S_FALSE;

	// Initialize the post-processor
	m_pPostProcessor = new CHtrPostProc();
	if( NULL == m_pPostProcessor )
	{
		MP4SwDecRelease(m_pDecInst);
		return S_FALSE;
	}
	HRESULT hr = m_pPostProcessor->Initialize();
	if( FAILED(hr) )
	{
		delete m_pPostProcessor;
		MP4SwDecRelease(m_pDecInst);
		return S_FALSE;
	}

	return S_OK;
}

HRESULT CHantroDecoderWrapper::DecodeStream( BYTE* pInputData, LONG inputSize,
                                             REFERENCE_TIME timeStamp, REFERENCE_TIME dur,
                                             BYTE* pOutputData, BOOL* pStreamNotEmpty,
                                             LONG* pWidth, LONG* pHeight,
                                             REFERENCE_TIME* pOutputStart, REFERENCE_TIME* pOutputDuration )
{
	MP4SwDecInput input;
	MP4SwDecOutput output;
	CHtrPostProc::PostProcessorSurface *pIn = NULL, *pOut = NULL;
	CHtrPostProc::QuantizationData *pQpData = NULL;

	input.pStream = pInputData;
	input.dataLen = inputSize;
	input.pExtOutputPic = NULL;

	REFERENCE_TIME start = 0;

	#ifdef HDW_LOG
	int cs = 0;
	#endif

	// "Default" output values
	*pStreamNotEmpty = 0;
	*pWidth  = 0;
	*pHeight = 0;
	*pOutputStart    = INVALID_REFTIME;
	*pOutputDuration = INVALID_REFTIME;

	MP4SwDecRet rv = MP4SwDecDecode(m_pDecInst, &input, &output);
	switch(rv)
	{
	// Vop ready
	case MP4SWDEC_VOP_RDY:
	case MP4SWDEC_VOP_RDY_BUFF_NOT_EMPTY:
		HRESULT hr;
		u32 timeIncrDelta;
		REFERENCE_TIME duration;

		MP4SwDecInfo decInfo;
		MP4SwDecGetInfo(m_pDecInst, &decInfo);

		if( output.timeCode.timeIncr >= m_prevTimeIncr )
			timeIncrDelta = output.timeCode.timeIncr - m_prevTimeIncr;
		else
			timeIncrDelta = output.timeCode.timeIncr + (output.timeCode.timeRes - m_prevTimeIncr);

		// If the input did not have correct timing, we'll look it from the stream
		(INVALID_REFTIME == timeStamp) ? 
			start = m_prevVopTime : start = timeStamp;					
		(INVALID_REFTIME == dur) ? 
			duration = (UNITS/output.timeCode.timeRes)*timeIncrDelta : duration = dur;

		// Get quantization parameters from the file
		MP4SwDecQpInfo qpInfo;		
		// Count the number of quantization parameters based on the frame size (i.e. the number of macroblocks)
		// Number of macroblocks per macroblock line: width % 16 ==  0 ? ( width / 16 ) : ( width / 16 ) + 1;
		u32 mbsPerLine;
		( decInfo.frameWidth % 16 == 0 ) ? 
			( mbsPerLine = decInfo.frameWidth / 16 ) : 
			( mbsPerLine = ( decInfo.frameWidth / 16 ) + 1 );
		// Number of macroblock lines: height % 16 == 0 ? ( height / 16 ) : ( height / 16 ) + 1;
		u32 mbLines;
		( decInfo.frameHeight % 16 == 0 ) ?
			( mbLines = decInfo.frameHeight / 16 ) :
		    ( mbLines = ( decInfo.frameHeight / 16 ) + 1 );
		// Size of data per macroblock line [byte]: 
		//    MbsPerLine % 4 == 0 ? ( MbsPerLine / 4 ) : ( MbsPerLine / 4 ) + ( MbsPerLine % 4 )
		u32 bytesPerLine;
		( mbsPerLine % 4 == 0 ) ? 
			( bytesPerLine = mbsPerLine / 4 ) :
		    ( bytesPerLine = ( mbsPerLine / 4 ) + ( mbsPerLine % 4 ) );
		// Size of the overall data [byte]:
		//    lineSize * noMbLines
		u32 qpInfoSize;
		qpInfoSize = bytesPerLine * mbLines;

        qpInfo.pQp = (u32*)malloc(sizeof(u32)*qpInfoSize);

		MP4SwDecGetQPs(m_pDecInst, &qpInfo);

		// Do color conversion and copy to correct output buffer
		pQpData = new CHtrPostProc::QuantizationData((DWORD*)qpInfo.pQp, qpInfoSize);
		pIn = new CHtrPostProc::PostProcessorSurface((BYTE*)output.pOutputPicture, 
									   decInfo.frameWidth,
									   decInfo.frameHeight,
									   OUTPUTTYPE_IYUV);
		pOut = new CHtrPostProc::PostProcessorSurface(pOutputData,
									   decInfo.frameWidth,
									   decInfo.frameHeight,
									   m_OutputColorSpace);

		//hr = ConvertColorSpace( output.pOutputPicture, MEDIASUBTYPE_IYUV, decInfo.frameWidth, decInfo.frameHeight, pOutputData, m_OutputColorSpace );
		//hr = ConvertColorSpace( (BYTE*)output.pOutputPicture, MEDIASUBTYPE_NULL, decInfo.frameWidth, decInfo.frameHeight, pOutputData, m_OutputColorSpace, (DWORD*)qpInfo.pQp, qpInfoSize );
		hr = m_pPostProcessor->Process(pIn, pOut, pQpData);

		delete pIn;
		delete pOut;
		delete pQpData;
		free(qpInfo.pQp);

		if( hr != S_OK )
		{
			return S_FALSE;
		}

		// Update return values
		*pStreamNotEmpty = rv==MP4SWDEC_VOP_RDY_BUFF_NOT_EMPTY;
		*pWidth  = decInfo.frameWidth;
		*pHeight = decInfo.frameHeight;
		*pOutputStart    = start;
		*pOutputDuration = duration;

		#ifdef HDW_LOG
		cs = csum( output.pOutputPicture, (3*decInfo.frameWidth*decInfo.frameHeight)/2 );
		#endif

		// Book keeping
		m_prevTimeIncr = output.timeCode.timeIncr;
		m_prevVopTime = start + duration;
		break;

	// Successful call, no VOP generated
	case MP4SWDEC_OK:
	case MP4SWDEC_STRM_PROCESSED:
	case MP4SWDEC_HDRS_RDY:
	case MP4SWDEC_VOS_END:
	case MP4SWDEC_HDRS_RDY_BUFF_NOT_EMPTY:
		*pStreamNotEmpty = rv==MP4SWDEC_HDRS_RDY_BUFF_NOT_EMPTY;
		return S_FALSE;
		break; // No output generated

	// Errors
	case MP4SWDEC_PARAM_ERR:
	case MP4SWDEC_STRM_ERR:
	case MP4SWDEC_STRM_ERR_BUFF_NOT_EMPTY:
	case MP4SWDEC_NOT_INITIALIZED:
	case MP4SWDEC_MEMFAIL:
	default:
		return E_FAIL;
		break; // No output generated
	} // switch

	#ifdef HDW_LOG
	fprintf( slog, "%d\t%d\t%d\t%d\t%d\t%04X\n", (int)(timeStamp/10000), inputSize, rv, output.nbrOfErrMBs, (int)(start/10000), cs );
	#endif

	return S_OK; // Success, generated output
}

HRESULT CHantroDecoderWrapper::EndStream(void)
{
	m_pPostProcessor->Close();
	delete m_pPostProcessor;
	MP4SwDecRelease(m_pDecInst);
	m_pDecInst = NULL;
	return S_OK;
}

⌨️ 快捷键说明

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