1

场景:
我在我的应用程序中使用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_);
  }
}

上面的代码是我从 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一些虚拟图像数据创建一个视频。

4

1 回答 1

1

如果您想获得完整且有效的 OpenH264编码器初始化程序,您可以单击...此处

根据您的问题场景,您正在尝试从一些虚拟图像创建视频文件(.mp4/.avi)。可以使用两个不同的库来完成此任务:i) 编解码器库,ii) 容器库。

i) 编解码器库:使用 OpenH264 压缩数据非常容易。我必须提到的一件事是,OpenH264 始终适用于原始帧,例如 yuv420 数据。所以,如果你想压缩你的图像数据,你必须将这些图像数据转换成 yuv420 颜色格式。要获取 OpenH264,请单击...此处

ii) 容器库:获得编码数据后,您必须使用另一个库来创建扩展名为 .mp4、.avi、.flv 等的容器。github 中有很多库可以完成这些工作,例如FFmpegOpenCVBento4MP4Makermp4parser等。在使用这些库之前,请详细检查许可证问题。如果您使用 FFmpeg,则不需要使用 OpenH264,因为 FFmpeg 本身可以与多个编解码器一起工作。您还会发现更多工作示例,因为许多开发人员都在使用视频数据。

希望能帮助到你。:)

于 2017-10-16T09:11:33.843 回答