STATUS resetStream()

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