分享
 
 
 

directshow的中文资料之播放影片

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

DirectShow编程指南

我们终于开始了我们的真正旅程!Let's Go!

由于DirectX和VC++的紧密联系,所有的代码都用C++写的。

一.播放影片

通过一个简单的C++程序示范如何播放影片。本节包括:

1.播放一个媒体文件--回放媒体文件的基本代码。

2.添加媒体seek功能--提供在媒体文件中如何seek一个特定的的位置的代码。(seek就是...你用过CFile::Seek么?嗯...就是他了)。

因为只是个演示很多都是定了的。例如:

TCHAR *szFilename = "c:\\dxmedia\\movie\\movie.avi";

当然你可以用各种方法得到你使用的文件信息。

另外就是定义了自己的响应消息和一个释放宏:

#define WM_GRAPHNOTIFY WM_USER+13

#define HELPER_RELEASE(x) { if (x) x->Release(); x = NULL; }

需要的头文件:

#include <windows.h>

#include <mmsystem.h>

#include <streams.h>

申明变量:

HWND ghApp;

HINSTANCE ghInst;

HRESULT hr;

LONG evCode;

LONG evParam1;

LONG evParam2;

其中ghApp是一个graph产生的事件的响应窗口句柄。ghInst是窗口的HINSTANCE。evCode将保存事件代码,evParam1和evParam2保存事件的参数。

申明和初始化必须的接口。由于接口的索引值是自动的加1,所以你不要调用IUnknown::AddRef方法(如果你觉得陌生,你可以参考综述篇的"一、DirectX和部件对象模型COM")。

IGraphBuilder *pigb = NULL;

IMediaControl *pimc = NULL;

IMediaEventEx *pimex = NULL;

IVideoWindow *pivw = NULL;

定义一个函数:szFile参数是播放的媒体文件名

void PlayFile(LPSTR szFile)

HRESULT hr;

建立一个Unicode(wide character)字符串。

WCHAR wFile[MAX_PATH];

MultiByteToWideChar( CP_ACP, 0, szFile, -1, wFile, MAX_PATH );

实例化一个filter graph manager。

hr = CoCreateInstance(CLSID_FilterGraph,

NULL,

CLSCTX_INPROC_SERVER,

IID_IGraphBuilder,

(void **)&pigb);

查询IMediaControl接口(提供run,pause and stop methods),IMediaEventEx接口(你可以接收事件响应),IVideoWindow接口。

pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);

pigb->QueryInterface(IID_IMediaEventEx, (void **)&pimex);

pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);

让filter graph manager建立filter graph去渲染输入文件。现在还没播放文件(当你用run函数播放时,filter graph会自动渲染输入文件的媒体类型,你不必指定渲染过滤器)。

hr = pigb->RenderFile(wFile, NULL);

用一个窗口捕捉graph的通知事件。可以改善性能,但是允许你的应用程序运行在另一个线程。

pimex->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0);

在ghApp处理消息去响应从graph传来的所有事件。如果事件发生了,DirectShow会post一个WM_GRAPHNOTIFY消息给ghApp。

开始播放文件。

hr = pimc->Run();

同样的,你也可以有

hr = pimc->Pause();

hr = pimc->Stop();

当然了,你可以用一个对话框的按钮来响应Pause 和 Stop。这样就实现了简单的回放。

记住了,在你的代码里,要释放你用的接口,可以用HELPER_RELEASE 宏。

例:HELPER_RELEASE(pigb);

现在加入seek功能。

在你的媒体文件中,你可以用IMediaPosition or IMediaSeeking 接口seek到一个特定的位置播放。IMediaPostion::put_CurrentPosition方法可以指定开始时间,例如你可以用下面的代码实现重放:

IMediaPosition *pimp;

hr = pigb->QueryInterface(&IID_IMediaPosition, (void **)&pimp);

hr = pimp->put_CurrentPosition(0);

时间的单位是100呐秒,下面的代码seek到文件的一秒处:

hr = pimp->put_CurrentPosition(10000000);

你也可以用IMediaPosition::put_StopTime 方法去设置文件的回放停止时间。

然而,用IMediaPosition只能用seek时间,如果你用 IMediaSeeking接口,你能用多种格式seek,用100呐秒单位,frame(帧),字节,media samples,或者是interlaced video fields。你可以用IMediaSeeking::SetTimeFormat 设置你需要的格式。注意,确信你不在播放媒体文件,当你设置格式的时候。

格式如下:

TIME_FORMAT_MEDIA_TIME 单位是100呐秒

TIME_FORMAT_BYTE 单位是字节

TIME_FORMAT_FIELD 单位是interlaced video field(我不太清楚这格式,所有只好用英文)

TIME_FORMAT_FRAME 单位是帧

TIME_FORMAT_SAMPLE 单位是sample (我不太清楚这格式,所有只好用英文)

举个例子吧,下面的代码设置格式为帧。

IMediaSeeking *pims;

hr = pigb->QueryInterface(IID_IMediaSeeking, (void **)&pims);

hr = pims->SetTimeFormat(&TIME_FORMAT_SAMPLE);

应用程序可以用多样的seek模式,而不需要考虑 时间/速率的转换。有时候这是很有用的。

下面示例如何用帧的格式开始和结束播放。如在15帧开是播放影片。你可以把代码插入到PlayFile函数的任何地方,注意的是,一定要在RenderFile函数的后面(还记得hr = pigb->RenderFile(wFile, NULL);这段代码么?)。

IMediaSeeking *pims;

hr = pigb->QueryInterface(IID_IMediaSeeking, (void **)&pims);

设置时间格式。

hr = pims->SetTimeFormat(&TIME_FORMAT_FRAME);

申明并初始化开始和结束变量:

LONGLONG start = 5L;

LONGLONG stop = 15L;

通过IMediaSeeking::SetPositions方法设置开始和结束时间, AM_SEEKING_AbsolutePositioning标志意味着这是一个绝对的位置(不是相对于媒体文件现在的位置)。在这个例子中,媒体文件就在第5帧开始,在15帧结束,持续时间是10帧。具体的时间长度要看视频帧的播放速率了。

pims->SetPositions(&start, AM_SEEKING_AbsolutePositioning, &stop,

AM_SEEKING_AbsolutePositioning);

最后释放接口。

pims->Release();

当然你也可以设置别的格式,和别的开始结束的信息。例如5秒到7秒。

hr = pims->SetTimeFormat(&TIME_FORMAT_FRAME);

LONGLONG start = 50000000L;

LONGLONG stop = 70000000L;

其他就看你自己喜欢了......(我没有任何权利干涉)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有