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

📄 rtphint.cpp

📁 AAC编解码源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	AddExtraProperties();

	int32_t extraLength = (int32_t)pFile->ReadUInt32();

	if (extraLength < 4) {
		throw new MP4Error("bad packet extra info length",
			"MP4RtpPacket::ReadExtra");
	}
	extraLength -= 4;

	while (extraLength > 0) {
		u_int32_t entryLength = pFile->ReadUInt32();
		u_int32_t entryTag = pFile->ReadUInt32();

		if (entryLength < 8) {
			throw new MP4Error("bad packet extra info entry length",
				"MP4RtpPacket::ReadExtra");
		}

		if (entryTag == STRTOINT32("rtpo") && entryLength == 12) {
			// read the rtp timestamp offset
			m_pProperties[16]->Read(pFile);
		} else {
			// ignore it, LATER carry it along
			pFile->SetPosition(pFile->GetPosition() + entryLength - 8);
		}

		extraLength -= entryLength;
	}

	if (extraLength < 0) {
		throw new MP4Error("invalid packet extra info length",
			"MP4RtpPacket::ReadExtra");
	}
}

void MP4RtpPacket::Set(u_int8_t payloadNumber, 
	u_int32_t packetId, bool setMbit)
{
	((MP4BitfieldProperty*)m_pProperties[5])->SetValue(setMbit);
	((MP4BitfieldProperty*)m_pProperties[6])->SetValue(payloadNumber);
	((MP4Integer16Property*)m_pProperties[7])->SetValue(packetId);
}

int32_t MP4RtpPacket::GetTransmitOffset()
{
	return ((MP4Integer32Property*)m_pProperties[0])->GetValue();
}

void MP4RtpPacket::SetTransmitOffset(int32_t transmitOffset)
{
	((MP4Integer32Property*)m_pProperties[0])->SetValue(transmitOffset);
}

bool MP4RtpPacket::GetPBit()
{
	return ((MP4BitfieldProperty*)m_pProperties[2])->GetValue();
}

bool MP4RtpPacket::GetXBit()
{
	return ((MP4BitfieldProperty*)m_pProperties[3])->GetValue();
}

bool MP4RtpPacket::GetMBit()
{
	return ((MP4BitfieldProperty*)m_pProperties[5])->GetValue();
}

u_int8_t MP4RtpPacket::GetPayload()
{
	return ((MP4BitfieldProperty*)m_pProperties[6])->GetValue();
}

u_int16_t MP4RtpPacket::GetSequenceNumber()
{
	return ((MP4Integer16Property*)m_pProperties[7])->GetValue();
}

bool MP4RtpPacket::IsBFrame()
{
	return ((MP4BitfieldProperty*)m_pProperties[10])->GetValue();
}

void MP4RtpPacket::SetBFrame(bool isBFrame)
{
	((MP4BitfieldProperty*)m_pProperties[10])->SetValue(isBFrame);
}

void MP4RtpPacket::SetTimestampOffset(u_int32_t timestampOffset)
{
	if (timestampOffset == 0) {
		return;
	}

	ASSERT(((MP4BitfieldProperty*)m_pProperties[9])->GetValue() == 0);

	// set X bit
	((MP4BitfieldProperty*)m_pProperties[9])->SetValue(1);

	AddExtraProperties();

	((MP4Integer32Property*)m_pProperties[16])->SetValue(timestampOffset);
}

void MP4RtpPacket::AddData(MP4RtpData* pData)
{
	m_rtpData.Add(pData);

	// increment entry count property
	((MP4Integer16Property*)m_pProperties[12])->IncrementValue();
}

u_int32_t MP4RtpPacket::GetDataSize()
{
	u_int32_t totalDataSize = 0;

	for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {
		totalDataSize += m_rtpData[i]->GetDataSize();
	}

	return totalDataSize;
}

void MP4RtpPacket::GetData(u_int8_t* pDest)
{
	for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {
		m_rtpData[i]->GetData(pDest);
		pDest += m_rtpData[i]->GetDataSize();
	}
}

void MP4RtpPacket::Write(MP4File* pFile)
{
	MP4Container::Write(pFile);

	for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {
		m_rtpData[i]->Write(pFile);
	}
}

void MP4RtpPacket::WriteEmbeddedData(MP4File* pFile, u_int64_t startPos)
{
	for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {
		m_rtpData[i]->WriteEmbeddedData(pFile, startPos);
	}
}

void MP4RtpPacket::Dump(FILE* pFile, u_int8_t indent, bool dumpImplicits)
{
	MP4Container::Dump(pFile, indent, dumpImplicits);

	for (u_int32_t i = 0; i < m_rtpData.Size(); i++) {
		Indent(pFile, indent);
		fprintf(pFile, "RtpData: %u\n", i);
		m_rtpData[i]->Dump(pFile, indent + 1, dumpImplicits);
	}
}

MP4RtpData::MP4RtpData(MP4RtpPacket* pPacket)
{
	m_pPacket = pPacket;

	AddProperty( /* 0 */
		new MP4Integer8Property("type"));
}

MP4Track* MP4RtpData::FindTrackFromRefIndex(u_int8_t refIndex)
{
	MP4Track* pTrack;

	if (refIndex == (u_int8_t)-1) {
		// ourselves
		pTrack = GetPacket()->GetHint()->GetTrack();
	} else if (refIndex == 0) {
		// our reference track
		pTrack = GetPacket()->GetHint()->GetTrack()->GetRefTrack();
	} else {
		// some other track
		MP4RtpHintTrack* pHintTrack =
			GetPacket()->GetHint()->GetTrack();

		MP4Atom* pTrakAtom = pHintTrack->GetTrakAtom();
		ASSERT(pTrakAtom);

		MP4Integer32Property* pTrackIdProperty = NULL;
		pTrakAtom->FindProperty(
			"trak.tref.hint.entries",
			(MP4Property**)&pTrackIdProperty);
		ASSERT(pTrackIdProperty);

		u_int32_t refTrackId = 
			pTrackIdProperty->GetValue(refIndex - 1);

		pTrack = pHintTrack->GetFile()->GetTrack(refTrackId); 
	}

	return pTrack;
}

MP4RtpNullData::MP4RtpNullData(MP4RtpPacket* pPacket)
	: MP4RtpData(pPacket)
{
	((MP4Integer8Property*)m_pProperties[0])->SetValue(0);

	AddProperty( /* 1 */
		new MP4BytesProperty("pad", 15));

	((MP4BytesProperty*)m_pProperties[1])->SetFixedSize(15);
}

MP4RtpImmediateData::MP4RtpImmediateData(MP4RtpPacket* pPacket)
	: MP4RtpData(pPacket)
{
	((MP4Integer8Property*)m_pProperties[0])->SetValue(1);

	AddProperty( /* 1 */
		new MP4Integer8Property("count"));
	AddProperty( /* 2 */
		new MP4BytesProperty("data", 14));

	((MP4BytesProperty*)m_pProperties[2])->SetFixedSize(14);
}

void MP4RtpImmediateData::Set(const u_int8_t* pBytes, u_int8_t numBytes)
{
	((MP4Integer8Property*)m_pProperties[1])->SetValue(numBytes);
	((MP4BytesProperty*)m_pProperties[2])->SetValue(pBytes, numBytes);
}

u_int16_t MP4RtpImmediateData::GetDataSize()
{
	return ((MP4Integer8Property*)m_pProperties[1])->GetValue();
}

void MP4RtpImmediateData::GetData(u_int8_t* pDest)
{
	u_int8_t* pValue;
	u_int32_t valueSize;
	((MP4BytesProperty*)m_pProperties[2])->GetValue(&pValue, &valueSize);

	memcpy(pDest, pValue, GetDataSize());
	MP4Free(pValue);
}

MP4RtpSampleData::MP4RtpSampleData(MP4RtpPacket* pPacket)
	: MP4RtpData(pPacket)
{
	((MP4Integer8Property*)m_pProperties[0])->SetValue(2);

	AddProperty( /* 1 */
		new MP4Integer8Property("trackRefIndex"));
	AddProperty( /* 2 */
		new MP4Integer16Property("length"));
	AddProperty( /* 3 */
		new MP4Integer32Property("sampleNumber"));
	AddProperty( /* 4 */
		new MP4Integer32Property("sampleOffset"));
	AddProperty( /* 5 */
		new MP4Integer16Property("bytesPerBlock"));
	AddProperty( /* 6 */
		new MP4Integer16Property("samplesPerBlock"));

	((MP4Integer16Property*)m_pProperties[5])->SetValue(1);
	((MP4Integer16Property*)m_pProperties[6])->SetValue(1);

	m_pRefData = NULL;
	m_pRefTrack = NULL;
	m_refSampleId = MP4_INVALID_SAMPLE_ID;
	m_refSampleOffset = 0;
}

void MP4RtpSampleData::SetEmbeddedImmediate(MP4SampleId sampleId, 
	u_int8_t* pData, u_int16_t dataLength)
{
	((MP4Integer8Property*)m_pProperties[1])->SetValue((u_int8_t)-1);
	((MP4Integer16Property*)m_pProperties[2])->SetValue(dataLength);
	((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId);
	((MP4Integer32Property*)m_pProperties[4])->SetValue(0); 
	m_pRefData = pData;
}

void MP4RtpSampleData::SetReferenceSample(
	MP4SampleId refSampleId, u_int32_t refSampleOffset, 
	u_int16_t sampleLength)
{
	((MP4Integer8Property*)m_pProperties[1])->SetValue(0);
	((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength);
	((MP4Integer32Property*)m_pProperties[3])->SetValue(refSampleId);
	((MP4Integer32Property*)m_pProperties[4])->SetValue(refSampleOffset);
}

void MP4RtpSampleData::SetEmbeddedSample(
	MP4SampleId sampleId, MP4Track* pRefTrack,
	MP4SampleId refSampleId, u_int32_t refSampleOffset, 
	u_int16_t sampleLength)
{
	((MP4Integer8Property*)m_pProperties[1])->SetValue((u_int8_t)-1);
	((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength);
	((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId);
	((MP4Integer32Property*)m_pProperties[4])->SetValue(0);
	m_pRefTrack = pRefTrack;
	m_refSampleId = refSampleId;
	m_refSampleOffset = refSampleOffset;
}

u_int16_t MP4RtpSampleData::GetDataSize()
{
	return ((MP4Integer16Property*)m_pProperties[2])->GetValue();
}

void MP4RtpSampleData::GetData(u_int8_t* pDest)
{
	u_int8_t trackRefIndex = 
		((MP4Integer8Property*)m_pProperties[1])->GetValue();

	MP4Track* pSampleTrack =
		FindTrackFromRefIndex(trackRefIndex);

	pSampleTrack->ReadSampleFragment(
		((MP4Integer32Property*)m_pProperties[3])->GetValue(),	// sampleId 
		((MP4Integer32Property*)m_pProperties[4])->GetValue(),	// sampleOffset
		((MP4Integer16Property*)m_pProperties[2])->GetValue(),	// sampleLength
		pDest);
}

void MP4RtpSampleData::WriteEmbeddedData(MP4File* pFile, u_int64_t startPos)
{
	// if not using embedded data, nothing to do
	if (((MP4Integer8Property*)m_pProperties[1])->GetValue() != (u_int8_t)-1) {
		return;
	}

	// figure out the offset within this hint sample for this embedded data
	u_int64_t offset = pFile->GetPosition() - startPos;
	ASSERT(offset <= 0xFFFFFFFF);	
	((MP4Integer32Property*)m_pProperties[4])->SetValue((u_int32_t)offset);

	u_int16_t length = ((MP4Integer16Property*)m_pProperties[2])->GetValue();

	if (m_pRefData) {
		pFile->WriteBytes(m_pRefData, length);
		return;
	} 

	if (m_refSampleId != MP4_INVALID_SAMPLE_ID) {
		u_int8_t* pSample = NULL;
		u_int32_t sampleSize = 0;

		ASSERT(m_pRefTrack);
		m_pRefTrack->ReadSample(m_refSampleId, &pSample, &sampleSize);

		ASSERT(m_refSampleOffset + length <= sampleSize);

		pFile->WriteBytes(&pSample[m_refSampleOffset], length);

		MP4Free(pSample);
		return;
	}
}

MP4RtpSampleDescriptionData::MP4RtpSampleDescriptionData(MP4RtpPacket* pPacket)
	: MP4RtpData(pPacket)
{
	((MP4Integer8Property*)m_pProperties[0])->SetValue(3);

	AddProperty( /* 1 */
		new MP4Integer8Property("trackRefIndex"));
	AddProperty( /* 2 */
		new MP4Integer16Property("length"));
	AddProperty( /* 3 */
		new MP4Integer32Property("sampleDescriptionIndex"));
	AddProperty( /* 4 */
		new MP4Integer32Property("sampleDescriptionOffset"));
	AddProperty( /* 5 */
		new MP4Integer32Property("reserved"));
}

void MP4RtpSampleDescriptionData::Set(u_int32_t sampleDescrIndex,
	u_int32_t offset, u_int16_t length)
{
	((MP4Integer16Property*)m_pProperties[2])->SetValue(length);
	((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleDescrIndex);
	((MP4Integer32Property*)m_pProperties[4])->SetValue(offset);
}

u_int16_t MP4RtpSampleDescriptionData::GetDataSize()
{
	return ((MP4Integer16Property*)m_pProperties[2])->GetValue();
}

void MP4RtpSampleDescriptionData::GetData(u_int8_t* pDest)
{
	// we start with the index into our track references
	u_int8_t trackRefIndex = 
		((MP4Integer8Property*)m_pProperties[1])->GetValue();

	// from which we can find the track structure
	MP4Track* pSampleTrack =
		FindTrackFromRefIndex(trackRefIndex);

	// next find the desired atom in the track's sample description table
	u_int32_t sampleDescrIndex =
		((MP4Integer32Property*)m_pProperties[3])->GetValue();

	MP4Atom* pTrakAtom =
		pSampleTrack->GetTrakAtom();

	char sdName[64];
	sprintf(sdName, "trak.mdia.minf.stbl.stsd.*[%u]", sampleDescrIndex);

	MP4Atom* pSdAtom =
		pTrakAtom->FindAtom(sdName);

	// bad reference
	if (pSdAtom == NULL) {
		throw new MP4Error("invalid sample description index",
			"MP4RtpSampleDescriptionData::GetData");
	}

	// check validity of the upcoming copy
	u_int16_t length = 
		((MP4Integer16Property*)m_pProperties[2])->GetValue();
	u_int32_t offset =
		((MP4Integer32Property*)m_pProperties[4])->GetValue();

	if (offset + length > pSdAtom->GetSize()) {
		throw new MP4Error("offset and/or length are too large", 
			"MP4RtpSampleDescriptionData::GetData");
	}

	// now we use the raw file to get the desired bytes

	MP4File* pFile = GetPacket()->GetHint()->GetTrack()->GetFile();

	u_int64_t orgPos = pFile->GetPosition();

	// It's not entirely clear from the spec whether the offset is from 
	// the start of the sample descirption atom, or the start of the atom's
	// data. I believe it is the former, but the commented out code will 
	// realize the latter interpretation if I turn out to be wrong.
	u_int64_t dataPos = pSdAtom->GetStart();
	//u_int64_t dataPos = pSdAtom->GetEnd() - pSdAtom->GetSize();

	pFile->SetPosition(dataPos + offset);

	pFile->ReadBytes(pDest, length);

	pFile->SetPosition(orgPos);
}

⌨️ 快捷键说明

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