利用DirectShow实现对视频文件H264编码与解码基类

// 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.pGra

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值