History

add thread decoding unit test.

xiaotian.shi committed 6 years ago

Commit 16a9ed81 parent ffdf9126 files · +585 −0Browse files

Showing the changes to test/api/BaseThreadDecoderTest.cpp (1 of 6 files). Show all

Unified · Split

test/api/BaseThreadDecoderTest.cpp+359−0
@@ -0,0 +1,359 @@
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 "BaseThreadDecoderTest.h"
7
8static void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight) {
9 int i;
10 unsigned char* pPtr = NULL;
11
12 pPtr = pData[0];
13 for (i = 0; i < iHeight; i++) {
14 fwrite (pPtr, 1, iWidth, pFp);
15 pPtr += iStride[0];
16 }
17
18 iHeight = iHeight / 2;
19 iWidth = iWidth / 2;
20 pPtr = pData[1];
21 for (i = 0; i < iHeight; i++) {
22 fwrite (pPtr, 1, iWidth, pFp);
23 pPtr += iStride[1];
24 }
25
26 pPtr = pData[2];
27 for (i = 0; i < iHeight; i++) {
28 fwrite (pPtr, 1, iWidth, pFp);
29 pPtr += iStride[1];
30 }
31}
32
33static void Process (SBufferInfo* pInfo, FILE* pFp) {
34 if (pFp && pInfo->pDst[0] && pInfo->pDst[1] && pInfo->pDst[2] && pInfo) {
35 int iStride[2];
36 int iWidth = pInfo->UsrData.sSystemBuffer.iWidth;
37 int iHeight = pInfo->UsrData.sSystemBuffer.iHeight;
38 iStride[0] = pInfo->UsrData.sSystemBuffer.iStride[0];
39 iStride[1] = pInfo->UsrData.sSystemBuffer.iStride[1];
40
41 Write2File (pFp, (unsigned char**)pInfo->pDst, iStride, iWidth, iHeight);
42 }
43}
44
45static bool ReadFrame (std::ifstream* file, BufferedData* buf) {
46 // start code of a frame is {0, 0, 1} or {0, 0, 0, 1}
47 char b;
48
49 buf->Clear();
50 int32_t sps_count = 0;
51 int32_t non_idr_pict_count = 0;
52 int32_t idr_pict_count = 0;
53 int32_t zeroCount = 0;
54 for (;;) {
55 file->read (&b, 1);
56 if (file->gcount() != 1) { // end of file
57 return true;
58 }
59 if (!buf->PushBack (b)) {
60 std::cout << "unable to allocate memory" << std::endl;
61 return false;
62 }
63 if (buf->Length() < 5) {
64 continue;
65 }
66 uint8_t nal_unit_type = 0;
67 int32_t startcode_len_plus_one = 0;
68 if (buf->Length() == 5) {
69 if (buf->data()[2] == 1) {
70 nal_unit_type = buf->data()[3] & 0x1F;
71 } else {
72 nal_unit_type = buf->data()[4] & 0x1F;
73 }
74 } else {
75 if (zeroCount < 2) {
76 zeroCount = b != 0 ? 0 : zeroCount + 1;
77 }
78 if (zeroCount == 2) {
79 file->read (&b, 1);
80 if (file->gcount() != 1) { // end of file
81 return true;
82 }
83 if (!buf->PushBack (b)) {
84 std::cout << "unable to allocate memory" << std::endl;
85 return false;
86 }
87 if (b == 1) { //0x000001
88 file->read (&b, 1);
89 if (file->gcount() != 1) { // end of file
90 return true;
91 }
92 if (!buf->PushBack (b)) {
93 std::cout << "unable to allocate memory" << std::endl;
94 return false;
95 }
96 nal_unit_type = b & 0x1F;
97 startcode_len_plus_one = 4;
98 zeroCount = 0;
99 } else if (b == 0) {
100 file->read (&b, 1);
101 if (file->gcount() != 1) { // end of file
102 return true;
103 }
104 if (!buf->PushBack (b)) {
105 std::cout << "unable to allocate memory" << std::endl;
106 return false;
107 }
108 if (b == 1) { //0x00000001
109 file->read (&b, 1);
110 if (file->gcount() != 1) { // end of file
111 return true;
112 }
113 if (!buf->PushBack (b)) {
114 std::cout << "unable to allocate memory" << std::endl;
115 return false;
116 }
117 nal_unit_type = b & 0x1F;
118 startcode_len_plus_one = 5;
119 zeroCount = 0;
120 } else {
121 zeroCount = 0;
122 }
123 } else {
124 zeroCount = 0;
125 }
126 }
127 }
128 if (nal_unit_type == 1) {
129 if (++non_idr_pict_count == 1 && idr_pict_count == 1) {
130 file->seekg (-startcode_len_plus_one, file->cur).good();
131 buf->SetLength (buf->Length() - startcode_len_plus_one);
132 return true;
133 }
134 if (non_idr_pict_count == 2) {
135 file->seekg (-startcode_len_plus_one, file->cur).good();
136 buf->SetLength (buf->Length() - startcode_len_plus_one);
137 return true;
138 }
139 } else if (nal_unit_type == 5) {
140 if (++idr_pict_count == 1 && non_idr_pict_count == 1) {
141 file->seekg (-startcode_len_plus_one, file->cur).good();
142 buf->SetLength (buf->Length() - startcode_len_plus_one);
143 return true;
144 }
145 if (idr_pict_count == 2) {
146 file->seekg (-startcode_len_plus_one, file->cur).good();
147 buf->SetLength (buf->Length() - startcode_len_plus_one);
148 return true;
149 }
150 } else if (nal_unit_type == 7) {
151 if ((++sps_count == 1) && (non_idr_pict_count == 1 || idr_pict_count == 1)) {
152 file->seekg (-startcode_len_plus_one, file->cur).good();
153 buf->SetLength (buf->Length() - startcode_len_plus_one);
154 return true;
155 }
156 }
157 }
158}
159
160BaseThreadDecoderTest::BaseThreadDecoderTest()
161 : decoder_ (NULL), uiTimeStamp (0), pYuvFile (NULL), bEnableYuvDumpTest (false), decodeStatus_ (OpenFile) {
162}
163
164int32_t BaseThreadDecoderTest::SetUp() {
165 long rv = WelsCreateDecoder (&decoder_);
166 EXPECT_EQ (0, rv);
167 EXPECT_TRUE (decoder_ != NULL);
168 if (decoder_ == NULL) {
169 return rv;
170 }
171
172 SDecodingParam decParam;
173 memset (&decParam, 0, sizeof (SDecodingParam));
174 decParam.uiTargetDqLayer = UCHAR_MAX;
175 decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
176 decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
177 int iThreadCount = (rand() % 2) + 2;
178 fprintf (stderr, "iThreadCount=%d\n", iThreadCount);
179 decoder_->SetOption (DECODER_OPTION_NUM_OF_THREADS, &iThreadCount);
180
181 rv = decoder_->Initialize (&decParam);
182 EXPECT_EQ (0, rv);
183 return (int32_t)rv;
184}
185
186void BaseThreadDecoderTest::TearDown() {
187 if (decoder_ != NULL) {
188 decoder_->Uninitialize();
189 WelsDestroyDecoder (decoder_);
190 }
191}
192
193
194void BaseThreadDecoderTest::DecodeFrame (const uint8_t* src, size_t sliceSize, Callback* cbk) {
195 SBufferInfo bufInfo;
196 memset (pData, 0, sizeof (pData));
197 memset (&bufInfo, 0, sizeof (SBufferInfo));
198 bufInfo.uiInBsTimeStamp = ++uiTimeStamp;
199
200 DECODING_STATE rv = decoder_->DecodeFrameNoDelay (src, (int) sliceSize, pData, &bufInfo);
201 ASSERT_TRUE (rv == dsErrorFree);
202 sBufInfo = bufInfo;
203 if (sBufInfo.iBufferStatus == 1 && cbk != NULL) {
204 if (bEnableYuvDumpTest) {
205 Process (&sBufInfo, pYuvFile);
206 }
207 const Frame frame = {
208 {
209 // y plane
210 sBufInfo.pDst[0],
211 bufInfo.UsrData.sSystemBuffer.iWidth,
212 bufInfo.UsrData.sSystemBuffer.iHeight,
213 bufInfo.UsrData.sSystemBuffer.iStride[0]
214 },
215 {
216 // u plane
217 sBufInfo.pDst[1],
218 sBufInfo.UsrData.sSystemBuffer.iWidth / 2,
219 sBufInfo.UsrData.sSystemBuffer.iHeight / 2,
220 sBufInfo.UsrData.sSystemBuffer.iStride[1]
221 },
222 {
223 // v plane
224 sBufInfo.pDst[2],
225 sBufInfo.UsrData.sSystemBuffer.iWidth / 2,
226 sBufInfo.UsrData.sSystemBuffer.iHeight / 2,
227 sBufInfo.UsrData.sSystemBuffer.iStride[1]
228 },
229 };
230 cbk->onDecodeFrame (frame);
231 }
232}
233void BaseThreadDecoderTest::FlushFrame (Callback* cbk) {
234 SBufferInfo bufInfo;
235 memset (pData, 0, sizeof (pData));
236 memset (&bufInfo, 0, sizeof (SBufferInfo));
237
238 DECODING_STATE rv = decoder_->FlushFrame (pData, &bufInfo);
239 ASSERT_TRUE (rv == dsErrorFree);
240 sBufInfo = bufInfo;
241 if (sBufInfo.iBufferStatus == 1 && cbk != NULL) {
242 if (bEnableYuvDumpTest) {
243 Process (&sBufInfo, pYuvFile);
244 }
245 const Frame frame = {
246 {
247 // y plane
248 sBufInfo.pDst[0],
249 sBufInfo.UsrData.sSystemBuffer.iWidth,
250 sBufInfo.UsrData.sSystemBuffer.iHeight,
251 sBufInfo.UsrData.sSystemBuffer.iStride[0]
252 },
253 {
254 // u plane
255 sBufInfo.pDst[1],
256 sBufInfo.UsrData.sSystemBuffer.iWidth / 2,
257 sBufInfo.UsrData.sSystemBuffer.iHeight / 2,
258 sBufInfo.UsrData.sSystemBuffer.iStride[1]
259 },
260 {
261 // v plane
262 sBufInfo.pDst[2],
263 sBufInfo.UsrData.sSystemBuffer.iWidth / 2,
264 sBufInfo.UsrData.sSystemBuffer.iHeight / 2,
265 sBufInfo.UsrData.sSystemBuffer.iStride[1]
266 },
267 };
268 cbk->onDecodeFrame (frame);
269 }
270}
271bool BaseThreadDecoderTest::ThreadDecodeFile (const char* fileName, Callback* cbk) {
272 std::ifstream file (fileName, std::ios::in | std::ios::binary);
273 if (!file.is_open())
274 return false;
275
276 std::string outFileName = std::string (fileName);
277 size_t pos = outFileName.find_last_of (".");
278 if (bEnableYuvDumpTest) {
279 outFileName = outFileName.substr (0, pos) + std::string (".yuv");
280 pYuvFile = fopen (outFileName.c_str(), "wb");
281 }
282
283 int iBufIndex = 0;
284 uiTimeStamp = 0;
285 memset (&sBufInfo, 0, sizeof (SBufferInfo));
286 while (true) {
287 if (false == ReadFrame (&file, &buf[iBufIndex]))
288 return false;
289 if (::testing::Test::HasFatalFailure()) {
290 return false;
291 }
292 if (buf[iBufIndex].Length() == 0) {
293 break;
294 }
295 DecodeFrame (buf[iBufIndex].data(), buf[iBufIndex].Length(), cbk);
296 if (::testing::Test::HasFatalFailure()) {
297 return false;
298 }
299 if (++iBufIndex >= 16) {
300 iBufIndex = 0;
301 }
302 }
303
304 int32_t iEndOfStreamFlag = 1;
305 decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
306
307 // Flush out last frames in decoder buffer
308 int32_t num_of_frames_in_buffer = 0;
309 decoder_->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer);
310 for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) {
311 FlushFrame (cbk);
312 }
313 if (bEnableYuvDumpTest) {
314 fclose (pYuvFile);
315 }
316 return true;
317}
318
319bool BaseThreadDecoderTest::Open (const char* fileName) {
320 if (decodeStatus_ == OpenFile) {
321 file_.open (fileName, std::ios_base::out | std::ios_base::binary);
322 if (file_.is_open()) {
323 decodeStatus_ = Decoding;
324 return true;
325 }
326 }
327 return false;
328}
329
330bool BaseThreadDecoderTest::DecodeNextFrame (Callback* cbk) {
331 switch (decodeStatus_) {
332 case Decoding:
333 if (false == ReadFrame (&file_, &buf_))
334 return false;
335 if (::testing::Test::HasFatalFailure()) {
336 return false;
337 }
338 if (buf_.Length() == 0) {
339 decodeStatus_ = EndOfStream;
340 return true;
341 }
342 DecodeFrame (buf_.data(), buf_.Length(), cbk);
343 if (::testing::Test::HasFatalFailure()) {
344 return false;
345 }
346 return true;
347 case EndOfStream: {
348 int32_t iEndOfStreamFlag = 1;
349 decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag);
350 DecodeFrame (NULL, 0, cbk);
351 decodeStatus_ = End;
352 break;
353 }
354 case OpenFile:
355 case End:
356 break;
357 }
358 return false;
359}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t