openh264 编码命令行工具源码分析

openh264

OpenH264 是由 Cisco 公司发布的一个开源的 H.264 编码和解码器。它提供了命令行工具,可以用于对视频进行编码和解码操作。

使用说明

  • openh264 编码命令行工具可以使用命令行或 config 配置进行编码操作。
  • 编译和使用方法具体可以参考 Windows11编译openh264源码

编码命令行工具源码分析

源码位置

位置:openh264/codec/console/enc/src/welsenc.cpp

框架

在这里插入图片描述

  1. 模块功能:
  • main:可执行程序的入口函数。
  • PrintHelp:打印帮助函数,提示如何应用命令行参数说明。
  • WelsTime:计算时间函数。
  • ParseConfig:解析 config 函数。
  • signal:信号处理,中断程序。
  • ParseCommandLine:解析命令行函数。
  • libopenh264enc:调用 openh264 编码模块API,实现编码功能。

关键类或结构体分析

  1. ISVCEncoder:编码抽象基类,提供了视频编码的基本操作,在 codec_api.h 文件中定义。
//代码有删减
class ISVCEncoder {
 public:
  /**
  * @brief  Initialize the encoder
  * @param  pParam  basic encoder parameter
  * @return CM_RETURN: 0 - success; otherwise - failed;
  */
  virtual int EXTAPI Initialize (const SEncParamBase* pParam) = 0;

  /**
  * @brief  Initilaize encoder by using extension parameters.
  * @param  pParam  extension parameter for encoder
  * @return CM_RETURN: 0 - success; otherwise - failed;
  */
  virtual int EXTAPI InitializeExt (const SEncParamExt* pParam) = 0;

  /**
  * @brief   Get the default extension parameters.
  *          If you want to change some parameters of encoder, firstly you need to get the default encoding parameters,
  *          after that you can change part of parameters you want to.
  * @param   pParam  extension parameter for encoder
  * @return  CM_RETURN: 0 - success; otherwise - failed;
  * */
  virtual int EXTAPI GetDefaultParams (SEncParamExt* pParam) = 0;
  /// uninitialize the encoder
  virtual int EXTAPI Uninitialize() = 0;

  /**
  * @brief Encode one frame
  * @param kpSrcPic the pointer to the source luminance plane
  *        chrominance data:
  *        CbData = kpSrc  +  m_iMaxPicWidth * m_iMaxPicHeight;
  *        CrData = CbData + (m_iMaxPicWidth * m_iMaxPicHeight)/4;
  *        the application calling this interface needs to ensure the data validation between the location
  * @param pBsInfo output bit stream
  * @return  0 - success; otherwise -failed;
  */
  virtual int EXTAPI EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo) = 0;

  /**
  * @brief  Encode the parameters from output bit stream
  * @param  pBsInfo output bit stream
  * @return 0 - success; otherwise - failed;
  */
  virtual int EXTAPI EncodeParameterSets (SFrameBSInfo* pBsInfo) = 0;

  /**
  * @brief  Force encoder to encoder frame as IDR if bIDR set as true
  * @param  bIDR true: force encoder to encode frame as IDR frame;false, return 1 and nothing to do
  * @return 0 - success; otherwise - failed;
  */
  virtual int EXTAPI ForceIntraFrame (bool bIDR, int iLayerId = -1) = 0;

  /**
  * @brief   Set option for encoder, detail option type, please refer to enumurate ENCODER_OPTION.
  * @param   pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,...
  * @return  CM_RETURN: 0 - success; otherwise - failed;
  */
  virtual int EXTAPI SetOption (ENCODER_OPTION eOptionId, void* pOption) = 0;

  /**
  * @brief   Get option for encoder, detail option type, please refer to enumurate ENCODER_OPTION.
  * @param   pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,...
  * @return  CM_RETURN: 0 - success; otherwise - failed;
  */
  virtual int EXTAPI GetOption (ENCODER_OPTION eOptionId, void* pOption) = 0;
  virtual ~ISVCEncoder() {}
};
  1. SFrameBSInfo:编码器中描述视频比特流信息结构体,在 codec_app_def.h 文件中定义。
//代码有删减
/**
* @brief Frame bit stream info
*/
typedef struct {
  int           iLayerNum;
  SLayerBSInfo  sLayerInfo[MAX_LAYER_NUM_OF_FRAME];

  EVideoFrameType eFrameType;
  int iFrameSizeInBytes;
  long long uiTimeStamp;
} SFrameBSInfo, *PFrameBSInfo;
  1. SEncParamExt:编码器中扩展编码参数结构体,包含了 svc 相关编码参数,在codec_app_def.h 文件中定义。
//代码有删减
/**
* @brief SVC Encoding Parameters extention
*/
typedef struct TagEncParamExt {
  EUsageType
  iUsageType;                          ///< same as in TagEncParamBase

  int       iPicWidth;                 ///< same as in TagEncParamBase
  int       iPicHeight;                ///< same as in TagEncParamBase
  int       iTargetBitrate;            ///< same as in TagEncParamBase
  RC_MODES  iRCMode;                   ///< same as in TagEncParamBase
  float     fMaxFrameRate;             ///< same as in TagEncParamBase

  int       iTemporalLayerNum;         ///< temporal layer number, max temporal layer = 4
  int       iSpatialLayerNum;          ///< spatial layer number,1<= iSpatialLayerNum <= MAX_SPATIAL_LAYER_NUM, MAX_SPATIAL_LAYER_NUM = 4
  SSpatialLayerConfig sSpatialLayers[MAX_SPATIAL_LAYER_NUM];

  ECOMPLEXITY_MODE iComplexityMode;
  unsigned int      uiIntraPeriod;     ///< period of Intra frame
  int               iNumRefFrame;      ///< number of reference frame used
  EParameterSetStrategy
  eSpsPpsIdStrategy;       ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additional
  bool    bPrefixNalAddingCtrl;        ///< false:not use Prefix NAL; true: use Prefix NAL
  bool    bEnableSSEI;                 ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI
  bool    bSimulcastAVC;               ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC
  int     iPaddingFlag;                ///< 0:disable padding;1:padding
  int     iEntropyCodingModeFlag;      ///< 0:CAVLC  1:CABAC.

  /* rc control */
  bool    bEnableFrameSkip;            ///< False: don't skip frame even if VBV buffer overflow.True: allow skipping frames to keep the bitrate within limits
  int     iMaxBitrate;                 ///< the maximum bitrate, in unit of bps, set it to UNSPECIFIED_BIT_RATE if not needed
  int     iMaxQp;                      ///< the maximum QP encoder supports
  int     iMinQp;                      ///< the minmum QP encoder supports
  unsigned int uiMaxNalSize;           ///< the maximum NAL size.  This value should be not 0 for dynamic slice mode

  /*LTR settings*/
  bool     bEnableLongTermReference;   ///< 1: on, 0: off
  int      iLTRRefNum;                 ///< the number of LTR(long term reference),TODO: not supported to set it arbitrary yet
  unsigned int      iLtrMarkPeriod;    ///< the LTR marked period that is used in feedback.
  /* multi-thread settings*/
  unsigned short
  iMultipleThreadIdc;                  ///< 1 # 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; lager than 1: count number of threads;
  bool  bUseLoadBalancing; ///< only used when uiSliceMode=1 or 3, will change slicing of a picture during the run-time of multi-thread encoding, so the result of each run may be different

  /* Deblocking loop filter */
  int       iLoopFilterDisableIdc;     ///< 0: on, 1: off, 2: on except for slice boundaries
  int       iLoopFilterAlphaC0Offset;  ///< AlphaOffset: valid range [-6, 6], default 0
  int       iLoopFilterBetaOffset;     ///< BetaOffset: valid range [-6, 6], default 0
  /*pre-processing feature*/
  bool    bEnableDenoise;              ///< denoise control
  bool    bEnableBackgroundDetection;  ///< background detection control //VAA_BACKGROUND_DETECTION //BGD cmd
  bool    bEnableAdaptiveQuant;        ///< adaptive quantization control
  bool    bEnableFrameCroppingFlag;    ///< enable frame cropping flag: TRUE always in application
  bool    bEnableSceneChangeDetect;

  bool    bIsLosslessLink;            ///<  LTR advanced setting
} SEncParamExt;
  1. SSourcePicture:编码器中输入源图像数据结构体,在 codec_app_def.h 文件中定义。
//代码有删减
/**
*  @brief Structure for source picture
*/
typedef struct Source_Picture_s {
  int       iColorFormat;          ///< color space type
  int       iStride[4];            ///< stride for each plane pData
  unsigned char*  pData[4];        ///< plane pData
  int       iPicWidth;             ///< luma picture width in x coordinate
  int       iPicHeight;            ///< luma picture height in y coordinate
  long long uiTimeStamp;           ///< timestamp of the source picture, unit: millisecond
} SSourcePicture;
  1. SFilesSet:命令行工具模块存储与视频编码相关的文件设置信息的结构体,在welsenc.cpp文件中定义。
//代码有删减
typedef struct tagFilesSet {
  string strBsFile;
  string strSeqFile;    // for cmd lines
  string strLayerCfgFile[MAX_DEPENDENCY_LAYER];
  char   sRecFileName[MAX_DEPENDENCY_LAYER][MAX_FNAME_LEN];
  uint32_t uiFrameToBeCoded;
  bool     bEnableMultiBsFile;

  tagFilesSet() {
    uiFrameToBeCoded = 0;
    bEnableMultiBsFile = false;
    for (int i = 0; i < MAX_DEPENDENCY_LAYER; i++)
      sRecFileName[i][0] = '\0';
  }
} SFilesSet;
  1. CReadConfig:命令行工具模块中读入 config 的类,在 read_config.h 中定义。
//代码有删减
class CReadConfig {
 public:
  CReadConfig();
  CReadConfig (const char* pConfigFileName);
  CReadConfig (const std::string& pConfigFileName);
  virtual ~CReadConfig();

  void Openf (const char* strFile);
  long ReadLine (std::string* strVal, const int iValSize = 4);
  const bool EndOfFile();
  const int GetLines();
  const bool ExistFile();
  const std::string& GetFileName();

 private:
  FILE*             m_pCfgFile;
  std::string       m_strCfgFileName;
  unsigned int      m_iLines;
};
  1. SLayerPEncCtx:命令行工具模块中层上下文结构体,被用于存储与特定编码层相关的参数和上下文信息,主要在解析命令行中使用,在 welsenc.cpp 文件中定义。
//代码有删减
/*
 *  Layer Context
 */
typedef struct LayerpEncCtx_s {
  int32_t       iDLayerQp;
  SSliceArgument  sSliceArgument;
} SLayerPEncCtx;

函数流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码流怪侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值