【发布时间】:2018-03-27 09:58:07
【问题描述】:
场景:
我在我的应用程序中使用OpenH264 编码为video_file.mp4。
环境:
平台:MacOs Sierra
编译器:Clang++
代码:
以下是我拥有的代码的症结:
void EncodeVideoFile() {
ISVCEncoder * encoder_;
std:string video_file_name = "/Path/to/some/folder/video_file.mp4";
EncodeFileParam * pEncFileParam;
SEncParamExt * pEnxParamExt;
float frameRate = 1000;
EUsageType usageType = EUsageType::CAMERA_VIDEO_REAL_TIME;
bool denoise = false;
bool lossless = true;
bool enable_ltr = false;
int layers = 1;
bool cabac = false;
int sliceMode = 1;
pEncFileParam = new EncodeFileParam;
pEncFileParam->eUsageType = EUsageType::CAMERA_VIDEO_REAL_TIME;
pEncFileParam->pkcFileName = video_file_name.c_str();
pEncFileParam->iWidth = frame_width;
pEncFileParam->iHeight = frame_height;
pEncFileParam->fFrameRate = frameRate;
pEncFileParam->iLayerNum = layers;
pEncFileParam->bDenoise = denoise;
pEncFileParam->bLossless = lossless;
pEncFileParam->bEnableLtr = enable_ltr;
pEncFileParam->bCabac = cabac;
int rv = WelsCreateSVCEncoder (&encoder_);
pEnxParamExt = new SEncParamExt;
pEnxParamExt->iUsageType = pEncFileParam->eUsageType;
pEnxParamExt->iPicWidth = pEncFileParam->iWidth;
pEnxParamExt->iPicHeight = pEncFileParam->iHeight;
pEnxParamExt->fMaxFrameRate = pEncFileParam->fFrameRate;
pEnxParamExt->iSpatialLayerNum = pEncFileParam->iLayerNum;
pEnxParamExt->bEnableDenoise = pEncFileParam->bDenoise;
pEnxParamExt->bIsLosslessLink = pEncFileParam->bLossless;
pEnxParamExt->bEnableLongTermReference = pEncFileParam->bEnableLtr;
pEnxParamExt->iEntropyCodingModeFlag = pEncFileParam->bCabac ? 1 : 0;
for (int i = 0; i < pEnxParamExt->iSpatialLayerNum; i++) {
pEnxParamExt->sSpatialLayers[i].sSliceArgument.uiSliceMode = pEncFileParam->eSliceMode;
}
encoder_->InitializeExt(pEnxParamExt);
int videoFormat = videoFormatI420;
encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);
int frameSize = frame_width * frame_height * 3 / 2;
int total_num = 500;
BufferedData buf;
buf.SetLength (frameSize);
// check the buffer before proceeding
if (buf.Length() != (size_t)frameSize) {
CloseEncoder();
return;
}
SFrameBSInfo info;
memset (&info, 0, sizeof (SFrameBSInfo));
SSourcePicture pic;
memset (&pic, 0, sizeof (SSourcePicture));
pic.iPicWidth = frame_width;
pic.iPicHeight = frame_height;
pic.iColorFormat = videoFormatI420;
pic.iStride[0] = pic.iPicWidth;
pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
pic.pData[0] = buf.data();
pic.pData[1] = pic.pData[0] + frame_width * frame_height;
pic.pData[2] = pic.pData[1] + (frame_width * frame_height >> 2);
for(int num = 0; num < total_num; num++) {
// try to encode the frame
rv = encoder_->EncodeFrame (&pic, &info);
}
if (encoder_) {
encoder_->Uninitialize();
WelsDestroySVCEncoder (encoder_);
}
}
以上代码是我从official usage examples of OpenH264 提取的,其中BufferedData.h 是我从OpenH264 utils 重用的类
问题:
但是,我收到以下错误:
[OpenH264] this = 0x0x1038bc8c0, Error:ParamValidationExt(), width > 0, height > 0, width * height <= 9437184, invalid 0 x 0 in dependency layer settings!
[OpenH264] this = 0x0x1038bc8c0, Error:WelsInitEncoderExt(), ParamValidationExt failed return 2.
[OpenH264] this = 0x0x1038bc8c0, Error:CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.
以上不会使应用程序崩溃,但它会经历一次空白运行,而不会使用我试图写入其中的虚拟数据创建video_file.mp4。
问题:
我申请pEnxParamExt的设置配置似乎有问题,该设置进入encoder_->InitializeExt。
我在设置编码器时做错了什么?
注意:
我不想连接任何相机设备。我只是想用一些虚拟图像数据创建一个.mp4 视频。
【问题讨论】:
-
我想,我应该清楚地提一件事。 Openh264 不处理 .mp4 数据。 Openh264 无法创建 .mp4 文件。 Openh264 适用于 yuv420 等原始视频数据。这个库的工作方式如下:YUV420 帧 --> Openh264(Encode) --> Openh264(Decode)-->YUV420 帧。因此,如果您真的想从某些图像创建 .mp4 文件,您可能应该使用其他库,例如 FFmpeg。
-
@RajibTheKing 感谢您的回复。在这种情况下我应该尝试什么扩展/容器。
.avi? 我是这个领域的新手。据我了解.avi或.mp4只是容器?我只想创建一个视频文件.avi或.mp4或其他任何东西都无所谓。 -
如果你想通过一些编码程序创建视频文件.avi或.mp4,你必须使用FFmpeg。但在一切之前,您应该对编解码器和容器有清晰的概念。我想你可以点击这个链接:stackoverflow.com/questions/36687188/create-video-using-ffmpeg 研究完这篇文章,你可以点击这个链接创建视频文件:stackoverflow.com/questions/34823545/…
-
我可以使用
FFmpeg创建视频文件。但是想要在没有FFmpeg的情况下做同样的事情,因为FFmpeg属于 LGPL 并且我的公司不想使用它。那是一个不同的问题。我可以使用 Qt 创建视频文件并要求 OpenH264 开始对其进行编码吗?我的是一个带有 C++ 的 Qt 应用程序。这是可能性吗? -
正如我之前所说,OpenH264 无法创建 .mp4 或 .avi 文件。但是您可以使用 OpenH264 从图像中获取编码数据,然后使用另一个开源库从这些编码数据中制作 .mp4/.avi 文件。我想,您应该使用 OpenCV 从图像序列创建视频文件。
标签: buffer video-encoding openh264