【问题标题】:How to work with AMMediaType for video filters如何将 AMMediaType 用于视频过滤器
【发布时间】:2015-06-05 19:52:57
【问题描述】:

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

本站说明如何使用:http://alax.info/blog/1371

  • CoCreateInstance 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);

在小时内我收到 DMO_E_TYPE_NOT_ACCEPTED。 我哪里错了?谁能帮我?谢谢。

【问题讨论】:

    标签: video directshow pascal lazarus


    【解决方案1】:

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

    我认为您的 pbFormat 代码不正确。显然,FillChar 会导致内存访问冲突,因为您这样做太早了。然后看起来您正在修改分配数据的副本(未显示 pVIH 声明)。然后 biXPelsPerMeter/biYPelsPerMeter 看起来有些奇怪,尽管我认为这是可以接受的。然后你就不用初始化其余的 TVideoInfoHeader 字段了。

    只需在调用前在调试器中观察 pVIH,您就会发现结构没有明确定义。

    从显式初始化VIDEOINFOHEADER 结构的所有字段开始。

    【讨论】:

      【解决方案2】:

      谢谢罗曼·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 的所有内容。 也许我做错了?

      【讨论】:

      • biBitCount 应该是 32,而不是 4。
      【解决方案3】:

      对不起我的英语。我很少写以避免错误。 videowindow1 是 pl_Win_DSPack for free pascal 的组件。 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 Video Decoder 与 ResizerDMO 连接,并且在属性过滤器 ResizerDMO 中我更改了参数,但视频没有调整大小。

      对不起,谢谢你的帮助

      【讨论】:

      • 您应该正在编辑您的问题,或者如果您不继续之前提出的问题,请开始一个新问题。答案框不适用于 StackOverflow 上的后续操作。
      • 我没用过pl_Win_DSPack,也不知道这个组件是什么。确保 (VideoWindow1 as IBaseFilter) 与 nil 不同。我也怀疑 ResizerDMO 是否支持像素格式(又名颜色空间)转换,所以最好强制输入子类型与输出(RGB32)相同。另一方面,并​​非所有视频解码器都支持输出到 RGB32。所以有时你会需要色彩空间转换。 所以我的建议是寻找现成的第三方过滤器。这是一组可能适合您的过滤器 - sourceforge.net/projects/videoprocessing
      • 谢谢 Anton Angelov。我认为它更容易用于我的项目 resizeDMO。最后一次机会,准备好使用过滤器,就像你建议的那样。现在我必须为我的项目找到合适的过滤器,并了解如何在我的应用程序中使用过滤器。谢谢,谢谢,谢谢。
      猜你喜欢
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 2018-06-27
      • 2017-01-07
      • 2019-02-08
      • 2023-03-16
      相关资源
      最近更新 更多