VMR9在捕获的文件上施加了错误的视频大小

时间:2013-11-05 16:38:54

标签: c++ directshow video-capture

我有以下代码,我正在尝试从网络摄像头捕获并同时预览视频( 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);

默认渲染器 w h 为640,480,而我的VMR9实例则为352,288。

**编辑**

问题是,在某些时候,由于某种原因,摄像机输出PIN的格式从:

RGB24
352x288

要:

I420
352x288

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

这可能是因为未知原因您的格式从640x480更改为352x288的原因。很难猜出什么是有效的拓扑结构,这取决于你找到它。更可靠的方法是避免RenderStream并以更可控的方式以更小的增量构建图表,方法是添加和连接您感兴趣的特定过滤器。