【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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/130542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux - 进程控制(下篇)- 进程等待

进程等待 为什么进程需要等待&#xff1f; 我们知道&#xff0c;在Linux 当中&#xff0c;父子进程之间一些结构就是一些多叉树的结构&#xff0c;一个父进程可能管理或者创建了很多个字进程。 而其实我们在代码当中使用fork&#xff08;&#xff09;函数创建的子进程的父进程…

模型训练----对输入变量原地操作(inplace operation)报错

遇到报错one of the variables needed for gradient computation has been modified by an inplace operation。意思是对输入x原地操作&#xff08;inplace operation&#xff09;&#xff0c;一个变量在反向传播过程中被修改了&#xff0c;而不是按照预期的版本&#xff08;ve…

vivo发布“蓝心千询”自然语言对话机器人

&#x1f989; AI新闻 &#x1f680; vivo发布“蓝心千询”自然语言对话机器人 摘要&#xff1a;vivo今日发布了“蓝心千询”自然语言对话机器人&#xff0c;基于蓝心大模型。蓝心千询可以进行知识信息的快速问答&#xff0c;文学创作、图片生成&#xff0c;甚至还能编写程序…

C语言基础知识

C语言基础知识 1. 基本数据类型2. 变量和常量3. 运算符4. 条件语句和循环5. 函数 C语言是一种广泛使用的计算机编程语言&#xff0c;由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;于1972年在贝尔实验室发明。C语言是一种高级语言&#xff0c;因为它允许使用更抽象的语法…

mit6.s081 笔记

1、系统调用 系统调用具体过程。 在任何地方&#xff0c;当我们需要使用系统调用时&#xff0c;只需要include “user/user.h”&#xff0c;就可以通过里面的函数声明来调系统调用&#xff0c;其函数的具体实现由 user/usys.pl 脚本帮我们生成对应的汇编代码&#xff08;具体代…

ENVI波段合成

1、envi5.3合成&#xff08;这种方法&#xff0c;必须有地理参考才可以&#xff09; 在工具栏处搜索波段&#xff0c;找到波段合成&#xff08;Layer Stacking&#xff09; 设置合成波段&#xff0c;其他默认 2、envi classic&#xff08;没有地理坐标也可以&#xff09; 我们…

https网站加载http资源问题

https网站加载http资源问题 前言&#xff1a;最近项目对接了一个第三方的平台、我们需要展示第三方平台返回来的图片资源、由于我们的服务器设置为了https、但是第三方平台返回的图片链接是 http 资源。所以就出现了图片无法加载出来的问题&#xff0c;在此记录一下问题的解决…

Java日期比较大小的3种方式及拓展

目录 一、字符串String的日期比较 二、数值型long比较 三、日期型Date直接比较 四、Date型日期的获取方式 五、Calendar获取年月日【拓展】 一、字符串String的日期比较 String型的日期通过compareTo()来比较&#xff0c;因为String实现了comparable接口 endDate.compare…

右击文件或者文件夹使用vscode打开

平常我们在打开项目时&#xff0c;经常会需要快捷打开方式&#xff0c;直接使右键使用编辑器打开&#xff0c;但是有时在安装时忘记了选择 “Add “Open with Code” action to Windows Explorer file context menu” 在Windows资源管理器文件上下文菜单中添加“用代码打开”操…

Xcode 14.3 新版问题总结

1. "xxx/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/xxxx" failed: No such file or directory 解决&#xff1a;Pods/Targets Support Files/Pods-App-frameworks.sh中 if [ -L "${source}" ]; thenecho "Symlinked..."# sour…

HttpClient基本使用

十二、HttpClient 12.1 介绍 HttpClient是Apache Jakarta Common 下的子项目&#xff0c;可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包&#xff0c;并且它支持HTTP协议最新的版本和建议。 HttpClient作用&#xff1a; 发送HTTP请求接收响应数据 …

Jtti:redis出现太多连接错误怎么解决

Redis出现太多连接错误通常是由于一些常见问题引起的&#xff0c;这些问题可能会导致连接超限、性能下降或服务不可用。以下是一些可能导致Redis连接错误的原因以及如何解决它们的建议&#xff1a; 1. 连接泄漏&#xff1a; 连接泄漏是指在使用完Redis连接后没有正确关闭它们。…

1-10 HTML中input属性

HTML中input属性 text&#xff1a;用于接受单行文本输入password&#xff1a;用于密码输入&#xff0c;输入字符会被掩盖radio&#xff1a;用于单选按钮&#xff0c;用户可以在一组选项中选择一个checkbox&#xff1a;用于复选框&#xff0c;用户可以选择多个选项number&#…

有效的括号

给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有…

Django 表单处理:从前端到后台的全流程指南

Django作为一个高级Python Web框架&#xff0c;它的表单处理能力强大&#xff0c;可以有效地处理用户输入&#xff0c;进行数据验证以及错误处理。本文将详细介绍如何在Django中创建、处理和使用表单。 1. Django表单系统的核心 Django的表单系统处理表单的生命周期&#xff…

Python之字符串详解

目录 一、字符串1、转义字符与原始字符串2、使用%运算符进行格式化 一、字符串 在Python中&#xff0c;字符串属于不可变、有序序列&#xff0c;使用单引号、双引号、三单引号或三双引号作为定界符&#xff0c;并且不同的定界符之间可以互相嵌套。 ‘abc’、‘123’、‘中国’…

MySQL:一文掌握MySQL索引

目录 概念优缺点索引的数据结构Hash索引有序数组索引二叉搜索树平衡二叉树B树B树 索引的物理结构MyISAM存储引擎InnoDB存储引擎 索引的分类页、区、段change buffer 和索引回表和覆盖索引索引优化面试题索引哪些情况下会失效什么是索引下推主键选择自增和uuid的区别 概念 官方…

修改YOLOv5的模型结构

YOLOv5 模型结构 C3模块结构图 修改目标 修改目标是移除C3模块concat后的卷积操作 YOLOv5的模型存储在项目目录下的models目录中。 一些以yaml为后缀的文件保存了一些模型的超参数&#xff0c;通过不同的参数&#xff0c;形成了yolov5s,yolov5n,yolov5l等不同参数等级&#…

3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用

一、概述 HOOPS Exchange是一套高性能模型转换软件库&#xff0c;可以给软件提供强大的模型的导入和导出功能&#xff0c;我们可以将其单独作为转换工具使用&#xff0c;也可以将其集成到自己的软件中。 同样&#xff0c;HOOPS 的其它产品&#xff0c;也离不开HOOPS Exchange…

鸿蒙应用开发取消标题栏

在config.json中的module下添加如下内容&#xff1a; "metaData": {"customizeData": [{"name": "hwc-theme","extra": "","value": "androidhwext:style/Theme.Emui.Light.NoTitleBar"}] }…