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

📄 hantrodecoderdmo.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       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 "HantroDecoderDMO.h" // Class declaration
#include "HantroDecoderGuids.h"

#pragma warning(disable:4100)  // Disable C4100: unreferenced formal parameter

/*------------------------------------------------------------------------------
    2. Module defines
------------------------------------------------------------------------------*/

#define HDDMO_LOG
#define HDDMO_TRACE   /*printf*/

#ifdef HDDMO_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. TypesMatch function
------------------------------------------------------------------------------*/
//  Helper - compares media types - ignoring the advisory fields
static bool TypesMatch(const DMO_MEDIA_TYPE *pmt1, const DMO_MEDIA_TYPE *pmt2) 
{
    if(pmt1->majortype   == pmt2->majortype &&
        pmt1->subtype     == pmt2->subtype &&
        pmt1->lSampleSize == pmt2->lSampleSize &&
        pmt1->formattype  == pmt2->formattype &&
        pmt1->cbFormat    == pmt2->cbFormat  &&
        0 == memcmp(pmt1->pbFormat, pmt2->pbFormat, pmt1->cbFormat)
      ) 
    {
        return true;
    }
    else 
    {
        return false;
    }
}

/*------------------------------------------------------------------------------
    4. CHantroDecoderDMO class
------------------------------------------------------------------------------*/
// Private method that returns a new instance. 
CUnknown* WINAPI CHantroDecoderDMO::CreateInstance( LPUNKNOWN pUnk, HRESULT *pHr )
{
    CHantroDecoderDMO *pNewObject = new CHantroDecoderDMO(pUnk);
    if( pNewObject == NULL )
    {
        *pHr = E_OUTOFMEMORY;
        return NULL;
    }

    *pHr = S_OK;
    return pNewObject;
} 

// This method retrieves information about an input stream, such as any restrictions on 
// the number of samples per buffer, and whether the stream performs a lookahead on the 
// input data. This information never changes.
//
// Parameters
//
//  dwInputStreamIndex
//    Zero-based index of an input stream on the DMO. 
//  pdwFlags
//    [out] Pointer to a variable that receives a bitwise combination of zero or more
//    DMO_INPUT_STREAM_INFO_FLAGS flags. 
//
// Return Values
//
// Returns an HRESULT value. Possible values include the following.
//  Value 						Description
//  S_OK 						Success
//  DMO_E_INVALIDSTREAMINDEX 	Invalid stream index
//  E_POINTER 					NULL pointer argument
HRESULT CHantroDecoderDMO::InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags)
{
    //  We can process data on any boundary
    *pdwFlags = 0;
    return S_OK;
}

// This method retrieves information about an output stream; for example, whether the stream is 
// discardable and whether it uses a fixed sample size. This information never changes.
//
// Parameters
//
//  dwOutputStreamIndex
//    Zero-based index of an output stream on the DMO. 
//  pdwFlags
//    [out] Pointer to a variable that receives a bitwise combination of zero or more 
//    DMO_OUTPUT_STREAM_INFO_FLAGS flags. 
//
// Return Values
//
// Returns an HRESULT value. Possible values include the following.
//  Value 						Description
//  S_OK 						Success
//  DMO_E_INVALIDSTREAMINDEX 	Invalid stream index
//  E_POINTER 					NULL pointer argument
HRESULT CHantroDecoderDMO::InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags)
{
	//  We output single frames
    *pdwFlags = DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
                DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
                DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE;

    return S_OK;
}

// This method queries whether an input stream can accept a given media type. 
// The derived class must declare and implement this method.
//
// Parameters
//
// dwInputStreamIndex
//    Index of an input stream. 
// pmt
//    Pointer to a DMO_MEDIA_TYPE structure that describes the media type. 
//
// Return Values
//    Returns S_OK if the media type is valid or otherwise returns DMO_E_INVALIDTYPE.
HRESULT CHantroDecoderDMO::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
	// Check if the type is already set and if so reject any type that's not identical
    if (InputTypeSet(dwInputStreamIndex)) {
        if (!TypesMatch(pmt, InputType(dwInputStreamIndex))) {
            return DMO_E_INVALIDTYPE;
        } else {
            return S_OK;
        }
    }
    
	// We accept only major type video
	if( MEDIATYPE_Video != pmt->majortype )
		return DMO_E_INVALIDTYPE;

	// Check for supported subtypes
	for( int i=0; i<4; i++ )
	{
		if( pmt->subtype == INPUTTYPE_MP4V ||
			pmt->subtype == INPUTTYPE_mp4v ||
			pmt->subtype == INPUTTYPE_H263 ||
			pmt->subtype == INPUTTYPE_h263 )
			break;
		if( i == 3 )
			return DMO_E_INVALIDTYPE;
	}

    // Check that format is defined 
	if( !(pmt->formattype == FORMAT_VideoInfo ||
		  pmt->formattype == FORMAT_VideoInfo2) )
	{
		return DMO_E_INVALIDTYPE;
	}
	if( pmt->pbFormat == NULL )
	{
		return DMO_E_INVALIDTYPE;
	}

    // If we got here, everything is ok
	return S_OK;
}

// This method queries whether an output stream can accept a given media type. The 
// derived class must declare and implement this method.
//
// Parameters
//
// dwOutputStreamIndex
//    Index of an output stream. 
// pmt
//    Pointer to a DMO_MEDIA_TYPE structure that describes the media type. 
//
// Return Values
//    Returns S_OK if the media type is valid or otherwise returns DMO_E_INVALIDTYPE.
HRESULT CHantroDecoderDMO::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
    //  Check if the type is already set and if so reject any type that's not identical
    if (OutputTypeSet(dwOutputStreamIndex)) {
        if (!TypesMatch(pmt, OutputType(dwOutputStreamIndex))) {
            return DMO_E_INVALIDTYPE;
        } else {
            return S_OK;
        }
    }
    
	// If input type is not set, output information can't be delivered
	if (!InputTypeSet(0)) {
		return DMO_E_TYPE_NOT_SET;
	}

	// Check the major type
	if( pmt->majortype != MEDIATYPE_Video )
	{
		return DMO_E_INVALIDTYPE;
	}

	// Check for supported subtypes
	for( int i=0; i<3; i++ )
	{
		if( pmt->subtype == OUTPUTTYPE_IYUV || 
			pmt->subtype == OUTPUTTYPE_iyuv ||
			pmt->subtype == MEDIASUBTYPE_RGB565 )
			break;
		if( i == 1 )
			return DMO_E_INVALIDTYPE;
	}

	if (pmt->formattype == FORMAT_VideoInfo &&
		pmt->pbFormat != NULL) {
			// get input and output formats
			const VIDEOINFOHEADER* pvihInput = (const VIDEOINFOHEADER*)InputType(0)->pbFormat;
			const VIDEOINFOHEADER* pvihOutput = (const VIDEOINFOHEADER*)pmt->pbFormat;
			const BITMAPINFOHEADER pbihInput = (const BITMAPINFOHEADER)pvihInput->bmiHeader;

			if (pmt->subtype == OUTPUTTYPE_IYUV || 
			    pmt->subtype == OUTPUTTYPE_iyuv )
			{
			// Check that we are supporting compression
			for( i=0; i<sizeof(supportedInputFourCCs)/sizeof(supportedInputFourCCs[0]); i++ )
			{
				if( pbihInput.biCompression == supportedInputFourCCs[i] )
					break;
				if( i == sizeof(supportedInputFourCCs)/sizeof(supportedInputFourCCs[0]) - 1 )
					return DMO_E_INVALIDTYPE;
			}
			}
			else if (pmt->subtype == MEDIASUBTYPE_RGB565 )
			{
				if( pbihInput.biCompression == BI_BITFIELDS)	// Unpacked RGB data )
					return S_OK;
			}
			
			return S_OK;
		}
	// no video information available
    return DMO_E_INVALIDTYPE;
}

// This method retrieves a preferred media type for a specified input stream.
//
// Parameters
//
//  dwInputStreamIndex
//    Zero-based index of an input stream on the DMO. 
//  dwTypeIndex
//    Zero-based index on the set of acceptable media types. 
//  pmt
//    [out] Pointer to a DMO_MEDIA_TYPE structure allocated by the caller. The 
//    method fills the structure with the media type. The format block might be NULL,
//    in which case the format type GUID is GUID_NULL. 
//
// Return Values
//
// Returns an HRESULT value. Possible values include the following.
//  Value 						Description
//  S_OK 						Success
//  DMO_E_INVALIDSTREAMINDEX 	Invalid stream index
//  DMO_E_NO_MORE_ITEMS 		Type index is out of range
//  E_OUTOFMEMORY 				Insufficient memory
//  E_POINTER 					NULL pointer argument
HRESULT CHantroDecoderDMO::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
                                      DMO_MEDIA_TYPE *pmt)
{
	if( dwTypeIndex >= 4 )
		return DMO_E_NO_MORE_ITEMS;

	memset(pmt, 0, sizeof(DMO_MEDIA_TYPE));
	pmt->bFixedSizeSamples = FALSE;
	pmt->bTemporalCompression = TRUE;
	pmt->lSampleSize = 0;
	pmt->majortype = MEDIATYPE_Video;
	switch( dwTypeIndex )
	{
	case 0:
		pmt->subtype = INPUTTYPE_MP4V;
		break;
	case 1:
		pmt->subtype = INPUTTYPE_mp4v;
		break;
	case 2:
		pmt->subtype = INPUTTYPE_H263;
		break;
	case 3:
		pmt->subtype = INPUTTYPE_h263;
		break;
	}

    return S_OK;
}

// This method retrieves a preferred media type for a specified output stream.
//
// Parameters
//
//  dwOutputStreamIndex
//    Zero-based index of an output stream on the DMO. 
//  dwTypeIndex
//    Zero-based index on the set of acceptable media types. 
//  pmt
//    [out] Pointer to a DMO_MEDIA_TYPE structure allocated by the caller. The 
//    method fills the structure with the media type. The format block might be NULL, 
//    in which case the format type GUID is GUID_NULL. 
//
// Return Values
//
//  Returns an HRESULT value. Possible values include the following.
//  Value 						Description
//  S_OK 						Success
//  DMO_E_INVALIDSTREAMINDEX 	Invalid stream index
//  DMO_E_NO_MORE_ITEMS 		Type index is out of range
//  E_OUTOFMEMORY 				Insufficient memory
//  E_POINTER 					NULL pointer argument
HRESULT CHantroDecoderDMO::InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
                                       DMO_MEDIA_TYPE *pmt)
{
	// If input type is not set, output information can't be delivered
	if (!InputTypeSet(0))
        return DMO_E_TYPE_NOT_SET;

	if( dwTypeIndex >= 3 )
		return DMO_E_NO_MORE_ITEMS;

    // If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
    // Return DMO_E_NO_MORE_ITEMS if the type does not exists.  See the 
    // documentation for IMediaObject::GetOutputType() for more information.
    if (NULL != pmt) {
        if (dwOutputStreamIndex == 0) {

            //  Create our media type
            HRESULT hr = MoInitMediaType(pmt, FIELD_OFFSET(VIDEOINFO, dwBitMasks[3]));
            if (FAILED(hr)) {
                return hr;
            }

			const VIDEOINFOHEADER *pvihInput = (const VIDEOINFOHEADER *)InputType(0)->pbFormat;
            LONG lWidth  = pvihInput->bmiHeader.biWidth;
            LONG lHeight = pvihInput->bmiHeader.biHeight;

            //  Initialize the media type structure (MoInitMediaType initalized cbFormat
            //  and pbFormat)
            pmt->majortype            = MEDIATYPE_Video;
			switch( dwTypeIndex )
			{
			case 0:
				pmt->subtype          = OUTPUTTYPE_IYUV;
				break;
			case 1:
				pmt->subtype          = OUTPUTTYPE_iyuv;
				break;
			case 2:
				pmt->subtype          = MEDIASUBTYPE_RGB565;
				break;
			}
            pmt->bFixedSizeSamples    = TRUE;
            pmt->bTemporalCompression = FALSE;
			if( pmt->subtype == MEDIASUBTYPE_RGB565 )
			{
				pmt->lSampleSize          = lWidth * lHeight * 2;
			}
			else
			{
				pmt->lSampleSize          = ( lWidth * lHeight * 3 ) / 2;
			}
            pmt->formattype           = FORMAT_VideoInfo;

⌨️ 快捷键说明

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