使用 ffmpeg 从 UDP H264 流中抓取的帧是 gray/distorded

Frames grabbed from UDP H264 stream with ffmpeg are gray/distorded

我在 windows 上使用 Javacv 的 FFMPEG 从 udp h264 流中抓取帧,并将它们放入 JavaFX 图像视图中。问题是大部分图像都没有很好地接收(它是灰色的,失真的......):

我以前也遇到过同样的问题,我在每帧之后在图像采集卡上使用刷新使其工作,但我忘记保存我的工作而丢失了,这次校正不起作用。

这是我 configure/launch FFMPEG 的部分:

        final Java2DFrameConverter converter = new Java2DFrameConverter();

        // Show drone camera
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("udp://227.0.0.1:2200");

        grabber.setFrameRate(_frameRate);
        grabber.setFormat(_format);
        grabber.setVideoBitrate(25000000);
        grabber.setVideoOption("preset", "ultrafast");
        grabber.setNumBuffers(0);

        grabber.start();

        // Grab frames as long as the thread is running
        while(_running){
               final Frame frame = grabber.grab();
               if (frame != null) {
                   final BufferedImage bufferedImage = converter.convert(frame);
                   if (bufferedImage != null) {
                         _cameraView.setImage(SwingFXUtils.toFXImage(bufferedImage, null));
                   }
                }
                Thread.sleep( 1000 / _frameRate );// don't grab frames faster than they are provided
                grabber.flush();
        }
        _grabber.close();

_format 为 "h264",_frameRate 为 30。

此外,系统中充斥着这样的打印(不过我不确定它们是否与问题有关):

[h264 @ 00000000869c0a80] Invalid NAL unit 4, skipping.
[h264 @ 00000000869c0a80] Invalid NAL unit 4, skipping.
[h264 @ 00000000869c0a80] Invalid NAL unit 4, skipping.
[h264 @ 00000000869c0a80] Reference 6 >= 4
[h264 @ 00000000869c0a80] error while decoding MB 115 14, bytestream 1979
[h264 @ 00000000869c0a80] concealing 6414 DC, 6414 AC, 6414 MV errors in P frame
[h264 @ 0000000078f81180] Invalid NAL unit 0, skipping.
[h264 @ 0000000078f81180] Invalid NAL unit 0, skipping.
[h264 @ 0000000078f81180] concealing 4811 DC, 4811 AC, 4811 MV errors in B frame

我不明白为什么它不再起作用了

我设法让它工作,但遗憾的是它并没有真正解决问题:

我删除了以下配置行:

grabber.setFrameRate(_frameRate);
grabber.setFormat(_format);
grabber.setVideoBitrate(25000000);
grabber.setVideoOption("preset", "ultrafast");
grabber.setNumBuffers(0);

我还删除了显然不需要的冲洗线和线程休眠:

Thread.sleep( 1000 / _frameRate );// don't grab frames faster than they are provided
grabber.flush();

它奏效了...