Merge pull request #1756 from sijchen/savc4
[Encoder] Implementation of bSimulcastAVC and UT
This commit is contained in:
@@ -3020,3 +3020,225 @@ TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TEST_F (EncodeDecodeTestAPI, SimulcastSVC) {
|
||||
#define LAYER_NUM (4)
|
||||
int iSpatialLayerNum = WelsClip3 ((rand() % LAYER_NUM), 2, LAYER_NUM);;
|
||||
int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
|
||||
int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
|
||||
float fFrameRate = rand() + 0.5f;
|
||||
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
||||
int iSliceNum = 1;
|
||||
encoder_->GetDefaultParams (¶m_);
|
||||
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
|
||||
|
||||
int rv = encoder_->InitializeExt (¶m_);
|
||||
ASSERT_TRUE (rv == cmResultSuccess);
|
||||
|
||||
unsigned char* pBsBuf[LAYER_NUM];
|
||||
int aLen[LAYER_NUM] = {0};
|
||||
ISVCDecoder* decoder[LAYER_NUM];
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
FILE* fEnc[LAYER_NUM] = { NULL };
|
||||
fEnc[0] = fopen ("enc0.264", "wb");
|
||||
fEnc[1] = fopen ("enc1.264", "wb");
|
||||
fEnc[2] = fopen ("enc2.264", "wb");
|
||||
fEnc[3] = fopen ("enc3.264", "wb");
|
||||
#endif
|
||||
|
||||
// init decoders
|
||||
int iIdx = 0;
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
|
||||
aLen[iIdx] = 0;
|
||||
|
||||
long rv = WelsCreateDecoder (&decoder[iIdx]);
|
||||
ASSERT_EQ (0, rv);
|
||||
ASSERT_TRUE (decoder[iIdx] != NULL);
|
||||
|
||||
SDecodingParam decParam;
|
||||
memset (&decParam, 0, sizeof (SDecodingParam));
|
||||
decParam.eOutputColorFormat = videoFormatI420;
|
||||
decParam.uiTargetDqLayer = UCHAR_MAX;
|
||||
decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
|
||||
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
|
||||
|
||||
rv = decoder[iIdx]->Initialize (&decParam);
|
||||
ASSERT_EQ (0, rv);
|
||||
}
|
||||
|
||||
for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
|
||||
int iResult;
|
||||
int iLayerLen = 0;
|
||||
unsigned char* pData[3] = { NULL };
|
||||
|
||||
InitialEncDec (param_.iPicWidth, param_.iPicHeight);
|
||||
EncodeOneFrame (0);
|
||||
|
||||
iLayerLen = 0;
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
aLen[iIdx] = 0;
|
||||
}
|
||||
for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
|
||||
iLayerLen = 0;
|
||||
const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
|
||||
for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
|
||||
iLayerLen += layerInfo.pNalLengthInByte[iNal];
|
||||
}
|
||||
|
||||
if (layerInfo.uiLayerType == NON_VIDEO_CODING_LAYER) {
|
||||
// under SimulcastSVC, need to copy non-VCL to all layers
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
|
||||
aLen[iIdx] += iLayerLen;
|
||||
}
|
||||
} else {
|
||||
iIdx = layerInfo.uiSpatialId;
|
||||
EXPECT_TRUE (iIdx < iSpatialLayerNum);
|
||||
memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
|
||||
aLen[iIdx] += iLayerLen;
|
||||
}
|
||||
}
|
||||
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pData[0] = pData[1] = pData[2] = 0;
|
||||
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
|
||||
#endif
|
||||
iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
|
||||
EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
|
||||
iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
|
||||
EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
|
||||
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
|
||||
}
|
||||
}
|
||||
|
||||
// free all
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
if (pBsBuf[iIdx]) {
|
||||
free (pBsBuf[iIdx]);
|
||||
}
|
||||
|
||||
if (decoder[iIdx] != NULL) {
|
||||
decoder[iIdx]->Uninitialize();
|
||||
WelsDestroyDecoder (decoder[iIdx]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE2
|
||||
fclose (fEnc[iIdx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_F (EncodeDecodeTestAPI, SimulcastAVC) {
|
||||
//#define DEBUG_FILE_SAVE3
|
||||
#define LAYER_NUM (4)
|
||||
int iSpatialLayerNum = WelsClip3 ((rand() % LAYER_NUM), 2, LAYER_NUM);;
|
||||
int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
|
||||
int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
|
||||
float fFrameRate = rand() + 0.5f;
|
||||
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
||||
int iSliceNum = 1;
|
||||
encoder_->GetDefaultParams (¶m_);
|
||||
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
|
||||
|
||||
//set flag of bSimulcastAVC
|
||||
param_.bSimulcastAVC = true;
|
||||
|
||||
int rv = encoder_->InitializeExt (¶m_);
|
||||
ASSERT_TRUE (rv == cmResultSuccess);
|
||||
|
||||
unsigned char* pBsBuf[LAYER_NUM];
|
||||
int aLen[LAYER_NUM] = {0};
|
||||
ISVCDecoder* decoder[LAYER_NUM];
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE3
|
||||
FILE* fEnc[LAYER_NUM];
|
||||
fEnc[0] = fopen ("enc0.264", "wb");
|
||||
fEnc[1] = fopen ("enc1.264", "wb");
|
||||
fEnc[2] = fopen ("enc2.264", "wb");
|
||||
fEnc[3] = fopen ("enc3.264", "wb");
|
||||
#endif
|
||||
|
||||
int iIdx = 0;
|
||||
|
||||
//create decoder
|
||||
for (int iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
|
||||
aLen[iIdx] = 0;
|
||||
|
||||
long rv = WelsCreateDecoder (&decoder[iIdx]);
|
||||
ASSERT_EQ (0, rv);
|
||||
ASSERT_TRUE (decoder[iIdx] != NULL);
|
||||
|
||||
SDecodingParam decParam;
|
||||
memset (&decParam, 0, sizeof (SDecodingParam));
|
||||
decParam.eOutputColorFormat = videoFormatI420;
|
||||
decParam.uiTargetDqLayer = UCHAR_MAX;
|
||||
decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
|
||||
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
|
||||
|
||||
rv = decoder[iIdx]->Initialize (&decParam);
|
||||
ASSERT_EQ (0, rv);
|
||||
}
|
||||
|
||||
iEncFrameNum = 1;
|
||||
for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
|
||||
int iResult;
|
||||
int iLayerLen = 0;
|
||||
unsigned char* pData[3] = { NULL };
|
||||
|
||||
InitialEncDec (param_.iPicWidth, param_.iPicHeight);
|
||||
EncodeOneFrame (0);
|
||||
|
||||
// init
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
aLen[iIdx] = 0;
|
||||
}
|
||||
for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
|
||||
iLayerLen = 0;
|
||||
const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
|
||||
for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
|
||||
iLayerLen += layerInfo.pNalLengthInByte[iNal];
|
||||
}
|
||||
|
||||
iIdx = layerInfo.uiSpatialId;
|
||||
EXPECT_TRUE (iIdx < iSpatialLayerNum);
|
||||
memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
|
||||
aLen[iIdx] += iLayerLen;
|
||||
}
|
||||
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
pData[0] = pData[1] = pData[2] = 0;
|
||||
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||
|
||||
#ifdef DEBUG_FILE_SAVE3
|
||||
fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
|
||||
#endif
|
||||
iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
|
||||
EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
|
||||
|
||||
iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
|
||||
EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
|
||||
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
|
||||
free (pBsBuf[iIdx]);
|
||||
|
||||
if (decoder[iIdx] != NULL) {
|
||||
decoder[iIdx]->Uninitialize();
|
||||
WelsDestroyDecoder (decoder[iIdx]);
|
||||
}
|
||||
#ifdef DEBUG_FILE_SAVE3
|
||||
fclose (fEnc[iIdx]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user