| 186 | } |
| 187 | |
| 188 | bool readFileChunk(bool init = false) { |
| 189 | if (!fileHandle) return false; |
| 190 | |
| 191 | { |
| 192 | std::scoped_lock<std::mutex> lock(buffersMutex); |
| 193 | if (frameRate > 0 && frameBuffers.size() >= frameRate * 2) { |
| 194 | return true; |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | size_t bytesRead = SDL_RWread(fileHandle, buffer, 1, CHUNK_SIZE); |
| 199 | |
| 200 | if (bytesRead > 0) { |
| 201 | splitter.push(buffer, bytesRead); |
| 202 | auto nal = splitter.popNal(); |
| 203 | if (!nal) return true; |
| 204 | streamBuffer.insert(streamBuffer.end(), nal.value().begin(), nal.value().end()); |
| 205 | processVideoFrame(); |
| 206 | return true; |
| 207 | } else if (auto nal = splitter.popNal(); nal) { |
| 208 | streamBuffer.insert(streamBuffer.end(), nal.value().begin(), nal.value().end()); |
| 209 | processVideoFrame(); |
| 210 | return true; |
| 211 | } else { |
| 212 | if (!init && looped) { |
| 213 | if (decoderStorage != nullptr) { |
| 214 | h264bsdShutdown(decoderStorage); |
| 215 | h264bsdFree(decoderStorage); |
| 216 | decoderStorage = nullptr; |
| 217 | } |
| 218 | |
| 219 | decoderStorage = h264bsdAlloc(); |
| 220 | if (!decoderStorage) { |
| 221 | Error("VideoNode: failed to allocate decoder storage"); |
| 222 | return false; |
| 223 | } |
| 224 | |
| 225 | u32 result = h264bsdInit(decoderStorage, 1); // 0 = enable output reordering |
| 226 | if (result != H264BSD_RDY) { |
| 227 | Error("VideoNode: failed to initialize decoder, error code: {}", result); |
| 228 | h264bsdFree(decoderStorage); |
| 229 | decoderStorage = nullptr; |
| 230 | return false; |
| 231 | } |
| 232 | |
| 233 | currentPicId = 0; |
| 234 | streamBuffer.clear(); |
| 235 | streamBufferPos = 0; |
| 236 | splitter.clear(); |
| 237 | SDL_RWseek(fileHandle, 0, RW_SEEK_SET); |
| 238 | } else if (!init) { |
| 239 | std::scoped_lock<std::mutex> lock(buffersMutex); |
| 240 | frameBuffers.emplace_back(); |
| 241 | } |
| 242 | return false; |
| 243 | } |
| 244 | } |
| 245 |
no test coverage detected