directshow媒体播放

http://blog.csdn.net/zpp100/article/details/5678235

 

1、简单地播放文件
#include <dshow.h>
#pragma comment (lib,"Ole32.lib")
#pragma comment (lib,"Strmiids.lib")
#define FILENAME L"C://Documents and Settings//vs6//
桌面//temp//FL5007822001-500-2.avi"
bool g_bExit=false; //this APP will be exited when g_bExit=TURE
#define ture (bool)-1
int main()
{
IGraphBuilder *pGraphBuilder; //这是directshow的核心

IMediaControl *pMediaControl; //
帮我们连接filter(媒体文件,解码器等)       //简单的说,它帮我们简单地打开和播放文件.
IVideoWindow *pVideoWindow; //用这个来控制directshow的视频窗口

//COM
初始化
CoInitialize(NULL);

//
建立FilterGraph
CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,
(LPVOID*)&pGraphBuilder);
// 向directshow询问MediaControl接口
:
pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&pMediaControl);
//建立
Graph:
pMediaControl->RenderFile(FILENAME);
          //向directshow询问VideoWindow接口
:
pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&pVideoWindow);
// 全屏:

pVideoWindow->put_Visible(OATRUE);
pVideoWindow->put_FullScreenMode(OATRUE);

          //
开始播放:
pMediaControl->Run();
//
等待:
MessageBox(NULL,"Block Execution","Block",MB_OK);
     
      //
停止:
pMediaControl->Stop();
// release resource:
pVideoWindow->Release();
pMediaControl->Release();
pGraphBuilder->Release();
// COM
销毁:
CoUninitialize();
return 0;
}

DIRECTSHOW

为了在程序中使用DirectShow,我单独安装DirectX版本为9.0。在安装DirectX之后,程序中需要引用“dshow.h”头文件,并导入“Strmiids.lib”库文件和“quartz.lib”库文件才可以使用DirectShow。代码如下:

#include <dshow.h>
#pragma comment (lib,"Strmiids.lib")

#pragma comment (lib,"quartz.lib")


DEBUT
strmbasd.lib,winmm.libRELEASE strmbase.lib,winmm.lib

       DirectShow主要由过滤器(Filter Graph)图表构成。通常需要设计一个过滤图表(Filter Graph),向过滤图表中添加相应的过滤器,最后连接过滤器的引脚就完成了功能的设计。过滤图表中包含了各种Filter,这些Filter能够按一定顺序连接在一起,构成一条流水线。从功能的角度划分,Filter大体可以分为3类,Source FiltersTransform FiltersRendering Filters

Source Filters主要负责获取数据,可以是一个文件、一个采集卡、声卡或数码相机等。

Transform Filters负责数据的转换、传输。例如各种编码器、解码器等。

Rendering Filters负责数据的最终去向,例如将数据传送到声卡、显卡或存储为文件。

我采用是DSHOWfilter,在建好filter graph,调用buider()然后在相应窗口上render这个数据.

1. direct show的常用编程接口
一些常用的过滤器图表管理器接口如下:
IGraphBuilder
:为应用程序提供创建过滤器图表的方法。
IMediaControl
:提供控制过滤器图表中多媒体数据流的方法,包括运行、暂停和停止。
IMediaEventEx
:继承自IMediaEvent接口,处理过滤器图表的事件。
IVideoWindow
:用于设置多媒体播放器窗口的属性,应用程序可以用它来设置窗口的所有者、位置和尺寸等属性。
IBasicAudio
:用于控制音频流的音量和平衡。
IBasicVideo
:用于设置视频特性,如视频显示的目的区域和源区域。
IMediaSeeking
:提供搜索数据流位置和设置播放速率的方法。
IMediaPosition
:用于寻找数据流的位置。
IVideoFrameStep
:用于步进播放视频流,可使DirectShow应用程序,包括DVD播放器一次只播放一帧视频。

CLSCTX_INPROC_SERVER
客户希望创建在同一进程中运行的组件。为能够同客户在同一进程中运行,组建必须是在DLL中实现的。

CLSCTX_INPROC_HANDLER
客户希望创建进程中处理器。一个进程甲处理器实际上是一个只实现了某个组件一部分的进程中组件。该组件的其他部分将由本地或

远程服务器上的某个进程外组件实现。

CLSCTX_LOCAL_SERVER
客户希望创建一个在同一机器上的另外一个进程中运行的组件。本地服务器是由EXE实现的。

//snap picture
long bitmapSize = 0;
if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0)))
{
unsigned char * buffer = new unsigned char[bitmapSize];
if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer)))
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;

lpbi = (LPBITMAPINFOHEADER)buffer;

int nColors = 0;
if( lpbi->biBitCount <=8)
nColors = 1 << lpbi->biBitCount;

hdr.bfType = ((WORD) ('M' << 8) | 'B'); //always is "BM"
hdr.bfSize = bitmapSize + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize +
nColors * sizeof(RGBQUAD));

CFile bitmapFile(m_MixPic, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary);
bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER));
bitmapFile.Write(buffer, bitmapSize);
bitmapFile.Close();
}
delete [] buffer;
}


CLSCTX_REMOTE_SERVER
客户希望创建一个在远程机器上运行的组件。此标志需要分布式COM正常工作。

第四个参数iid为组件上待使用的接口的IIDCoCreateInstance将在最后一个参数中返回此接口的指针。
通过将一个IID传给CoCreateInstance,客户将无需在创建组件之后去调用其QueryInterface函数。

传给CoCreateInstance的最后两个参数同传给QueryInterface的参数是一样的。

4. DSHOW中怎样将视频绑定到指定的窗口或控件上
主要分以下几个方面说明:
The Video Window
视频窗口;
Using the IVideoWindow Interface

DirectShow Sample Code
代码;

The Video Window 视频窗口;
   
当你渲染一个视频时,filter graph 将包含一个视频渲染的filter。视频渲染即将其渲染到屏幕上的一个窗口内。除非特别指定,

不然视频回放窗口是一个顶层窗口,并且有自己的边框和工具条。指定方法是使渲染视频的窗口作为你程序窗口的一个子窗口。
这可以由设置视频窗口的属性来达到目的,指定其父窗口、风格、和位置。
   
   
视频渲染filter支持IVideoWindow接口,该接口包含了设置和获取视频窗口的属性的方法。然而,如果你用filter graph manager

构造了自己的filter graph,你不一定持有指向视频renderer 过滤器的指针,因此 filter graph manager也支持IVideoWindow

它持有一个filter graph中所有filter所暴露的IVideoWindow的列表。当你通过filter graph manager调用一个IVideoWindow方法时,

filter graph manager将会把调用分发到那些filter上。这样,filter graph manager能支持单个filter上的操作,而不用程序去找出
适当的filter

     filter graph manager使用了同样的机制暴露了IBasicVideoIBasicAudio接口。这些接口包含了设置音频和视频属性的方法。
通过过滤图管理器调用这些方法,而不要通过单个filter调用。

Using the IVideoWindow Interface;
首先,创建一个filter graph manager的实例并构造一个filter graph

然后,在渲染之前,设置视频窗口的属性,如下:
邦定视频到一个指定的父窗口。通过调用IVideoWindow::put_Owner方法,传递一个指向父窗口的指针给它。
IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow,(void **)&pVidWin);
pVidWin->put_Owner((OAHWND)g_hwnd);

通过调用IVideoWindow::put_WindowStyle方法,并传递一个风格组合参数,就可以将视频窗口改变为子窗口。
WS_CHILD
标志表示窗口是一个子窗口;WS_CLIPSBLINGS标志防止了窗口在另一个子窗口的客户区绘制。
pVidWin->put_WindowStyle(WS_CHILD|WS_CLIPSBLINGS);

通过调用IVideoWindow::SetWindowPosition 方法,可以设置视频窗口的位置。这个方法采用设备坐标
口的xy,宽度、高度。同样的程序延展了视频窗口并填充了整个父窗口。
CRECT grc;
GetClientRect(g_hwnd,&grc);
pVidWin->SetWindowPosition(rect.left, rect.top, rect.Width(),

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值