【问题标题】:DirectShow video stream ends immediately (m_pMediaSample is NULL)DirectShow 视频流立即结束(m_pMediaSample 为 NULL)
【发布时间】:2014-07-07 16:36:44
【问题描述】:

我有一个 视频渲染器,它是从 CBaseVideoRenderer 重新编写的。渲染器用于从实时源 (BDA) 接收数据的图中。看起来连接已正确建立,但由于没有样本,视频渲染立即结束。然而,音频渲染工作,即我可以听到声音,而我的渲染器的DoRenderSample 从未被调用。

在调试器中单步执行代码,我发现在CBaseRenderer::StartStreaming 中,流立即结束,因为成员m_pMediaSampleNULL。如果我用 EVR 渲染器替换我的渲染器,它会显示帧,即流不会在 EVR 渲染器的第一帧之前结束,而只是我的渲染器。

为什么会这样,我该如何解决?我实现了(遵循http://www.codeproject.com/Articles/152317/DirectShow-Filters-Development-Part-Video-Render 的示例)我理解的基本接口(@98​​7654331@、SetMediaTypeDoRenderSample),所以我看不到任何影响这里发生的事情的可能性......

编辑:这是从 ROT 看到的图表:

我基本上尝试做的是捕获使用 VIDEOINFOHEADER2 的 DVB 流,标准采样采集器不支持该流。虽然该频道是未加密的公共德国电视频道,但会不会是 DRM 问题?

编辑 2: 我已将渲染器附加到另一个源(Blackmagic Intensity Shuttle)。似乎是源导致了问题,因为我在另一张图中获得了样本。

编辑 3: 按照 Roman 的建议,我创建了一个变换过滤器。图表看起来像

不幸的是,我遇到了同样的问题,即我没有得到任何样本(Transform 未被调用)。

【问题讨论】:

  • 我最好的猜测是您的过滤器中的问题:您的推导不正确或出现了问题,但您发布的内容还不够。渲染器应该等待样本,根据您的描述,您的渲染器会执行相反的操作并中止。
  • 我基本上遵循了codeproject.com/Articles/152317/… 的示例,它只覆盖了完全相同的方法。据我了解,CBaseVideoRenderer 的实现应该代表我等待样本。
  • 对于 Sample Grabber 中缺少 VIDEOINFOHEADER2 支持的自定义视频渲染器看起来不是合适的解决方案。
  • 罗曼,你这是什么意思?据我了解,微软的抓取器无法理解VIDEOINFOHEADER2,也已被弃用。因此,我看到了两个选项:自定义渲染器或转换过滤器。据我了解,转换过滤器编写起来更复杂,所以我尝试了渲染器(我对 DShow 很陌生,所以我可能弄错了)。
  • \DirectShow\Samples\C++\DirectShow\Filters\Grabber 此处:“Microsoft® DirectX® 9.0 SDK 更新(2004 年 10 月)附加内容”。不过,您可能不得不追逐下载。如果我没记错的话,它在 2005 年 2 月左右被完全删除。

标签: directshow c++ directshow renderer


【解决方案1】:

您应该选择了从媒体管道中提取视频帧的错误路径。所以你正在实现一个“网络渲染器”,它会终止管道以进一步将数据发送到网络。

接受提要的渲染器听起来很合适。然而,实现自定义渲染器是一项不典型的任务,因此没有太多关于此的信息。此外,一个功能齐全的渲染器通常配备了示例调度部分,该部分结束了流传输 - 当您通过从基类继承来自定义它时,事情相对容易被破坏。也就是说,虽然该方法听起来不错,但您可能希望将其与您拥有的另一个选项进行比较,即...

Sample Grabber + Null Renderer 的组合,两个标准过滤器,您可以将回调附加到这些过滤器并获取正确终止管道的帧。这里的问题是标准的 Sample Grabber 不支持VIDEOINFOHEADER2。使用另一个视频解码器,您可能会获得解码信息VIDEOINFOHEADER,这是一种选择。然后改进 Sample Grabber 本身是另一种解决方案:DirectX SDK Extras February 2005 (dxsdk_feb2005_extras.exe) 是 SDK,其中包含一个类似于标准 Sample Grabber 的过滤器,称为 Grabber \DirectShow\Samples\C++\DirectShow\Filters\Grabber。它是/曾经在源代码中可用,并提供了一个很好的描述文本文件。扩展以允许它接受VIDEOINFOHEADER2 并以这种方式为您的应用程序提供有效负载数据相对容易。

从 DirectShow 图表中获取数据的最简单方法,如果您不打算使用 MultiMedia Streaming,大概是自己写的TransInPlace过滤器,一个子品种 变换过滤器。然后将此过滤器连接到您希望的所需数据流 监视,然后运行、暂停、查找或以其他方式控制图形。数据,因为它通过 通过变换过滤器,可以随心所欲地进行操作。我们称这种 过滤器,一个Њsample grabberћ。微软发布了一个功能有限的样本采集器 用 DX8.0。此过滤器受到限制,因为它不处理 DV 数据或媒体类型 格式为 VideoInfo2。它不允许用户接收预卷样品。 (什么是前卷样本?参见 DX8.1 文档)它的 ЊOneShotћ 模式也有一些问题。

此外,Grabber 示例本身非常简单 - 总共可能有 1000 行代码,包括 cmets。

【讨论】:

  • 嗯。我有转换过滤器,它在图中连接并且图可以运行,但是...Transform 永远不会被调用。也就是说,我的效果和之前一样。
  • 所以关于 DRM,您可能是对的,请参阅 this Q 并检查视频解码器输出上的媒体类型。此外,您至少可以尝试其他解码器以检查它们是否可以正常工作。
  • VIDEOINFOHEADER2::dwCopyProtectFlags 在我的情况下为 0 - 我想知道那个人是如何获得此信息以连接到第 3 方渲染器的...
【解决方案2】:

您的解码器或分离器似乎没有对视频帧进行解复用。进一步查看链,看看哪些过滤器正在为您的渲染器 pin 提供数据,可能是它唯一识别音频。

尝试将文件放入 Graphedit(顺便说一句,网上有一个更好的),看看它创建了哪些过滤器。

然后查看 DirectShow SDK 中的示例。

【讨论】:

  • 我已经通过 ROT 检查了图表。正如我所说,如果我添加 EVR 而不是我的渲染器,它会显示视频。如果调用OnStartStreaming,我会假设连接正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-02
  • 2022-12-02
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
相关资源
最近更新 更多