织梦CMS - 轻松建站从此开始!

罗索

source filter开发笔记(1)

落鹤生 发布于 2010-12-16 13:32 点击:次 
站在微软这个巨人的肩上做任何事情都会变得简单,在开发媒体播放器经常需要自己写filter完成特定的需要,写一个filter其实很简单,只需要对COM有基本的了解,然后再站在巨人肩上,完成以下几个步骤,就可以很轻易的写出一个filter.
TAG:

站在微软这个巨人的肩上做任何事情都会变得简单,在开发媒体播放器经常需要自己写filter完成特定的需要,写一个filter其实很简单,只需要对COM有基本的了解,然后再站在巨人肩上,完成以下几个步骤,就可以很轻易的写出一个filter.

Step 1. Choose a Base Class.(选择一个基类)

Step 2. Declare the Filter Class.(定义过滤器类)

Step 3. Support Media Type Negotiation.(支持媒体类型)

Step 4. Set Allocator Properties.(设置内存分配器属性) 

Step 5. Transform the Image.(传输数据)

Step 6. Add Support for COM.(添加到COM)

filter又分为source filter和transfrom filter和rander filter.

一.源filter实现.

       源filter分为二种形式,一种为拉(pull)模式,另一种为推(push)模式.

       一般的,如果需要实现为拉模式的话,输出pin

需要从IAsyncReader派生下来,如果需要实现为推模式的,那么使用IMemInputPin.

       IAsyncReader的接口描述: (推模式source filter)

       1.HRESULT RequestAllocator(IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual);

       RequestAllocator方法在pin连接时请求一个内存分配器. 优先使用pPreferred做为内存分配器,如果没有,则需要自己创建一个内存分配器,提供给ppActual.

       pPreferred事实上就是下游input pin提供的内存分配器,也就是说,如果下游input pin不提供内存分配器,则需要自己创建一个内存分配器.

       pProps参数为内存分配器的属性,是下游input pin需要的内存分配器的属性.

              ALLOCATOR_PROPERTIES 结构体解释如下:

                     cBuffers 

                     内存缓冲的总个数. 

                     cbBuffer 

                     内存缓冲的字节数,不包括前缀空间. 

                     cbAlign 

                     内存缓冲的对齐方式,内存缓冲将会是这个值的倍数. 

                     cbPrefix 

                     每个内存缓冲的前缀空间字节数.  

       2.HRESULT Request(IMediaSample* pSample, DWORD dwUser);

       这个方法请求一个sample,在这里可以延迟填充pSample,也可将pSample保存起来放入一个队列,在其它线程里做填充操作, dwUser为上游的用户上下文,需要保存起来,以便在调用WaitForNext时传回给下游的Filter.

       当WaitForNext被调用时,此时可以在这里做等待其它线程拷贝数据或者在直接在这里进行数据拷贝等操作,并且将pSample指针赋值给WaitForNext的IMediaSample参数,另外也需要将上下文传回给WaitForNext的参数.

       3.HRESULT WaitForNext(DWORD dwTimeout, IMediaSample** ppSample, DWORD* pdwUser);

       这个方法是在播放请求一个数据时被调用(稍晚于Request),在一个IMediaSample传递结束,以及在这里设置实际数据长度.传输完成后,数据才真正进入播放.

       4.HRESULT BeginFlush( );

       该方法表示重新开始缓冲数据开始,也就是放弃所有正在进行的数据读取.当程序停止时,或者用户进行seek操作时,该方法会被调用,这意味着Filter需要把之前缓冲的数据撤销.

       5.HRESULT EndFlush( );

       表示刷新缓冲完成.

       6.HRESULT SyncReadAligned(IMediaSample* pSample);

       同步对齐读取数据.

       7.HRESULT SyncRead(LONGLONG llPosition, LONG lLength, BYTE* pBuffer);

       同上.指定长度和位置,直接读取数据到pBuffer.

       8.HRESULT Length(LONGLONG* pTotal, LONGLONG* pAvailable);

       返回总长度,以及当前可读取的长度.

       如果可读取的长度超过了总长度,可能会引起阻塞一段时间.

    

未完等待续...http://my.oschina.net/jackwgm/blog/4716

(jackwgm)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201012/10612.html]
本文出处:my.oschina.net/jackwgm 作者:jackwgm
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容