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

📄 mp4file.cpp

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

float MP4File::GetTrackVideoFrameRate(MP4TrackId trackId)
{
	MP4SampleId numSamples =
		GetTrackNumberOfSamples(trackId);
#ifdef _WIN32
	int64_t
#else
	u_int64_t 
#endif
		msDuration =
		ConvertFromTrackDuration(trackId, 
			GetTrackDuration(trackId), MP4_MSECS_TIME_SCALE);

	if (msDuration == 0) {
		return 0.0;
	}

	return ((double)numSamples / (double)msDuration) * MP4_MSECS_TIME_SCALE;
}

void MP4File::GetTrackESConfiguration(MP4TrackId trackId, 
	u_int8_t** ppConfig, u_int32_t* pConfigSize)
{
	GetTrackBytesProperty(trackId, 
		"mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo[0].info",
		ppConfig, pConfigSize);
}

void MP4File::SetTrackESConfiguration(MP4TrackId trackId, 
	const u_int8_t* pConfig, u_int32_t configSize)
{
	// get a handle on the track decoder config descriptor 
	MP4DescriptorProperty* pConfigDescrProperty = NULL;
	FindProperty(MakeTrackName(trackId, 
		"mdia.minf.stbl.stsd.*[0].esds.decConfigDescr.decSpecificInfo"),
		(MP4Property**)&pConfigDescrProperty);

	if (pConfigDescrProperty == NULL) {
		// probably trackId refers to a hint track
		throw new MP4Error("no such property", "MP4SetTrackESConfiguration");
	}

	// lookup the property to store the configuration
	MP4BytesProperty* pInfoProperty = NULL;
	pConfigDescrProperty->FindProperty("decSpecificInfo[0].info",
		(MP4Property**)&pInfoProperty);

	// configuration being set for the first time
	if (pInfoProperty == NULL) {
		// need to create a new descriptor to hold it
		MP4Descriptor* pConfigDescr =
			pConfigDescrProperty->AddDescriptor(MP4DecSpecificDescrTag);
		pConfigDescr->Generate();

		pConfigDescrProperty->FindProperty(
			"decSpecificInfo[0].info",
			(MP4Property**)&pInfoProperty);
		ASSERT(pInfoProperty);
	}

	// set the value
	pInfoProperty->SetValue(pConfig, configSize);
}

const char* MP4File::GetHintTrackSdp(MP4TrackId hintTrackId)
{
	return GetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText");
}

void MP4File::SetHintTrackSdp(MP4TrackId hintTrackId, const char* sdpString)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4SetHintTrackSdp");
	}

	AddDescendantAtoms(
		MakeTrackName(hintTrackId, NULL), "udta.hnti.sdp ");

	SetTrackStringProperty(hintTrackId, "udta.hnti.sdp .sdpText", sdpString);
}

void MP4File::AppendHintTrackSdp(MP4TrackId hintTrackId, 
	const char* sdpFragment)
{
	const char* oldSdpString = NULL;
	try {
		oldSdpString = GetHintTrackSdp(hintTrackId);
	}
	catch (MP4Error* e) {
		delete e;
		SetHintTrackSdp(hintTrackId, sdpFragment);
		return;
	}

	char* newSdpString =
		(char*)MP4Malloc(strlen(oldSdpString) + strlen(sdpFragment) + 1);
	strcpy(newSdpString, oldSdpString);
	strcat(newSdpString, sdpFragment);
	SetHintTrackSdp(hintTrackId, newSdpString);
	MP4Free(newSdpString);
}

void MP4File::GetHintTrackRtpPayload(
	MP4TrackId hintTrackId,
	char** ppPayloadName,
	u_int8_t* pPayloadNumber,
	u_int16_t* pMaxPayloadSize)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetHintTrackRtpPayload");
	}

	((MP4RtpHintTrack*)pTrack)->GetPayload(
		ppPayloadName, pPayloadNumber, pMaxPayloadSize);
}

void MP4File::SetHintTrackRtpPayload(MP4TrackId hintTrackId,
	const char* payloadName, u_int8_t* pPayloadNumber, u_int16_t maxPayloadSize)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4SetHintTrackRtpPayload");
	}

	u_int8_t payloadNumber;
	if (pPayloadNumber && *pPayloadNumber != 0) {
		payloadNumber = *pPayloadNumber;
	} else {
		payloadNumber = AllocRtpPayloadNumber();
		if (pPayloadNumber) {
			*pPayloadNumber = payloadNumber;
		}
	}

	((MP4RtpHintTrack*)pTrack)->SetPayload(
		payloadName, payloadNumber, maxPayloadSize);
}

u_int8_t MP4File::AllocRtpPayloadNumber()
{
	MP4Integer32Array usedPayloads;
	u_int32_t i;

	// collect rtp payload numbers in use by existing tracks
	for (i = 0; i < m_pTracks.Size(); i++) {
		MP4Atom* pTrakAtom = m_pTracks[i]->GetTrakAtom();

		MP4Integer32Property* pPayloadProperty = NULL;
		pTrakAtom->FindProperty("trak.udta.hinf.payt.payloadNumber",
			(MP4Property**)&pPayloadProperty);

		if (pPayloadProperty) {
			usedPayloads.Add(pPayloadProperty->GetValue());
		}
	}

	// search dynamic payload range for an available slot
	u_int8_t payload;
	for (payload = 96; payload < 128; payload++) {
		for (i = 0; i < usedPayloads.Size(); i++) {
			if (payload == usedPayloads[i]) {
				break;
			}
		}
		if (i == usedPayloads.Size()) {
			break;
		}
	}

	if (payload >= 128) {
		throw new MP4Error("no more available rtp payload numbers",
			"AllocRtpPayloadNumber");
	}

	return payload;
}

MP4TrackId MP4File::GetHintTrackReferenceTrackId(
	MP4TrackId hintTrackId)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetHintTrackReferenceTrackId");
	}

	MP4Track* pRefTrack = ((MP4RtpHintTrack*)pTrack)->GetRefTrack();

	if (pRefTrack == NULL) {
		return MP4_INVALID_TRACK_ID;
	}
	return pRefTrack->GetId();
}

void MP4File::ReadRtpHint(
	MP4TrackId hintTrackId,
	MP4SampleId hintSampleId,
	u_int16_t* pNumPackets)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", "MP4ReadRtpHint");
	}
	((MP4RtpHintTrack*)pTrack)->
		ReadHint(hintSampleId, pNumPackets);
}

u_int16_t MP4File::GetRtpHintNumberOfPackets(
	MP4TrackId hintTrackId)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetRtpHintNumberOfPackets");
	}
	return ((MP4RtpHintTrack*)pTrack)->GetHintNumberOfPackets();
}

int8_t MP4File::GetRtpPacketBFrame(
	MP4TrackId hintTrackId,
	u_int16_t packetIndex)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetRtpHintBFrame");
	}
	return ((MP4RtpHintTrack*)pTrack)->GetPacketBFrame(packetIndex);
}

int32_t MP4File::GetRtpPacketTransmitOffset(
	MP4TrackId hintTrackId,
	u_int16_t packetIndex)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetRtpPacketTransmitOffset");
	}
	return ((MP4RtpHintTrack*)pTrack)->GetPacketTransmitOffset(packetIndex);
}

void MP4File::ReadRtpPacket(
	MP4TrackId hintTrackId,
	u_int16_t packetIndex,
	u_int8_t** ppBytes, 
	u_int32_t* pNumBytes,
	u_int32_t ssrc,
	bool includeHeader,
	bool includePayload)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", "MP4ReadPacket");
	}
	((MP4RtpHintTrack*)pTrack)->ReadPacket(
		packetIndex, ppBytes, pNumBytes,
		ssrc, includeHeader, includePayload);
}

MP4Timestamp MP4File::GetRtpTimestampStart(
	MP4TrackId hintTrackId)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4GetRtpTimestampStart");
	}
	return ((MP4RtpHintTrack*)pTrack)->GetRtpTimestampStart();
}

void MP4File::SetRtpTimestampStart(
	MP4TrackId hintTrackId,
	MP4Timestamp rtpStart)
{
	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4SetRtpTimestampStart");
	}
	((MP4RtpHintTrack*)pTrack)->SetRtpTimestampStart(rtpStart);
}

void MP4File::AddRtpHint(MP4TrackId hintTrackId, 
	bool isBframe, u_int32_t timestampOffset)
{
	ProtectWriteOperation("MP4AddRtpHint");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", "MP4AddRtpHint");
	}
	((MP4RtpHintTrack*)pTrack)->AddHint(isBframe, timestampOffset);
}

void MP4File::AddRtpPacket(
	MP4TrackId hintTrackId, bool setMbit, int32_t transmitOffset)
{
	ProtectWriteOperation("MP4AddRtpPacket");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", "MP4AddRtpPacket");
	}
	((MP4RtpHintTrack*)pTrack)->AddPacket(setMbit, transmitOffset);
}

void MP4File::AddRtpImmediateData(MP4TrackId hintTrackId, 
	const u_int8_t* pBytes, u_int32_t numBytes)
{
	ProtectWriteOperation("MP4AddRtpImmediateData");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4AddRtpImmediateData");
	}
	((MP4RtpHintTrack*)pTrack)->AddImmediateData(pBytes, numBytes);
}

void MP4File::AddRtpSampleData(MP4TrackId hintTrackId, 
	MP4SampleId sampleId, u_int32_t dataOffset, u_int32_t dataLength)
{
	ProtectWriteOperation("MP4AddRtpSampleData");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4AddRtpSampleData");
	}
	((MP4RtpHintTrack*)pTrack)->AddSampleData(
		sampleId, dataOffset, dataLength);
}

void MP4File::AddRtpESConfigurationPacket(MP4TrackId hintTrackId)
{
	ProtectWriteOperation("MP4AddRtpESConfigurationPacket");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4AddRtpESConfigurationPacket");
	}
	((MP4RtpHintTrack*)pTrack)->AddESConfigurationPacket();
}

void MP4File::WriteRtpHint(MP4TrackId hintTrackId,
	MP4Duration duration, bool isSyncSample)
{
	ProtectWriteOperation("MP4WriteRtpHint");

	MP4Track* pTrack = m_pTracks[FindTrackIndex(hintTrackId)];

	if (strcmp(pTrack->GetType(), MP4_HINT_TRACK_TYPE)) {
		throw new MP4Error("track is not a hint track", 
			"MP4WriteRtpHint");
	}
	((MP4RtpHintTrack*)pTrack)->WriteHint(duration, isSyncSample);
}

u_int64_t MP4File::ConvertFromMovieDuration(
	MP4Duration duration,
	u_int32_t timeScale)
{
	return MP4ConvertTime((u_int64_t)duration, 
		GetTimeScale(), timeScale);
}

u_int64_t MP4File::ConvertFromTrackTimestamp(
	MP4TrackId trackId, 
	MP4Timestamp timeStamp,
	u_int32_t timeScale)
{
	return MP4ConvertTime((u_int64_t)timeStamp, 
		GetTrackTimeScale(trackId), timeScale);
}

MP4Timestamp MP4File::ConvertToTrackTimestamp(
	MP4TrackId trackId, 
	u_int64_t timeStamp,
	u_int32_t timeScale)
{
	return (MP4Timestamp)MP4ConvertTime(timeStamp, 
		timeScale, GetTrackTimeScale(trackId));
}

u_int64_t MP4File::ConvertFromTrackDuration(
	MP4TrackId trackId, 
	MP4Duration duration,
	u_int32_t timeScale)
{
	return MP4ConvertTime((u_int64_t)duration, 
		GetTrackTimeScale(trackId), timeScale);
}

MP4Duration MP4File::ConvertToTrackDuration(
	MP4TrackId trackId, 
	u_int64_t duration,
	u_int32_t timeScale)
{
	return (MP4Duration)MP4ConvertTime(duration, 
		timeScale, GetTrackTimeScale(trackId));
}

u_int8_t MP4File::ConvertTrackTypeToStreamType(const char* trackType)
{
	u_int8_t streamType;

	if (!strcmp(trackType, MP4_OD_TRACK_TYPE)) {
		streamType = MP4ObjectDescriptionStreamType;
	} else if (!strcmp(trackType, MP4_SCENE_TRACK_TYPE)) {
		streamType = MP4SceneDescriptionStreamType;
	} else if (!strcmp(trackType, MP4_CLOCK_TRACK_TYPE)) {
		streamType = MP4ClockReferenceStreamType;
	} else if (!strcmp(trackType, MP4_MPEG7_TRACK_TYPE)) {
		streamType = MP4Mpeg7StreamType;
	} else if (!strcmp(trackType, MP4_OCI_TRACK_TYPE)) {
		streamType = MP4OCIStreamType;
	} else if (!strcmp(trackType, MP4_IPMP_TRACK_TYPE)) {
		streamType = MP4IPMPStreamType;
	} else if (!strcmp(trackType, MP4_MPEGJ_TRACK_TYPE)) {
		streamType = MP4MPEGJStreamType;
	} else {
		streamType = MP4UserPrivateStreamType;
	}

	return streamType;
}

// edit list

char* MP4File::MakeTrackEditName(
	MP4TrackId trackId,
	MP4EditId editId,
	const char* name)
{
	char* trakName = MakeTrackName(trackId, NULL);

	static char editName[1024];
	snprintf(editName, sizeof(editName), 
		"%s.edts.elst.entries[%u].%s", 
		trakName, editId - 1, name);
	return editName;
}

MP4EditId MP4File::AddTrackEdit(
	MP4TrackId trackId,
	MP4EditId editId)
{
	ProtectWriteOperation("AddTrackEdit");
	return m_pTracks[FindTrackIndex(trackId)]->AddEdit(editId);
}

void MP4File::DeleteTrackEdit(
	MP4TrackId trackId,
	MP4EditId editId)
{
	ProtectWriteOperation("DeleteTrackEdit");
	m_pTracks[FindTrackIndex(trackId)]->DeleteEdit(editId);
}

u_int32_t MP4File::GetTrackNumberOfEdits(
	MP4TrackId trackId)
{
	return GetTrackIntegerProperty(trackId, "edts.elst.entryCount");
}

MP4Duration MP4File::GetTrackEditTotalDuration(
	MP4TrackId trackId,
	MP4EditId editId)
{
	return m_pTracks[FindTrackIndex(trackId)]->GetEditTotalDuration(editId);
}

MP4Timestamp MP4File::GetTrackEditStart(
	MP4TrackId trackId,
	MP4EditId editId)
{
	return m_pTracks[FindTrackIndex(trackId)]->GetEditStart(editId);
}

MP4Timestamp MP4File::GetTrackEditMediaStart(
	MP4TrackId trackId,
	MP4EditId editId)
{
	return GetIntegerProperty(
		MakeTrackEditName(trackId, editId, "mediaTime"));
}

void MP4File::SetTrackEditMediaStart(
	MP4TrackId trackId,
	MP4EditId editId,
	MP4Timestamp startTime)
{
	SetIntegerProperty(
		MakeTrackEditName(trackId, editId, "mediaTime"),
		startTime);
}

MP4Duration MP4File::GetTrackEditDuration(
	MP4TrackId trackId,
	MP4EditId editId)
{
	return GetIntegerProperty(
		MakeTrackEditName(trackId, editId, "segmentDuration"));
}

void MP4File::SetTrackEditDuration(
	MP4TrackId trackId,
	MP4EditId editId,
	MP4Duration duration)
{
	SetIntegerProperty(
		MakeTrackEditName(trackId, editId, "segmentDuration"),
		duration);
}

bool MP4File::GetTrackEditDwell(
	MP4TrackId trackId,
	MP4EditId editId)
{
	return (GetIntegerProperty(
		MakeTrackEditName(trackId, editId, "mediaRate")) == 0);
}

void MP4File::SetTrackEditDwell(
	MP4TrackId trackId,
	MP4EditId editId,
	bool dwell)
{
	SetIntegerProperty(
		MakeTrackEditName(trackId, editId, "mediaRate"),
		(dwell ? 0 : 1));
}

MP4SampleId MP4File::GetSampleIdFromEditTime(
	MP4TrackId trackId,
	MP4Timestamp when,
	MP4Timestamp* pStartTime,
	MP4Duration* pDuration)
{
	return m_pTracks[FindTrackIndex(trackId)]->GetSampleIdFromEditTime(
		when, pStartTime, pDuration);
}

⌨️ 快捷键说明

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