问题描述
有一台相机以每秒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结合使用的完整示例