#ifndef _AP4_META_DATA_H_
#define _AP4_META_DATA_H_
#include "Ap4Atom.h"
#include "Ap4AtomFactory.h"
#include "Ap4String.h"
#include "Ap4Array.h"
#include "Ap4List.h"
class AP4_File;
class AP4_MoovAtom;
class AP4_DataBuffer;
class AP4_ContainerAtom;
class AP4_DataAtom;
class AP4_3GppLocalizedStringAtom;
class AP4_DcfStringAtom;
class AP4_DcfdAtom;
const AP4_Atom::Type AP4_ATOM_TYPE_DATA = AP4_ATOM_TYPE('d','a','t','a'); const AP4_Atom::Type AP4_ATOM_TYPE_MEAN = AP4_ATOM_TYPE('m','e','a','n'); const AP4_Atom::Type AP4_ATOM_TYPE_NAME = AP4_ATOM_TYPE('n','a','m','e'); const AP4_Atom::Type AP4_ATOM_TYPE_dddd = AP4_ATOM_TYPE('-','-','-','-'); const AP4_Atom::Type AP4_ATOM_TYPE_cNAM = AP4_ATOM_TYPE(0xA9,'n','a','m'); const AP4_Atom::Type AP4_ATOM_TYPE_cART = AP4_ATOM_TYPE(0xA9,'A','R','T'); const AP4_Atom::Type AP4_ATOM_TYPE_cCOM = AP4_ATOM_TYPE(0xA9,'c','o','m'); const AP4_Atom::Type AP4_ATOM_TYPE_cWRT = AP4_ATOM_TYPE(0xA9,'w','r','t'); const AP4_Atom::Type AP4_ATOM_TYPE_cALB = AP4_ATOM_TYPE(0xA9,'a','l','b'); const AP4_Atom::Type AP4_ATOM_TYPE_cGEN = AP4_ATOM_TYPE(0xA9,'g','e','n'); const AP4_Atom::Type AP4_ATOM_TYPE_cGRP = AP4_ATOM_TYPE(0xA9,'g','r','p'); const AP4_Atom::Type AP4_ATOM_TYPE_cDAY = AP4_ATOM_TYPE(0xA9,'d','a','y'); const AP4_Atom::Type AP4_ATOM_TYPE_cTOO = AP4_ATOM_TYPE(0xA9,'t','o','o'); const AP4_Atom::Type AP4_ATOM_TYPE_cCMT = AP4_ATOM_TYPE(0xA9,'c','m','t'); const AP4_Atom::Type AP4_ATOM_TYPE_cLYR = AP4_ATOM_TYPE(0xA9,'l','y','r'); const AP4_Atom::Type AP4_ATOM_TYPE_TRKN = AP4_ATOM_TYPE('t','r','k','n'); const AP4_Atom::Type AP4_ATOM_TYPE_DISK = AP4_ATOM_TYPE('d','i','s','k'); const AP4_Atom::Type AP4_ATOM_TYPE_COVR = AP4_ATOM_TYPE('c','o','v','r'); const AP4_Atom::Type AP4_ATOM_TYPE_DESC = AP4_ATOM_TYPE('d','e','s','c'); const AP4_Atom::Type AP4_ATOM_TYPE_CPIL = AP4_ATOM_TYPE('c','p','i','l'); const AP4_Atom::Type AP4_ATOM_TYPE_TMPO = AP4_ATOM_TYPE('t','m','p','o'); const AP4_Atom::Type AP4_ATOM_TYPE_apID = AP4_ATOM_TYPE('a','p','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_cnID = AP4_ATOM_TYPE('c','n','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_cmID = AP4_ATOM_TYPE('c','m','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_atID = AP4_ATOM_TYPE('a','t','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_plID = AP4_ATOM_TYPE('p','l','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_geID = AP4_ATOM_TYPE('g','e','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_sfID = AP4_ATOM_TYPE('s','f','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_akID = AP4_ATOM_TYPE('a','k','I','D');
const AP4_Atom::Type AP4_ATOM_TYPE_aART = AP4_ATOM_TYPE('a','A','R','T');
const AP4_Atom::Type AP4_ATOM_TYPE_TVNN = AP4_ATOM_TYPE('t','v','n','n'); const AP4_Atom::Type AP4_ATOM_TYPE_TVSH = AP4_ATOM_TYPE('t','v','s','h'); const AP4_Atom::Type AP4_ATOM_TYPE_TVEN = AP4_ATOM_TYPE('t','v','e','n'); const AP4_Atom::Type AP4_ATOM_TYPE_TVSN = AP4_ATOM_TYPE('t','v','s','n'); const AP4_Atom::Type AP4_ATOM_TYPE_TVES = AP4_ATOM_TYPE('t','v','e','s'); const AP4_Atom::Type AP4_ATOM_TYPE_STIK = AP4_ATOM_TYPE('s','t','i','k');
const AP4_Atom::Type AP4_ATOM_TYPE_PCST = AP4_ATOM_TYPE('p','c','s','t'); const AP4_Atom::Type AP4_ATOM_TYPE_PURD = AP4_ATOM_TYPE('p','u','r','d'); const AP4_Atom::Type AP4_ATOM_TYPE_PURL = AP4_ATOM_TYPE('p','u','r','l'); const AP4_Atom::Type AP4_ATOM_TYPE_EGID = AP4_ATOM_TYPE('e','g','i','d'); const AP4_Atom::Type AP4_ATOM_TYPE_PGAP = AP4_ATOM_TYPE('p','g','a','p'); const AP4_Atom::Type AP4_ATOM_TYPE_CATG = AP4_ATOM_TYPE('c','a','t','g'); const AP4_Atom::Type AP4_ATOM_TYPE_KEYW = AP4_ATOM_TYPE('k','e','y','w'); const AP4_Atom::Type AP4_ATOM_TYPE_SONM = AP4_ATOM_TYPE('s','o','n','m'); const AP4_Atom::Type AP4_ATOM_TYPE_SOAL = AP4_ATOM_TYPE('s','o','a','l'); const AP4_Atom::Type AP4_ATOM_TYPE_SOAR = AP4_ATOM_TYPE('s','o','a','r'); const AP4_Atom::Type AP4_ATOM_TYPE_SOAA = AP4_ATOM_TYPE('s','o','a','a'); const AP4_Atom::Type AP4_ATOM_TYPE_SOCO = AP4_ATOM_TYPE('s','o','c','o'); const AP4_Atom::Type AP4_ATOM_TYPE_SOSN = AP4_ATOM_TYPE('s','o','s','n');
const AP4_Atom::Type AP4_ATOM_TYPE_TITL = AP4_ATOM_TYPE('t','i','t','l'); const AP4_Atom::Type AP4_ATOM_TYPE_DSCP = AP4_ATOM_TYPE('d','s','c','p'); const AP4_Atom::Type AP4_ATOM_TYPE_CPRT = AP4_ATOM_TYPE('c','p','r','t'); const AP4_Atom::Type AP4_ATOM_TYPE_PERF = AP4_ATOM_TYPE('p','e','r','f'); const AP4_Atom::Type AP4_ATOM_TYPE_AUTH = AP4_ATOM_TYPE('a','u','t','h'); const AP4_Atom::Type AP4_ATOM_TYPE_GNRE = AP4_ATOM_TYPE('g','n','r','e'); const AP4_Atom::Type AP4_ATOM_TYPE_RTNG = AP4_ATOM_TYPE('r','t','n','g'); const AP4_Atom::Type AP4_ATOM_TYPE_CLSF = AP4_ATOM_TYPE('c','l','s','f'); const AP4_Atom::Type AP4_ATOM_TYPE_KYWD = AP4_ATOM_TYPE('k','y','w','d'); const AP4_Atom::Type AP4_ATOM_TYPE_LOCI = AP4_ATOM_TYPE('l','o','c','i'); const AP4_Atom::Type AP4_ATOM_TYPE_ALBM = AP4_ATOM_TYPE('a','l','b','m'); const AP4_Atom::Type AP4_ATOM_TYPE_YRRC = AP4_ATOM_TYPE('y','r','r','c'); const AP4_Atom::Type AP4_ATOM_TYPE_TSEL = AP4_ATOM_TYPE('t','s','e','l');
const AP4_Atom::Type AP4_ATOM_TYPE_ICNU = AP4_ATOM_TYPE('i','c','n','u'); const AP4_Atom::Type AP4_ATOM_TYPE_INFU = AP4_ATOM_TYPE('i','n','f','u'); const AP4_Atom::Type AP4_ATOM_TYPE_CVRU = AP4_ATOM_TYPE('c','v','r','u'); const AP4_Atom::Type AP4_ATOM_TYPE_LRCU = AP4_ATOM_TYPE('l','r','c','u'); const AP4_Atom::Type AP4_ATOM_TYPE_DCFD = AP4_ATOM_TYPE('d','c','f','D');
class AP4_MetaData {
public:
class Key {
public:
Key(const char* name, const char* ns) :
m_Name(name), m_Namespace(ns) {}
const AP4_String& GetNamespace() const { return m_Namespace; }
const AP4_String& GetName() const { return m_Name; }
private:
const AP4_String m_Name;
const AP4_String m_Namespace;
};
class Value {
public:
typedef enum {
TYPE_BINARY,
TYPE_STRING_UTF_8,
TYPE_STRING_UTF_16,
TYPE_STRING_PASCAL,
TYPE_GIF,
TYPE_JPEG,
TYPE_INT_08_BE,
TYPE_INT_16_BE,
TYPE_INT_32_BE,
TYPE_FLOAT_32_BE,
TYPE_FLOAT_64_BE
} Type;
typedef enum {
TYPE_CATEGORY_STRING,
TYPE_CATEGORY_BINARY,
TYPE_CATEGORY_INTEGER,
TYPE_CATEGORY_FLOAT
} TypeCategory;
typedef enum {
MEANING_UNKNOWN,
MEANING_ID3_GENRE,
MEANING_BOOLEAN,
MEANING_FILE_KIND,
MEANING_BINARY_ENCODED_CHARS
} Meaning;
virtual ~Value() {}
Type GetType() const { return m_Type; }
TypeCategory GetTypeCategory() const;
Meaning GetMeaning() const { return m_Meaning; }
const AP4_String& GetLanguage() const { return m_Language; }
void SetLanguage(const char* language) { m_Language = language; }
virtual AP4_String ToString() const = 0;
virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const = 0;
virtual long ToInteger() const = 0;
protected:
static TypeCategory MapTypeToCategory(Type type);
Value(Type type,
Meaning meaning = MEANING_UNKNOWN,
const char* language = NULL) :
m_Type(type), m_Meaning(meaning), m_Language(language) {}
Type m_Type;
Meaning m_Meaning;
AP4_String m_Language;
};
struct KeyInfo {
const char* name;
const char* description;
AP4_UI32 four_cc;
Value::Type value_type;
};
class Entry {
public:
Entry(const char* name, const char* ns, Value* value) :
m_Key(name, ns), m_Value(value) {}
~Entry() { delete m_Value; }
AP4_Result AddToFile(AP4_File& file, AP4_Ordinal index = 0);
AP4_Result AddToFileIlst(AP4_File& file, AP4_Ordinal index = 0);
AP4_Result AddToFileDcf(AP4_File& file, AP4_Ordinal index = 0);
AP4_Result AddToFileUdta(AP4_File& file, AP4_Ordinal index = 0);
AP4_Result RemoveFromFile(AP4_File& file, AP4_Ordinal index);
AP4_Result RemoveFromFileIlst(AP4_File& file, AP4_Ordinal index);
AP4_Result RemoveFromFileDcf(AP4_File& file, AP4_Ordinal index);
AP4_Result RemoveFromFileUdta(AP4_File& file, AP4_Ordinal index);
AP4_ContainerAtom* FindInIlst(AP4_ContainerAtom* ilst) const;
AP4_Result ToAtom(AP4_Atom*& atom) const;
Key m_Key;
Value* m_Value;
};
static AP4_Array<KeyInfo> KeyInfos;
AP4_MetaData(AP4_File* file);
AP4_Result ParseMoov(AP4_MoovAtom* moov);
AP4_Result ParseUdta(AP4_ContainerAtom* udta, const char* namespc);
~AP4_MetaData();
const AP4_List<Entry>& GetEntries() const { return m_Entries; }
AP4_Result ResolveKeyName(AP4_Atom::Type atom_type, AP4_String& value);
AP4_Result AddIlstEntries(AP4_ContainerAtom* atom, const char* namespc);
AP4_Result Add3GppEntry(AP4_3GppLocalizedStringAtom* atom, const char* namespc);
AP4_Result AddDcfStringEntry(AP4_DcfStringAtom* atom, const char* namespc);
AP4_Result AddDcfdEntry(AP4_DcfdAtom* atom, const char* namespc);
private:
friend class AP4;
static AP4_Result Initialize(); static AP4_Result Initialized();
static AP4_Result UnInitialize();
AP4_List<Entry> m_Entries;
};
class AP4_MetaDataAtomTypeHandler : public AP4_AtomFactory::TypeHandler
{
public:
AP4_MetaDataAtomTypeHandler(AP4_AtomFactory* atom_factory) :
m_AtomFactory(atom_factory) {}
virtual AP4_Result CreateAtom(AP4_Atom::Type type,
AP4_UI32 size,
AP4_ByteStream& stream,
AP4_Atom::Type context,
AP4_Atom*& atom);
struct TypeList {
const AP4_Atom::Type* m_Types;
AP4_Size m_Size;
};
static const AP4_Atom::Type IlstTypes[];
static const TypeList IlstTypeList;
static const AP4_Atom::Type _3gppLocalizedStringTypes[];
static const TypeList _3gppLocalizedStringTypeList;
static const AP4_Atom::Type _3gppOtherTypes[];
static const TypeList _3gppOtherTypeList;
static const AP4_Atom::Type DcfStringTypes[];
static const TypeList DcfStringTypeList;
static bool IsTypeInList(AP4_Atom::Type type, const TypeList& list);
private:
AP4_AtomFactory* m_AtomFactory;
};
class AP4_MetaDataTag
{
public:
virtual ~AP4_MetaDataTag() {}
virtual AP4_Result Write(AP4_ByteStream& stream);
virtual AP4_Result Inspect(AP4_AtomInspector& inspector);
protected:
AP4_MetaDataTag(AP4_UI32 data_type,
AP4_UI32 data_lang,
AP4_Size size,
AP4_ByteStream& stream);
};
class AP4_3GppLocalizedStringAtom : public AP4_Atom
{
public:
AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_3GppLocalizedStringAtom, AP4_Atom)
static AP4_3GppLocalizedStringAtom* Create(Type type, AP4_UI32 size, AP4_ByteStream& stream);
AP4_3GppLocalizedStringAtom(Type type, const char* language, const char* value);
AP4_3GppLocalizedStringAtom(Type type,
AP4_UI32 size,
AP4_UI08 version,
AP4_UI32 flags,
AP4_ByteStream& stream);
virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
virtual AP4_Result WriteFields(AP4_ByteStream& stream);
const char* GetLanguage() const { return m_Language; }
const AP4_String& GetValue() const { return m_Value; }
private:
char m_Language[4];
AP4_String m_Value;
};
class AP4_DcfStringAtom : public AP4_Atom
{
public:
AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DcfStringAtom, AP4_Atom)
static AP4_DcfStringAtom* Create(Type type, AP4_UI32 size, AP4_ByteStream& stream);
AP4_DcfStringAtom(Type type, const char* value);
AP4_DcfStringAtom(Type type,
AP4_UI32 size,
AP4_UI08 version,
AP4_UI32 flags,
AP4_ByteStream& stream);
virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
virtual AP4_Result WriteFields(AP4_ByteStream& stream);
const AP4_String& GetValue() const { return m_Value; }
private:
AP4_String m_Value;
};
class AP4_DcfdAtom : public AP4_Atom
{
public:
AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DcfdAtom, AP4_Atom)
static AP4_DcfdAtom* Create(AP4_UI32 size, AP4_ByteStream& stream);
AP4_DcfdAtom(AP4_UI08 version,
AP4_UI32 flags,
AP4_ByteStream& stream);
AP4_DcfdAtom(AP4_UI32 duration);
virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
virtual AP4_Result WriteFields(AP4_ByteStream& stream);
AP4_UI32 GetDuration() const { return m_Duration; }
private:
AP4_UI32 m_Duration;
};
class AP4_MetaDataStringAtom : public AP4_Atom
{
public:
AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_MetaDataStringAtom, AP4_Atom)
AP4_MetaDataStringAtom(Type type, const char* value);
AP4_MetaDataStringAtom(Type type, AP4_UI32 size, AP4_ByteStream& stream);
virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
virtual AP4_Result WriteFields(AP4_ByteStream& stream);
const AP4_String& GetValue() { return m_Value; }
private:
AP4_UI32 m_Reserved;
AP4_String m_Value;
};
class AP4_DataAtom : public AP4_Atom
{
public:
AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_DataAtom, AP4_Atom)
typedef enum {
DATA_TYPE_BINARY = 0,
DATA_TYPE_STRING_UTF_8 = 1,
DATA_TYPE_STRING_UTF_16 = 2,
DATA_TYPE_STRING_PASCAL = 3,
DATA_TYPE_GIF = 13,
DATA_TYPE_JPEG = 14,
DATA_TYPE_SIGNED_INT_BE = 21,
DATA_TYPE_FLOAT_32_BE = 22,
DATA_TYPE_FLOAT_64_BE = 23
} DataType;
typedef enum {
LANGUAGE_ENGLISH = 0
} DataLang;
AP4_DataAtom(const AP4_MetaData::Value& value);
AP4_DataAtom(AP4_UI32 size, AP4_ByteStream& stream);
~AP4_DataAtom();
virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
virtual AP4_Result WriteFields(AP4_ByteStream& stream);
DataType GetDataType() { return m_DataType; }
DataLang GetDataLang() { return m_DataLang; }
AP4_MetaData::Value::Type GetValueType();
AP4_Result LoadString(AP4_String*& string);
AP4_Result LoadBytes(AP4_DataBuffer& bytes);
AP4_Result LoadInteger(long& value);
private:
DataType m_DataType;
DataLang m_DataLang;
AP4_ByteStream* m_Source;
};
class AP4_StringMetaDataValue : public AP4_MetaData::Value {
public:
AP4_StringMetaDataValue(const char* value, const char* language=NULL) :
Value(TYPE_STRING_UTF_8, MEANING_UNKNOWN, language),
m_Value(value) {}
virtual AP4_String ToString() const;
virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const;
virtual long ToInteger() const;
private:
AP4_String m_Value;
};
class AP4_IntegerMetaDataValue : public AP4_MetaData::Value {
public:
AP4_IntegerMetaDataValue(Type type, long value) :
Value(type), m_Value(value) {}
virtual AP4_String ToString() const;
virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const;
virtual long ToInteger() const;
private:
long m_Value;
};
class AP4_BinaryMetaDataValue : public AP4_MetaData::Value {
public:
AP4_BinaryMetaDataValue(Type type, const AP4_UI08* data, AP4_Size size) :
Value(type), m_Value(data, size) {}
virtual AP4_String ToString() const;
virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const;
virtual long ToInteger() const;
private:
AP4_DataBuffer m_Value;
};
class AP4_AtomMetaDataValue : public AP4_MetaData::Value
{
public:
AP4_AtomMetaDataValue(AP4_DataAtom* data_atom, AP4_UI32 parent_type);
virtual AP4_String ToString() const;
virtual AP4_Result ToBytes(AP4_DataBuffer& bytes) const;
virtual long ToInteger() const;
private:
AP4_DataAtom* m_DataAtom;
};
#endif