📄 mp4property.cpp
字号:
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 + -