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

📄 mp4creator.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  return pTrackIds;}void CreateHintTrack(MP4FileHandle mp4File, MP4TrackId mediaTrackId,		     const char* payloadName, bool interleave, 		     u_int16_t maxPayloadSize, bool doEncrypt){  bool rc = FALSE;  if (MP4GetTrackNumberOfSamples(mp4File, mediaTrackId) == 0) {    fprintf(stderr, 	    "%s: couldn't create hint track, no media samples\n", ProgName);    MP4Close(mp4File);    exit(EXIT_CREATE_HINT);  }  // vector out to specific hinters  const char* trackType = MP4GetTrackType(mp4File, mediaTrackId);  if (doEncrypt || MP4IsIsmaCrypMediaTrack(mp4File, mediaTrackId)) {    ismacryp_session_id_t icSID;    mp4av_ismacrypParams *icPp =  (mp4av_ismacrypParams *) malloc(sizeof(mp4av_ismacrypParams));    memset(icPp, 0, sizeof(mp4av_ismacrypParams));    if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {       if (ismacrypInitSession(&icSID, KeyTypeAudio) != 0) {          fprintf(stderr, 	      "%s: can't hint, error in init ismacryp session\n", ProgName);          goto quit_error;       }    }    else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {       if (ismacrypInitSession(&icSID, KeyTypeVideo) != 0) {          fprintf(stderr, 	      "%s: can't hint, error in init ismacryp session\n", ProgName);          goto quit_error;       }    }    else {      fprintf(stderr, 	      "%s: can't hint track type %s\n", ProgName, trackType);      goto quit_error;    }        // get all the ismacryp parameters needed by the hinters:    if (ismacrypGetKeyCount(icSID, &(icPp->key_count)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting key count for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetKeyIndicatorLength(icSID, &(icPp->key_ind_len)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting key ind len for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetKeyIndPerAU(icSID, &(icPp->key_ind_perau)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting key ind per au for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetSelectiveEncryption(icSID, &(icPp->selective_enc)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting selective enc for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetDeltaIVLength(icSID, &(icPp->delta_iv_len)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting delta iv len for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetIVLength(icSID, &(icPp->iv_len)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting iv len for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetScheme(icSID, (ismacryp_scheme_t *) &(icPp->scheme)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting scheme for session %d\n",                ProgName, icSID);      goto quit_error;    }    if (ismacrypGetKey(icSID, 1,&(icPp->key_len),&(icPp->salt_len),                       &(icPp->key),&(icPp->salt),&(icPp->key_life)) != 0) {      fprintf(stderr, 	      "%s: can't hint, error getting scheme for session %d\n",                ProgName, icSID);      goto quit_error;    }    goto ok_continue;    quit_error:    ismacrypEndSession(icSID);    MP4Close(mp4File);    exit(EXIT_CREATE_HINT);    ok_continue:    if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {      rc = MP4AV_RfcCryptoAudioHinter(mp4File, mediaTrackId,                                       icPp, 				      interleave, maxPayloadSize, 				      "enc-mpeg4-generic");      ismacrypEndSession(icSID);    } else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {      rc = MP4AV_RfcCryptoVideoHinter(mp4File, mediaTrackId,                                       icPp,                                       maxPayloadSize,				      "enc-mpeg4-generic");      ismacrypEndSession(icSID);    } else {      fprintf(stderr, 	      "%s: can't hint track type %s\n", ProgName, trackType);    }  }  else if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {    const char *media_data_name;    media_data_name = MP4GetTrackMediaDataName(mp4File, mediaTrackId);        if (strcasecmp(media_data_name, "mp4a") == 0) {      u_int8_t audioType = MP4GetTrackEsdsObjectTypeId(mp4File, mediaTrackId);      switch (audioType) {      case MP4_INVALID_AUDIO_TYPE:      case MP4_MPEG4_AUDIO_TYPE:	if (payloadName && 	    (strcasecmp(payloadName, "latm") == 0 ||	     strcasecmp(payloadName, "mp4a-latm") == 0)) {	  rc = MP4AV_Rfc3016LatmHinter(mp4File, mediaTrackId, 				       maxPayloadSize);	  break;	}      case MP4_MPEG2_AAC_MAIN_AUDIO_TYPE:      case MP4_MPEG2_AAC_LC_AUDIO_TYPE:      case MP4_MPEG2_AAC_SSR_AUDIO_TYPE:	rc = MP4AV_RfcIsmaHinter(mp4File, mediaTrackId, 				 interleave, maxPayloadSize);	break;      case MP4_MPEG1_AUDIO_TYPE:      case MP4_MPEG2_AUDIO_TYPE:	if (payloadName && 	    (!strcasecmp(payloadName, "3119") 	     || !strcasecmp(payloadName, "mpa-robust"))) {	  rc = MP4AV_Rfc3119Hinter(mp4File, mediaTrackId, 				   interleave, maxPayloadSize);	} else {	  rc = MP4AV_Rfc2250Hinter(mp4File, mediaTrackId, 				   false, maxPayloadSize);	}	break;      case MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE:      case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE:	rc = L16Hinter(mp4File, mediaTrackId, maxPayloadSize);	break;      case MP4_ULAW_AUDIO_TYPE:      case MP4_ALAW_AUDIO_TYPE:	rc = G711Hinter(mp4File, mediaTrackId, maxPayloadSize);	break;      default:	fprintf(stderr, 		"%s: can't hint non-MPEG4/non-MP3 audio type\n", ProgName);      }    } else if (strcasecmp(media_data_name, "samr") == 0 ||	       strcasecmp(media_data_name, "sawb") == 0) {      rc = MP4AV_Rfc3267Hinter(mp4File, mediaTrackId, maxPayloadSize);    }  } else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {    const char *media_data_name;    media_data_name = MP4GetTrackMediaDataName(mp4File, mediaTrackId);        if (strcasecmp(media_data_name, "mp4v") == 0) {      u_int8_t videoType = MP4GetTrackEsdsObjectTypeId(mp4File, mediaTrackId);            switch (videoType) {      case MP4_MPEG4_VIDEO_TYPE:	rc = MP4AV_Rfc3016Hinter(mp4File, mediaTrackId, maxPayloadSize);	break;      case MP4_MPEG1_VIDEO_TYPE:      case MP4_MPEG2_SIMPLE_VIDEO_TYPE:      case MP4_MPEG2_MAIN_VIDEO_TYPE:	rc = Mpeg12Hinter(mp4File, mediaTrackId, maxPayloadSize);	break;      default:	fprintf(stderr, 		"%s: can't hint non-MPEG4 video type\n", ProgName);	break;      }    } else if (strcasecmp(media_data_name, "avc1") == 0) {      // h264;      rc = MP4AV_H264Hinter(mp4File, mediaTrackId, maxPayloadSize);    } else if (strcasecmp(media_data_name, "s263") == 0) {      rc = MP4AV_Rfc2429Hinter(mp4File, mediaTrackId, maxPayloadSize);    }  } else {    fprintf(stderr, 	    "%s: can't hint track type %s\n", ProgName, trackType);  }  if (!rc) {    fprintf(stderr, 	    "%s: error hinting track %u\n", ProgName, mediaTrackId);    MP4Close(mp4File);    exit(EXIT_CREATE_HINT);  }}static void extract_h264_track (MP4FileHandle mp4File, 				MP4TrackId trackId,				int outFd,				const char *outputFileName){  uint8_t **seqheader, **pictheader;  uint32_t *pictheadersize, *seqheadersize;  uint32_t ix;  uint8_t header[4] = {0, 0, 0, 1};  MP4GetTrackH264SeqPictHeaders(mp4File, trackId, 				&seqheader, &seqheadersize,				&pictheader, &pictheadersize);  for (ix = 0; seqheadersize[ix] != 0; ix++) {    write(outFd, header, 4);    write(outFd, seqheader[ix], seqheadersize[ix]);  }  for (ix = 0; pictheadersize[ix] != 0; ix++) {    write(outFd, header, 4);    write(outFd, pictheader[ix], pictheadersize[ix]);  }    MP4SampleId numSamples =     MP4GetTrackNumberOfSamples(mp4File, trackId);  u_int8_t* pSample;  u_int32_t sampleSize;  uint32_t buflen_size;  MP4GetTrackH264LengthSize(mp4File, trackId, &buflen_size);  // extraction loop  for (MP4SampleId sampleId = 1 ; sampleId <= numSamples; sampleId++) {    pSample = NULL;    sampleSize = 0;    int rc = MP4ReadSample(			 mp4File, 			 trackId, 			 sampleId, 			 &pSample, 			 &sampleSize);    if (rc == 0) {      fprintf(stderr, "%s: read sample %u for %s failed\n",	      ProgName, sampleId, outputFileName);      exit(EXIT_EXTRACT_TRACK);    }    uint32_t read_offset = 0;    uint32_t nal_len;    bool first = true;#if 0    printf("\n\nsample id: %u\n", sampleId);#endif    do {#if 0      printf("read offset %u buflen %u sample Size %u\n", 	     read_offset, buflen_size, sampleSize);#endif      if (read_offset + buflen_size >= sampleSize) {	fprintf(stderr, 		"extra bytes at end of sample %d - nal len size %u, %u bytes left", 		sampleId, buflen_size, sampleSize - read_offset);	read_offset = sampleSize;      } else {	if (buflen_size == 1) {	  nal_len = pSample[read_offset];	} else {	  nal_len = (pSample[read_offset] << 8) | pSample[read_offset + 1];	  if (buflen_size == 4) {	  nal_len <<= 16;	  nal_len |= (pSample[read_offset + 2] << 8) | pSample[read_offset + 3];	  }	}#if 0	printf("read offset %u nallen %u sample Size %u %d\n", 	       read_offset, nal_len, sampleSize, first);#endif	if (read_offset + nal_len > sampleSize) {	  fprintf(stderr, 		  "nal length past end of buffer - sample %u size %u frame offset %u left %u\n",		  sampleId, nal_len, read_offset, sampleSize - read_offset);	  read_offset = sampleSize;	} else {	  if (first) {	    write(outFd, header, 4);	    first = false;	  } else {	    write(outFd, header + 1, 3);	  }	  // printf("sample id %d size %u %x\n", sampleId, nal_len, nal_len);	  write(outFd, pSample + read_offset + buflen_size,		nal_len);	  read_offset += nal_len + buflen_size;	}      }    } while (read_offset < sampleSize);    free(pSample);  }  close(outFd);}void ExtractTrack (MP4FileHandle mp4File, MP4TrackId trackId, 		   const char* outputFileName){  int openFlags = O_WRONLY | O_TRUNC | OPEN_CREAT;  u_int8_t amrType = AMR_TYPE_NONE;  int outFd = open(outputFileName, openFlags, 0644);  if (outFd == -1) {    fprintf(stderr, "%s: can't open %s: %s\n",	    ProgName, outputFileName, strerror(errno));    exit(EXIT_EXTRACT_TRACK);  }  // some track types have special needs  // to properly recreate their raw ES file  bool prependES = false;  bool prependADTS = false;  const char* trackType =    MP4GetTrackType(mp4File, trackId);  const char *media_data_name =     MP4GetTrackMediaDataName(mp4File, trackId);  if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) {    if (strcmp(media_data_name, "avc1") == 0) {      extract_h264_track(mp4File, trackId, outFd, outputFileName);      return;    }    prependES = true;  } else if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) {    if (strcmp(media_data_name, "mp4a") == 0) {      uint8_t type = 		MP4GetTrackEsdsObjectTypeId(mp4File, trackId);      if (MP4_IS_AAC_AUDIO_TYPE(type) || 	  type == MP4_MPEG4_INVALID_AUDIO_TYPE)      prependADTS = true;    } else if (strcmp(media_data_name, "sawb") == 0) {      amrType = AMR_TYPE_AMRWB;    } else if (strcmp(media_data_name, "samr") == 0) {      amrType = AMR_TYPE_AMR;    }    switch (amrType) {    case AMR_TYPE_AMR:      if (write(outFd, AMR_MAGIC_AMR, AMR_MAGIC_LEN_AMR) != AMR_MAGIC_LEN_AMR) {        fprintf(stderr, "%s: can't write to file: %s\n",		ProgName, strerror(errno));        return;      }      break;    case AMR_TYPE_AMRWB:      if (write(outFd, AMR_MAGIC_AMRWB, AMR_MAGIC_LEN_AMRWB) != AMR_MAGIC_LEN_AMRWB) {        fprintf(stderr, "%s: can't write to file: %s\n",		ProgName, strerror(errno));        return;      }      break;    default:      break;    }  }  MP4SampleId numSamples = #if 1    MP4GetTrackNumberOfSamples(mp4File, trackId);#else  1;#endif  u_int8_t* pSample;  u_int32_t sampleSize;  // extraction loop  for (MP4SampleId sampleId = 1 ; sampleId <= numSamples; sampleId++) {    int rc;    // signal to ReadSample()     // that it should malloc a buffer for us    pSample = NULL;    sampleSize = 0;    if (prependADTS) {      // need some very specialized work for these      MP4AV_AdtsMakeFrameFromMp4Sample(				       mp4File,				       trackId,				       sampleId,				       aacProfileLevel,				       &pSample,				       &sampleSize);    } else {      // read the sample      rc = MP4ReadSample(			 mp4File, 			 trackId, 			 sampleId, 			 &pSample, 			 &sampleSize);      if (rc == 0) {	fprintf(stderr, "%s: read sample %u for %s failed\n",		ProgName, sampleId, outputFileName);	exit(EXIT_EXTRACT_TRACK);      }      if (prependES && sampleId == 1) {	u_int8_t* pConfig = NULL;	u_int32_t configSize = 0;		if (MP4GetTrackESConfiguration(mp4File, trackId, 				       &pConfig, &configSize)) {				  if (configSize != 0) {	    write(outFd, pConfig, configSize);	  }	  CHECK_AND_FREE(pConfig);	}      }    }    rc = write(outFd, pSample, sampleSize);    if (rc == -1 || (u_int32_t)rc != sampleSize) {      fprintf(stderr, "%s: write to %s failed: %s\n",	      ProgName, outputFileName, strerror(errno));      exit(EXIT_EXTRACT_TRACK);    }    free(pSample);  }  // close ES file  close(outFd);}bool Is3GPP(MP4FileHandle mp4File){  u_int32_t numberOfTracks = MP4GetNumberOfTracks(mp4File);  u_int32_t i;   for (i = 0 ; i < numberOfTracks ; i++) {    MP4TrackId trackId = MP4FindTrackId(mp4File, i);    const char *type, *media_data_name;    type = MP4GetTrackType(mp4File, trackId);    media_data_name = MP4GetTrackMediaDataName(mp4File, trackId);    if (strcmp(type, MP4_VIDEO_TRACK_TYPE) == 0) {      if (strcmp(media_data_name, "s263") != 0) {	return false;      }    } else if (strcmp(type, MP4_AUDIO_TRACK_TYPE) == 0) {      if (strcmp(media_data_name, "samr") != 0 &&	  strcmp(media_data_name, "sawb") != 0)	return false;    }  }  return true;}

⌨️ 快捷键说明

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