【问题标题】:How to let FFMPEG fetch frames from OpenCV and stream them to HTTP server如何让 FFMPEG 从 OpenCV 获取帧并将它们流式传输到 HTTP 服务器
【发布时间】:2020-08-21 13:17:08
【问题描述】:

有一台以每秒 20 帧的速度拍摄的相机。每帧为 4000x3000 像素。 这些帧被发送到包含 openCV 的软件。 OpenCV 将帧大小调整为 1920x1080,然后必须将它们发送到 FFMPEG 以使用 Nvidia Nvenc 编码为 H264 或 H265。 编码后的视频随后通过 HTTP 传输到最多 10 台设备。

基础设施非常好(10 GB 局域网),配备最先进的切换器、路由器等......

现在,从 Nvme SSD 编码图像时,我可以获得 90 FPS。这意味着达到了所需的编码速度。

问题是如何将图像从 OpenCV 获取到 FFMPEG ? 将在使用 MERN 堆栈制作的 web 应用上观看该流(假设这是相关的)。

【问题讨论】:

  • 您要编码cv::Matcv::cuda::GpuMat 帧吗?
  • 将原始格式的流通过管道传输到 ffmpeg 标准输入
  • @Zteffi 我想尽可能使用 cv::cuda::GPuMat ,它应该更快对吗?据我了解,这会将数据直接获取到 GPU 内存
  • @szatmary 我需要更多详细信息,你能给我一个好的来源的链接
  • 您还需要重新混合音频还是只处理视频?

标签: opencv encoding ffmpeg streaming nvenc


【解决方案1】:

对于cv::Mat,您有cv::VideoWriter。如果您希望使用 FFMpeg,假设 Mat 是连续的,可以强制执行:

if (! mat.isContinuous())
{ 
    mat = mat.clone();
}

您可以简单地将 mat.data 输入到sws_scale

sws_scale(videoSampler, mat.data, stride, 0, mat.rows, videoFrame->data, videoFrame->linesize);

或直接进入AVFrame

对于cv::cuda::GpuMat,VideoWriter 实现不可用,但您可以使用 NVIDIA Video Codec SDK 并类似地将 cv::cuda::GpuMat::data 输入NvEncoderCuda,只需确保您的 GpuMat 有 4 个通道(BGRA ):

NV_ENC_BUFFER_FORMAT eFormat = NV_ENC_BUFFER_FORMAT_ABGR;
std::unique_ptr<NvEncoderCuda> pEnc(new NvEncoderCuda(cuContext, nWidth, nHeight, eFormat));

...
cv::cuda::cvtColor(srcIn, srcIn, cv::ColorConversionCodes::COLOR_BG2BGRA);
NvEncoderCuda::CopyToDeviceFrame(cuContext, srcIn.data, 0, (CUdeviceptr)encoderInputFrame->inputPtr,
            (int)encoderInputFrame->pitch,
            pEnc->GetEncodeWidth(),
            pEnc->GetEncodeHeight(),
            CU_MEMORYTYPE_HOST,
            encoderInputFrame->bufferFormat,
            encoderInputFrame->chromaOffsets,
            encoderInputFrame->numChromaPlanes);

Here 是我使用 GpuMat 和 NVIDIA Video Codec SDK 的完整示例

【讨论】:

    猜你喜欢
    • 2020-10-27
    • 2013-12-26
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2011-11-26
    • 2019-09-25
    • 2018-12-20
    • 1970-01-01
    相关资源
    最近更新 更多