使用 gstreamer 解码实时 WMA/MMS 流

发布于 2024-11-15 22:10:35 字数 860 浏览 3 评论 0原文

我有一个从 Windows Media 服务器接收流式音频的应用程序,其内容类型为 application/x-mms-framed。应用程序在将流传递到 gstreamer 管道之前从数据中删除帧,如下所示:(

 gst-launch fdsrc ! asfdemux ! fakesink

当然,通常管道通常包括 WMA 解码器和其他东西 - 这只是说明问题所需的最低限度)。

我从调试输出中可以看到,ASF 解析第二个数据包时出错:它试图以超出实际开始位置 +3 字节的偏移量来读取它。

来自调试输出的一些数据:

  • 初始标头数据包(来自帧流的 $H)为 5027 字节,似乎已正确解析。最小数据包大小为 1567。
  • 以下每个数据包(来自帧流的 $D)包含 1564 字节。

我认为问题在于 ASF 解复用器对每个数据包使用固定的最小数据包大小值 1567,即使它认识到实际数据包包含较少的数据。它将额外的 3 个字节视为隐式填充,并(有效地)跳过它们,而不是减少要消耗的数据包大小。

这可能是因为我的代码只是以某种方式剥离框架,也需要传递实际的框架大小。也许有一种方法可以使用 gstreamer 的缓冲区传递机制来做到这一点,在这种情况下,我需要编写一个 gstreamer 插件来进行解帧。这样的插件将转换 application/x-mms-framed -> 视频/x-ms-asf。我希望找到一个现有的插件可以做到这一点,但到目前为止还没有成功。

我是否走在正确的轨道上,或者这只是 ASF demuxer 中的一个错误(我怀疑不是,因为我实际上尝试了 3 个不同的 ASF demuxer 插件)?

I have an application that receives streamed audio from Windows Media Servers with a content type of application/x-mms-framed. The application removes the framing from the data before passing the stream to a gstreamer pipeline like:

 gst-launch fdsrc ! asfdemux ! fakesink

(of course, usually the pipeline would usually include a WMA decoder and other stuff - this is just the minimum required to illustrate the problem).

I can see from the debug output that the ASF parsing is going wrong with the second data packet: it is trying to read it with an offset of +3 bytes beyond where it actually starts.

Some data from the debug output:

  • The initial header packet ($H from the framed stream) is 5027 bytes and seems to be parsed correctly. The minimum packet size is 1567.
  • Each of the following data packets ($D from the framed stream) contains 1564 bytes.

I think the problem is that the ASF demuxer is using the fixed min-packet-size value of 1567 for each packet even though it recognizes that the actual packet contains less data. It treats the extra 3 bytes as implicit padding and (effectively) skips them rather than reducing the packet size to consume.

This is probably because my code which simply strips the framing somehow also needs to pass on the actual frame size. Maybe there is a way of doing this with gstreamer's buffer-passing mechanism, in which case I would need to write a gstreamer plugin to do the unframing. Such a plugin would convert application/x-mms-framed -> video/x-ms-asf. I was hoping to find an existing plugin that would do that but no success so far.

Am I on the right track or is this simply a bug in the ASF demuxer (I suspect not as I have actually tried 3 different ASF demuxer plugins)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡的优雅 2024-11-22 22:10:35

我绝对建议编写一个插件。它有点像锅炉板,但却是一种更可靠的方法。缓冲区对象有一个 GST_BUFFER_SIZE 字段来指示大小。

I'd definitely suggest to write a plugin. Its a bit of boiler plater, but a much more solid approach. The buffer object have a GST_BUFFER_SIZE field to tell the size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文