Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
825ce5dcd9 | ||
![]() |
6f9624790c | ||
![]() |
ca0ed2a067 | ||
![]() |
be97ccb45b | ||
![]() |
6e56e80a8a | ||
![]() |
4f7602e268 | ||
![]() |
d6ff4304fa |
BIN
OpenH264_API_v1.2.0.docx
Normal file
BIN
OpenH264_API_v1.2.0.docx
Normal file
Binary file not shown.
21
RELEASES
21
RELEASES
@ -1,5 +1,16 @@
|
||||
|
||||
Releases
|
||||
-----------
|
||||
v1.2.0
|
||||
------
|
||||
- Add and modify encoder APIs related to rate control and screen content encoding
|
||||
- Remove PauseFrame in encoder APIs
|
||||
- Improve rate control and compression ratio for screen content encoding
|
||||
- Improve error concealment algorithm
|
||||
- Improve validation of input parameters
|
||||
- Add ARM64 assembly
|
||||
- bug fixes
|
||||
|
||||
-----------
|
||||
v1.1.0
|
||||
------
|
||||
@ -15,6 +26,16 @@ Binaries
|
||||
These binary releases are distributed under this license:
|
||||
http://www.openh264.org/BINARY_LICENSE.txt
|
||||
|
||||
v1.2.0
|
||||
------
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-android19.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux32.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux64.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx32.dylib.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx64.dylib.bz2
|
||||
http://ciscobinary.openh264.org/openh264-1.2.0-win32msvc.dll.bz2
|
||||
http://ciscobinary.openh264.org/openh264-1.2.0-win64msvc.dll.bz2
|
||||
|
||||
v1.1.0
|
||||
------
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-android19.so.bz2
|
||||
|
@ -461,8 +461,8 @@ typedef struct TagParserBsInfo {
|
||||
} SParserBsInfo, PParserBsInfo;
|
||||
|
||||
typedef struct TagVideoEncoderStatistics {
|
||||
unsigned int uWidth; // the width of encoded frame
|
||||
unsigned int uHeight; // 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
|
||||
|
||||
@ -475,23 +475,23 @@ typedef struct TagVideoEncoderStatistics {
|
||||
unsigned int uiSkippedFrameCount; // number of frames
|
||||
|
||||
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||
unsigned int uIDRReqNum; // number of IDR requests
|
||||
unsigned int uIDRSentNum; // number of actual IDRs sent
|
||||
unsigned int uLTRSentNum; // number of LTR sent/marked
|
||||
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
|
||||
|
||||
typedef struct TagVideoDecoderStatistics {
|
||||
unsigned int uWidth; // the width of encode/decode frame
|
||||
unsigned int uHeight; // the height of encode/decode frame
|
||||
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
|
||||
uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
|
||||
unsigned int uIDRReqNum; // number of actual IDR request
|
||||
unsigned int uLTRReqNum; // number of actual LTR request
|
||||
unsigned int uIDRRecvNum; // number of actual IDR received
|
||||
unsigned int uiIDRReqNum; // number of actual IDR request
|
||||
unsigned int uiLTRReqNum; // number of actual LTR request
|
||||
unsigned int uiIDRRecvNum; // number of actual IDR received
|
||||
} SDecoderStatistics; // in building, coming soon
|
||||
|
||||
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#define VERSION_NUMBER "openh264 default: 1.1"
|
||||
#define VERSION_NUMBER "openh264 default: 1.2"
|
||||
|
||||
#endif // VERSION_H
|
||||
|
@ -399,9 +399,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, MB_WIDTH_LUMA,
|
||||
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, 0,
|
||||
iPicWidth); // frame width
|
||||
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, MB_HEIGHT_LUMA,
|
||||
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, 0,
|
||||
iPicHeight);// frame height
|
||||
|
||||
pSpatialLayer->iSpatialBitrate =
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -716,7 +716,7 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
|
||||
==
|
||||
SM_DYN_SLICE);
|
||||
|
||||
assert (kiSliceIdx == pCurSlice->uiSliceIdx);
|
||||
assert (kiSliceIdx == (int) pCurSlice->uiSliceIdx);
|
||||
|
||||
if (I_SLICE == pEncCtx->eSliceType) {
|
||||
pNalHeadExt->bIdrFlag = 1;
|
||||
@ -882,7 +882,7 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
|
||||
}
|
||||
const bool kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
|
||||
pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
|
||||
const bool kbSliceIdxNotExceedConstraint = (pCurSlice->uiSliceIdx + kiActiveThreadsNum) <
|
||||
const bool kbSliceIdxNotExceedConstraint = ((int) pCurSlice->uiSliceIdx + kiActiveThreadsNum) <
|
||||
pSliceCtx->iMaxSliceNumConstraint;
|
||||
const bool kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
|
||||
pSliceCtx->iMaxSliceNumConstraint);
|
||||
|
@ -598,13 +598,13 @@ void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVid
|
||||
SEncoderStatistics* pStatistics = & (m_pEncContext->sEncoderStatistics);
|
||||
|
||||
int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
|
||||
if ((0 != pStatistics->uWidth && 0 != pStatistics->uHeight)
|
||||
&& (pStatistics->uWidth != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth
|
||||
|| pStatistics->uHeight != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight)) {
|
||||
if ((0 != pStatistics->uiWidth && 0 != pStatistics->uiHeight)
|
||||
&& (pStatistics->uiWidth != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth
|
||||
|| pStatistics->uiHeight != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight)) {
|
||||
pStatistics->uiResolutionChangeTimes ++;
|
||||
}
|
||||
pStatistics->uWidth = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth;
|
||||
pStatistics->uHeight = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight;
|
||||
pStatistics->uiWidth = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth;
|
||||
pStatistics->uiHeight = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight;
|
||||
|
||||
int32_t iProcessedFrameCount = pStatistics->uiInputFrameCount - pStatistics->uiSkippedFrameCount;
|
||||
const bool kbCurrentFrameSkipped = (videoFrameTypeSkip == eFrameType);
|
||||
@ -626,21 +626,24 @@ void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVid
|
||||
pStatistics->uiBitRate = m_pEncContext->pWelsSvcRc->iActualBitRate; //TODO: finish the calculation in RC
|
||||
|
||||
if (videoFrameTypeIDR == eFrameType || videoFrameTypeI == eFrameType) {
|
||||
pStatistics->uIDRSentNum ++;
|
||||
pStatistics->uiIDRSentNum ++;
|
||||
}
|
||||
if (m_pEncContext->pLtr->bLTRMarkingFlag) {
|
||||
pStatistics->uLTRSentNum ++;
|
||||
pStatistics->uiLTRSentNum ++;
|
||||
}
|
||||
//TODO: update uIDRSentNum in forceIDR
|
||||
//TODO: update uiIDRReqNum in forceIDR
|
||||
|
||||
if (m_pEncContext->iStatisticsLogInterval > 0) {
|
||||
if (WELS_ABS (kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs) > m_pEncContext->iStatisticsLogInterval) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||
"EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=%f, LatestBitRate=%d, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=%d",
|
||||
pStatistics->uWidth, pStatistics->uHeight, pStatistics->fAverageFrameSpeedInMs,
|
||||
pStatistics->fAverageFrameRate, pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
|
||||
"EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=NA, LatestBitRate=NA, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=NA",
|
||||
pStatistics->uiWidth, pStatistics->uiHeight,
|
||||
pStatistics->fAverageFrameSpeedInMs, pStatistics->fAverageFrameRate,
|
||||
pStatistics->uiInputFrameCount, pStatistics->uiSkippedFrameCount,
|
||||
pStatistics->uiResolutionChangeTimes, pStatistics->uIDRReqNum, pStatistics->uIDRSentNum, pStatistics->uLTRSentNum);
|
||||
pStatistics->uiResolutionChangeTimes, pStatistics->uiIDRSentNum, pStatistics->uiLTRSentNum);
|
||||
//TODO: the following statistics will be calculated and added later
|
||||
//pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
|
||||
//pStatistics->uiIDRReqNum,
|
||||
m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
|
||||
}
|
||||
}
|
||||
@ -1103,8 +1106,8 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
break;
|
||||
case ENCODER_OPTION_GET_STATISTICS: {
|
||||
SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption));
|
||||
pStatistics->uWidth = m_pEncContext->sEncoderStatistics.uWidth;
|
||||
pStatistics->uHeight = m_pEncContext->sEncoderStatistics.uHeight;
|
||||
pStatistics->uiWidth = m_pEncContext->sEncoderStatistics.uiWidth;
|
||||
pStatistics->uiHeight = m_pEncContext->sEncoderStatistics.uiHeight;
|
||||
pStatistics->fAverageFrameSpeedInMs = m_pEncContext->sEncoderStatistics.fAverageFrameSpeedInMs;
|
||||
|
||||
// rate control related
|
||||
@ -1116,9 +1119,9 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
pStatistics->uiSkippedFrameCount = m_pEncContext->sEncoderStatistics.uiSkippedFrameCount;
|
||||
|
||||
pStatistics->uiResolutionChangeTimes = m_pEncContext->sEncoderStatistics.uiResolutionChangeTimes;
|
||||
pStatistics->uIDRReqNum = m_pEncContext->sEncoderStatistics.uIDRReqNum;
|
||||
pStatistics->uIDRSentNum = m_pEncContext->sEncoderStatistics.uIDRSentNum;
|
||||
pStatistics->uLTRSentNum = m_pEncContext->sEncoderStatistics.uLTRSentNum;
|
||||
pStatistics->uiIDRReqNum = m_pEncContext->sEncoderStatistics.uiIDRReqNum;
|
||||
pStatistics->uiIDRSentNum = m_pEncContext->sEncoderStatistics.uiIDRSentNum;
|
||||
pStatistics->uiLTRSentNum = m_pEncContext->sEncoderStatistics.uiLTRSentNum;
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
|
||||
|
@ -1668,7 +1668,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) {
|
||||
encToDecData (info, len);
|
||||
unsigned char* pData[3] = { NULL };
|
||||
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||
if (iIdx < strlen (p.pLossSequence)) {
|
||||
if (iIdx < (int) strlen (p.pLossSequence)) {
|
||||
switch (p.pLossSequence[iIdx]) {
|
||||
case '0':
|
||||
iTarDid = 0;
|
||||
|
@ -64,6 +64,7 @@ class EncoderInterfaceTest : public ::testing::Test {
|
||||
void EncodeOneFrame (SEncParamBase* pEncParamBase);
|
||||
void PrepareOneSrcFrame();
|
||||
void EncodeOneIDRandP (ISVCEncoder* pPtrEnc);
|
||||
void ChangeResolutionAndCheckStatistics (const SEncParamBase& sEncParamBase, SEncoderStatistics* pEncoderStatistics);
|
||||
|
||||
public:
|
||||
ISVCEncoder* pPtrEnc;
|
||||
@ -662,6 +663,46 @@ TEST_F (EncoderInterfaceTest, BasicReturnTypeTest) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void EncoderInterfaceTest::ChangeResolutionAndCheckStatistics (const SEncParamBase& sEncParamBase,
|
||||
SEncoderStatistics* pEncoderStatistics) {
|
||||
unsigned int uiExistingFrameCount = pEncoderStatistics->uiInputFrameCount;
|
||||
unsigned int uiExistingIDR = pEncoderStatistics->uiIDRSentNum;
|
||||
unsigned int uiExistingResolutionChange = pEncoderStatistics->uiResolutionChangeTimes;
|
||||
|
||||
// 1, get the existing param
|
||||
int iResult = pPtrEnc->GetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
|
||||
// 2, change setting
|
||||
unsigned int uiKnownResolutionChangeTimes = uiExistingResolutionChange;
|
||||
bool bCheckIDR = false;
|
||||
if (pParamExt->iPicWidth != sEncParamBase.iPicWidth || pParamExt->iPicHeight != sEncParamBase.iPicHeight) {
|
||||
uiKnownResolutionChangeTimes += 1;
|
||||
bCheckIDR = true;
|
||||
}
|
||||
pParamExt->iPicWidth = pParamExt->sSpatialLayers[0].iVideoWidth = sEncParamBase.iPicWidth;
|
||||
pParamExt->iPicHeight = pParamExt->sSpatialLayers[0].iVideoHeight = sEncParamBase.iPicHeight;
|
||||
pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
|
||||
// 3, code one frame
|
||||
PrepareOneSrcFrame();
|
||||
iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
iResult = pPtrEnc->GetOption (ENCODER_OPTION_GET_STATISTICS, pEncoderStatistics);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
|
||||
EXPECT_EQ (pEncoderStatistics->uiInputFrameCount, uiExistingFrameCount + 1);
|
||||
EXPECT_EQ (pEncoderStatistics->uiResolutionChangeTimes, uiKnownResolutionChangeTimes);
|
||||
if (bCheckIDR) {
|
||||
EXPECT_EQ (pEncoderStatistics->uiIDRSentNum, uiExistingIDR + 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ (pEncoderStatistics->uiWidth, static_cast<unsigned int> (sEncParamBase.iPicWidth));
|
||||
EXPECT_EQ (pEncoderStatistics->uiHeight, static_cast<unsigned int> (sEncParamBase.iPicHeight));
|
||||
}
|
||||
|
||||
|
||||
TEST_F (EncoderInterfaceTest, GetStatistics) {
|
||||
SEncParamBase sEncParamBase;
|
||||
GetValidEncParamBase (&sEncParamBase);
|
||||
@ -682,41 +723,20 @@ TEST_F (EncoderInterfaceTest, GetStatistics) {
|
||||
iResult = pPtrEnc->GetOption (ENCODER_OPTION_GET_STATISTICS, &sEncoderStatistics);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
EXPECT_EQ (sEncoderStatistics.uiInputFrameCount, static_cast<unsigned int> (2));
|
||||
EXPECT_EQ (sEncoderStatistics.uIDRSentNum, static_cast<unsigned int> (1));
|
||||
EXPECT_EQ (sEncoderStatistics.uiIDRSentNum, static_cast<unsigned int> (1));
|
||||
EXPECT_EQ (sEncoderStatistics.uiResolutionChangeTimes, static_cast<unsigned int> (0));
|
||||
|
||||
EXPECT_EQ (sEncoderStatistics.uWidth, static_cast<unsigned int> (sEncParamBase.iPicWidth));
|
||||
EXPECT_EQ (sEncoderStatistics.uHeight, static_cast<unsigned int> (sEncParamBase.iPicHeight));
|
||||
EXPECT_EQ (sEncoderStatistics.uiWidth, static_cast<unsigned int> (sEncParamBase.iPicWidth));
|
||||
EXPECT_EQ (sEncoderStatistics.uiHeight, static_cast<unsigned int> (sEncParamBase.iPicHeight));
|
||||
|
||||
// try param change
|
||||
// 1, get the existing
|
||||
pPtrEnc->GetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
|
||||
// 2, change the reoslution
|
||||
GetValidEncParamBase (&sEncParamBase);
|
||||
int32_t knownResolutionChangeTimes = 0;
|
||||
if (pParamExt->iPicWidth != sEncParamBase.iPicWidth || pParamExt->iPicHeight != sEncParamBase.iPicHeight) {
|
||||
knownResolutionChangeTimes = 1;
|
||||
}
|
||||
pParamExt->iPicWidth = pParamExt->sSpatialLayers[0].iVideoWidth = sEncParamBase.iPicWidth;
|
||||
pParamExt->iPicHeight = pParamExt->sSpatialLayers[0].iVideoHeight = sEncParamBase.iPicHeight;
|
||||
pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
ChangeResolutionAndCheckStatistics (sEncParamBase, &sEncoderStatistics);
|
||||
|
||||
// 3, code one frame
|
||||
PrepareOneSrcFrame();
|
||||
iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
iResult = pPtrEnc->GetOption (ENCODER_OPTION_GET_STATISTICS, &sEncoderStatistics);
|
||||
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||
|
||||
EXPECT_EQ (sEncoderStatistics.uiInputFrameCount, static_cast<unsigned int> (3));
|
||||
EXPECT_EQ (sEncoderStatistics.uIDRSentNum, static_cast<unsigned int> (2));
|
||||
EXPECT_EQ (sEncoderStatistics.uiResolutionChangeTimes, static_cast<unsigned int> (knownResolutionChangeTimes));
|
||||
|
||||
EXPECT_EQ (sEncoderStatistics.uWidth, static_cast<unsigned int> (sEncParamBase.iPicWidth));
|
||||
EXPECT_EQ (sEncoderStatistics.uHeight, static_cast<unsigned int> (sEncParamBase.iPicHeight));
|
||||
GetValidEncParamBase (&sEncParamBase);
|
||||
sEncParamBase.iPicWidth = (sEncParamBase.iPicWidth % 16) + 1; //try 1~16
|
||||
sEncParamBase.iPicHeight = (sEncParamBase.iPicHeight % 16) + 1; //try 1~16
|
||||
ChangeResolutionAndCheckStatistics (sEncParamBase, &sEncoderStatistics);
|
||||
|
||||
// 4, change log interval
|
||||
int32_t iInterval = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user