我正在编写一个从多个音频和视频设备读取的程序,并将数据写入合适的容器(例如mpeg)。我已经在Linux中编写了代码,但现在我还要为windows编写另一个版本。这就是我在Linux中编写它的方式:
initialize the devices (audio: ALSA, video: V4L2)
get the file descriptors
mainloop
select on file descriptors
respond to the proper device
不幸的是我的专业知识仅适用于Linux,我从未使用过Windows SDK。我不知道正确的范例是什么。人们是否以同样的方式使用fds并选择?在那种情况下有没有办法从directshow获得一个fd? 哦,最后一件事,我必须只使用一个线程来完成所有这些。因此,不允许多个线程同时运行且每个处理一个设备的解决方案。 Linux中的代码目前也在一个线程上运行。代码也应该用c ++编写。谢谢。
第二个想法这里只提出一个问题,那就是:如何从DirectShow库中获取视频/音频设备的文件描述符。使用V4L2和ALSA的人,我在DirectShow中寻找相同的东西。
答案 0 :(得分:2)
Windows提供了几个视频和音频API,这是因为较旧的API被[假定的]后代替换,但是旧的API仍然可以保持与现有应用程序的兼容性。
音频API:waveInXxx
系列函数,DirectSound,DirectShow,WASAPI
视频API:适用于Windows的视频,DirectShow,Media Foundation
支持视频+音频流和文件的视频/音频API:适用于Windows的视频,DirectShow,Media Foundation
上面提到的所有内容都提供了某些功能,接口,方法,可扩展性和兼容性选项。我不认为fd,fds和select适用于上面提到的任何一个。出于特定原因,人们可能更喜欢使用API的组合,例如,只有WASAPI才能对音频捕获进行精细控制,但它只是音频API。音频压缩和媒体文件的制作,尤其是视频启用,通常由DirectShow和Media Foundation处理。
视频和音频设备没有文件描述符。在DirectShow和Media Foundation中,您可以获取相应捕获设备的接口/对象,然后您可以以API特定方式发现设备功能,例如支持的格式。然后,您可以获取捕获的数据或将捕获组件连接到另一个对象,例如编码或显示数据。由于文件描述符不是Windows中故事的一部分,因此您的问题基本上不清楚。显然你要求那些熟悉Linux和Windows开发的人员提供一些关于如何在Windows中实现你在Linux中已经做过的事情的指导,但是我担心你最终会以常规的Windows方式完成它,如何使用Windows API建议并在文档和样本中进行演示。
-
DirectShow和Media Foundation API涵盖整个媒体处理管道步骤:捕获,处理和演示。在DirectShow中,您使用组件"过滤器"来构建您的管道。连接在一起(MF具有类似的概念),然后更高级别的应用程序控制它们的操作而不触及实际数据。过滤器与数据交换而不向应用程序报告流传输的每个数据块。
这就是为什么你可能很难找到获得原始框架的可能性"。 DirectShow设计假定原始帧在过滤器之间传递,而不是发送到调用应用程序。获取原始帧对于连接的过滤器来说是微不足道的,您需要根据DirectShow过滤器,库存或自定义来表达所有媒体数据处理需求。
那些 - 无论出于何种原因 - 想要从DirectShow管道中提取此媒体数据流的人经常使用所谓的Sample Grabber Filter(操作系统和MSDN论坛上的数十个问题),这是一个易于处理的库存过滤器,能够接受回调函数并报告流过的每个数据。此过滤器是从捕获设备中提取帧的最简单方法,可以访问原始数据。
DirectShow和Media Foundation标准视频捕获功能基于支持Windows中通过WDM驱动程序存在的模拟视频捕获设备。对于它们,API具有创建和可用的相应组件/过滤器,其可以在管道内连接。由于DirectShow相对容易扩展,因此可以将其他设备放入相同形状的视频捕获过滤器中,这可以涵盖通过SDK,虚拟摄像机等可用的第三方捕获设备。一旦将它们放入DirectShow过滤器,它们就是适用于其他与DirectShow兼容的应用程序,特别是基本上看不出是真正的相机还是软件。
答案 1 :(得分:2)
Roman是这些主题的专家,我认为你不会找到更好的答案。 要添加到Roman的答案,您可以在DirectShow中执行类似的操作:
Enumerate video/audio capture devices/select capture device
Construct DirectShow graph
Add video and audio capture source filters to graph
Add 2 sample grabbers to graph
Configure sample grabber callbacks
Connect capture source filters to samples grabbers
Add renderers to graph (This could be a null renderer or a video/audio renderer)
Connect sample grabbers to renderers
Play graph
Run the event loop
DirectShow will invoke the callbacks per media sample traversing the graph.
您的图表通常如下所示:
callback
|
Video capture -- sample grabber -- renderer
Audio capture -- sample grabber -- renderer
|
callback
正如Roman所说,SDK中有很多样本显示如何
关于线程的主题,您将编写主应用程序线程的代码,DirectShow将处理内部线程管理。但请注意,如果您的回调函数处理密集,则可能会干扰回放,因为(来自MSDN):
数据处理线程阻塞,直到回调方法返回。如果回调没有快速返回,则可能会干扰回放。
根据您的应用要求,这可能重要也可能不重要。如果重要的是你可以,例如将数据传递给另一个线程进行处理。阻止数据处理线程的结果是,在视频的情况下,您将获得较低的帧速率。