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

📄 mp4track.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  }}MP4Atom* MP4Track::AddAtom(char* parentName, char* childName){	MP4Atom* pChildAtom = MP4Atom::CreateAtom(childName);	MP4Atom* pParentAtom = m_pTrakAtom->FindAtom(parentName);	ASSERT(pParentAtom);	pParentAtom->AddChildAtom(pChildAtom);	pChildAtom->Generate();	return pChildAtom;}u_int64_t MP4Track::GetDuration(){	return m_pMediaDurationProperty->GetValue();}u_int32_t MP4Track::GetTimeScale(){	return m_pTimeScaleProperty->GetValue();}void MP4Track::UpdateDurations(MP4Duration duration){	// update media, track, and movie durations	m_pMediaDurationProperty->SetValue(		m_pMediaDurationProperty->GetValue() + duration);	MP4Duration movieDuration = ToMovieDuration(duration);	m_pTrackDurationProperty->SetValue(		m_pTrackDurationProperty->GetValue() + movieDuration);	m_pFile->UpdateDuration(m_pTrackDurationProperty->GetValue());}MP4Duration MP4Track::ToMovieDuration(MP4Duration trackDuration){	return (trackDuration * m_pFile->GetTimeScale()) 		/ m_pTimeScaleProperty->GetValue();}void MP4Track::UpdateModificationTimes(){	// update media and track modification times	MP4Timestamp now = MP4GetAbsTimestamp();	m_pMediaModificationProperty->SetValue(now);	m_pTrackModificationProperty->SetValue(now);}u_int32_t MP4Track::GetNumberOfChunks(){	return m_pChunkOffsetProperty->GetCount();}u_int32_t MP4Track::GetChunkStscIndex(MP4ChunkId chunkId){	u_int32_t stscIndex;	u_int32_t numStscs = m_pStscCountProperty->GetValue();	ASSERT(chunkId);	ASSERT(numStscs > 0);	for (stscIndex = 0; stscIndex < numStscs; stscIndex++) {		if (chunkId < m_pStscFirstChunkProperty->GetValue(stscIndex)) {			ASSERT(stscIndex != 0);			break;		}	}	return stscIndex - 1;}MP4Timestamp MP4Track::GetChunkTime(MP4ChunkId chunkId){	u_int32_t stscIndex = GetChunkStscIndex(chunkId);	MP4ChunkId firstChunkId = 		m_pStscFirstChunkProperty->GetValue(stscIndex);	MP4SampleId firstSample = 		m_pStscFirstSampleProperty->GetValue(stscIndex);	u_int32_t samplesPerChunk = 		m_pStscSamplesPerChunkProperty->GetValue(stscIndex);	MP4SampleId firstSampleInChunk = 		firstSample + ((chunkId - firstChunkId) * samplesPerChunk);	MP4Timestamp chunkTime;	GetSampleTimes(firstSampleInChunk, &chunkTime, NULL);	return chunkTime;}u_int32_t MP4Track::GetChunkSize(MP4ChunkId chunkId){	u_int32_t stscIndex = GetChunkStscIndex(chunkId);	MP4ChunkId firstChunkId = 		m_pStscFirstChunkProperty->GetValue(stscIndex);	MP4SampleId firstSample = 		m_pStscFirstSampleProperty->GetValue(stscIndex);	u_int32_t samplesPerChunk = 		m_pStscSamplesPerChunkProperty->GetValue(stscIndex);	MP4SampleId firstSampleInChunk = 		firstSample + ((chunkId - firstChunkId) * samplesPerChunk);	// need cumulative sizes of samples in chunk 	u_int32_t chunkSize = 0;	for (u_int32_t i = 0; i < samplesPerChunk; i++) {		chunkSize += GetSampleSize(firstSampleInChunk + i);	}	return chunkSize;}void MP4Track::ReadChunk(MP4ChunkId chunkId, 	u_int8_t** ppChunk, u_int32_t* pChunkSize){	ASSERT(chunkId);	ASSERT(ppChunk);	ASSERT(pChunkSize);	u_int64_t chunkOffset = 		m_pChunkOffsetProperty->GetValue(chunkId - 1);	*pChunkSize = GetChunkSize(chunkId);	*ppChunk = (u_int8_t*)MP4Malloc(*pChunkSize);	VERBOSE_READ_SAMPLE(m_pFile->GetVerbosity(),		printf("ReadChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",			m_trackId, chunkId, chunkOffset, *pChunkSize, *pChunkSize));	u_int64_t oldPos = m_pFile->GetPosition(); // only used in mode == 'w'	try {		m_pFile->SetPosition(chunkOffset);		m_pFile->ReadBytes(*ppChunk, *pChunkSize);	}	catch (MP4Error* e) {		// let's not leak memory		MP4Free(*ppChunk);		*ppChunk = NULL;		if (m_pFile->GetMode() == 'w') {			m_pFile->SetPosition(oldPos);		}		throw e;	}	if (m_pFile->GetMode() == 'w') {		m_pFile->SetPosition(oldPos);	}}void MP4Track::RewriteChunk(MP4ChunkId chunkId, 	u_int8_t* pChunk, u_int32_t chunkSize){	u_int64_t chunkOffset = m_pFile->GetPosition();	m_pFile->WriteBytes(pChunk, chunkSize);	m_pChunkOffsetProperty->SetValue(chunkOffset, chunkId - 1);	VERBOSE_WRITE_SAMPLE(m_pFile->GetVerbosity(),		printf("RewriteChunk: track %u id %u offset 0x"X64" size %u (0x%x)\n",			m_trackId, chunkId, chunkOffset, chunkSize, chunkSize)); }// map track type name aliases to official namesbool MP4Track::InitEditListProperties(){  m_pElstCountProperty = NULL;  m_pElstMediaTimeProperty = NULL;  m_pElstDurationProperty = NULL;  m_pElstRateProperty = NULL;  m_pElstReservedProperty = NULL;  MP4Atom* pElstAtom =    m_pTrakAtom->FindAtom("trak.edts.elst");  if (!pElstAtom) {    return false;  }  (void)pElstAtom->FindProperty(				"elst.entryCount",				(MP4Property**)&m_pElstCountProperty);  (void)pElstAtom->FindProperty(				"elst.entries.mediaTime",				(MP4Property**)&m_pElstMediaTimeProperty);  (void)pElstAtom->FindProperty(				"elst.entries.segmentDuration",				(MP4Property**)&m_pElstDurationProperty);  (void)pElstAtom->FindProperty(				"elst.entries.mediaRate",				(MP4Property**)&m_pElstRateProperty);  (void)pElstAtom->FindProperty(				"elst.entries.reserved",				(MP4Property**)&m_pElstReservedProperty);  return m_pElstCountProperty    && m_pElstMediaTimeProperty    && m_pElstDurationProperty    && m_pElstRateProperty    && m_pElstReservedProperty;}MP4EditId MP4Track::AddEdit(MP4EditId editId){	if (!m_pElstCountProperty) {	  (void)m_pFile->AddDescendantAtoms(m_pTrakAtom, "edts.elst");	  if (InitEditListProperties() == false) return MP4_INVALID_EDIT_ID;	}	if (editId == MP4_INVALID_EDIT_ID) {		editId = m_pElstCountProperty->GetValue() + 1;	}	m_pElstMediaTimeProperty->InsertValue(0, editId - 1);	m_pElstDurationProperty->InsertValue(0, editId - 1);	m_pElstRateProperty->InsertValue(1, editId - 1);	m_pElstReservedProperty->InsertValue(0, editId - 1);	m_pElstCountProperty->IncrementValue();	return editId;}void MP4Track::DeleteEdit(MP4EditId editId){	if (editId == MP4_INVALID_EDIT_ID) {		throw new MP4Error("edit id can't be zero", 			"MP4Track::DeleteEdit");	}	if (!m_pElstCountProperty	  || m_pElstCountProperty->GetValue() == 0) {		throw new MP4Error("no edits exist", 			"MP4Track::DeleteEdit");	}	m_pElstMediaTimeProperty->DeleteValue(editId - 1);	m_pElstDurationProperty->DeleteValue(editId - 1);	m_pElstRateProperty->DeleteValue(editId - 1);	m_pElstReservedProperty->DeleteValue(editId - 1);	m_pElstCountProperty->IncrementValue(-1);	// clean up if last edit is deleted	if (m_pElstCountProperty->GetValue() == 0) {		m_pElstCountProperty = NULL;		m_pElstMediaTimeProperty = NULL;		m_pElstDurationProperty = NULL;		m_pElstRateProperty = NULL;		m_pElstReservedProperty = NULL;		m_pTrakAtom->DeleteChildAtom(			m_pTrakAtom->FindAtom("trak.edts"));	}}MP4Timestamp MP4Track::GetEditStart(	MP4EditId editId) {	if (editId == MP4_INVALID_EDIT_ID) {		return MP4_INVALID_TIMESTAMP;	} else if (editId == 1) {		return 0;	}	return (MP4Timestamp)GetEditTotalDuration(editId - 1);}	MP4Duration MP4Track::GetEditTotalDuration(	MP4EditId editId){	u_int32_t numEdits = 0;	if (m_pElstCountProperty) {		numEdits = m_pElstCountProperty->GetValue();	}	if (editId == MP4_INVALID_EDIT_ID) {		editId = numEdits;	}	if (numEdits == 0 || editId > numEdits) {		return MP4_INVALID_DURATION;	}	MP4Duration totalDuration = 0;	for (MP4EditId eid = 1; eid <= editId; eid++) {		totalDuration += 			m_pElstDurationProperty->GetValue(eid - 1);	}	return totalDuration;}MP4SampleId MP4Track::GetSampleIdFromEditTime(	MP4Timestamp editWhen, 	MP4Timestamp* pStartTime, 	MP4Duration* pDuration){	MP4SampleId sampleId = MP4_INVALID_SAMPLE_ID;	u_int32_t numEdits = 0;	if (m_pElstCountProperty) {		numEdits = m_pElstCountProperty->GetValue();	}	if (numEdits) {		MP4Duration editElapsedDuration = 0;		for (MP4EditId editId = 1; editId <= numEdits; editId++) {			// remember edit segment's start time (in edit timeline)			MP4Timestamp editStartTime = 				(MP4Timestamp)editElapsedDuration;			// accumulate edit segment's duration			editElapsedDuration += 				m_pElstDurationProperty->GetValue(editId - 1);			// calculate difference between the specified edit time			// and the end of this edit segment			if (editElapsedDuration - editWhen <= 0) {				// the specified time has not yet been reached				continue;			}			// 'editWhen' is within this edit segment			// calculate the specified edit time			// relative to just this edit segment			MP4Duration editOffset =				editWhen - editStartTime;			// calculate the media (track) time that corresponds			// to the specified edit time based on the edit list			MP4Timestamp mediaWhen = 				m_pElstMediaTimeProperty->GetValue(editId - 1)				+ editOffset;			// lookup the sample id for the media time			sampleId = GetSampleIdFromTime(mediaWhen, false);			// lookup the sample's media start time and duration			MP4Timestamp sampleStartTime;			MP4Duration sampleDuration;			GetSampleTimes(sampleId, &sampleStartTime, &sampleDuration);			// calculate the difference if any between when the sample			// would naturally start and when it starts in the edit timeline 			MP4Duration sampleStartOffset =				mediaWhen - sampleStartTime;			// calculate the start time for the sample in the edit time line			MP4Timestamp editSampleStartTime =				editWhen - MIN(editOffset, sampleStartOffset);			MP4Duration editSampleDuration = 0;			// calculate how long this sample lasts in the edit list timeline			if (m_pElstRateProperty->GetValue(editId - 1) == 0) {				// edit segment is a "dwell"				// so sample duration is that of the edit segment				editSampleDuration =					m_pElstDurationProperty->GetValue(editId - 1);			} else {				// begin with the natural sample duration				editSampleDuration = sampleDuration;				// now shorten that if the edit segment starts				// after the sample would naturally start 				if (editOffset < sampleStartOffset) {					editSampleDuration -= sampleStartOffset - editOffset;				}				// now shorten that if the edit segment ends				// before the sample would naturally end				if (editElapsedDuration 				  < editSampleStartTime + sampleDuration) {					editSampleDuration -= (editSampleStartTime + sampleDuration) 						- editElapsedDuration;				}			}			if (pStartTime) {				*pStartTime = editSampleStartTime;			}			if (pDuration) {				*pDuration = editSampleDuration;			}			VERBOSE_EDIT(m_pFile->GetVerbosity(),				printf("GetSampleIdFromEditTime: when "U64" "					"sampleId %u start "U64" duration "D64"\n", 					editWhen, sampleId, 					editSampleStartTime, editSampleDuration));			return sampleId;		}		throw new MP4Error("time out of range", 			"MP4Track::GetSampleIdFromEditTime");	} else { // no edit list		sampleId = GetSampleIdFromTime(editWhen, false);		if (pStartTime || pDuration) {			GetSampleTimes(sampleId, pStartTime, pDuration);		}	}	return sampleId;}void MP4Track::CalculateBytesPerSample (){  MP4Atom *pMedia = m_pTrakAtom->FindAtom("trak.mdia.minf.stbl.stsd");  MP4Atom *pMediaData;  const char *media_data_name;  if (pMedia == NULL) return;  if (pMedia->GetNumberOfChildAtoms() != 1) return;    pMediaData = pMedia->GetChildAtom(0);  media_data_name = pMediaData->GetType();  if ((ATOMID(media_data_name) == ATOMID("twos")) ||      (ATOMID(media_data_name) == ATOMID("sowt"))) {    MP4IntegerProperty *chan, *sampleSize;    chan = (MP4IntegerProperty *)pMediaData->GetProperty(4);    sampleSize = (MP4IntegerProperty *)pMediaData->GetProperty(5);    m_bytesPerSample = chan->GetValue() * (sampleSize->GetValue() / 8);  }}  

⌨️ 快捷键说明

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