void ManualImageStreamer::producerStream() { uint i = mStartNumber; int replays = 0; uint64_t previousTimestamp = 0; auto previousTimestampTime = std::chrono::high_resolution_clock::time_point::min(); int currentSequence = 0; while(true) { { std::unique_lock<std::mutex> lock(mStopMutex); if(mStop) { mStreamIsStarted = false; mFirstFrameIsInserted = false; mHasReachedEnd = false; break; } } try { Image::pointer image = mImages[currentSequence].at(i); addOutputData(0, image); if(image->getCreationTimestamp() != 0) { uint64_t timestamp = image->getCreationTimestamp(); // Wait as long as necessary before adding image // Time passed since last frame auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::high_resolution_clock::now() - previousTimestampTime); while (timestamp > previousTimestamp + timePassed.count()) { // Wait int64_t left = (timestamp - previousTimestamp) - timePassed.count(); reportInfo() << "Sleeping for " << left << " ms" << reportEnd(); std::this_thread::sleep_for(std::chrono::milliseconds(left)); timePassed = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::high_resolution_clock::now() - previousTimestampTime); } previousTimestamp = timestamp; previousTimestampTime = std::chrono::high_resolution_clock::now(); } if(mSleepTime > 0) std::this_thread::sleep_for(std::chrono::milliseconds(mSleepTime)); if(!mFirstFrameIsInserted) { { std::lock_guard<std::mutex> lock(mFirstFrameMutex); mFirstFrameIsInserted = true; } mFirstFrameCondition.notify_one(); } mNrOfFrames++; i += mStepSize; } catch(std::out_of_range &e) { if(i > 0) { reportInfo() << "Reached end of stream" << Reporter::end(); // If there where no files found at all, we need to release the execute method if(!mFirstFrameIsInserted) { { std::lock_guard<std::mutex> lock(mFirstFrameMutex); mFirstFrameIsInserted = true; } mFirstFrameCondition.notify_one(); } if(mLoop || (mNrOfReplays > 0 && replays != mNrOfReplays || (currentSequence < mImages.size()-1))) { // Restart stream previousTimestamp = 0; previousTimestampTime = std::chrono::high_resolution_clock::time_point::min(); replays++; i = mStartNumber; currentSequence++; // Go to first sequence if looping is enabled if(mLoop && currentSequence == mImages.size()) { currentSequence = 0; } continue; } mHasReachedEnd = true; // Reached end of stream break; } else { throw e; } } } }