基于Vivek VCAM扩展虚拟音视频设备无音频回调问题咨询
基于Vivek VCAM源码实现音视频同步虚拟摄像头的音频传输修复
问题描述
我已基于Vivek的VCAM滤镜源码成功实现虚拟摄像头设备,现需要将其扩展为可同时传输音视频的单一虚拟摄像头,同步输出视频与音频流。
针对该需求我已完成如下修改:
- 注册媒体类型与输出Pin配置:
const AMOVIESETUP_MEDIATYPE AMSMediaTypesVCam[] = { { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL }, { &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL } }; const AMOVIESETUP_PIN AMSPinVCam = { L"Output", // Pin字符串名称 FALSE, // 是否为渲染Pin TRUE, // 是否为输出Pin FALSE, // 是否允许无实例 FALSE, // 是否允许多实例 &CLSID_NULL, // 连接的滤镜CLSID NULL, // 连接的Pin 2, // 支持的媒体类型数量 AMSMediaTypesVCam // Pin支持的媒体类型列表 };
其余代码与Vivek原有虚拟摄像头实现完全一致,但目前音频媒体类型相关逻辑始终未被调用,无法将音频缓冲区传输到虚拟摄像头。
2. GetMediaType函数适配:
// GetMediaType函数内逻辑 if (IsEqualGUID(*pmt->Type(), MEDIATYPE_Video) || iPosition == 1) { // 配置位图格式(视频相关逻辑) } else if (IsEqualGUID(*pmt->Type(), MEDIATYPE_Audio)) { // 配置波形格式(音频相关逻辑) }
DecideBufferSize函数适配:
// DecideBufferSize函数内逻辑 if (IsEqualGUID(*m_mt.Type(), MEDIATYPE_Video)) { // 视频缓冲区分配逻辑 } else if (IsEqualGUID(*m_mt.Type(), MEDIATYPE_Audio)) { // 音频缓冲区分配逻辑 }
需要明确还需完成哪些修改才能实现音频流正常传输。
问题根因
你当前的实现本质上是给单个输出Pin同时注册了音视频两种媒体类型,这不符合DirectShow的滤镜设计规范:单个输出Pin在同一连接生命周期内只能协商一种主媒体类型,绝大多数应用枚举虚拟摄像头设备时,只会优先请求视频媒体类型,永远不会触发同个Pin上的音频类型协商逻辑,这就是音频分支代码始终不被调用的根本原因。
另外Windows系统对摄像头类设备的枚举逻辑默认只会采集视频Pin的流,音频流需要暴露独立的音频输出Pin,同时完成设备端的音频接口注册,否则系统和应用根本不会识别到设备支持音频输出。
必须完成的修改项
- 拆分输出Pin:不要在同一个输出Pin上同时注册音视频媒体类型,新增独立的音频输出Pin。视频输出Pin仅保留
MEDIATYPE_Video相关的媒体类型配置,音频输出Pin单独注册MEDIATYPE_Audio相关的媒体类型。两个Pin独立实现GetMediaType、CheckMediaType、DecideBufferSize、FillBuffer逻辑,不要共用一套判断分支。 - 修正媒体类型枚举逻辑:你当前
GetMediaType中iPosition == 1的判断写在视频分支是错误的,音频Pin的媒体类型枚举要从iPosition=0开始,按音频支持的格式依次返回(比如PCM等目标音频子类型),不要和视频的位置索引混在一起。 - 补全音频媒体类型完整参数:不要只设置主类型为
MEDIATYPE_Audio,必须完整填充WAVEFORMATEX结构体,明确采样率、位深、声道数、块对齐、平均字节率等参数,否则应用枚举时会认为音频Pin格式无效直接跳过。 - 补全音频流推送逻辑:在音频Pin的
FillBuffer函数中按采样间隔填充音频帧数据,同时做好音视频时间戳对齐:音视频帧的起始参考时间要匹配同一时钟源,音频帧时长按照采样数/采样率计算,视频帧时长按照帧率计算,避免音画不同步。 - 修改设备注册逻辑:原有VCAM的注册信息只在视频设备类下注册,你需要补充在音频输入设备分类(
CLSID_AudioInputDeviceCategory)下注册音频输出接口,否则系统音频枚举列表里看不到你的虚拟设备音频端,通讯、直播类应用自然不会请求音频流。 - 实现流状态同步控制:两个输出Pin要共用同一个参考时钟,在滤镜的
Run、Pause、Stop状态切换时,同时控制两个Pin的流启动、暂停、停止动作,避免单端流启动导致的连接异常。
注意事项
不要尝试用单个输出Pin同时推音视频,除了不符合DirectShow规范外,大部分基于MediaFoundation框架的新应用(比如Win10/11自带相机、Teams、新版Chrome)根本不识别单Pin混合媒体类型的设备,拆分为独立音视频Pin是唯一兼容全场景的实现方案。
内容的提问来源于stack exchange,提问作者enzio91900
相关产品推荐
相关产品推荐

