【MediaFoundation】读取音视频

编程入门 行业动态 更新时间:2024-10-06 18:22:57

【MediaFoundation】读取<a href=https://www.elefans.com/category/jswz/34/1768069.html style=音视频"/>

【MediaFoundation】读取音视频

原文链接: 官方文档

Microsoft Media Foundation支持音频和视频捕获。视频捕获设备通过UVC类驱动程序支持,并必须与UVC 1.1兼容。音频捕获设备通过Windows音频会话API(WASAPI)支持。

在Media Foundation中,捕获设备通过媒体源对象来表示,该对象公开了IMFMediaSource接口。在大多数情况下,应用程序不会直接使用这个接口,而是会使用一个更高级的API,如Source Reader,来控制捕获设备。

枚举音视频捕获设备

要枚举系统上的捕获设备,请执行以下步骤:

  1. 调用MFCreateAttributes函数来创建一个属性存储。
  2. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE属性设置为以下值之一:
描述
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID列举音频设别
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID列举视频设别
  1. 调用MFEnumDeviceSources函数。该函数分配了一个IMFActivate指针的数组。每个指针表示系统上一个设备的激活对象。
  2. 调用IMFActivate::ActivateObject 方法从一个激活的对象中创建一个媒体源的实例。
  3. 可以访问被激活的对象的属性,包括:
    • MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME 包含设备展示的名字。这个展示的名字是给用户看的,并不一定是唯一的。
    • 对于视频设备,MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性包含了设备的符号链接。符号链接在系统上唯一标识设备,但不是可读的字符串。
    • 对于音频设备, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 效果同上。

下面是一个完整的Demo用于输出视频设备的名称。

#include <iostream>
#include <Windows.h>
#include <mferror.h>
#include <comdef.h>
#include <mfidl.h>
#include <mfapi.h>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")void DebugShowDeviceNames(IMFActivate** ppDevices, UINT count)
{for (DWORD i = 0; i < count; i++){HRESULT hr = S_OK;WCHAR* szFriendlyName = NULL;// Try to get the display name.UINT32 cchName;hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,&szFriendlyName, &cchName);if (SUCCEEDED(hr)){// 调试的时候输出到调试窗口/*OutputDebugString(szFriendlyName);OutputDebugString(L"\n");*/// 直接输出到终端std::wcout << szFriendlyName << std::endl;}CoTaskMemFree(szFriendlyName);}
}HRESULT CreateVideoCaptureDevice(IMFMediaSource** ppSource)
{*ppSource = NULL;UINT32 count = 0;IMFAttributes* pConfig = NULL;IMFActivate** ppDevices = NULL;// Create an attribute store to hold the search criteria.HRESULT hr = MFCreateAttributes(&pConfig, 1);// Request video capture devices.if (SUCCEEDED(hr)){hr = pConfig->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);}// Enumerate the devices,if (SUCCEEDED(hr)){hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);DebugShowDeviceNames(ppDevices, count);}// Create a media source for the first device in the list.if (SUCCEEDED(hr)){if (count > 0){hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));}else{hr = MF_E_NOT_FOUND;}}for (DWORD i = 0; i < count; i++){ppDevices[i]->Release();}CoTaskMemFree(ppDevices);return hr;
}int main()
{IMFMediaSource* ppSource = nullptr;auto ret = CreateVideoCaptureDevice(&ppSource);
}

使用捕获设备

在为捕获设备创建媒体源后,使用 Source Reader 从设备获取数据。Source Reader 提供包含捕获音频数据或视频帧的媒体样本。下一步取决于你的应用场景:

  • 视频预览:使用 Microsoft Direct3D 或 Direct2D 来显示视频
  • 文件捕获:使用 Sink Writer 对文件进行编码
  • 音频预览: Use WASAPI.

如果你想将音频捕获与视频捕获结合起来,可以使用聚合媒体源。聚合媒体源包含一组媒体源,并将所有的流合并到一个单一的媒体源对象中。要创建聚合媒体源的实例,调用 MFCreateAggregateSource 函数。

关闭设备

当不再需要捕获设备时,你必须通过调用 MFCreateDeviceSource 或 IMFActivate::ActivateObject 获取的 IMFMediaSource 对象上调用 Shutdown 来关闭设备。如果不调用 Shutdown,可能会导致内存链接,因为系统可能会保持对 IMFMediaSource 资源的引用,直到调用 Shutdown 为止。

if (g_pSource)
{g_pSource->Shutdown();g_pSource->Release();g_pSource = NULL;
}

如果申请了字符容器或者符号链接设别,你应该释放这些对象

   CoTaskMemFree(g_pwszSymbolicLink);g_pwszSymbolicLink = NULL;g_cchSymbolicLink = 0;

更多推荐

【MediaFoundation】读取音视频

本文发布于:2023-11-17 09:23:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1641262.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:音视频   MediaFoundation

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!