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; }
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; }
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; }