1 #include <fstream>
2 #include <gtest/gtest.h>
3 #include "codec_def.h"
4 #include "codec_app_def.h"
5 #include "utils/BufferedData.h"
6 #include "BaseDecoderTest.h"
7
ReadFrame(std::ifstream * file,BufferedData * buf)8 static bool ReadFrame (std::ifstream* file, BufferedData* buf) {
9 // start code of a frame is {0, 0, 0, 1}
10 int zeroCount = 0;
11 char b;
12
13 buf->Clear();
14 for (;;) {
15 file->read (&b, 1);
16 if (file->gcount() != 1) { // end of file
17 return true;
18 }
19 if (!buf->PushBack (b)) {
20 std::cout << "unable to allocate memory" << std::endl;
21 return false;
22 }
23
24 if (buf->Length() <= 4) {
25 continue;
26 }
27
28 if (zeroCount < 3) {
29 zeroCount = b != 0 ? 0 : zeroCount + 1;
30 } else {
31 if (b == 1) {
32 if (file->seekg (-4, file->cur).good()) {
33 if (-1 == buf->SetLength(buf->Length() - 4))
34 return false;
35 return true;
36 } else {
37 std::cout << "unable to seek file" << std::endl;
38 return false;
39 }
40 } else if (b == 0) {
41 zeroCount = 3;
42 } else {
43 zeroCount = 0;
44 }
45 }
46 }
47 }
48
BaseDecoderTest()49 BaseDecoderTest::BaseDecoderTest()
50 : decoder_ (NULL), decodeStatus_ (OpenFile) {}
51
SetUp()52 int32_t BaseDecoderTest::SetUp() {
53 long rv = WelsCreateDecoder (&decoder_);
54 EXPECT_EQ (0, rv);
55 EXPECT_TRUE (decoder_ != NULL);
56 if (decoder_ == NULL) {
57 return rv;
58 }
59
60 SDecodingParam decParam;
61 memset (&decParam, 0, sizeof (SDecodingParam));
62 decParam.uiTargetDqLayer = UCHAR_MAX;
63 decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
64 decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
65
66 rv = decoder_->Initialize (&decParam);
67 EXPECT_EQ (0, rv);
68 return (int32_t)rv;
69 }
70
TearDown()71 void BaseDecoderTest::TearDown() {
72 if (decoder_ != NULL) {
73 decoder_->Uninitialize();
74 WelsDestroyDecoder (decoder_);
75 }
76 }
77
78
DecodeFrame(const uint8_t * src,size_t sliceSize,Callback * cbk)79 void BaseDecoderTest::DecodeFrame (const uint8_t* src, size_t sliceSize, Callback* cbk) {
80 uint8_t* data[3];
81 SBufferInfo bufInfo;
82 memset (data, 0, sizeof (data));
83 memset (&bufInfo, 0, sizeof (SBufferInfo));
84
85 DECODING_STATE rv = decoder_->DecodeFrame2 (src, (int) sliceSize, data, &bufInfo);
86 ASSERT_TRUE (rv == dsErrorFree);
87
88 if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
89 const Frame frame = {
90 {
91 // y plane
92 data[0],
93 bufInfo.UsrData.sSystemBuffer.iWidth,
94 bufInfo.UsrData.sSystemBuffer.iHeight,
95 bufInfo.UsrData.sSystemBuffer.iStride[0]
96 },
97 {
98 // u plane
99 data[1],
100 bufInfo.UsrData.sSystemBuffer.iWidth / 2,
101 bufInfo.UsrData.sSystemBuffer.iHeight / 2,
102 bufInfo.UsrData.sSystemBuffer.iStride[1]
103 },
104 {
105 // v plane
106 data[2],
107 bufInfo.UsrData.sSystemBuffer.iWidth / 2,
108 bufInfo.UsrData.sSystemBuffer.iHeight / 2,
109 bufInfo.UsrData.sSystemBuffer.iStride[1]
110 },
111 };
112 cbk->onDecodeFrame (frame);
113 }
114 }
FlushFrame(Callback * cbk)115 void BaseDecoderTest::FlushFrame (Callback* cbk) {
116 uint8_t* data[3];
117 SBufferInfo bufInfo;
118 memset (data, 0, sizeof (data));
119 memset (&bufInfo, 0, sizeof (SBufferInfo));
120
121 DECODING_STATE rv = decoder_->FlushFrame (data, &bufInfo);
122 ASSERT_TRUE (rv == dsErrorFree);
123
124 if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
125 const Frame frame = {
126 {
127 // y plane
128 data[0],
129 bufInfo.UsrData.sSystemBuffer.iWidth,
130 bufInfo.UsrData.sSystemBuffer.iHeight,
131 bufInfo.UsrData.sSystemBuffer.iStride[0]
132 },
133 {
134 // u plane
135 data[1],
136 bufInfo.UsrData.sSystemBuffer.iWidth / 2,
137 bufInfo.UsrData.sSystemBuffer.iHeight / 2,
138 bufInfo.UsrData.sSystemBuffer.iStride[1]
139 },
140 {
141 // v plane
142 data[2],
143 bufInfo.UsrData.sSystemBuffer.iWidth / 2,
144 bufInfo.UsrData.sSystemBuffer.iHeight / 2,
145 bufInfo.UsrData.sSystemBuffer.iStride[1]
146 },
147 };
148 cbk->onDecodeFrame (frame);
149 }
150 }
DecodeFile(const char * fileName,Callback * cbk)151 bool BaseDecoderTest::DecodeFile (const char* fileName, Callback* cbk) {
152 std::ifstream file (fileName, std::ios::in | std::ios::binary);
153 if (!file.is_open())
154 return false;
155
156 BufferedData buf;
157 while (true) {
158 if (false == ReadFrame(&file, &buf))
159 return false;
160 if (::testing::Test::HasFatalFailure()) {
161 return false;
162 }
163 if (buf.Length() == 0) {
164 break;
165 }
166 DecodeFrame (buf.data(), buf.Length(), cbk);
167 if (::testing::Test::HasFatalFailure()) {
168 return false;
169 }
170 }
171
172 int32_t iEndOfStreamFlag = 1;
173 decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
174
175 // Get pending last frame
176 DecodeFrame (NULL, 0, cbk);
177 // Flush out last frames in decoder buffer
178 int32_t num_of_frames_in_buffer = 0;
179 decoder_->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer);
180 for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) {
181 FlushFrame (cbk);
182 }
183 return true;
184 }
185
Open(const char * fileName)186 bool BaseDecoderTest::Open (const char* fileName) {
187 if (decodeStatus_ == OpenFile) {
188 file_.open (fileName, std::ios_base::out | std::ios_base::binary);
189 if (file_.is_open()) {
190 decodeStatus_ = Decoding;
191 return true;
192 }
193 }
194 return false;
195 }
196
DecodeNextFrame(Callback * cbk)197 bool BaseDecoderTest::DecodeNextFrame (Callback* cbk) {
198 switch (decodeStatus_) {
199 case Decoding:
200 if (false == ReadFrame(&file_, &buf_))
201 return false;
202 if (::testing::Test::HasFatalFailure()) {
203 return false;
204 }
205 if (buf_.Length() == 0) {
206 decodeStatus_ = EndOfStream;
207 return true;
208 }
209 DecodeFrame (buf_.data(), buf_.Length(), cbk);
210 if (::testing::Test::HasFatalFailure()) {
211 return false;
212 }
213 return true;
214 case EndOfStream: {
215 int32_t iEndOfStreamFlag = 1;
216 decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
217 DecodeFrame (NULL, 0, cbk);
218 decodeStatus_ = End;
219 break;
220 }
221 case OpenFile:
222 case End:
223 break;
224 }
225 return false;
226 }
227