in src/client/src/Stream.c [3169:3307]
STATUS resetStream(PKinesisVideoStream pKinesisVideoStream)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
BOOL streamLocked = FALSE;
PKinesisVideoClient pKinesisVideoClient = NULL;
CHK(pKinesisVideoStream != NULL, STATUS_NULL_ARG);
pKinesisVideoClient = pKinesisVideoStream->pKinesisVideoClient;
CHK(pKinesisVideoClient != NULL, STATUS_CLIENT_FREED_BEFORE_STREAM);
// Shutdown the processing
// Prevent repeated resetStream call if one is in progress
CHK(!pKinesisVideoStream->base.shutdown, retStatus);
CHK_STATUS_CONTINUE(shutdownStream(pKinesisVideoStream, TRUE));
// Lock the stream
pKinesisVideoClient->clientCallbacks.lockMutexFn(pKinesisVideoClient->clientCallbacks.customData, pKinesisVideoStream->base.lock);
streamLocked = TRUE;
// Reset the current view item
MEMSET(&pKinesisVideoStream->curViewItem, 0x00, SIZEOF(CurrentViewItem));
pKinesisVideoStream->curViewItem.viewItem.handle = INVALID_ALLOCATION_HANDLE_VALUE;
// Trim all the buffer to head
CHK_STATUS_CONTINUE(contentViewRemoveAll(pKinesisVideoStream->pView));
CHK_STATUS_CONTINUE(freeStackQueue(pKinesisVideoStream->pMetadataQueue, FALSE));
CHK_STATUS_CONTINUE(freeStackQueue(pKinesisVideoStream->pUploadInfoQueue, FALSE));
// set the maximum frame size observed to 0
pKinesisVideoStream->maxFrameSizeSeen = 0;
// reset shutdown status
pKinesisVideoStream->base.shutdown = FALSE;
pKinesisVideoStream->base.result = SERVICE_CALL_RESULT_NOT_SET;
// If stream is already ready, set streamState to STREAM_STATE_STOPPED. Because pKinesisVideoStream->base.result
// is SERVICE_CALL_RESULT_NOT_SET which will be mapped to STATUS_SERVICE_CALL_UNKOWN_ERROR by serviceCallResultCheck,
// when we stepStateMachine the streamState will go to STREAM_STATE_READY (in which case putFrame wont fail) but
// start executing state from STREAM_STATE_DESCRIBE. If not already ready, set state back to STREAM_STATE_NEW.
if (pKinesisVideoStream->streamReady) {
pKinesisVideoStream->streamState = STREAM_STATE_STOPPED;
} else {
pKinesisVideoStream->streamState = STREAM_STATE_NEW;
CHK_STATUS(setStateMachineCurrentState(pKinesisVideoStream->base.pStateMachine, STREAM_STATE_NEW));
}
pKinesisVideoStream->streamStatus = STREAM_STATUS_CREATING;
// Stream is not stopped and not closed
pKinesisVideoStream->streamStopped = FALSE;
pKinesisVideoStream->streamClosed = FALSE;
// Set the stream start timestamps and index
pKinesisVideoStream->newSessionTimestamp = INVALID_TIMESTAMP_VALUE;
pKinesisVideoStream->newSessionIndex = INVALID_VIEW_INDEX_VALUE;
// Set streamingAuthInfo.expiration to invalid time value since resetStream abolishes all current connections and
// step states agains to create new connections. This also avoid putFrame thread triggering mkv header regeneration
// due to token expiration and cause the new putMedia connection created by resetStream to get end-of-stream prematurely.
pKinesisVideoStream->streamingAuthInfo.expiration = INVALID_TIMESTAMP_VALUE;
pKinesisVideoStream->gracePeriod = FALSE;
// Shouldn't reset the generator on next key frame
pKinesisVideoStream->resetGeneratorOnKeyFrame = FALSE;
// after resetStream should begin with key frame
pKinesisVideoStream->skipNonKeyFrames = TRUE;
// Shouldn't reset the generator so set invalid time
pKinesisVideoStream->resetGeneratorTime = INVALID_TIMESTAMP_VALUE;
// No connections have been dropped as this is a new stream
pKinesisVideoStream->connectionState = UPLOAD_CONNECTION_STATE_OK;
// Set the last frame EoFr indicator
pKinesisVideoStream->eofrFrame = FALSE;
// Set the initial diagnostics information from the defaults
pKinesisVideoStream->diagnostics.currentFrameRate = pKinesisVideoStream->streamInfo.streamCaps.frameRate;
pKinesisVideoStream->diagnostics.elementaryFrameRate = pKinesisVideoStream->streamInfo.streamCaps.frameRate;
pKinesisVideoStream->diagnostics.currentTransferRate = pKinesisVideoStream->streamInfo.streamCaps.avgBandwidthBps;
pKinesisVideoStream->diagnostics.accumulatedByteCount = 0;
pKinesisVideoStream->diagnostics.lastFrameRateTimestamp = pKinesisVideoStream->diagnostics.lastTransferRateTimestamp = 0;
// Set the trackers
// set eosTracker offset to 0 so that it would send eos again. No need to reset eosTracker data and size because
// data is always same.
pKinesisVideoStream->eosTracker.offset = 0;
pKinesisVideoStream->eosTracker.send = FALSE;
pKinesisVideoStream->metadataTracker.size = 0;
pKinesisVideoStream->metadataTracker.offset = 0;
pKinesisVideoStream->metadataTracker.send = FALSE;
if (pKinesisVideoStream->metadataTracker.data != NULL) {
MEMFREE(pKinesisVideoStream->metadataTracker.data);
}
pKinesisVideoStream->metadataTracker.data = NULL;
// Reset mkv generator
mkvgenResetGenerator(pKinesisVideoStream->pMkvGenerator);
// Reset ack parser
resetAckParserState(pKinesisVideoStream);
// Reset state machine retry status
if (pKinesisVideoStream->base.pStateMachine != NULL) {
CHK_STATUS(resetStateMachineRetryCount(pKinesisVideoStream->base.pStateMachine));
}
// Reset client state machine retry status
CHK_STATUS(resetStateMachineRetryCount(pKinesisVideoClient->base.pStateMachine));
// Release the condition variable
if (IS_VALID_CVAR_VALUE(pKinesisVideoStream->bufferAvailabilityCondition)) {
pKinesisVideoClient->clientCallbacks.broadcastConditionVariableFn(pKinesisVideoClient->clientCallbacks.customData,
pKinesisVideoStream->bufferAvailabilityCondition);
}
// step out of stopped state
CHK_STATUS(stepStateMachine(pKinesisVideoStream->base.pStateMachine));
// Unlock the stream
pKinesisVideoClient->clientCallbacks.unlockMutexFn(pKinesisVideoClient->clientCallbacks.customData, pKinesisVideoStream->base.lock);
streamLocked = FALSE;
CleanUp:
if (streamLocked) {
pKinesisVideoClient->clientCallbacks.unlockMutexFn(pKinesisVideoClient->clientCallbacks.customData, pKinesisVideoStream->base.lock);
}
LEAVES();
return retStatus;
}