我刚刚开始使用DirectShow编程,DirectShow API的'C'特性使我的皮肤爬行.无尽的返回代码而不是异常,addref/release遍布各处,函数获取指针指针...
是否有任何'C++友好'的DirectShow编程包装器隐藏下面的所有COM丑陋.
我正在使用 DirectShow.Net 库创建一个过滤器图,该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频。然后,在网页上,我可以使用对象元素在 Windows Media Player 对象中呈现视频源。所以现在我很好奇是否可以使用某种类型的 FilterSource 读取该 http 地址。我看到有些人使用 AsyncReader 作为 IBaseFilter,然后将其转换为 IFileSourceFilter 并调用 load 方法并向其传递网络的 url。但我无法使用“http://localhost:8080”的 url 成功执行此操作。我猜这是因为它不是实际的“文件源”。我尝试在 IFileSourceFilter Load 方法中使用 AMMediaType ,其主要类型为 MediaType.URLStream ,子类型为 MediaSubType.Asf ,但仍然没有运气。如果有人能帮助我解决这个问题,我会象征性地吻他们,因为我已经为此工作了一段时间了。请哦请帮助我。
在我的代码中,我相应地创建了 FilterGraph 和 CaptureGraph。然后创建一个 AsyncReader 实例并将其转换为 IBaseFilter。接下来,我将其转换为 IFileSourceFilter 并调用 Load 方法,并向其传递“http://localhost:8080”url。然后将其添加到 FilterGraph。然后,我创建视频渲染过滤器并添加它,但是当我尝试调用 CaptureGraphBuilder2 对象的 RenderStream 方法时,它会抛出“未指定错误”异常。这是我的代码...
var fGraph = new FilterGraph() as IFilterGraph2;
var cGraph = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
cGraph.SetFiltergraph(fGraph);
var tmp = new AsyncReader() as IBaseFilter;
// This is where I tried …Run Code Online (Sandbox Code Playgroud) DSpack具有示例代码,用于播放与DirectShow兼容的视频设备并同时捕获视频帧.TVideoWindow附加到FilterGraph以显示视频(Firgure-1).如果您删除TVideoWindow,则操作系统(Windows)将自动调出ActiveMovie并在单独的窗口中显示视频(图2).
有没有办法使用DSPack捕获视频帧而不使用任何GUI组件而不显示视频?
DSPack论坛提到了NullRenderer过滤器,但没有关于如何使用它的文档或示例.看起来我们可以实现这一点,如果我们直接在GraphEdit中用Null Render手动替换Video Renderer(图3).
我们如何通过在代码中进行所有操作来实现图3中所示的结果?DSPack没有解释如何创建Null渲染器.
Figure-1: The graph of the default example code
Run Code Online (Sandbox Code Playgroud)

Figure-2: Shows what happens if I remove the TVideoWindow
Run Code Online (Sandbox Code Playgroud)

Figure-3: Shows what happens if I replace Video Renderer with a
Null Renderer and manually connect them in the GraphEdit.
Run Code Online (Sandbox Code Playgroud)

这就是我最终做的事情(到目前为止)
请拨打以下ReassignSampleGrabberOutput之前filterGraph.Play;
procedure TForm1.ReassignSampleGrabberOutput;
var
nullRenderer : IBaseFilter;
nullRendererPins: IEnumPins;
nullRendererPin : IPin;
graph: IGraphBuilder;
begin
nullRenderer := CreateComObject(CLSID_NullRenderer) as IBaseFilter;
FilterGraph1.QueryInterface(IID_IGraphBuilder, graph);
graph.AddFilter(nullRenderer, 'Null Renderer');
nullRenderer.EnumPins(nullRendererPins);
nullRendererPins.Reset;
if nullRendererPins.Next(1, nullRendererPin, nil) = S_OK …Run Code Online (Sandbox Code Playgroud) 我有一张 AJA Capture 卡。随卡安装的驱动程序包括一些 DirectShow 过滤器。如果我将过滤器弹出到 GraphEdit 中,我会看到:

如果我运行 ffmpeg 命令
ffmpeg -f dshow -list_options true -i video="AJA Capture Source"
Run Code Online (Sandbox Code Playgroud)
我懂了
[dshow @ 0034eec0] DirectShow video device options
[dshow @ 0034eec0] Pin "Video"
[dshow @ 0034eec0] pixel_format=yuyv422 min s=720x486 fps=27.2604 max s=1024x
486 fps=29.985
...
[dshow @ 0034eec0] Pin "Audio 1-2"
[dshow @ 0034eec0] Pin "Line21"
video=AJA Capture Source: Immediate exit requested
Run Code Online (Sandbox Code Playgroud)
所以我看到了我需要的视频和音频引脚。但是当我尝试运行 ffmpeg 命令来捕获两者时,我只能弄清楚如何做视频部分。如何连接到该音频引脚?似乎所有的示例和文档都指向使用单独的音频设备,而不是挂钩到引脚。我现在像这样从批处理文件中运行它,我使用 ^ 来断行
ffmpeg.exe ^
-y ^
-rtbufsize 100M ^
-f dshow ^
-i video="AJA Capture …Run Code Online (Sandbox Code Playgroud) 我正在使用 DirectShow.Net 创建一个项目,该项目使用 Visual C# 在 Windows 窗体中显示网络摄像头视图的预览。
我想从获得一系列可用的视频设备开始,这样我就可以在内置网络摄像头或 USB 网络摄像头之间进行选择。
我已经看到了几个用 C++ 完成的例子,例如在 msdn“ http://msdn.microsoft.com/en-us/library/windows/desktop/dd377566(v=vs.85).aspx ”上。
但是,由于我不知道任何 C++,因此我不知道如何将此代码转换为 C#。
当我调用过滤器 getpin() 方法时出现以下异常:
运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一种调用约定声明的函数和用另一种调用约定声明的函数指针调用的结果。
所以看来使用了错误的调用约定
我尝试在过滤器标头中修复此问题:
改变:
CBasePin* GetPin(int n);
Run Code Online (Sandbox Code Playgroud)
到:
CBasePin* __stdcall GetPin(int n);
Run Code Online (Sandbox Code Playgroud)
但这不会编译,因为它说(翻译自德语)
重写虚函数与 CBaseFilter::GetPin 的区别仅在于调用约定
我还尝试在项目配置中设置调用约定,但这不起作用。
那我现在该怎么办?
这是过滤器界面:
class MyFilter : public CBaseFilter, public IMyFilter
{
public:
DECLARE_IUNKNOWN;
MyFilter(LPUNKNOWN pUnk, HRESULT* phr);
virtual ~MyFilter(void);
int GetPinCount();
CBasePin* GetPin(int n);
void acceptFilterInput(LPCWSTR pinname, IMediaSample* sample);
static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP STDMETHODCALLTYPE StartRecording();
STDMETHODIMP STDMETHODCALLTYPE Pause();
STDMETHODIMP STDMETHODCALLTYPE Stop();
CCritSec m_lock_filter;
CBaseInputPin* pin0;
CBaseInputPin* pin1; …Run Code Online (Sandbox Code Playgroud) 我正在尝试向捕获源过滤器添加音频功能,以便制作带有音频的虚拟摄像头。从TMH和rdp的代码开始,我用另一个引脚对其进行了扩展,称为“音频”:
CUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
{
ASSERT(phr);
CUnknown *punk = new CVCam(lpunk, phr);
return punk;
}
CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) : CSource(LPCSTR(FILTER_NAME), lpunk, CLSID_VirtualCam)
{
ASSERT(phr);
CAutoLock cAutoLock(&m_cStateLock);
m_paStreams = (CSourceStream **) new CVCamStream*[2];
m_paStreams[0] = new CVCamStream(phr, this, L"Video");
m_paStreams[1] = new CVAudioStream(phr, this, L"Audio");
}
HRESULT CVCam::QueryInterface(REFIID riid, void **ppv)
{
if (riid == _uuidof(IAMStreamConfig) || riid == _uuidof(IKsPropertySet))
{
HRESULT hr;
hr = m_paStreams[0]->QueryInterface(riid, ppv);
if (hr != S_OK) return …Run Code Online (Sandbox Code Playgroud) 从此处捕获源过滤器的绝佳示例开始,我编写了自己的输入捕获设备,该设备在 Graph Studio Next 中运行良好,但在 Skype 或类似应用程序中并未显示为捕获设备(即网络摄像头)。
因为我想了解发生了什么,所以我请您帮助我找出那些应用程序需要什么来显示这样的设备。
一些相关代码:
DLL文件
DEFINE_GUID(CLSID_VirtualCam, 0x8e14549a, 0xdb61, 0x4309, 0xaf, 0xa1, 0x35, 0x78, 0xe9, 0x27, 0xe9, 0x33);
const AMOVIESETUP_MEDIATYPE AMSMediaTypesVideo =
{
&MEDIATYPE_Video,
&MEDIASUBTYPE_NULL
};
const AMOVIESETUP_PIN AMSPinVCam[] =
{
{
L"Output", // Pin string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Can we have none
FALSE, // Can we have many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types …Run Code Online (Sandbox Code Playgroud) 我无法在 windows 10 64 位 m/c 上找到 graphedit 工具,我还根据 microsoft docs 安装了 windows 10 sdk。
参考:https : //docs.microsoft.com/en-us/windows/desktop/directshow/using-graphedit
任何人都可以在有关说明和下载的链接上给我建议,以获取最新版本的图形编辑以及使其在 Windows 10 上运行的任何先决步骤。
问候,
阿君
directshow ×10
c++ ×5
c# ×2
com ×2
.net ×1
audio ×1
delphi ×1
dspack ×1
ffmpeg ×1
graphedit ×1
http ×1
input-filter ×1
visual-c++ ×1
winapi ×1
windows ×1
windows-10 ×1