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

📄 mp4.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	if (dstFile == NULL) {
		dstFile = srcFile;
	}

	const char* trackType = 
		MP4GetTrackType(srcFile, srcTrackId);

	if (!trackType) {
		return dstTrackId;
	}

	if (MP4_IS_VIDEO_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddVideoTrack(
			dstFile,
			MP4GetTrackTimeScale(srcFile, srcTrackId),
			MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
			MP4GetTrackVideoWidth(srcFile, srcTrackId),
			MP4GetTrackVideoHeight(srcFile, srcTrackId),
			MP4GetTrackVideoType(srcFile, srcTrackId));

	} else if (MP4_IS_AUDIO_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddAudioTrack(
			dstFile,
			MP4GetTrackTimeScale(srcFile, srcTrackId),
			MP4GetTrackFixedSampleDuration(srcFile, srcTrackId),
			MP4GetTrackAudioType(srcFile, srcTrackId));

	} else if (MP4_IS_OD_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddODTrack(dstFile);

	} else if (MP4_IS_SCENE_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddSceneTrack(dstFile);

	} else if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddHintTrack(
			dstFile,
			MP4GetHintTrackReferenceTrackId(srcFile, srcTrackId));

	} else if (MP4_IS_SYSTEMS_TRACK_TYPE(trackType)) {
		dstTrackId = MP4AddSystemsTrack(dstFile, trackType);

	} else {
		dstTrackId = MP4AddTrack(dstFile, trackType);
	}

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

	MP4SetTrackTimeScale(
		dstFile, 
		dstTrackId,
		MP4GetTrackTimeScale(srcFile, srcTrackId));

	// copy track ES configuration
	u_int8_t* pConfig = NULL;
	u_int32_t configSize = 0;

	MP4GetTrackESConfiguration(
		srcFile, 
		srcTrackId,
		&pConfig,
		&configSize);

	MP4SetTrackESConfiguration(
		dstFile, 
		dstTrackId,
		pConfig,
		configSize);

		free(pConfig);

	if (MP4_IS_HINT_TRACK_TYPE(trackType)) {
		// probably not exactly what is wanted
		// but caller can adjust later to fit their desires

		char* payloadName = NULL;
		u_int8_t payloadNumber;
		u_int16_t maxPayloadSize;

		MP4GetHintTrackRtpPayload(
			srcFile,
			srcTrackId,
			&payloadName,
			&payloadNumber,
			&maxPayloadSize);

		MP4SetHintTrackRtpPayload(
			dstFile,
			dstTrackId,
			payloadName,
			&payloadNumber,
			maxPayloadSize);

		MP4SetHintTrackSdp(
			dstFile,
			dstTrackId,
			MP4GetHintTrackSdp(srcFile, srcTrackId));
	}

	return dstTrackId;
}

extern "C" MP4TrackId MP4CopyTrack(
	MP4FileHandle srcFile, 
	MP4TrackId srcTrackId,
	MP4FileHandle dstFile, 
	bool applyEdits)
{
	bool copySamples = true;	// LATER allow false => reference samples

	MP4TrackId dstTrackId =
		MP4CloneTrack(srcFile, srcTrackId, dstFile);

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

	bool viaEdits =
		applyEdits && MP4GetTrackNumberOfEdits(srcFile, srcTrackId);

	MP4SampleId sampleId = 0;
	MP4SampleId numSamples = 
		MP4GetTrackNumberOfSamples(srcFile, srcTrackId);

	MP4Timestamp when = 0;
	MP4Duration editsDuration = 
		MP4GetTrackEditTotalDuration(srcFile, srcTrackId);

	while (true) {
		MP4Duration sampleDuration = MP4_INVALID_DURATION;

		if (viaEdits) {
			sampleId = MP4GetSampleIdFromEditTime(
				srcFile,
				srcTrackId,
				when,
				NULL,
				&sampleDuration);

			// in theory, this shouldn't happen
			if (sampleId == MP4_INVALID_SAMPLE_ID) {
				MP4DeleteTrack(dstFile, dstTrackId);
				return MP4_INVALID_TRACK_ID;
			}

			when += sampleDuration;

			if (when >= editsDuration) {
				break;
			}
		} else {
			sampleId++;
			if (sampleId > numSamples) {
				break;
			}
		}

		bool rc = false;

		if (copySamples) {
			rc = MP4CopySample(
				srcFile,
				srcTrackId,
				sampleId,
				dstFile,
				dstTrackId,
				sampleDuration);

		} else {
			rc = MP4ReferenceSample(
				srcFile,
				srcTrackId,
				sampleId,
				dstFile,
				dstTrackId,
				sampleDuration);
		}

		if (!rc) {
			MP4DeleteTrack(dstFile, dstTrackId);
			return MP4_INVALID_TRACK_ID;
		}
	}

	return dstTrackId;
}

extern "C" bool MP4DeleteTrack(
	MP4FileHandle hFile, 
	MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->DeleteTrack(trackId);
			return true;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return false;
}

extern "C" u_int32_t MP4GetNumberOfTracks(
	MP4FileHandle hFile, 
	const char* type,
	u_int8_t subType)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetNumberOfTracks(type, subType);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" MP4TrackId MP4FindTrackId(
	MP4FileHandle hFile, 
	u_int16_t index, 
	const char* type,
	u_int8_t subType)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->FindTrackId(index, type, subType);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_INVALID_TRACK_ID;
}

extern "C" u_int16_t MP4FindTrackIndex(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->FindTrackIndex(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return (u_int16_t)-1;
}

/* specific track properties */

extern "C" const char* MP4GetTrackType(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackType(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return NULL;
}

extern "C" MP4Duration MP4GetTrackDuration(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackDuration(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_INVALID_DURATION;
}

extern "C" u_int32_t MP4GetTrackTimeScale(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackTimeScale(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" bool MP4SetTrackTimeScale(
	MP4FileHandle hFile, MP4TrackId trackId, u_int32_t value)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->SetTrackTimeScale(trackId, value);
			return true;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return false;
}

extern "C" u_int8_t MP4GetTrackAudioType(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackAudioType(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_INVALID_AUDIO_TYPE;
}

extern "C" u_int8_t MP4GetTrackAudioMpeg4Type(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackAudioMpeg4Type(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_MPEG4_INVALID_AUDIO_TYPE;
}


extern "C" u_int8_t MP4GetTrackVideoType(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackVideoType(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_INVALID_VIDEO_TYPE;
}

extern "C" MP4Duration MP4GetTrackFixedSampleDuration(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackFixedSampleDuration(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return MP4_INVALID_DURATION;
}

extern "C" u_int32_t MP4GetTrackBitRate(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.*.esds.decConfigDescr.avgBitrate");
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" void MP4GetTrackESConfiguration(
	MP4FileHandle hFile, MP4TrackId trackId, 
	u_int8_t** ppConfig, u_int32_t* pConfigSize)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->GetTrackESConfiguration(
				trackId, ppConfig, pConfigSize);
			return;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	*ppConfig = NULL;
	*pConfigSize = 0;
	return;
}

extern "C" bool MP4SetTrackESConfiguration(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const u_int8_t* pConfig, u_int32_t configSize)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->SetTrackESConfiguration(
				trackId, pConfig, configSize);
			return true;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return false;
}

extern "C" MP4SampleId MP4GetTrackNumberOfSamples(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackNumberOfSamples(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" u_int16_t MP4GetTrackVideoWidth(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.mp4v.width");
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" u_int16_t MP4GetTrackVideoHeight(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId,
				"mdia.minf.stbl.stsd.mp4v.height");
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0;
}

extern "C" float MP4GetTrackVideoFrameRate(
	MP4FileHandle hFile, MP4TrackId trackId)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackVideoFrameRate(trackId);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return 0.0;
}

/* generic track properties */

extern "C" u_int64_t MP4GetTrackIntegerProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackIntegerProperty(trackId, 
				propName);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return (u_int64_t)-1;
}

extern "C" float MP4GetTrackFloatProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackFloatProperty(trackId, propName);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return NAN;
}

extern "C" const char* MP4GetTrackStringProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			return ((MP4File*)hFile)->GetTrackStringProperty(trackId, propName);
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return NULL;
}

extern "C" void MP4GetTrackBytesProperty(
	MP4FileHandle hFile, MP4TrackId trackId, const char* propName, 
	u_int8_t** ppValue, u_int32_t* pValueSize)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->GetTrackBytesProperty(
				trackId, propName, ppValue, pValueSize);
			return;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	*ppValue = NULL;
	*pValueSize = 0;
	return;
}

extern "C" bool MP4SetTrackIntegerProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName, int64_t value)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->SetTrackIntegerProperty(trackId, 
				propName, value);
			return true;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return false;
}

extern "C" bool MP4SetTrackFloatProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName, float value)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->SetTrackFloatProperty(trackId, propName, value);
			return true;
		}
		catch (MP4Error* e) {
			PRINT_ERROR(e);
			delete e;
		}
	}
	return false;
}

extern "C" bool MP4SetTrackStringProperty(
	MP4FileHandle hFile, MP4TrackId trackId, 
	const char* propName, const char* value)
{
	if (MP4_IS_VALID_FILE_HANDLE(hFile)) {
		try {
			((MP4File*)hFile)->SetTrackStringProperty(trackId, propName, value);
			return true;
		}

⌨️ 快捷键说明

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