Esempio n. 1
0
bool CX264VideoEncoder::GetEsConfig (uint8_t **ppEsConfig, 
				     uint32_t *pEsConfigLen)
{
#ifdef DEBUG_H264
  debug_message("Getting es config for x264");
#endif
  CHECK_AND_FREE(Profile()->m_videoMpeg4Config);
  Profile()->m_videoMpeg4ConfigLength = 0;

  x264_nal_t *nal;
  int nal_num;
  if (x264_encoder_headers(m_h, &nal, &nal_num) != 0) {
    error_message("x264 - can't create headers");
    StopEncoder();
    return false;
  }
  
  uint8_t *seqptr = m_vopBuffer;
  uint8_t *picptr = m_vopBuffer;
  uint32_t seqlen = 0, piclen = 0;
  bool found_seq = false, found_pic = false;
  if (m_vopBuffer == NULL) {
    m_vopBuffer = (u_int8_t*)malloc(Profile()->m_videoMaxVopSize);
  }
  uint8_t *vopBuffer = m_vopBuffer;
  int vopBufferLen = Profile()->m_videoMaxVopSize;

  for (int ix = 0; ix < nal_num; ix++) {
    int i_size;
    i_size = x264_nal_encode(vopBuffer, &vopBufferLen, 1, &nal[ix]);
    if (i_size > 0) {
      bool useit = false;
      uint header_size = 0;
      if (h264_is_start_code(vopBuffer)) {
	header_size = vopBuffer[2] == 1 ? 3 : 4;
      }
      if (nal[ix].i_type == H264_NAL_TYPE_SEQ_PARAM) {
	found_seq = true;
	seqlen = i_size - header_size;
	seqptr = vopBuffer + header_size;
	useit = true;
      } else if (nal[ix].i_type == H264_NAL_TYPE_PIC_PARAM) {
	found_pic = true;
	piclen = i_size - header_size;
	picptr = vopBuffer + header_size;
	useit = true;
      }
      if (useit) {
	vopBuffer += i_size;
	vopBufferLen -= i_size;
      }
    }
  }
	  
  if (found_seq == false) {
    error_message("Can't find seq pointer in x264 header");
    StopEncoder();
    return false;
  }
  if (found_pic == false) {
    error_message("Can't find pic pointer in x264 header");
    StopEncoder();
    return false;
  }

  uint8_t *p = seqptr;
  
  if (*p == 0 && p[1] == 0 && 
      (p[2] == 1 || (p[2] == 0 && p[3] == 1))) {
    if (p[2] == 0) p += 4;
    else p += 3;
  }
  Profile()->m_videoMpeg4ProfileId = p[1] << 16 |
    p[2] << 8 |
    p[3];

  debug_message("profile id %x", Profile()->m_videoMpeg4ProfileId);
  
  char *sprop = NULL;
  char *base64;
  base64 = MP4BinaryToBase64(seqptr, seqlen);
  sprop = strdup(base64);
  free(base64);
  base64 = MP4BinaryToBase64(picptr, piclen);
  sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
  strcat(sprop, ",");
  strcat(sprop, base64);
  free(base64);

  debug_message("sprop %s", sprop);
  Profile()->m_videoMpeg4Config = (uint8_t *)sprop;
  Profile()->m_videoMpeg4ConfigLength = strlen(sprop) + 1;
  StopEncoder();
  return true;
}
Esempio n. 2
0
 extern "C" MP4TrackId MP4AV_AVSM_HintTrackCreate (MP4FileHandle mp4File,
						  MP4TrackId mediaTrackId)
{
  MP4TrackId hintTrackId =
    MP4AddHintTrack(mp4File, mediaTrackId);						//添加hint相关的原子mdia.minf.hmhd;mdia.minf.stbl.stsd.rtp
																//mdia.minf.stbl.stsd.rtp .tims.timeScale;tref.hint;udta.hnti.sdp
																//udta.hinf
 
  
  if (hintTrackId == MP4_INVALID_TRACK_ID) {					
    return MP4_INVALID_TRACK_ID;
  }

  u_int8_t payloadNumber = MP4_SET_DYNAMIC_PAYLOAD;

  // don't include mpeg4-esid
  MP4SetHintTrackRtpPayload(mp4File, hintTrackId, 
			    "AVSM", &payloadNumber, 0,						//改变名称“H264”
			    NULL, true, false);
				
  // get the mpeg4 video configuration 
  u_int8_t **pSeq, **pPict ;
  u_int32_t *pSeqSize, *pPictSize;								//参数改变
  char *base64;
  uint32_t profile_level;
  char *sprop = NULL;
  uint32_t ix = 0;

 MP4GetTrackAVSMSeqPictHeaders(mp4File,
				mediaTrackId,
				&pSeq,
				&pSeqSize,										//**获得序列头和图像头相关参数pSeq,pSeqSize,pPict,pPictSize
				&pPict,
				&pPictSize);
				      
  if (pSeqSize && pSeqSize[0] != 0) {								//添加seq参数集
    // we have valid sequence and picture headers
    uint8_t *p = pSeq[0];
    if (*p == 0 && p[1] == 0 && 
	(p[2] == 1 || (p[2] == 0 && p[3] == 0))) {
      if (p[2] == 0) p += 4;
      else p += 3;
    }
    profile_level = p[1] << 8 | p[2];
    while (pSeqSize[ix] != 0) {
      base64 = MP4BinaryToBase64(pSeq[ix], pSeqSize[ix]);
      if (sprop == NULL) {
	sprop = strdup(base64);
      } else {
	sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
	strcat(sprop, ",");
	strcat(sprop, base64);
      }
      free(base64);
      free(pSeq[ix]);
      ix++;
    }
    free(pSeq);
    free(pSeqSize);

    ix = 0;
    while (pPictSize[ix] != 0) {									//添加picture参数集
      base64 = MP4BinaryToBase64(pPict[ix], pPictSize[ix]);
      sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
      strcat(sprop, ",");
      strcat(sprop, base64);
      free(base64);
      free(pPict[ix]);
      ix++;
    }																
    free(pPict);
    free(pPictSize);

    // create the appropriate SDP attribute *
    char* sdpBuf = (char*)malloc(strlen(sprop) + 128);				//sdp
	
	u_int16_t svideoWidth = MP4GetTrackVideoWidth(mp4File, mediaTrackId);		
	u_int16_t svideoHeight = MP4GetTrackVideoHeight(mp4File, mediaTrackId);	//********添加********
  
	  
    sprintf(sdpBuf,
		"a=cliprect:0,0,%d,%d\015\012"
	    "a=fmtp:%u profile-level-id=%04x; sprop-parameter-sets=%s; packetization-mode=1\015\012",
	    svideoWidth,
		svideoHeight,
		payloadNumber,
	    profile_level,
	    sprop); 
	  
    /* add this to the track's sdp */
    MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
	  
    free(sprop);
    free(sdpBuf);
  }
  return hintTrackId;
}
Esempio n. 3
0
extern "C" MP4TrackId MP4AV_H264_HintTrackCreate (MP4FileHandle mp4File,
						  MP4TrackId mediaTrackId)
{
  MP4TrackId hintTrackId =
    MP4AddHintTrack(mp4File, mediaTrackId);

  if (hintTrackId == MP4_INVALID_TRACK_ID) {
    return MP4_INVALID_TRACK_ID;
  }

  u_int8_t payloadNumber = MP4_SET_DYNAMIC_PAYLOAD;

  // don't include mpeg4-esid
  MP4SetHintTrackRtpPayload(mp4File, hintTrackId, 
			    "H264", &payloadNumber, 0,
			    NULL, true, false);

  /* get the mpeg4 video configuration */
  u_int8_t **pSeq, **pPict ;
  u_int32_t *pSeqSize, *pPictSize;
  char *base64;
  uint32_t profile_level;
  char *sprop = NULL;
  uint32_t ix = 0;

  MP4GetTrackH264SeqPictHeaders(mp4File,
				mediaTrackId,
				&pSeq,
				&pSeqSize,
				&pPict,
				&pPictSize);
				      
  if (pSeqSize && pSeqSize[0] != 0) {
    // we have valid sequence and picture headers
    uint8_t *p = pSeq[0];
    if (*p == 0 && p[1] == 0 && 
	(p[2] == 1 || (p[2] == 0 && p[3] == 0))) {
      if (p[2] == 0) p += 4;
      else p += 3;
    }
    profile_level = p[0] << 16 |
      p[1] << 8 |
      p[2];
    while (pSeqSize[ix] != 0) {
      base64 = MP4BinaryToBase64(pSeq[ix], pSeqSize[ix]);
      if (sprop == NULL) {
	sprop = strdup(base64);
      } else {
	sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
	strcat(sprop, ",");
	strcat(sprop, base64);
      }
      free(base64);
      free(pSeq[ix]);
      ix++;
    }
    free(pSeq);
    free(pSeqSize);

    ix = 0;
    while (pPictSize[ix] != 0) {
      base64 = MP4BinaryToBase64(pPict[ix], pPictSize[ix]);
      sprop = (char *)realloc(sprop, strlen(sprop) + strlen(base64) + 1 + 1);
      strcat(sprop, ",");
      strcat(sprop, base64);
      free(base64);
      free(pPict[ix]);
      ix++;
    }
    free(pPict);
    free(pPictSize);

    /* create the appropriate SDP attribute */
    char* sdpBuf = (char*)malloc(strlen(sprop) + 128);
	  
    sprintf(sdpBuf,
	    "a=fmtp:%u profile-level-id=%06x; sprop-parameter-sets=%s; packetization-mode=1\015\012",
	    payloadNumber,
	    profile_level,
	    sprop); 
	  
    /* add this to the track's sdp */
    MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);
	  
    free(sprop);
    free(sdpBuf);
  }
  return hintTrackId;
}