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

📄 mp4property.cpp

📁 AAC编解码源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (pValue) {
			m_values[index] = (u_int8_t*)MP4Malloc(valueSize);
			memcpy(m_values[index], pValue, valueSize);
			m_valueSizes[index] = valueSize;
		} else {
			m_values[index] = NULL;
			m_valueSizes[index] = 0;
		}
	}
}

void MP4BytesProperty::SetValueSize(u_int32_t valueSize, u_int32_t index) 
{
	if (m_fixedValueSize) {
		throw new MP4Error("can't change size of fixed sized property",
			"MP4BytesProperty::SetValueSize");
	}
	if (m_values[index] != NULL) {
		m_values[index] = (u_int8_t*)MP4Realloc(m_values[index], valueSize);
	}
	m_valueSizes[index] = valueSize;
}

void MP4BytesProperty::SetFixedSize(u_int32_t fixedSize) 
{
	m_fixedValueSize = 0;
	for (u_int32_t i = 0; i < GetCount(); i++) {
		SetValueSize(fixedSize, i);
	}
	m_fixedValueSize = fixedSize;
}

void MP4BytesProperty::Read(MP4File* pFile, u_int32_t index)
{
	if (m_implicit) {
		return;
	}
	MP4Free(m_values[index]);
	m_values[index] = (u_int8_t*)MP4Malloc(m_valueSizes[index]);
	pFile->ReadBytes(m_values[index], m_valueSizes[index]);
}

void MP4BytesProperty::Write(MP4File* pFile, u_int32_t index)
{
	if (m_implicit) {
		return;
	}
	pFile->WriteBytes(m_values[index], m_valueSizes[index]);
}

void MP4BytesProperty::Dump(FILE* pFile, u_int8_t indent,
	bool dumpImplicits, u_int32_t index)
{
	if (m_implicit && !dumpImplicits) {
		return;
	}
	Indent(pFile, indent);
	fprintf(pFile, "%s = <%u bytes> ", m_name, m_valueSizes[index]);
	for (u_int32_t i = 0; i < m_valueSizes[index]; i++) {
		if ((i % 16) == 0 && m_valueSizes[index] > 16) {
			fprintf(pFile, "\n");
			Indent(pFile, indent);
		}
		fprintf(pFile, "%02x ", m_values[index][i]);
	}
	fprintf(pFile, "\n");
}

// MP4TableProperty

MP4TableProperty::MP4TableProperty(char* name, MP4Property* pCountProperty)
	: MP4Property(name) 
{
	ASSERT(pCountProperty->GetType() == Integer8Property
		|| pCountProperty->GetType() == Integer32Property);
	m_pCountProperty = pCountProperty;
	m_pCountProperty->SetReadOnly();
}

MP4TableProperty::~MP4TableProperty()
{
	for (u_int32_t i = 0; i < m_pProperties.Size(); i++) {
		delete m_pProperties[i];
	}
}

void MP4TableProperty::AddProperty(MP4Property* pProperty) 
{
	ASSERT(pProperty);
	ASSERT(pProperty->GetType() != TableProperty);
	ASSERT(pProperty->GetType() != DescriptorProperty);
	m_pProperties.Add(pProperty);
	pProperty->SetParentAtom(m_pParentAtom);
	pProperty->SetCount(0);
}

bool MP4TableProperty::FindProperty(const char *name,
	MP4Property** ppProperty, u_int32_t* pIndex)
{
	ASSERT(m_name);

	// check if first component of name matches ourselves
	if (!MP4NameFirstMatches(m_name, name)) {
		return false;
	}

	// check if the specified table entry exists
	u_int32_t index;
	bool haveIndex = MP4NameFirstIndex(name, &index);
	if (haveIndex) {
		if (index >= GetCount()) {
			return false;
		}
		if (pIndex) {
			*pIndex = index;
		}
	}

	VERBOSE_FIND(m_pParentAtom->GetFile()->GetVerbosity(),
		printf("FindProperty: matched %s\n", name));

	// get name of table property
	const char *tablePropName = MP4NameAfterFirst(name);
	if (tablePropName == NULL) {
		if (!haveIndex) {
			*ppProperty = this;
			return true;
		}
		return false;
	}

	// check if this table property exists
	return FindContainedProperty(tablePropName, ppProperty, pIndex);
}

bool MP4TableProperty::FindContainedProperty(const char *name,
	MP4Property** ppProperty, u_int32_t* pIndex)
{
	u_int32_t numProperties = m_pProperties.Size();

	for (u_int32_t i = 0; i < numProperties; i++) {
		if (m_pProperties[i]->FindProperty(name, ppProperty, pIndex)) {
			return true;
		}
	}
	return false;
}

void MP4TableProperty::Read(MP4File* pFile, u_int32_t index)
{
	ASSERT(index == 0);

	if (m_implicit) {
		return;
	}

	u_int32_t numProperties = m_pProperties.Size();

	if (numProperties == 0) {
		WARNING(numProperties == 0);
		return;
	}

	u_int32_t numEntries = GetCount();

	/* for each property set size */
	for (u_int32_t j = 0; j < numProperties; j++) {
		m_pProperties[j]->SetCount(numEntries);
	}

	for (u_int32_t i = 0; i < numEntries; i++) {
		ReadEntry(pFile, i);
	}
}

void MP4TableProperty::ReadEntry(MP4File* pFile, u_int32_t index)
{
	for (u_int32_t j = 0; j < m_pProperties.Size(); j++) {
		m_pProperties[j]->Read(pFile, index);
	}
}

void MP4TableProperty::Write(MP4File* pFile, u_int32_t index)
{
	ASSERT(index == 0);

	if (m_implicit) {
		return;
	}

	u_int32_t numProperties = m_pProperties.Size();

	if (numProperties == 0) {
		WARNING(numProperties == 0);
		return;
	}

	u_int32_t numEntries = GetCount();

	ASSERT(m_pProperties[0]->GetCount() == numEntries);

	for (u_int32_t i = 0; i < numEntries; i++) {
		WriteEntry(pFile, i);
	}
}

void MP4TableProperty::WriteEntry(MP4File* pFile, u_int32_t index)
{
	for (u_int32_t j = 0; j < m_pProperties.Size(); j++) {
		m_pProperties[j]->Write(pFile, index);
	}
}

void MP4TableProperty::Dump(FILE* pFile, u_int8_t indent,
	bool dumpImplicits, u_int32_t index)
{
	ASSERT(index == 0);

	// implicit tables just can't be dumped
	if (m_implicit) {
		return;
	}

	u_int32_t numProperties = m_pProperties.Size();

	if (numProperties == 0) {
		WARNING(numProperties == 0);
		return;
	}

	u_int32_t numEntries = GetCount();

	for (u_int32_t i = 0; i < numEntries; i++) {
		for (u_int32_t j = 0; j < numProperties; j++) {
			m_pProperties[j]->Dump(pFile, indent + 1, dumpImplicits, i);
		}
	}
}

// MP4DescriptorProperty
  
MP4DescriptorProperty::MP4DescriptorProperty(char* name, 
	u_int8_t tagsStart, u_int8_t tagsEnd, bool mandatory, bool onlyOne)
	: MP4Property(name) 
{ 
	SetTags(tagsStart, tagsEnd);
	m_sizeLimit = 0;
	m_mandatory = mandatory;
	m_onlyOne = onlyOne;
}

MP4DescriptorProperty::~MP4DescriptorProperty() 
{
	for (u_int32_t i = 0; i < m_pDescriptors.Size(); i++) {
		delete m_pDescriptors[i];
	}
}

void MP4DescriptorProperty::SetParentAtom(MP4Atom* pParentAtom) {
	m_pParentAtom = pParentAtom;
	for (u_int32_t i = 0; i < m_pDescriptors.Size(); i++) {
		m_pDescriptors[i]->SetParentAtom(pParentAtom);
	}
}

MP4Descriptor* MP4DescriptorProperty::AddDescriptor(u_int8_t tag)
{
	// check that tag is in expected range
	ASSERT(tag >= m_tagsStart && tag <= m_tagsEnd);

	MP4Descriptor* pDescriptor = CreateDescriptor(tag);
	ASSERT(pDescriptor);

	m_pDescriptors.Add(pDescriptor);
	pDescriptor->SetParentAtom(m_pParentAtom);

	return pDescriptor;
}

void MP4DescriptorProperty::DeleteDescriptor(u_int32_t index)
{
	delete m_pDescriptors[index];
	m_pDescriptors.Delete(index);
}

void MP4DescriptorProperty::Generate()
{
	// generate a default descriptor
	// if it is mandatory, and single
	if (m_mandatory && m_onlyOne) {
		MP4Descriptor* pDescriptor = 
			AddDescriptor(m_tagsStart);
		pDescriptor->Generate();
	}
}

bool MP4DescriptorProperty::FindProperty(const char *name,
	MP4Property** ppProperty, u_int32_t* pIndex)
{
	// we're unnamed, so just check contained properties
	if (m_name == NULL || !strcmp(m_name, "")) {
		return FindContainedProperty(name, ppProperty, pIndex);
	}

	// check if first component of name matches ourselves
	if (!MP4NameFirstMatches(m_name, name)) {
		return false;
	}

	// check if the specific descriptor entry exists
	u_int32_t descrIndex;
	bool haveDescrIndex = MP4NameFirstIndex(name, &descrIndex);

	if (haveDescrIndex && descrIndex >= GetCount()) {
		return false;
	}

	if (m_pParentAtom) {
		VERBOSE_FIND(m_pParentAtom->GetFile()->GetVerbosity(),
			printf("FindProperty: matched %s\n", name));
	}

	// get name of descriptor property
	name = MP4NameAfterFirst(name);
	if (name == NULL) {
		if (!haveDescrIndex) {
			*ppProperty = this;
			return true;
		}
		return false;
	}

	/* check rest of name */
	if (haveDescrIndex) {
		return m_pDescriptors[descrIndex]->FindProperty(name, 
			ppProperty, pIndex); 
	} else {
		return FindContainedProperty(name, ppProperty, pIndex);
	}
}

bool MP4DescriptorProperty::FindContainedProperty(const char *name,
	MP4Property** ppProperty, u_int32_t* pIndex)
{
	for (u_int32_t i = 0; i < m_pDescriptors.Size(); i++) {
		if (m_pDescriptors[i]->FindProperty(name, ppProperty, pIndex)) {
			return true;
		}
	}
	return false;
}

void MP4DescriptorProperty::Read(MP4File* pFile, u_int32_t index)
{
	ASSERT(index == 0);

	if (m_implicit) {
		return;
	}

	u_int64_t start = pFile->GetPosition();

	while (true) {
		// enforce size limitation
		if (m_sizeLimit && pFile->GetPosition() >= start + m_sizeLimit) {
			break;
		}

		u_int8_t tag;
		try {
			pFile->PeekBytes(&tag, 1);
		}
		catch (MP4Error* e) {
			if (pFile->GetPosition() >= pFile->GetSize()) {
				// EOF
				delete e;
				break;
			}
			throw e;
		}

		// check if tag is in desired range
		if (tag < m_tagsStart || tag > m_tagsEnd) {
			break;
		}

		MP4Descriptor* pDescriptor = 
			AddDescriptor(tag);

		pDescriptor->Read(pFile);
	}

	// warnings
	if (m_mandatory && m_pDescriptors.Size() == 0) {
		VERBOSE_READ(pFile->GetVerbosity(),
			printf("Warning: Mandatory descriptor 0x%02x missing\n",
				m_tagsStart));
	} else if (m_onlyOne && m_pDescriptors.Size() > 1) {
		VERBOSE_READ(pFile->GetVerbosity(),
			printf("Warning: Descriptor 0x%02x has more than one instance\n",
				m_tagsStart));
	}
}

void MP4DescriptorProperty::Write(MP4File* pFile, u_int32_t index)
{
	ASSERT(index == 0);

	if (m_implicit) {
		return;
	}

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

void MP4DescriptorProperty::Dump(FILE* pFile, u_int8_t indent,
	bool dumpImplicits, u_int32_t index)
{
	ASSERT(index == 0);

	if (m_implicit && !dumpImplicits) {
		return;
	}

	if (m_name) {
		Indent(pFile, indent);
		fprintf(pFile, "%s\n", m_name);
		indent++;
	}

	for (u_int32_t i = 0; i < m_pDescriptors.Size(); i++) {
		m_pDescriptors[i]->Dump(pFile, indent, dumpImplicits);
	}
}

⌨️ 快捷键说明

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