STATUS addStreamCallbacks()

in src/source/CallbacksProvider.c [512:590]


STATUS addStreamCallbacks(PClientCallbacks pClientCallbacks, PStreamCallbacks pStreamCallbacks)
{
    ENTERS();
    STATUS retStatus = STATUS_SUCCESS;
    UINT32 i;
    PCallbacksProvider pCallbackProvider = (PCallbacksProvider) pClientCallbacks;

    CHK(pCallbackProvider != NULL && pStreamCallbacks != NULL, STATUS_NULL_ARG);

    // Validate the version first
    CHK(pStreamCallbacks->version <= STREAM_CALLBACKS_CURRENT_VERSION, STATUS_INVALID_STREAM_CALLBACKS_VERSION);

    // Check if we have place to put it
    CHK(pCallbackProvider->streamCallbacksCount < pCallbackProvider->callbackChainCount, STATUS_MAX_CALLBACK_CHAIN);

    // Guard against adding same callbacks multiple times (duplicate) - This prevents freeing memory twice
    for (i = 0; i < pCallbackProvider->streamCallbacksCount; i++) {
        CHK(pStreamCallbacks->freeStreamCallbacksFn == NULL || pCallbackProvider->pStreamCallbacks[i].customData != pStreamCallbacks->customData ||
                pCallbackProvider->pStreamCallbacks[i].freeStreamCallbacksFn != pStreamCallbacks->freeStreamCallbacksFn,
            STATUS_DUPLICATE_STREAM_CALLBACK_FREE_FUNC);
    }

    // Struct-copy the values and increment the current counter
    pCallbackProvider->pStreamCallbacks[pCallbackProvider->streamCallbacksCount++] = *pStreamCallbacks;

    // Set the aggregates
    if (pStreamCallbacks->streamUnderflowReportFn != NULL) {
        pCallbackProvider->clientCallbacks.streamUnderflowReportFn = streamUnderflowReportAggregate;
    }

    if (pStreamCallbacks->bufferDurationOverflowPressureFn != NULL) {
        pCallbackProvider->clientCallbacks.bufferDurationOverflowPressureFn = bufferDurationOverflowPressureAggregate;
    }

    if (pStreamCallbacks->streamLatencyPressureFn != NULL) {
        pCallbackProvider->clientCallbacks.streamLatencyPressureFn = streamLatencyPressureAggregate;
    }

    if (pStreamCallbacks->streamConnectionStaleFn != NULL) {
        pCallbackProvider->clientCallbacks.streamConnectionStaleFn = streamConnectionStaleAggregate;
    }

    if (pStreamCallbacks->droppedFrameReportFn != NULL) {
        pCallbackProvider->clientCallbacks.droppedFrameReportFn = droppedFrameReportAggregate;
    }

    if (pStreamCallbacks->droppedFragmentReportFn != NULL) {
        pCallbackProvider->clientCallbacks.droppedFragmentReportFn = droppedFragmentReportAggregate;
    }

    if (pStreamCallbacks->streamErrorReportFn != NULL) {
        pCallbackProvider->clientCallbacks.streamErrorReportFn = streamErrorReportAggregate;
    }

    if (pStreamCallbacks->fragmentAckReceivedFn != NULL) {
        pCallbackProvider->clientCallbacks.fragmentAckReceivedFn = fragmentAckReceivedAggregate;
    }

    if (pStreamCallbacks->streamDataAvailableFn != NULL) {
        pCallbackProvider->clientCallbacks.streamDataAvailableFn = streamDataAvailableAggregate;
    }

    if (pStreamCallbacks->streamReadyFn != NULL) {
        pCallbackProvider->clientCallbacks.streamReadyFn = streamReadyAggregate;
    }

    if (pStreamCallbacks->streamClosedFn != NULL) {
        pCallbackProvider->clientCallbacks.streamClosedFn = streamClosedAggregate;
    }

    if (pStreamCallbacks->streamShutdownFn != NULL) {
        pCallbackProvider->clientCallbacks.streamShutdownFn = streamShutdownAggregate;
    }

CleanUp:

    LEAVES();
    return retStatus;
}