如何让FFMPEG从OpenCV获取帧并将其流式传输到HTTP服务器

问题描述

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

具有先进的切换器,路由器等的基础设施非常棒(10 GB Lan)...

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

问题是如何将图像从OpenCV转换为FFMPEG? 将在使用MERN堆栈制作的Web应用程序上观看该流(假设这是相关的)。

解决方法

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

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

您只需将mat.data馈送到sws_scale

sws_scale(videoSampler,mat.data,stride,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,(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结合使用的完整示例

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...