如何在RTSP流中实时拍摄帧?

时间:2018-06-29 22:46:11

标签: ffmpeg queue buffer javacv

我正在尝试使用javacv来无延迟地抓取帧,而且我有点困惑如何做以及javacv和其他东西如何在后台正常工作。

在我的示例中,我运行的RTSP流具有以下配置:

Codec: H.264
Frame Size: 1280x720
Maximum Frame Rate: 60 fps

为了实现这一目标,我创建了如下线程:

public class TakeFrameFromStreamingThread implements Runnable {
  private CircularFifoQueue<Frame> queue;
  private Camera camera;
  private FFmpegFrameGrabber grabber = null;

  public TakeFrameFromStreamingThread(CircularFifoQueue<Frame> queue, Camera camera) {
    try {
      this.queue = queue;
      this.camera = camera;
      this.initGrabber(camera);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  public void run() {
    try {
      while (true) {
        if (grabber == null) {
          initGrabber(camera); // connect
    }

    Frame frame = null;
    frame = grabber.grabImage();

    if (frame != null) {
      this.queue.add(frame);
    } else { // when frame == null then connection has been lost
      initGrabber(camera); // reconnect
    }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void initGrabber(Camera camera) throws Exception {
    grabber = new FFmpegFrameGrabber(camera.getURL()); // rtsp url
    grabber.setVideoCodec(avcodec.AV_CODEC_ID_H264);
    grabber.setOption("rtsp_transport", "tcp");
    grabber.setFrameRate(60);
    grabber.setImageWidth(camera.getResolution().getWidth());
    grabber.setImageHeight(camera.getResolution().getHeight());
    grabber.start();
  }
}

似乎可行。每当我需要一个框架时,就从我的主线程中pool queue

我最终用这个解决方案解决了另一个问题。我很困惑,为什么每次需要一个帧时调用grabImage()都会返回下一帧,而不是流式传输的实时帧。

通过这种解决方案,我猜想有一个javacv(或ffmpeg idk)用帧填充的缓冲区,然后grabImage()只是从该缓冲区中获取一个帧。所以这是我的第一个问题:

1)是吗? ffmpeg是否依靠缓冲区存储帧,然后grab()只是从那里获取帧?

好吧,如果这是事实,那么必须以某种速率填充此缓冲区,当然,如果该速率大于我的grabImage()调用率,最终我将失去实时功能一旦缓冲区完全填满,我什至会丢失帧。

在这种情况下,我的grabImage()花费了大约 50毫秒,这使我从该缓冲区中以 20 fps 的速率获取帧。因此,我需要确保ffmpeg接收的帧最多为 20 fps 。所以这是我的第二个问题:

2)如何知道和更改ffmpeg缓冲速率?我猜它正在以相同的流速率( 60 fps )填充或来自媒体资源grabber.setFrameRate()。完全不确定我是否应该使用源流中具有相同值的采集器设置器。

0 个答案:

没有答案