in src/source/stream/stream.c [191:317]
DataFrameHandle Kvs_streamAddDataFrame(StreamHandle xStreamHandle, DataFrameIn_t *pxDataFrameIn)
{
int xRes = KVS_ERRNO_NONE;
Stream_t *pxStream = xStreamHandle;
DataFrame_t *pxDataFrame = NULL;
size_t uMkvHdrLen = 0;
DataFrame_t *pxDataFrameCurrent = NULL;
PDLIST_ENTRY pxListHead = NULL;
PDLIST_ENTRY pxListItem = NULL;
bool bListAdded = false;
bool bNeedCorrectDeltaTimestamp = false;
bool bCorrectDeltaTimestampStarted = false;
uint64_t uClusterTimestamp = 0;
uint16_t uDeltaTimestampMs = 0;
if (pxStream == NULL || pxDataFrameIn == NULL)
{
LogError("Invalid argument");
xRes = KVS_ERRNO_FAIL;
}
else if ((uMkvHdrLen = Mkv_getClusterHdrLen(pxDataFrameIn->xClusterType)) == 0 || (pxDataFrame = (DataFrame_t *)kvsMalloc(sizeof(DataFrame_t) + uMkvHdrLen)) == NULL)
{
LogError("Failed to create data frame");
xRes = KVS_ERRNO_FAIL;
}
else if (Lock(pxStream->xLock) != LOCK_OK)
{
LogError("Failed to Lock");
xRes = KVS_ERRNO_FAIL;
}
else
{
memset(pxDataFrame, 0, sizeof(DataFrame_t));
memcpy(pxDataFrame, pxDataFrameIn, sizeof(DataFrameIn_t));
DList_InitializeListHead(&(pxDataFrame->xClusterEntry));
DList_InitializeListHead(&(pxDataFrame->xDataFrameEntry));
pxDataFrame->uMkvHdrLen = uMkvHdrLen;
pxDataFrame->pMkvHdr = (char *)pxDataFrame + sizeof(DataFrame_t);
uClusterTimestamp = pxStream->uEarliestClusterTimestamp;
pxListHead = &(pxStream->xDataFramePending);
pxListItem = pxListHead->Flink;
while (pxListItem != pxListHead)
{
pxDataFrameCurrent = containingRecord(pxListItem, DataFrame_t, xDataFrameEntry);
if (pxDataFrame->xDataFrameIn.uTimestampMs < pxDataFrameCurrent->xDataFrameIn.uTimestampMs ||
((pxDataFrame->xDataFrameIn.uTimestampMs == pxDataFrameCurrent->xDataFrameIn.uTimestampMs) && (pxDataFrame->xDataFrameIn.xTrackType == TRACK_VIDEO)))
{
DList_InsertTailList(pxListItem, &(pxDataFrame->xDataFrameEntry));
uDeltaTimestampMs = (uint16_t)(pxDataFrame->xDataFrameIn.uTimestampMs - uClusterTimestamp);
if (pxDataFrame->xDataFrameIn.xClusterType == MKV_CLUSTER)
{
uDeltaTimestampMs = 0;
/* If we insert a cluster head, then the following frames's delta timestamp needs updates. */
bNeedCorrectDeltaTimestamp = true;
}
bListAdded = true;
break;
}
if (pxDataFrameCurrent->xDataFrameIn.xClusterType == MKV_CLUSTER)
{
uClusterTimestamp = pxDataFrameCurrent->xDataFrameIn.uTimestampMs;
}
pxListItem = pxListItem->Flink;
}
if (!bListAdded)
{
uDeltaTimestampMs = (uint16_t)(pxDataFrame->xDataFrameIn.uTimestampMs - uClusterTimestamp);
DList_InsertTailList(&(pxStream->xDataFramePending), &(pxDataFrame->xDataFrameEntry));
bListAdded = true;
}
Mkv_initializeClusterHdr(
(uint8_t *)(pxDataFrame->pMkvHdr),
pxDataFrame->uMkvHdrLen,
pxDataFrameIn->xClusterType,
pxDataFrameIn->uDataLen,
pxDataFrameIn->xTrackType,
pxDataFrameIn->bIsKeyFrame,
pxDataFrameIn->uTimestampMs,
uDeltaTimestampMs);
if (bNeedCorrectDeltaTimestamp)
{
bCorrectDeltaTimestampStarted = false;
pxListHead = &(pxStream->xDataFramePending);
pxListItem = pxListHead->Flink;
while (pxListItem != pxListHead)
{
pxDataFrameCurrent = containingRecord(pxListItem, DataFrame_t, xDataFrameEntry);
if (pxDataFrameCurrent->xDataFrameIn.xClusterType == MKV_CLUSTER)
{
uClusterTimestamp = pxDataFrameCurrent->xDataFrameIn.uTimestampMs;
bCorrectDeltaTimestampStarted = true;
}
if (bCorrectDeltaTimestampStarted)
{
uDeltaTimestampMs = (uint16_t)(pxDataFrameCurrent->xDataFrameIn.uTimestampMs - uClusterTimestamp);
Mkv_initializeClusterHdr(
(uint8_t *)(pxDataFrameCurrent->pMkvHdr),
pxDataFrameCurrent->uMkvHdrLen,
pxDataFrameCurrent->xDataFrameIn.xClusterType,
pxDataFrameCurrent->xDataFrameIn.uDataLen,
pxDataFrameCurrent->xDataFrameIn.xTrackType,
pxDataFrameCurrent->xDataFrameIn.bIsKeyFrame,
pxDataFrameCurrent->xDataFrameIn.uTimestampMs,
uDeltaTimestampMs);
}
pxListItem = pxListItem->Flink;
}
}
Unlock(pxStream->xLock);
}
if (xRes != KVS_ERRNO_NONE)
{
if (pxDataFrame != NULL)
{
kvsFree(pxDataFrame);
pxDataFrame = NULL;
}
}
return pxDataFrame;
}