我正在尝试使用 FFMPEG 将视频帧流式传输到 RTSP 服务器。我用 C++ 实例化了 ffmpeg 管道。有时该过程工作正常,有时我会收到错误“将数据包提交到复用器时出错:管道损坏”。复用数据包时出错。奇怪的是,流有时工作,有时不工作,这让我相信我设置的 FFMPEG 参数不一定是错误的。
我正在 MATLAB 中使用 mex 函数来接收帧并对其进行流式传输。
// Global variables
FILE* openPipeLine = NULL;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], int frameWidth, int frameHeight)
{
Ptr<Mat> inputFrame = ocvMxArrayToImage_uint8(prhs[0], true);
Mat processedFrame = *inputFrame;
// Check if FFMPEG process has been started
if (!openPipeLine)
{
openPipeLine = _popen("ffmpeg -report -f rawvideo -r 10 -video_size 1280x720 -pixel_format bgr24 -i pipe: -vcodec libx264 -pix_fmt yuv420p -f rtsp rtsp://localhost:8554/mystream 2> log.txt", "wb");
}
// Write the frame data to the pipeline
fwrite(processedFrame.data, 1, frameWidth * frameHeight * 3, openPipeLine);
mexAtExit(exitFcn);
}
下面是 ffmpeg 过程的完整报告。我的操作系统变量是否会不时发生变化,导致流有时工作而有时中断?我使用的是 Windows 10。
Log level: 48
Command line:
ffmpeg -report -f rawvideo -r 10 -video_size 1280x720 -pixel_format bgr24 -i pipe: -vcodec libx264 -pix_fmt yuv420p -f rtsp rtsp://localhost:8554/mystream
built with gcc 12.2.0 (Rev10, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-lib libavutil 58. 16.101 / 58. 16.101
libavcodec 60. 23.100 / 60. 23.100
libavformat 60. 10.100 / 60. 10.100
libavdevice 60. 2.101 / 60. 2.101
libavfilter 9. 11.100 / 9. 11.100
libswscale 7. 3.100 / 7. 3.100
libswresample 4. 11.100 / 4. 11.100
libpostproc 57. 2.100 / 57. 2.100
Splitting the commandline.
Successfully parsed a group of options.
Opening an input file: pipe:.
[rawvideo @ 00000182dba5efc0] Opening 'pipe:' for reading
[pipe @ 00000182dba611c0] Setting default whitelist 'crypto,data'
[rawvideo @ 00000182dba5efc0] Before avformat_find_stream_info() pos: 0 bytes read:65536 seeks:0 nb_streams:1
[rawvideo @ 00000182dba5efc0] All info found
[rawvideo @ 00000182dba5efc0] After avformat_find_stream_info() pos: 2764800 bytes read:2764800 seeks:0 frames:1
Input #0, rawvideo, from 'pipe:':
Duration: N/A, start: 0.000000, bitrate: 221184 kb/s
Stream #0:0, 1, 1/10: Video: rawvideo (BGR[24] / 0x18524742), bgr24, 1280x720, 221184 kb/s, 10 tbr, 10 tbn
Successfully opened the file.
Parsing a group of options: output url rtsp://192.168.0.2:8554/mystream.
Applying option vcodec (force video codec ('copy' to copy stream)) with argument libx264.
Applying option pix_fmt (set pixel format) with argument yuv420p.
Applying option f (force format) with argument rtsp.
Successfully parsed a group of options.
Opening an output file: rtsp://192.168.0.2:8554/mystream.
[out#0/rtsp @ 00000182dba72c00] No explicit maps, mapping streams automatically...
[vost#0:0/libx264 @ 00000182dba75cc0] Created video stream from input stream 0:0
Successfully opened the file.
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
detected 16 logical cores
[graph 0 input from stream 0:0 @ 00000182dba86180] Setting 'video_size' to value '1280x720'
[graph 0 input from stream 0:0 @ 00000182dba86180] Setting 'pix_fmt' to value '3'
[graph 0 input from stream 0:0 @ 00000182dba86180] Setting 'time_base' to value '1/10'
[graph 0 input from stream 0:0 @ 00000182dba86180] Setting 'pixel_aspect' to value '0/1'
[graph 0 input from stream 0:0 @ 00000182dba86180] Setting 'frame_rate' to value '10/1'
[graph 0 input from stream 0:0 @ 00000182dba86180] w:1280 h:720 pixfmt:bgr24 tb:1/10 fr:10/1 sar:0/1
[format @ 00000182dba86540] Setting 'pix_fmts' to value 'yuv420p'
[auto_scale_0 @ 00000182dba869c0] w:iw h:ih flags:'' interl:0
[format @ 00000182dba86540] auto-inserting filter 'auto_scale_0' between the filter 'Parsed_null_0' and the filter 'format'
[AVFilterGraph @ 00000182dba49040] query_formats: 4 queried, 2 merged, 1 already done, 0 delayed
[auto_scale_0 @ 00000182dba869c0] w:1280 h:720 fmt:bgr24 sar:0/1 -> w:1280 h:720 fmt:yuv420p sar:0/1 flags:0x00000004
[libx264 @ 00000182dba76080] using mv_range_thread = 24
[libx264 @ 00000182dba76080] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 00000182dba76080] profile High, level 3.1, 4:2:0, 8-bit
[libx264 @ 00000182dba76080] 264 - core 164 r3107 a8b68eb - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=22 lookahead_threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=10 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[tcp @ 00000182dc5ce480] No default whitelist set
[tcp @ 00000182dc5ce480] Original list of addresses:
[tcp @ 00000182dc5ce480] Address 192.168.0.2 port 8554
[tcp @ 00000182dc5ce480] Interleaved list of addresses:
[tcp @ 00000182dc5ce480] Address 192.168.0.2 port 8554
[tcp @ 00000182dc5ce480] Starting connection attempt to 192.168.0.2 port 8554
[tcp @ 00000182dc5ce480] Successfully connected to 192.168.0.2 port 8554
[rtsp @ 00000182dba72d00] SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 192.168.0.2
t=0 0
a=tool:libavformat 60.10.100
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZQFAFuhAAAAMAEAAAAwFA8YMZYA==,aOvjyyLA; profile-level-id=64001F
a=control:streamid=0
[rtp @ 00000182dc5cd040] No default whitelist set
[udp @ 00000182dba4b140] No default whitelist set
[udp @ 00000182dba4b140] end receive buffer size reported is 393216
[udp @ 00000182dc9bf040] No default whitelist set
[udp @ 00000182dc9bf040] end receive buffer size reported is 393216
Output #0, rtsp, to 'rtsp://192.168.0.2:8554/mystream':
Metadata:
encoder : Lavf60.10.100
Stream #0:0, 0, 1/90000: Video: h264, yuv420p(tv, progressive), 1280x720, q=2-31, 10 fps, 90k tbn
Metadata:
encoder : Lavc60.23.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 0 fps=0.0 q=0.0 size= 0kB time=N/A bitrate=N/A speed=N/A
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
frame= 0 fps=0.0 q=0.0 size= 0kB time=N/A bitrate=N/A speed=N/A
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
frame= 0 fps=0.0 q=0.0 size= 0kB time=N/A bitrate=N/A speed=N/A
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
[libx264 @ 00000182dba76080] frame= 0 QP=21.34 NAL=3 Slice:I Poc:0 I:3600 P:0 SKIP:0 size=135901 bytes
frame= 0 fps=0.0 q=25.0 size= 0kB time=-00:00:00.20 bitrate= -0.0kbits/s speed=N/A
[vost#0:0/libx264 @ 00000182dba75cc0] Error submitting a packet to the muxer: Broken pipe
[out#0/rtsp @ 00000182dba72c00] Error muxing a packet
[out#0/rtsp @ 00000182dba72c00] Terminating muxer thread
[rawvideo @ 00000182dba72700] PACKET SIZE: 2764800, STRIDE: 3840
[libx264 @ 00000182dba76080] frame= 1 QP=18.29 NAL=2 Slice:P Poc:2 I:2662 P:866 SKIP:72 size=54835 bytes
frame= 1 fps=0.0 q=25.0 size=N/A time=-00:00:00.10 bitrate=N/A speed=N/A
No more output streams to write to, finishing.
Conversion failed!
您使用的是最新版本的 ffmpeg 吗?我已经使用 ffmpeg 流式传输到 Twitch (rtmp/flv) 几个月了,没有任何问题,但在过去的一两周里,我显然遇到了同样的问题。随机发生错误并且流丢失。
[vost#0:1/copy @ 0x558a6e8afa40] Error submitting a packet to the muxer: Broken pipe
[out#0/flv @ 0x558a6ea08f40] Error muxing a packet
[out#0/flv @ 0x558a6ea08f40] Error writing trailer: Broken pipe
[out#0/flv @ 0x558a6ea08f40] Error closing file: Broken pipe
我总是使用来自此存储库的更新的 ffmpeg 二进制文件。也许这个问题是在当前的某些提交中引入的。我将使用 Linux 发行版存储库中的稳定 ffmpeg 进行测试,看看问题是否消失。