0

我有以下代码,我试图用它来从网络摄像头捕获并同时预览视频(pRenderer指向一个窗口化的 VMR9 过滤器,而mPMux指向一个由ICaptureGraphBuilder2::SetOutputFileName返回的多路复用器):

hr = mPBuild->RenderStream(
    &PIN_CATEGORY_PREVIEW,
    &MEDIATYPE_Video,
    mPCapVideo,
    NULL,
    pRenderer);

hr = mPBuild->RenderStream(
    &PIN_CATEGORY_CAPTURE,
    &MEDIATYPE_Video,
    mPCapVideo,
    NULL,
    mPMux);

虽然预览看起来不错,但捕获的视频分辨率仅为 352x288,并且严重失真,虽然我仍然可以识别出其中的两个脸部实例,但它充满了明亮的绿色区域,并且呈现出交错的伪影。只有 Windows Media Player 似乎无法渲染此视频,VLC 和 Quicktime 显示正确渲染的 352x288 视频。

如果我使用默认渲染器:

hr = mPBuild->RenderStream(
    &PIN_CATEGORY_PREVIEW,
    &MEDIATYPE_Video,
    mPCapVideo,
    NULL,
    NULL);

hr = mPBuild->RenderStream(
    &PIN_CATEGORY_CAPTURE,
    &MEDIATYPE_Video,
    mPCapVideo,
    NULL,
    mPMux);

捕获的 AVI 大小为 640x480,所有播放器都能够正确再现它,包括媒体播放器。

看起来 VMR9 正在对整个图形施加视频大小,即使是捕获的文件也是如此。以下代码证实了这种直觉,该代码位于对IMediaControl::Run的调用之前:

IBasicVideo *pBasicVideo;
hr = mPGraph->QueryInterface(IID_PPV_ARGS(&pBasicVideo));
long w, h;
hr = pBasicVideo->GetVideoSize(&w, &h);

默认渲染器wh为 640、480,而我的 VMR9 实例为 352、288。

** 编辑 **

问题是,由于某种原因,相机输出 PIN 的格式从以下位置切换:

RGB24
352x288

至:

I420
352x288

而且我猜媒体播放器在 AVI 中存在这种格式的问题。一个有趣的事实是,资源管理器中的视频缩略图还可以,我可以看到第一帧的颜色正确。

4

2 回答 2

2

好吧,当您连接两个过滤器时,它们必须就视频格式(包括分辨率)达成一致。不同的渲染器可能更喜欢不同的格式,所以你有这种行为。您可以查询 IAMStreamConfig 接口的网络摄像头输出引脚,以获取支持的格式列表并选择您需要的格式。播放捕获的视频时出现问题应该是由不正确的标题引起的:实际的视频格式不是文件标题中指定的格式。

于 2013-11-11T08:24:12.590 回答
2

RenderStream是其他 DirectShow API 方法的高级包装器,它为您填充缺失的部分构建流式传输管道(过滤器图)。由于它正在积极使用Intelligent Connect,因此它可能会添加您不知道的新过滤器,包括您不想要的过滤器,以及可能影响您在通话时已经拥有的过滤器上的媒体类型(格式)的过滤器.

这可能是您的格式从 640x480 更改为 352x288 的可能原因,原因不明。很难猜出什么是有效的拓扑结构,这取决于您自己找出答案。一种更可靠的方法是通过添加和连接您感兴趣的特定过滤器,以更可控的方式避免RenderStream并以更小的增量构建图形。

于 2013-11-19T20:04:00.327 回答