如何使用AMMediaType进行视频过滤

时间:2015-04-01 08:32:09

标签: video directshow pascal lazarus

我正在使用Video Resizer DSP Video Resizer DSP调整视频大小。 我使用Lazarus Free Pascal和DSPack。

本网站介绍了如何使用:http://alax.info/blog/1371

  • CoCreate将DSP作为DMO实例并将其添加到DMO Wrapper Filter
  • 使用IWMResizerProps :: SetFullCropRegion初始化DSP
  • 连接输入引脚
  • 通过IMediaObject :: SetOutputType
  • 设置输出类型
  • IGraphBuilder :: ConnectDirect输出引脚

我写这个:

//Create Resizer DMO
hr := CoCreateInstance(CLSID_DMOWrapperFilter, NIL, CLSCTX_ALL,
IID_IBaseFilter, FResizerDMO);
if FAILED(hr) then EXIT;
//CLSID_CVideoResizerDMO = '{1ea1ea14-48f4-4054-ad1a-e8aee10ac805}'
Hr := (FResizerDMO as IDMOWrapperFilter).Init( CLSID_CVideoResizerDMO,  
DMOCATEGORY_VIDEO_EFFECT );
if FAILED(Hr) then EXIT;
//Add filter to graph
(fgRender as IGraphBuilder).AddFilter( FResizerDMO, 'Resizer' );
if FAILED(Hr) then EXIT; 
// end create FResizerDMO in my graph

// Set output type via IMediaObject::SetOutputType and create structure 
ZeroMemory(@mt, sizeof(DMO_MEDIA_TYPE));
mt.majortype := MEDIATYPE_Video;
mt.subtype := MEDIASUBTYPE_RGB32;
mt.formattype := FORMAT_VideoInfo; 
mt.lSampleSize := pVIH.bmiHeader.biSize;
FillChar(pVIH, SizeOf(TVideoInfoHeader), 0);
mt.pbFormat := CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
pVIH := TVideoInfoHeader(mt.pbFormat^);
pVIH.bmiHeader.biWidth := 720;
pVIH.bmiHeader.biHeight := 576;
pVIH.bmiHeader.biXPelsPerMeter:=9;
pVIH.bmiHeader.biYPelsPerMeter:=16;
pVIH.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
pVIH.bmiHeader.biSizeImage := 720 * 576 * 4;
//  connect pin and next
hr := (FResizerDMO as IMediaObject).SetOutputType
(0,@mt,DMO_SET_TYPEF_CLEAR);

在hr中我收到 DMO_E_TYPE_NOT_ACCEPTED 。 哪里出错了?谁能帮我?谢谢。

3 个答案:

答案 0 :(得分:0)

关于此主题的帖子的交叉发布:How to configure the Resizer DMO?

我不认为你的pbFormat代码是正确的。显然,FillChar会过早地导致内存访问违规。然后看起来你正在修改已分配数据的副本(未显示pVIH声明)。然后biXPelsPerMeter / biYPelsPerMeter看起来有些奇怪,即使我认为这可以被接受。然后你不要初始化其余的TVideoInfoHeader字段。

在电话会议之前,只需在debuger中观看pVIH,您就会看到结构没有明确定义。

首先明确初始化VIDEOINFOHEADER结构的所有字段。

答案 1 :(得分:0)

谢谢Roman R.

//Create Resizer DMO
hr := CoCreateInstance(CLSID_DMOWrapperFilter, NIL, CLSCTX_ALL,
IID_IBaseFilter, FResizerDMO);
if FAILED(hr) then EXIT;
//CLSID_CVideoResizerDMO = '{1ea1ea14-48f4-4054-ad1a-e8aee10ac805}'
Hr := (FResizerDMO as IDMOWrapperFilter).Init( CLSID_CVideoResizerDMO,  
DMOCATEGORY_VIDEO_EFFECT );
if FAILED(Hr) then EXIT;
//Add filter to graph
(fgRender as IGraphBuilder).AddFilter( FResizerDMO, 'Resizer' );
if FAILED(Hr) then EXIT; 
// end create FResizerDMO in my graph
//--------------------------------
// Use IWMResizerProps::SetFullCropRegion to initialize the DSP
// I have a hard time writing this. this must resize the canvas?
//-------------------------------
ZeroMemory(@mt, sizeof(DMO_MEDIA_TYPE));
mt.majortype := MEDIATYPE_Video;
mt.subtype := MEDIASUBTYPE_RGB32;
mt.formattype := FORMAT_VideoInfo; 
mt.lSampleSize := pVIH.bmiHeader.biSize;
FillChar(pVIH, SizeOf(TVideoInfoHeader), 0);
mt.pbFormat := CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
pVIH := TVideoInfoHeader(mt.pbFormat^);
source.Left:=0;  source.Top:=0; source.Right:=1920; source.Bottom:=1080;
// if source = ( 0,0,0,0) read size of the video source?
pVIH.rcSource := source;
target.Left:=0; target.Top:=0; target.Right:=576; target.Bottom:=720;
PVIH.rcTarget:= target;
pVIH.dwBitRate:= 0;
PVIH.dwBitErrorRate:= 0;
pVIH.AvgTimePerFrame:= 333667; //this is for 29 frames, I want 25 frames
 pVIH.bmiHeader.biWidth := 720;
pVIH.bmiHeader.biHeight := 576;
pVIH.bmiHeader.biXPelsPerMeter:=9;
pVIH.bmiHeader.biYPelsPerMeter:=16;
pVIH.bmiHeader.biSize := SizeOf(TBitmapInfoHeader);
pVIH.bmiHeader.biSizeImage := 720 * 576 * 4;
pVIH.bmiHeader.biPlanes := 1;
pVIH.bmiHeader.biBitCount := 4;
pVIH.bmiHeader.biCompression:= BI_RGB;
pVIH.bmiHeader.biClrUsed:=0;
pVIH.bmiHeader.biClrImportant:=0; 
//******* connect  pin input filter of FResizerDMO
Connect(SourceFilter,LAVSplitter);
Connect(LAVSplitter, ffdshowVideoDecoderV1);
Connect(ffdshowVideoDecoderV1,FResizerDMO);
//***************
hr := (FResizerDMO as IMediaObject).SetOutputType
(0,@mt,DMO_SET_TYPEF_CLEAR);

我必须纠正以配置Resizer DMO。 也许我做错了什么?

答案 2 :(得分:0)

抱歉我的英语。我写的很少,以避免错误。 videowindow1是免费pascal的pl_Win_DSPack的组成部分。 videowindows1 =视频混合渲染器9。

hr := CoCreateInstance(CLSID_CaptureGraphBuilder2, nil,
CLSCTX_INPROC_SERVER,IID_ICaptureGraphBuilder2, ICapGraph);
ICapGraph.SetFilterGraph(fgRender as IGraphBuilder);
                    //*****************
hr := ICapGraph.RenderStream(nil,nil, SourceFilter, nil, FResizerDMO);
hr := (FResizerDMO as IMediaObject).SetOutputType(0,@(pMT^),0);// or pMT 
DeleteMediaType(pMT);
hr := ICapGraph.RenderStream(nil, nil, FResizerDMO, nil, VideoWindow1 as 
IBaseFilter);
fgRender.Play;
mc.Run; 

1)使用此代码,视频不会调整大小。我在videowindow1中看到,视频运行的小方块,videowindow1更大。 2)使用GraphStudioNext我已经建立了许多组合。只有ffdshow视频解码器与ResizerDMO连接,在属性过滤器ResizerDMO中我更改参数,但视频没有调整大小。

对不起,谢谢你的帮助