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