int KvsApp_addFrameWithCallbacks()

in src/source/app/kvsapp.c [1284:1374]


int KvsApp_addFrameWithCallbacks(KvsAppHandle handle, uint8_t *pData, size_t uDataLen, size_t uDataSize, uint64_t uTimestamp, TrackType_t xTrackType, DataFrameCallbacks_t *pCallbacks)
{
    int res = ERRNO_NONE;
    KvsApp_t *pKvs = (KvsApp_t *)handle;
    DataFrameIn_t xDataFrameIn = {0};
    DataFrameUserData_t *pUserData = NULL;

    if (pKvs == NULL || pData == NULL || uDataLen == 0)
    {
        res = ERRNO_FAIL;
    }
    else if (uTimestamp < pKvs->uEarliestTimestamp)
    {
        res = ERRNO_FAIL;
    }
    else if (xTrackType == TRACK_VIDEO && NALU_isAnnexBFrame(pData, uDataLen) && NALU_convertAnnexBToAvccInPlace(pData, uDataLen, uDataSize, (uint32_t *)&uDataLen) != ERRNO_NONE)
    {
        LogError("Failed to convert Annex-B to Avcc in place");
        res = ERRNO_FAIL;
    }
    else if (checkAndBuildStream(pKvs, pData, uDataLen, xTrackType) != ERRNO_NONE)
    {
        LogError("Failed to build stream buffer");
        res = ERRNO_FAIL;
    }
    else if (pKvs->xStreamHandle == NULL)
    {
        res = ERRNO_FAIL;
    }
    else if ((pUserData = (DataFrameUserData_t *)kvsMalloc(sizeof(DataFrameUserData_t))) == NULL)
    {
        LogError("OOM: pUserData");
        res = ERRNO_FAIL;
    }
    else
    {
        xDataFrameIn.pData = (char *)pData;
        xDataFrameIn.uDataLen = uDataLen;
        xDataFrameIn.bIsKeyFrame = (xTrackType == TRACK_VIDEO) ? isKeyFrame(pData, uDataLen) : false;
        xDataFrameIn.uTimestampMs = uTimestamp;
        xDataFrameIn.xTrackType = xTrackType;
        xDataFrameIn.xClusterType = (xDataFrameIn.bIsKeyFrame) ? MKV_CLUSTER : MKV_SIMPLE_BLOCK;

        memset(pUserData, 0, sizeof(DataFrameUserData_t));
        if (pCallbacks == NULL)
        {
            /* Assign default callbacks. */
            pUserData->xCallbacks.onDataFrameTerminateInfo.onDataFrameTerminate = defaultOnDataFrameTerminate;
            pUserData->xCallbacks.onDataFrameTerminateInfo.pAppData = NULL;
            pUserData->xCallbacks.onDataFrameToBeSentInfo.onDataFrameToBeSent = NULL;
            pUserData->xCallbacks.onDataFrameToBeSentInfo.pAppData = NULL;
        }
        else
        {
            memcpy(&(pUserData->xCallbacks), pCallbacks, sizeof(DataFrameCallbacks_t));
        }
        xDataFrameIn.pUserData = pUserData;

        if (pKvs->xStrategy.xPolicy == STREAM_POLICY_RING_BUFFER)
        {
            prvStreamFlushHeadUntilMem(pKvs, pKvs->xStrategy.xRingBufferPara.uMemLimit);
        }

        if (Kvs_streamAddDataFrame(pKvs->xStreamHandle, &xDataFrameIn) == NULL)
        {
            LogError("Failed to add data frame");
            res = ERRNO_FAIL;
        }
    }

    if (res != ERRNO_NONE)
    {
        if (pData != NULL)
        {
            if (pCallbacks != NULL && pCallbacks->onDataFrameTerminateInfo.onDataFrameTerminate != NULL)
            {
                pCallbacks->onDataFrameTerminateInfo.onDataFrameTerminate(pData, uDataLen, uTimestamp, xTrackType, NULL);
            }
            else
            {
                defaultOnDataFrameTerminate(pData, uDataLen, uTimestamp, xTrackType, NULL);
            }
        }
        if (pUserData != NULL)
        {
            kvsFree(pUserData);
        }
    }

    return res;
}