openh264/test/api/BaseDecoderTest.cpp

175 lines
4.2 KiB
C++
Raw Normal View History

#include <fstream>
#include <gtest/gtest.h>
#include "codec_def.h"
#include "codec_app_def.h"
#include "utils/BufferedData.h"
#include "BaseDecoderTest.h"
2014-06-26 03:50:41 +02:00
static void ReadFrame (std::ifstream* file, BufferedData* buf) {
// start code of a frame is {0, 0, 0, 1}
int zeroCount = 0;
char b;
buf->Clear();
for (;;) {
2014-06-26 03:50:41 +02:00
file->read (&b, 1);
if (file->gcount() != 1) { // end of file
return;
}
2014-06-26 03:50:41 +02:00
if (!buf->PushBack (b)) {
FAIL() << "unable to allocate memory";
}
if (buf->Length() <= 4) {
continue;
}
if (zeroCount < 3) {
zeroCount = b != 0 ? 0 : zeroCount + 1;
} else {
if (b == 1) {
2014-06-26 03:50:41 +02:00
if (file->seekg (-4, file->cur).good()) {
buf->SetLength (buf->Length() - 4);
return;
} else {
FAIL() << "unable to seek file";
}
} else if (b == 0) {
zeroCount = 3;
} else {
zeroCount = 0;
}
}
}
}
BaseDecoderTest::BaseDecoderTest()
2014-06-26 03:50:41 +02:00
: decoder_ (NULL), decodeStatus_ (OpenFile) {}
void BaseDecoderTest::SetUp() {
2014-06-26 03:50:41 +02:00
long rv = WelsCreateDecoder (&decoder_);
ASSERT_EQ (0, rv);
ASSERT_TRUE (decoder_ != NULL);
SDecodingParam decParam;
2014-06-26 03:50:41 +02:00
memset (&decParam, 0, sizeof (SDecodingParam));
decParam.iOutputColorFormat = videoFormatI420;
decParam.uiTargetDqLayer = UCHAR_MAX;
decParam.uiEcActiveFlag = 1;
decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
2014-06-26 03:50:41 +02:00
rv = decoder_->Initialize (&decParam);
ASSERT_EQ (0, rv);
}
void BaseDecoderTest::TearDown() {
if (decoder_ != NULL) {
decoder_->Uninitialize();
2014-06-26 03:50:41 +02:00
WelsDestroyDecoder (decoder_);
}
}
2014-06-26 03:50:41 +02:00
void BaseDecoderTest::DecodeFrame (const uint8_t* src, int sliceSize, Callback* cbk) {
uint8_t* data[3];
SBufferInfo bufInfo;
2014-06-26 03:50:41 +02:00
memset (data, 0, sizeof (data));
memset (&bufInfo, 0, sizeof (SBufferInfo));
2014-06-26 03:50:41 +02:00
DECODING_STATE rv = decoder_->DecodeFrame2 (src, sliceSize, data, &bufInfo);
ASSERT_TRUE (rv == dsErrorFree);
if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
const Frame frame = {
2014-06-26 03:50:41 +02:00
{
// 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]
},
};
2014-06-26 03:50:41 +02:00
cbk->onDecodeFrame (frame);
}
}
2014-06-26 03:50:41 +02:00
void BaseDecoderTest::DecodeFile (const char* fileName, Callback* cbk) {
std::ifstream file (fileName, std::ios::in | std::ios::binary);
ASSERT_TRUE (file.is_open());
2014-02-05 11:04:32 +01:00
BufferedData buf;
while (true) {
2014-06-26 03:50:41 +02:00
ReadFrame (&file, &buf);
if (::testing::Test::HasFatalFailure()) {
return;
}
if (buf.Length() == 0) {
break;
}
2014-06-26 03:50:41 +02:00
DecodeFrame (buf.data(), buf.Length(), cbk);
if (::testing::Test::HasFatalFailure()) {
return;
}
}
int32_t iEndOfStreamFlag = 1;
2014-06-26 03:50:41 +02:00
decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
// Get pending last frame
2014-06-26 03:50:41 +02:00
DecodeFrame (NULL, 0, cbk);
}
2014-06-26 03:50:41 +02:00
bool BaseDecoderTest::Open (const char* fileName) {
if (decodeStatus_ == OpenFile) {
2014-06-26 03:50:41 +02:00
file_.open (fileName, std::ios_base::out | std::ios_base::binary);
if (file_.is_open()) {
decodeStatus_ = Decoding;
return true;
}
}
return false;
}
2014-06-26 03:50:41 +02:00
bool BaseDecoderTest::DecodeNextFrame (Callback* cbk) {
switch (decodeStatus_) {
case Decoding:
2014-06-26 03:50:41 +02:00
ReadFrame (&file_, &buf_);
if (::testing::Test::HasFatalFailure()) {
return false;
}
if (buf_.Length() == 0) {
decodeStatus_ = EndOfStream;
return true;
}
2014-06-26 03:50:41 +02:00
DecodeFrame (buf_.data(), buf_.Length(), cbk);
if (::testing::Test::HasFatalFailure()) {
return false;
}
return true;
case EndOfStream: {
int32_t iEndOfStreamFlag = 1;
2014-06-26 03:50:41 +02:00
decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
DecodeFrame (NULL, 0, cbk);
decodeStatus_ = End;
break;
}
2014-02-06 04:37:42 +01:00
case OpenFile:
case End:
break;
}
return false;
}