int Mkv_initializeHeaders()

in src/source/mkv/mkv_generator.c [540:645]


int Mkv_initializeHeaders(MkvHeader_t *pMkvHeader, VideoTrackInfo_t *pVideoTrackInfo, AudioTrackInfo_t *pAudioTrackInfo)
{
    int xRes = KVS_ERRNO_NONE;
    ;
    uint8_t *pIdx = NULL;
    uint32_t uHeaderLen = 0;
    uint8_t pSegmentUuid[UUID_LEN] = {0};
    uint32_t uSegmentTracksLen = 0;

    uint8_t *pSegmentVideo = NULL;
    uint32_t uSegmentVideoLen = 0;

    bool bHasAudioTrack = false;
    uint8_t *pSegmentAudio = NULL;
    uint32_t uSegmentAudioLen = 0;

    size_t i = 0;

    if (pMkvHeader == NULL || pVideoTrackInfo == NULL)
    {
        LogError("Invalid argument");
        xRes = KVS_ERRNO_FAIL;
    }
    else
    {
        memset(pMkvHeader, 0, sizeof(MkvHeader_t));

        for (i = 0; i < UUID_LEN; i++)
        {
            pSegmentUuid[i] = getRandomNumber();
        }

        bHasAudioTrack = (pAudioTrackInfo != NULL) ? true : false;

        if (prvCreateVideoTrackEntry(pVideoTrackInfo, &pSegmentVideo, &uSegmentVideoLen) != KVS_ERRNO_NONE ||
            (bHasAudioTrack && prvCreateAudioTrackEntry(pAudioTrackInfo, &pSegmentAudio, &uSegmentAudioLen) != KVS_ERRNO_NONE))
        {
            LogError("Failed to create track entries");
            xRes = KVS_ERRNO_FAIL;
        }
        else
        {
            /* Calculate size of EBML and Segment header. */
            uHeaderLen = gEbmlHeaderSize;
            uHeaderLen += gSegmentHeaderSize;
            uHeaderLen += gSegmentInfoHeaderSize;
            uHeaderLen += gSegmentTrackHeaderSize;

            uHeaderLen += uSegmentVideoLen;
            uHeaderLen += (bHasAudioTrack) ? uSegmentAudioLen : 0;

            /* Allocate memory for EBML and Segment header. */
            if ((pMkvHeader->pHeader = (uint8_t *)kvsMalloc(uHeaderLen)) == NULL)
            {
                LogError("OOM: MKV Header");
                xRes = KVS_ERRNO_FAIL;
            }
            else
            {
                pIdx = pMkvHeader->pHeader;

                memcpy(pIdx, gEbmlHeader, gEbmlHeaderSize);
                pIdx += gEbmlHeaderSize;

                memcpy(pIdx, gSegmentHeader, gSegmentHeaderSize);
                pIdx += gSegmentHeaderSize;

                memcpy(pIdx, gSegmentInfoHeader, gSegmentInfoHeaderSize);
                memcpy(pIdx + MKV_SEGMENT_INFO_UID_OFFSET, pSegmentUuid, UUID_LEN);
                snprintf((char *)(pIdx + MKV_SEGMENT_INFO_TITLE_OFFSET), SEGMENT_TITLE_MAX_LEN, "%s", SEGMENT_TITLE);
                snprintf((char *)(pIdx + MKV_SEGMENT_INFO_MUXING_APP_OFFSET), MUXING_APP_MAX_LEN, "%s", MUXING_APP);
                snprintf((char *)(pIdx + MKV_SEGMENT_INFO_WRITING_APP_OFFSET), WRITING_APP_MAX_LEN, "%s", WRITING_APP);
                pIdx += gSegmentInfoHeaderSize;

                memcpy(pIdx, gSegmentTrackHeader, gSegmentTrackHeaderSize);
                uSegmentTracksLen = uSegmentVideoLen;
                uSegmentTracksLen += (bHasAudioTrack) ? uSegmentAudioLen : 0;
                PUT_UNALIGNED_4_byte_BE(pIdx + MKV_SEGMENT_TRACK_LENGTH_OFFSET, MKV_LENGTH_INDICATOR_4_BYTE | uSegmentTracksLen);
                pIdx += gSegmentTrackHeaderSize;

                memcpy(pIdx, pSegmentVideo, uSegmentVideoLen);
                pIdx += uSegmentVideoLen;

                if (bHasAudioTrack)
                {
                    memcpy(pIdx, pSegmentAudio, uSegmentAudioLen);
                    pIdx += uSegmentAudioLen;
                }

                pMkvHeader->uHeaderLen = uHeaderLen;
            }
        }
    }

    if (pSegmentVideo != NULL)
    {
        kvsFree(pSegmentVideo);
    }

    if (pSegmentAudio != NULL)
    {
        kvsFree(pSegmentAudio);
    }

    return xRes;
}