📄 hantrodecoderwrapper.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 + -