STATUS frameOrderCoordinatorPutFrame()

in src/client/src/FrameOrderCoordinator.c [244:333]


STATUS frameOrderCoordinatorPutFrame(PKinesisVideoStream pKinesisVideoStream, PFrame pUserFrame)
{
    STATUS retStatus = STATUS_SUCCESS;
    PKinesisVideoClient pKinesisVideoClient = NULL;
    PFrame pFrame;
    UINT32 overallSize, i = 0;
    BOOL locked = FALSE;
    PFrameOrderTrackData pPutFrameTrackData = NULL;
    PFrameOrderCoordinator pFrameOrderCoordinator = NULL;

    CHK(pKinesisVideoStream != NULL && pUserFrame != NULL, STATUS_NULL_ARG);
    // route traffic to putFrame if in FRAME_ORDER_MODE_PASS_THROUGH mode.
    if (pKinesisVideoStream->streamInfo.streamCaps.frameOrderingMode == FRAME_ORDER_MODE_PASS_THROUGH) {
        retStatus = putFrame(pKinesisVideoStream, pUserFrame);
        CHK(FALSE, retStatus);
    }

    pFrameOrderCoordinator = pKinesisVideoStream->pFrameOrderCoordinator;
    pKinesisVideoClient = pKinesisVideoStream->pKinesisVideoClient;

    pKinesisVideoClient->clientCallbacks.lockMutexFn(pKinesisVideoClient->clientCallbacks.customData, pFrameOrderCoordinator->lock);
    locked = TRUE;

    for (i = 0; i < pKinesisVideoStream->streamInfo.streamCaps.trackInfoCount; ++i) {
        if (pFrameOrderCoordinator->putFrameTrackDataList[i].pTrackInfo->trackId == pUserFrame->trackId) {
            pPutFrameTrackData = &pFrameOrderCoordinator->putFrameTrackDataList[i];
            break;
        }
    }

    CHK(pPutFrameTrackData != NULL || CHECK_FRAME_FLAG_END_OF_FRAGMENT(pUserFrame->flags), STATUS_MKV_TRACK_INFO_NOT_FOUND);
    if (!CHECK_FRAME_FLAG_END_OF_FRAGMENT(pUserFrame->flags)) {
        CHK(pPutFrameTrackData->frameCount <= DEFAULT_MAX_FRAME_QUEUE_SIZE_PER_TRACK, STATUS_MAX_FRAME_TIMESTAMP_DELTA_BETWEEN_TRACKS_EXCEEDED);
    }

    if (!pFrameOrderCoordinator->keyFrameDetected && CHECK_FRAME_FLAG_KEY_FRAME(pUserFrame->flags)) {
        pFrameOrderCoordinator->keyFrameDetected = TRUE;
    }

    // In case of AV sync modes which explicitly set EoFR after each fragment, the fragmentation
    // should not be driven by the key-frame flags but rather EoFR.
    if ((pKinesisVideoStream->streamInfo.streamCaps.frameOrderingMode == FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_DTS_ONE_MS_COMPENSATE ||
         pKinesisVideoStream->streamInfo.streamCaps.frameOrderingMode == FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE) &&
        pFrameOrderCoordinator->keyFrameDetected && CHECK_FRAME_FLAG_END_OF_FRAGMENT(pUserFrame->flags)) {
        CHK(FALSE, STATUS_SETTING_KEY_FRAME_FLAG_WHILE_USING_EOFR);
    }

    if (CHECK_FRAME_FLAG_END_OF_FRAGMENT(pUserFrame->flags)) {
        CHK_STATUS(frameOrderCoordinatorFlush(pKinesisVideoStream));
        CHK_STATUS(putFrame(pKinesisVideoStream, pUserFrame));
        // Only set the eofr flag in fragment EoFR modes
        if (pKinesisVideoStream->streamInfo.streamCaps.frameOrderingMode == FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_DTS_ONE_MS_COMPENSATE ||
            pKinesisVideoStream->streamInfo.streamCaps.frameOrderingMode == FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_DTS_ONE_MS_COMPENSATE_EOFR) {
            pFrameOrderCoordinator->eofrPut = TRUE;
        }

        CHK(FALSE, retStatus);
    }

    overallSize = SIZEOF(Frame) + pUserFrame->size;
    CHK(NULL != (pFrame = (PFrame) MEMALLOC(overallSize)), STATUS_NOT_ENOUGH_MEMORY);

    *pFrame = *pUserFrame;
    pFrame->frameData = (PBYTE)(pFrame + 1);
    MEMCPY(pFrame->frameData, pUserFrame->frameData, pUserFrame->size);

    CHK_STATUS(stackQueueEnqueue(pPutFrameTrackData->frameQueue, (UINT64) pFrame));

    if (pPutFrameTrackData->frameCount == 0) {
        pFrameOrderCoordinator->trackWithFrame++;
    }
    pPutFrameTrackData->frameCount++;

    // only put earliest frame when all tracks have frame
    while (pFrameOrderCoordinator->trackWithFrame == pFrameOrderCoordinator->putFrameTrackDataListCount) {
        CHK_STATUS(putEarliestFrame(pKinesisVideoStream));
    }

CleanUp:

    if (STATUS_FAILED(retStatus) && pKinesisVideoStream != NULL) {
        pKinesisVideoStream->diagnostics.putFrameErrors++;
    }

    if (locked) {
        pKinesisVideoClient->clientCallbacks.unlockMutexFn(pKinesisVideoClient->clientCallbacks.customData, pFrameOrderCoordinator->lock);
    }

    return retStatus;
}