【MediaFoundation】读取音视频

2023-11-03 19:52

本文主要是介绍【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】读取音视频的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/340510

相关文章

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

通过C#和RTSPClient实现简易音视频解码功能

《通过C#和RTSPClient实现简易音视频解码功能》在多媒体应用中,实时传输协议(RTSP)用于流媒体服务,特别是音视频监控系统,通过C#和RTSPClient库,可以轻松实现简易的音视... 目录前言正文关键特性解决方案实现步骤示例代码总结最后前言在多媒体应用中,实时传输协议(RTSP)用于流媒体服

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

下载/保存/读取 文件,并转成流输出

最近对文件的操作又熟悉了下;现在记载下来:学习在于 坚持!!!不以细小而不为。 实现的是:文件的下载、文件的保存到SD卡、文件的读取输出String 类型、最后是文件转换成流输出;一整套够用了; 重点: 1:   操作网络要记得开线程; 2:更新网络获取的数据 切记用Handler机制; 3:注意代码的可读性(这里面只是保存到SD卡,在项目中切记要对SD卡的有无做判断,然后再获取路径!)

ROS1 + Realsense d455 固件安装+读取rostopic数据

目录 安装固件(一定要匹配)ROS1 wrapper 安装方法Realsense SDK 安装方法Realsense Firmware 安装方法 修改roslaunch配置文件,打开双目图像和IMU数据其他坑点参考链接 安装固件(一定要匹配) 如果你是使用ROS1获取realsense数据的话,一定要注意,SDK, Firmware的版本不是越新越好!!,这是因为intel已经不

Python批量读取身份证信息录入系统和重命名

前言 大家好, 如果你对自动化处理身份证图片感兴趣,可以尝试以下操作:从身份证图片中快速提取信息,填入表格并提交到网页系统。如果你无法完成这个任务,我们将在“Python自动化办公2.0”课程中详细讲解实现整个过程。 实现过程概述: 模块与功能: re 模块:用于从 OCR 识别出的文本中提取所需的信息。 日期模块:计算年龄。 pandas:处理和操作表格数据。 PaddleOCR:百度的