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;
}