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+
8+static 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+
33+static 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+
45+static 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+
160+BaseThreadDecoderTest::BaseThreadDecoderTest()
161+ : decoder_ (NULL), uiTimeStamp (0), pYuvFile (NULL), bEnableYuvDumpTest (false), decodeStatus_ (OpenFile) {
162+}
163+
164+int32_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+
186+void BaseThreadDecoderTest::TearDown() {
187+ if (decoder_ != NULL) {
188+ decoder_->Uninitialize();
189+ WelsDestroyDecoder (decoder_);
190+ }
191+}
192+
193+
194+void 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+}
233+void 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+}
271+bool 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+
319+bool 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+
330+bool 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