#include <fstream>#include <gtest/gtest.h>#include "codec_def.h"#include "codec_app_def.h"#include "utils/BufferedData.h"#include "BaseDecoderTest.h" static bool ReadFrame (std::ifstream* file, BufferedData* buf) { // start code of a frame is {0, 0, 0, 1} int zeroCount = 0; char b; buf->Clear(); for (;;) { file->read (&b, 1); if (file->gcount() != 1) { // end of file return true; } if (!buf->PushBack (b)) { std::cout << "unable to allocate memory" << std::endl; return false; } if (buf->Length() <= 4) { continue; } if (zeroCount < 3) { zeroCount = b != 0 ? 0 : zeroCount + 1; } else { if (b == 1) { if (file->seekg (-4, file->cur).good()) { if (-1 == buf->SetLength(buf->Length() - 4)) return false; return true; } else { std::cout << "unable to seek file" << std::endl; return false; } } else if (b == 0) { zeroCount = 3; } else { zeroCount = 0; } } }} BaseDecoderTest::BaseDecoderTest() : decoder_ (NULL), decodeStatus_ (OpenFile) {} int32_t BaseDecoderTest::SetUp() { long rv = WelsCreateDecoder (&decoder_); EXPECT_EQ (0, rv); EXPECT_TRUE (decoder_ != NULL); if (decoder_ == NULL) { return rv; } SDecodingParam decParam; memset (&decParam, 0, sizeof (SDecodingParam)); decParam.uiTargetDqLayer = UCHAR_MAX; decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY; decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; rv = decoder_->Initialize (&decParam); EXPECT_EQ (0, rv); return (int32_t)rv;} void BaseDecoderTest::TearDown() { if (decoder_ != NULL) { decoder_->Uninitialize(); WelsDestroyDecoder (decoder_); }} void BaseDecoderTest::DecodeFrame (const uint8_t* src, size_t sliceSize, Callback* cbk) { uint8_t* data[3]; SBufferInfo bufInfo; memset (data, 0, sizeof (data)); memset (&bufInfo, 0, sizeof (SBufferInfo)); DECODING_STATE rv = decoder_->DecodeFrame2 (src, (int) sliceSize, data, &bufInfo); ASSERT_TRUE (rv == dsErrorFree); if (bufInfo.iBufferStatus == 1 && cbk != NULL) { const Frame frame = { { // y plane data[0], bufInfo.UsrData.sSystemBuffer.iWidth, bufInfo.UsrData.sSystemBuffer.iHeight, bufInfo.UsrData.sSystemBuffer.iStride[0] }, { // u plane data[1], bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iStride[1] }, { // v plane data[2], bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iStride[1] }, }; cbk->onDecodeFrame (frame); }}void BaseDecoderTest::FlushFrame (Callback* cbk) { uint8_t* data[3]; SBufferInfo bufInfo; memset (data, 0, sizeof (data)); memset (&bufInfo, 0, sizeof (SBufferInfo)); DECODING_STATE rv = decoder_->FlushFrame (data, &bufInfo); ASSERT_TRUE (rv == dsErrorFree); if (bufInfo.iBufferStatus == 1 && cbk != NULL) { const Frame frame = { { // y plane data[0], bufInfo.UsrData.sSystemBuffer.iWidth, bufInfo.UsrData.sSystemBuffer.iHeight, bufInfo.UsrData.sSystemBuffer.iStride[0] }, { // u plane data[1], bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iStride[1] }, { // v plane data[2], bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iStride[1] }, }; cbk->onDecodeFrame (frame); }}bool BaseDecoderTest::DecodeFile (const char* fileName, Callback* cbk) { std::ifstream file (fileName, std::ios::in | std::ios::binary); if (!file.is_open()) return false; BufferedData buf; while (true) { if (false == ReadFrame(&file, &buf)) return false; if (::testing::Test::HasFatalFailure()) { return false; } if (buf.Length() == 0) { break; } DecodeFrame (buf.data(), buf.Length(), cbk); if (::testing::Test::HasFatalFailure()) { return false; } } int32_t iEndOfStreamFlag = 1; decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag); // Get pending last frame DecodeFrame (NULL, 0, cbk); // Flush out last frames in decoder buffer int32_t num_of_frames_in_buffer = 0; decoder_->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer); for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) { FlushFrame (cbk); } return true;} bool BaseDecoderTest::Open (const char* fileName) { if (decodeStatus_ == OpenFile) { file_.open (fileName, std::ios_base::out | std::ios_base::binary); if (file_.is_open()) { decodeStatus_ = Decoding; return true; } } return false;} bool BaseDecoderTest::DecodeNextFrame (Callback* cbk) { switch (decodeStatus_) { case Decoding: if (false == ReadFrame(&file_, &buf_)) return false; if (::testing::Test::HasFatalFailure()) { return false; } if (buf_.Length() == 0) { decodeStatus_ = EndOfStream; return true; } DecodeFrame (buf_.data(), buf_.Length(), cbk); if (::testing::Test::HasFatalFailure()) { return false; } return true; case EndOfStream: { int32_t iEndOfStreamFlag = 1; decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag); DecodeFrame (NULL, 0, cbk); decodeStatus_ = End; break; } case OpenFile: case End: break; } return false;}
#include <fstream>
#include <gtest/gtest.h>
#include "codec_def.h"
#include "codec_app_def.h"
#include "utils/BufferedData.h"
#include "BaseDecoderTest.h"
static bool ReadFrame (std::ifstream* file, BufferedData* buf) {
// start code of a frame is {0, 0, 0, 1}
int zeroCount = 0;
char b;
buf->Clear();
for (;;) {
file->read (&b, 1);
if (file->gcount() != 1) { // end of file
return true;
}
if (!buf->PushBack (b)) {
std::cout << "unable to allocate memory" << std::endl;
return false;
}
if (buf->Length() <= 4) {
continue;
}
if (zeroCount < 3) {
zeroCount = b != 0 ? 0 : zeroCount + 1;
} else {
if (b == 1) {
if (file->seekg (-4, file->cur).good()) {
if (-1 == buf->SetLength(buf->Length() - 4))
return false;
return true;
} else {
std::cout << "unable to seek file" << std::endl;
return false;
}
} else if (b == 0) {
zeroCount = 3;
} else {
zeroCount = 0;
}
}
}
}
BaseDecoderTest::BaseDecoderTest()
: decoder_ (NULL), decodeStatus_ (OpenFile) {}
int32_t BaseDecoderTest::SetUp() {
long rv = WelsCreateDecoder (&decoder_);
EXPECT_EQ (0, rv);
EXPECT_TRUE (decoder_ != NULL);
if (decoder_ == NULL) {
return rv;
}
SDecodingParam decParam;
memset (&decParam, 0, sizeof (SDecodingParam));
decParam.uiTargetDqLayer = UCHAR_MAX;
decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
rv = decoder_->Initialize (&decParam);
EXPECT_EQ (0, rv);
return (int32_t)rv;
}
void BaseDecoderTest::TearDown() {
if (decoder_ != NULL) {
decoder_->Uninitialize();
WelsDestroyDecoder (decoder_);
}
}
void BaseDecoderTest::DecodeFrame (const uint8_t* src, size_t sliceSize, Callback* cbk) {
uint8_t* data[3];
SBufferInfo bufInfo;
memset (data, 0, sizeof (data));
memset (&bufInfo, 0, sizeof (SBufferInfo));
DECODING_STATE rv = decoder_->DecodeFrame2 (src, (int) sliceSize, data, &bufInfo);
ASSERT_TRUE (rv == dsErrorFree);
if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
const Frame frame = {
{
// y plane
data[0],
bufInfo.UsrData.sSystemBuffer.iWidth,
bufInfo.UsrData.sSystemBuffer.iHeight,
bufInfo.UsrData.sSystemBuffer.iStride[0]
},
{
// u plane
data[1],
bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1]
},
{
// v plane
data[2],
bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1]
},
};
cbk->onDecodeFrame (frame);
}
}
void BaseDecoderTest::FlushFrame (Callback* cbk) {
uint8_t* data[3];
SBufferInfo bufInfo;
memset (data, 0, sizeof (data));
memset (&bufInfo, 0, sizeof (SBufferInfo));
DECODING_STATE rv = decoder_->FlushFrame (data, &bufInfo);
ASSERT_TRUE (rv == dsErrorFree);
if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
const Frame frame = {
{
// y plane
data[0],
bufInfo.UsrData.sSystemBuffer.iWidth,
bufInfo.UsrData.sSystemBuffer.iHeight,
bufInfo.UsrData.sSystemBuffer.iStride[0]
},
{
// u plane
data[1],
bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1]
},
{
// v plane
data[2],
bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1]
},
};
cbk->onDecodeFrame (frame);
}
}
bool BaseDecoderTest::DecodeFile (const char* fileName, Callback* cbk) {
std::ifstream file (fileName, std::ios::in | std::ios::binary);
if (!file.is_open())
return false;
BufferedData buf;
while (true) {
if (false == ReadFrame(&file, &buf))
return false;
if (::testing::Test::HasFatalFailure()) {
return false;
}
if (buf.Length() == 0) {
break;
}
DecodeFrame (buf.data(), buf.Length(), cbk);
if (::testing::Test::HasFatalFailure()) {
return false;
}
}
int32_t iEndOfStreamFlag = 1;
decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
// Get pending last frame
DecodeFrame (NULL, 0, cbk);
// Flush out last frames in decoder buffer
int32_t num_of_frames_in_buffer = 0;
decoder_->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer);
for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) {
FlushFrame (cbk);
}
return true;
}
bool BaseDecoderTest::Open (const char* fileName) {
if (decodeStatus_ == OpenFile) {
file_.open (fileName, std::ios_base::out | std::ios_base::binary);
if (file_.is_open()) {
decodeStatus_ = Decoding;
return true;
}
}
return false;
}
bool BaseDecoderTest::DecodeNextFrame (Callback* cbk) {
switch (decodeStatus_) {
case Decoding:
if (false == ReadFrame(&file_, &buf_))
return false;
if (::testing::Test::HasFatalFailure()) {
return false;
}
if (buf_.Length() == 0) {
decodeStatus_ = EndOfStream;
return true;
}
DecodeFrame (buf_.data(), buf_.Length(), cbk);
if (::testing::Test::HasFatalFailure()) {
return false;
}
return true;
case EndOfStream: {
int32_t iEndOfStreamFlag = 1;
decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
DecodeFrame (NULL, 0, cbk);
decodeStatus_ = End;
break;
}
case OpenFile:
case End:
break;
}
return false;
}