in src/mkvgen/src/MkvGenerator.c [1662:1765]
STATUS mkvgenAdaptCodecPrivateData(PStreamMkvGenerator pMkvGenerator, MKV_TRACK_INFO_TYPE trackType, PCHAR codecId, UINT32 cpdSize, PBYTE cpd,
PUINT32 pCpdSize, PBYTE* ppCpd, PTrackCustomData pData)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
UINT32 adaptedCodecPrivateDataSize;
PBYTE pCpd = NULL;
// Initialize to existing size
adaptedCodecPrivateDataSize = cpdSize;
// Early return on empty cpd
CHK(adaptedCodecPrivateDataSize != 0, retStatus);
// Check if the CPD needs to be adapted
if (trackType == MKV_TRACK_INFO_TYPE_VIDEO && pMkvGenerator->adaptCpdNals) {
if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H264) != MKV_CONTENT_TYPE_NONE) {
CHK_STATUS(adaptH264CpdNalsFromAnnexBToAvcc(cpd, cpdSize, NULL, &adaptedCodecPrivateDataSize));
} else if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H265) != MKV_CONTENT_TYPE_NONE) {
CHK_STATUS(adaptH265CpdNalsFromAnnexBToHvcc(cpd, cpdSize, NULL, &adaptedCodecPrivateDataSize));
}
}
// Adapt/copy the CPD
pCpd = (PBYTE) MEMALLOC(adaptedCodecPrivateDataSize);
CHK(pCpd != NULL, STATUS_NOT_ENOUGH_MEMORY);
if (trackType == MKV_TRACK_INFO_TYPE_VIDEO && pMkvGenerator->adaptCpdNals) {
if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H264) != MKV_CONTENT_TYPE_NONE) {
CHK_STATUS(adaptH264CpdNalsFromAnnexBToAvcc(cpd, cpdSize, pCpd, &adaptedCodecPrivateDataSize));
} else if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H265) != MKV_CONTENT_TYPE_NONE) {
CHK_STATUS(adaptH265CpdNalsFromAnnexBToHvcc(cpd, cpdSize, pCpd, &adaptedCodecPrivateDataSize));
}
} else {
MEMCPY(pCpd, cpd, adaptedCodecPrivateDataSize);
}
// Check whether we need to generate a video config element for
// H264, H265 or M-JJPG content type if the CPD is present
switch (trackType) {
case MKV_TRACK_INFO_TYPE_UNKOWN:
break;
case MKV_TRACK_INFO_TYPE_VIDEO:
// Check and process the H264 then H265 and later M-JPG content type
if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H264) != MKV_CONTENT_TYPE_NONE) {
// Important: The assumption here is that if this is not in AvCC format and it's in Annex-B or RAW then
// the first NALu is the SPS. We will not skip over possible SEI or AUD NALus
retStatus = getVideoWidthAndHeightFromH264Sps(pCpd, adaptedCodecPrivateDataSize, &pData->trackVideoConfig.videoWidth,
&pData->trackVideoConfig.videoHeight);
} else if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_H265) != MKV_CONTENT_TYPE_NONE) {
// Important: The assumption here is that if this is not in HvCC format and it's in Annex-B or RAW then
// the first NALu is the SPS. We will not skip over possible SEI or AUD NALus
retStatus = getVideoWidthAndHeightFromH265Sps(pCpd, adaptedCodecPrivateDataSize, &pData->trackVideoConfig.videoWidth,
&pData->trackVideoConfig.videoHeight);
} else if (((pMkvGenerator->contentType & MKV_CONTENT_TYPE_X_MKV_VIDEO) != MKV_CONTENT_TYPE_NONE) &&
(0 == STRCMP(codecId, MKV_FOURCC_CODEC_ID))) {
// For M-JPG we have content type as video/x-matroska and the codec
// type set as V_MS/VFW/FOURCC
retStatus = getVideoWidthAndHeightFromBih(pCpd, adaptedCodecPrivateDataSize, &pData->trackVideoConfig.videoWidth,
&pData->trackVideoConfig.videoHeight);
}
if (STATUS_FAILED(retStatus)) {
// This might not be yet fatal so warn and reset the status
DLOGW("Failed extracting video configuration from SPS with %08x.", retStatus);
MEMSET(&pData->trackVideoConfig, 0x00, SIZEOF(TrackVideoConfig));
retStatus = STATUS_SUCCESS;
}
break;
case MKV_TRACK_INFO_TYPE_AUDIO:
// zero out the fields
MEMSET(&pData->trackAudioConfig, 0x00, SIZEOF(TrackCustomData));
if ((pMkvGenerator->contentType & MKV_CONTENT_TYPE_AAC) != MKV_CONTENT_TYPE_NONE) {
retStatus = getSamplingFreqAndChannelFromAacCpd(pCpd, adaptedCodecPrivateDataSize, &pData->trackAudioConfig.samplingFrequency,
&pData->trackAudioConfig.channelConfig);
} else if ((pMkvGenerator->contentType & (MKV_CONTENT_TYPE_ALAW | MKV_CONTENT_TYPE_MULAW)) != MKV_CONTENT_TYPE_NONE) {
retStatus = getAudioConfigFromAmsAcmCpd(pCpd, adaptedCodecPrivateDataSize, &pData->trackAudioConfig.samplingFrequency,
&pData->trackAudioConfig.channelConfig, &pData->trackAudioConfig.bitDepth);
}
if (STATUS_FAILED(retStatus)) {
// This might not be yet fatal so warn and reset the status
DLOGW("Failed extracting audio configuration from codec private data with %08x.", retStatus);
MEMSET(&pData->trackAudioConfig, 0x00, SIZEOF(TrackAudioConfig));
retStatus = STATUS_SUCCESS;
}
break;
}
CleanUp:
*ppCpd = pCpd;
*pCpdSize = adaptedCodecPrivateDataSize;
LEAVES();
return retStatus;
}