一段时间以来,我一直在使用NVidia视频编解码器库,并且能够从摄像机读取帧并将其馈送到编码器。编码文件正在保存。所以这是我需要帮助的相关代码。
最初,我打开编码数据的输出文件,如下所示。 szOutFilePath包含用于存储视频编码文件的路径和文件名。
示例: szOutFilePath =“ /home/admin/project/video.avi”
//Encoder output file
std::ofstream fpOut(szOutFilePath, std::ios::out | std::ios::binary | std::ofstream::trunc);
if (!fpOut)
{
std::ostringstream err;
err << "Unable to open output file: " << szOutFilePath << std::endl;
throw std::invalid_argument(err.str());
}
然后我将相机捕获的opencv图像转换为YUV图像。
openCvImage= cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());
//Converting the opencv image to YUV420 format.
cvtColor(openCvImage, yuvImage, CV_BGR2YUV_I420);
包含当前图像帧的yuvImage如下馈送到编码器。
try
{
// For receiving encoded packets
std::vector<std::vector<uint8_t>> vPacket;
if (counter != c_countOfImagesToGrab)
{
const NvEncInputFrame* encoderInputFrame = enc.GetNextInputFrame();
NvEncoderCuda::CopyToDeviceFrame(cuContext, (uint8_t*)yuvImage.data, 0, (CUdeviceptr)encoderInputFrame->inputPtr,
(int)encoderInputFrame->pitch,
enc.GetEncodeWidth(),
enc.GetEncodeHeight(),
CU_MEMORYTYPE_HOST,
encoderInputFrame->bufferFormat,
encoderInputFrame->chromaOffsets,
encoderInputFrame->numChromaPlanes);
enc.EncodeFrame(vPacket);
}
else
{
enc.EndEncode(vPacket);
}
nFrame += (int)vPacket.size();
for (std::vector<uint8_t> &packet : vPacket)
{
// For each encoded packet
fpOut.write(reinterpret_cast<char*>(packet.data()), packet.size());
}
}
catch (const std::exception &ex)
{
std::cout << ex.what();
}
我正在获取正确的编码视频文件。有趣的是,该视频正在名为“ Parole Media Player”的媒体播放器中正常播放。但是,同一视频不能在VLC媒体播放器中播放。我的猜测是,h264编码的数据没有正确格式化并放入.avi容器中,结果VLC媒体播放器无法播放它。
谁能告诉我如何使用NVidia视频编解码器库正确创建容器。我一直在寻找解决方案很长时间,但是失败了。任何帮助将不胜感激!
答案 0 :(得分:0)
只需回答我自己的问题,我就将编码后的视频保存为.264格式,并使用ffmpeg库将其转换为.MP4格式。感谢“评论”部分的人清除我的疑问。你们都是MVP。