是否将程序输出传递给DirectShow源筛选器以由Lync拾取
Pass program output to a DirectShow source filter to be picked up by Lync?
目标
总的来说,我想完成以下任务:
- 从程序实时生成一系列图像
- 将图像传递给DirectShow源筛选器,该筛选器已注册为捕获源
- 在类似Lync的程序中选择生成的"虚拟网络摄像头">
图像生成已经编写完成,必须利用现有的框架。我目前正在研究框架和DirectShow之间的接口。下面描述我当前用于传递图像的实现。
接口
COM接口在.idl
文件中描述,生成的.c
/.h
文件包含在源过滤器中,并扩展到框架模块中。
附加的方法允许指定媒体格式以支持并基于图像生成速率调整参数。
passImage
方法将指针传递到生成的图像缓冲器和缓冲器的大小。这是由框架接收器模块在接收到要通过的新数据时调用的
MyInterface.idl
[
object,
uuid("46B4BD3C-CD67-4158-BB83-89EA95306A4D"),
] interface IExtLiveSrc : IUnknown
{
...
HRESULT passImage
(
[in] unsigned long size,
[in, size_is(size)] BYTE **img
);
};
DirectShow源筛选器
源过滤器被实现为两个类和一个相关的CLSID,它们被导出为DLL并使用regsvr32
注册。DLLRegisterServer
方法被适当地实现以在CLSID_VideoInputDeviceCategory
下注册COM对象。
MyFilter.h
class CVSource : public CSource {
static CUnknown *WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
// private constructor
}
class CVSourceStream : public CSourceStream
, public virtual IKsPropertySet
, public virtual IAMStreamConfig
, public virtual IExtLiveSrc
{
// constructor, IUnknown, IKsPropertySet, IAMStreamConfig methods
...
HRESULT FillBuffer(IMediaSample *pms);
STDMETHODIMP passImage(unsigned long size, BYTE **img);
}
注意:pin(CSourceStream
派生类(实现了用于传递图像的接口。假设缓冲区大小协商已经建立。
passImage((
STDMETHODIMP CVSourceStream::passImage(unsigned long size, BYTE **img) {
memcpy_s(this->bufferedImg, size, *img, size);
return S_OK;
}
FillBuffer((
HRESULT CVSourceStream::FillBuffer(IMediaSample *pms) {
// Set timestamp on IMediaSample instance
...
BYTE *pData;
pms->GetPointer(&pData);
long lDataLen = pms->GetSize();
memcpy_s(pData, lDataLen, this->bufferedImg, lDataLen);
return S_OK;
}
问题
暂时忽略锁定和同步(我知道FillBuffer()
应该阻塞,直到数据可用(,我做出了以下观察。
- 将生成的缓冲区测试序列直接添加到
FillBuffer()
会导致Lync正确显示它们 - 当运行我的程序时,
passImage()
行为正确,缓冲区实例变量接收正确的数据。但是,在调试时似乎从未调用过FillBuffer()
根据我所做的研究,我的问题似乎是两个不同的进程(我的框架程序和Lync(在源筛选器DLL中不共享相同的数据,因为创建了筛选器图的两个独立实例。
Lync的筛选器图实例与我的程序正在解压缩的图像共享数据的最干净的方式是什么?我看到过"进程间通信"被抛来抛去。虽然我不熟悉这个概念,但为了实现目标,我需要采取哪些步骤(管道、套接字、共享内存、注册表等(?
链接
MSDN论坛上也有类似的讨论
有人讨论了一个与我类似的问题,但没有足够的具体细节,我不想在旧的帖子上发帖。
关于堆栈溢出的类似问题。
事实上,这与我已经拥有的非常相似。然而,我需要运行一个新的应用程序,该应用程序可能会创建自己的过滤器图。
您必须在进程之间传递数据:Lync将始终在其进程中使用筛选器,而不询问从何处获取数据。由于它应该从外部进程获取数据,因此它必须处理进程间通信,并"以某种方式连接"到数据来源的远程进程。
你可以选择如何"以某种方式"准确地实现这一点。我更喜欢使用内存映射文件和事件/互斥进行同步。生产者进程生成数据并将其存储在MMF中,然后Lync进程内的消费者过滤器读取这些数据并作为生成的视频交付。
- 输入验证以筛选出字符、字符串和一系列整数
- 参数包中的筛选器类型
- 在 OpenGL 中使用透视与正交投影时的光线投射(鼠标拾取)
- 筛选 QFileDialog 中显示的目录
- 筛选嵌套的动态元组(元组的动态元组)
- 如何从结构列表中筛选信息
- 通过QLineEdit筛选查询并更新QSqlQueryModel
- 如何从所选目录(位于listWidget中)中筛选图像文件
- 在 c++17 中筛选类型元组
- 不需要更改筛选器算法中的数据
- 在存储库中,筛选器函数返回动态向量或其他存储库
- Centos6 gcc6:编译简单的 c++11 测试文件时,默认的 ABI 不拾取
- 微筛选器从用户模式应用程序接收常量值
- 微筛选器无法阻止'Windows Photos'打开的图像
- C++可变参数模板类型筛选转换
- 当我的程序不在焦点中时,不拾取 GetAsyncKeyState. 在游戏中不工作
- 点云库:计算筛选关键点 - 输入云错误
- 未调用微筛选器PRE_OP_CALLBACK
- OPENCV筛选未定义的参考问题
- 是否将程序输出传递给DirectShow源筛选器以由Lync拾取