openh264
OpenH264 是由 Cisco 公司发布的一个开源的 H.264 编码和解码器。它提供了命令行工具,可以用于对视频进行编码和解码操作。
使用说明
- openh264 编码命令行工具可以使用命令行或 config 配置进行编码操作。
- 编译和使用方法具体可以参考 Windows11编译openh264源码。
编码命令行工具源码分析
源码位置
位置:openh264/codec/console/enc/src/welsenc.cpp
框架
- 模块功能:
- main:可执行程序的入口函数。
- PrintHelp:打印帮助函数,提示如何应用命令行参数说明。
- WelsTime:计算时间函数。
- ParseConfig:解析 config 函数。
- signal:信号处理,中断程序。
- ParseCommandLine:解析命令行函数。
- libopenh264enc:调用 openh264 编码模块API,实现编码功能。
关键类或结构体分析
- 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 encodervirtual 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() {}
};
- 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;
- SEncParamExt:编码器中扩展编码参数结构体,包含了 svc 相关编码参数,在codec_app_def.h 文件中定义。
//代码有删减
/**
* @brief SVC Encoding Parameters extention
*/
typedef struct TagEncParamExt {EUsageTypeiUsageType; ///< same as in TagEncParamBaseint iPicWidth; ///< same as in TagEncParamBaseint iPicHeight; ///< same as in TagEncParamBaseint iTargetBitrate; ///< same as in TagEncParamBaseRC_MODES iRCMode; ///< same as in TagEncParamBasefloat fMaxFrameRate; ///< same as in TagEncParamBaseint iTemporalLayerNum; ///< temporal layer number, max temporal layer = 4int iSpatialLayerNum; ///< spatial layer number,1<= iSpatialLayerNum <= MAX_SPATIAL_LAYER_NUM, MAX_SPATIAL_LAYER_NUM = 4SSpatialLayerConfig sSpatialLayers[MAX_SPATIAL_LAYER_NUM];ECOMPLEXITY_MODE iComplexityMode;unsigned int uiIntraPeriod; ///< period of Intra frameint iNumRefFrame; ///< number of reference frame usedEParameterSetStrategyeSpsPpsIdStrategy; ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additionalbool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NALbool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEIbool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVCint iPaddingFlag; ///< 0:disable padding;1:paddingint 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 limitsint iMaxBitrate; ///< the maximum bitrate, in unit of bps, set it to UNSPECIFIED_BIT_RATE if not neededint iMaxQp; ///< the maximum QP encoder supportsint iMinQp; ///< the minmum QP encoder supportsunsigned int uiMaxNalSize; ///< the maximum NAL size. This value should be not 0 for dynamic slice mode/*LTR settings*/bool bEnableLongTermReference; ///< 1: on, 0: offint iLTRRefNum; ///< the number of LTR(long term reference),TODO: not supported to set it arbitrary yetunsigned int iLtrMarkPeriod; ///< the LTR marked period that is used in feedback./* multi-thread settings*/unsigned shortiMultipleThreadIdc; ///< 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 boundariesint iLoopFilterAlphaC0Offset; ///< AlphaOffset: valid range [-6, 6], default 0int iLoopFilterBetaOffset; ///< BetaOffset: valid range [-6, 6], default 0/*pre-processing feature*/bool bEnableDenoise; ///< denoise controlbool bEnableBackgroundDetection; ///< background detection control //VAA_BACKGROUND_DETECTION //BGD cmdbool bEnableAdaptiveQuant; ///< adaptive quantization controlbool bEnableFrameCroppingFlag; ///< enable frame cropping flag: TRUE always in applicationbool bEnableSceneChangeDetect;bool bIsLosslessLink; ///< LTR advanced setting
} SEncParamExt;
- SSourcePicture:编码器中输入源图像数据结构体,在 codec_app_def.h 文件中定义。
//代码有删减
/**
* @brief Structure for source picture
*/
typedef struct Source_Picture_s {int iColorFormat; ///< color space typeint iStride[4]; ///< stride for each plane pDataunsigned char* pData[4]; ///< plane pDataint iPicWidth; ///< luma picture width in x coordinateint iPicHeight; ///< luma picture height in y coordinatelong long uiTimeStamp; ///< timestamp of the source picture, unit: millisecond
} SSourcePicture;
- SFilesSet:命令行工具模块存储与视频编码相关的文件设置信息的结构体,在welsenc.cpp文件中定义。
//代码有删减
typedef struct tagFilesSet {string strBsFile;string strSeqFile; // for cmd linesstring 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;
- 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;
};
- SLayerPEncCtx:命令行工具模块中层上下文结构体,被用于存储与特定编码层相关的参数和上下文信息,主要在解析命令行中使用,在 welsenc.cpp 文件中定义。
//代码有删减
/** Layer Context*/
typedef struct LayerpEncCtx_s {int32_t iDLayerQp;SSliceArgument sSliceArgument;
} SLayerPEncCtx;