📄 cmediainfo.cpp
字号:
//
// CMediaInfo.cpp
//
/*-----------------------------------------------------*\
HQ Tech, Make Technology Easy!
More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/
#include <streams.h>
#include "stdafx.h"
#include "CMediaInfo.h"
#include "GlobalDefs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CMediaInfo, CObject, 1)
/////////////////////////////////////////////////////////////////////////////
CMediaInfo::CMediaInfo()
{
mFilePath[0] = '\0';
mProgramId = 0;
mFileType = 0;
mFileSize = 0;
}
CMediaInfo::CMediaInfo(const CMediaInfo& inMedia)
{
Clone(inMedia);
}
CMediaInfo::~CMediaInfo()
{
}
void CMediaInfo::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
CString str;
if (ar.IsStoring())
{
str = mFilePath;
ar << str;
ar << mProgramId;
ar << mFileType;
ar << mFileSize;
}
else
{
ar >> str;
strcpy(mFilePath, str);
ar >> mProgramId;
ar >> mFileType;
ar >> mFileSize;
}
}
CMediaInfo& CMediaInfo::operator=(const CMediaInfo& inMedia)
{
Clone(inMedia);
return *this;
}
void CMediaInfo::Clone(const CMediaInfo& inMedia)
{
strcpy(mFilePath, inMedia.mFilePath);
mProgramId = inMedia.mProgramId;
mFileType = inMedia.mFileType;
mFileSize = inMedia.mFileSize;
}
void CMediaInfo::CopyTo(struct Program_List * outInfo)
{
memcpy(outInfo->file_path, mFilePath, MAX_FILE_PATH);
outInfo->pid = mProgramId;
outInfo->file_type = mFileType;
outInfo->file_size = mFileSize;
}
void CMediaInfo::CopyFrom(struct Program_List * inInfo)
{
memcpy(mFilePath, inInfo->file_path, MAX_FILE_PATH);
mProgramId = inInfo->pid;
mFileType = inInfo->file_type;
mFileSize = inInfo->file_size;
}
BOOL CMediaInfo::SetFilePath(const char * inFile)
{
if (ParseFile(inFile))
{
strcpy(mFilePath, inFile);
return TRUE;
}
return FALSE;
}
void CMediaInfo::SetProgramId(long inPID)
{
mProgramId = inPID;
}
BOOL CMediaInfo::ParseFile(const char * inFile)
{
// At first, get the file size
mFileSize = 0;
CFileStatus fileStatus;
if (CFile::GetStatus(inFile, fileStatus))
{
mFileSize = fileStatus.m_size;
}
// Get the file extension
CString strExt = strrchr(inFile, '.');
if (strExt.CompareNoCase(".mpeg") == 0 ||
strExt.CompareNoCase(".mpg") == 0 )
{
// Further checking...
if(!CheckMpegFile(inFile))
{
AfxMessageBox("MPEG2 is not supported!");
return FALSE;
}
}
else if (strExt.CompareNoCase(".avi") == 0)
{
// Further checking...
if(CheckOGGFile(inFile))
mFileType = FT_OGG;
else
mFileType = FT_AVI;
}
else if (strExt.CompareNoCase(".rm") == 0||
strExt.CompareNoCase(".rmvb") == 0)
{
// Further checking...
mFileType = FT_REAL;
}
else
{
AfxMessageBox("This file type is not supported!");
return FALSE;
}
return TRUE;
}
// Try to connect to microsoft mpeg1 stream splitter.
// If connection succeeded, mpeg1 file. Otherwise, mpeg2 file.
BOOL CMediaInfo::CheckMpegFile(const char * inFile)
{
mFileType = FT_MPEG1; // Default
IGraphBuilder * pBuilder = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **) &pBuilder);
if (pBuilder)
{
// Create a file source filter
IBaseFilter * pSource = NULL;
WCHAR wcFilePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, inFile, -1, wcFilePath, MAX_PATH);
pBuilder->AddSourceFilter(wcFilePath, L"Source", &pSource);
pSource->Release();
// Create microsoft MPEG-1 Stream Splitter
IBaseFilter * pSplitter = NULL;
CoCreateInstance(CLSID_MPEG1Splitter , NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)&pSplitter);
pBuilder->AddFilter(pSplitter, L"MPEG-1 Splitter");
pSplitter->Release();
// Try to connect them...
IPin * pOut = GetPinByDirection(pSource, PINDIR_OUTPUT);
IPin * pIn = GetPinByDirection(pSplitter, PINDIR_INPUT);
HRESULT hr = pBuilder->ConnectDirect(pOut, pIn, NULL);
if (FAILED(hr))
{
pBuilder->RemoveFilter(pSplitter);
pBuilder->RemoveFilter(pSource);
pBuilder->Release();
return FALSE;
//mFileType = FT_MPEG2;
// Attention here! 1M data at the end of the file!
}
pBuilder->RemoveFilter(pSplitter);
pBuilder->RemoveFilter(pSource);
pBuilder->Release();
}
return TRUE;
}
IPin * CMediaInfo::GetPinByDirection(IBaseFilter * inFilter,
PIN_DIRECTION inDirection)
{
IPin * foundPin = NULL;
if (inFilter)
{
IEnumPins * pinEnum = 0;
if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
{
pinEnum->Reset();
IPin * pin = 0;
ULONG fetchCount = 0;
while (!foundPin && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) &&
fetchCount)
{
if (pin)
{
PIN_INFO pinInfo;
if (SUCCEEDED(pin->QueryPinInfo(&pinInfo)))
{
pinInfo.pFilter->Release();
if (pinInfo.dir == inDirection)
{
foundPin = pin;
}
}
// If found pin, we keep pin reference.
// If not, we release it here.
if (!foundPin)
{
pin->Release();
}
pin = 0;
}
}
pinEnum->Release();
}
}
// We don't keep outstanding reference count
if (foundPin)
{
foundPin->Release();
}
return foundPin;
}
BOOL CMediaInfo::CheckOGGFile(const char *inFile)
{
HRESULT hr = NOERROR;
IFileSourceFilter * FileFilter;
if (SUCCEEDED(CoCreateInstance(CLSID_MYOGGFILESOURCEFILTER, NULL, CLSCTX_INPROC_SERVER,
IID_IFileSourceFilter, (void **)&FileFilter)))
{
WCHAR playingID[200];
MultiByteToWideChar(CP_ACP,0,inFile,-1,playingID,200);
if(SUCCEEDED(FileFilter->Load(playingID,NULL)))
{
FileFilter->Release();
return TRUE;
}
FileFilter->Release();
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -