Showing the changes to test/api/BaseThreadDecoderTest.cpp (1 of 3 files). Show all
Unified · Split
| @@ -5,6 +5,102 @@ · 4 unmodified lines | ||
| 5 | 5 | #include "utils/BufferedData.h" |
| 6 | 6 | #include "BaseThreadDecoderTest.h" |
| 7 | 7 | |
| 8 | +static int32_t readBit (uint8_t* pBufPtr, int32_t& curBit) { | |
| 9 | + int nIndex = curBit / 8; | |
| 10 | + int nOffset = curBit % 8 + 1; | |
| 11 | + | |
| 12 | + curBit++; | |
| 13 | + return (pBufPtr[nIndex] >> (8 - nOffset)) & 0x01; | |
| 14 | +} | |
| 15 | + | |
| 16 | +static int32_t readBits (uint8_t* pBufPtr, int32_t& n, int32_t& curBit) { | |
| 17 | + int r = 0; | |
| 18 | + int i; | |
| 19 | + for (i = 0; i < n; i++) { | |
| 20 | + r |= (readBit (pBufPtr, curBit) << (n - i - 1)); | |
| 21 | + } | |
| 22 | + return r; | |
| 23 | +} | |
| 24 | + | |
| 25 | +static int32_t bsGetUe (uint8_t* pBufPtr, int32_t& curBit) { | |
| 26 | + int r = 0; | |
| 27 | + int i = 0; | |
| 28 | + while ((readBit (pBufPtr, curBit) == 0) && (i < 32)) { | |
| 29 | + i++; | |
| 30 | + } | |
| 31 | + r = readBits (pBufPtr, i, curBit); | |
| 32 | + r += (1 << i) - 1; | |
| 33 | + return r; | |
| 34 | +} | |
| 35 | + | |
| 36 | +static int32_t readFirstMbInSlice (uint8_t* pSliceNalPtr) { | |
| 37 | + int32_t curBit = 0; | |
| 38 | + int32_t firstMBInSlice = bsGetUe (pSliceNalPtr + 1, curBit); | |
| 39 | + return firstMBInSlice; | |
| 40 | +} | |
| 41 | + | |
| 42 | +static int32_t ReadFrame (uint8_t* pBuf, const int32_t& iFileSize, const int32_t& bufPos) { | |
| 43 | + int32_t bytes_available = iFileSize - bufPos; | |
| 44 | + if (bytes_available < 4) { | |
| 45 | + return bytes_available; | |
| 46 | + } | |
| 47 | + uint8_t* ptr = pBuf + bufPos; | |
| 48 | + int32_t read_bytes = 0; | |
| 49 | + int32_t sps_count = 0; | |
| 50 | + int32_t pps_count = 0; | |
| 51 | + int32_t non_idr_pict_count = 0; | |
| 52 | + int32_t idr_pict_count = 0; | |
| 53 | + int32_t nal_deliminator = 0; | |
| 54 | + while (read_bytes < bytes_available - 4) { | |
| 55 | + bool has4ByteStartCode = ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 1; | |
| 56 | + bool has3ByteStartCode = false; | |
| 57 | + if (!has4ByteStartCode) { | |
| 58 | + has3ByteStartCode = ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 1; | |
| 59 | + } | |
| 60 | + if (has4ByteStartCode || has3ByteStartCode) { | |
| 61 | + int32_t byteOffset = has4ByteStartCode ? 4 : 3; | |
| 62 | + uint8_t nal_unit_type = has4ByteStartCode ? (ptr[4] & 0x1F) : (ptr[3] & 0x1F); | |
| 63 | + if (nal_unit_type == 1) { | |
| 64 | + int32_t firstMBInSlice = readFirstMbInSlice (ptr + byteOffset); | |
| 65 | + if (++non_idr_pict_count >= 1 && idr_pict_count >= 1 && firstMBInSlice == 0) { | |
| 66 | + return read_bytes; | |
| 67 | + } | |
| 68 | + if (non_idr_pict_count >= 2 && firstMBInSlice == 0) { | |
| 69 | + return read_bytes; | |
| 70 | + } | |
| 71 | + } else if (nal_unit_type == 5) { | |
| 72 | + int32_t firstMBInSlice = readFirstMbInSlice (ptr + byteOffset); | |
| 73 | + if (++idr_pict_count >= 1 && non_idr_pict_count >= 1 && firstMBInSlice == 0) { | |
| 74 | + return read_bytes; | |
| 75 | + } | |
| 76 | + if (idr_pict_count >= 2 && firstMBInSlice == 0) { | |
| 77 | + return read_bytes; | |
| 78 | + } | |
| 79 | + } else if (nal_unit_type == 7) { | |
| 80 | + if ((++sps_count >= 1) && (non_idr_pict_count >= 1 || idr_pict_count >= 1)) { | |
| 81 | + return read_bytes; | |
| 82 | + } | |
| 83 | + if (sps_count == 2) return read_bytes; | |
| 84 | + } else if (nal_unit_type == 8) { | |
| 85 | + if (++pps_count >= 1 && (non_idr_pict_count >= 1 || idr_pict_count >= 1)) return read_bytes; | |
| 86 | + } else if (nal_unit_type == 9) { | |
| 87 | + if (++nal_deliminator == 2) { | |
| 88 | + return read_bytes; | |
| 89 | + } | |
| 90 | + } | |
| 91 | + if (read_bytes >= bytes_available - 4) { | |
| 92 | + return bytes_available; | |
| 93 | + } | |
| 94 | + read_bytes += 4; | |
| 95 | + ptr += 4; | |
| 96 | + } else { | |
| 97 | + ++ptr; | |
| 98 | + ++read_bytes; | |
| 99 | + } | |
| 100 | + } | |
| 101 | + return bytes_available; | |
| 102 | +} | |
| 103 | + | |
| 8 | 104 | static void Write2File (FILE* pFp, unsigned char* pData[3], int iStride[2], int iWidth, int iHeight) { |
| 9 | 105 | int i; |
| 10 | 106 | unsigned char* pPtr = NULL; |
| @@ -42,121 +138,6 @@ static void Process (SBufferInfo* pInfo, FILE* pFp) { · 31 unmodified lines | ||
| 42 | 138 | } |
| 43 | 139 | } |
| 44 | 140 | |
| 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 | 141 | BaseThreadDecoderTest::BaseThreadDecoderTest() |
| 161 | 142 | : decoder_ (NULL), uiTimeStamp (0), pYuvFile (NULL), bEnableYuvDumpTest (false), decodeStatus_ (OpenFile) { |
| 162 | 143 | } |
| @@ -272,6 +253,19 @@ bool BaseThreadDecoderTest::ThreadDecodeFile (const char* fileName, Callback* cb · 109 unmodified lines | ||
| 272 | 253 | if (!file.is_open()) |
| 273 | 254 | return false; |
| 274 | 255 | |
| 256 | + BufferedData buf; | |
| 257 | + char b; | |
| 258 | + for (;;) { | |
| 259 | + file.read (&b, 1); | |
| 260 | + if (file.gcount() != 1) { // end of file | |
| 261 | + break; | |
| 262 | + } | |
| 263 | + if (!buf.PushBack (b)) { | |
| 264 | + std::cout << "unable to allocate memory" << std::endl; | |
| 265 | + return false; | |
| 266 | + } | |
| 267 | + } | |
| 268 | + | |
| 275 | 269 | std::string outFileName = std::string (fileName); |
| 276 | 270 | size_t pos = outFileName.find_last_of ("."); |
| 277 | 271 | if (bEnableYuvDumpTest) { |
| @@ -279,25 +273,23 @@ bool BaseThreadDecoderTest::ThreadDecodeFile (const char* fileName, Callback* cb · 1 unmodified line | ||
| 279 | 273 | pYuvFile = fopen (outFileName.c_str(), "wb"); |
| 280 | 274 | } |
| 281 | 275 | |
| 282 | − int iBufIndex = 0; | |
| 283 | 276 | uiTimeStamp = 0; |
| 284 | 277 | memset (&sBufInfo, 0, sizeof (SBufferInfo)); |
| 285 | − while (true) { | |
| 286 | − if (false == ReadFrame (&file, &buf[iBufIndex])) | |
| 287 | − return false; | |
| 278 | + int32_t bufPos = 0; | |
| 279 | + int32_t bytesConsumed = 0; | |
| 280 | + int32_t fileSize = buf.Length(); | |
| 281 | + while (bytesConsumed < fileSize) { | |
| 282 | + int32_t frameSize = ReadFrame (buf.data(), fileSize, bufPos); | |
| 288 | 283 | if (::testing::Test::HasFatalFailure()) { |
| 289 | 284 | return false; |
| 290 | 285 | } |
| 291 | − if (buf[iBufIndex].Length() == 0) { | |
| 292 | − break; | |
| 293 | − } | |
| 294 | − DecodeFrame (buf[iBufIndex].data(), buf[iBufIndex].Length(), cbk); | |
| 286 | + uint8_t* frame_ptr = buf.data() + bufPos; | |
| 287 | + DecodeFrame (frame_ptr, frameSize, cbk); | |
| 295 | 288 | if (::testing::Test::HasFatalFailure()) { |
| 296 | 289 | return false; |
| 297 | 290 | } |
| 298 | − if (++iBufIndex >= 16) { | |
| 299 | − iBufIndex = 0; | |
| 300 | − } | |
| 291 | + bufPos += frameSize; | |
| 292 | + bytesConsumed += frameSize; | |
| 301 | 293 | } |
| 302 | 294 | |
| 303 | 295 | int32_t iEndOfStreamFlag = 1; |
| @@ -325,34 +317,3 @@ bool BaseThreadDecoderTest::Open (const char* fileName) { · 21 unmodified lines | ||
| 325 | 317 | } |
| 326 | 318 | return false; |
| 327 | 319 | } |
| 328 | − | |
| 329 | −bool BaseThreadDecoderTest::DecodeNextFrame (Callback* cbk) { | |
| 330 | − switch (decodeStatus_) { | |
| 331 | − case Decoding: | |
| 332 | − if (false == ReadFrame (&file_, &buf_)) | |
| 333 | − return false; | |
| 334 | − if (::testing::Test::HasFatalFailure()) { | |
| 335 | − return false; | |
| 336 | − } | |
| 337 | − if (buf_.Length() == 0) { | |
| 338 | − decodeStatus_ = EndOfStream; | |
| 339 | − return true; | |
| 340 | − } | |
| 341 | − DecodeFrame (buf_.data(), buf_.Length(), cbk); | |
| 342 | − if (::testing::Test::HasFatalFailure()) { | |
| 343 | − return false; | |
| 344 | − } | |
| 345 | − return true; | |
| 346 | − case EndOfStream: { | |
| 347 | − int32_t iEndOfStreamFlag = 1; | |
| 348 | − decoder_->SetOption (DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag); | |
| 349 | − DecodeFrame (NULL, 0, cbk); | |
| 350 | − decodeStatus_ = End; | |
| 351 | − break; | |
| 352 | − } | |
| 353 | − case OpenFile: | |
| 354 | − case End: | |
| 355 | − break; | |
| 356 | − } | |
| 357 | − return false; | |
| 358 | −} | |