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

📄 h264.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	return 1;}/* * Parse the RBSP with NAL unit type of IDR(Coded slice of an IDR picture), and * get the slice type(I,P,B) of this slice. */static int parseNALU_IDR_SLICE(u_int8_t* pBuf, u_int32_t* pBufSize, u_int32_t* slice_type){	u_int32_t 	tmp, i = 0, j = 0;		// SH: first_mb_in_slice : ue(v)	ue_v(pBuf, &i, &j);	// SH: slice_type : ue(v)	tmp = ue_v(pBuf, &i, &j);	if (tmp > 4) {		tmp -= 5;	}	*slice_type =  tmp;		return 1;}MP4TrackId H264Creator(MP4FileHandle mp4File, FILE* inFile){	bool rc; 	u_int8_t sampleBuffer[256 * 1024];	u_int8_t analyzeBuffer[256 * 1024];	u_int32_t maxSampleSize = sizeof(sampleBuffer);		u_int8_t* pCurrentBuf = sampleBuffer;	u_int8_t* pNaluBuf = sampleBuffer;	u_int32_t naluBufSize;	u_int8_t* pRbspBuf = analyzeBuffer;	u_int32_t rbspBufSize;	// the current sample	MP4SampleId sampleId = 1;	MP4Timestamp currentSampleTime = 0;	// the last reference VOP 	MP4SampleId refVopId = 1;	MP4Timestamp refVopTime = 0;	// track configuration info	u_int8_t videoProfileLevel = 0x03;	u_int16_t timeTicks = 1;	u_int16_t slice_width = 320;	u_int16_t slice_height = 240;	u_int32_t esConfigSize = 0;	u_int32_t slice_type = 0;		u_int32_t forbidden_bit;	u_int32_t nal_ref_idc;	u_int32_t nal_unit_type;		bool foundSPS = false, foundPPS = false, foundIDR = false;	// start reading NAL unit until we get the first NAL unit with IDR	do {		if (!LoadNextNALU(inFile, pNaluBuf, &naluBufSize)) {			fprintf(stderr, "%s : No NAL unit with type of IDR!\n", ProgName);			return MP4_INVALID_TRACK_ID;		}		rbspBufSize = naluBufSize;		memcpy(pRbspBuf, pNaluBuf, naluBufSize);		parseAnnexbNALU(pRbspBuf, &rbspBufSize, &forbidden_bit, 				&nal_ref_idc, &nal_unit_type);		switch (nal_unit_type)		{			case NALU_TYPE_SPS: // NALU_TYPE_SPS				parseNALU_SPS(pRbspBuf, &rbspBufSize, &slice_width, &slice_height);				fprintf(stderr, "Parse SPS NALU: img_width = %d, img_height = %d\n",slice_width, slice_height);						foundSPS = true;				break;			case NALU_TYPE_PPS: // NALU_TYPE_PPS				foundPPS = true;				break;			case NALU_TYPE_IDR:					foundIDR = true;				break;			case NALU_TYPE_SLICE:				break;		}		if (!foundIDR) {			esConfigSize += naluBufSize;			pNaluBuf += naluBufSize;		}			}	while (!foundIDR);	if (foundSPS == false) {		fprintf(stderr,			"%s: fatal: No NAL unit type of SPS found in video stream\n",			ProgName);		return MP4_INVALID_TRACK_ID;	}	if (foundPPS == false) {		 fprintf(stderr,			"%s: fatal: No NAL unit type of PPS found in video stream\n",	 		 ProgName);		 return MP4_INVALID_TRACK_ID;	}	timeTicks = 1;	u_int32_t mp4FrameDuration;	// convert frame duration to canonical time scale	if (VideoFrameRate) {		mp4FrameDuration = (u_int32_t)(((float)Mp4TimeScale) / VideoFrameRate);	}	else {		mp4FrameDuration = (u_int32_t)(((float)Mp4TimeScale) / 25);	}	// create the new video track	MP4TrackId trackId = 		MP4AddVideoTrack(				mp4File,				Mp4TimeScale,				mp4FrameDuration,				slice_width,				slice_height,				MP4_H264_VIDEO_TYPE);		if (trackId == MP4_INVALID_TRACK_ID)	{		fprintf(stderr, 			"%s: can't create video track\n", ProgName);		return MP4_INVALID_TRACK_ID;	}				if (VideoProfileLevelSpecified) {      		videoProfileLevel = VideoProfileLevel;	}		if (MP4GetNumberOfTracks(mp4File, MP4_VIDEO_TRACK_TYPE) == 1) {		MP4SetVideoProfileLevel(mp4File, 			MP4AV_Mpeg4VideoToSystemsProfileLevel(videoProfileLevel));	}	if (esConfigSize) {		MP4SetTrackESConfiguration(mp4File, trackId, 			pCurrentBuf, esConfigSize);//		 pCurrentBuf += esConfigSize;		}	// now process the rest of the video stream	while (true) {		if (nal_unit_type != NALU_TYPE_IDR && nal_unit_type != NALU_TYPE_SLICE) {			// keep it in the buffer until a IDR comes along			pNaluBuf += naluBufSize;		} else { // we have a IDR			u_int32_t sampleSize = (pNaluBuf + naluBufSize) - pCurrentBuf;			memcpy(pRbspBuf, pNaluBuf, naluBufSize);			rbspBufSize = naluBufSize;			parseAnnexbNALU(pRbspBuf, &rbspBufSize,				       	&forbidden_bit, &nal_ref_idc, &nal_unit_type);			parseNALU_IDR_SLICE(pRbspBuf, &rbspBufSize, &slice_type);			rc = MP4WriteSample(mp4File, trackId, 				pCurrentBuf, sampleSize,				mp4FrameDuration, 0, slice_type==I_SLICE);			if (!rc) {				fprintf(stderr,						"%s: can't write video frame %u\n",					 ProgName, sampleId);				MP4DeleteTrack(mp4File, trackId);				return MP4_INVALID_TRACK_ID;			}			// deal with rendering time offsets 			// that can occur when B frames are being used 			// which is the case for all profiles except Simple Profile			if (slice_type != 1) {				if (videoProfileLevel > 3) {					// Note - this writes to the previous					// I or P frame					MP4SetSampleRenderingOffset(						mp4File, trackId, refVopId,						currentSampleTime - refVopTime);				}				refVopId = sampleId;				refVopTime = currentSampleTime;			}			 			fprintf(stderr,"Frame:%d,   type(%d): %s, size: %d bytes\n",  				sampleId, slice_type, slice_type==I_SLICE?"I":slice_type==P_SLICE?"P":slice_type==B_SLICE?"B":slice_type==SI_SLICE?"SI":slice_type==SP_SLICE?"SP":"?", sampleSize);						sampleId++;			currentSampleTime += mp4FrameDuration;			// reset pointers			pNaluBuf = pCurrentBuf = sampleBuffer;		}		// load next NAL unit from bitstream		if (!LoadNextNALU(inFile, pNaluBuf, &naluBufSize)) {			break;		}		// guard against buffer overflow		if (pNaluBuf + naluBufSize >= pCurrentBuf + maxSampleSize) {			fprintf(stderr,					"%s: buffer overflow, invalid video stream?\n", ProgName);			MP4DeleteTrack(mp4File, trackId);			return MP4_INVALID_TRACK_ID;		}	}		// Left over at end - make sure we set the last P or I frame	// with the last time	if (videoProfileLevel > 3) {	  MP4SetSampleRenderingOffset(mp4File, trackId, refVopId,				      currentSampleTime - refVopTime);	}	return trackId;}bool MP4AV_H264Hinter(	MP4FileHandle mp4File, 	MP4TrackId mediaTrackId, 	u_int16_t maxPayloadSize){	u_int32_t numSamples = MP4GetTrackNumberOfSamples(mp4File, mediaTrackId);	u_int32_t maxSampleSize = MP4GetTrackMaxSampleSize(mp4File, mediaTrackId);					if (numSamples == 0 || maxSampleSize == 0) {		return false;	}	MP4TrackId hintTrackId =		MP4AddHintTrack(mp4File, mediaTrackId);	if (hintTrackId == MP4_INVALID_TRACK_ID) {		return false;	}	u_int8_t payloadNumber = MP4_SET_DYNAMIC_PAYLOAD;		MP4SetHintTrackRtpPayload(mp4File, hintTrackId, 			"H264", &payloadNumber, 0);		/* get the mpeg4 video configuration */	u_int8_t* pConfig;	u_int32_t configSize;	u_int8_t systemsProfileLevel = 0x01; // temporary value		MP4GetTrackESConfiguration(mp4File, mediaTrackId, &pConfig, &configSize);		if (pConfig) {		/* convert it into ASCII form */		char* sConfig = MP4BinaryToBase16(pConfig, configSize);		if (sConfig == NULL) {			MP4DeleteTrack(mp4File, hintTrackId);			return false;		}		/* create the appropriate SDP attribute */		char* sdpBuf = (char*)malloc(strlen(sConfig) + 128);				sprintf(sdpBuf, 			"a=fmtp:%u profile-level-id=%u; config=%s;\015\012",				payloadNumber,				systemsProfileLevel,				sConfig);		/* add this to the track's sdp */		MP4AppendHintTrackSdp(mp4File, hintTrackId, sdpBuf);				free(sConfig);		free(sdpBuf);	}	u_int8_t* pSampleBuffer = (u_int8_t*)malloc(maxSampleSize);	if (pSampleBuffer == NULL) {		MP4DeleteTrack(mp4File, hintTrackId);		return false;	}	for (MP4SampleId sampleId = 1; sampleId <= numSamples; sampleId++) {		u_int32_t sampleSize = maxSampleSize;		MP4Timestamp startTime;		MP4Duration duration;		MP4Duration renderingOffset;		bool isSyncSample;		u_int32_t forbidden_bit, nal_ref_idc, nal_unit_type;		u_int32_t slice_type;				bool rc = MP4ReadSample(				mp4File, mediaTrackId, sampleId, 				&pSampleBuffer, &sampleSize, 				&startTime, &duration, 				&renderingOffset, &isSyncSample);		// 		FILE *file;		// 		file = fopen("out.dat","ab");// 		fwrite(pSampleBuffer, 1, sampleSize, file);// 		fclose(file);// 		file = fopen("out.txt", "a");// 		fprintf(file, "SampleId = %d, Size = %d\n", sampleId, sampleSize);// 		fclose(file);				if (!rc) {			MP4DeleteTrack(mp4File, hintTrackId);			return false;		}				u_int32_t tempSize = sampleSize;		parseAnnexbNALU(pSampleBuffer, &tempSize,				&forbidden_bit, &nal_ref_idc, &nal_unit_type);		parseNALU_IDR_SLICE(pSampleBuffer, &tempSize, &slice_type); 		bool isBFrame = (slice_type==B_SLICE);		MP4AddRtpVideoHint(mp4File, hintTrackId, isBFrame, renderingOffset);		if (sampleId == 1) {			MP4AddRtpESConfigurationPacket(mp4File, hintTrackId);		}		u_int32_t offset = 0;		u_int32_t remaining = sampleSize;		// TBD should scan for resync markers (if enabled in ES config)		// and packetize on those boundaries		while (remaining) {			bool isLastPacket = false;			u_int32_t length;			if (remaining <= maxPayloadSize) {				length = remaining;				isLastPacket = true;			} else {				length = maxPayloadSize;			}			MP4AddRtpPacket(mp4File, hintTrackId, isLastPacket);			MP4AddRtpSampleData(mp4File, hintTrackId, sampleId, 				offset, length);			offset += length;			remaining -= length;		}		MP4WriteRtpHint(mp4File, hintTrackId, duration, isSyncSample);	}	return true;}

⌨️ 快捷键说明

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