使用命名管道使用 FFMPEG 记录 RTP VP8 数据包

Posted

技术标签:

【中文标题】使用命名管道使用 FFMPEG 记录 RTP VP8 数据包【英文标题】:Recording RTP VP8 packets with FFMPEG with named pipe 【发布时间】:2015-08-06 11:29:21 【问题描述】:

我正在用 C++ 开发的网关中开发一个 WebRTC 视频会话记录器,我只能访问单个 RTP 数据包。

当会话开始时,我创建两个线程,一个初始化命名管道,另一个启动 FFMPEG 以从该管道获取数据并将其存储在 matroska 文件中,使用以下命令:

ffmpeg -i \\.\pipe\screenRec -f matroska D:\djhfifj.mkv

每当我收到RTP 数据包时,我都会通过管道将它发送到FFMPEG。尽管所有通信都正常工作,但FFMPEG 似乎无法识别RTP 数据包:

ffmpeg version N-73633-gdfc5858 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.9.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
  libavutil      54. 28.100 / 54. 28.100
  libavcodec     56. 47.100 / 56. 47.100
  libavformat    56. 40.100 / 56. 40.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 21.100 /  5. 21.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.100 /  1.  2.100
  libpostproc    53.  3.100 / 53.  3.100
[aac @ 031b3fc0] Format aac detected only with low score of 1, misdetection possible!
[aac @ 031bd820] More than one AAC RDB per ADTS frame is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[aac @ 031bd820] channel element 3.13 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (26) exceeds limit (9).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (60) exceeds limit (44).
[aac @ 031bd820] Number of bands (6) exceeds limit (4).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (30) exceeds limit (23).
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (16) exceeds limit (11).
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 9 times
[aac @ 031bd820] channel element 3.5 is not allocated
[aac @ 031bd820] channel element 3.13 is not allocated
[aac @ 031bd820] channel element 3.3 is not allocated
[aac @ 031bd820] Number of bands (16) exceeds limit (14).
[aac @ 031bd820] channel element 3.10 is not allocated
[aac @ 031bd820] channel element 3.2 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (61) exceeds limit (43).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (29) exceeds limit (13).
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] channel element 0.7 is not allocated
[aac @ 031bd820] Number of bands (24) exceeds limit (15).
[aac @ 031bd820] channel element 1.1 is not allocated
[aac @ 031bd820] channel element 2.0 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (62) exceeds limit (41).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (15) exceeds limit (13).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (23) exceeds limit (2).
[aac @ 031bd820] channel element 1.4 is not allocated
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] channel element 1.2 is not allocated
[aac @ 031bd820] channel element 1.8 is not allocated
[aac @ 031bd820] channel element 3.7 is not allocated
[aac @ 031bd820] channel element 2.9 is not allocated
[aac @ 031bd820] channel element 3.8 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (48) exceeds limit (43).
[aac @ 031bd820] channel element 3.8 is not allocated
[aac @ 031bd820] channel element 2.13 is not allocated
[aac @ 031bd820] channel element 3.4 is not allocated
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 13 times
[aac @ 031bd820] channel element 2.14 is not allocated
[aac @ 031bd820] SBR was found before the first channel element.
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] Number of bands (6) exceeds limit (5).
[aac @ 031bd820] channel element 3.0 is not allocated
[aac @ 031bd820] channel element 1.5 is not allocated
[aac @ 031bd820] channel element 1.13 is not allocated
[aac @ 031bd820] channel element 1.7 is not allocated
[aac @ 031bd820] channel element 2.0 is not allocated
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 13 times
[aac @ 031bd820] channel element 3.0 is not allocated
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] SBR was found before the first channel element.
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (31) exceeds limit (30).
[aac @ 031bd820] channel element 1.12 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (29) exceeds limit (10).
[aac @ 031bd820] channel element 3.2 is not allocated
[aac @ 031bd820] channel element 3.15 is not allocated
[aac @ 031bd820] channel element 1.5 is not allocated
[aac @ 031bd820] channel element 2.7 is not allocated
[aac @ 031bd820] channel element 1.9 is not allocated
[aac @ 031bd820] Number of bands (54) exceeds limit (34).
[aac @ 031bd820] channel element 1.6 is not allocated
[aac @ 031bd820] channel element 1.2 is not allocated
[aac @ 031bd820] channel element 3.7 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] ms_present = 3 is reserved.
[aac @ 031b3fc0] decoding for stream 0 failed
[aac @ 031b3fc0] Could not find codec parameters for stream 0 (Audio: aac (LTP), 4.0, fltp, 1506 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
\\.\pipe\screenRec96: could not find codec parameters
Input #0, aac, from '\\.\pipe\screenRec96':
  Duration: N/A, bitrate: 1506 kb/s
    Stream #0:0: Audio: aac (LTP), 4.0, fltp, 1506 kb/s
[abuffer @ 0435cd00] Value inf for parameter 'time_base' out of range [0 - 2.14748e+009]
    Last message repeated 3 times
[abuffer @ 0435cd00] Error setting option time_base to value 1/0.
[graph 0 input from stream 0:0 @ 0319afe0] Error applying options to the filter.
Error opening filters!

是否可以让FFMPEG明白发送的数据包是RTPVP8

【问题讨论】:

【参考方案1】:

所以,这将是棘手的。在我们找到解决方案之前,让我先解释一下原因。 FFmpeg 支持两种类型的 RTP 通信层:UDP 和 TCP。大多数人将 TCP 用于无线电等事物,其中实时元素并不那么重要,提前几秒钟缓冲就可以了。 UDP 用于 p2p 通信,如 webrtc。所以我假设你想使用UDP。 (TCP 的情况略有不同,但差别不大。)UDP 数据包具有数据包边界,如果您只是将它们“转储”到命名管道,它们就会丢失。其次,您没有告诉 ffmpeg 命名管道中的数据类型,因此 ffmpeg 可能只是认为它是一个原始 aac 文件(中间的 rtp 位是随机垃圾)。垃圾进,垃圾出。

所以。你如何解决它?就像我说的,这并不容易。我认为您绝对想将 ffmpeg 用作库,而不是可执行文件。然后,我想你想初始化ffmpeg来读取你的数据流为rtp,所以在你的应用控制代码中打开一个localhost(127.0.0.1)socket,通过libavformat打开一个rtp://127.0.0.1/(localhost)连接,并让您的应用程序向其写入将由 ffmpeg 接收的数据包。现在,它将了解它们是 UDP 数据包并执行适当的操作。还有其他方法可以完成同样的事情——事实上,如果你让 ffmpeg 为你做 UDP 连接管理会容易得多,但如果你不想这样做,那也没关系。

【讨论】:

感谢您的回复!我避免使用 ffmpeg 库并打开通信端口。但是如果没有办法通过命名管道提供 RTP 或原始 VP8 数据包,而不必重新排序数据包。这就是我要采取的方法......干杯! 谢谢!在您的帮助下,我设法解决了这个问题。我执行了ffmpeg命令: ffmpeg -dump -i teste.sdp -f matroska X.mkv 并在sdp中说哪个端口有rtp通道(udp套接字)。然后对于收到的每个数据包,我通过 udp 套接字发送它。

以上是关于使用命名管道使用 FFMPEG 记录 RTP VP8 数据包的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg中的多个命名管道

将 ffmpeg 输出通过管道传输到命名管道

ffmpeg rtp传输使用

RTP Payload Format for VP8 Video

如何使用ffmpeg实现h264流传输+H264实现RTP传输数据

将 Windows 命名管道用于 IPC 的一种有效方法