| 269 | } |
| 270 | |
| 271 | bool SequenceFile::writeFrame(int index, std::shared_ptr<BitmapBuffer> bitmap) { |
| 272 | std::lock_guard<std::mutex> autoLock(locker); |
| 273 | if (index < 0 || index >= _numFrames || bitmap == nullptr) { |
| 274 | LOGE("SequenceFile::writeFrame() invalid index or pixels!"); |
| 275 | return false; |
| 276 | } |
| 277 | if (bitmap->info() != _info) { |
| 278 | LOGE("SequenceFile::writeFrame() the specified bitmap info is different from ours!"); |
| 279 | return false; |
| 280 | } |
| 281 | auto timeRange = GetTimeRangeContains(_staticTimeRanges, index); |
| 282 | if (frames[timeRange.start].size != 0) { |
| 283 | return false; |
| 284 | } |
| 285 | auto pixels = bitmap->lockPixels(); |
| 286 | if (pixels == nullptr) { |
| 287 | LOGE("SequenceFile::writeFrame() failed to lock pixels from the specified bitmap!"); |
| 288 | return false; |
| 289 | } |
| 290 | auto compressedSize = compressFrame(static_cast<int>(timeRange.start), pixels, _info.byteSize()); |
| 291 | bitmap->unlockPixels(); |
| 292 | if (compressedSize == 0) { |
| 293 | return false; |
| 294 | } |
| 295 | if (_fileSize == 0 && !writeFileHead()) { |
| 296 | return false; |
| 297 | } |
| 298 | if (fseek(file, 0, SEEK_END)) { |
| 299 | LOGE("SequenceFile::writeFrame() failed to seek to the end of the file"); |
| 300 | return false; |
| 301 | } |
| 302 | if (fwrite(scratchBuffer.bytes(), 1, compressedSize, file) != compressedSize) { |
| 303 | LOGE("SequenceFile::writeFrame() failed to write the compressed frame to disk"); |
| 304 | return false; |
| 305 | } |
| 306 | for (auto i = timeRange.start; i <= timeRange.end; i++) { |
| 307 | auto& frame = frames[i]; |
| 308 | frame.offset = _fileSize + FRAME_HEAD_SIZE; |
| 309 | frame.size = compressedSize - FRAME_HEAD_SIZE; |
| 310 | cachedFrames++; |
| 311 | } |
| 312 | _fileSize += compressedSize; |
| 313 | if (cachedFrames == _numFrames) { |
| 314 | scratchBuffer.reset(); |
| 315 | encoder = nullptr; |
| 316 | } |
| 317 | if (diskCache) { |
| 318 | diskCache->notifyFileSizeChanged(fileID, _fileSize); |
| 319 | } |
| 320 | return true; |
| 321 | } |
| 322 | |
| 323 | size_t SequenceFile::compressFrame(int index, const void* pixels, size_t byteSize) { |
| 324 | if (!checkScratchBuffer()) { |