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

📄 fframeextractfilter.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
字号:
//------------------------------------------------------------------------------
// File: fFrameExtractFilter.cpp
//
// Desc: implement CFrameExtractFilter class.
//
// Author : JiyoungShin(idon.shin@samsung.com)
//
// Copyright 2007 Samsung System LSI, All rights reserved.
//------------------------------------------------------------------------------

#include "stdafx.h"
#include "FrameExtractFilter.h"
#include "fFrameExtractFilter.h"
#include "fFrameExtractFilter_op.h"

#include <stdio.h>
#include "FrameExtractor.h"
#include "H264Frames.h"
#include "H263Frames.h"
#include "MPEG4Frames.h"
#include "VC1Frames.h"


static unsigned char delimiter_H264[]  = {0x00, 0x00, 0x00, 0x01}; // H.264
static unsigned char delimiter_MPEG4[] = {0x00, 0x00, 0x01}; //MPEG4


#include "FileRead.h"
#ifndef DATAREAD_TYPE
#error "DATAREAD_TYPE is not defined."
#endif
#if (DATAREAD_TYPE == DATA_FILE)
	#define FRAMEX_IN_TYPE_SEL	(FRAMEX_IN_TYPE_FILE)
#else
	#define FRAMEX_IN_TYPE_SEL	(FRAMEX_IN_TYPE_MEM)
#endif


//
// Constructor
//
CFrameExtractFilter::CFrameExtractFilter(LPUNKNOWN pUnk, HRESULT *phr)
	: CSource(NAME("CFrameExtractFilter"), pUnk, CLSID_FrameExtractFilter),
	m_pwFileName(NULL), m_File(NULL), m_pFramexCtx(NULL)
{
    CAutoLock cAutoLock(&m_cStateLock);

	//
	// CSource::AddPin() is automatically called
	// by creating a source stream (CSourceStream)
	//

	// Add one source stream (output pin)!
	new CFrameExtractFilterStream(phr, this, L"Out");

	m_first = 1;
}


//
// Destructor
//
CFrameExtractFilter::~CFrameExtractFilter()
{
	// Close file
	if (m_File)
		SSB_FILE_CLOSE(m_File);

	if (m_pwFileName)
		delete[] m_pwFileName;

	if (m_pFramexCtx)
		FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
}


//
// Load
//
STDMETHODIMP CFrameExtractFilter::Load(LPCOLESTR pwszFileName, const AM_MEDIA_TYPE *pmt)
{
	// IFileSourceFilter::Load()
	// Any calls to this method after the first call will fail!

	if (m_pwFileName)
		return E_FAIL;

	CheckPointer(pwszFileName, E_POINTER);

	// lstrlenW is one of the few Unicode functions that works on win95
	DWORD dwSize = lstrlenW(pwszFileName) + 1;

	TCHAR pszFileName[MAX_PATH] = {0};
	lstrcpy(pszFileName, pwszFileName);

	CAutoLock lck(&m_cStateLock);

	// file checking
	HRESULT hr = CheckFile(pszFileName, pmt);
	
	if (FAILED(hr))
		return E_FAIL;

	// Restore the current file name
	m_pwFileName = new WCHAR[dwSize];

	if (m_pwFileName != NULL)
		CopyMemory(m_pwFileName, pwszFileName, dwSize * sizeof(WCHAR));

	return S_OK;
}


//
// GetCurFile
//
STDMETHODIMP CFrameExtractFilter::GetCurFile(LPOLESTR *ppwszFileName, AM_MEDIA_TYPE *pmt)
{
	CheckPointer(ppwszFileName, E_POINTER);
	*ppwszFileName = NULL;

	if (m_pwFileName != NULL) 
	{
		DWORD dwSize = sizeof(WCHAR) * (1 + lstrlenW(m_pwFileName));
		
		*ppwszFileName = (LPOLESTR)CoTaskMemAlloc(dwSize);
		if (*ppwszFileName != NULL) 
		{
			CopyMemory(*ppwszFileName, m_pwFileName, dwSize);
		
		}
	}

	if (pmt != NULL) 
	{
		CopyMediaType(pmt, &m_mt);
	}

	return S_OK;
}


int CFrameExtractFilter::GetNextFrame(unsigned char *pFrameBuf, unsigned int *pSize)
{
	int nRead;


	// 贸澜 龋免登绰 版快绰 config stream阑 府畔茄促.
	if (m_first) {
		switch (m_StrmType) {
		case RAW_STRM_TYPE_M4V:
			m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_MPEG4, 3, 1);
			FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
			nRead = ExtractConfigStreamMpeg4((FRAMEX_CTX *) m_pFramexCtx, m_File, pFrameBuf, *pSize, NULL);
			break;

		case RAW_STRM_TYPE_H264RAW:
			m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_H264, 4, 1);
			FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
			nRead = ExtractConfigStreamH264((FRAMEX_CTX *) m_pFramexCtx, m_File, pFrameBuf, *pSize, NULL);
			break;

		case RAW_STRM_TYPE_RCV:
			nRead = ExtractConfigStreamVC1(m_File, pFrameBuf, *pSize, NULL);
			break;

		default:
			return -1;
		}

		m_first = 0;

		return nRead;
	}

	switch (m_StrmType) {
	case RAW_STRM_TYPE_M4V:
		nRead = NextFrameMpeg4((FRAMEX_CTX *) m_pFramexCtx, (FILE *) m_File, pFrameBuf, *pSize, NULL);
		break;

	case RAW_STRM_TYPE_H264RAW:
		nRead = NextFrameH264((FRAMEX_CTX *) m_pFramexCtx, (FILE *) m_File, pFrameBuf, *pSize, NULL);
		break;

	case RAW_STRM_TYPE_RCV:
		nRead = NextFrameVC1(m_File, pFrameBuf, *pSize, NULL);
		break;

	default:
		return -1;
	}
	
	if (nRead <= 5)
		return -1;

	return nRead;
}


//
// ReadTheFile
//
HRESULT CFrameExtractFilter::CheckFile(LPCTSTR pszFileName, const AM_MEDIA_TYPE *pmt)
{
	TCHAR         file_ext[4];

	int           nRead;
	unsigned int  width, height;
	union {
		MPEG4_CONFIG_DATA mpeg4_conf;
		H263_CONFIG_DATA  h263_conf;
		H264_CONFIG_DATA  h264_conf;
		VC1_CONFIG_DATA   vc1_conf;
	} u;

	unsigned char *p_confbuf;


#define FILE_EXT_M4V	L".m4v"
#define FILE_EXT_H264	L".264"
#define FILE_EXT_RCV	L".rcv"

	if (wcslen(pszFileName) > 4)
		wcsncpy(file_ext, pszFileName + (wcslen(pszFileName) - 4), 4);
	else
		file_ext[0] = 0;

	// Identify the codec type according to the filename extention
	if(_wcsnicmp(file_ext, FILE_EXT_M4V, 4) == 0)
		m_StrmType = RAW_STRM_TYPE_M4V;
	else if(_wcsnicmp(file_ext, FILE_EXT_H264, 4) == 0)
		m_StrmType = RAW_STRM_TYPE_H264RAW;
	else if(_wcsnicmp(file_ext, FILE_EXT_RCV, 4) == 0)
		m_StrmType = RAW_STRM_TYPE_RCV;
	else{
		RETAILMSG(1, (L"[FrameExtractFilter]unsupported file type(%s)\n", pszFileName));
		return E_FAIL;
	}

	// Open file
	m_File = SSB_FILE_OPEN(pszFileName);
	if (m_File == NULL){
		RETAILMSG(1, (L"[FrameExtractFilter]file(%s) doesn't exist\n", pszFileName));
		return E_FAIL;
	}

#define CONFIG_STRM_LENG_MAX	(128 * 1024)	// 128 KB
	p_confbuf = (unsigned char *) malloc(CONFIG_STRM_LENG_MAX);
	if (p_confbuf == NULL) {
		RETAILMSG(1, (L"[FrameExtractFilter] memory allocation for CONFIG_STRM failed.\n"));
		SSB_FILE_CLOSE(m_File);
		return E_FAIL;
	}
	// Obtaininig Width, Height
	memset(&u, 0, sizeof(u));
	switch (m_StrmType) {
	case RAW_STRM_TYPE_M4V:
		m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_MPEG4, 3, 1);
		FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
		nRead = ExtractConfigStreamMpeg4((FRAMEX_CTX *) m_pFramexCtx, m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.mpeg4_conf));
		FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
		m_pFramexCtx = NULL;

		width  = u.mpeg4_conf.width;
		height = u.mpeg4_conf.height;
		break;

	case RAW_STRM_TYPE_H264RAW:
		m_pFramexCtx = FrameExtractorInit(FRAMEX_IN_TYPE_SEL, delimiter_H264, 4, 1);
		FrameExtractorFirst((FRAMEX_CTX *) m_pFramexCtx, m_File);
		nRead = ExtractConfigStreamH264((FRAMEX_CTX *) m_pFramexCtx, m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.h264_conf));
		FrameExtractorFinal((FRAMEX_CTX *) m_pFramexCtx);
		m_pFramexCtx = NULL;

		width  = u.h264_conf.width;
		height = u.h264_conf.height;
		break;

	case RAW_STRM_TYPE_RCV:
		nRead = ExtractConfigStreamVC1(m_File, p_confbuf, CONFIG_STRM_LENG_MAX, &(u.vc1_conf));

		width  = u.vc1_conf.width;
		height = u.vc1_conf.height;
		break;

	default:
		free(p_confbuf);
		SSB_FILE_CLOSE(m_File);
		return E_FAIL;
	}

	// Close file
	free(p_confbuf);
	SSB_FILE_CLOSE(m_File);


	// Validate the width & height value
	if ((width > 720) || (width < 16) || (height > 576) || (height < 16)) {
		RETAILMSG(1, (L"[FrameExtractFilter] video size is too big. (width=%d, height=%d)\n", width, height));
		return E_FAIL;
	}

	// Open file
	m_File = SSB_FILE_OPEN(pszFileName);
	if (m_File == NULL){
		RETAILMSG(1, (L"[FrameExtractFilter]file(%s) doesn't exist\n", pszFileName));
		return E_FAIL;
	}


	// Setting MediaType
	CMediaType mt;

	if (pmt == NULL)
	{
		if (FAILED(MakeMediaType(&mt, width, height)))
		{
			SSB_FILE_CLOSE(m_File);
			return E_FAIL;
		}
	}
	else
		mt = *pmt;

	// this is not a simple assignment... pointers and format
	// block (if any) are intelligently copied
	m_mt = mt;

	return S_OK;
}


//
// MakeMediaType
//
HRESULT CFrameExtractFilter::MakeMediaType(CMediaType *pMediaType, int width, int height)
{
	unsigned int  *size;

	pMediaType->InitMediaType();
    pMediaType->SetType(&MEDIATYPE_Stream);

	switch (m_StrmType) {
	case RAW_STRM_TYPE_M4V:
    	pMediaType->SetSubtype(&MEDIASUBTYPE_m4v);
		break;

	case RAW_STRM_TYPE_H264RAW:
		pMediaType->SetSubtype(&MEDIASUBTYPE_h264raw);
		break;

	case RAW_STRM_TYPE_RCV:
		pMediaType->SetSubtype(&MEDIASUBTYPE_rcv);
		break;

	default:
		RETAILMSG(1, (L"[FrameExtractFilter]unsupported file type\n"));
		return E_FAIL;
	}

	size = (unsigned int *) pMediaType->ReallocFormatBuffer(sizeof(unsigned int) * 2);
	size[0] = width;
	size[1] = height;

	pMediaType->SetFormat((BYTE *)size, sizeof(unsigned int) * 2);

	return S_OK;
}

int CFrameExtractFilter::CloseFile()
{
	if (m_File) {
		SSB_FILE_CLOSE(m_File);
		m_File = NULL;
	}

	return 0;
}

⌨️ 快捷键说明

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