⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfccrypto.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  const char *part4kil = "key-indicator-length";  const char *part4ivl = "IV-length";  // add 1 for null char  int   pathlen = strlen(part1)+strlen(part2a)+strlen(part3)+strlen(part4se) + 1;  char  *path;  path = (char *)malloc(pathlen);    // get selective encryption setting from the file (iSFM atom)  snprintf(path,            pathlen,	   "%s%s%s%s",           part1,	   isAudio ? part2a : part2v,           part3, part4se);  uint64_t temp;  MP4GetTrackIntegerProperty(mp4File, mediaTrackId, 			     path, &temp);  *useSelectiveEnc = temp;   // get the key indicator length from the file (iSFM atom)  snprintf(path,            pathlen,	   "%s%s%s%s",           part1,	   isAudio ? part2a : part2v,           part3, part4kil);  MP4GetTrackIntegerProperty(mp4File, mediaTrackId, 			     path, &temp);  *KIlen = temp;  // get the IV length from the file (iSFM atom)  snprintf(path,            pathlen,	   "%s%s%s%s",           part1,	   isAudio ? part2a : part2v,           part3, part4ivl);  MP4GetTrackIntegerProperty(mp4File, mediaTrackId, 			     path, &temp);  *IVlen = temp;  free(path);  return true;}// gets the AU hdr length, and the AU sample header data informationstatic bool MP4AV_ProcessIsmaCrypHdrs(MP4FileHandle mp4File, 				      MP4TrackId mediaTrackId, 				      u_int8_t samplesThisHint, 				      MP4SampleId* pSampleIds,				      u_int8_t useSelectiveEnc, 				      u_int8_t KIlen, 				      u_int8_t IVlen,				      u_int8_t *deltaIVLen,				      u_int16_t *iCrypAUHdrLen,				      ismaCrypSampleHdrDataInfo_t **iCrypSampleHdrData,				      mp4av_ismacrypParams *icPp){  int numEncAUs = 0;  u_int8_t i = 0;  u_int8_t kIPerAU = false;  /**/  kIPerAU = icPp->key_ind_perau;  *deltaIVLen = icPp->delta_iv_len;  *iCrypAUHdrLen = 0;  u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);  u_int8_t * pSampleBuffer = (u_int8_t *) malloc ((maxSampleSize + IVlen 						       + KIlen + 1)						      * sizeof(u_int8_t));  if (pSampleBuffer == NULL)     return false;  for (i = 0; i < samplesThisHint; i++) {    bool sampleIsEncrypted = false;    if (useSelectiveEnc) {      // add the 8 bits to signal if sample is encrypted       // (always present for selencryption)      *iCrypAUHdrLen += 8;      (*iCrypSampleHdrData)[i].hasEncField = 1;      // need to figure out if sample is encrypted      u_int32_t sampleSize = maxSampleSize;      bool rc = MP4ReadSample(mp4File, mediaTrackId, pSampleIds[i],       		      &pSampleBuffer, &sampleSize);      if (!rc) {        free(pSampleBuffer);	return false;      }      // check the 1st bit, if 1, then is encrypted, else is not      if (pSampleBuffer[0] & 0x01) {	sampleIsEncrypted = true;	(*iCrypSampleHdrData)[i].isEncrypted = 1;      } else {	sampleIsEncrypted = false;	(*iCrypSampleHdrData)[i].isEncrypted = 0;      }      if (pSampleBuffer != NULL) {	free(pSampleBuffer);      }    } else {      sampleIsEncrypted = true;      (*iCrypSampleHdrData)[i].isEncrypted = 1;      (*iCrypSampleHdrData)[i].hasEncField = 0;    }        if (sampleIsEncrypted) {      if ((IVlen > 0) && (numEncAUs == 0)) { // first AU of pkt	*iCrypAUHdrLen += 8 * IVlen;	(*iCrypSampleHdrData)[i].hasIVField = 1;      } else if ((IVlen > 0) && (numEncAUs > 0) && (*deltaIVLen > 0)) {	// IsmaCrypDeltaIVLength is non-zero 	*iCrypAUHdrLen += 8 * (*deltaIVLen);	(*iCrypSampleHdrData)[i].hasIVField = 1; // is delta iv field      } else {	(*iCrypSampleHdrData)[i].hasIVField = 0;      }      // the hdr has the  key indicator if this is the first encrypted AU       // of the packet or if IsmaCrypKeyIndicatorPerAU is not zero      if ((KIlen > 0) && (numEncAUs == 0 || kIPerAU)) {	*iCrypAUHdrLen += 8 * KIlen;	(*iCrypSampleHdrData)[i].hasKIField = 1;      } else {	(*iCrypSampleHdrData)[i].hasKIField = 0;      }            numEncAUs++;     }  }  return true;}// Note: this is based on MP4AV_RfcIsmaConcatenatorstatic bool MP4AV_RfcCryptoConcatenator(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId, 	MP4TrackId hintTrackId,	u_int8_t samplesThisHint, 	MP4SampleId* pSampleIds, 	MP4Duration hintDuration,	u_int16_t maxPayloadSize,	mp4av_ismacrypParams *icPp,	bool isInterleaved){  // handle degenerate case  if (samplesThisHint == 0) {    return true;  }  u_int8_t auPayloadHdrSize = 0;  // LATER would be more efficient if this were a parameter  u_int8_t mpeg4AudioType =    MP4GetTrackAudioMpeg4Type(mp4File, mediaTrackId);  if (mpeg4AudioType == MP4_MPEG4_CELP_AUDIO_TYPE) {    auPayloadHdrSize = 1;  } else {    auPayloadHdrSize = 2;  }  // construct the new hint  MP4AddRtpHint(mp4File, hintTrackId);  MP4AddRtpPacket(mp4File, hintTrackId, true);  u_int8_t payloadHeader[2];  u_int16_t numHdrBits = samplesThisHint * auPayloadHdrSize * 8;  ismaCrypSampleHdrDataInfo_t *iCrypSampleHdrInfo =     (ismaCrypSampleHdrDataInfo_t *)     malloc (samplesThisHint * sizeof(ismaCrypSampleHdrDataInfo_t));  if (iCrypSampleHdrInfo == NULL)    return false;  memset(iCrypSampleHdrInfo, 0, 	 samplesThisHint * sizeof(ismaCrypSampleHdrDataInfo_t));  u_int16_t ismaCrypAUHdrLen = 0;  u_int8_t useSelectiveEnc = 0;  u_int8_t KIlen = 0;  u_int8_t IVlen = 0;  u_int8_t deltaIVlen = 0;  if (MP4AV_GetiSFMSettings(mp4File, mediaTrackId, &useSelectiveEnc, 			    &KIlen, &IVlen, true) == false) {    return false;  }        bool rc = MP4AV_ProcessIsmaCrypHdrs(mp4File, mediaTrackId, 				      samplesThisHint, pSampleIds, 				      useSelectiveEnc, KIlen, IVlen,				      &deltaIVlen, &ismaCrypAUHdrLen,				      &iCrypSampleHdrInfo, 				      icPp);  if (rc == false) {    return false;  }  // add the AU header length AU header  numHdrBits += ismaCrypAUHdrLen;  payloadHeader[0] = numHdrBits >> 8;  payloadHeader[1] = numHdrBits & 0xFF;  MP4AddRtpImmediateData(mp4File, hintTrackId,			 (u_int8_t*)&payloadHeader, sizeof(payloadHeader));  u_int8_t i;  // add the AU headers  u_int32_t prevIV = 0;  u_int32_t prevSize = 0;  /*  u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);  u_int8_t * pSampleBuffer = (u_int8_t *) malloc ((maxSampleSize 						     + IVlen + KIlen + 1)						    * sizeof(u_int8_t));  if (pSampleBuffer == NULL)     return false;  */  for (i = 0; i < samplesThisHint; i++) {    MP4SampleId sampleId = pSampleIds[i];    u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);    u_int32_t curIV = 0;    // add the ismacryp AU header for the sample    // first read the sample data into pSampleBuffer    u_int32_t sampleSize = maxSampleSize;    u_int8_t * pSampleBuffer = (u_int8_t *) malloc ((maxSampleSize 						     + IVlen + KIlen + 1)   						    * sizeof(u_int8_t));    if (pSampleBuffer == NULL)       return false;    bool rc = MP4ReadSample(mp4File, mediaTrackId, pSampleIds[i], 			    &pSampleBuffer, &sampleSize);    if (!rc) {      return false;    }    u_int8_t * pCurPosSampleBuffer = pSampleBuffer;    // add the selective encryption header field if needed    if (iCrypSampleHdrInfo[i].hasEncField == 1) {      // if selective encryption      // add the 8 bits to signal if the sample is encrypted      // sample_is_encrypted bit + 7 reserved bits      MP4AddRtpImmediateData(mp4File, hintTrackId,			     pCurPosSampleBuffer, 1);        pCurPosSampleBuffer += 1;    }     // add the IV/delta IV header field if needed    if (iCrypSampleHdrInfo[i].hasIVField == 1) {      // get the value of the current IV      u_int32_t tmpIV = 0;      memcpy(&tmpIV, pCurPosSampleBuffer, IVlen);      // convert back to host byte order      curIV = ntohl(tmpIV);      // add the IV - from the ismacryp sample header data      if (i == 0) { // first AU	MP4AddRtpImmediateData(mp4File, hintTrackId,			       pCurPosSampleBuffer, IVlen);      } else if ((i > 0) && isInterleaved) { // subsequent AU and interleaving	u_int8_t ivdeltalen = sizeof(int8_t) * deltaIVlen;	// compute the delta IV	if (deltaIVlen == 1) {	  int8_t ivDelta = curIV - prevIV - prevSize;	  MP4AddRtpImmediateData(mp4File, hintTrackId,  			       (u_int8_t*)&ivDelta, ivdeltalen);	} else if (deltaIVlen == 2) {	  u_int16_t ivDelta = htons(curIV - prevIV - prevSize);	  MP4AddRtpImmediateData(mp4File, hintTrackId,  			       (u_int8_t*)&ivDelta, ivdeltalen);	} else if (deltaIVlen > 2) { 	  // should not happen with current ismacryp spec	  return false;	}      }     }       // there is always an IV field in the ismacryp sample header     // if IVlen > 0 so move the data pointer    pCurPosSampleBuffer += IVlen;     // add the key indicator field if needed    if (iCrypSampleHdrInfo[i].hasKIField == 1) {      // add the key indicator - from the ismacryp sample header data      MP4AddRtpImmediateData(mp4File, hintTrackId,			     pCurPosSampleBuffer, KIlen);    }    // there is always a key indicator field in the ismacryp sample header     // if KIlen > 0 so move the data pointer    pCurPosSampleBuffer += KIlen;    if (pSampleBuffer != NULL) {      free(pSampleBuffer);    }    // remove size of ismaCryp sample header from the sample size    u_int32_t ismaCrypSampleHdrSize = MP4AV_GetIsmaCrypSampleHdrSize (					iCrypSampleHdrInfo[i], IVlen, KIlen);    sampleSize = MP4GetSampleSize(mp4File, mediaTrackId, sampleId)       - ismaCrypSampleHdrSize;        if (auPayloadHdrSize == 1) {      // AU payload header is 6 bits of size      // follow by 2 bits of the difference between sampleId's - 1      payloadHeader[0] = sampleSize << 2;    } else { // auPayloadHdrSize == 2      // AU payload header is 13 bits of size      // follow by 3 bits of the difference between sampleId's - 1      payloadHeader[0] = sampleSize >> 5;      payloadHeader[1] = (sampleSize & 0x1F) << 3;    }    if (i > 0) {      payloadHeader[auPayloadHdrSize - 1] 	|= ((sampleId - pSampleIds[i-1]) - 1);     }#if 0    printf("sample %u size %u %02x %02x prev sample %d\n",             sampleId, sampleSize, payloadHeader[0],            payloadHeader[1], pSampleIds[i-1]);#endif    MP4AddRtpImmediateData(mp4File, hintTrackId,			   (u_int8_t*)&payloadHeader, auPayloadHdrSize);    prevIV = curIV;    prevSize = sampleSize;  }  // then the samples  for (i = 0; i < samplesThisHint; i++) {    MP4SampleId sampleId = pSampleIds[i];    // figure out the size of the ismacryp sample header    u_int32_t iCrypSampleHdrSize = MP4AV_GetIsmaCrypSampleHdrSize                                   (iCrypSampleHdrInfo[i], IVlen, KIlen);    // remove it from the sample size to get the real size of the data    u_int32_t sampleSize =       MP4GetSampleSize(mp4File, mediaTrackId, sampleId) - iCrypSampleHdrSize;    // use the offset parameter to point to the beginning of the data     // and skip the ismacryp sample header    MP4AddRtpSampleData(mp4File, hintTrackId, sampleId, 			iCrypSampleHdrSize, sampleSize);  }  // write the hint  MP4WriteRtpHint(mp4File, hintTrackId, hintDuration);  if (iCrypSampleHdrInfo != NULL) {    free(iCrypSampleHdrInfo);  }  return true;}// Add the RTP packet with a sample fragmentstatic bool MP4AV_RfcCryptoFragmenter(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId, 	MP4TrackId hintTrackId,	MP4SampleId sampleId, 	u_int32_t sampleSize, 	MP4Duration sampleDuration,	u_int16_t maxPayloadSize,	mp4av_ismacrypParams *icPp){  MP4AddRtpHint(mp4File, hintTrackId);  MP4AddRtpPacket(mp4File, hintTrackId, false);  // ismacryp  u_int16_t numHdrBits = 0;  ismaCrypSampleHdrDataInfo_t *iCrypSampleHdrInfo =     (ismaCrypSampleHdrDataInfo_t *)     malloc (sizeof(ismaCrypSampleHdrDataInfo_t));  if (iCrypSampleHdrInfo == NULL)    return false;  memset(iCrypSampleHdrInfo, 0, sizeof(ismaCrypSampleHdrDataInfo_t));  u_int16_t ismaCrypAUHdrLen = 0;  u_int8_t useSelectiveEnc = 0;  u_int8_t KIlen = 0;  u_int8_t IVlen = 0;  u_int8_t deltaIVlen = 0;  if (MP4AV_GetiSFMSettings(mp4File, mediaTrackId, &useSelectiveEnc, 			    &KIlen, &IVlen, true) == false) {    return false;  }  bool rc = MP4AV_ProcessIsmaCrypHdrs(mp4File, mediaTrackId, 1, &sampleId, 				      useSelectiveEnc, KIlen, IVlen,				      &deltaIVlen, &ismaCrypAUHdrLen,				      &iCrypSampleHdrInfo,				      icPp);  if (rc == false) {    return false;  }  // Note: CELP is never fragmented  // so we assume the two byte AAC-hbr payload header  numHdrBits = 16 + ismaCrypAUHdrLen; // 2 bytes for AAC AU hdr  // add size of AU headers  u_int8_t payloadHeaderSize[2];  payloadHeaderSize[0] = numHdrBits >> 8;  payloadHeaderSize[1] = numHdrBits & 0xFF;  MP4AddRtpImmediateData(mp4File, hintTrackId,			 (u_int8_t*)&payloadHeaderSize, 			 sizeof(payloadHeaderSize));  // add ismacryp AU headers  if (ismaCrypAUHdrLen > 0) {    u_int32_t tmpSampleSize = sampleSize;    u_int8_t * pSampleBuffer = (u_int8_t *) malloc ((tmpSampleSize + IVlen 						     + KIlen + 1)						    * sizeof(u_int8_t));    if (pSampleBuffer == NULL)      return false;    u_int8_t * pCurSampleBuf = pSampleBuffer;    bool rc2 = MP4ReadSample(mp4File, mediaTrackId, sampleId, 			     &pSampleBuffer, &tmpSampleSize);    if (rc2 == false) {      return false;    }    if (iCrypSampleHdrInfo[0].hasEncField == 1) {      MP4AddRtpImmediateData(mp4File, hintTrackId, pCurSampleBuf, 1);        pCurSampleBuf += 1;    }     if (iCrypSampleHdrInfo[0].hasIVField == 1) {      MP4AddRtpImmediateData(mp4File, hintTrackId, pCurSampleBuf, IVlen);    }    pCurSampleBuf += IVlen;    if (iCrypSampleHdrInfo[0].hasKIField == 1) {      MP4AddRtpImmediateData(mp4File, hintTrackId, pCurSampleBuf, KIlen);    }    pCurSampleBuf += KIlen;        if (pSampleBuffer != NULL) {      free(pSampleBuffer);    }  }  // remove size of ismaCryp sample header from the sample size  u_int32_t ismaCrypSampleHdrSize = MP4AV_GetIsmaCrypSampleHdrSize (					 iCrypSampleHdrInfo[0], IVlen, KIlen);  sampleSize -= ismaCrypSampleHdrSize;    // add AAC AU header  u_int8_t payloadHeader[2];  payloadHeader[0] = sampleSize >> 5;  payloadHeader[1] = (sampleSize & 0x1F) << 3;  MP4AddRtpImmediateData(mp4File, hintTrackId,			 (u_int8_t*)&payloadHeader, sizeof(payloadHeader));  // start after the ismaCrypSampleHdr  u_int16_t sampleOffset = ismaCrypSampleHdrSize;   u_int16_t fragLength = maxPayloadSize - 4;  do {    MP4AddRtpSampleData(mp4File, hintTrackId,			sampleId, sampleOffset, fragLength);    sampleOffset += fragLength;    if (sampleSize - sampleOffset > maxPayloadSize) {      fragLength = maxPayloadSize;       MP4AddRtpPacket(mp4File, hintTrackId, false);    } else {      fragLength = sampleSize - sampleOffset;       if (fragLength) {	MP4AddRtpPacket(mp4File, hintTrackId, true);      }    }  } while (sampleOffset < sampleSize);    MP4WriteRtpHint(mp4File, hintTrackId, sampleDuration);  return true;}// based on MP4AV_RfcIsmaHinter, with ismacryp SDP addedextern "C" bool MP4AV_RfcCryptoAudioHinter(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId,         mp4av_ismacrypParams *icPp,	bool interleave,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -