0

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

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

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

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

4

1 回答 1

0

因为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);

是我将 GpuMat 与 NVIDIA Video Codec SDK 一起使用的完整示例

于 2020-08-24T11:40:59.467 回答