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

📄 fmfcdecfilter.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// File: fMFCDecFilter.cpp
//
// Desc: implement CMFCDecFilter class
//
// Author : JiyoungShin(idon.shin@samsung.com)
//
// Copyright 2007 Samsung System LSI, All rights reserved.
//------------------------------------------------------------------------------

#include "stdafx.h"
#include "MFCDecFilter.h"
#include "fMFCDecFilter.h"
#include "fMFCDecFilter_ip.h"
#include "fMFCDecFilter_op.h"

#include <windows.h>
#include <stdio.h>


#include "SsbSipMpeg4Decode.h"
#include "SsbSipH264Decode.h"
#include "SsbSipVC1Decode.h"

#define	YV12			1
#define	RGB565			2
#define OUTPIN_TYPE		(YV12)


extern "C" void _initConvTab();
extern "C" void _yuv420ToRgb565(unsigned char *p_lum, unsigned char *p_cb, unsigned char *p_cr, int w_src, int h_src,
                            unsigned char *dest,  int w_dst, int h_dst,
							int topdown);


//
// Constructor
//
CMFCDecFilter::CMFCDecFilter(LPUNKNOWN pUnk, HRESULT *phr)
	: CTransformFilter(NAME("MFC Decoder Filter"), pUnk, CLSID_MFCDecFilter)
{
    CAutoLock cAutoLock(&m_csFilter);

	if (SUCCEEDED(*phr))
	{
		// Create an output pin
		CMFCDecFilterOutputPin *pOut = new CMFCDecFilterOutputPin(phr, this, L"Out");
		if (pOut)
		{
			if (SUCCEEDED(*phr))
				m_pOutput = pOut;
			else
				delete pOut;
		}
		else
			*phr = E_OUTOFMEMORY;

		//
		// NOTE!: If we've created our own output pin we must also create
		// the input pin ourselves because the CTransformFilter base class 
		// will create an extra output pin if the input pin wasn't created.        
		//
		CMFCDecFilterInputPin *pIn = new CMFCDecFilterInputPin(phr, this, L"In");
		if (pIn)
		{
			if (SUCCEEDED(*phr))
				m_pInput = pIn;
			else
				delete pIn;
		}
		else
			*phr = E_OUTOFMEMORY;
	}

	this->m_MP4IsFirstTransform  = TRUE;
	this->m_H264IsFirstTransform = TRUE;
	this->m_VC1IsFirstTransform  = TRUE;
	this->m_WMV9sFirstTransform  = TRUE;

	this->decode_ctx             = NULL;


#if (OUTPIN_TYPE != YV12)
	_initConvTab();
#endif
}


//
// Destructor
//
CMFCDecFilter::~CMFCDecFilter()
{
	if (decode_ctx == NULL)
		return;

	if((m_StrmType == RAW_STRM_TYPE_M4V) && (decode_ctx != NULL))
	{
		SsbSipMPEG4DecodeDeInit(decode_ctx);
		decode_ctx = NULL;
	}
	else if((m_StrmType == RAW_STRM_TYPE_H264RAW) && (decode_ctx != NULL))
	{
		SsbSipH264DecodeDeInit(decode_ctx);
		decode_ctx = NULL;
	}
	else if((m_StrmType == RAW_STRM_TYPE_RCV) && (decode_ctx != NULL))
	{
		SsbSipVC1DecodeDeInit(decode_ctx);
		decode_ctx = NULL;
	}
	else if((m_StrmType == VIDEO_STRM_TYPE_WMV9) && (decode_ctx != NULL))
	{
		SsbSipVC1DecodeDeInit(decode_ctx);
		decode_ctx = NULL;
	}


RETAILMSG(1, (L"\n   ---  {{CMFCDecFilter}}   Destructor"));
}


//
// Transform
//
HRESULT CMFCDecFilter::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
	HRESULT     hr;
	long            y_size, u_size;
	BYTE	    *pDataOut;


	// Copy IMediaSample data except for data
	hr = CopySample(pIn, pOut);
	if (FAILED(hr))
		return hr;

	hr = pOut->GetPointer(&pDataOut);
	if (FAILED(hr))
		return hr;

	y_size = m_Width * m_Height;
	u_size = y_size >> 2;


#if (OUTPIN_TYPE == YV12)
	memcpy(pDataOut, m_pFrmBuf, y_size);
	memcpy(pDataOut + y_size, m_pFrmBuf + y_size + u_size, u_size);
	memcpy(pDataOut + y_size + u_size, m_pFrmBuf + y_size, u_size);
	pOut->SetActualDataLength(m_FrmSize);

#else
	_yuv420ToRgb565(m_pFrmBuf, m_pFrmBuf + y_size, m_pFrmBuf + y_size + u_size, m_Width, m_Height,
	                pDataOut, m_Width, m_Height,
	                1);
	pOut->SetActualDataLength(y_size << 1);
#endif


	return hr;
}


//
// CheckInputType
//
HRESULT CMFCDecFilter::CheckInputType(const CMediaType *mtIn)
{
	unsigned int	*size;
	long			length =0;

	
	if (IsEqualGUID(*mtIn->Type(), MEDIATYPE_Stream) == TRUE) {
		if (IsEqualGUID(mtIn->subtype, MEDIASUBTYPE_m4v) == TRUE)
			m_StrmType = RAW_STRM_TYPE_M4V;
		else if (IsEqualGUID(mtIn->subtype, MEDIASUBTYPE_h264raw) == TRUE)
			m_StrmType = RAW_STRM_TYPE_H264RAW;
		else if (IsEqualGUID(mtIn->subtype, MEDIASUBTYPE_rcv) == TRUE)
			m_StrmType = RAW_STRM_TYPE_RCV;
		else
			return VFW_E_TYPE_NOT_ACCEPTED;
	}
	else if (IsEqualGUID(*mtIn->Type(), MEDIATYPE_Video) == TRUE) {
		if(mtIn->subtype ==WMMEDIASUBTYPE_WMV3)
			m_StrmType = VIDEO_STRM_TYPE_WMV9;
		else if(mtIn->subtype ==WMMEDIASUBTYPE_wmv3)
			m_StrmType = VIDEO_STRM_TYPE_WMV9;
		else
			return VFW_E_TYPE_NOT_ACCEPTED;
	}
	else
		return VFW_E_TYPE_NOT_ACCEPTED;

	size = (unsigned int *) mtIn->Format();
	length = mtIn->FormatLength();
	
	if(m_StrmType == VIDEO_STRM_TYPE_WMV9)
	{
		m_Width  = size[13];
		m_Height = size[14];
		m_Wmvdata = size[22];
	}
	else
	{
		m_Width = size[0];
		m_Height =size[1];
	}
	
	RETAILMSG(1, (L"\n{ MFC DECODER FILTER } CheckInputType OK, filetype = %d, size=(%d,%d)\n", m_StrmType, size[0], size[1]));

	return S_OK;
}


//
// CheckTransform
//
HRESULT CMFCDecFilter::CheckTransform(const CMediaType *pmtIn, const CMediaType *pmtOut)
{
	return S_OK;
}


//
// DecideBufferSize
//
HRESULT CMFCDecFilter::DecideBufferSize(IMemAllocator *pAllocator, ALLOCATOR_PROPERTIES *pProperties)
{
	// First, the input pin has to be connected
	if (m_pInput->IsConnected() == FALSE)
		return E_UNEXPECTED;

	ASSERT(pAllocator);
	ASSERT(pProperties);

	HRESULT hr;

    // Pass the allocator requirements to our output side
    // but do a little sanity checking first
    pProperties->cBuffers  = 1;
	pProperties->cbPrefix  = 0;
#if (OUTPIN_TYPE == YV12)
	pProperties->cbBuffer  = ((m_Width*m_Height*3)>>1);
#else
	pProperties->cbBuffer  = ((m_Width*m_Height)<<1)+1;
#endif

    ALLOCATOR_PROPERTIES Actual;
	hr = pAllocator->SetProperties(pProperties, &Actual);
	if (FAILED(hr)) 
	{
		RETAILMSG(1,(L"[MFC Filter]wmv9 DecideBufferSize  end fail 1.\n"));
		return hr;
	}

    // Make sure we got the right alignment and at least the minimum required
	if (pProperties->cBuffers > Actual.cBuffers ||
		pProperties->cbBuffer > Actual.cbBuffer ||
		pProperties->cbAlign > Actual.cbAlign) 
	{
		RETAILMSG(1,(L"[MFC Filter]wmv9 DecideBufferSize  end fail 2.\n"));
		return E_FAIL;
	}

	return S_OK;
}


//
// GetMediaType
//
HRESULT CMFCDecFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
	DWORD	*pDwBitMask;

	if (m_pInput->IsConnected() == FALSE)
	{
		return E_UNEXPECTED;
	}
	if (iPosition < 0) 
	{
		return E_INVALIDARG;
	}

	VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pMediaType->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER) + sizeof(DWORD)*3);
	if (vih == NULL) 
	{
		RETAILMSG(STATUS, (TEXT("\n[MFC Filter]VIDEOINFOHEADER:E_OUTOFMEMORY\n")));
		return E_OUTOFMEMORY;
	}
	pDwBitMask = (DWORD *)((BYTE *)vih + sizeof(VIDEOINFOHEADER));
	ZeroMemory(vih, sizeof (VIDEOINFOHEADER) + sizeof(DWORD)*3);

	pMediaType->SetFormatType(&FORMAT_VideoInfo);
	vih->bmiHeader.biSize	= sizeof(BITMAPINFOHEADER);

	vih->bmiHeader.biWidth	= m_Width;	//Width of the image
	vih->bmiHeader.biHeight = m_Height;	//Height of image
	vih->bmiHeader.biPlanes = 1;

	switch(iPosition)
	{
#if (OUTPIN_TYPE == YV12)
	case 0:
		vih->bmiHeader.biCompression= MEDIASUBTYPE_YV12.Data1;
		vih->bmiHeader.biBitCount	= 12;		//Bits/Pixel
		pMediaType->SetSubtype(&MEDIASUBTYPE_YV12);
		vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader);
		break;
#else
	case 0:
		vih->bmiHeader.biCompression= BI_BITFIELDS;
		vih->bmiHeader.biBitCount	= 16;		//Bits/Pixel
		pMediaType->SetSubtype(&MEDIASUBTYPE_RGB565);
		pDwBitMask[0] = 0x0000f800;
		pDwBitMask[1] = 0x000007e0;
		pDwBitMask[2] = 0x0000001f;
		vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader);
		break;
#endif
	default:
		RETAILMSG(STATUS, (TEXT("\n[MFC Filter]GetMediaType:Position\n")));
		return VFW_S_NO_MORE_ITEMS;
	}

	pMediaType->SetType(&MEDIATYPE_Video);
	pMediaType->SetTemporalCompression(FALSE);
	pMediaType->SetSampleSize(vih->bmiHeader.biSizeImage);
	pMediaType->SetFormat((BYTE *)vih, sizeof(VIDEOINFOHEADER) + sizeof(DWORD)*3);//cc
	return S_OK;
}

//
// When Stream ends
//
HRESULT CMFCDecFilter::EndOfStream()
{

	
	return CTransformFilter::EndOfStream();
}


//
// Copy
//
HRESULT CMFCDecFilter::CopySample(IMediaSample *pSource, IMediaSample *pDest)
{
	// Copy the sample times
	REFERENCE_TIME TimeStart, TimeEnd;
	if (NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
		pDest->SetTime(&TimeStart, &TimeEnd);

	LONGLONG MediaStart, MediaEnd;
	if (pSource->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR)
		pDest->SetMediaTime(&MediaStart,&MediaEnd);

	// Copy the Sync point property
	HRESULT hr = pSource->IsSyncPoint();
	if (hr == S_OK)
		pDest->SetSyncPoint(TRUE);
	else if (hr == S_FALSE)
		pDest->SetSyncPoint(FALSE);
	else	// an unexpected error has occured...
		return E_UNEXPECTED;

	// Copy the media type
	AM_MEDIA_TYPE *pMediaType;
	pSource->GetMediaType(&pMediaType);
	pDest->SetMediaType(pMediaType);
	DeleteMediaType(pMediaType);

	// Copy the preroll property
	hr = pSource->IsPreroll();
	if (hr == S_OK)
		pDest->SetPreroll(TRUE);
	else if (hr == S_FALSE)
		pDest->SetPreroll(FALSE);
	else	// an unexpected error has occured...
		return E_UNEXPECTED;

	// Copy the discontinuity property
	hr = pSource->IsDiscontinuity();
	if (hr == S_OK)
		pDest->SetDiscontinuity(TRUE);
	else if (hr == S_FALSE)
		pDest->SetDiscontinuity(FALSE);
	else	// an unexpected error has occured...
		return E_UNEXPECTED;

	return S_OK;
}


//
// H264Transform
//
HRESULT CMFCDecFilter::MP4Decode(IMediaSample* pSample)
{
	BYTE						*pDataIn;
	HRESULT						hr;
	unsigned int					dwBytesToRead;
	BYTE						*pStrmBuf;
	SSBSIP_MPEG4_STREAM_INFO    stream_info;


	hr = pSample->GetPointer(&pDataIn);
	if (FAILED(hr))
		return hr;

	dwBytesToRead = pSample->GetActualDataLength();

	////////////////////////////////////////////////
	// 1. Decoder init							  //
	////////////////////////////////////////////////
	if(m_MP4IsFirstTransform) {
		decode_ctx = SsbSipMPEG4DecodeInit();
		if (decode_ctx == NULL) {
			RETAILMSG(1,(L"[MFC Filter]SsbSipMPEG4DecodeInit Failed.\n"));
			return 0;

		}
		
		////////////////////////////////////////////////
		// 2. Data copy								  //
		////////////////////////////////////////////////
		pStrmBuf = (BYTE*) SsbSipMPEG4DecodeGetInBuf(decode_ctx, dwBytesToRead);
		memcpy(pStrmBuf, pDataIn, dwBytesToRead);

		////////////////////////////////////////////////
		// 3. Decoder Init							  //
		////////////////////////////////////////////////
		if (SsbSipMPEG4DecodeExe(decode_ctx, dwBytesToRead) != SSBSIP_MPEG4_DEC_RET_OK) {
			RETAILMSG(1,(L"MPEG4 Decoder Configuration Failed.\n"));
			return 0;
		}

⌨️ 快捷键说明

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