Esempio n. 1
0
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;
            }
        }
    }
}