DirectShow过滤器开发-写MP3音频文件过滤器(再写 写MP3)
下载本过滤器DLL
本过滤器将MP3音频流写到MP3音频文件。
过滤器信息
过滤器名称:写MP3_2
过滤器GUID:{AE46BC15-71E5-471C-8540-3B73094111EC}
DLL注册函数名:DllRegisterServer
删除注册函数名:DllUnregisterServer
过滤器有1个输入引脚。
输入引脚标识:In
输入引脚媒体类型:
主要类型:MEDIATYPE_Audio
子类型:{0x00000055, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
格式类型:FORMAT_WaveFormatEx
过滤器DLL的全部代码
DLL.h
#ifndef DLL_FILE
#define DLL_FILE
#include "strmbase10.h"//过滤器基础类定义文件
#if _DEBUG
#pragma comment(lib, "strmbasd10.lib")//过滤器基础类实现文件调试版本
#else
#pragma comment(lib, "strmbase10.lib")//过滤器基础类实现文件发布版本
#endif
// {AE46BC15-71E5-471C-8540-3B73094111EC}
DEFINE_GUID(CLSID_WriteMP3,
0xae46bc15, 0x71e5, 0x471c, 0x85, 0x40, 0x3b, 0x73, 0x9, 0x41, 0x11, 0xec);
DEFINE_GUID(MEDIASUBTYPE_MP3,
0x00000055, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
template <class T> void SafeRelease(T** ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
class CFilter;
class CInputPin : public CBaseInputPin
{
friend class CFilter;
CFilter *pCFilter;
public:
CInputPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName);
~CInputPin();
HRESULT CheckMediaType(const CMediaType *pmt);
STDMETHODIMP Receive(IMediaSample *pSample);
HRESULT Active();
HRESULT Inactive();
HANDLE hFile = NULL;//输出文件句柄
};
class CFilter : public CBaseFilter, public CCritSec, public IFileSinkFilter
{
friend class CInputPin;
public:
CFilter(LPWSTR lpName, LPUNKNOWN pUnk, HRESULT *phr);
virtual ~CFilter();
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
virtual HRESULT STDMETHODCALLTYPE SetFileName(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt);
virtual HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt);
static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);
int GetPinCount();
CBasePin *GetPin(int n);
STDMETHODIMP Run(REFERENCE_TIME tStart);
CInputPin *m_pInputPin; //输入引脚指针
WCHAR* m_pFileName = NULL;//要创作的MP3文件路径
};
#endif //DLL_FILE
DLL.cpp
#include "DLL.h"
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_Audio, //主要类型
&MEDIASUBTYPE_MP3 //子类型
};
const AMOVIESETUP_PIN sudPin = //引脚信息
{
L"In", //引脚名称
FALSE, //渲染引脚
FALSE, //输出引脚
FALSE, //具有该引脚的零个实例
FALSE, //可以创建一个以上引脚的实例
&CLSID_NULL, //该引脚连接的过滤器的类标识
NULL, //该引脚连接的引脚名称
1, //引脚支持的媒体类型数
&sudPinTypes //媒体类型信息
};
const AMOVIESETUP_FILTER WriteMP3 = //过滤器的注册信息
{
&CLSID_WriteMP3, //过滤器的类标识
L"写MP3_2", //过滤器的名称
MERIT_DO_NOT_USE, //过滤器优先值
1, //引脚数量
&sudPin //引脚信息
};
CFactoryTemplate g_Templates[] = {
{
L"写MP3_2" //对象(这里为过滤器)名称
, &CLSID_WriteMP3 //对象CLSID的指针
, CFilter::CreateInstance //创建对象实例的函数的指针
, NULL //指向从DLL入口点调用的函数的指针
, &WriteMP3 //指向AMOVIESETUP_FILTER结构的指针
}
};
int g_cTemplates = 1;
STDAPI DllRegisterServer()//注册DLL
{
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()//删除DLL注册
{
return AMovieDllRegisterServer2(FALSE);
}
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}
CFilter.cpp
#include "DLL.h"
#include "strsafe.h"
CFilter::CFilter(LPWSTR lpName, LPUNKNOWN pUnk, HRESULT *phr) : CBaseFilter(lpName, pUnk, (CCritSec *) this, CLSID_WriteMP3)
{
m_pInputPin = new CInputPin(this, phr, L"In");//创建输入引脚
}
CFilter::~CFilter()
{
if (m_pFileName != NULL)delete[] m_pFileName;
}
CUnknown * WINAPI CFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{
return new CFilter(L"写MP3_2", pUnk, phr);//创建过滤器
}
int CFilter::GetPinCount()
{
return 1;
}
CBasePin *CFilter::GetPin(int n)
{
if (n != 0)
{
return NULL;
}
return m_pInputPin;
}
STDMETHODIMP CFilter::NonDelegatingQueryInterface(REFIID iid, void ** ppv)
{
if (iid == IID_IFileSinkFilter)
{
return GetInterface(static_cast<IFileSinkFilter*>(this), ppv);
}
else
return CBaseFilter::NonDelegatingQueryInterface(iid, ppv);
}
HRESULT CFilter::GetCurFile(LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt)
{
CheckPointer(ppszFileName, E_POINTER);
*ppszFileName = NULL;
if (m_pFileName != NULL)
{
size_t len = 1 + lstrlenW(m_pFileName);
*ppszFileName = (LPOLESTR)QzTaskMemAlloc(sizeof(WCHAR) * (len));
if (*ppszFileName != NULL)
{
HRESULT hr = StringCchCopyW(*ppszFileName, len, m_pFileName);
}
}
if (pmt)
{
ZeroMemory(pmt, sizeof(*pmt));
pmt->majortype = MEDIATYPE_NULL;
pmt->subtype = MEDIASUBTYPE_NULL;
}
return S_OK;
}
HRESULT CFilter::SetFileName(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt)
{
CheckPointer(pszFileName, E_POINTER);
if (wcslen(pszFileName) > MAX_PATH || wcslen(pszFileName)<4)
return ERROR_FILENAME_EXCED_RANGE;
size_t len = 1 + lstrlenW(pszFileName);
m_pFileName = new WCHAR[len];
if (m_pFileName == 0)
return E_OUTOFMEMORY;
HRESULT hr = StringCchCopyW(m_pFileName, len, pszFileName);
if (m_pFileName[len - 2] != '3' || m_pFileName[len - 3] != 'p' || m_pFileName[len - 4] != 'm' || m_pFileName[len - 5] != '.')//如果不是MP3文件
{
delete[] m_pFileName; m_pFileName = NULL;
return VFW_E_INVALID_FILE_FORMAT;//设置文件名失败
}
return S_OK;
}
STDMETHODIMP CFilter::Run(REFERENCE_TIME tStart)
{
if (m_pFileName == NULL)
{
MessageBox(NULL, L"未指定输出文件", L"写MP3_2", MB_OK); return S_FALSE;
}
return CBaseFilter::Run(tStart);
}
CInputPin.cpp
#include "DLL.h"
#include "mmreg.h"
CInputPin::CInputPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName) : CBaseInputPin(NAME("In"), pFilter, pFilter, phr, pPinName)
{
pCFilter = pFilter;
}
CInputPin::~CInputPin()//输入引脚析构函数
{
}
HRESULT CInputPin::CheckMediaType(const CMediaType *pmt)
{
if (pmt->majortype == MEDIATYPE_Audio && pmt->subtype == MEDIASUBTYPE_MP3 && pmt->formattype == FORMAT_WaveFormatEx)
{
WAVEFORMATEX* p = (WAVEFORMATEX*)pmt->pbFormat;
if (p->wFormatTag != 85)return S_FALSE;
return S_OK;
}
else
return S_FALSE;
}
HRESULT CInputPin::Receive(IMediaSample * pSample)//接收函数
{
HRESULT hr;
BYTE* pBy = NULL;
hr = pSample->GetPointer(&pBy);//获取引脚样本缓冲区指针
long len = pSample->GetActualDataLength();//获取有效数据长度
if (hFile)
{
WriteFile(hFile, pBy, len, NULL, NULL);//写MP3数据
}
return S_OK;
}
HRESULT CInputPin::Active()
{
if (pCFilter->m_pFileName == NULL)
{
MessageBox(0, L"没有指定输出文件", L"写MP3_2", MB_OK); return S_FALSE;
}
hFile = CreateFile(pCFilter->m_pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//创建输出文件
if (INVALID_HANDLE_VALUE == hFile)
{
MessageBox(0, L"创建输出文件失败", L"写MP3_2", MB_OK); return S_FALSE;
}
char chID[3] = { 'I','D','3' };
WriteFile(hFile, chID, 3, NULL, NULL);//写标识
BYTE by1 = 3;
WriteFile(hFile, &by1, 1, NULL, NULL);//写版本号:ID3V2.3
BYTE by2 = 0;
WriteFile(hFile, &by2, 1, NULL, NULL);//写副版本号
BYTE by3 = 0;
WriteFile(hFile, &by3, 1, NULL, NULL);//写标志
DWORD mSize = 0;
WriteFile(hFile, &mSize, 4, NULL, NULL);//写标签大小
return CBaseInputPin::Active();
}
HRESULT CInputPin::Inactive()
{
CloseHandle(hFile);//关闭输出文件
hFile = NULL;
return CBaseInputPin::Inactive();
}
下载本过滤器DLL