1.doxgen documentation format for comments in api/*.h 2. comments to wiki tools in openh264/docs/*

This commit is contained in:
huashi 2014-11-21 10:38:30 +08:00
parent 24fb213d6e
commit 7175d3c90e
10 changed files with 3337 additions and 307 deletions

View File

@ -1,4 +1,6 @@
/*!
*@page License
*
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
@ -50,73 +52,345 @@ typedef unsigned char bool;
#define EXTAPI
#endif
/**
* @file codec_api.h
*/
/**
* @page Overview
* * This page is for openh264 codec API usage.
* * For how to use the encoder,please refer to page UsageExampleForEncoder
* * For how to use the decoder,please refer to page UsageExampleForDecoder
* * For more detail about ISVEncoder,please refer to page ISVCEnoder
* * For more detail about ISVDecoder,please refer to page ISVCDecoder
*/
/**
* @page DecoderUsageExample
*
* @brief
* * An example for using the decoder
*
* Step 1:decoder declaration
* @code
*
* //decoder declaration
* ISVCDecoder *pSvcDecoder;
* //input: encoded bitstream start position; should include start code prefix
* unsigned char *pBuf =...;
* //input: encoded bit stream length; should include the size of start code prefix
* int iSize =...;
* //output: [0~2] for Y,U,V buffer
* unsigned char *pData[3] =...;
* //in-out: declare and initialize the output buffer info
* SBufferInfo sDstBufInfo;
* memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
*
* @endcode
*
* Step 2:decoder creation
* @code
* CreateDecoder(pSvcDecoder);
* @endcode
*
* Step 3:declare required parameter
* @code
* SDecodingParam sDecParam = {0};
* sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
* @endcode
*
* Step 4:initialize the parameter and decoder context, allocate memory
* @code
* Initialize(&sDecParam);
* @endcode
*
* Step 5:do actual decoding process in slice level;
* this can be done in a loop until data ends
* @code
* iRet = DecodeFrame2(pBuf, iSize, pData, &sDstBufInfo);
* //decode failed
* If (iRet != 0){
* RequestIDR or something like that.
* }
* //pData can be used for render.
* if (sDstBufInfo.iBufferStatus==1){
* output pData[0], pData[1], pData[2];
* }
* @endcode
*
* Step 6:uninitialize the decoder and memory free
* @code
* Uninitialize();
* @endcode
*
* Step 7:destroy the decoder
* @code
* DestroyDecoder();
* @endcode
*
*/
/**
* @page EncoderUsageExample1
*
* @brief
* * An example for using encoder with basic parameter
*
* Step1:setup encoder
* @code
* int rv = WelsCreateSVCEncoder (&encoder_);
* ASSERT_EQ (0, rv);
* ASSERT_TRUE (encoder_ != NULL);
* @endcode
*
* Step2:initilize with basic parameter
* @code
* SEncParamBase param;
* memset (&param, 0, sizeof (SEncParamBase));
* param.iUsageType = usageType;
* param.fMaxFrameRate = frameRate;
* param.iPicWidth = width;
* param.iPicHeight = height;
* param.iTargetBitrate = 5000000;
* param.iInputCsp = videoFormatI420;
* encoder_->Initialize (&param);
* @endcode
*
* Step3:set option, set option during encoding process
* @code
* encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
* @endcode
*
* Step4: encode and store ouput bistream
* @code
* int frameSize = width * height * 3 / 2;
* BufferedData buf;
* buf.SetLength (frameSize);
* ASSERT_TRUE (buf.Length() == (size_t)frameSize);
* SFrameBSInfo info;
* memset (&info, 0, sizeof (SFrameBSInfo));
* SSourcePicture pic;
* memset (&pic, 0, sizeof (SsourcePicture));
* pic.iPicWidth = width;
* pic.iPicHeight = 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] + width * height;
* pic.pData[2] = pic.pData[1] + (width * height >> 2);
* for(int num = 0;num<total_num;num++) {
* //prepare input data
* rv = encoder_->EncodeFrame (&pic, &info);
* ASSERT_TRUE (rv == cmResultSuccess);
* if (info.eFrameType != videoFrameTypeSkip && cbk != NULL) {
* //output bitstream
* }
* }
* @endcode
*
* Step5:teardown encoder
* @code
* if (encoder_) {
* encoder_->Uninitialize();
* WelsDestroySVCEncoder (encoder_);
* }
* @endcode
*
*/
/**
* @page EncoderUsageExample2
*
* @brief
* * An example for using the encoder with extension parameter.
* * The same operation on Step 1,3,4,5 with Example-1
*
* Step 2:initialize with extension parameter
* @code
* SEncParamExt param;
* encoder->GetDefaultParams (&param);
* param.iUsageType = usageType;
* param.fMaxFrameRate = frameRate;
* param.iPicWidth = width;
* param.iPicHeight = height;
* param.iTargetBitrate = 5000000;
* param.iInputCsp = videoFormatI420;
* param.bEnableDenoise = denoise;
* param.iSpatialLayerNum = layers;
* //SM_DYN_SLICE don't support multi-thread now
* if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE)
* param.iMultipleThreadIdc = 2;
*
* for (int i = 0; i < param.iSpatialLayerNum; i++) {
* param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
* param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
* param.sSpatialLayers[i].fFrameRate = frameRate;
* param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate;
*
* param.sSpatialLayers[i].sSliceCfg.uiSliceMode = sliceMode;
* if (sliceMode == SM_DYN_SLICE) {
* param.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 600;
* param.uiMaxNalSize = 1500;
* }
* }
* param.iTargetBitrate *= param.iSpatialLayerNum;
* encoder_->InitializeExt (&param);
*
* @endcode
*/
#ifdef __cplusplus
/**
* @brief Endocder definition
*/
class ISVCEncoder {
public:
/*
* return: CM_RETURN: 0 - success; otherwise - failed;
*/
/**
* @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;
/*
* return: 0 - success; otherwise -failed;
*/
/**
* @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;
/*
* return: 0 - success; otherwise - failed;
*/
/**
* @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;
/*
* return: 0 - success; otherwise - failed;
*/
/**
* @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) = 0;
/************************************************************************
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
************************************************************************/
/*
* return: CM_RETURN: 0 - success; otherwise - failed;
*/
/**
* @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 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 GetOption (ENCODER_OPTION eOptionId, void* pOption) = 0;
virtual ~ISVCEncoder() {}
};
/**
* @brief Decoder definition
*/
class ISVCDecoder {
public:
/**
* @brief Initilaize decoder
* @param pParam parameter for decoder
* @return 0 - success; otherwise - failed;
*/
virtual long EXTAPI Initialize (const SDecodingParam* pParam) = 0;
/// Uninitialize the decoder
virtual long EXTAPI Uninitialize() = 0;
/**
* @brief Decode one frame
* @param pSrc the h264 stream to be decoded
* @param iSrcLen the length of h264 stream
* @param ppDst buffer pointer of decoded data (YUV)
* @param pStride output stride
* @param iWidth output width
* @param iHeight output height
* @return 0 - success; otherwise -failed;
*/
virtual DECODING_STATE EXTAPI DecodeFrame (const unsigned char* pSrc,
const int iSrcLen,
unsigned char** ppDst,
int* pStride,
int& iWidth,
int& iHeight) = 0;
/*
* return: 0 - success; otherwise -failed;
*/
/**
* @brief For slice level DecodeFrame2() (4 parameters input),
* whatever the function return value is, the output data
* of I420 format will only be available when pDstInfo->iBufferStatus == 1,.
* (e.g., in multi-slice cases, only when the whole picture
* is completely reconstructed, this variable would be set equal to 1.)
* @param pSrc the h264 stream to be decoded
* @param iSrcLen the length of h264 stream
* @param ppDst buffer pointer of decoded data (YUV)
* @param pDstInfo information provided to API(width, height, etc.)
* @return 0 - success; otherwise -failed;
*/
virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* pSrc,
const int iSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo) = 0;
/*
* This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax
* return: 0 - success; otherwise -failed;
*/
/**
* @brief This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax
* @param pSrc the h264 stream to be decoded
* @param iSrcLen the length of h264 stream
* @param pDstInfo bit stream info
* @return 0 - success; otherwise -failed;
*/
virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* pSrc,
const int iSrcLen,
SParserBsInfo* pDstInfo) = 0;
/*
* this API does not work for now!! This is for future use to support non-I420 color format output.
*/
/**
* @brief This API does not work for now!! This is for future use to support non-I420 color format output.
* @param pSrc the h264 stream to be decoded
* @param iSrcLen the length of h264 stream
* @param pDst buffer pointer of decoded data (YUV)
* @param iDstStride output stride
* @param iDstLen bit stream info
* @param iWidth output width
* @param iHeight output height
* @param iColorFormat output color format
* @return to do ...
*/
virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* pSrc,
const int iSrcLen,
unsigned char* pDst,
@ -126,10 +400,18 @@ class ISVCDecoder {
int& iHeight,
int& iColorFormat) = 0;
/*************************************************************************
* OutDataFormat, Eos Flag, EC method, ...
*************************************************************************/
/**
* @brief Set option for decoder, detail option type, please refer to enumurate DECODER_OPTION.
* @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ...
* @return CM_RETURN: 0 - success; otherwise - failed;
*/
virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) = 0;
/**
* @brief Get option for decoder, detail option type, please refer to enumurate DECODER_OPTION.
* @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ...
* @return CM_RETURN: 0 - success; otherwise - failed;
*/
virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) = 0;
virtual ~ISVCDecoder() {}
};
@ -197,11 +479,38 @@ long (*GetOption) (ISVCDecoder*, DECODER_OPTION eOptionId, void* pOption);
typedef void (*WelsTraceCallback) (void* ctx, int level, const char* string);
/** @brief Create encoder
* @param ppEncoder encoder
* @return 0 - success; otherwise - failed;
*/
int WelsCreateSVCEncoder (ISVCEncoder** ppEncoder);
/** @brief Destroy encoder
* @param pEncoder encoder
* @return void
*/
void WelsDestroySVCEncoder (ISVCEncoder* pEncoder);
/** @brief Get the capability of decoder
* @param pDecCapability decoder capability
* @return 0 - success; otherwise - failed;
*/
int WelsGetDecoderCapability (SDecoderCapability* pDecCapability);
/** @brief Create decoder
* @param ppDecoder decoder
* @return 0 - success; otherwise - failed;
*/
long WelsCreateDecoder (ISVCDecoder** ppDecoder);
/** @brief Destroy decoder
* @param pDecoder decoder
* @return void
*/
void WelsDestroyDecoder (ISVCDecoder* pDecoder);
#ifdef __cplusplus

View File

@ -30,9 +30,15 @@
*
*/
#ifndef WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
#define WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
////////////////Data and /or structures introduced in Cisco OpenH264 application////////////////
/**
* @file codec_app_def.h
* @brief Data and /or structures introduced in Cisco OpenH264 application
*/
#include "codec_def.h"
/* Constants */
#define MAX_TEMPORAL_LAYER_NUM 4
@ -40,98 +46,113 @@
#define MAX_QUALITY_LAYER_NUM 4
#define MAX_LAYER_NUM_OF_FRAME 128
#define MAX_NAL_UNITS_IN_LAYER 128 // predetermined here, adjust it later if need
#define MAX_NAL_UNITS_IN_LAYER 128 ///< predetermined here, adjust it later if need
#define MAX_RTP_PAYLOAD_LEN 1000
#define AVERAGE_RTP_PAYLOAD_LEN 800
#define SAVED_NALUNIT_NUM_TMP ( (MAX_SPATIAL_LAYER_NUM*MAX_QUALITY_LAYER_NUM) + 1 + MAX_SPATIAL_LAYER_NUM ) //SPS/PPS + SEI/SSEI + PADDING_NAL
#define SAVED_NALUNIT_NUM_TMP ( (MAX_SPATIAL_LAYER_NUM*MAX_QUALITY_LAYER_NUM) + 1 + MAX_SPATIAL_LAYER_NUM ) ///< SPS/PPS + SEI/SSEI + PADDING_NAL
#define MAX_SLICES_NUM_TMP ( ( MAX_NAL_UNITS_IN_LAYER - SAVED_NALUNIT_NUM_TMP ) / 3 )
#define AUTO_REF_PIC_COUNT -1 // encoder selects the number of reference frame automatically
#define UNSPECIFIED_BIT_RATE 0 //
#define AUTO_REF_PIC_COUNT -1 ///< encoder selects the number of reference frame automatically
#define UNSPECIFIED_BIT_RATE 0 ///< to do: add detail comment
/**
* @brief Decoding status
*/
typedef enum {
/* Errors derived from bitstream parsing */
dsErrorFree = 0x00, /* Bitstream error-free */
dsFramePending = 0x01, /* Need more throughput to generate a frame output, */
dsRefLost = 0x02, /* layer lost at reference frame with temporal id 0 */
dsBitstreamError = 0x04, /* Error bitstreams(maybe broken internal frame) the decoder cared */
dsDepLayerLost = 0x08, /* Dependented layer is ever lost */
dsNoParamSets = 0x10, /* No parameter set NALs involved */
dsDataErrorConcealed = 0x20, /* current data Error concealed specified */
/**
* Errors derived from bitstream parsing
*/
dsErrorFree = 0x00, ///< bit stream error-free
dsFramePending = 0x01, ///< need more throughput to generate a frame output,
dsRefLost = 0x02, ///< layer lost at reference frame with temporal id 0
dsBitstreamError = 0x04, ///< error bitstreams(maybe broken internal frame) the decoder cared
dsDepLayerLost = 0x08, ///< dependented layer is ever lost
dsNoParamSets = 0x10, ///< no parameter set NALs involved
dsDataErrorConcealed = 0x20, ///< current data error concealed specified
/* Errors derived from logic level */
dsInvalidArgument = 0x1000, /* Invalid argument specified */
dsInitialOptExpected = 0x2000, /* Initializing operation is expected */
dsOutOfMemory = 0x4000, /* Out of memory due to new request */
/* ANY OTHERS? */
dsDstBufNeedExpand = 0x8000 /* Actual picture size exceeds size of dst pBuffer feed in decoder, so need expand its size */
/**
* Errors derived from logic level
*/
dsInvalidArgument = 0x1000, ///< invalid argument specified
dsInitialOptExpected = 0x2000, ///< initializing operation is expected
dsOutOfMemory = 0x4000, ///< out of memory due to new request
/**
* ANY OTHERS?
*/
dsDstBufNeedExpan = 0x8000 ///< actual picture size exceeds size of dst pBuffer feed in decoder, so need expand its size
} DECODING_STATE;
/* Option types introduced in SVC encoder application */
/**
* @brief Option types introduced in SVC encoder application
*/
typedef enum {
ENCODER_OPTION_DATAFORMAT = 0,
ENCODER_OPTION_IDR_INTERVAL,
ENCODER_OPTION_SVC_ENCODE_PARAM_BASE,
ENCODER_OPTION_SVC_ENCODE_PARAM_EXT,
ENCODER_OPTION_FRAME_RATE,
ENCODER_OPTION_IDR_INTERVAL, ///< IDR period,0/-1 means no Intra period (only the first frame); lager than 0 means the desired IDR period, must be multiple of (2^temporal_layer)
ENCODER_OPTION_SVC_ENCODE_PARAM_BASE, ///< structure of Base Param
ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, ///< structure of Extension Param
ENCODER_OPTION_FRAME_RATE, ///< maximal input frame rate, current supported range: MAX_FRAME_RATE = 30,MIN_FRAME_RATE = 1
ENCODER_OPTION_BITRATE,
ENCODER_OPTION_MAX_BITRATE,
ENCODER_OPTION_INTER_SPATIAL_PRED,
ENCODER_OPTION_RC_MODE,
ENCODER_PADDING_PADDING,
ENCODER_PADDING_PADDING, ///< 0:disable padding;1:padding
ENCODER_OPTION_PROFILE,
ENCODER_OPTION_LEVEL,
ENCODER_OPTION_NUMBER_REF,
ENCODER_OPTION_DELIVERY_STATUS,
ENCODER_OPTION_PROFILE, ///< assgin the profile for each layer
ENCODER_OPTION_LEVEL, ///< assgin the level for each layer
ENCODER_OPTION_NUMBER_REF, ///< the number of refererence frame
ENCODER_OPTION_DELIVERY_STATUS, ///< the delivery info which is a feedback from app level
ENCODER_LTR_RECOVERY_REQUEST,
ENCODER_LTR_MARKING_FEEDBACK,
ENCODER_LTR_MARKING_PERIOD,
ENCODER_OPTION_LTR,
ENCODER_OPTION_LTR, ///< 0:disable LTR;larger than 0 enable LTR; LTR number is fixed to be 2 in current encoder
ENCODER_OPTION_COMPLEXITY,
ENCODER_OPTION_ENABLE_SSEI, //enable SSEI: true--enable ssei; false--disable ssei
ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, //enable prefix: true--enable prefix; false--disable prefix
ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, //enable pSps/pPps id addition: true--enable pSps/pPps id; false--disable pSps/pPps id addistion
ENCODER_OPTION_ENABLE_SSEI, ///< enable SSEI: true--enable ssei; false--disable ssei
ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, ///< enable prefix: true--enable prefix; false--disable prefix
ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, ///< enable pSps/pPps id addition: true--enable pSps/pPps id; false--disable pSps/pPps id addistion
ENCODER_OPTION_CURRENT_PATH,
ENCODER_OPTION_DUMP_FILE,
ENCODER_OPTION_TRACE_LEVEL,
ENCODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT,
ENCODER_OPTION_DUMP_FILE, ///< dump layer reconstruct frame to a specified file
ENCODER_OPTION_TRACE_LEVEL, ///< trace info based on the trace level
ENCODER_OPTION_TRACE_CALLBACK, ///< a void (*)(void* context, int level, const char* message) function which receives log messages
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, ///< context info of trace callback
ENCODER_OPTION_GET_STATISTICS, //read only
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, // log interval in milliseconds
ENCODER_OPTION_GET_STATISTICS, ///< read only
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, ///< log interval in millisecond
// advanced algorithmetic settings
ENCODER_OPTION_IS_LOSSLESS_LINK
ENCODER_OPTION_IS_LOSSLESS_LINK ///< advanced algorithmetic settings
} ENCODER_OPTION;
/* Option types introduced in decoder application */
/**
* @brief Option types introduced in decoder application
*/
typedef enum {
DECODER_OPTION_DATAFORMAT = 0, /* Set color space of decoding output frame */
DECODER_OPTION_END_OF_STREAM, /* Indicate bitstream of the final frame to be decoded */
DECODER_OPTION_VCL_NAL, //feedback whether or not have VCL NAL in current AU for application layer
DECODER_OPTION_TEMPORAL_ID, //feedback temporal id for application layer
DECODER_OPTION_FRAME_NUM, //feedback current decoded frame number
DECODER_OPTION_IDR_PIC_ID, // feedback current frame belong to which IDR period
DECODER_OPTION_LTR_MARKING_FLAG, // feedback wether current frame mark a LTR
DECODER_OPTION_LTR_MARKED_FRAME_NUM, // feedback frame num marked by current Frame
DECODER_OPTION_ERROR_CON_IDC, //not finished yet, indicate decoder error concealment status, in progress
DECODER_OPTION_DATAFORMAT = 0, ///< color format, now supports 23 only (I420)
DECODER_OPTION_END_OF_STREAM, ///< end of stream flag
DECODER_OPTION_VCL_NAL, ///< feedback whether or not have VCL NAL in current AU for application layer
DECODER_OPTION_TEMPORAL_ID, ///< feedback temporal id for application layer
DECODER_OPTION_FRAME_NUM, ///< feedback current decoded frame number
DECODER_OPTION_IDR_PIC_ID, ///< feedback current frame belong to which IDR period
DECODER_OPTION_LTR_MARKING_FLAG, ///< feedback wether current frame mark a LTR
DECODER_OPTION_LTR_MARKED_FRAME_NUM, ///< feedback frame num marked by current Frame
DECODER_OPTION_ERROR_CON_IDC, ///< not finished yet, indicate decoder error concealment status, in progress
DECODER_OPTION_TRACE_LEVEL,
DECODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,
DECODER_OPTION_TRACE_CALLBACK, ///< a void (*)(void* context, int level, const char* message) function which receives log messages
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,///< context info of trace callbac
DECODER_OPTION_GET_STATISTICS
} DECODER_OPTION;
//enuerate the types of error concealment methods
/**
* @brief Enumerate the type of error concealment methods
*/
typedef enum {
ERROR_CON_DISABLE = 0,
ERROR_CON_FRAME_COPY,
@ -140,19 +161,26 @@ typedef enum {
ERROR_CON_SLICE_COPY_CROSS_IDR,
ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE
} ERROR_CON_IDC;
typedef enum { //feedback that whether or not have VCL NAL in current AU
/**
* @brief Feedback that whether or not have VCL NAL in current AU
*/
typedef enum {
FEEDBACK_NON_VCL_NAL = 0,
FEEDBACK_VCL_NAL,
FEEDBACK_UNKNOWN_NAL
} FEEDBACK_VCL_NAL_IN_AU;
/* Type of layer being encoded */
/**
* @brief Type of layer being encoded
*/
typedef enum {
NON_VIDEO_CODING_LAYER = 0,
VIDEO_CODING_LAYER = 1
} LAYER_TYPE;
/**
* @brief Spatial layer num
*/
typedef enum {
SPATIAL_LAYER_0 = 0,
SPATIAL_LAYER_1 = 1,
@ -161,13 +189,18 @@ typedef enum {
SPATIAL_LAYER_ALL = 4
} LAYER_NUM;
//enumerate the type of video bitstream which is provided to decoder
/**
* @brief Enumerate the type of video bitstream which is provided to decoder
*/
typedef enum {
VIDEO_BITSTREAM_AVC = 0,
VIDEO_BITSTREAM_SVC = 1,
VIDEO_BITSTREAM_DEFAULT = VIDEO_BITSTREAM_SVC
} VIDEO_BITSTREAM_TYPE;
/**
* @brief Enumerate the type of key frame request
*/
typedef enum {
NO_RECOVERY_REQUSET = 0,
LTR_RECOVERY_REQUEST = 1,
@ -177,62 +210,87 @@ typedef enum {
LTR_MARKING_FAILED = 5
} KEY_FRAME_REQUEST_TYPE;
/**
* @brief Structure for LTR recover request
*/
typedef struct {
unsigned int uiFeedbackType; //IDR request or LTR recovery request
unsigned int uiIDRPicId; // distinguish request from different IDR
int iLastCorrectFrameNum;
int iCurrentFrameNum; //specify current decoder frame_num.
unsigned int uiFeedbackType; ///< IDR request or LTR recovery request
unsigned int uiIDRPicId; ///< distinguish request from different IDR
int iLastCorrectFrameNum;
int iCurrentFrameNum; ///< specify current decoder frame_num.
} SLTRRecoverRequest;
/**
* @brief Structure for LTR marking feedback
*/
typedef struct {
unsigned int uiFeedbackType; //mark failed or successful
unsigned int uiIDRPicId; // distinguish request from different IDR
int iLTRFrameNum; //specify current decoder frame_num
unsigned int uiFeedbackType; ///< mark failed or successful
unsigned int uiIDRPicId; ///< distinguish request from different IDR
int iLTRFrameNum; ///< specify current decoder frame_num
} SLTRMarkingFeedback;
/**
* @brief Structure for LTR configuration
*/
typedef struct {
bool bEnableLongTermReference; // 1: on, 0: off
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
bool bEnableLongTermReference; ///< 1: on, 0: off
int iLTRRefNum; ///< TODO: not supported to set it arbitrary yet
} SLTRConfig;
/**
* @brief Structure for slice argument
*/
typedef struct {
unsigned int
uiSliceMbNum[MAX_SLICES_NUM_TMP]; //here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
unsigned int uiSliceNum;
unsigned int uiSliceSizeConstraint;
} SSliceArgument;//not all the elements in this argument will be used, how it will be used depends on uiSliceMode; see below
uiSliceMbNum[MAX_SLICES_NUM_TMP]; ///< only used when uiSliceMode=2;here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
unsigned int uiSliceNum; ///< only used when uiSliceMode=1
unsigned int uiSliceSizeConstraint; ///< only used when uiSliceMode=4
} SSliceArgument; ///< not all the elements in this argument will be used, how it will be used depends on uiSliceMode; please refer to SliceModeEnum
/**
* @brief Enumerate the type of slice mode
*/
typedef enum {
SM_SINGLE_SLICE = 0, // | SliceNum==1
SM_FIXEDSLCNUM_SLICE = 1, // | according to SliceNum | Enabled dynamic slicing for multi-thread
SM_RASTER_SLICE = 2, // | according to SlicesAssign | Need input of MB numbers each slice. In addition, if other constraint in SSliceArgument is presented, need to follow the constraints. Typically if MB num and slice size are both constrained, re-encoding may be involved.
SM_ROWMB_SLICE = 3, // | according to PictureMBHeight | Typical of single row of mbs each slice?+ slice size constraint which including re-encoding
SM_DYN_SLICE = 4, // | according to SliceSize | Dynamic slicing (have no idea about slice_nums until encoding current frame)
SM_AUTO_SLICE = 5, // | according to thread number
SM_SINGLE_SLICE = 0, ///< | SliceNum==1
SM_FIXEDSLCNUM_SLICE = 1, ///< | according to SliceNum | enabled dynamic slicing for multi-thread
SM_RASTER_SLICE = 2, ///< | according to SlicesAssign | need input of MB numbers each slice. In addition, if other constraint in SSliceArgument is presented, need to follow the constraints. Typically if MB num and slice size are both constrained, re-encoding may be involved.
SM_ROWMB_SLICE = 3, ///< | according to PictureMBHeight | typical of single row of mbs each slice + slice size constraint which including re-encoding
SM_DYN_SLICE = 4, ///< | according to SliceSize | dynamic slicing (have no idea about slice_nums until encoding current frame)
SM_AUTO_SLICE = 5, ///< | according to thread number
SM_RESERVED = 6
} SliceModeEnum;
/**
* @brief Enumerate the type of rate control mode
*/
typedef enum {
RC_QUALITY_MODE = 0, //Quality mode
RC_BITRATE_MODE = 1, //Bitrate mode
RC_BUFFERBASED_MODE = 2,//no bitrate control,only using buffer status,adjust the video quality
RC_OFF_MODE = -1 // rate control off mode
RC_QUALITY_MODE = 0, ///< quality mode
RC_BITRATE_MODE = 1, ///< bitrate mode
RC_BUFFERBASED_MODE = 2, ///< no bitrate control,only using buffer status,adjust the video quality
RC_OFF_MODE = -1 ///< rate control off mode
} RC_MODES;
/**
* @brief Enumerate the type of profile id
*/
typedef enum {
PRO_UNKNOWN = 0,
PRO_UNKNOWN = 0,
PRO_BASELINE = 66,
PRO_MAIN = 77,
PRO_EXTENDED = 88,
PRO_HIGH = 100,
PRO_HIGH10 = 110,
PRO_HIGH422 = 122,
PRO_HIGH444 = 144,
PRO_HIGH10 = 110,
PRO_HIGH422 = 122,
PRO_HIGH444 = 144,
PRO_CAVLC444 = 244,
PRO_SCALABLE_BASELINE = 83,
PRO_SCALABLE_HIGH = 86
} EProfileIdc;
/**
* @brief Enumerate the type of level id
*/
typedef enum {
LEVEL_UNKNOWN,
LEVEL_1_0,
@ -254,136 +312,158 @@ typedef enum {
LEVEL_5_2
} ELevelIdc;
/**
* @brief Enumerate the type of wels log
*/
enum {
WELS_LOG_QUIET = 0x00, // Quiet mode
WELS_LOG_ERROR = 1 << 0, // Error log iLevel
WELS_LOG_WARNING = 1 << 1, // Warning log iLevel
WELS_LOG_INFO = 1 << 2, // Information log iLevel
WELS_LOG_DEBUG = 1 << 3, // Debug log, critical algo log
WELS_LOG_DETAIL = 1 << 4, // per packet/frame log
WELS_LOG_RESV = 1 << 5, // Resversed log iLevel
WELS_LOG_QUIET = 0x00, ///< quiet mode
WELS_LOG_ERROR = 1 << 0, ///< error log iLevel
WELS_LOG_WARNING = 1 << 1, ///< Warning log iLevel
WELS_LOG_INFO = 1 << 2, ///< information log iLevel
WELS_LOG_DEBUG = 1 << 3, ///< debug log, critical algo log
WELS_LOG_DETAIL = 1 << 4, ///< per packet/frame log
WELS_LOG_RESV = 1 << 5, ///< resversed log iLevel
WELS_LOG_LEVEL_COUNT = 6,
WELS_LOG_DEFAULT = WELS_LOG_DEBUG // Default log iLevel in Wels codec
WELS_LOG_DEFAULT = WELS_LOG_DEBUG ///< default log iLevel in Wels codec
};
/**
* @brief Structure for slice configuration
*/
typedef struct {
SliceModeEnum uiSliceMode; //by default, uiSliceMode will be SM_SINGLE_SLICE
SliceModeEnum uiSliceMode; ///< by default, uiSliceMode will be SM_SINGLE_SLICE
SSliceArgument sSliceArgument;
} SSliceConfig;
/**
* @brief Structure for spatial layer configuration
*/
typedef struct {
int iVideoWidth; // video size in cx specified for a layer
int iVideoHeight; // video size in cy specified for a layer
float fFrameRate; // frame rate specified for a layer
int iSpatialBitrate; // target bitrate for a spatial layer
int iMaxSpatialBitrate;
EProfileIdc uiProfileIdc; // value of profile IDC (PRO_UNKNOWN for auto-detection)
ELevelIdc uiLevelIdc;
int iDLayerQp;
int iVideoWidth; ///< width of picture in luminance samples of a layer
int iVideoHeight; ///< height of picture in luminance samples of a layer
float fFrameRate; ///< frame rate specified for a layer
int iSpatialBitrate; ///< target bitrate for a spatial layer
int iMaxSpatialBitrate; ///< maximum bitrate for a spatial layer
EProfileIdc uiProfileIdc; ///< value of profile IDC (PRO_UNKNOWN for auto-detection)
ELevelIdc uiLevelIdc; ///< value of profile IDC (0 for auto-detection)
int iDLayerQp; ///< value of level IDC (0 for auto-detection)
SSliceConfig sSliceCfg;
SSliceConfig sSliceCfg; ///< slice configuration for a layer
} SSpatialLayerConfig;
/**
* @brief Encoder usage type
*/
typedef enum {
CAMERA_VIDEO_REAL_TIME, //camera video signal
SCREEN_CONTENT_REAL_TIME //screen content signal
CAMERA_VIDEO_REAL_TIME, ///< camera video signal
SCREEN_CONTENT_REAL_TIME ///< screen content signal
} EUsageType;
/**
* @brief Enumulate the complexity mode
*/
typedef enum {
LOW_COMPLEXITY, //the lowest compleixty,the fastest speed,
MEDIUM_COMPLEXITY, //medium complexity, medium speed,medium quality
HIGH_COMPLEXITY //high complexity, lowest speed, high quality
LOW_COMPLEXITY, ///< the lowest compleixty,the fastest speed,
MEDIUM_COMPLEXITY, ///< medium complexity, medium speed,medium quality
HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality
} ECOMPLEXITY_MODE;
// TODO: Refine the parameters definition.
// SVC Encoding Parameters
/**
* @brief SVC Encoding Parameters
*/
typedef struct TagEncParamBase {
EUsageType
iUsageType; //application type;// CAMERA_VIDEO_REAL_TIME: //camera video signal; SCREEN_CONTENT_REAL_TIME: screen content signal;
iUsageType; ///< application type;1.CAMERA_VIDEO_REAL_TIME:camera video signal; 2.SCREEN_CONTENT_REAL_TIME:screen content signal;
int iPicWidth; // width of picture in samples
int iPicHeight; // height of picture in samples
int iTargetBitrate; // target bitrate desired
RC_MODES iRCMode; // RC mode
float fMaxFrameRate; // input maximal frame rate
int iPicWidth; ///< width of picture in luminance samples (the maximum of all layers if multiple spatial layers presents)
int iPicHeight; ///< height of picture in luminance samples((the maximum of all layers if multiple spatial layers presents)
int iTargetBitrate; ///< target bitrate desired
RC_MODES iRCMode; ///< rate control mode
float fMaxFrameRate; ///< maximal input frame rate
} SEncParamBase, *PEncParamBase;
/**
* @brief SVC Encoding Parameters extention
*/
typedef struct TagEncParamExt {
EUsageType
iUsageType; //application type;// CAMERA_VIDEO_REAL_TIME: //camera video signal; SCREEN_CONTENT_REAL_TIME: screen content signal;
iUsageType; ///< application type;1.CAMERA_VIDEO_REAL_TIME:camera video signal;2.SCREEN_CONTENT_REAL_TIME:screen content signal;
int iPicWidth; // width of picture in samples
int iPicHeight; // height of picture in samples
int iTargetBitrate; // target bitrate desired
RC_MODES iRCMode; // RC mode
float fMaxFrameRate; // input maximal frame rate
int iPicWidth; ///< width of picture in luminance samples (the maximum of all layers if multiple spatial layers presents)
int iPicHeight; ///< height of picture in luminance samples((the maximum of all layers if multiple spatial layers presents)
int iTargetBitrate; ///< target bitrate desired
RC_MODES iRCMode; ///< rate control mode
float fMaxFrameRate; ///< maximal input frame rate
int iTemporalLayerNum; // layer number at temporal level
int iSpatialLayerNum; // layer number at spatial level
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
bool bEnableSpsPpsIdAddition;
bool bPrefixNalAddingCtrl;
bool bEnableSSEI;
int iPaddingFlag; // 0:disable padding;1:padding
int iEntropyCodingModeFlag;
unsigned int uiIntraPeriod; ///< period of Intra frame
int iNumRefFrame; ///< number of reference frame used
bool bEnableSpsPpsIdAddition; ///< false:not adjust ID in SPS/PPS; true: adjust ID in SPS/PPS
bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI
int iPaddingFlag; ///< 0:disable padding;1:padding
int iEntropyCodingModeFlag; ///< 0:CAVLC 1:CABAC.
/* rc control */
bool bEnableFrameSkip; // allow skipping frames to keep the bitrate within limits
int iMaxBitrate; // max bitrate desired
int iMaxQp;
int iMinQp;
unsigned int uiMaxNalSize;
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
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; //TODO: not supported to set it arbitrary yet
unsigned int iLtrMarkPeriod;
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; > 1: count number of threads;
iMultipleThreadIdc; ///< 1 # 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; lager than 1: count number of threads;
/* 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
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 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;
/*LTR advanced setting*/
bool bIsLosslessLink;
bool bIsLosslessLink; ///< LTR advanced setting
} SEncParamExt;
//Define a new struct to show the property of video bitstream.
/**
* @brief Define a new struct to show the property of video bitstream.
*/
typedef struct {
unsigned int size; //size of the struct
VIDEO_BITSTREAM_TYPE eVideoBsType;
unsigned int size; ///< size of the struct
VIDEO_BITSTREAM_TYPE eVideoBsType; ///< video stream type (AVC/SVC)
} SVideoProperty;
/* SVC Decoding Parameters, reserved here and potential applicable in the future */
/**
* @brief SVC Decoding Parameters, reserved here and potential applicable in the future
*/
typedef struct TagSVCDecodingParam {
char* pFileNameRestructed; // File name of restructed frame used for PSNR calculation based debug
char* pFileNameRestructed; ///< file name of reconstructed frame used for PSNR calculation based debug
EVideoFormatType eOutputColorFormat; // color space format to be outputed, EVideoFormatType specified in codec_def.h
unsigned int uiCpuLoad; // CPU load
unsigned char uiTargetDqLayer; // Setting target dq layer id
EVideoFormatType eOutputColorFormat; ///< color space format to be outputed, EVideoFormatType specified in codec_def.h
unsigned int uiCpuLoad; ///< CPU load
unsigned char uiTargetDqLayer; ///< setting target dq layer id
ERROR_CON_IDC eEcActiveIdc; // Whether active error concealment feature in decoder
ERROR_CON_IDC eEcActiveIdc; ///< whether active error concealment feature in decoder
SVideoProperty sVideoProperty;
SVideoProperty sVideoProperty; ///< video stream property
} SDecodingParam, *PDecodingParam;
/* Bitstream inforamtion of a layer being encoded */
/**
* @brief Bitstream inforamtion of a layer being encoded
*/
typedef struct {
unsigned char uiTemporalId;
unsigned char uiSpatialId;
@ -391,17 +471,22 @@ typedef struct {
unsigned char uiLayerType;
int iNalCount; // Count number of NAL coded already
int* pNalLengthInByte; // Length of NAL size in byte from 0 to iNalCount-1
unsigned char* pBsBuf; // Buffer of bitstream contained
int iNalCount; ///< count number of NAL coded already
int* pNalLengthInByte; ///< length of NAL size in byte from 0 to iNalCount-1
unsigned char* pBsBuf; ///< buffer of bitstream contained
} SLayerBSInfo, *PLayerBSInfo;
/**
* @brief Frame bit stream info
*/
typedef struct {
int iTemporalId; // Temporal ID
//The sub sequence layers are ordered hierarchically based on their dependency on each other so that any picture in a layer shall not be
//predicted from any picture on any higher layer.
int iSubSeqId; //refer to D.2.11 Sub-sequence information SEI message semantics
int iTemporalId; ///< temporal ID
/**
* The sub sequence layers are ordered hierarchically based on their dependency on each other so that any picture in a layer shall not be
* predicted from any picture on any higher layer.
*/
int iSubSeqId; ///< refer to D.2.11 Sub-sequence information SEI message semantics
int iLayerNum;
SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
@ -411,41 +496,63 @@ typedef struct {
long long uiTimeStamp;
} SFrameBSInfo, *PFrameBSInfo;
/**
* @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
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;
} SSourcePicture;
/**
* @brief Structure for bit rate info
*/
typedef struct TagBitrateInfo {
LAYER_NUM iLayer;
int iBitrate; //the maximum bitrate
int iBitrate; ///< the maximum bitrate
} SBitrateInfo;
/**
* @brief Structure for dump layer info
*/
typedef struct TagDumpLayer {
int iLayer;
char* pFileName;
} SDumpLayer;
/**
* @brief Structure for profile info in layer
*
*/
typedef struct TagProfileInfo {
int iLayer;
EProfileIdc uiProfileIdc; //the profile info
EProfileIdc uiProfileIdc; ///< the profile info
} SProfileInfo;
/**
* @brief Structure for level info in layer
*
*/
typedef struct TagLevelInfo {
int iLayer;
ELevelIdc uiLevelIdc; //the level info
ELevelIdc uiLevelIdc; ///< the level info
} SLevelInfo;
/**
* @brief Structure for dilivery status
*
*/
typedef struct TagDeliveryStatus {
bool bDeliveryFlag; //0: the previous frame isn't delivered,1: the previous frame is delivered
int iDropFrameType; // the frame type that is dropped; reserved
int iDropFrameSize; // the frame size that is dropped; reserved
bool bDeliveryFlag; ///< 0: the previous frame isn't delivered,1: the previous frame is delivered
int iDropFrameType; ///< the frame type that is dropped; reserved
int iDropFrameSize; ///< the frame size that is dropped; reserved
} SDeliveryStatus;
/**
* @brief The capability of decoder
*/
typedef struct TagDecoderCapability {
int iProfileIdc;
int iProfileIop;
@ -458,46 +565,56 @@ typedef struct TagDecoderCapability {
bool bRedPicCap;
} SDecoderCapability;
/**
* @brief to do
*/
typedef struct TagParserBsInfo {
int iNalNum; //total NAL number in current AU
int iNalLenInByte [MAX_NAL_UNITS_IN_LAYER]; //each nal length
unsigned char* pDstBuff; //outputted dst buffer for parsed bitstream
int iSpsWidthInPixel; //required SPS width info
int iSpsHeightInPixel; //required SPS height info
int iNalNum; ///< total NAL number in current AU
int iNalLenInByte [MAX_NAL_UNITS_IN_LAYER]; ///< each nal length
unsigned char* pDstBuff; ///< outputted dst buffer for parsed bitstream
int iSpsWidthInPixel; ///< required SPS width info
int iSpsHeightInPixel; ///< required SPS height info
} SParserBsInfo, PParserBsInfo;
/**
* @brief Structure for encoder statistics
*/
typedef struct TagVideoEncoderStatistics {
unsigned int uiWidth; // the width of encoded frame
unsigned int uiHeight; // the height of encoded frame
unsigned int uiWidth; ///< the width of encoded frame
unsigned int uiHeight; ///< the height of encoded frame
//following standard, will be 16x aligned, if there are multiple spatial, this is of the highest
float fAverageFrameSpeedInMs; // Average_Encoding_Time
float fAverageFrameSpeedInMs; ///< average_Encoding_Time
// rate control related
float fAverageFrameRate; // the average frame rate in, calculate since encoding starts, supposed that the input timestamp is in unit of ms
float fLatestFrameRate; // the frame rate in, in the last second, supposed that the input timestamp is in unit of ms (? useful for checking BR, but is it easy to calculate?
unsigned int uiBitRate; // sendrate in Bits per second, calculated within the set time-window
float fAverageFrameRate; ///< the average frame rate in, calculate since encoding starts, supposed that the input timestamp is in unit of ms
float fLatestFrameRate; ///< the frame rate in, in the last second, supposed that the input timestamp is in unit of ms (? useful for checking BR, but is it easy to calculate?
unsigned int uiBitRate; ///< sendrate in Bits per second, calculated within the set time-window
unsigned int uiInputFrameCount; // number of frames
unsigned int uiSkippedFrameCount; // number of frames
unsigned int uiInputFrameCount; ///< number of frames
unsigned int uiSkippedFrameCount; ///< number of frames
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
unsigned int uiIDRReqNum; // number of IDR requests
unsigned int uiIDRSentNum; // number of actual IDRs sent
unsigned int uiLTRSentNum; // number of LTR sent/marked
unsigned int uiResolutionChangeTimes; ///< uiResolutionChangeTimes
unsigned int uiIDRReqNum; ///< number of IDR requests
unsigned int uiIDRSentNum; ///< number of actual IDRs sent
unsigned int uiLTRSentNum; ///< number of LTR sent/marked
} SEncoderStatistics; // in building, coming soon
/**
* @brief Structure for decoder statistics
*/
typedef struct TagVideoDecoderStatistics {
unsigned int uiWidth; // the width of encode/decode frame
unsigned int uiHeight; // the height of encode/decode frame
float fAverageFrameSpeedInMs; // Average_Decoding_Time
unsigned int uiDecodedFrameCount; // number of frames
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
unsigned int uiIDRRecvNum; // number of actual IDR received
unsigned int uiWidth; ///< the width of encode/decode frame
unsigned int uiHeight; ///< the height of encode/decode frame
float fAverageFrameSpeedInMs; ///< average_Decoding_Time
unsigned int uiDecodedFrameCount; ///< number of frames
unsigned int uiResolutionChangeTimes; ///< uiResolutionChangeTimes
unsigned int uiIDRRecvNum; ///< number of actual IDR received
//EC on related
unsigned int uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
unsigned int uiEcIDRNum; // number of actual unintegrity IDR or not received but eced
unsigned int uiEcFrameNum; //
unsigned int uiIDRLostNum;//Decoder detect out the number of lost IDR lost
unsigned int
uiAvgEcRatio; ///< when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
unsigned int uiEcIDRNum; ///< number of actual unintegrity IDR or not received but eced
unsigned int uiEcFrameNum; ///<
unsigned int uiIDRLostNum; ///< decoder detect the number of lost IDR
} SDecoderStatistics; // in building, coming soon
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__

View File

@ -33,9 +33,15 @@
#ifndef WELS_VIDEO_CODEC_DEFINITION_H__
#define WELS_VIDEO_CODEC_DEFINITION_H__
/**
* @file codec_def.h
*/
/**
* @brief Enumerate the type of video format
*/
typedef enum {
/*rgb color formats*/
videoFormatRGB = 1,
videoFormatRGB = 1, ///< rgb color formats
videoFormatRGBA = 2,
videoFormatRGB555 = 3,
videoFormatRGB565 = 4,
@ -44,51 +50,61 @@ typedef enum {
videoFormatABGR = 7,
videoFormatARGB = 8,
/*yuv color formats*/
videoFormatYUY2 = 20,
videoFormatYUY2 = 20, ///< yuv color formats
videoFormatYVYU = 21,
videoFormatUYVY = 22,
videoFormatI420 = 23, //same as IYUV
videoFormatI420 = 23, ///< the same as IYUV
videoFormatYV12 = 24,
videoFormatInternal = 25, // Only Used for SVC decoder testbed
videoFormatInternal = 25, ///< only used in SVC decoder testbed
videoFormatNV12 = 26, // new format for output by DXVA decoding
videoFormatNV12 = 26, ///< new format for output by DXVA decoding
videoFormatVFlip = 0x80000000
} EVideoFormatType;
/**
* @brief Enumerate video frame type
*/
typedef enum {
videoFrameTypeInvalid, /* Encoder not ready or parameters are invalidate */
videoFrameTypeIDR, /* This type is only available for H264 if this frame is key frame, then return this type */
videoFrameTypeI, /* I frame type */
videoFrameTypeP, /* P frame type */
videoFrameTypeSkip, /* Skip the frame based encoder kernel */
videoFrameTypeIPMixed /* Frame type introduced I and P slices are mixing */
videoFrameTypeInvalid, ///< encoder not ready or parameters are invalidate
videoFrameTypeIDR, ///< IDR frame in H.264
videoFrameTypeI, ///< I frame type
videoFrameTypeP, ///< P frame type
videoFrameTypeSkip, ///< skip the frame based encoder kernel
videoFrameTypeIPMixed ///< a frame where I and P slices are mixing, not supported yet
} EVideoFrameType;
/**
* @brief Enumerate return type
*/
typedef enum {
cmResultSuccess,
cmInitParaError, /*Parameters are invalid */
cmResultSuccess, ///< successful
cmInitParaError, ///< parameters are invalid
cmUnkonwReason,
cmMallocMemeError, /*Malloc a memory error*/
cmInitExpected, /*Initial action is expected*/
cmMallocMemeError, ///< malloc a memory error
cmInitExpected, ///< initial action is expected
cmUnsupportedData
} CM_RETURN;
/* nal unit type */
/**
* @brief Enumulate the nal unit type
*/
enum ENalUnitType {
NAL_UNKNOWN = 0,
NAL_SLICE = 1,
NAL_UNKNOWN = 0,
NAL_SLICE = 1,
NAL_SLICE_DPA = 2,
NAL_SLICE_DPB = 3,
NAL_SLICE_DPC = 4,
NAL_SLICE_IDR = 5, /* ref_idc != 0 */
NAL_SEI = 6, /* ref_idc == 0 */
NAL_SLICE_IDR = 5, ///< ref_idc != 0
NAL_SEI = 6, ///< ref_idc == 0
NAL_SPS = 7,
NAL_PPS = 8
/* ref_idc == 0 for 6,9,10,11,12 */
///< ref_idc == 0 for 6,9,10,11,12
};
/* NRI: eNalRefIdc */
/**
* @brief NRI: eNalRefIdc
*/
enum ENalPriority {
NAL_PRIORITY_DISPOSABLE = 0,
NAL_PRIORITY_LOW = 1,
@ -107,31 +123,37 @@ enum ENalPriority {
/* Error Tools definition */
typedef unsigned short ERR_TOOL;
/**
@brief to do
*/
enum {
ET_NONE = 0x00, // NONE Error Tools
ET_IP_SCALE = 0x01, // IP Scalable
ET_FMO = 0x02, // Flexible Macroblock Ordering
ET_IR_R1 = 0x04, // Intra Refresh in predifined 2% MB
ET_IR_R2 = 0x08, // Intra Refresh in predifined 5% MB
ET_IR_R3 = 0x10, // Intra Refresh in predifined 10% MB
ET_FEC_HALF = 0x20, // Forward Error Correction in 50% redundency mode
ET_FEC_FULL = 0x40, // Forward Error Correction in 100% redundency mode
ET_RFS = 0x80 // Reference Frame Selection
ET_NONE = 0x00, ///< NONE Error Tools
ET_IP_SCALE = 0x01, ///< IP Scalable
ET_FMO = 0x02, ///< Flexible Macroblock Ordering
ET_IR_R1 = 0x04, ///< Intra Refresh in predifined 2% MB
ET_IR_R2 = 0x08, ///< Intra Refresh in predifined 5% MB
ET_IR_R3 = 0x10, ///< Intra Refresh in predifined 10% MB
ET_FEC_HALF = 0x20, ///< Forward Error Correction in 50% redundency mode
ET_FEC_FULL = 0x40, ///< Forward Error Correction in 100% redundency mode
ET_RFS = 0x80 ///< Reference Frame Selection
};
/* information of coded Slice(=NAL)(s) */
/**
* @brief Information of coded Slice(=NAL)(s)
*/
typedef struct SliceInformation {
unsigned char* pBufferOfSlices; // base buffer of coded slice(s)
int iCodedSliceCount; // number of coded slices
unsigned int* pLengthOfSlices; // array of slices length accordingly by number of slice
int iFecType; // FEC type[0, 50%FEC, 100%FEC]
unsigned char uiSliceIdx; // index of slice in frame [FMO: 0,..,uiSliceCount-1; No FMO: 0]
unsigned char uiSliceCount; // count number of slice in frame [FMO: 2-8; No FMO: 1]
char iFrameIndex; // index of frame[-1, .., idr_interval-1]
unsigned char uiNalRefIdc; // NRI, priority level of slice(NAL)
unsigned char uiNalType; // NAL type
unsigned char* pBufferOfSlices; ///< base buffer of coded slice(s)
int iCodedSliceCount; ///< number of coded slices
unsigned int* pLengthOfSlices; ///< array of slices length accordingly by number of slice
int iFecType; ///< FEC type[0, 50%FEC, 100%FEC]
unsigned char uiSliceIdx; ///< index of slice in frame [FMO: 0,..,uiSliceCount-1; No FMO: 0]
unsigned char uiSliceCount; ///< count number of slice in frame [FMO: 2-8; No FMO: 1]
char iFrameIndex; ///< index of frame[-1, .., idr_interval-1]
unsigned char uiNalRefIdc; ///< NRI, priority level of slice(NAL)
unsigned char uiNalType; ///< NAL type
unsigned char
uiContainingFinalNal; // whether final NAL is involved in buffer of coded slices, flag used in Pause feature in T27
uiContainingFinalNal; ///< whether final NAL is involved in buffer of coded slices, flag used in Pause feature in T27
} SliceInfo, *PSliceInfo;
@ -145,44 +167,57 @@ typedef struct SliceInformation {
#define SQCIF_WIDTH 128
#define SQCIF_HEIGHT 96
/* thresholds of the initial, maximal and minimal rate */
/**
* @brief thresholds of the initial, maximal and minimal rate
*/
typedef struct {
int iWidth; // frame width
int iHeight; // frame height
int iThresholdOfInitRate; // threshold of initial rate
int iThresholdOfMaxRate; // threshold of maximal rate
int iThresholdOfMinRate; // threshold of minimal rate
int iMinThresholdFrameRate; //min frame rate min
int iSkipFrameRate; //skip to frame rate min
int iSkipFrameStep; //how many frames to skip
int iWidth; ///< frame width
int iHeight; ///< frame height
int iThresholdOfInitRate; ///< threshold of initial rate
int iThresholdOfMaxRate; ///< threshold of maximal rate
int iThresholdOfMinRate; ///< threshold of minimal rate
int iMinThresholdFrameRate; ///< min frame rate min
int iSkipFrameRate; ///< skip to frame rate min
int iSkipFrameStep; ///< how many frames to skip
} SRateThresholds, *PRateThresholds;
/**
* @brief Structure for decoder memery
*/
typedef struct TagSysMemBuffer {
int iWidth; //width of decoded pic for display
int iHeight; //height of decoded pic for display
int iFormat; // type is "EVideoFormatType"
int iStride[2]; //stride of 2 component
int iWidth; ///< width of decoded pic for display
int iHeight; ///< height of decoded pic for display
int iFormat; ///< type is "EVideoFormatType"
int iStride[2]; ///< stride of 2 component
} SSysMEMBuffer;
/**
* @brief Buffer info
*/
typedef struct TagBufferInfo {
int iBufferStatus; // 0: one frame data is not ready; 1: one frame data is ready
int iBufferStatus; ///< 0: one frame data is not ready; 1: one frame data is ready
union {
SSysMEMBuffer sSystemBuffer;
} UsrData;
SSysMEMBuffer sSystemBuffer; ///< memory info for one picture
} UsrData; ///< output buffer info
} SBufferInfo;
/* Constants related to transmission rate at various resolutions */
/**
* @brief Constants related to transmission rate at various resolutions
*/
static const SRateThresholds ksRateThrMap[4] = {
// initial-maximal-minimal
{CIF_WIDTH, CIF_HEIGHT, 225000, 384000, 96000, 3, 1, 1}, // CIF
{QVGA_WIDTH, QVGA_HEIGHT, 192000, 320000, 80000, -1, -1, -1}, // QVGA
{QCIF_WIDTH, QCIF_HEIGHT, 150000, 256000, 64000, 8, 4, 2}, // QCIF
{QCIF_WIDTH, QCIF_HEIGHT, 150000, 256000, 64000, 8, 4, 2}, // QCIF
{SQCIF_WIDTH, SQCIF_HEIGHT, 120000, 192000, 48000, 5, 3, 1} // SQCIF
};
// In a GOP, multiple of the key frame number, derived from
// the number of layers(index or array below)
/**
* @brief In a GOP, multiple of the key frame number, derived from
* the number of layers(index or array below)
*/
static const char kiKeyNumMultiple[] = {
1, 1, 2, 4, 8, 16,
};

1865
docs/doxygen/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

25
docs/doxygen/Home.rest Normal file
View File

@ -0,0 +1,25 @@
.. contents::
:local:
1. Overview
---------------------
<doxygen2rst page=Overview> Overview </doxygen2rst>
2. Page index
---------------------
- `ISVCEncoder <wiki/ISVCEncoder>`_
- `ISVCDecoder <wiki/ISVCDecoder>`_
- `Example code for encoder usage <wiki/UsageExampleForEncoder>`_
- `Example code for decoder usage <wiki/UsageExampleForDecoder>`_
- `How to update wiki page <wiki/API2Wiki>`_
3. Classes
---------------------
- `ISVCEncoder <wiki/ISVCEncoder>`_
- `ISVCDecoder <wiki/ISVCDecoder>`_
- `Types and Structures <wiki/TypesAndStructures>`_
4. License
---------------------
<doxygen2rst page=License> License </doxygen2rst>

View File

@ -0,0 +1,19 @@
This file describes the interface of ISVCDecoder
.. contents::
:local:
:depth: 2
Methods(ISVCDecoder)
============================
<doxygen2rst class=ISVCDecoder> Class:ISVCDecoder </doxygen2rst>
Global functions
============================
<doxygen2rst function=WelsGetDecoderCapability> function:WelsGetDecoderCapability </doxygen2rst>
<doxygen2rst function=WelsCreateDecoder> function:WelsCreateDecoder </doxygen2rst>
<doxygen2rst function=WelsDestroyDecoder> function:WelsDestroyDecoder </doxygen2rst>

View File

@ -0,0 +1,16 @@
This file describes the interface of ISVCEncoder
.. contents::
:local:
:depth: 2
Methods(ISVCEncoder)
============================
<doxygen2rst class=ISVCEncoder> Class:ISVCEncoder </doxygen2rst>
Global functions
===========================
<doxygen2rst function=WelsCreateSVCEncoder> function:WelsCreateSVCEncoder </doxygen2rst>
<doxygen2rst function=WelsDestroySVCEncoder> function:WelsDestroySVCEncoder </doxygen2rst>

View File

@ -0,0 +1,10 @@
This page is about the example of decoder usage
.. contents::
:local:
:depth: 2
Decoder Usage Example(ISVCDecoder)
=================================
<doxygen2rst page=DecoderUsageExample> Decoder usage example </doxygen2rst>

View File

@ -0,0 +1,15 @@
This page is about the example of encoder usage
.. contents::
:local:
:depth: 2
Encoder Usage Example-1
============================
<doxygen2rst page=EncoderUsageExample1> Encoder usage example 1 </doxygen2rst>
Encoder Usage Example-2
============================
<doxygen2rst page=EncoderUsageExample2> Encoder usage example 2 </doxygen2rst>

619
docs/doxygen2rst.py Normal file
View File

@ -0,0 +1,619 @@
from __future__ import print_function
import re, sys, os, time, glob, errno, tempfile, binascii, subprocess, shutil
from lxml import etree
from optparse import OptionParser
import textwrap
import string
VERSION = '0.1'
__all__ = ['DoxyGen2RST']
LINE_BREAKER = "\n"
MAX_COLUMN = 80
def is_valid_uuid(uuid_string):
uuid4hex = re.compile('[0-9a-f]{32}\Z', re.I)
return uuid4hex.match(uuid_string) != None
def get_page(refid):
fields = refid.split("_")
if(is_valid_uuid(fields[-1][-32:])):
return ["_".join(fields[0:-1]), fields[-1]]
return [refid, None]
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
def _glob(path, *exts):
path = os.path.join(path, "*") if os.path.isdir(path) else path + "*"
return [f for files in [glob.glob(path + ext) for ext in exts] for f in files]
class DoxyGen2RST(object):
"""
Customize the Doxygen XML output into RST format, then it can
be translated into all formats with the unified user interface.
The Doxygen output itself is too verbose and not hard to be
organized for a good documentation.
"""
def __init__(self,
src,
dst,
missing_filename = "missing.rst",
is_github = False,
enable_uml = True,
github_ext = ""):
self.doxy_output_dir = os.path.join(src, "_doxygen", "xml")
self.output_dir = dst
self.rst_dir = src
self.enable_uml = enable_uml
mkdir_p(dst)
self.is_github = is_github
if(is_github):
self.page_ext = github_ext
self.anchor_prefix = "wiki-"
else:
self.anchor_prefix = ""
self.page_ext = ".html"
self.filter = ["*.rst", "*.rest"]
self.re_doxy = "<doxygen2rst\s(\S*)=(\S*)>(.*?)</doxygen2rst>"
self.index_root = etree.parse(os.path.join(self.doxy_output_dir, "index.xml")).getroot()
self.references = {}
self.missed_types_structs = {}
self.name_refid_map = {}
self.build_references()
self.page_references = {}
self.missing_filename = missing_filename
self.temp_uml_path = os.path.join(tempfile.gettempdir(), "uml_" + binascii.b2a_hex(os.urandom(15)))
if os.path.exists(self.temp_uml_path):
shutil.rmtree(self.temp_uml_path)
os.mkdir(self.temp_uml_path)
def _find_ref_id(self, kind, name):
#print("_find_ref_id, %s - %s" %(kind, name))
if(kind == "function"):
for comp in self.index_root.iter("member"):
if(comp.attrib["kind"].lower() == kind.lower() and
comp.findtext("name").lower() == name.lower()):
return (comp.attrib["refid"])
pass
else:
for comp in self.index_root.iter("compound"):
if(comp.attrib["kind"].lower() == kind.lower() and
comp.findtext("name").lower() == name.lower()):
return comp.attrib["refid"]
return None
def strip_title_ref(self, text):
table = string.maketrans("","")
retstr = text.translate(table, string.punctuation)
words = retstr.split()
retstr = "-".join(words)
return retstr.lower()
def build_references(self):
for file in _glob(self.rst_dir, *self.filter):
filename = os.path.basename(file)
fin = open(file,'r')
content = fin.read()
it = re.finditer(self.re_doxy, content, re.DOTALL)
for m in it:
ref_id = self._find_ref_id(m.groups()[0], m.groups()[1])
if(ref_id is None):
#print("Reference is NOT found for: %s=%s" % (m.groups()[0], m.groups()[1]))
continue
page_name = os.path.splitext(filename)[0]
title_ref = self.strip_title_ref(m.groups()[2])
self.references[ref_id] = [m.groups()[0], m.groups()[1], page_name, filename, title_ref]
self.name_refid_map[m.groups()[1]] = ref_id
fin.close()
#print(self.references)
def call_plantuml(self):
if(not self.enable_uml):
return
java_bin = os.path.join(os.environ['JAVA_HOME'], "bin", "java")
output_path = os.path.abspath(os.path.join(self.output_dir, "images"))
cmds = ["\"" + java_bin + "\"", "-jar", "plantuml.jar", self.temp_uml_path + "/", "-o", output_path]
print(" ".join(cmds))
os.system(" ".join(cmds))
shutil.rmtree(self.temp_uml_path)
def _build_uml(self, uml_name, content):
uml_path = os.path.join(self.temp_uml_path, uml_name + ".txt")
fuml = open(uml_path, "w+")
fuml.write("@startuml\n")
fuml.write(content)
fuml.write("\n@enduml\n")
fuml.close()
return ".. image:: images/" + uml_name + ".png" + LINE_BREAKER
def _build(self, m):
retstr = ""
if(m.groups()[0] == "uml"):
retstr = self._build_uml(m.groups()[1], m.groups()[2])
elif(m.groups()[0] == "link"):
link = m.groups()[1] + self.page_ext
retstr = ("`%s <%s>`_" % (m.groups()[2], link))
else:
if(m.groups()[0] != "function"):
retstr += self._build_title(m.groups()[2])
retstr += self.convert_doxy(m.groups()[0], m.groups()[1])
return retstr
def generate(self):
for file in _glob(self.rst_dir, *self.filter):
filename = os.path.basename(file)
fin = open(file,'r')
input_txt = fin.read()
fin.close()
output_txt = re.sub(self.re_doxy, self._build, input_txt, 0, re.DOTALL)
output_txt += self._build_page_ref_notes()
fout = open(os.path.join(self.output_dir, filename), 'w+')
fout.write(output_txt)
fout.close()
#print("%s --- %s" %( file, os.path.join(self.output_dir, filename)))
self._build_missed_types_and_structs()
self.call_plantuml()
def make_para_title(self, title, indent = 4):
retstr = LINE_BREAKER
if(title):
retstr += "".ljust(indent, " ") + "| **" + title + "**" + LINE_BREAKER
return retstr
def _build_title(self, title, flag = '=', ref = None):
retstr = LINE_BREAKER
if(ref):
retstr += ".. _ref-" + ref + ":" + LINE_BREAKER + LINE_BREAKER
retstr += title + LINE_BREAKER
retstr += "".ljust(20, flag) + LINE_BREAKER
retstr += LINE_BREAKER
return retstr
def _build_ref(self, node):
text = node.text.strip()
retstr = ""
target = '`' + text + '`'
retstr += target + "_ "
if target in self.page_references:
reflink = self.page_references[target]
print("Link already added: %s == %s" % (reflink[0], node.attrib["refid"]))
assert(reflink[0] == node.attrib["refid"])
pass
else:
self.page_references[target] = (node.attrib["refid"], node.attrib["kindref"], text)
return retstr
def _build_code_block(self, node):
retstr = "::" + LINE_BREAKER + LINE_BREAKER
for codeline in node.iter("codeline"):
retstr += " "
for phrases in codeline.iter("highlight"):
if(phrases.text):
retstr += phrases.text.strip()
for child in phrases:
if(child.text):
retstr += child.text.strip()
if(child.tag == "sp"):
retstr += " "
if(child.tag == "ref" and child.text):
#escape the reference in the code block
retstr += "" # self._build_ref(child)
if(child.tail):
retstr += child.tail.strip()
retstr += LINE_BREAKER
return retstr
def _build_itemlist(self, node):
retstr = ""
for para in node:
if(para.tag != "para"):
continue
if(para.text):
retstr += para.text.strip()
for child in para:
if(child.tag == "ref" and child.text):
retstr += self._build_ref(child)
if(child.tail):
retstr += child.tail.strip()
return retstr
def _build_itemizedlist(self, node):
retstr = LINE_BREAKER
if(node == None):
return ""
for item in node:
if(item.tag != "listitem"):
continue
retstr += " - " + self._build_itemlist(item)
retstr += LINE_BREAKER
return retstr
def _build_verbatim(self, node):
retstr = LINE_BREAKER
if(node.text):
lines = node.text.splitlines()
print(lines[0])
m = re.search("{plantuml}\s(\S*)", lines[0])
if(m):
uml_name = "uml_" + m.groups()[0]
retstr += self._build_uml(uml_name, "\n".join(lines[1:]))
else:
retstr += "::" + LINE_BREAKER + LINE_BREAKER
retstr += node.text
return retstr
def _build_para(self, para):
retstr = ""
no_new_line = False
if(para.text):
retstr += textwrap.fill(para.text.strip(), MAX_COLUMN) + LINE_BREAKER + LINE_BREAKER
for child in para:
no_new_line = False
if(child.tag == "simplesect"):
for child_para in child:
if(child.attrib["kind"] == "return"):
return_str = self._build_para(child_para)
retstr += "".ljust(4, " ") + "| Return:" + LINE_BREAKER
for line in return_str.splitlines():
retstr += "".ljust(4, " ") + "| " + line + LINE_BREAKER
elif(child_para.tag == "title" and child_para.text):
lf.make_para_title(child_para.text.strip(), 4)
elif(child_para.tag == "para"): #for @see
retstr += self._build_para(child_para)
elif(child_para.text):
retstr += "".ljust(4, " ") + "| " + child_para.text.strip() + LINE_BREAKER
if(child.tag == "preformatted"):
retstr += "::" + LINE_BREAKER + LINE_BREAKER
if(child.text):
for line in child.text.splitlines():
retstr += " " + line + LINE_BREAKER
if(child.tag == "ref" and child.text):
retstr = retstr.rstrip('\n')
retstr += " " + self._build_ref(child)
no_new_line = True
if(child.tag == "programlisting"):
retstr += self._build_code_block(child)
if(child.tag == "itemizedlist"):
retstr += self._build_itemizedlist(child)
if(child.tag == "verbatim"):
retstr += self._build_verbatim(child)
if(not no_new_line):
retstr += LINE_BREAKER
if(child.tail):
retstr += textwrap.fill(child.tail.strip(), MAX_COLUMN) + LINE_BREAKER + LINE_BREAKER
return retstr
def get_text(self, node):
retstr = ""
if(node == None):
return ""
for para in node:
if(para.tag != "para"):
continue
retstr += self._build_para(para)
return retstr
def _find_text_ref(self, node):
retstr = ""
if(node.text):
retstr += node.text.strip()
for child in node:
if(child.tag == "ref"):
retstr += " " + self._build_ref(child) + " "
if(child.tail):
retstr += child.tail.strip()
return retstr
def _build_row_breaker(self, columns):
retstr = "+"
for column in columns:
retstr += "".ljust(column, "-") + "+"
return retstr + LINE_BREAKER
def _wrap_cell(self, text, length = 30):
newlines = []
for line in text.splitlines():
newlines.extend(textwrap.wrap(line, length))
return newlines
def _build_row(self, row, columns):
retstr = ""
row_lines = []
max_line = 0
for i in range(3):
row_lines.append(row[i].splitlines())
if(max_line < len(row_lines[i])):
max_line = len(row_lines[i])
for i in range(max_line):
for j in range(3):
retstr += "|"
if(len(row_lines[j]) > i):
retstr += row_lines[j][i]
retstr += "".ljust(columns[j] - len(row_lines[j][i]), " ")
else:
retstr += "".ljust(columns[j], " ")
retstr += "|" + LINE_BREAKER
return retstr
def _build_table(self, rows):
retstr = ""
columns = [0, 0, 0]
for row in rows:
for i in range(3):
for rowline in row[i].splitlines():
if(columns[i] < len(rowline) + 2):
columns[i] = len(rowline) + 2
#columns[0] = 40 if(columns[0] > 40) else columns[0]
#columns[1] = 40 if(columns[1] > 40) else columns[1]
#columns[2] = MAX_COLUMN - columns[0] - columns[1]
retstr += self._build_row_breaker(columns)
for row in rows:
retstr += self._build_row(row, columns)
retstr += self._build_row_breaker(columns)
return retstr;
def build_param_list(self, params, paramdescs):
retstr = ""
param_descriptions = []
for desc in paramdescs:
param_descriptions.append(desc)
rows = []
rows.append(("Name", "Type", "Descritpion"))
for param in params:
declname = param.findtext("declname")
paramdesc = None
for desc in param_descriptions:
paramname = desc.findtext("parameternamelist/parametername")
if(paramname.lower() == declname.lower()):
paramdesc = desc.find("parameterdescription")
break
decltype = self._find_text_ref(param.find("type"))
rows.append((declname, decltype, self.get_text(paramdesc)))
if(len(rows) > 1):
retstr += self._build_table(rows)
return retstr
def _build_enum(self, member):
enum_id = member.attrib["id"]
file, tag = get_page(enum_id)
retstr = self._build_title(member.findtext("name"), ref = tag)
detail_node = self.get_desc_node(member)
if(detail_node is not None):
retstr += LINE_BREAKER
retstr += self.get_text(detail_node)
rows = []
rows.append(("Name", "Initializer", "Descritpion"))
for enumvalue in member.iter("enumvalue"):
name = enumvalue.findtext("name")
initializer = enumvalue.findtext("initializer")
if(not initializer):
initializer = ""
desc = self.get_text(enumvalue.find("briefdescription"))
desc += self.get_text(enumvalue.find("detaileddescription"))
if(not desc):
desc = ""
rows.append((name, initializer, desc))
if(len(rows) > 1):
retstr += self._build_table(rows)
return retstr
def _build_struct(self, node):
retstr = ""
detail_node = self.get_desc_node(node)
if(detail_node is not None):
retstr += self.get_text(detail_node) + LINE_BREAKER
rows = []
rows.append(("Name", "Type", "Descritpion"))
for member in node.iter("memberdef"):
if(member.attrib["kind"] == "variable"):
name = member.findtext("name")
type = self._find_text_ref(member.find("type"))
desc = self.get_text(member.find("briefdescription"))
desc += self.get_text(member.find("detaileddescription"))
desc += self.get_text(member.find("inbodydescription"))
if(not desc):
desc = ""
rows.append((name, type, desc))
if(len(rows) > 1):
retstr += self._build_table(rows)
return retstr
def _build_class(self, node):
retstr = ""
for member in node.iter("memberdef"):
if(member.attrib["kind"] == "function"):
retstr += self.build_function(member)
return retstr
def get_desc_node(self, member):
detail_node = member.find("detaileddescription")
brief_node = member.find("briefdescription")
detail_txt = ""
if(detail_node == None and brief_node == None):
return None
if(detail_node is not None):
detail_txt = detail_node.findtext("para")
if(not detail_txt and brief_node != None):
detail_txt = brief_node.findtext("para")
detail_node = brief_node
return detail_node
def build_function(self, member):
retstr = ""
desc_node = self.get_desc_node(member)
if(desc_node is None):
return ""
detail_txt = desc_node.findtext("para")
if(not detail_txt or detail_txt.strip() == "{ignore}"):
return ""
func_id = member.attrib["id"]
page_id, ref_id = get_page(func_id)
retstr += self._build_title(member.findtext("name"), '-', ref = ref_id)
retstr += self.get_text(desc_node)
retstr += LINE_BREAKER
detail_node = member.find("detaileddescription")
if(desc_node != detail_node):
retstr += self.get_text(detail_node)
retstr += self.build_param_list(member.iter("param"), detail_node.iter("parameteritem"))
return retstr
def _build_missed_types_and_structs(self):
fout = open(os.path.join(self.output_dir, self.missing_filename), 'w+')
fout.write(".. contents:: " + LINE_BREAKER)
fout.write(" :local:" + LINE_BREAKER)
fout.write(" :depth: 2" + LINE_BREAKER + LINE_BREAKER)
footnote = ""
while (len(self.missed_types_structs) > 0):
for key, value in self.missed_types_structs.iteritems():
fout.write(self.covert_item(value[0], key, value[1]))
#print(value)
self.missed_types_structs = {}
footnote += self._build_page_ref_notes()
fout.write(footnote)
fout.close()
def _build_page_ref_notes(self):
retstr = LINE_BREAKER
#TODO
for key, value in self.page_references.iteritems():
page, tag = get_page(value[0])
m = re.search("_8h_", page)
if(m):
continue;
rstname = None
anchor = value[2].lower()
if not page in self.references:
self.missed_types_structs[value[0]] = (page, tag)
rstname = os.path.splitext(self.missing_filename)[0]
else:
rstname = self.references[page][2]
anchor = self.references[page][4]
#if(tag and not self.is_github):
# anchor = self.anchor_prefix + "ref-" + tag
retstr += ".. _" + key + ": " + rstname + self.page_ext + "#" + anchor
retstr += LINE_BREAKER + LINE_BREAKER
self.page_references = {}
return retstr
def _build_item_by_id(self, node, id):
retstr = ""
for member in node.iter("memberdef"):
if(member.attrib["id"] != id):
continue
if(member.attrib["kind"] == "enum"):
retstr += self._build_enum(member)
return retstr
def covert_item(self, compound, id, tag):
xml_path = os.path.join(self.doxy_output_dir, "%s.xml" % compound)
print("covert_item: id=%s, name=%s" % (id, xml_path))
obj_root = etree.parse(xml_path).getroot()
retstr = ""
compound = obj_root.find("compounddef")
compound_kind = compound.attrib["kind"]
if(not tag):
retstr += self._build_title(compound.findtext("compoundname"))
if(compound_kind == "class"):
retstr += self._build_class(compound)
elif(compound_kind == "struct"):
retstr += self._build_struct(compound)
else:
retstr += self._build_item_by_id(compound, id)
return retstr
def _build_page(self, compound):
retstr = ""
retstr += self.get_text(compound.find("detaileddescription"))
return retstr
def _build_file(self, compound, type, ref_id, name):
retstr = ""
for member in compound.iter("memberdef"):
if(member.attrib["kind"] == "function" and member.attrib["id"] == ref_id):
retstr += self.build_function(member)
return retstr
def convert_doxy(self, type, name):
#print(name)
file = ref_id = self.name_refid_map[name]
dst_kind = type
if(type == "function"):
file, tag = get_page(ref_id)
dst_kind = "file"
xml_path = os.path.join(self.doxy_output_dir, "%s.xml" % file)
print("convert_doxy: type=%s, name=%s" % (type, xml_path))
obj_root = etree.parse(xml_path).getroot()
compound = obj_root.find("compounddef")
compound_kind = compound.attrib["kind"]
assert(dst_kind == compound_kind)
retstr = ""
if(compound_kind == "class"):
retstr += self._build_class(compound)
elif(compound_kind == "struct"):
retstr += self._build_struct(compound)
elif(compound_kind == "page"):
retstr += self._build_page(compound)
elif(compound_kind == "group"):
retstr += self._build_page(compound)
elif(compound_kind == "file"):
retstr += self._build_file(compound, type, ref_id, name)
return retstr
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-g", "--github", action="store_true", help="Render the link in format of github wiki.")
parser.add_argument("-e", "--ext", default="", help="extension for github wiki")
parser.add_argument("-i", "--input", default="doxygen", help="Input file path of doxygen output and source rst file.")
parser.add_argument("-o", "--output", default="wikipage", help="Output converted restructured text files to path.")
parser.add_argument("-s", "--struct", default="TypesAndStructures.rest", help="Output of auto generated enum and structures.")
parser.add_argument("-u", "--uml", action="store_true", help="Enable UML, you need to download plantuml.jar from Plantuml and put it to here. http://plantuml.sourceforge.net/")
args = parser.parse_args()
ext = ""
if(len(args.ext) > 0):
ext = ("." + args.ext)
agent = DoxyGen2RST(args.input,
args.output,
args.struct,
is_github = True,
enable_uml = args.uml,
github_ext = ext)
agent.generate()