PVOID ProducerTestBase::basicProducerRoutine()

in tst/ProducerApiTest.cpp [25:141]


PVOID ProducerTestBase::basicProducerRoutine(KinesisVideoStream* kinesis_video_stream,
                                             STREAMING_TYPE streaming_type) {
    UINT32 index = 0, persistentMetadataIndex = 0;
    UINT64 timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count() / DEFAULT_TIME_UNIT_IN_NANOS;
    Frame frame;
    std::string metadataNameStr;

    // Set an indicator that the producer is not stopped
    producer_stopped_ = false;

    // Loop until cancelled
    frame.duration = TEST_FRAME_DURATION;
    frame.frameData = frameBuffer_;
    frame.trackId = DEFAULT_TRACK_ID;
    MEMSET(frame.frameData, 0x55, SIZEOF(frameBuffer_));

    BYTE cpd2[] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x34,
                   0xAC, 0x2B, 0x40, 0x1E, 0x00, 0x78, 0xD8, 0x08,
                   0x80, 0x00, 0x01, 0xF4, 0x00, 0x00, 0xEA, 0x60,
                   0x47, 0xA5, 0x50, 0x00, 0x00, 0x00, 0x01, 0x68,
                   0xEE, 0x3C, 0xB0};
    UINT32 cpdSize = SIZEOF(cpd2);

    EXPECT_TRUE(kinesis_video_stream->start(cpd2, cpdSize, DEFAULT_TRACK_ID));

    while (!stop_producer_) {
        // Produce frames
        if (IS_OFFLINE_STREAMING_MODE(streaming_type)) {
            timestamp += frame.duration;
        } else {
            timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
                    std::chrono::system_clock::now().time_since_epoch()).count() / DEFAULT_TIME_UNIT_IN_NANOS;
        }

        frame.index = index++;
        frame.decodingTs = timestamp;
        frame.presentationTs = timestamp;

        // Add small variation to the frame size (if larger frames
        frame.size = SIZEOF(frameBuffer_);
        if (frame.size > 100) {
            frame.size -= RAND() % 100;
        }

        // Key frame every 50th
        frame.flags = (frame.index % 50 == 0) ? FRAME_FLAG_KEY_FRAME : FRAME_FLAG_NONE;

        std::stringstream strstrm;
        strstrm << " TID: 0x" << std::hex << GETTID();
        LOG_DEBUG("Putting frame for stream: " << kinesis_video_stream->getStreamName()
                                               << strstrm.str()
                                               << " Id: " << frame.index
                                               << ", Key Frame: "
                                               << (((frame.flags & FRAME_FLAG_KEY_FRAME) == FRAME_FLAG_KEY_FRAME)
                                                   ? "true" : "false")
                                               << ", Size: " << frame.size
                                               << ", Dts: " << frame.decodingTs
                                               << ", Pts: " << frame.presentationTs);

        // Apply some non-persistent metadata every few frames
        if (frame.index % 20 == 0) {
            std::ostringstream metadataName, metadataValue;
            metadataName << "MetadataNameForFrame_" << frame.index;
            metadataValue << "MetadataValueForFrame_" << frame.index;
            EXPECT_TRUE(kinesis_video_stream->putFragmentMetadata(metadataName.str(), metadataValue.str(), false));
        }

        // Apply some persistent metadata on a larger intervals to span fragments
        if (frame.index % 60 == 0) {
            std::ostringstream metadataName, metadataValue;
            std::string metadataValueStr;

            metadataName << "PersistentMetadataName_" << persistentMetadataIndex;
            metadataValue << "PersistentMetadataValue_" << persistentMetadataIndex;

            // Set or clear persistent metadata every other time.
            if (persistentMetadataIndex % 2 == 0) {
                metadataNameStr = metadataName.str();
                metadataValueStr = metadataValue.str();
            } else {
                metadataValueStr = std::string();
            }

            persistentMetadataIndex++;
            EXPECT_TRUE(kinesis_video_stream->putFragmentMetadata(metadataNameStr, metadataValueStr, true));
        }

#if 0
        // Simulate EoFr first
        if (frame.index % 50 == 0 && frame.index != 0) {
            Frame eofr = EOFR_FRAME_INITIALIZER;
            EXPECT_TRUE(kinesis_video_stream->putFrame(eofr));
        }
#endif

        EXPECT_TRUE(kinesis_video_stream->putFrame(frame));

        // Sleep a while for non-offline modes
        if (streaming_type != STREAMING_TYPE_OFFLINE) {
            THREAD_SLEEP(TEST_FRAME_DURATION);
        }
    }

    LOG_DEBUG("Stopping the stream: " << kinesis_video_stream->getStreamName());
    EXPECT_TRUE(kinesis_video_stream->stopSync()) << "Timed out awaiting for the stream stop notification";


    // The signalling should be handled per stream.
    // This is for a demo purpose only!!!
    EXPECT_TRUE(gProducerApiTest->stop_called_) << "Status of stopped state " << gProducerApiTest->stop_called_;

    // Indicate that the producer routine had stopped
    producer_stopped_ = true;

    return NULL;
}