| 81 | } |
| 82 | |
| 83 | QByteArray FileSourceFFmpegFile::getNextUnit(bool getLastDataAgain) |
| 84 | { |
| 85 | if (getLastDataAgain) |
| 86 | return this->lastReturnArray; |
| 87 | |
| 88 | // Is a packet loaded? |
| 89 | if (this->currentPacketData.isEmpty()) |
| 90 | { |
| 91 | if (!this->goToNextPacket(true)) |
| 92 | { |
| 93 | this->posInFile = -1; |
| 94 | return {}; |
| 95 | } |
| 96 | |
| 97 | this->currentPacketData = QByteArray::fromRawData((const char *)(this->currentPacket.getData()), |
| 98 | this->currentPacket.getDataSize()); |
| 99 | this->posInData = 0; |
| 100 | } |
| 101 | |
| 102 | // AVPacket data can be in one of two formats: |
| 103 | // 1: The raw annexB format with start codes (0x00000001 or 0x000001) |
| 104 | // 2: ISO/IEC 14496-15 mp4 format: The first 4 bytes determine the size of the NAL unit followed |
| 105 | // by the payload |
| 106 | if (this->packetDataFormat == PacketDataFormat::RawNAL) |
| 107 | { |
| 108 | const auto firstBytes = this->currentPacketData.mid(posInData, 4); |
| 109 | int offset; |
| 110 | if (firstBytes.at(0) == (char)0 && firstBytes.at(1) == (char)0 && firstBytes.at(2) == (char)0 && |
| 111 | firstBytes.at(3) == (char)1) |
| 112 | offset = 4; |
| 113 | else if (firstBytes.at(0) == (char)0 && firstBytes.at(1) == (char)0 && |
| 114 | firstBytes.at(2) == (char)1) |
| 115 | offset = 3; |
| 116 | else |
| 117 | { |
| 118 | // The start code could not be found ... |
| 119 | this->currentPacketData.clear(); |
| 120 | return {}; |
| 121 | } |
| 122 | |
| 123 | // Look for the next start code (or the end of the file) |
| 124 | auto nextStartCodePos = this->currentPacketData.indexOf(startCode, posInData + 3); |
| 125 | |
| 126 | if (nextStartCodePos == -1) |
| 127 | { |
| 128 | // Return the remainder of the buffer and clear it so that the next packet is loaded on the |
| 129 | // next call |
| 130 | this->lastReturnArray = currentPacketData.mid(this->posInData + offset); |
| 131 | this->currentPacketData.clear(); |
| 132 | } |
| 133 | else |
| 134 | { |
| 135 | auto size = nextStartCodePos - this->posInData - offset; |
| 136 | lastReturnArray = this->currentPacketData.mid(this->posInData + offset, size); |
| 137 | this->posInData += 3 + size; |
| 138 | } |
| 139 | } |
| 140 | else if (this->packetDataFormat == PacketDataFormat::MP4) |
no test coverage detected