// Encode.h: interface for the CEncode class.
//
#if !defined(AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_)
#define AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "streams.h"
#include "afxpriv.h"
# define SafeRelease(s) {if(s) {(s)->Release(); (s) = NULL;}}
# define WM_ENCODE_NOTIFY (WM_USER + 1200)
# define WM_DECODE_NOTIFY (WM_USER + 1201)
class CEncode
{
public:
CEncode();
virtual ~CEncode();
private:
struct _CODE_GRAPH
{
IGraphBuilder * pGraph;
IMediaControl * pControl;
IMediaEventEx * pEvent;
IMediaSeeking * pSeek;
IMediaFilter * pMedia;
ICaptureGraphBuilder2 * pBuilder;
}m_nEncode, m_nDecode; //Filter Graph Manager变量
struct _ENCODE_FILTER
{
IBaseFilter * pSrc;
IBaseFilter * pAviDecode;
IBaseFilter * pFileWrite;
IBaseFilter * pAviMux;
IBaseFilter * H264Encode;
IFileSinkFilter2 * pSink;
}m_nEncodeFilter; //Encode Graph变量
struct _DECODE_FILTER
{
IBaseFilter * pSrc;
IBaseFilter * pEncode;
IBaseFilter * pFileWrite;
IBaseFilter * pAviMux;
IBaseFilter * H264Decode;
IFileSinkFilter2 * pSink;
}m_nDecodeFilter; //Decode Graph变量
struct _CONTROL_STATE
{
int iProgress; //进度值(0 - 100)
bool bStop; //ture - 终止编码 false - 不终止编码
bool bStopFlag; //终止标志
bool bCompleted; //数据传输完成标志
}m_nEncodeCtl, m_nDecodeCtl; //Graph控制变量
public:
/********************功能函数*******************/
int CompressFile( CString strSourcePathName, CString strDestPathName); //实现视频文件的H264编码
int UnCompressFile( CString strSourcePathName, CString strDestPathName, CString strCompressorName); //对H264编码的视频文件用其它的编码器重新编码
int GetProgress(bool bFlag=true); //获得视频编码完成的进度
bool TerminiateProgress(bool bFlag=true); //终止视频编码
bool SetNotifyWindow(HWND inWindow, bool bFlag); //设置消息处理窗口
void OnCodecNotify(WPARAM inWParam, LPARAM inLParam, bool bFlags); //编码/解码消息处理
private:
/****************编码条件的检测*****************/
bool _IsFileOpenedCorrectly(CString strFileName);
bool _IsSuitedFileType(CString strFileName);
bool _HasDecodeFilter(CString strFileName);
int _IsH264Encoded(CString strFileName); //返回值:1 - 成功, 0 - 失败, -1 - 其它情况
int _HasH264Filter(bool bFlag); //返回值:1 - 成功 ,0 - 失败, -1 - 其它情况
/**************Filter Graph的创建与销毁************/
HRESULT _CreateFilterGraph(IGraphBuilder ** inGraph, ICaptureGraphBuilder2** inBuilder);
void _DestroyFilterGraph(IGraphBuilder * inGraph, ICaptureGraphBuilder2* inBuilder);
void _DestroyEncodeGraph();
void _DestroyDecodeGraph();
/*******************辅助功能函数*******************/
bool _CreateCompressDevice( CString strDevice , IBaseFilter ** pCompressorFilter ) ; //创建设备
bool _FindPins(IBaseFilter * pInFilter, bool bFlag, IPin ** pOutPin); //true - 输入pin, false - 输出pin
void _NukeDownstream(IGraphBuilder* inGraph, IBaseFilter * inFilter); //删除下游链路
};
#endif // !defined(AFX_ENCODE_H__F6B1A672_0A17_4011_87DA_F97CA0B0E52E__INCLUDED_)
// Encode.cpp: implementation of the CEncode class.
//
//
#include "stdafx.h"
#include "EncodeDemo.h"
#include "Encode.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
CEncode::CEncode()
{
/*********Encode Graph中变量***********/
m_nEncode.pGraph = NULL;
m_nEncode.pBuilder = NULL;
m_nEncode.pControl = NULL;
m_nEncode.pEvent = NULL;
m_nEncode.pSeek = NULL;
m_nEncode.pMedia = NULL;
m_nEncodeFilter.H264Encode = NULL;
m_nEncodeFilter.pAviDecode = NULL;
m_nEncodeFilter.pAviMux = NULL;
m_nEncodeFilter.pFileWrite = NULL;
m_nEncodeFilter.pSink = NULL;
m_nEncodeFilter.pSrc = NULL;
/*********Decode Graph中变量***********/
m_nDecode.pGraph = NULL;
m_nDecode.pBuilder = NULL;
m_nDecode.pControl = NULL;
m_nDecode.pEvent = NULL;
m_nDecode.pSeek = NULL;
m_nDecode.pMedia = NULL;
m_nDecodeFilter.H264Decode = NULL;
m_nDecodeFilter.pAviMux = NULL;
m_nDecodeFilter.pEncode = NULL;
m_nDecodeFilter.pFileWrite = NULL;
m_nDecodeFilter.pSink = NULL;
m_nDecodeFilter.pSrc = NULL;
/*****Graph控制变量及状态变量*****/
m_nEncodeCtl.iProgress = 0;
m_nDecodeCtl.iProgress = 0;
m_nEncodeCtl.bStop = false;
m_nDecodeCtl.bStop = false;
m_nEncodeCtl.bStopFlag = false;
m_nDecodeCtl.bStopFlag = false;
m_nEncodeCtl.bCompleted = false;
m_nDecodeCtl.bCompleted = false;
}
CEncode::~CEncode()
{
/********异常退出资源释放*******/
// _DestroyEncodeGraph();
// _DestroyDecodeGraph();
}
int CEncode::CompressFile( CString strSourcePathName, CString strDestPathName)
{
/****************编码条件的检测*****************/
if(!_IsFileOpenedCorrectly(strSourcePathName))
return -3;
if(1 == _IsH264Encoded(strSourcePathName))
return -5;
if(!_HasDecodeFilter(strSourcePathName))
return -1;
if(0==_HasH264Filter(true))
return -2;
/*******************编码Graph创建的检测**************/
if (m_nEncode.pGraph&&m_nEncodeFilter.pSrc) //Filter Graph Manager已经创建
{
if(m_nEncode.pControl)
m_nEncode.pControl->Stop();//停止压缩
_NukeDownstream(m_nEncode.pGraph, m_nEncodeFilter.pSrc); //销毁下游链路
m_nEncode.pGraph->RemoveFilter(m_nEncodeFilter.pSrc);
SafeRelease(m_nEncode.pSeek);
SafeRelease(m_nEncode.pControl);
SafeRelease(m_nEncode.pEvent);
SafeRelease(m_nEncodeFilter.pSink);
SafeRelease(m_nEncodeFilter.pSrc);
_DestroyFilterGraph(m_nEncode.pGraph, m_nEncode.pBuilder);
}
/**************编码Graph的创建*************/
HRESULT hr = E_FAIL;
hr = _CreateFilterGraph(&m_nEncode.pGraph, &m_nEncode.pBuilder);
if(FAILED(hr))
{
AfxMessageBox("Uninitialize COM Library!");
return 0;
}
int iResult = 0;
do
{
/***************************查询接口***************************/
hr = m_nEncode.pGraph->QueryInterface(IID_IMediaControl, (void**)&m_nEncode.pControl);
if (FAILED(hr))//查询失败
break ;
hr = m_nEncode.pGraph->QueryInterface(IID_IMediaEventEx, (void**)&m_nEncode.pEvent);
if (FAILED(hr))//查询失败
break ;
hr = m_nEncode.pGraph->QueryInterface(IID_IMediaSeeking, (void**)&m_nEncode.pSeek);
if (FAILED(hr))//查询失败
break ;
hr = m_nEncode.pGraph->QueryInterface(IID_IMediaFilter, (void**)&m_nEncode.pMedia);
if (FAILED(hr))//查询失败
break ;
/*************************辅助Filter的创建*********************/
hr = m_nEncode.pGraph->AddSourceFilter(strSourcePathName.AllocSysString(), L"Source Filter", &m_nEncodeFilter.pSrc);
if(FAILED(hr))//添加失败
break ;
hr = CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nEncodeFilter.pAviDecode);
if (FAILED(hr))//创建失败
break ;
hr = CoCreateInstance(CLSID_AviDest, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nEncodeFilter.pAviMux);
if (FAILED(hr)) //创建失败
break;
hr = m_nEncodeFilter.pAviMux->QueryInterface(IID_IMediaSeeking, (void**)&m_nEncode.pSeek);
if (FAILED(hr))//查询失败
break ;
hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IFileSinkFilter2, (void**)&m_nEncodeFilter.pSink);
if (FAILED(hr)) //创建失败
break ;
hr = m_nEncodeFilter.pSink->QueryInterface(IID_IBaseFilter, (void**)&m_nEncodeFilter.pFileWrite);
if(FAILED(hr)) //创建失败
break ;
/* if(!_CreateCompressDevice("DT264 Compress Filter", &m_nEncodeFilter.H264Encode)) //创建压缩设备失败
break ; */
if (!m_nEncodeFilter.H264Encode) //H264Encode Filter 未被创建
break;
hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.pAviDecode, L"AVI Decompressor");
hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.H264Encode, L"H264 Compress Filter");
/*******************Filter Graph链路的创建*******************/
hr = m_nEncode.pBuilder->RenderStream(NULL, NULL, m_nEncodeFilter.pSrc, m_nEncodeFilter.pAviDecode, m_nEncodeFilter.H264Encode);
if (FAILED(hr)) //创建链路失败
{
AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate pSrc->pAviDecompress->pCompressFilter Failed!");
break;
}
hr = m_nEncode.pGraph->AddFilter(m_nEncodeFilter.pAviMux, L"AVI Dest Filter");
hr = m_nEncode.pGraph->AddFilter((IBaseFilter *)m_nEncodeFilter.pFileWrite, L"File Write Filter");
hr = m_nEncodeFilter.pSink->SetMode(AM_FILE_OVERWRITE);
hr = m_nEncodeFilter.pSink->SetFileName(strDestPathName.AllocSysString() , NULL);
if(FAILED(hr))
{
iResult = -4;
break;
}
hr = m_nEncode.pBuilder->RenderStream(NULL, NULL, m_nEncodeFilter.H264Encode, m_nEncodeFilter.pAviMux, m_nEncodeFilter.pFileWrite);
if (FAILED(hr))
{
AfxMessageBox("/r该编解码器不支持所选的媒体类型,请下载相应的插件。/rCreate H264 Compress Filter->---->File Write Filter Failed!");
break;
}
hr=m_nEncode.pMedia->SetSyncSource(NULL);
hr = m_nEncode.pControl->Run(); //运行filter graph
if(SUCCEEDED(hr))
{
iResult = 1;
m_nEncodeCtl.bStopFlag = true;
}
}while(false);
return iResult;
}
int CEncode::UnCompressFile( CString strSourcePathName, CString strDestPathName, CString strCompressorName)
{
/****************编码条件的检测*****************/
if(!_IsFileOpenedCorrectly(strSourcePathName))
return -4;
if(!_IsSuitedFileType(strSourcePathName))
return -2;
if(0 == _IsH264Encoded(strSourcePathName))
return -1;
if(0==_HasH264Filter(false))
return -6;
/*******************编码Graph创建的检测**************/
if (m_nDecode.pGraph&&m_nDecodeFilter.pSrc) //Filter Graph Manager已经创建
{
if(m_nDecode.pControl)
m_nDecode.pControl->Stop();//停止压缩
_NukeDownstream(m_nDecode.pGraph, m_nDecodeFilter.pSrc); //销毁下游链路
m_nDecode.pGraph->RemoveFilter(m_nDecodeFilter.pSrc);
SafeRelease(m_nDecode.pSeek);
SafeRelease(m_nDecode.pControl);
SafeRelease(m_nDecode.pEvent);
SafeRelease(m_nDecodeFilter.pSink);
SafeRelease(m_nDecodeFilter.pSrc);
_DestroyFilterGraph(m_nDecode.pGraph, m_nDecode.pBuilder);
}