📄 mp4property.cpp
字号:
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
*/
#include "mp4common.h"
MP4Property::MP4Property(const char* name)
{
m_name = name;
m_pParentAtom = NULL;
m_readOnly = false;
m_implicit = false;
}
bool MP4Property::FindProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex)
{
if (name == NULL) {
return false;
}
if (!strcasecmp(m_name, name)) {
if (m_pParentAtom) {
VERBOSE_FIND(m_pParentAtom->GetFile()->GetVerbosity(),
printf("FindProperty: matched %s\n", name));
}
*ppProperty = this;
return true;
}
return false;
}
// Integer Property
u_int64_t MP4IntegerProperty::GetValue(u_int32_t index)
{
switch (this->GetType()) {
case Integer8Property:
return ((MP4Integer8Property*)this)->GetValue(index);
case Integer16Property:
return ((MP4Integer16Property*)this)->GetValue(index);
case Integer24Property:
return ((MP4Integer24Property*)this)->GetValue(index);
case Integer32Property:
return ((MP4Integer32Property*)this)->GetValue(index);
case Integer64Property:
return ((MP4Integer64Property*)this)->GetValue(index);
default:
ASSERT(FALSE);
}
return (0);
}
void MP4IntegerProperty::SetValue(u_int64_t value, u_int32_t index)
{
switch (this->GetType()) {
case Integer8Property:
((MP4Integer8Property*)this)->SetValue(value, index);
break;
case Integer16Property:
((MP4Integer16Property*)this)->SetValue(value, index);
break;
case Integer24Property:
((MP4Integer24Property*)this)->SetValue(value, index);
break;
case Integer32Property:
((MP4Integer32Property*)this)->SetValue(value, index);
break;
case Integer64Property:
((MP4Integer64Property*)this)->SetValue(value, index);
break;
default:
ASSERT(FALSE);
}
}
void MP4IntegerProperty::InsertValue(u_int64_t value, u_int32_t index)
{
switch (this->GetType()) {
case Integer8Property:
((MP4Integer8Property*)this)->InsertValue(value, index);
break;
case Integer16Property:
((MP4Integer16Property*)this)->InsertValue(value, index);
break;
case Integer24Property:
((MP4Integer24Property*)this)->InsertValue(value, index);
break;
case Integer32Property:
((MP4Integer32Property*)this)->InsertValue(value, index);
break;
case Integer64Property:
((MP4Integer64Property*)this)->InsertValue(value, index);
break;
default:
ASSERT(FALSE);
}
}
void MP4IntegerProperty::DeleteValue(u_int32_t index)
{
switch (this->GetType()) {
case Integer8Property:
((MP4Integer8Property*)this)->DeleteValue(index);
break;
case Integer16Property:
((MP4Integer16Property*)this)->DeleteValue(index);
break;
case Integer24Property:
((MP4Integer24Property*)this)->DeleteValue(index);
break;
case Integer32Property:
((MP4Integer32Property*)this)->DeleteValue(index);
break;
case Integer64Property:
((MP4Integer64Property*)this)->DeleteValue(index);
break;
default:
ASSERT(FALSE);
}
}
void MP4IntegerProperty::IncrementValue(int32_t increment, u_int32_t index)
{
SetValue(GetValue() + increment);
}
void MP4Integer8Property::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 (0x%02x)\n",
m_name, m_values[index], m_values[index]);
}
void MP4Integer16Property::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 (0x%04x)\n",
m_name, m_values[index], m_values[index]);
}
void MP4Integer24Property::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 (0x%06x)\n",
m_name, m_values[index], m_values[index]);
}
void MP4Integer32Property::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 (0x%08x)\n",
m_name, m_values[index], m_values[index]);
}
void MP4Integer64Property::Dump(FILE* pFile, u_int8_t indent,
bool dumpImplicits, u_int32_t index)
{
if (m_implicit && !dumpImplicits) {
return;
}
Indent(pFile, indent);
fprintf(pFile,
#ifdef _WIN32
"%s = "LLU" (0x%016I64x)\n",
#else
"%s = "LLU" (0x%016llx)\n",
#endif
m_name, m_values[index], m_values[index]);
}
// MP4BitfieldProperty
void MP4BitfieldProperty::Read(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
m_values[index] = pFile->ReadBits(m_numBits);
}
void MP4BitfieldProperty::Write(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
pFile->WriteBits(m_values[index], m_numBits);
}
void MP4BitfieldProperty::Dump(FILE* pFile, u_int8_t indent,
bool dumpImplicits, u_int32_t index)
{
if (m_implicit && !dumpImplicits) {
return;
}
Indent(pFile, indent);
u_int8_t hexWidth = m_numBits / 4;
if (hexWidth == 0 || (m_numBits % 4)) {
hexWidth++;
}
fprintf(pFile,
#ifdef _WIN32
"%s = "LLU" (0x%0*I64x) <%u bits>\n",
#else
"%s = "LLU" (0x%0*llx) <%u bits>\n",
#endif
m_name, m_values[index], (int)hexWidth, m_values[index], m_numBits);
}
// MP4Float32Property
void MP4Float32Property::Read(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
if (m_useFixed16Format) {
m_values[index] = pFile->ReadFixed16();
} else if (m_useFixed32Format) {
m_values[index] = pFile->ReadFixed32();
} else {
m_values[index] = pFile->ReadFloat();
}
}
void MP4Float32Property::Write(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
if (m_useFixed16Format) {
pFile->WriteFixed16(m_values[index]);
} else if (m_useFixed32Format) {
pFile->WriteFixed32(m_values[index]);
} else {
pFile->WriteFloat(m_values[index]);
}
}
void MP4Float32Property::Dump(FILE* pFile, u_int8_t indent,
bool dumpImplicits, u_int32_t index)
{
if (m_implicit && !dumpImplicits) {
return;
}
Indent(pFile, indent);
fprintf(pFile, "%s = %f\n",
m_name, m_values[index]);
}
// MP4StringProperty
MP4StringProperty::MP4StringProperty(char* name,
bool useCountedFormat, bool useUnicode)
: MP4Property(name)
{
SetCount(1);
m_values[0] = NULL;
m_useCountedFormat = useCountedFormat;
m_useExpandedCount = false;
m_useUnicode = useUnicode;
m_fixedLength = 0; // length not fixed
}
MP4StringProperty::~MP4StringProperty()
{
u_int32_t count = GetCount();
for (u_int32_t i = 0; i < count; i++) {
MP4Free(m_values[i]);
}
}
void MP4StringProperty::SetCount(u_int32_t count)
{
u_int32_t oldCount = m_values.Size();
m_values.Resize(count);
for (u_int32_t i = oldCount; i < count; i++) {
m_values[i] = NULL;
}
}
void MP4StringProperty::SetValue(const char* value, u_int32_t index)
{
if (m_readOnly) {
throw new MP4Error(EACCES, "property is read-only", m_name);
}
MP4Free(m_values[index]);
if (m_fixedLength) {
m_values[index] = (char*)MP4Calloc(m_fixedLength + 1);
if (value) {
strncpy(m_values[index], value, m_fixedLength);
}
} else {
if (value) {
m_values[index] = MP4Stralloc(value);
} else {
m_values[index] = NULL;
}
}
}
void MP4StringProperty::Read(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
if (m_useCountedFormat) {
m_values[index] = pFile->ReadCountedString(
(m_useUnicode ? 2 : 1), m_useExpandedCount);
} else if (m_fixedLength) {
MP4Free(m_values[index]);
m_values[index] = (char*)MP4Calloc(m_fixedLength + 1);
pFile->ReadBytes((u_int8_t*)m_values[index], m_fixedLength);
} else {
m_values[index] = pFile->ReadString();
}
}
void MP4StringProperty::Write(MP4File* pFile, u_int32_t index)
{
if (m_implicit) {
return;
}
if (m_useCountedFormat) {
pFile->WriteCountedString(m_values[index],
(m_useUnicode ? 2 : 1), m_useExpandedCount);
} else if (m_fixedLength) {
pFile->WriteBytes((u_int8_t*)m_values[index], m_fixedLength);
} else {
pFile->WriteString(m_values[index]);
}
}
void MP4StringProperty::Dump(FILE* pFile, u_int8_t indent,
bool dumpImplicits, u_int32_t index)
{
if (m_implicit && !dumpImplicits) {
return;
}
Indent(pFile, indent);
if (m_useUnicode) {
fprintf(pFile, "%s = %ls\n", m_name, (wchar_t*)m_values[index]);
} else {
fprintf(pFile, "%s = %s\n", m_name, m_values[index]);
}
}
// MP4BytesProperty
MP4BytesProperty::MP4BytesProperty(char* name, u_int32_t valueSize)
: MP4Property(name)
{
SetCount(1);
m_values[0] = (u_int8_t*)MP4Calloc(valueSize);
m_valueSizes[0] = valueSize;
m_fixedValueSize = 0;
}
MP4BytesProperty::~MP4BytesProperty()
{
u_int32_t count = GetCount();
for (u_int32_t i = 0; i < count; i++) {
MP4Free(m_values[i]);
}
}
void MP4BytesProperty::SetCount(u_int32_t count)
{
u_int32_t oldCount = m_values.Size();
m_values.Resize(count);
m_valueSizes.Resize(count);
for (u_int32_t i = oldCount; i < count; i++) {
m_values[i] = NULL;
m_valueSizes[i] = 0;
}
}
void MP4BytesProperty::SetValue(const u_int8_t* pValue, u_int32_t valueSize,
u_int32_t index)
{
if (m_readOnly) {
throw new MP4Error(EACCES, "property is read-only", m_name);
}
if (m_fixedValueSize) {
if (valueSize > m_fixedValueSize) {
throw new MP4Error("value size exceeds fixed value size",
"MP4BytesProperty::SetValue");
}
if (m_values[index] == NULL) {
m_values[index] = (u_int8_t*)MP4Calloc(m_fixedValueSize);
m_valueSizes[index] = m_fixedValueSize;
}
if (pValue) {
memcpy(m_values[index], pValue, valueSize);
}
} else {
MP4Free(m_values[index]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -