• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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