| 92 | } |
| 93 | |
| 94 | QByteArray FileSourceAnnexBFile::getNextNALUnit(bool getLastDataAgain, pairUint64 *startEndPosInFile) |
| 95 | { |
| 96 | if (getLastDataAgain) |
| 97 | return this->lastReturnArray; |
| 98 | |
| 99 | this->lastReturnArray.clear(); |
| 100 | |
| 101 | if (startEndPosInFile) |
| 102 | startEndPosInFile->first = this->bufferStartPosInFile + uint64_t(this->posInBuffer); |
| 103 | |
| 104 | int nextStartCodePos = -1; |
| 105 | int searchOffset = 3; |
| 106 | bool startCodeFound = false; |
| 107 | while (!startCodeFound) |
| 108 | { |
| 109 | if (this->posInBuffer < 0) |
| 110 | { |
| 111 | // Part of the start code was in the last buffer (see special boundary cases below). Add those parts. |
| 112 | const auto nrZeroBytesMissing = std::abs(this->posInBuffer); |
| 113 | this->lastReturnArray.append(nrZeroBytesMissing, char(0)); |
| 114 | } |
| 115 | nextStartCodePos = this->fileBuffer.indexOf(STARTCODE, this->posInBuffer + searchOffset); |
| 116 | |
| 117 | if (nextStartCodePos < 0 || (uint64_t)nextStartCodePos > this->fileBufferSize) |
| 118 | { |
| 119 | // No start code found ... append all data in the current buffer. |
| 120 | this->lastReturnArray += this->fileBuffer.mid(this->posInBuffer, this->fileBufferSize - this->posInBuffer); |
| 121 | DEBUG_ANNEXBFILE("FileSourceHEVCAnnexBFile::getNextNALUnit no start code found - ret size " << this->lastReturnArray.size()); |
| 122 | |
| 123 | if (this->fileBufferSize < BUFFERSIZE) |
| 124 | { |
| 125 | // We are out of file and could not find a next position |
| 126 | this->posInBuffer = BUFFERSIZE; |
| 127 | if (startEndPosInFile) |
| 128 | startEndPosInFile->second = this->bufferStartPosInFile + this->fileBufferSize - 1; |
| 129 | return this->lastReturnArray; |
| 130 | } |
| 131 | |
| 132 | // Before we load the next bytes: The start code might be located at the boundary to the next buffer |
| 133 | const auto lastByteZero0 = this->fileBuffer.at(this->fileBufferSize - 3) == (char)0; |
| 134 | const auto lastByteZero1 = this->fileBuffer.at(this->fileBufferSize - 2) == (char)0; |
| 135 | const auto lastByteZero2 = this->fileBuffer.at(this->fileBufferSize - 1) == (char)0; |
| 136 | |
| 137 | // We have to continue searching - get the next buffer |
| 138 | updateBuffer(); |
| 139 | |
| 140 | if (this->fileBufferSize > 2) |
| 141 | { |
| 142 | // Now look for the special boundary case: |
| 143 | if (this->fileBuffer.at(0) == (char)1 && lastByteZero2 && lastByteZero1) |
| 144 | { |
| 145 | // Found a start code - the 1 byte is here and the two (or three) 0 bytes were in the last buffer |
| 146 | startCodeFound = true; |
| 147 | nextStartCodePos = lastByteZero0 ? -3 : -2; |
| 148 | this->lastReturnArray.chop(lastByteZero0 ? 3 : 2); |
| 149 | } |
| 150 | else if (this->fileBuffer.at(0) == (char)0 && this->fileBuffer.at(1) == (char)1 && lastByteZero2) |
| 151 | { |