实现DirectShow source filter有两大类方法

先研究第一种实现方法。从DirectShow SDK push source的例子来看,CSource派生类的实现都非常简单,无非在构造函数中生成一个CSourceStream派生的pin对象,在析构函数中将pin删除。主要的代码实现都在CSourceStream的派生类。而CSourceStream要重载的主要方法包括

HRESULT GetMediaType(CMediaType *pMediaType);

HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest);

HRESULT FillBuffer(IMediaSample *pSample);

GetMediaType接口用于返回pin接受的媒体格式。GetMediaType有两种形式的接口,一种是一个参数的,另外一种是两个参数的

HRESULT GetMediaType(CMediaType *pMediaType);

HRESULT GetMediaType(int iPosition, CMediaType *pmt);

一个参数的版本适用于pin只提供一种输出格式的情况。如果pin支持多种格式的输出,需要使用第二种接口,同时重载CSourceStream::CheckMediaType接口。

CMediaType类是对AM_MEDIA_TYPE结构体的封装。这个结构体要赋值的成员还是挺多的,如何设置可以参考例子当中的GetMediaType函数

http://blog.csdn.net/zhengxinwcking/article/details/30475869

DecideBufferSize接口用于设置需要多大的buffer。CSourceStream类的父类CBasePin中有个m_mt的成员保存了GetMediaType设置的媒体格式。一份buffer的大小通常就是GetMediaType中设置的pmt->lSampleSize。一般用一份buffer也够了。

FillBuffer接口用于填写每一帧的音视频数据。这个接口一般先调用IMediaSample::GetPointer获得新一帧数据的缓冲,然后把数据写入这个缓冲。接着调用IMediaSample::SetTime设置帧的时间戳。最后调用IMediaSample::SetSyncPoint设置该帧是否为关键帧。对于提供非压缩数据的source filter,每一帧都应该设置为TRUE。

如果source filter的下游是vmr7(vmr9测试没有这个问题),还需要多实现两个接口

HRESULT CheckMediaType(const CMediaType *pMediaType)

STDMETHODIMP Notify(IBaseFilter *pSelf, Quality q)

vmr7要自己实现CheckMediaType的原因是,如果不重载CheckMediaType,DecideBufferSize函数中调用IMemAllocator::SetProperties会报错,返回E_FAIL,从而导致FillBuffer不会被调用(更正,如果IMemAllocator::SetProperties,则DecideBufferSize也应该报错,这样仍可以运行)。stackoverflow上面有一个类似的问题

https://stackoverflow.com/questions/7928828/negotiating-an-allocator-between-directshow-filters-fails

上面的解释是,VMR/EVR filter所需要的buffer stride会跟source filter GetMediaType设置的图像宽度不一致(显存需要字节对齐),导致格式发生改变。当VMR/EVR改变格式数据的时候,它会调用IPin::QueryAccept询问上游filter是否接受这个格式。CSourceStream实现的CheckMediaType是这样的

HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType)

{

CAutoLock lock(m_pFilter->pStateLock());

CMediaType mt;

GetMediaType(&mt);

if (mt == *pMediaType) {

return NOERROR;

}

return E_FAIL;

}

它会调用我们派生类实现的GetMediaType获得一个CMediaType,然后将这个CMediaType和下游传过来的CMediaType作比较。如果不一致,就返回E_FAIL。而CMediaType的==运算符是这样定义的

BOOL

CMediaType::operator == (const CMediaType& rt) const

{

// I don't believe we need to check sample size or

// temporal compression flags, since I think these must

// be represented in the type, subtype and format somehow. They

// are pulled out as separate flags so that people who don't understand

// the particular format representation can still see them, but

// they should duplicate information in the format block.

return ((IsEqualGUID(majortype,rt.majortype) == TRUE) &&

(IsEqualGUID(subtype,rt.subtype) == TRUE) &&

(IsEqualGUID(formattype,rt.formattype) == TRUE) &&

(cbFormat == rt.cbFormat) &&

( (cbFormat == 0) ||

pbFormat != NULL && rt.pbFormat != NULL &&

(memcmp(pbFormat, rt.pbFormat, cbFormat) == 0)));

}

通过调试,发现上游传过来的格式是用VIDEOINFO结构体的,而且biHeight是负数,因此会被误判为格式不相同。因此需要我们自己重载实现CheckMediaType

Notify虽然没什么鸟用,但是必须实现。否则CBasePin::Notify会抛出断言错误

CBasePin::Notify(IBaseFilter * pSender, Quality q)

{

UNREFERENCED_PARAMETER(q);

UNREFERENCED_PARAMETER(pSender);

DbgBreak("IQualityControl::Notify not over-ridden from CBasePin. (IGNORE is OK)");

return E_NOTIMPL;

} //Notify

directshow方法关键帧java,如何实现DirectShow source filter相关推荐

  1. DirectShow编程(2)- 开始DirectShow旅程

    2. 开始DirectShow旅程     这个章节的内容主要是编写DirectShow应用所需的一些基本概念,可以把它当作一个高级介绍,理解这些内容只需具备一般的编程和有关多媒体的知识. 2.1. ...

  2. string 方法 java_String 的几个 方法。 (java)

    写了几年 java 程序,今天才看到 String 的 endwith startwith .实在不好意思. 还有就是 不区分大小写的 字符串比较.String.CASE_INSENSITIVE_OR ...

  3. 用“逐步排除”的方法定位Java服务线上“系统性”故障

    说明:原文地址已经不可访问,其他地方有转载,不过很多丢失图片,所以,找到一处有图的重新配好图. 用"逐步排除"的方法定位Java服务线上"系统性"故障 Post ...

  4. java编译会产生多少个类文件,编译一个定义了三个类和四个方法的Java源程序文件,总共会产生多少个字节码文件 ? ( )...

    编译一个定义了三个类和四个方法的Java源程序文件,总共会产生多少个字节码文件 ? ( ) 更多相关问题 论述风化作用基本概念及其主要类型. 什么是药用植物 学?其 研究任务是什么 ? 庐山瀑布很有名 ...

  5. JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法

    JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法 参考文章: (1)JNI调用native方法出现 ...

  6. 五种方法创建 Java 对象,你知道几种呢?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 网络 五种方法创建java对象 作为Java开 ...

  7. java解析shell命令_Android中执行java命令的方法及java代码执行并解析shell命令

    这篇文章给大家介绍Android中执行java命令的方法及java代码执行并解析shell命令,需要的朋友一起学习 android中执行java命令的方法大家都晓得吗,下面一段内容给大家带来了具体解析 ...

  8. 方法重载 java 1614780176

    方法重载 java 1614780176 关于 演示 操作类 测试类 注意

  9. android 判断字符相等,字符串的截取,判断字符串是否相等和字符串是否为空的方法总结Java,Android...

    最近做项目Android时遇到了字符串的截取,判断字符串是否相等和字符串是否为空问题刚好用的上自己也知道些,所以整理了方便以后用,和供大家参考,有什么更好的方法或者其它方法我么可以一起交流,谢谢大家! ...

  10. java 集合初始化_6种方法初始化JAVA中的list集合

    List 是 Java 开发中经常会使用的集合,你们知道有哪些方式可以初始化一个 List 吗?这其中不缺乏一些坑,今天栈长我给大家一一普及一下. 1.常规方式 List languages = ne ...

最新文章

  1. java foreach order_Java 8流中的forEach vs forEachOrdered
  2. retrofit2 spring接受参数_Spring面试中有可能遇到的问题
  3. 在 ASP.NET MVC 中使用 Chart 控件
  4. python数据结构_(字典)大O性能_学习笔记(3)
  5. 不可靠的信号、可靠信号
  6. 95-160-024-源码-DataStream-ConnectedStreams与union合并流
  7. tp5 前台页面获取url链接里的参数,如下
  8. 最近做了个数据采集的工具
  9. 云计算 雾计算 边缘计算的区别
  10. ifconfig源码分析之与内核交互数据
  11. 显示低帧率排查思路记录
  12. SQL server 2016数据库 下载安装
  13. Navicat连接Oracle数据库
  14. matlab流体力学分析,matlab流体力学
  15. 关于机器人方面的sci论文_科学网—2014年SCI收录机器人期刊22种目录 - 万跃华的博文...
  16. 测试用例设计方法——等价类划分法、边界值分析法、场景法、判定表、因果图、错误推测法和正交试验法
  17. 我再copy回来。中海真是有心人。只是,你们在哪里?
  18. 斯托克斯公式(三维中两类曲面和第二类曲线互相转换)
  19. 滴滴共享单车在深圳被叫停;六六接受京东道歉;宝马发布最新充电网络计划丨价值早报
  20. 跟着官方文档一步一步搭建基于gozero的微服务

热门文章

  1. notepad实现垂直标签
  2. 如何在你的Android手机上配置 Python 环境?
  3. 「缠师课后回复精选」第9课 甄别“早泄”男的数学原则!
  4. Android 8.0正式版彩蛋,炸了!微信8.0竟然有18个彩蛋更新!
  5. uni-app(vue小程序)学习笔记
  6. 使用Arduino,蓝牙和Android app的开源爬墙机器人
  7. php yml,YAML、YML在线编辑器(格式化校验)
  8. wps复选框怎么设置_wps中excel复选框怎么设置
  9. 油猴(Tampermonkey)使用教程
  10. 【第十届“泰迪杯”数据挖掘挑战赛】B题:电力系统负荷预测分析 ARIMA、AutoARIMA、LSTM、Prophet、多元Prophet 实现