我有以下代码,我试图用它来从网络摄像头捕获并同时预览视频(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 中存在这种格式的问题。一个有趣的事实是,资源管理器中的视频缩略图还可以,我可以看到第一帧的颜色正确。