| /* |
| * 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 |
| */ |
| |
| #ifndef MP4V2_IMPL_MP4PROPERTY_H |
| #define MP4V2_IMPL_MP4PROPERTY_H |
| |
| namespace mp4v2 { namespace impl { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| // forward declarations |
| class MP4Atom; |
| |
| class MP4Descriptor; |
| MP4ARRAY_DECL(MP4Descriptor, MP4Descriptor*); |
| |
| enum MP4PropertyType { |
| Integer8Property, |
| Integer16Property, |
| Integer24Property, |
| Integer32Property, |
| Integer64Property, |
| Float32Property, |
| StringProperty, |
| BytesProperty, |
| TableProperty, |
| DescriptorProperty, |
| LanguageCodeProperty, |
| BasicTypeProperty, |
| }; |
| |
| class MP4Property { |
| public: |
| MP4Property(MP4Atom& parentAtom, const char *name = NULL); |
| |
| virtual ~MP4Property() { } |
| |
| MP4Atom& GetParentAtom() { |
| return m_parentAtom; |
| } |
| |
| const char *GetName() { |
| return m_name; |
| } |
| |
| virtual MP4PropertyType GetType() = 0; |
| |
| bool IsReadOnly() { |
| return m_readOnly; |
| } |
| void SetReadOnly(bool value = true) { |
| m_readOnly = value; |
| } |
| |
| bool IsImplicit() { |
| return m_implicit; |
| } |
| void SetImplicit(bool value = true) { |
| m_implicit = value; |
| } |
| |
| virtual uint32_t GetCount() = 0; |
| virtual void SetCount(uint32_t count) = 0; |
| |
| virtual void Generate() { /* default is a no-op */ }; |
| |
| virtual void Read(MP4File& file, uint32_t index = 0) = 0; |
| |
| virtual void Write(MP4File& file, uint32_t index = 0) = 0; |
| |
| virtual void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0) = 0; |
| |
| virtual bool FindProperty(const char* name, |
| MP4Property** ppProperty, uint32_t* pIndex = NULL); |
| |
| protected: |
| MP4Atom& m_parentAtom; |
| const char* m_name; |
| bool m_readOnly; |
| bool m_implicit; |
| |
| private: |
| MP4Property(); |
| MP4Property ( const MP4Property &src ); |
| MP4Property &operator= ( const MP4Property &src ); |
| }; |
| |
| MP4ARRAY_DECL(MP4Property, MP4Property*); |
| |
| class MP4IntegerProperty : public MP4Property { |
| protected: |
| MP4IntegerProperty(MP4Atom& parentAtom, const char* name) |
| : MP4Property(parentAtom, name) { }; |
| |
| public: |
| uint64_t GetValue(uint32_t index = 0); |
| |
| void SetValue(uint64_t value, uint32_t index = 0); |
| |
| void InsertValue(uint64_t value, uint32_t index = 0); |
| |
| void DeleteValue(uint32_t index = 0); |
| |
| void IncrementValue(int32_t increment = 1, uint32_t index = 0); |
| |
| private: |
| MP4IntegerProperty(); |
| MP4IntegerProperty ( const MP4IntegerProperty &src ); |
| MP4IntegerProperty &operator= ( const MP4IntegerProperty &src ); |
| }; |
| |
| #define MP4INTEGER_PROPERTY_DECL2(isize, xsize) \ |
| class MP4Integer##xsize##Property : public MP4IntegerProperty { \ |
| public: \ |
| MP4Integer##xsize##Property(MP4Atom& parentAtom, const char* name) \ |
| : MP4IntegerProperty(parentAtom, name) { \ |
| SetCount(1); \ |
| m_values[0] = 0; \ |
| } \ |
| \ |
| MP4PropertyType GetType() { \ |
| return Integer##xsize##Property; \ |
| } \ |
| \ |
| uint32_t GetCount() { \ |
| return m_values.Size(); \ |
| } \ |
| void SetCount(uint32_t count) { \ |
| m_values.Resize(count); \ |
| } \ |
| \ |
| uint##isize##_t GetValue(uint32_t index = 0) { \ |
| return m_values[index]; \ |
| } \ |
| \ |
| void SetValue(uint##isize##_t value, uint32_t index = 0) { \ |
| if (m_readOnly) { \ |
| ostringstream msg; \ |
| msg << "property is read-only: " << m_name; \ |
| throw new PlatformException(msg.str().c_str(), EACCES, __FILE__, __LINE__, __FUNCTION__); \ |
| } \ |
| m_values[index] = value; \ |
| } \ |
| void AddValue(uint##isize##_t value) { \ |
| m_values.Add(value); \ |
| } \ |
| void InsertValue(uint##isize##_t value, uint32_t index) { \ |
| m_values.Insert(value, index); \ |
| } \ |
| void DeleteValue(uint32_t index) { \ |
| m_values.Delete(index); \ |
| } \ |
| void IncrementValue(int32_t increment = 1, uint32_t index = 0) { \ |
| m_values[index] += increment; \ |
| } \ |
| void Read(MP4File& file, uint32_t index = 0) { \ |
| if (m_implicit) { \ |
| return; \ |
| } \ |
| m_values[index] = file.ReadUInt##xsize(); \ |
| } \ |
| \ |
| void Write(MP4File& file, uint32_t index = 0) { \ |
| if (m_implicit) { \ |
| return; \ |
| } \ |
| file.WriteUInt##xsize(m_values[index]); \ |
| } \ |
| void Dump(uint8_t indent, \ |
| bool dumpImplicits, uint32_t index = 0); \ |
| \ |
| protected: \ |
| MP4Integer##isize##Array m_values; \ |
| private: \ |
| MP4Integer##xsize##Property(); \ |
| MP4Integer##xsize##Property ( const MP4Integer##xsize##Property &src ); \ |
| MP4Integer##xsize##Property &operator= ( const MP4Integer##xsize##Property &src ); \ |
| }; |
| |
| #define MP4INTEGER_PROPERTY_DECL(size) \ |
| MP4INTEGER_PROPERTY_DECL2(size, size) |
| |
| MP4INTEGER_PROPERTY_DECL(8); |
| MP4INTEGER_PROPERTY_DECL(16); |
| MP4INTEGER_PROPERTY_DECL2(32, 24); |
| MP4INTEGER_PROPERTY_DECL(32); |
| MP4INTEGER_PROPERTY_DECL(64); |
| |
| class MP4BitfieldProperty : public MP4Integer64Property { |
| public: |
| MP4BitfieldProperty(MP4Atom& parentAtom, const char* name, uint8_t numBits) |
| : MP4Integer64Property(parentAtom, name) { |
| ASSERT(numBits != 0); |
| ASSERT(numBits <= 64); |
| m_numBits = numBits; |
| } |
| |
| uint8_t GetNumBits() { |
| return m_numBits; |
| } |
| void SetNumBits(uint8_t numBits) { |
| m_numBits = numBits; |
| } |
| |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| protected: |
| uint8_t m_numBits; |
| |
| private: |
| MP4BitfieldProperty(); |
| MP4BitfieldProperty ( const MP4BitfieldProperty &src ); |
| MP4BitfieldProperty &operator= ( const MP4BitfieldProperty &src ); |
| }; |
| |
| class MP4Float32Property : public MP4Property { |
| public: |
| MP4Float32Property(MP4Atom& parentAtom, const char* name) |
| : MP4Property(parentAtom, name) { |
| m_useFixed16Format = false; |
| m_useFixed32Format = false; |
| SetCount(1); |
| m_values[0] = 0.0; |
| } |
| |
| MP4PropertyType GetType() { |
| return Float32Property; |
| } |
| |
| uint32_t GetCount() { |
| return m_values.Size(); |
| } |
| void SetCount(uint32_t count) { |
| m_values.Resize(count); |
| } |
| |
| float GetValue(uint32_t index = 0) { |
| return m_values[index]; |
| } |
| |
| void SetValue(float value, uint32_t index = 0) { |
| if (m_readOnly) { |
| ostringstream msg; |
| msg << "property is read-only: " << m_name; |
| throw new PlatformException(msg.str().c_str(), EACCES, __FILE__, __LINE__, __FUNCTION__); |
| } |
| m_values[index] = value; |
| } |
| |
| void AddValue(float value) { |
| m_values.Add(value); |
| } |
| |
| void InsertValue(float value, uint32_t index) { |
| m_values.Insert(value, index); |
| } |
| |
| bool IsFixed16Format() { |
| return m_useFixed16Format; |
| } |
| |
| void SetFixed16Format(bool useFixed16Format = true) { |
| m_useFixed16Format = useFixed16Format; |
| } |
| |
| bool IsFixed32Format() { |
| return m_useFixed32Format; |
| } |
| |
| void SetFixed32Format(bool useFixed32Format = true) { |
| m_useFixed32Format = useFixed32Format; |
| } |
| |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| protected: |
| bool m_useFixed16Format; |
| bool m_useFixed32Format; |
| MP4Float32Array m_values; |
| |
| private: |
| MP4Float32Property(); |
| MP4Float32Property ( const MP4Float32Property &src ); |
| MP4Float32Property &operator= ( const MP4Float32Property &src ); |
| }; |
| |
| class MP4StringProperty : public MP4Property { |
| public: |
| MP4StringProperty(MP4Atom& parentAtom, const char* name, |
| bool useCountedFormat = false, bool useUnicode = false, bool arrayMode = false); |
| |
| ~MP4StringProperty(); |
| |
| MP4PropertyType GetType() { |
| return StringProperty; |
| } |
| |
| uint32_t GetCount() { |
| return m_values.Size(); |
| } |
| |
| void SetCount(uint32_t count); |
| |
| const char* GetValue(uint32_t index = 0) { |
| return m_values[index]; |
| } |
| |
| void SetValue(const char* value, uint32_t index = 0); |
| |
| void AddValue(const char* value) { |
| uint32_t count = GetCount(); |
| SetCount(count + 1); |
| SetValue(value, count); |
| } |
| |
| bool IsCountedFormat() { |
| return m_useCountedFormat; |
| } |
| |
| void SetCountedFormat(bool useCountedFormat) { |
| m_useCountedFormat = useCountedFormat; |
| } |
| |
| bool IsExpandedCountedFormat() { |
| return m_useExpandedCount; |
| } |
| |
| void SetExpandedCountedFormat(bool useExpandedCount) { |
| m_useExpandedCount = useExpandedCount; |
| } |
| |
| bool IsUnicode() { |
| return m_useUnicode; |
| } |
| |
| void SetUnicode(bool useUnicode) { |
| m_useUnicode = useUnicode; |
| } |
| |
| uint32_t GetFixedLength() { |
| return m_fixedLength; |
| } |
| |
| void SetFixedLength(uint32_t fixedLength) { |
| m_fixedLength = fixedLength; |
| } |
| |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| protected: |
| bool m_arrayMode; // during read/write ignore index and read/write full array |
| bool m_useCountedFormat; |
| bool m_useExpandedCount; |
| bool m_useUnicode; |
| uint32_t m_fixedLength; |
| |
| MP4StringArray m_values; |
| |
| private: |
| MP4StringProperty(); |
| MP4StringProperty ( const MP4StringProperty &src ); |
| MP4StringProperty &operator= ( const MP4StringProperty &src ); |
| }; |
| |
| class MP4BytesProperty : public MP4Property { |
| public: |
| MP4BytesProperty(MP4Atom& parentAtom, const char* name, uint32_t valueSize = 0, |
| uint32_t defaultValueSize = 0); |
| |
| ~MP4BytesProperty(); |
| |
| MP4PropertyType GetType() { |
| return BytesProperty; |
| } |
| |
| uint32_t GetCount() { |
| return m_values.Size(); |
| } |
| |
| void SetCount(uint32_t count); |
| |
| void GetValue(uint8_t** ppValue, uint32_t* pValueSize, |
| uint32_t index = 0) { |
| // N.B. caller must free memory |
| *ppValue = (uint8_t*)MP4Malloc(m_valueSizes[index]); |
| memcpy(*ppValue, m_values[index], m_valueSizes[index]); |
| *pValueSize = m_valueSizes[index]; |
| } |
| |
| char* GetValueStringAlloc( uint32_t index = 0 ) { |
| char* buf = (char*)MP4Malloc( m_valueSizes[index] + 1 ); |
| memcpy( buf, m_values[index], m_valueSizes[index] ); |
| buf[m_valueSizes[index]] = '\0'; |
| return buf; |
| } |
| |
| bool CompareToString( const string& s, uint32_t index = 0 ) { |
| return string( (const char*)m_values[index], m_valueSizes[index] ) != s; |
| } |
| |
| void CopyValue(uint8_t* pValue, uint32_t index = 0) { |
| // N.B. caller takes responsbility for valid pointer |
| // and sufficient memory at the destination |
| memcpy(pValue, m_values[index], m_valueSizes[index]); |
| } |
| |
| void SetValue(const uint8_t* pValue, uint32_t valueSize, |
| uint32_t index = 0); |
| |
| void AddValue(const uint8_t* pValue, uint32_t valueSize) { |
| uint32_t count = GetCount(); |
| SetCount(count + 1); |
| SetValue(pValue, valueSize, count); |
| } |
| |
| uint32_t GetValueSize( uint32_t index = 0 ) { |
| return m_valueSizes[index]; |
| } |
| |
| void SetValueSize(uint32_t valueSize, uint32_t index = 0); |
| |
| uint32_t GetFixedSize() { |
| return m_fixedValueSize; |
| } |
| |
| void SetFixedSize(uint32_t fixedSize); |
| |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| protected: |
| uint32_t m_fixedValueSize; |
| uint32_t m_defaultValueSize; |
| MP4Integer32Array m_valueSizes; |
| MP4BytesArray m_values; |
| |
| private: |
| MP4BytesProperty(); |
| MP4BytesProperty ( const MP4BytesProperty &src ); |
| MP4BytesProperty &operator= ( const MP4BytesProperty &src ); |
| }; |
| |
| class MP4TableProperty : public MP4Property { |
| public: |
| MP4TableProperty(MP4Atom& parentAtom, const char* name, MP4IntegerProperty* pCountProperty); |
| |
| ~MP4TableProperty(); |
| |
| MP4PropertyType GetType() { |
| return TableProperty; |
| } |
| |
| void AddProperty(MP4Property* pProperty); |
| |
| MP4Property* GetProperty(uint32_t index) { |
| return m_pProperties[index]; |
| } |
| |
| virtual uint32_t GetCount() { |
| return m_pCountProperty->GetValue(); |
| } |
| virtual void SetCount(uint32_t count) { |
| m_pCountProperty->SetValue(count); |
| } |
| |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| bool FindProperty(const char* name, |
| MP4Property** ppProperty, uint32_t* pIndex = NULL); |
| |
| protected: |
| virtual void ReadEntry(MP4File& file, uint32_t index); |
| virtual void WriteEntry(MP4File& file, uint32_t index); |
| |
| bool FindContainedProperty(const char* name, |
| MP4Property** ppProperty, uint32_t* pIndex); |
| |
| protected: |
| MP4IntegerProperty* m_pCountProperty; |
| MP4PropertyArray m_pProperties; |
| |
| private: |
| MP4TableProperty(); |
| MP4TableProperty ( const MP4TableProperty &src ); |
| MP4TableProperty &operator= ( const MP4TableProperty &src ); |
| }; |
| |
| class MP4DescriptorProperty : public MP4Property { |
| public: |
| MP4DescriptorProperty(MP4Atom& parentAtom, const char* name = NULL, |
| uint8_t tagsStart = 0, uint8_t tagsEnd = 0, |
| bool mandatory = false, bool onlyOne = false); |
| |
| ~MP4DescriptorProperty(); |
| |
| MP4PropertyType GetType() { |
| return DescriptorProperty; |
| } |
| |
| void SetParentAtom(MP4Atom* pParentAtom); |
| |
| void SetSizeLimit(uint64_t sizeLimit) { |
| m_sizeLimit = sizeLimit; |
| } |
| |
| uint32_t GetCount() { |
| return m_pDescriptors.Size(); |
| } |
| void SetCount(uint32_t count) { |
| m_pDescriptors.Resize(count); |
| } |
| |
| void SetTags(uint8_t tagsStart, uint8_t tagsEnd = 0) { |
| m_tagsStart = tagsStart; |
| m_tagsEnd = tagsEnd ? tagsEnd : tagsStart; |
| } |
| |
| MP4Descriptor* AddDescriptor(uint8_t tag); |
| |
| void AppendDescriptor(MP4Descriptor* pDescriptor) { |
| m_pDescriptors.Add(pDescriptor); |
| } |
| |
| void DeleteDescriptor(uint32_t index); |
| |
| void Generate(); |
| void Read(MP4File& file, uint32_t index = 0); |
| void Write(MP4File& file, uint32_t index = 0); |
| void Dump(uint8_t indent, |
| bool dumpImplicits, uint32_t index = 0); |
| |
| bool FindProperty(const char* name, |
| MP4Property** ppProperty, uint32_t* pIndex = NULL); |
| |
| protected: |
| virtual MP4Descriptor* CreateDescriptor(MP4Atom& parentAtom, uint8_t tag); |
| |
| bool FindContainedProperty(const char* name, |
| MP4Property** ppProperty, uint32_t* pIndex); |
| |
| protected: |
| uint8_t m_tagsStart; |
| uint8_t m_tagsEnd; |
| uint64_t m_sizeLimit; |
| bool m_mandatory; |
| bool m_onlyOne; |
| MP4DescriptorArray m_pDescriptors; |
| |
| private: |
| MP4DescriptorProperty(); |
| MP4DescriptorProperty ( const MP4DescriptorProperty &src ); |
| MP4DescriptorProperty &operator= ( const MP4DescriptorProperty &src ); |
| }; |
| |
| class MP4QosQualifierProperty : public MP4DescriptorProperty { |
| public: |
| MP4QosQualifierProperty(MP4Atom& parentAtom, const char* name = NULL, |
| uint8_t tagsStart = 0, uint8_t tagsEnd = 0, |
| bool mandatory = false, bool onlyOne = false) : |
| MP4DescriptorProperty(parentAtom, name, tagsStart, tagsEnd, mandatory, onlyOne) { } |
| |
| protected: |
| MP4Descriptor* CreateDescriptor(MP4Atom& parentAtom, uint8_t tag); |
| |
| private: |
| MP4QosQualifierProperty(); |
| MP4QosQualifierProperty ( const MP4QosQualifierProperty &src ); |
| MP4QosQualifierProperty &operator= ( const MP4QosQualifierProperty &src ); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| /// ISO-639-2/T language code. |
| /// Language codes are 3-alpha (always lowercase) codes which are then |
| /// offset using 0x60 and packed as 5-bit values into 16-bits, most |
| /// significant bit is zero-padding. |
| |
| class MP4LanguageCodeProperty : public MP4Property { |
| private: |
| bmff::LanguageCode _value; |
| |
| public: |
| explicit MP4LanguageCodeProperty( MP4Atom& parentAtom, const char* , bmff::LanguageCode = bmff::ILC_UND ); |
| MP4LanguageCodeProperty( MP4Atom& parentAtom, const char* , const string& ); |
| |
| MP4PropertyType GetType(); |
| uint32_t GetCount(); |
| void SetCount( uint32_t ); |
| void Read( MP4File&, uint32_t = 0 ); |
| void Write( MP4File&, uint32_t = 0 ); |
| void Dump( uint8_t, bool, uint32_t = 0 ); |
| |
| bmff::LanguageCode GetValue(); |
| void SetValue( bmff::LanguageCode ); |
| |
| private: |
| MP4LanguageCodeProperty(); |
| MP4LanguageCodeProperty ( const MP4LanguageCodeProperty &src ); |
| MP4LanguageCodeProperty &operator= ( const MP4LanguageCodeProperty &src ); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| class MP4BasicTypeProperty : public MP4Property { |
| private: |
| itmf::BasicType _value; |
| |
| public: |
| explicit MP4BasicTypeProperty( MP4Atom& parentAtom, const char* , itmf::BasicType = itmf::BT_UNDEFINED ); |
| |
| MP4PropertyType GetType(); |
| uint32_t GetCount(); |
| void SetCount( uint32_t ); |
| void Read( MP4File&, uint32_t = 0 ); |
| void Write( MP4File&, uint32_t = 0 ); |
| void Dump( uint8_t, bool, uint32_t = 0 ); |
| itmf::BasicType GetValue(); |
| void SetValue( itmf::BasicType ); |
| |
| private: |
| MP4BasicTypeProperty(); |
| MP4BasicTypeProperty ( const MP4BasicTypeProperty &src ); |
| MP4BasicTypeProperty &operator= ( const MP4BasicTypeProperty &src ); |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| }} // namespace mp4v2::impl |
| |
| #endif // MP4V2_IMPL_MP4PROPERTY_H |