From 7593551e490f8ecf60f65f20b84654cf1dfef3cf Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 13 Nov 2023 20:11:35 +0100 Subject: [PATCH] Import libAAF into Ardour's source-tree tools/update_libaaf.sh - libaaf v0.1-85-g3e4c2cd --- libs/aaf/AAFClass.c | 1114 ++++++ libs/aaf/AAFCore.c | 1904 +++++++++ libs/aaf/AAFDump.c | 264 ++ libs/aaf/AAFIAudioFiles.c | 553 +++ libs/aaf/AAFIParser.c | 4169 ++++++++++++++++++++ libs/aaf/AAFIface.c | 848 ++++ libs/aaf/AAFToText.c | 2438 ++++++++++++ libs/aaf/CFBDump.c | 346 ++ libs/aaf/LibCFB.c | 1346 +++++++ libs/aaf/ProTools.c | 303 ++ libs/aaf/RIFFParser.c | 322 ++ libs/aaf/Resolve.c | 222 ++ libs/aaf/URIParser.c | 1314 ++++++ libs/aaf/aaf/AAFClass.h | 65 + libs/aaf/aaf/AAFCore.h | 810 ++++ libs/aaf/aaf/AAFDefs/AAFClassDefUIDs.h | 461 +++ libs/aaf/aaf/AAFDefs/AAFCodecDefs.h | 223 ++ libs/aaf/aaf/AAFDefs/AAFCompressionDefs.h | 120 + libs/aaf/aaf/AAFDefs/AAFContainerDefs.h | 484 +++ libs/aaf/aaf/AAFDefs/AAFDataDefs.h | 81 + libs/aaf/aaf/AAFDefs/AAFExtEnum.h | 106 + libs/aaf/aaf/AAFDefs/AAFFileKinds.h | 146 + libs/aaf/aaf/AAFDefs/AAFInterpolatorDefs.h | 49 + libs/aaf/aaf/AAFDefs/AAFOPDefs.h | 23 + libs/aaf/aaf/AAFDefs/AAFOperationDefs.h | 171 + libs/aaf/aaf/AAFDefs/AAFParameterDefs.h | 356 ++ libs/aaf/aaf/AAFDefs/AAFPluginDefs.h | 37 + libs/aaf/aaf/AAFDefs/AAFPropertyDefs.h | 1306 ++++++ libs/aaf/aaf/AAFDefs/AAFPropertyIDs.h | 364 ++ libs/aaf/aaf/AAFDefs/AAFTypeDefUIDs.h | 627 +++ libs/aaf/aaf/AAFDump.h | 52 + libs/aaf/aaf/AAFIAudioFiles.h | 37 + libs/aaf/aaf/AAFIParser.h | 104 + libs/aaf/aaf/AAFIface.h | 861 ++++ libs/aaf/aaf/AAFToText.h | 145 + libs/aaf/aaf/AAFTypes.h | 692 ++++ libs/aaf/aaf/CFBDump.h | 56 + libs/aaf/aaf/LibCFB.h | 817 ++++ libs/aaf/aaf/ProTools.h | 40 + libs/aaf/aaf/RIFFParser.h | 131 + libs/aaf/aaf/Resolve.h | 42 + libs/aaf/aaf/URIParser.h | 142 + libs/aaf/aaf/debug.h | 92 + libs/aaf/aaf/libaaf.h | 45 + libs/aaf/aaf/utils.h | 93 + libs/aaf/aaf/version.h | 2 + libs/aaf/debug.c | 98 + libs/aaf/utils.c | 357 ++ 48 files changed, 24378 insertions(+) create mode 100644 libs/aaf/AAFClass.c create mode 100644 libs/aaf/AAFCore.c create mode 100644 libs/aaf/AAFDump.c create mode 100644 libs/aaf/AAFIAudioFiles.c create mode 100644 libs/aaf/AAFIParser.c create mode 100644 libs/aaf/AAFIface.c create mode 100644 libs/aaf/AAFToText.c create mode 100644 libs/aaf/CFBDump.c create mode 100644 libs/aaf/LibCFB.c create mode 100644 libs/aaf/ProTools.c create mode 100644 libs/aaf/RIFFParser.c create mode 100644 libs/aaf/Resolve.c create mode 100644 libs/aaf/URIParser.c create mode 100644 libs/aaf/aaf/AAFClass.h create mode 100644 libs/aaf/aaf/AAFCore.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFClassDefUIDs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFCodecDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFCompressionDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFContainerDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFDataDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFExtEnum.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFFileKinds.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFInterpolatorDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFOPDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFOperationDefs.h create mode 100644 libs/aaf/aaf/AAFDefs/AAFParameterDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFPluginDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFPropertyDefs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFPropertyIDs.h create mode 100755 libs/aaf/aaf/AAFDefs/AAFTypeDefUIDs.h create mode 100644 libs/aaf/aaf/AAFDump.h create mode 100644 libs/aaf/aaf/AAFIAudioFiles.h create mode 100644 libs/aaf/aaf/AAFIParser.h create mode 100644 libs/aaf/aaf/AAFIface.h create mode 100644 libs/aaf/aaf/AAFToText.h create mode 100644 libs/aaf/aaf/AAFTypes.h create mode 100644 libs/aaf/aaf/CFBDump.h create mode 100644 libs/aaf/aaf/LibCFB.h create mode 100644 libs/aaf/aaf/ProTools.h create mode 100644 libs/aaf/aaf/RIFFParser.h create mode 100644 libs/aaf/aaf/Resolve.h create mode 100644 libs/aaf/aaf/URIParser.h create mode 100644 libs/aaf/aaf/debug.h create mode 100644 libs/aaf/aaf/libaaf.h create mode 100644 libs/aaf/aaf/utils.h create mode 100644 libs/aaf/aaf/version.h create mode 100644 libs/aaf/debug.c create mode 100644 libs/aaf/utils.c diff --git a/libs/aaf/AAFClass.c b/libs/aaf/AAFClass.c new file mode 100644 index 0000000000..351627051b --- /dev/null +++ b/libs/aaf/AAFClass.c @@ -0,0 +1,1114 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * @brief AAF core functions. + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + */ + +#include +#include +#include +#include + +#include "aaf/AAFCore.h" +#include "aaf/AAFToText.h" +#include "aaf/AAFTypes.h" + +#include "aaf/AAFDefs/AAFClassDefUIDs.h" +#include "aaf/AAFDefs/AAFPropertyIDs.h" +#include "aaf/AAFDefs/AAFTypeDefUIDs.h" + +#include "aaf/debug.h" + +#include "aaf/AAFClass.h" + +#define debug(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_ERROR, __VA_ARGS__) + +#define attachNewProperty(aafd, Class, Prop, Pid, IsReq) \ + Prop = calloc (sizeof (aafPropertyDef), sizeof (unsigned char)); \ + if (Prop == NULL) { \ + error ("%s.", strerror (errno)); \ + return -1; \ + } \ + Prop->pid = Pid; \ + Prop->name = NULL; \ + Prop->isReq = IsReq; \ + Prop->meta = 0; \ + Prop->next = Class->Properties; \ + memset (&Prop->type, 0x00, sizeof (aafUID_t)); \ + Class->Properties = Prop; + +int +aafclass_classExists (AAF_Data* aafd, aafUID_t* ClassID) +{ + aafClass* Class = NULL; + + foreachClass (Class, aafd->Classes) if (aafUIDCmp (Class->ID, ClassID)) break; + + if (Class == NULL) + return 0; + + return 1; +} + +/** + * Allocates and initializes a new aafClass structure, adds it + * to the aafd->class list and returns a pointer to the newly + * allocated Class. + * + * @param aafd pointer to the AAF_Data structure. + * @param id pointer to the ClassID. + * @param isConcrete boolean to set the Class as either an ABSTRACT or a CONCRETE Class. + * @param parent pointer to the parent Class. + * @return pointer to the newly allocated aafClass. + */ + +aafClass* +aafclass_defineNewClass (AAF_Data* aafd, const aafUID_t* id, uint8_t isConcrete, aafClass* parent) +{ + aafClass* Class = malloc (sizeof (aafClass)); + + if (Class == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + Class->ID = id; + Class->Parent = parent; + Class->Properties = NULL; + Class->isConcrete = isConcrete; + + Class->meta = 0; + Class->name = NULL; + + Class->next = aafd->Classes; + aafd->Classes = Class; + + return Class; +} + +/** + * Retrieve an aafClass for a given ClassID. + * + * @param aafd pointer to the AAF_Data structure. + * @param id pointer to the ClassID to search for. + * @return pointer to the retrieved aafClass structure, or NULL if not found. + */ + +aafClass* +aafclass_getClassByID (AAF_Data* aafd, const aafUID_t* id) +{ + aafClass* Class = NULL; + + for (Class = aafd->Classes; Class != NULL; Class = Class->next) + if (aafUIDCmp (Class->ID, id)) + break; + + return Class; +} + +aafPropertyDef* +aafclass_getPropertyDefinitionByID (aafClass* Classes, aafPID_t pid) +{ + aafClass* Class = NULL; + aafPropertyDef* PDef = NULL; + + foreachClassInheritance (Class, Classes) + foreachPropertyDefinition (PDef, Class->Properties) if (PDef->pid == pid) return PDef; + + return NULL; +} + +/** + * Defines each Class with its properties according to + * the standard. All the Classes are then hold by the + * AAF_Data.Class list. + * + * We define the Classes at runtime, so we can later + * add any custom class defined in the MetaDictionary. + * This is not yet implemented though. + * + * @param aafd The AAF_Data struct pointer. + */ +int +aafclass_setDefaultClasses (AAF_Data* aafd) +{ + aafPropertyDef* prop = NULL; + + /* TODO test ENOMEM after each class alloc */ + + aafClass* IOC = aafclass_defineNewClass (aafd, &AAFClassID_InterchangeObject, ABSTRACT, NULL); + + if (IOC == NULL) { + return -1; + } + + attachNewProperty (aafd, IOC, prop, PID_InterchangeObject_ObjClass, PROP_REQ); + attachNewProperty (aafd, IOC, prop, PID_InterchangeObject_Generation, PROP_OPT); + + aafClass* Root = aafclass_defineNewClass (aafd, &AAFClassID_Root, CONCRETE, IOC); + + if (Root == NULL) { + return -1; + } + + attachNewProperty (aafd, Root, prop, PID_Root_MetaDictionary, PROP_REQ); + attachNewProperty (aafd, Root, prop, PID_Root_Header, PROP_REQ); + + aafClass* Header = aafclass_defineNewClass (aafd, &AAFClassID_Header, CONCRETE, IOC); + + if (Header == NULL) { + return -1; + } + + attachNewProperty (aafd, Header, prop, PID_Header_ByteOrder, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_LastModified, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_Version, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_Content, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_Dictionary, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_IdentificationList, PROP_REQ); + attachNewProperty (aafd, Header, prop, PID_Header_ObjectModelVersion, PROP_OPT); + attachNewProperty (aafd, Header, prop, PID_Header_OperationalPattern, PROP_OPT); + attachNewProperty (aafd, Header, prop, PID_Header_EssenceContainers, PROP_OPT); + attachNewProperty (aafd, Header, prop, PID_Header_DescriptiveSchemes, PROP_OPT); + + aafClass* Identif = aafclass_defineNewClass (aafd, &AAFClassID_Identification, CONCRETE, IOC); + + if (Identif == NULL) { + return -1; + } + + attachNewProperty (aafd, Identif, prop, PID_Identification_CompanyName, PROP_REQ); + attachNewProperty (aafd, Identif, prop, PID_Identification_ProductName, PROP_REQ); + attachNewProperty (aafd, Identif, prop, PID_Identification_ProductVersion, PROP_OPT); + attachNewProperty (aafd, Identif, prop, PID_Identification_ProductVersionString, PROP_REQ); + attachNewProperty (aafd, Identif, prop, PID_Identification_ProductID, PROP_REQ); + attachNewProperty (aafd, Identif, prop, PID_Identification_Date, PROP_REQ); + attachNewProperty (aafd, Identif, prop, PID_Identification_ToolkitVersion, PROP_OPT); + attachNewProperty (aafd, Identif, prop, PID_Identification_Platform, PROP_OPT); + attachNewProperty (aafd, Identif, prop, PID_Identification_GenerationAUID, PROP_REQ); + + aafClass* Dictionary = aafclass_defineNewClass (aafd, &AAFClassID_Dictionary, CONCRETE, IOC); + + if (Dictionary == NULL) { + return -1; + } + + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_OperationDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_ParameterDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_DataDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_PluginDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_CodecDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_ContainerDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_InterpolationDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_KLVDataDefinitions, PROP_OPT); + attachNewProperty (aafd, Dictionary, prop, PID_Dictionary_TaggedValueDefinitions, PROP_OPT); + + aafClass* Content = aafclass_defineNewClass (aafd, &AAFClassID_ContentStorage, CONCRETE, IOC); + + if (Content == NULL) { + return -1; + } + + attachNewProperty (aafd, Content, prop, PID_ContentStorage_Mobs, PROP_REQ); + attachNewProperty (aafd, Content, prop, PID_ContentStorage_EssenceData, PROP_REQ); + + aafClass* Mob = aafclass_defineNewClass (aafd, &AAFClassID_Mob, ABSTRACT, IOC); + + if (Mob == NULL) { + return -1; + } + + attachNewProperty (aafd, Mob, prop, PID_Mob_MobID, PROP_REQ); + attachNewProperty (aafd, Mob, prop, PID_Mob_Name, PROP_OPT); + attachNewProperty (aafd, Mob, prop, PID_Mob_Slots, PROP_REQ); + attachNewProperty (aafd, Mob, prop, PID_Mob_LastModified, PROP_REQ); + attachNewProperty (aafd, Mob, prop, PID_Mob_CreationTime, PROP_REQ); + attachNewProperty (aafd, Mob, prop, PID_Mob_UserComments, PROP_OPT); + attachNewProperty (aafd, Mob, prop, PID_Mob_Attributes, PROP_OPT); + attachNewProperty (aafd, Mob, prop, PID_Mob_KLVData, PROP_OPT); + attachNewProperty (aafd, Mob, prop, PID_Mob_UsageCode, PROP_OPT); + + aafClass* CompoMob = aafclass_defineNewClass (aafd, &AAFClassID_CompositionMob, CONCRETE, Mob); + + if (CompoMob == NULL) { + return -1; + } + + attachNewProperty (aafd, CompoMob, prop, PID_CompositionMob_DefaultFadeLength, PROP_OPT); + attachNewProperty (aafd, CompoMob, prop, PID_CompositionMob_DefFadeType, PROP_OPT); + attachNewProperty (aafd, CompoMob, prop, PID_CompositionMob_DefFadeEditUnit, PROP_OPT); + attachNewProperty (aafd, CompoMob, prop, PID_CompositionMob_Rendering, PROP_OPT); + + aafClass* MasterMob = aafclass_defineNewClass (aafd, &AAFClassID_MasterMob, CONCRETE, Mob); + + if (MasterMob == NULL) { + return -1; + } + + /* The MasterMob class does not define any additional properties. */ + + aafClass* SourceMob = aafclass_defineNewClass (aafd, &AAFClassID_SourceMob, CONCRETE, Mob); + + if (SourceMob == NULL) { + return -1; + } + + attachNewProperty (aafd, SourceMob, prop, PID_SourceMob_EssenceDescription, PROP_REQ); + + aafClass* MobSlot = aafclass_defineNewClass (aafd, &AAFClassID_MobSlot, ABSTRACT, IOC); + + if (MobSlot == NULL) { + return -1; + } + + attachNewProperty (aafd, MobSlot, prop, PID_MobSlot_SlotID, PROP_REQ); + attachNewProperty (aafd, MobSlot, prop, PID_MobSlot_SlotName, PROP_OPT); + attachNewProperty (aafd, MobSlot, prop, PID_MobSlot_PhysicalTrackNumber, PROP_OPT); + attachNewProperty (aafd, MobSlot, prop, PID_MobSlot_Segment, PROP_REQ); + + aafClass* TimelineMobSlot = aafclass_defineNewClass (aafd, &AAFClassID_TimelineMobSlot, CONCRETE, MobSlot); + + if (TimelineMobSlot == NULL) { + return -1; + } + + attachNewProperty (aafd, TimelineMobSlot, prop, PID_TimelineMobSlot_EditRate, PROP_REQ); + attachNewProperty (aafd, TimelineMobSlot, prop, PID_TimelineMobSlot_Origin, PROP_REQ); + attachNewProperty (aafd, TimelineMobSlot, prop, PID_TimelineMobSlot_MarkIn, PROP_OPT); + attachNewProperty (aafd, TimelineMobSlot, prop, PID_TimelineMobSlot_MarkOut, PROP_OPT); + attachNewProperty (aafd, TimelineMobSlot, prop, PID_TimelineMobSlot_UserPos, PROP_OPT); + + aafClass* EventMobSlot = aafclass_defineNewClass (aafd, &AAFClassID_EventMobSlot, CONCRETE, MobSlot); + + if (EventMobSlot == NULL) { + return -1; + } + + attachNewProperty (aafd, EventMobSlot, prop, PID_EventMobSlot_EditRate, PROP_REQ); + // attachNewProperty( aafd, EventMobSlot, prop, PID_EventMobSlot_EventSlotOrigin, ??? ); + + aafClass* StaticMobSlot = aafclass_defineNewClass (aafd, &AAFClassID_StaticMobSlot, CONCRETE, MobSlot); + + if (StaticMobSlot == NULL) { + return -1; + } + + /* The StaticMobSlot class does not define any additional properties. */ + + aafClass* KLVData = aafclass_defineNewClass (aafd, &AAFClassID_KLVData, CONCRETE, IOC); + + if (KLVData == NULL) { + return -1; + } + + attachNewProperty (aafd, KLVData, prop, PID_KLVData_Value, PROP_REQ); + + aafClass* TaggedValue = aafclass_defineNewClass (aafd, &AAFClassID_TaggedValue, CONCRETE, IOC); + + if (TaggedValue == NULL) { + return -1; + } + + attachNewProperty (aafd, TaggedValue, prop, PID_TaggedValue_Name, PROP_REQ); + attachNewProperty (aafd, TaggedValue, prop, PID_TaggedValue_Value, PROP_REQ); + + aafClass* Parameter = aafclass_defineNewClass (aafd, &AAFClassID_Parameter, ABSTRACT, IOC); + + if (Parameter == NULL) { + return -1; + } + + attachNewProperty (aafd, Parameter, prop, PID_Parameter_Definition, PROP_REQ); + + aafClass* ConstantValue = aafclass_defineNewClass (aafd, &AAFClassID_ConstantValue, CONCRETE, Parameter); + + if (ConstantValue == NULL) { + return -1; + } + + attachNewProperty (aafd, ConstantValue, prop, PID_ConstantValue_Value, PROP_REQ); + + aafClass* VaryingValue = aafclass_defineNewClass (aafd, &AAFClassID_VaryingValue, CONCRETE, Parameter); + + if (VaryingValue == NULL) { + return -1; + } + + attachNewProperty (aafd, VaryingValue, prop, PID_VaryingValue_Interpolation, PROP_REQ); + attachNewProperty (aafd, VaryingValue, prop, PID_VaryingValue_PointList, PROP_REQ); + + aafClass* ControlPoint = aafclass_defineNewClass (aafd, &AAFClassID_ControlPoint, CONCRETE, IOC); + + if (ControlPoint == NULL) { + return -1; + } + + attachNewProperty (aafd, ControlPoint, prop, PID_ControlPoint_Value, PROP_REQ); + attachNewProperty (aafd, ControlPoint, prop, PID_ControlPoint_Time, PROP_REQ); + attachNewProperty (aafd, ControlPoint, prop, PID_ControlPoint_EditHint, PROP_OPT); + + aafClass* Locator = aafclass_defineNewClass (aafd, &AAFClassID_Locator, ABSTRACT, IOC); + + if (Locator == NULL) { + return -1; + } + + /* The Locator class does not define any additional properties. */ + + aafClass* NetworkLocator = aafclass_defineNewClass (aafd, &AAFClassID_NetworkLocator, CONCRETE, Locator); + + if (NetworkLocator == NULL) { + return -1; + } + + attachNewProperty (aafd, NetworkLocator, prop, PID_NetworkLocator_URLString, PROP_REQ); + + aafClass* TextLocator = aafclass_defineNewClass (aafd, &AAFClassID_TextLocator, CONCRETE, Locator); + + if (TextLocator == NULL) { + return -1; + } + + attachNewProperty (aafd, TextLocator, prop, PID_TextLocator_Name, PROP_REQ); + + aafClass* Component = aafclass_defineNewClass (aafd, &AAFClassID_Component, ABSTRACT, IOC); + + if (Component == NULL) { + return -1; + } + + attachNewProperty (aafd, Component, prop, PID_Component_DataDefinition, PROP_REQ); + attachNewProperty (aafd, Component, prop, PID_Component_Length, PROP_OPT); + attachNewProperty (aafd, Component, prop, PID_Component_KLVData, PROP_OPT); + attachNewProperty (aafd, Component, prop, PID_Component_UserComments, PROP_OPT); + attachNewProperty (aafd, Component, prop, PID_Component_Attributes, PROP_OPT); + + aafClass* Transition = aafclass_defineNewClass (aafd, &AAFClassID_Transition, CONCRETE, Component); + + if (Transition == NULL) { + return -1; + } + + attachNewProperty (aafd, Transition, prop, PID_Transition_OperationGroup, PROP_REQ); + attachNewProperty (aafd, Transition, prop, PID_Transition_CutPoint, PROP_REQ); + + aafClass* Segment = aafclass_defineNewClass (aafd, &AAFClassID_Segment, ABSTRACT, Component); + + if (Segment == NULL) { + return -1; + } + + /* The Segment class does not define any additional properties. */ + + aafClass* Sequence = aafclass_defineNewClass (aafd, &AAFClassID_Sequence, CONCRETE, Segment); + + if (Sequence == NULL) { + return -1; + } + + attachNewProperty (aafd, Sequence, prop, PID_Sequence_Components, PROP_REQ); + + aafClass* Filler = aafclass_defineNewClass (aafd, &AAFClassID_Filler, CONCRETE, Segment); + + if (Filler == NULL) { + return -1; + } + + /* The Filler class does not define any additional properties. */ + + aafClass* SourceRef = aafclass_defineNewClass (aafd, &AAFClassID_SourceReference, ABSTRACT, Segment); + + if (SourceRef == NULL) { + return -1; + } + + attachNewProperty (aafd, SourceRef, prop, PID_SourceReference_SourceID, PROP_OPT); + attachNewProperty (aafd, SourceRef, prop, PID_SourceReference_SourceMobSlotID, PROP_REQ); + attachNewProperty (aafd, SourceRef, prop, PID_SourceReference_ChannelIDs, PROP_OPT); + attachNewProperty (aafd, SourceRef, prop, PID_SourceReference_MonoSourceSlotIDs, PROP_OPT); + + aafClass* SourceClip = aafclass_defineNewClass (aafd, &AAFClassID_SourceClip, CONCRETE, SourceRef); + + if (SourceClip == NULL) { + return -1; + } + + attachNewProperty (aafd, SourceClip, prop, PID_SourceClip_StartTime, PROP_OPT); + attachNewProperty (aafd, SourceClip, prop, PID_SourceClip_FadeInLength, PROP_OPT); + attachNewProperty (aafd, SourceClip, prop, PID_SourceClip_FadeInType, PROP_OPT); + attachNewProperty (aafd, SourceClip, prop, PID_SourceClip_FadeOutLength, PROP_OPT); + attachNewProperty (aafd, SourceClip, prop, PID_SourceClip_FadeOutType, PROP_OPT); + + aafClass* Event = aafclass_defineNewClass (aafd, &AAFClassID_Event, ABSTRACT, Segment); + + if (Event == NULL) { + return -1; + } + + attachNewProperty (aafd, Event, prop, PID_Event_Position, PROP_REQ); + attachNewProperty (aafd, Event, prop, PID_Event_Comment, PROP_OPT); + + aafClass* CommentMarker = aafclass_defineNewClass (aafd, &AAFClassID_CommentMarker, CONCRETE, Event); + + if (CommentMarker == NULL) { + return -1; + } + + attachNewProperty (aafd, CommentMarker, prop, PID_CommentMarker_Annotation, PROP_OPT); + + aafClass* DescriptiveMarker = aafclass_defineNewClass (aafd, &AAFClassID_DescriptiveMarker, CONCRETE, CommentMarker); + + if (DescriptiveMarker == NULL) { + return -1; + } + + attachNewProperty (aafd, DescriptiveMarker, prop, PID_DescriptiveMarker_DescribedSlots, PROP_OPT); + attachNewProperty (aafd, DescriptiveMarker, prop, PID_DescriptiveMarker_Description, PROP_OPT); + + aafClass* GPITrigger = aafclass_defineNewClass (aafd, &AAFClassID_GPITrigger, CONCRETE, Event); + + if (GPITrigger == NULL) { + return -1; + } + + attachNewProperty (aafd, GPITrigger, prop, PID_GPITrigger_ActiveState, PROP_REQ); + + aafClass* Timecode = aafclass_defineNewClass (aafd, &AAFClassID_Timecode, CONCRETE, Segment); + + if (Timecode == NULL) { + return -1; + } + + attachNewProperty (aafd, Timecode, prop, PID_Timecode_Start, PROP_REQ); + attachNewProperty (aafd, Timecode, prop, PID_Timecode_FPS, PROP_REQ); + attachNewProperty (aafd, Timecode, prop, PID_Timecode_Drop, PROP_REQ); + + aafClass* TCStream = aafclass_defineNewClass (aafd, &AAFClassID_TimecodeStream, ABSTRACT, Segment); + + if (TCStream == NULL) { + return -1; + } + + attachNewProperty (aafd, TCStream, prop, PID_TimecodeStream_SampleRate, PROP_REQ); + attachNewProperty (aafd, TCStream, prop, PID_TimecodeStream_Source, PROP_REQ); + attachNewProperty (aafd, TCStream, prop, PID_TimecodeStream_SourceType, PROP_REQ); + + aafClass* TCStream12M = aafclass_defineNewClass (aafd, &AAFClassID_TimecodeStream12M, CONCRETE, TCStream); + + if (TCStream12M == NULL) { + return -1; + } + + attachNewProperty (aafd, TCStream12M, prop, PID_TimecodeStream12M_IncludeSync, PROP_OPT); + + aafClass* Edgecode = aafclass_defineNewClass (aafd, &AAFClassID_Edgecode, CONCRETE, Segment); + + if (Edgecode == NULL) { + return -1; + } + + attachNewProperty (aafd, Edgecode, prop, PID_EdgeCode_Start, PROP_REQ); + attachNewProperty (aafd, Edgecode, prop, PID_EdgeCode_FilmKind, PROP_REQ); + attachNewProperty (aafd, Edgecode, prop, PID_EdgeCode_CodeFormat, PROP_REQ); + attachNewProperty (aafd, Edgecode, prop, PID_EdgeCode_Header, PROP_OPT); + + aafClass* Pulldown = aafclass_defineNewClass (aafd, &AAFClassID_Pulldown, CONCRETE, Segment); + + if (Pulldown == NULL) { + return -1; + } + + attachNewProperty (aafd, Pulldown, prop, PID_Pulldown_InputSegment, PROP_REQ); + attachNewProperty (aafd, Pulldown, prop, PID_Pulldown_PulldownKind, PROP_REQ); + attachNewProperty (aafd, Pulldown, prop, PID_Pulldown_PulldownDirection, PROP_REQ); + attachNewProperty (aafd, Pulldown, prop, PID_Pulldown_PhaseFrame, PROP_REQ); + + aafClass* OperationGroup = aafclass_defineNewClass (aafd, &AAFClassID_OperationGroup, CONCRETE, Segment); + + if (OperationGroup == NULL) { + return -1; + } + + attachNewProperty (aafd, OperationGroup, prop, PID_OperationGroup_Operation, PROP_REQ); + attachNewProperty (aafd, OperationGroup, prop, PID_OperationGroup_InputSegments, PROP_OPT); + attachNewProperty (aafd, OperationGroup, prop, PID_OperationGroup_Parameters, PROP_OPT); + attachNewProperty (aafd, OperationGroup, prop, PID_OperationGroup_Rendering, PROP_OPT); + attachNewProperty (aafd, OperationGroup, prop, PID_OperationGroup_BypassOverride, PROP_OPT); + + aafClass* NestedScope = aafclass_defineNewClass (aafd, &AAFClassID_NestedScope, CONCRETE, Segment); + + if (NestedScope == NULL) { + return -1; + } + + attachNewProperty (aafd, NestedScope, prop, PID_NestedScope_Slots, PROP_REQ); + + aafClass* ScopeReference = aafclass_defineNewClass (aafd, &AAFClassID_ScopeReference, CONCRETE, Segment); + + if (ScopeReference == NULL) { + return -1; + } + + attachNewProperty (aafd, ScopeReference, prop, PID_ScopeReference_RelativeScope, PROP_REQ); + attachNewProperty (aafd, ScopeReference, prop, PID_ScopeReference_RelativeSlot, PROP_REQ); + + aafClass* Selector = aafclass_defineNewClass (aafd, &AAFClassID_Selector, CONCRETE, Segment); + + if (Selector == NULL) { + return -1; + } + + attachNewProperty (aafd, Selector, prop, PID_Selector_Selected, PROP_REQ); + attachNewProperty (aafd, Selector, prop, PID_Selector_Alternates, PROP_OPT); + + aafClass* EssenceGroup = aafclass_defineNewClass (aafd, &AAFClassID_EssenceGroup, CONCRETE, Segment); + + if (EssenceGroup == NULL) { + return -1; + } + + attachNewProperty (aafd, EssenceGroup, prop, PID_EssenceGroup_Choices, PROP_REQ); + attachNewProperty (aafd, EssenceGroup, prop, PID_EssenceGroup_StillFrame, PROP_OPT); + + aafClass* DescriptiveFramework = aafclass_defineNewClass (aafd, &AAFClassID_DescriptiveFramework, ABSTRACT, IOC); + + if (DescriptiveFramework == NULL) { + return -1; + } + + aafClass* EssenceDesc = aafclass_defineNewClass (aafd, &AAFClassID_EssenceDescriptor, ABSTRACT, IOC); + + if (EssenceDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, EssenceDesc, prop, PID_EssenceDescriptor_Locator, PROP_OPT); + + aafClass* FileDesc = aafclass_defineNewClass (aafd, &AAFClassID_FileDescriptor, ABSTRACT, EssenceDesc); + + if (FileDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, FileDesc, prop, PID_FileDescriptor_SampleRate, PROP_REQ); + attachNewProperty (aafd, FileDesc, prop, PID_FileDescriptor_Length, PROP_REQ); + attachNewProperty (aafd, FileDesc, prop, PID_FileDescriptor_ContainerFormat, PROP_OPT); + attachNewProperty (aafd, FileDesc, prop, PID_FileDescriptor_CodecDefinition, PROP_OPT); + // attachNewProperty( aafd, FileDesc, prop, PID_FileDescriptor_LinkedSlotID, ??? ); + + aafClass* DigitalImageDesc = aafclass_defineNewClass (aafd, &AAFClassID_DigitalImageDescriptor, ABSTRACT, FileDesc); + + if (DigitalImageDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_Compression, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_StoredHeight, PROP_REQ); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_StoredWidth, PROP_REQ); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_StoredF2Offset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_SampledHeight, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_SampledWidth, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_SampledXOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_SampledYOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_DisplayHeight, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_DisplayWidth, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_DisplayXOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_DisplayYOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_DisplayF2Offset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_FrameLayout, PROP_REQ); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_VideoLineMap, PROP_REQ); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_ImageAspectRatio, PROP_REQ); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_ActiveFormatDescriptor, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_AlphaTransparency, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_ImageAlignmentFactor, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_FieldDominance, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_FieldStartOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_FieldEndOffset, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_ColorPrimaries, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_CodingEquations, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_TransferCharacteristic, PROP_OPT); + attachNewProperty (aafd, DigitalImageDesc, prop, PID_DigitalImageDescriptor_SignalStandard, PROP_OPT); + + aafClass* CDCIDesc = aafclass_defineNewClass (aafd, &AAFClassID_CDCIDescriptor, CONCRETE, DigitalImageDesc); + + if (CDCIDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_HorizontalSubsampling, PROP_REQ); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_VerticalSubsampling, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_ComponentWidth, PROP_REQ); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_AlphaSamplingWidth, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_PaddingBits, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_ColorSiting, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_BlackReferenceLevel, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_WhiteReferenceLevel, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_ColorRange, PROP_OPT); + attachNewProperty (aafd, CDCIDesc, prop, PID_CDCIDescriptor_ReversedByteOrder, PROP_OPT); + + aafClass* RGBADesc = aafclass_defineNewClass (aafd, &AAFClassID_RGBADescriptor, CONCRETE, DigitalImageDesc); + + if (RGBADesc == NULL) { + return -1; + } + + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_PixelLayout, PROP_REQ); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_Palette, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_PaletteLayout, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_ComponentMinRef, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_ComponentMaxRef, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_AlphaMinRef, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_AlphaMaxRef, PROP_OPT); + attachNewProperty (aafd, RGBADesc, prop, PID_RGBADescriptor_ScanningDirection, PROP_OPT); + + aafClass* TapeDesc = aafclass_defineNewClass (aafd, &AAFClassID_TapeDescriptor, CONCRETE, EssenceDesc); + + if (TapeDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_FormFactor, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_VideoSignal, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_TapeFormat, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_Length, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_ManufacturerID, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_Model, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_TapeBatchNumber, PROP_OPT); + attachNewProperty (aafd, TapeDesc, prop, PID_TapeDescriptor_TapeStock, PROP_OPT); + + aafClass* FilmDesc = aafclass_defineNewClass (aafd, &AAFClassID_FilmDescriptor, CONCRETE, EssenceDesc); + + if (FilmDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_FilmFormat, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_FrameRate, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_PerforationsPerFrame, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_FilmAspectRatio, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_Manufacturer, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_Model, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_FilmGaugeFormat, PROP_OPT); + attachNewProperty (aafd, FilmDesc, prop, PID_FilmDescriptor_FilmBatchNumber, PROP_OPT); + + aafClass* WAVEDesc = aafclass_defineNewClass (aafd, &AAFClassID_WAVEDescriptor, CONCRETE, FileDesc); + + if (WAVEDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, WAVEDesc, prop, PID_WAVEDescriptor_Summary, PROP_REQ); + + aafClass* AIFCDesc = aafclass_defineNewClass (aafd, &AAFClassID_AIFCDescriptor, CONCRETE, FileDesc); + + if (AIFCDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, AIFCDesc, prop, PID_AIFCDescriptor_Summary, PROP_REQ); + + aafClass* TIFFDesc = aafclass_defineNewClass (aafd, &AAFClassID_TIFFDescriptor, CONCRETE, FileDesc); + + if (TIFFDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_IsUniform, PROP_REQ); + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_IsContiguous, PROP_REQ); + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_LeadingLines, PROP_OPT); + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_TrailingLines, PROP_OPT); + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_JPEGTableID, PROP_OPT); + attachNewProperty (aafd, TIFFDesc, prop, PID_TIFFDescriptor_Summary, PROP_REQ); + + aafClass* SoundDesc = aafclass_defineNewClass (aafd, &AAFClassID_SoundDescriptor, CONCRETE, FileDesc); + + if (SoundDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_AudioSamplingRate, PROP_REQ); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_Locked, PROP_OPT); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_AudioRefLevel, PROP_OPT); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_ElectroSpatial, PROP_OPT); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_Channels, PROP_REQ); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_QuantizationBits, PROP_REQ); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_DialNorm, PROP_OPT); + attachNewProperty (aafd, SoundDesc, prop, PID_SoundDescriptor_Compression, PROP_OPT); + + aafClass* PCMDesc = aafclass_defineNewClass (aafd, &AAFClassID_PCMDescriptor, CONCRETE, SoundDesc); + + if (PCMDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_BlockAlign, PROP_REQ); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_SequenceOffset, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_AverageBPS, PROP_REQ); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_ChannelAssignment, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakEnvelopeVersion, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakEnvelopeFormat, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PointsPerPeakValue, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakEnvelopeBlockSize, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakChannels, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakFrames, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakOfPeaksPosition, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakEnvelopeTimestamp, PROP_OPT); + attachNewProperty (aafd, PCMDesc, prop, PID_PCMDescriptor_PeakEnvelopeData, PROP_OPT); + + aafClass* PhysicalDesc = aafclass_defineNewClass (aafd, &AAFClassID_PhysicalDescriptor, ABSTRACT, EssenceDesc); + + if (PhysicalDesc == NULL) { + return -1; + } + + /* The PhysicalDescriptor class does not define any additional properties. */ + + aafClass* ImportDesc = aafclass_defineNewClass (aafd, &AAFClassID_ImportDescriptor, CONCRETE, PhysicalDesc); + + if (ImportDesc == NULL) { + return -1; + } + + /* The ImportDescriptor class does not define any additional properties. */ + + aafClass* RecordingDesc = aafclass_defineNewClass (aafd, &AAFClassID_RecordingDescriptor, CONCRETE, PhysicalDesc); + + if (RecordingDesc == NULL) { + return -1; + } + + /* The RecordingDescriptor class does not define any additional properties. */ + + aafClass* AuxiliaryDesc = aafclass_defineNewClass (aafd, &AAFClassID_AuxiliaryDescriptor, CONCRETE, PhysicalDesc); + + if (AuxiliaryDesc == NULL) { + return -1; + } + + attachNewProperty (aafd, AuxiliaryDesc, prop, PID_AuxiliaryDescriptor_MimeType, PROP_REQ); + attachNewProperty (aafd, AuxiliaryDesc, prop, PID_AuxiliaryDescriptor_CharSet, PROP_OPT); + + aafClass* DefObject = aafclass_defineNewClass (aafd, &AAFClassID_DefinitionObject, ABSTRACT, IOC); + + if (DefObject == NULL) { + return -1; + } + + attachNewProperty (aafd, DefObject, prop, PID_DefinitionObject_Identification, PROP_REQ); + attachNewProperty (aafd, DefObject, prop, PID_DefinitionObject_Name, PROP_REQ); + attachNewProperty (aafd, DefObject, prop, PID_DefinitionObject_Description, PROP_OPT); + + aafClass* DataDef = aafclass_defineNewClass (aafd, &AAFClassID_DataDefinition, CONCRETE, DefObject); + + if (DataDef == NULL) { + return -1; + } + + /* The DataDefinition class does not define any additional properties. */ + + aafClass* ContainerDef = aafclass_defineNewClass (aafd, &AAFClassID_ContainerDefinition, CONCRETE, DefObject); + + if (ContainerDef == NULL) { + return -1; + } + + attachNewProperty (aafd, ContainerDef, prop, PID_ContainerDefinition_EssenceIsIdentified, PROP_OPT); + + aafClass* OperationDef = aafclass_defineNewClass (aafd, &AAFClassID_OperationDefinition, CONCRETE, DefObject); + + if (OperationDef == NULL) { + return -1; + } + + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_DataDefinition, PROP_REQ); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_IsTimeWarp, PROP_OPT); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_DegradeTo, PROP_OPT); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_OperationCategory, PROP_OPT); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_NumberInputs, PROP_REQ); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_Bypass, PROP_OPT); + attachNewProperty (aafd, OperationDef, prop, PID_OperationDefinition_ParametersDefined, PROP_OPT); + + aafClass* ParameterDef = aafclass_defineNewClass (aafd, &AAFClassID_ParameterDefinition, CONCRETE, DefObject); + + if (ParameterDef == NULL) { + return -1; + } + + attachNewProperty (aafd, ParameterDef, prop, PID_ParameterDefinition_Type, PROP_REQ); + attachNewProperty (aafd, ParameterDef, prop, PID_ParameterDefinition_DisplayUnits, PROP_OPT); + + aafClass* InterpolationDef = aafclass_defineNewClass (aafd, &AAFClassID_InterpolationDefinition, CONCRETE, DefObject); + + if (InterpolationDef == NULL) { + return -1; + } + + /* The InterpolationDefinition class does not define any additional properties. */ + + aafClass* CodecDef = aafclass_defineNewClass (aafd, &AAFClassID_CodecDefinition, CONCRETE, DefObject); + + if (CodecDef == NULL) { + return -1; + } + + attachNewProperty (aafd, CodecDef, prop, PID_CodecDefinition_FileDescriptorClass, PROP_REQ); + attachNewProperty (aafd, CodecDef, prop, PID_CodecDefinition_DataDefinitions, PROP_REQ); + + aafClass* PluginDef = aafclass_defineNewClass (aafd, &AAFClassID_PluginDefinition, CONCRETE, DefObject); + + if (PluginDef == NULL) { + return -1; + } + + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_PluginCategory, PROP_REQ); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_VersionNumber, PROP_REQ); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_VersionString, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Manufacturer, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_ManufacturerInfo, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_ManufacturerID, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Platform, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MinPlatformVersion, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MaxPlatformVersion, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Engine, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MinEngineVersion, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MaxEngineVersion, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_PluginAPI, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MinPluginAPI, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_MaxPluginAPI, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_SoftwareOnly, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Accelerator, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Locators, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_Authentication, PROP_OPT); + attachNewProperty (aafd, PluginDef, prop, PID_PluginDefinition_DefinitionObject, PROP_OPT); + + aafClass* TaggedValueDef = aafclass_defineNewClass (aafd, &AAFClassID_TaggedValueDefinition, CONCRETE, DefObject); + + if (TaggedValueDef == NULL) { + return -1; + } + + /* The TaggedValueDefinition class does not define any additional properties. */ + + aafClass* KLVDataDef = aafclass_defineNewClass (aafd, &AAFClassID_KLVDataDefinition, CONCRETE, DefObject); + + if (KLVDataDef == NULL) { + return -1; + } + + attachNewProperty (aafd, KLVDataDef, prop, PID_KLVDataDefinition_KLVDataType, PROP_OPT); + + aafClass* EssenceData = aafclass_defineNewClass (aafd, &AAFClassID_EssenceData, CONCRETE, IOC); + + if (EssenceData == NULL) { + return -1; + } + + attachNewProperty (aafd, EssenceData, prop, PID_EssenceData_MobID, PROP_REQ); + attachNewProperty (aafd, EssenceData, prop, PID_EssenceData_Data, PROP_REQ); + attachNewProperty (aafd, EssenceData, prop, PID_EssenceData_SampleIndex, PROP_OPT); + + aafClass* MetaDefinition = aafclass_defineNewClass (aafd, &AAFClassID_MetaDefinition, ABSTRACT, NULL); + + if (MetaDefinition == NULL) { + return -1; + } + + attachNewProperty (aafd, MetaDefinition, prop, PID_MetaDefinition_Identification, PROP_REQ); + attachNewProperty (aafd, MetaDefinition, prop, PID_MetaDefinition_Name, PROP_REQ); + attachNewProperty (aafd, MetaDefinition, prop, PID_MetaDefinition_Description, PROP_OPT); + + aafClass* ClassDefinition = aafclass_defineNewClass (aafd, &AAFClassID_ClassDefinition, CONCRETE, MetaDefinition); + + if (ClassDefinition == NULL) { + return -1; + } + + attachNewProperty (aafd, ClassDefinition, prop, PID_ClassDefinition_ParentClass, PROP_REQ); + attachNewProperty (aafd, ClassDefinition, prop, PID_ClassDefinition_Properties, PROP_OPT); + attachNewProperty (aafd, ClassDefinition, prop, PID_ClassDefinition_IsConcrete, PROP_REQ); + + aafClass* PropertyDefinition = aafclass_defineNewClass (aafd, &AAFClassID_PropertyDefinition, CONCRETE, MetaDefinition); + + if (PropertyDefinition == NULL) { + return -1; + } + + attachNewProperty (aafd, PropertyDefinition, prop, PID_PropertyDefinition_Type, PROP_REQ); + attachNewProperty (aafd, PropertyDefinition, prop, PID_PropertyDefinition_IsOptional, PROP_REQ); + attachNewProperty (aafd, PropertyDefinition, prop, PID_PropertyDefinition_LocalIdentification, PROP_REQ); + attachNewProperty (aafd, PropertyDefinition, prop, PID_PropertyDefinition_IsUniqueIdentifier, PROP_OPT); + + aafClass* TypeDef = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinition, ABSTRACT, MetaDefinition); + + if (TypeDef == NULL) { + return -1; + } + + /* The TypeDefinition class does not define any additional properties. */ + + aafClass* TypeDefCharacter = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionCharacter, CONCRETE, TypeDef); + + if (TypeDefCharacter == NULL) { + return -1; + } + + /* The TypeDefinitionCharacter class does not define any additional properties. */ + + aafClass* TypeDefEnum = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionEnumeration, CONCRETE, TypeDef); + + if (TypeDefEnum == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefEnum, prop, PID_TypeDefinitionEnumeration_ElementType, PROP_REQ); + attachNewProperty (aafd, TypeDefEnum, prop, PID_TypeDefinitionEnumeration_ElementNames, PROP_REQ); + attachNewProperty (aafd, TypeDefEnum, prop, PID_TypeDefinitionEnumeration_ElementValues, PROP_REQ); + + aafClass* TypeDefExtEnum = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionExtendibleEnumeration, CONCRETE, TypeDef); + + if (TypeDefExtEnum == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefExtEnum, prop, PID_TypeDefinitionExtendibleEnumeration_ElementNames, PROP_REQ); + attachNewProperty (aafd, TypeDefExtEnum, prop, PID_TypeDefinitionExtendibleEnumeration_ElementValues, PROP_REQ); + + aafClass* TypeDefFixedArray = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionFixedArray, CONCRETE, TypeDef); + + if (TypeDefFixedArray == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefFixedArray, prop, PID_TypeDefinitionFixedArray_ElementType, PROP_REQ); + attachNewProperty (aafd, TypeDefFixedArray, prop, PID_TypeDefinitionFixedArray_ElementCount, PROP_REQ); + + aafClass* TypeDefIndirect = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionIndirect, CONCRETE, TypeDef); + + if (TypeDefIndirect == NULL) { + return -1; + } + + /* The TypeDefinitionIndirect class does not define any additional properties. */ + + aafClass* TypeDefInt = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionInteger, CONCRETE, TypeDef); + + if (TypeDefInt == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefInt, prop, PID_TypeDefinitionInteger_Size, PROP_REQ); + attachNewProperty (aafd, TypeDefInt, prop, PID_TypeDefinitionInteger_IsSigned, PROP_REQ); + + aafClass* TypeDefOpaque = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionOpaque, CONCRETE, TypeDef); + + if (TypeDefOpaque == NULL) { + return -1; + } + + /* The TypeDefinitionOpaque class does not define any additional properties. */ + + aafClass* TypeDefRecord = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionRecord, CONCRETE, TypeDef); + + if (TypeDefRecord == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefRecord, prop, PID_TypeDefinitionRecord_MemberTypes, PROP_REQ); + attachNewProperty (aafd, TypeDefRecord, prop, PID_TypeDefinitionRecord_MemberNames, PROP_REQ); + + aafClass* TypeDefRename = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionRename, CONCRETE, TypeDef); + + if (TypeDefRename == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefRename, prop, PID_TypeDefinitionRename_RenamedType, PROP_REQ); + + aafClass* TypeDefSet = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionSet, CONCRETE, TypeDef); + + if (TypeDefSet == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefSet, prop, PID_TypeDefinitionSet_ElementType, PROP_REQ); + + aafClass* TypeDefStream = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionStream, CONCRETE, TypeDef); + + if (TypeDefStream == NULL) { + return -1; + } + + /* The TypeDefinitionStream class does not define any additional properties. */ + + aafClass* TypeDefString = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionString, CONCRETE, TypeDef); + + if (TypeDefString == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefString, prop, PID_TypeDefinitionString_ElementType, PROP_REQ); + + aafClass* TypeDefStrongObjRef = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionStrongObjectReference, CONCRETE, TypeDef); + + if (TypeDefStrongObjRef == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefStrongObjRef, prop, PID_TypeDefinitionStrongObjectReference_ReferencedType, PROP_REQ); + + aafClass* TypeDefVariableArray = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionVariableArray, CONCRETE, TypeDef); + + if (TypeDefVariableArray == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefVariableArray, prop, PID_TypeDefinitionVariableArray_ElementType, PROP_REQ); + + aafClass* TypeDefWeakObjRef = aafclass_defineNewClass (aafd, &AAFClassID_TypeDefinitionWeakObjectReference, CONCRETE, TypeDef); + + if (TypeDefWeakObjRef == NULL) { + return -1; + } + + attachNewProperty (aafd, TypeDefWeakObjRef, prop, PID_TypeDefinitionWeakObjectReference_ReferencedType, PROP_REQ); + attachNewProperty (aafd, TypeDefWeakObjRef, prop, PID_TypeDefinitionWeakObjectReference_TargetSet, PROP_REQ); + + aafClass* MetaDictionary = aafclass_defineNewClass (aafd, &AAFClassID_MetaDictionary, CONCRETE, NULL); + + if (MetaDictionary == NULL) { + return -1; + } + + attachNewProperty (aafd, MetaDictionary, prop, PID_MetaDictionary_ClassDefinitions, PROP_OPT); + attachNewProperty (aafd, MetaDictionary, prop, PID_MetaDictionary_TypeDefinitions, PROP_OPT); + + return 0; +} diff --git a/libs/aaf/AAFCore.c b/libs/aaf/AAFCore.c new file mode 100644 index 0000000000..04bbfb5c91 --- /dev/null +++ b/libs/aaf/AAFCore.c @@ -0,0 +1,1904 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +#include "aaf/AAFCore.h" +#include "aaf/AAFDump.h" +#include "aaf/AAFToText.h" +#include "aaf/AAFTypes.h" + +#include "aaf/AAFDefs/AAFClassDefUIDs.h" +#include "aaf/AAFDefs/AAFFileKinds.h" +#include "aaf/AAFDefs/AAFPropertyIDs.h" +#include "aaf/AAFDefs/AAFTypeDefUIDs.h" + +#include "aaf/debug.h" + +#include "aaf/AAFClass.h" +#include "aaf/utils.h" + +#define debug(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafd->dbg, aafd, DEBUG_SRC_ID_AAF_CORE, VERB_ERROR, __VA_ARGS__) + +/** + * Loops through each aafPropertyIndexEntry_t of a "properties" node stream. + * + * @param Header Pointer to the stream's aafPropertyIndexHeader_t struct. + * @param Entry Pointer that will receive each aafPropertyIndexEntry_t struct. + * @param Value Pointer to each property's data value, of aafPropertyIndexEntry_t._length + * bytes length. + * @param i uint32_t iterator. + */ + +#define foreachPropertyEntry(propStream, Header, Entry, Value, valueOffset, i) \ + for (valueOffset = sizeof (aafPropertyIndexHeader_t) + (Header._entryCount * sizeof (aafPropertyIndexEntry_t)), \ + i = 0; \ + i < Header._entryCount && \ + memcpy (&Entry, (propStream + ((sizeof (aafPropertyIndexHeader_t)) + (sizeof (aafPropertyIndexEntry_t) * i))), sizeof (aafPropertyIndexEntry_t)) && \ + (Value = propStream + valueOffset); \ + valueOffset += Entry._length, \ + i++) + +/** + * Loops through each aafStrongRefSetEntry_t of a StrongRefSet Index node stream. + * + * @param Header Pointer to the stream's aafStrongRefSetHeader_t struct. + * @param Entry Pointer that will receive each aafStrongRefSetEntry_t struct. + * @param i uint32_t iterator. + */ + +#define foreachStrongRefSetEntry(Header, Entry, i) \ + for (i = 0; \ + i < Header->_entryCount && \ + memcpy (&Entry, ((char*)(Header)) + (sizeof (aafStrongRefSetHeader_t) + (Header->_identificationSize + sizeof (aafStrongRefSetEntry_t)) * i), sizeof (aafStrongRefSetEntry_t) + Header->_identificationSize); \ + i++) + +/** + * Loops through each aafStrongRefVectorEntry_t of a StrongRefVector Index node stream. + * + * @param Header Pointer to the stream's aafStrongRefVectorHeader_t struct. + * @param Entry Pointer that will receive each aafStrongRefVectorEntry_t struct. + * @param i uint32_t iterator. + */ +#define foreachStrongRefVectorEntry(vectorStream, Header, Entry, i) \ + for (i = 0; \ + i < Header._entryCount && \ + memcpy (&Entry, (vectorStream + (sizeof (aafStrongRefVectorHeader_t) + (sizeof (aafStrongRefVectorEntry_t) * i))), sizeof (aafStrongRefVectorEntry_t)); \ + i++) + +#define attachNewProperty(Class, PDef, Pid, IsReq) \ + PDef = calloc (sizeof (aafPropertyDef), sizeof (unsigned char)); \ + if (PDef == NULL) { \ + error ("%s.", strerror (errno)); \ + return NULL; \ + } \ + PDef->pid = Pid; \ + PDef->isReq = IsReq; \ + PDef->meta = 0; \ + PDef->name = NULL; \ + PDef->next = Class->Properties; \ + Class->Properties = PDef; + +/* + * Retrieves useful file informations out of Header Object. + * + * @param aafd Pointer to the AAF_Data structure. + * + * @return 0 on success\n + * -1 on error. + */ + +static int +parse_Header (AAF_Data* aafd); + +/* + * Retrieves useful file informations out of Identification Object. + * + * @param aafd Pointer to the AAF_Data structure. + * + * @return 0 on success\n + * -1 on error. + */ + +static int +parse_Identification (AAF_Data* aafd); + +/* + * Tests the CFB_Data.hdr._clsid field for a valid AAF file. + * + * @note The spec says that the AAFFileKind signature should be retrieved from the CLSID + * of the Root IStorage. In practice, this CLSID holds the #AAFClassID_Root value, and + * the AAFFileKind is (sometimes) found in the CLSID of the CFB_Header, which according + * to the CFB spec should be zero. All of this has been observed in AAF files built with + * the official AAFSDK. + * + * As a conclusion, the way to test for a valid AAF file is not a valid test itself.. or + * not sufficiently documented. Thus, this function shall not be trusted until further + * knowledge improvement. + * + * @param aafd Pointer to the AAF_Data structure. + * + * @return 1 if the file *looks like* a valid AAF\n + * 0 otherwise. + */ + +// static int isValidAAF( AAF_Data *aafd ); + +/** + * Sets the AAF_Data structure's pointers to the main AAF Tree objects. These pointers + * can then be used for quick conveniant objects access. + * + * @param aafd Pointer to the AAF_Data structure. + */ + +static void +setObjectShortcuts (AAF_Data* aafd); + +/** + * Parses the entire Compound File Binary Tree and retrieves Objets and Properties. + * + * This function first parses the Root Object, then follows the Root::MetaDictionary to + * retrieve potential custom Classes and Properties with retrieveMetaDictionaryClass(), + * and then parses the rest of the Tree starting at Root::Header. + * + * This function should be called after the AAF Classes has been defined by + * #aafclass_setDefaultClasses(). This function is called by aaf_load_file(). + * + * @param aafd Pointer to the AAF_Data structure. + */ + +static int +retrieveObjectTree (AAF_Data* aafd); + +/** + * Parses the entire MetaDictionary, retrieving potential custom classes and properties. + * This function is to be called within a loop that iterates through the + * MetaDictionary::ClassDefinitions Objects, and by itself when looking for parent + * Classes. + * + * @param aafd Pointer to the AAF_Data structure. + * @param TargetClassDef Pointer to the current ClassDefinition Object. + * + * @return A pointer to the retrieved Class. + */ + +static aafClass* +retrieveMetaDictionaryClass (AAF_Data* aafd, aafObject* TargetClassDef); + +/** + * Allocates a new aafObject structure, and adds it to the AAF_Data.Objects list. + * + * @param aafd Pointer to the AAF_Data structure. + * @param node Pointer to the corresponding cfbNode structure. + * @param Class Pointer to the corresponding class definition aafClass structure. + * @param parent Pointer to the new Object's parent object, that is the one that has an + * ownership reference (Strong Ref Set/Vector) to the new Object. + * + * @return A pointer to the newly created aafObject. + */ + +static aafObject* +newObject (AAF_Data* aafd, cfbNode* node, aafClass* Class, aafObject* parent); + +/** + * Allocates a new aafProperty structure. + * + * @param Def Pointer to the corresponding property definition aafPropertyDef structure. + * + * @return A pointer to the newly created aafProperty. + */ + +static aafProperty* +newProperty (AAF_Data* aafd, aafPropertyDef* Def); + +/** + * Test whether or not, a property ID (property definition) was already retrieved for a given Class. + * + * @param Class Pointer to the aafClass. + * @param Pid Property ID. + * + * @return A pointer to the retrieved property definition\n + * NULL otherwise. + */ + +static aafPropertyDef* +propertyIdExistsInClass (aafClass* Class, aafPID_t Pid); + +/** + * Sets the aafStrongRefSetHeader_t Obj->Header and aafStrongRefSetEntry_t Obj->Entry, + * when parsing an Object from a StrongReferenceSet. This function is called by the + * #retrieveStrongReferenceSet() function. + * + * @param Obj Pointer to an aafObject structure. + * @param Header Pointer to an aafStrongRefSetHeader_t structure. + * @param Entry Pointer to an aafStrongRefSetEntry_t structure. + */ + +static int +setObjectStrongRefSet (aafObject* Obj, aafStrongRefSetHeader_t* Header, aafStrongRefSetEntry_t* Entry); + +/** + * Sets the aafStrongRefVectorHeader_t Obj->Header and aafStrongRefVectorEntry_t + * Obj->Entry, when parsing an Object from a StrongReferenceSet. This function is called + * by the retrieveStrongReferenceVector() function. + * + * @param Obj Pointer to an aafObject structure. + * @param Header Pointer to an aafStrongRefVectorHeader_t structure. + * @param Entry Pointer to an aafStrongRefVectorEntry_t structure. + */ + +static int +setObjectStrongRefVector (aafObject* Obj, aafStrongRefVectorHeader_t* Header, aafStrongRefVectorEntry_t* Entry); + +/** + * Retrieves and parses a single StrongReference Object. This function is called by + * retrieveProperty() when it encounters an SF_STRONG_OBJECT_REFERENCE property. + * + * @param aafd Pointer to the AAF_Data structure. + * @param Prop Pointer to the property holding the SF_STRONG_OBJECT_REFERENCE. + * @param parent Pointer to the parent Object which holds the Prop property. + */ + +static int +retrieveStrongReference (AAF_Data* aafd, aafProperty* Prop, aafObject* parent); + +/** + * Retrieves and parses StrongReferenceSet Objects. This function is called by + * retrieveProperty() when it encounters an SF_STRONG_OBJECT_REFERENCE_SET property. + * + * @param aafd Pointer to the AAF_Data structure. + * @param Prop Pointer to the property holding the SF_STRONG_OBJECT_REFERENCE_SET. + * @param parent Pointer to the parent Object which holds the Prop property. + */ + +static int +retrieveStrongReferenceSet (AAF_Data* aafd, aafProperty* Prop, aafObject* parent); + +/** + * Retrieve and parse StrongReferenceVector Objects. This function is called by + * retrieveProperty() when it encounters an SF_STRONG_OBJECT_REFERENCE_VECTOR property. + * + * @param aafd Pointer to the AAF_Data structure. + * @param Prop Pointer to the property holding the SF_STRONG_OBJECT_REFERENCE_VECTOR. + * @param parent Pointer to the parent Object which holds the Prop property. + */ + +static int +retrieveStrongReferenceVector (AAF_Data* aafd, aafProperty* Prop, aafObject* parent); + +/** + * Adds a new aafProperty to an Object->properties list. If the property Stored Form is + * either SF_STRONG_OBJECT_REFERENCE, SF_STRONG_OBJECT_REFERENCE_SET or + * SF_STRONG_OBJECT_REFERENCE_VECTOR, then the function follows the "link" to the + * Object(s) by calling respectively retrieveStrongReference(), + * retrieveStrongReferenceSet() or retrieveStrongReferenceVector(). This function is + * called by retrieveObjectProperties(). + * + * @param aafd Pointer to the AAF_Data structure. + * @param Obj Pointer to the aafObject structure holding this property. + * @param Def Pointer to the aafPropertyDef structure defining this property. + * @param p Pointer to the aafPropertyIndexEntry_t structure representing the property + * in the file. + * @param v Pointer to a p->_length long byte array holding the actual property value. + * @param bo uint8_t specifying the property's Byte Order. TO BE IMPLEMENTED + * + * @TODO Take ByteOrder into account + */ + +static int +retrieveProperty (AAF_Data* aafd, aafObject* Obj, aafPropertyDef* Def, aafPropertyIndexEntry_t* p, aafByte_t* v, uint8_t bo); + +/** + * Retrieves the properties for a given aafObject. + * + * @param aafd Pointer to the AAF_Data structure. + * @param Obj Pointer to the aafObject holding the properties. + */ + +static int +retrieveObjectProperties (AAF_Data* aafd, aafObject* Obj); + +/** + * Retrieves a StrongRef Set/Vector Index Node in the Compound File Tree. This function + * is called by both retrieveStrongReferenceSet() and retrieveStrongReferenceVector(). + * + * @param aafd Pointer to the AAF_Data structure. + * @param parent Pointer to the parent aafObject. + * @param refName Pointer to a null terminated string holding the reference name. + * + * @return Pointer to the retrieved Node cfbNode structure. + */ + +static cfbNode* +getStrongRefIndexNode (AAF_Data* aafd, aafObject* parent, const wchar_t* refName); + +/** + * Retrieves a StrongRef Set or Vector Entry Node in the Compound File Tree. This + * function is called by both retrieveStrongReferenceSet() and + * retrieveStrongReferenceVector(). + * + * @param aafd Pointer to the AAF_Data structure. + * @param parent Pointer to the parent Index Node. + * @param baseName Pointer to a null terminated string holding the reference base name. + * @param index uint32_t number representing the index number of the reference. + * + * @return Pointer to the retrieved Node cfbNode structure. + */ + +static cfbNode* +getStrongRefEntryNode (AAF_Data* aafd, aafObject* parent, const wchar_t* baseName, uint16_t index); + +/** + * Retrieves and returns a list of aafPropertyIndexHeader_t. + * For a given cfbNode, retrieves its /properties Stream Node and returns the stream as + * a pointer to an aafPropertyIndexHeader_t structure, wich the stream should begin with. + * + * @param aafd Pointer to the AAF_Data structure. + * @param node Pointer to a cfbNode structure. + * + * @return Pointer to an aafPropertyIndexHeader_t structure, followed by _entryCount + * aafPropertyIndexEntry_t structures. + */ + +static aafByte_t* +getNodeProperties (AAF_Data* aafd, cfbNode* node); + +/** + * Retrieves and returns a list of StrongReferenceSet. + * + * For a given Index cfbNode, retrieves its Stream and returns it as a pointer to an + * aafStrongRefSetHeader_t structure, wich the stream should begin with. + * + * @param aafd Pointer to the AAF_Data structure. + * @param node Pointer to an Index cfbNode structure. + * @param parent Pointer to the aafObject parent, only used on error printing. + * + * @return Pointer to an aafStrongRefSetHeader_t structure, followed by _entryCount + * aafStrongRefSetEntry_t structures. + */ + +static aafStrongRefSetHeader_t* +getStrongRefSetList (AAF_Data* aafd, cfbNode* node, aafObject* parent); + +/** + * Retrieves and returns a list of StrongReferenceVectors. + * + * For a given Index cfbNode, retrieves its Stream and returns it as a pointer to an + * aafStrongRefVectorHeader_t structure, wich the stream should begin with. + * + * @param aafd Pointer to the AAF_Data structure. + * @param node Pointer to an Index cfbNode structure. + * @param parent Pointer to the aafObject parent, only used on error printing. + * + * @return Pointer to an aafStrongRefVectorHeader_t structure, followed by + * _entryCount aafStrongRefVectorEntry_t structures. + */ + +static aafByte_t* +getStrongRefVectorList (AAF_Data* aafd, cfbNode* node, aafObject* parent); + +AAF_Data* +aaf_alloc (struct dbg* dbg) +{ + AAF_Data* aafd = calloc (sizeof (AAF_Data), sizeof (unsigned char)); + + if (aafd == NULL) + error ("%s.", strerror (errno)); + + aafd->cfbd = NULL; + // aafd->verb = VERB_QUIET; + + aafd->Identification.CompanyName = NULL; + aafd->Identification.ProductName = NULL; + aafd->Identification.ProductVersionString = NULL; + aafd->Identification.Platform = NULL; + + aafd->Classes = NULL; + aafd->Objects = NULL; + // aafd->debug_callback = &laaf_debug_callback; + aafd->dbg = dbg; + + aafd->cfbd = cfb_alloc (dbg); + + if (aafd->cfbd == NULL) { + return NULL; + } + + // aafd->cfbd->verb = aafd->verb; + + return aafd; +} + +int +aaf_load_file (AAF_Data* aafd, const char* file) +{ + if (file == NULL) + return 1; + + aafd->Objects = NULL; + aafd->Classes = NULL; + + if (cfb_load_file (&aafd->cfbd, file) < 0) { + return 1; + } + + /* + * NOTE: at least Avid Media Composer doesn't respect + * the standard clsid AAFFileKind_Aaf4KBinary identifier. + * Therefore isValidAAF() is useless until futher findings.. + */ + + // if ( isValidAAF( aafd ) == 0 ) { + // return 1; + // } + + if (aafclass_setDefaultClasses (aafd) < 0) { + return -1; + } + + if (retrieveObjectTree (aafd) < 0) { + return -1; + } + + if (parse_Header (aafd) < 0) { + return -1; + } + + if (parse_Identification (aafd) < 0) { + return -1; + } + + return 0; +} + +void +aaf_release (AAF_Data** aafd) +{ + if (aafd == NULL || *aafd == NULL) + return; + + if ((*aafd)->cfbd != NULL) + cfb_release (&((*aafd)->cfbd)); + + aafClass* Class = NULL; + aafClass* tmpClass = NULL; + + for (Class = (*aafd)->Classes; Class != NULL; Class = tmpClass) { + tmpClass = Class->next; + + aafPropertyDef* PDef = NULL; + aafPropertyDef* tmpPDef = NULL; + + if (Class->name != NULL) { + free (Class->name); + } + + for (PDef = Class->Properties; PDef != NULL; PDef = tmpPDef) { + tmpPDef = PDef->next; + + // if ( PDef->meta ) { + if (PDef->name != NULL) + free (PDef->name); + // } + + free (PDef); + } + + free (Class); + } + + aafObject* Object = NULL; + aafObject* tmpObject = NULL; + + for (Object = (*aafd)->Objects; Object != NULL; Object = tmpObject) { + tmpObject = Object->nextObj; + + if (Object->Header != NULL) + free (Object->Header); + + if (Object->Entry != NULL) + free (Object->Entry); + + aafProperty* Prop = NULL; + aafProperty* tmpProp = NULL; + + for (Prop = Object->Properties; Prop != NULL; Prop = tmpProp) { + tmpProp = Prop->next; + + switch (Prop->sf) { + case SF_STRONG_OBJECT_REFERENCE: + case SF_STRONG_OBJECT_REFERENCE_SET: + case SF_STRONG_OBJECT_REFERENCE_VECTOR: + break; + + default: + free (Prop->val); + } + + free (Prop); + } + + free (Object); + } + + if ((*aafd)->Identification.CompanyName != NULL) { + free ((*aafd)->Identification.CompanyName); + } + + if ((*aafd)->Identification.ProductName != NULL) { + free ((*aafd)->Identification.ProductName); + } + + if ((*aafd)->Identification.ProductVersionString != NULL) { + free ((*aafd)->Identification.ProductVersionString); + } + + if ((*aafd)->Identification.Platform != NULL) { + free ((*aafd)->Identification.Platform); + } + + /* free once in AAFIface */ + // if ( (*aafd)->dbg ) { + // laaf_free_debug( (*aafd)->dbg ); + // } + + free (*aafd); + + *aafd = NULL; +} + +wchar_t* +aaf_get_ObjectPath (aafObject* Obj) +{ + static wchar_t path[CFB_PATH_NAME_SZ]; + + uint32_t offset = CFB_PATH_NAME_SZ; + path[--offset] = 0x0000; // NULL terminating byte + + while (Obj != NULL) { + for (int i = wcslen (Obj->Name) - 1; i >= 0 && offset > 0; i--) { + path[--offset] = Obj->Name[i]; + } + + if (offset == 0) + break; + + path[--offset] = '/'; + + Obj = Obj->Parent; + } + + return path + offset; +} + +int +_aaf_foreach_ObjectInSet (aafObject** Obj, aafObject* head, const aafUID_t* filter) +{ + if (*Obj == NULL) + *Obj = head; + else + *Obj = (*Obj)->next; + + if (filter != NULL) + for (; *Obj != NULL; *Obj = (*Obj)->next) + if (aafUIDCmp ((*Obj)->Class->ID, filter)) + break; + + return (*Obj == NULL) ? 0 : 1; +} + +aafObject* +aaf_get_ObjectByWeakRef (aafObject* list, aafWeakRef_t* ref) +{ + if (ref == NULL || + list == NULL || + list->Entry == NULL) { + return NULL; + } + + AAF_Data* aafd = list->aafd; + + /* Target is a Reference Vector */ + if (list->Header->_identificationSize == 0) { + // debug( "Has local key" ); + + for (; list != NULL; list = list->next) { + if (list->Entry->_localKey == ref->_referencedPropertyIndex) { + // debug( "list->Entry->_localKey : 0x%x", list->Entry->_localKey ); + // debug( "list->Header->_identificationSize : %u", list->Header->_identificationSize ); + // debug( "FOUND : 0x%x", list->Entry->_localKey ); + return list; + } + } + } + /* Target is a Reference Set */ + else { + for (; list != NULL; list = list->next) { + if (memcmp (list->Entry->_identification, ref->_identification, ref->_identificationSize) == 0) { + if (list->Header->_identificationSize != ref->_identificationSize) { + /* TODO : is it possible ? is it an error ? */ + debug ("list->Header->_identificationSize (%i bytes) doesn't match ref->_identificationSize (%i bytes)", list->Header->_identificationSize, ref->_identificationSize); + } + + return list; + } + } + } + + return NULL; +} + +aafObject* +aaf_get_MobByID (aafObject* Mobs, aafMobID_t* MobID) +{ + aafObject* Mob = NULL; + + if (MobID == NULL) + return NULL; + + aaf_foreach_ObjectInSet (&Mob, Mobs, NULL) + { + aafMobID_t* Current = aaf_get_propertyValue (Mob, PID_Mob_MobID, &AAFTypeID_MobIDType); + + if (Current == NULL || aafMobIDCmp (Current, MobID)) + break; + } + + return Mob; +} + +aafObject* +aaf_get_MobSlotBySlotID (aafObject* MobSlots, aafSlotID_t SlotID) +{ + aafObject* MobSlot = NULL; + + aaf_foreach_ObjectInSet (&MobSlot, MobSlots, NULL) + { + aafSlotID_t* CurrentSlotID = aaf_get_propertyValue (MobSlot, PID_MobSlot_SlotID, &AAFTypeID_UInt32); + + if (CurrentSlotID == NULL || *CurrentSlotID == SlotID) + break; + } + + return MobSlot; +} + +/* + * TODO Works when the property was retrieved from MetaDictionary. What if the property is standard ? + */ + +aafPID_t +aaf_get_PropertyIDByName (AAF_Data* aafd, const wchar_t* name) +{ + aafClass* Class = NULL; + + foreachClass (Class, aafd->Classes) + { + aafPropertyDef* PDef = NULL; + + foreachPropertyDefinition (PDef, Class->Properties) + { + if (PDef->name != NULL && wcscmp (PDef->name, name) == 0) { + return PDef->pid; + } + } + } + + return 0; +} + +aafProperty* +aaf_get_property (aafObject* Obj, aafPID_t pid) +{ + if (Obj == NULL) + return NULL; + + AAF_Data* aafd = Obj->aafd; + + aafProperty* Prop = NULL; + + for (Prop = Obj->Properties; Prop != NULL; Prop = Prop->next) + if (Prop->pid == pid) + break; + + if (Prop == NULL) { + aafPropertyDef* PDef = aafclass_getPropertyDefinitionByID (Obj->Class, pid); + + if (PDef == NULL) { + warning ("Unknown property 0x%04x (%ls) of Class %ls", pid, aaft_PIDToText (aafd, pid), aaft_ClassIDToText (aafd, Obj->Class->ID)); + return NULL; + } + + if (PDef->isReq) { + error ("Could not retrieve %ls required property 0x%04x (%ls)", aaft_ClassIDToText (aafd, Obj->Class->ID), pid, aaft_PIDToText (aafd, pid)); + } else { + debug ("Could not retrieve %ls optional property 0x%04x (%ls)", aaft_ClassIDToText (aafd, Obj->Class->ID), pid, aaft_PIDToText (aafd, pid)); + } + } + + return Prop; +} + +void* +aaf_get_propertyValue (aafObject* Obj, aafPID_t pid, const aafUID_t* typeID) +{ + if (Obj == NULL) { + return NULL; + } + + AAF_Data* aafd = Obj->aafd; + aafProperty* Prop = aaf_get_property (Obj, pid); + + if (Prop == NULL) { + return NULL; + } + + void* value = Prop->val; + uint16_t len = Prop->len; + + if (Prop->sf == SF_DATA_STREAM || aafUIDCmp (typeID, &AAFTypeID_Indirect)) { + /* + * DATA_STREAM stored form and IndirectValues start with a byte identifying byte order : 0x4c, 0x42, 0x55 + * We must skip that byte. + */ + value = (void*)(((char*)value) + 1); + len--; + } + + if (aafUIDCmp (typeID, &AAFTypeID_String)) { + if (((uint16_t*)value)[(len / 2) - 1] != 0x0000) { + error ("Object %ls string property 0x%04x (%ls) does not end with NULL", aaft_ClassIDToText (aafd, Obj->Class->ID), pid, aaft_PIDToText (aafd, pid)); + return NULL; + } + + return cfb_w16towchar (NULL, value, len); + } + + if (aafUIDCmp (typeID, &AAFTypeID_Indirect)) { + /* + * In case of Indirect with string value we check NULL termination here, + * because when calling next aaf_get_indirectValue() we wont have access + * to Prop->len anymore. + */ + + aafIndirect_t* Indirect = value; + + if (aafUIDCmp (&Indirect->TypeDef, &AAFTypeID_String) && ((uint16_t*)value)[(len / 2) - 1] != 0x0000) { + error ("Object %ls Indirect::string property 0x%04x (%ls) does not end with NULL", aaft_ClassIDToText (aafd, Obj->Class->ID), pid, aaft_PIDToText (aafd, pid)); + return NULL; + } + } + + if ((aafUIDCmp (typeID, &AAFTypeID_Boolean) && len != sizeof (aafBoolean_t)) || + (aafUIDCmp (typeID, &AAFTypeID_Int8) && len != sizeof (int8_t)) || + (aafUIDCmp (typeID, &AAFTypeID_UInt8) && len != sizeof (uint8_t)) || + (aafUIDCmp (typeID, &AAFTypeID_Int16) && len != sizeof (int16_t)) || + (aafUIDCmp (typeID, &AAFTypeID_UInt16) && len != sizeof (uint16_t)) || + (aafUIDCmp (typeID, &AAFTypeID_Int32) && len != sizeof (int32_t)) || + (aafUIDCmp (typeID, &AAFTypeID_UInt32) && len != sizeof (uint32_t)) || + (aafUIDCmp (typeID, &AAFTypeID_Int64) && len != sizeof (int64_t)) || + (aafUIDCmp (typeID, &AAFTypeID_UInt64) && len != sizeof (uint64_t)) || + (aafUIDCmp (typeID, &AAFTypeID_PositionType) && len != sizeof (aafPosition_t)) || + (aafUIDCmp (typeID, &AAFTypeID_LengthType) && len != sizeof (aafLength_t)) || + (aafUIDCmp (typeID, &AAFTypeID_Rational) && len != sizeof (aafRational_t)) || + (aafUIDCmp (typeID, &AAFTypeID_TimeStamp) && len != sizeof (aafTimeStamp_t)) || + (aafUIDCmp (typeID, &AAFTypeID_VersionType) && len != sizeof (aafVersionType_t)) || + (aafUIDCmp (typeID, &AAFTypeID_ProductVersion) && len != sizeof (aafProductVersion_t)) || + (aafUIDCmp (typeID, &AAFTypeID_UsageType) && len != sizeof (aafUID_t)) || + (aafUIDCmp (typeID, &AAFTypeID_AUID) && len != sizeof (aafUID_t)) || + (aafUIDCmp (typeID, &AAFTypeID_MobIDType) && len != sizeof (aafMobID_t))) { + error ("Object %ls property 0x%04x (%ls) size (%u) does not match type %ls", aaft_ClassIDToText (aafd, Obj->Class->ID), pid, aaft_PIDToText (aafd, pid), len, aaft_TypeIDToText (typeID)); + return NULL; + } + + return value; +} + +void* +aaf_get_indirectValue (AAF_Data* aafd, aafIndirect_t* Indirect, const aafUID_t* typeDef) +{ + if (Indirect == NULL) { + error ("Indirect is NULL"); + return NULL; + } + + if (typeDef && aafUIDCmp (&Indirect->TypeDef, typeDef) == 0) { + error ("Requested Indirect value of type %ls but has type %ls", aaft_TypeIDToText (typeDef), aaft_TypeIDToText (&Indirect->TypeDef)); + return NULL; + } + + if (aafUIDCmp (typeDef, &AAFTypeID_String)) { + /* + * Indirect->Value is guaranted by aaf_get_property() to be NULL terminated + */ + + size_t indirectValueSize = 0; + + for (size_t i = 0; (i % 2 || !(Indirect->Value[i] == 0x00 && Indirect->Value[i + 1] == 0x00)); i++) { + indirectValueSize++; + } + + indirectValueSize += 2; + + uint16_t* w16 = malloc (indirectValueSize); + + if (w16 == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + memcpy (w16, Indirect->Value, indirectValueSize); + + wchar_t* str = cfb_w16towchar (NULL, w16, indirectValueSize); + + free (w16); + + return str; + } + + return &Indirect->Value; +} + +static int +parse_Header (AAF_Data* aafd) +{ + aafObject* Header = aafd->Header.obj; + + if (Header == NULL) { + error ("Missing Header Object."); + return -1; + } + + int16_t* ByteOrder = aaf_get_propertyValue (Header, PID_Header_ByteOrder, &AAFTypeID_Int16); + + if (ByteOrder == NULL) { + warning ("Missing Header::ByteOrder."); + } + + aafd->Header.ByteOrder = *ByteOrder; + + aafTimeStamp_t* LastModified = aaf_get_propertyValue (Header, PID_Header_LastModified, &AAFTypeID_TimeStamp); + + if (LastModified == NULL) { + warning ("Missing Header::LastModified."); + } + + aafd->Header.LastModified = LastModified; + + aafVersionType_t* Version = aaf_get_propertyValue (Header, PID_Header_Version, &AAFTypeID_VersionType); + + if (Version == NULL) { + warning ("Missing Header::Version."); + } + + aafd->Header.Version = Version; + + uint32_t* ObjectModelVersion = aaf_get_propertyValue (Header, PID_Header_ObjectModelVersion, &AAFTypeID_UInt32); + + if (ObjectModelVersion == NULL) { + warning ("Missing Header::ObjectModelVersion."); + } + + aafd->Header.ObjectModelVersion = *ObjectModelVersion; + + const aafUID_t* OperationalPattern = aaf_get_propertyValue (Header, PID_Header_OperationalPattern, &AAFTypeID_AUID); + + if (OperationalPattern == NULL) { + warning ("Missing Header::OperationalPattern."); + OperationalPattern = (const aafUID_t*)&AUID_NULL; + } + + aafd->Header.OperationalPattern = OperationalPattern; + + return 0; +} + +static int +parse_Identification (AAF_Data* aafd) +{ + aafObject* Identif = aafd->Identification.obj; + + if (Identif == NULL) { + error ("Missing Identification Object."); + return -1; + } + + wchar_t* Company = aaf_get_propertyValue (Identif, PID_Identification_CompanyName, &AAFTypeID_String); + + if (Company == NULL) { + warning ("Missing Identification::CompanyName."); + } + + aafd->Identification.CompanyName = Company; + + wchar_t* ProductName = aaf_get_propertyValue (Identif, PID_Identification_ProductName, &AAFTypeID_String); + + if (ProductName == NULL) { + warning ("Missing Identification::ProductName."); + } + + aafd->Identification.ProductName = ProductName; + + aafProductVersion_t* ProductVersion = aaf_get_propertyValue (Identif, PID_Identification_ProductVersion, &AAFTypeID_ProductVersion); + + if (ProductVersion == NULL) { + warning ("Missing Identification::ProductVersion."); + } + + aafd->Identification.ProductVersion = ProductVersion; + + wchar_t* ProductVersionString = aaf_get_propertyValue (Identif, PID_Identification_ProductVersionString, &AAFTypeID_String); + + if (ProductVersionString == NULL) { + warning ("Missing Identification::ProductVersionString."); + } + + aafd->Identification.ProductVersionString = ProductVersionString; + + aafUID_t* ProductID = aaf_get_propertyValue (Identif, PID_Identification_ProductID, &AAFTypeID_AUID); + + if (ProductID == NULL) { + warning ("Missing Identification::ProductID."); + } + + aafd->Identification.ProductID = ProductID; + + aafTimeStamp_t* Date = aaf_get_propertyValue (Identif, PID_Identification_Date, &AAFTypeID_TimeStamp); + + if (Date == NULL) { + warning ("Missing Identification::Date."); + } + + aafd->Identification.Date = Date; + + aafProductVersion_t* ToolkitVersion = aaf_get_propertyValue (Identif, PID_Identification_ToolkitVersion, &AAFTypeID_ProductVersion); + + if (ToolkitVersion == NULL) { + warning ("Missing Identification::ToolkitVersion."); + } + + aafd->Identification.ToolkitVersion = ToolkitVersion; + + wchar_t* Platform = aaf_get_propertyValue (Identif, PID_Identification_Platform, &AAFTypeID_String); + + if (Platform == NULL) { + warning ("Missing Identification::Platform."); + } + + aafd->Identification.Platform = Platform; + + aafUID_t* GenerationAUID = aaf_get_propertyValue (Identif, PID_Identification_GenerationAUID, &AAFTypeID_AUID); + + if (GenerationAUID == NULL) { + warning ("Missing Identification::GenerationAUID."); + } + + aafd->Identification.GenerationAUID = GenerationAUID; + + return 0; +} + +// static int isValidAAF( AAF_Data *aafd ) +// { +// aafUID_t *hdrClsID = (aafUID_t*)&aafd->cfbd->hdr->_clsid; +// +// if ( aafUIDCmp( hdrClsID, &AAFFileKind_Aaf512Binary ) || +// aafUIDCmp( hdrClsID, &AAFFileKind_Aaf4KBinary ) ) +// return 1; +// +// // warning( "Unsuported AAF encoding (%ls).", aaft_FileKindToText( hdrClsID ) ); +// +// return 0; +// } + +static void +setObjectShortcuts (AAF_Data* aafd) +{ + // aafd->Root = aafd->Root; + + aafd->Header.obj = aaf_get_propertyValue (aafd->Root, PID_Root_Header, &AAFUID_NULL); + // aafd->MetaDictionary = aaf_get_propertyValue( aafd->Root, PID_Root_MetaDictionary ); + + aafd->ClassDefinition = aaf_get_propertyValue (aafd->MetaDictionary, PID_MetaDictionary_ClassDefinitions, &AAFTypeID_ClassDefinitionStrongReferenceSet); + aafd->TypeDefinition = aaf_get_propertyValue (aafd->MetaDictionary, PID_MetaDictionary_TypeDefinitions, &AAFTypeID_TypeDefinitionStrongReferenceSet); + + aafd->Identification.obj = aaf_get_propertyValue (aafd->Header.obj, PID_Header_IdentificationList, &AAFTypeID_IdentificationStrongReferenceVector); + aafd->Content = aaf_get_propertyValue (aafd->Header.obj, PID_Header_Content, &AAFTypeID_ContentStorageStrongReference); + aafd->Dictionary = aaf_get_propertyValue (aafd->Header.obj, PID_Header_Dictionary, &AAFTypeID_DictionaryStrongReference); + + aafd->Mobs = aaf_get_propertyValue (aafd->Content, PID_ContentStorage_Mobs, &AAFTypeID_MobStrongReferenceSet); + aafd->EssenceData = aaf_get_propertyValue (aafd->Content, PID_ContentStorage_EssenceData, &AAFTypeID_EssenceDataStrongReferenceSet); + + aafd->OperationDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_OperationDefinitions, &AAFTypeID_OperationDefinitionStrongReferenceSet); + aafd->ParameterDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_ParameterDefinitions, &AAFTypeID_ParameterDefinitionStrongReferenceSet); + aafd->DataDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_DataDefinitions, &AAFTypeID_DataDefinitionStrongReferenceSet); + aafd->PluginDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_PluginDefinitions, &AAFTypeID_PluginDefinitionStrongReferenceSet); + aafd->CodecDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_CodecDefinitions, &AAFTypeID_CodecDefinitionStrongReferenceSet); + aafd->ContainerDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_ContainerDefinitions, &AAFTypeID_ContainerDefinitionStrongReferenceSet); + aafd->InterpolationDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_InterpolationDefinitions, &AAFTypeID_InterpolationDefinitionStrongReferenceSet); + aafd->KLVDataDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_KLVDataDefinitions, &AAFTypeID_KLVDataDefinitionStrongReferenceSet); + aafd->TaggedValueDefinition = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_TaggedValueDefinitions, &AAFTypeID_TaggedValueDefinitionStrongReferenceSet); +} + +static int +retrieveObjectTree (AAF_Data* aafd) +{ + int rc = 0; + aafByte_t* propStream = NULL; + + cfbNode* Node = &aafd->cfbd->nodes[0]; + + aafClass* Class = aafclass_getClassByID (aafd, (aafUID_t*)&Node->_clsId); + + if (Class == NULL && aafUIDCmp (Class->ID, (aafUID_t*)&Node->_clsId) != 0) { + error ("Looks like the fist Object is not the Root Class : %ls.", aaft_ClassIDToText (aafd, Class->ID)); + goto err; + } + + aafd->Root = newObject (aafd, Node, Class, NULL); + + if (aafd->Root == NULL) { + goto err; + } + + /* retrieveObjectProperties() */ + + propStream = getNodeProperties (aafd, aafd->Root->Node); + + if (propStream == NULL) { + error ("Could not retrieve properties for %ls.", aaf_get_ObjectPath (aafd->Root)); + goto err; + } + + aafPropertyIndexHeader_t Header; + aafPropertyIndexEntry_t Prop; + + aafPropertyIndexEntry_t AAFHeaderProp; + aafPropertyIndexEntry_t AAFMetaDcProp; + + memcpy (&Header, propStream, sizeof (aafPropertyIndexHeader_t)); + + aafByte_t* AAFHeaderVal = NULL; + aafByte_t* AAFMetaDcVal = NULL; + + aafByte_t* value = NULL; + + aafPropertyDef* PDef = NULL; + + uint32_t i = 0; + int valueOffset = 0; + + foreachPropertyEntry (propStream, Header, Prop, value, valueOffset, i) + { + if (Prop._pid == PID_Root_Header) { + memcpy (&AAFHeaderProp, &Prop, sizeof (aafPropertyIndexEntry_t)); + AAFHeaderVal = value; + } + + if (Prop._pid == PID_Root_MetaDictionary) { + memcpy (&AAFMetaDcProp, &Prop, sizeof (aafPropertyIndexEntry_t)); + AAFMetaDcVal = value; + } + } + + PDef = aafclass_getPropertyDefinitionByID (aafd->Root->Class, PID_Root_MetaDictionary); + + /* Start recursive parsing of /Root/Header/{*} */ + + rc = retrieveProperty (aafd, aafd->Root, PDef, &AAFMetaDcProp, AAFMetaDcVal, Header._byteOrder); + + if (rc < 0) { + error ("Could not retrieve property %ls.", aaft_PIDToText (aafd, PDef->pid)); + goto err; + } + + /* + * Retrieve MetaDictionary. + */ + + aafObject* MetaDic = aaf_get_propertyValue (aafd->Root, PID_Root_MetaDictionary, &AAFUID_NULL); + + if (MetaDic == NULL) { + error ("Missing PID_Root_MetaDictionary."); + goto err; + } + + aafObject* ClassDefs = aaf_get_propertyValue (MetaDic, PID_MetaDictionary_ClassDefinitions, &AAFTypeID_ClassDefinitionStrongReferenceSet); + + if (ClassDefs == NULL) { + error ("Missing PID_MetaDictionary_ClassDefinitions."); + goto err; + } + + aafObject* ClassDef = NULL; + + aaf_foreach_ObjectInSet (&ClassDef, ClassDefs, NULL) + { + retrieveMetaDictionaryClass (aafd, ClassDef); + } + + PDef = aafclass_getPropertyDefinitionByID (aafd->Root->Class, PID_Root_Header); + + /* Starts recursive parsing of /Root/Header/{*} */ + + rc = retrieveProperty (aafd, aafd->Root, PDef, &AAFHeaderProp, AAFHeaderVal, Header._byteOrder); + + if (rc < 0) { + error ("Could not retrieve property %ls.", aaft_PIDToText (aafd, PDef->pid)); + goto err; + } + + setObjectShortcuts (aafd); + + rc = 0; + goto end; + +err: + rc = -1; + +end: + + if (propStream) + free (propStream); + + return rc; +} + +static aafClass* +retrieveMetaDictionaryClass (AAF_Data* aafd, aafObject* TargetClassDef) +{ + aafObject* MetaDic = aaf_get_propertyValue (aafd->Root, PID_Root_MetaDictionary, &AAFUID_NULL); + + aafObject* ClassDefs = aaf_get_propertyValue (MetaDic, PID_MetaDictionary_ClassDefinitions, &AAFTypeID_ClassDefinitionStrongReferenceSet); + aafObject* ClassDef = NULL; + + if (ClassDefs == NULL) { + error ("Could not retrieve PID_MetaDictionary_ClassDefinitions property from MetaDic."); + return NULL; + } + + aaf_foreach_ObjectInSet (&ClassDef, ClassDefs, NULL) + { + if (ClassDef == TargetClassDef) + break; + } + + if (ClassDef == NULL) { + error ("Could not retrieve ClassDefinition %p.", (void*)TargetClassDef); + return NULL; + } + + aafUID_t* ClassID = aaf_get_propertyValue (ClassDef, PID_MetaDefinition_Identification, &AAFTypeID_AUID); + + aafWeakRef_t* parent = aaf_get_propertyValue (ClassDef, PID_ClassDefinition_ParentClass, &AAFTypeID_ClassDefinitionWeakReference); + aafObject* Parent = aaf_get_ObjectByWeakRef (ClassDefs, parent); + + aafClass* ParentClass = NULL; + + if (Parent != ClassDef) { + ParentClass = retrieveMetaDictionaryClass (aafd, Parent); + } else if (aafUIDCmp (ClassID, &AAFClassID_InterchangeObject) == 0 && + aafUIDCmp (ClassID, &AAFClassID_MetaDefinition) == 0 && + aafUIDCmp (ClassID, &AAFClassID_MetaDictionary) == 0) { + /* + * TODO: what is this ? when does it happen ? + */ + error ("Parent's Class equals Child's : %ls.", aaft_ClassIDToText (aafd, ClassID)); + return NULL; + } + + aafClass* Class = aafclass_getClassByID (aafd, ClassID); + + if (Class == NULL) { + aafBoolean_t* isCon = aaf_get_propertyValue (ClassDef, PID_ClassDefinition_IsConcrete, &AAFTypeID_Boolean); + + if (isCon == NULL) { + error ("Missing ClassDefinition::IsConcrete."); + return NULL; + } + + Class = aafclass_defineNewClass (aafd, ClassID, *isCon, ParentClass); + + Class->name = aaf_get_propertyValue (ClassDef, PID_MetaDefinition_Name, &AAFTypeID_String); + Class->meta = 1; + } else { // if class is standard, we only set its name + if (Class->name == NULL) { + Class->name = aaf_get_propertyValue (ClassDef, PID_MetaDefinition_Name, &AAFTypeID_String); + } + } + + aafObject* Props = aaf_get_propertyValue (ClassDef, PID_ClassDefinition_Properties, &AAFTypeID_PropertyDefinitionStrongReferenceSet); + aafObject* Prop = NULL; + + aaf_foreach_ObjectInSet (&Prop, Props, NULL) + { + aafPID_t* Pid = aaf_get_propertyValue (Prop, PID_PropertyDefinition_LocalIdentification, &AAFTypeID_UInt16); + + if (Pid == NULL) { + error ("Missing PropertyDefinition::LocalIdentification."); + return NULL; + } + + aafBoolean_t* isOpt = aaf_get_propertyValue (Prop, PID_PropertyDefinition_IsOptional, &AAFTypeID_Boolean); + + if (isOpt == NULL) { + error ("Missing PropertyDefinition::IsOptional."); + return NULL; + } + + /* + * We skip all the properties that were already defined in aafclass_setDefaultClasses(). + */ + + aafPropertyDef* PDef = NULL; + + if (!(PDef = propertyIdExistsInClass (Class, *Pid))) { + attachNewProperty (Class, PDef, *Pid, (*isOpt) ? 0 : 1); + PDef->meta = 1; + } else { + // debug( "Property %d exists.", *Pid ); + continue; + } + + PDef->name = aaf_get_propertyValue (Prop, PID_MetaDefinition_Name, &AAFTypeID_String); + + aafObject* TypeDefs = aaf_get_propertyValue (MetaDic, PID_MetaDictionary_TypeDefinitions, &AAFTypeID_TypeDefinitionStrongReferenceSet); + + if (TypeDefs == NULL) { + error ("Missing TypeDefinitions from MetaDictionary"); + return NULL; + } + + aafWeakRef_t* WeakRefToType = aaf_get_propertyValue (Prop, PID_PropertyDefinition_Type, &AAFTypeID_PropertyDefinitionWeakReference); + + if (WeakRefToType == NULL) { + error ("Missing PID_PropertyDefinition_Type"); + return NULL; + } + + aafObject* TypeDef = aaf_get_ObjectByWeakRef (TypeDefs, WeakRefToType); + + if (TypeDef == NULL) { + error ("Could not retrieve TypeDefinition from dictionary."); + return NULL; + } + + aafUID_t* typeUID = aaf_get_propertyValue (TypeDef, PID_MetaDefinition_Identification, &AAFTypeID_AUID); + + if (typeUID == NULL) { + error ("Missing PID_MetaDefinition_Identification"); + return NULL; + } + + /* + * Looks like nobody cares about AAF standard TypeDefinition. All observed files + * had incorrect values for Type Name and Identification, even Avid's files. So... + */ + + memcpy (&PDef->type, typeUID, sizeof (aafUID_t)); + + // wchar_t *typeName = aaf_get_propertyValue( TypeDef, PID_MetaDefinition_Name, &AAFTypeID_String ); + // + // debug( "TypeName : %ls (%ls) | name : %ls.", + // // AUIDToText(typeUID), + // typeName, + // aaft_TypeIDToText( typeUID ), + // PDef->name ); + // + // free( typeName ); + } + + return Class; +} + +static aafObject* +newObject (AAF_Data* aafd, cfbNode* Node, aafClass* Class, aafObject* Parent) +{ + aafObject* Obj = calloc (sizeof (aafObject), sizeof (unsigned char)); + + if (Obj == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + cfb_w16towchar (Obj->Name, Node->_ab, Node->_cb); + + Obj->aafd = aafd; + Obj->Class = Class; + Obj->Node = Node; + Obj->Properties = NULL; + Obj->Parent = Parent; + Obj->Header = NULL; + Obj->Entry = NULL; + + Obj->next = NULL; + Obj->prev = NULL; + Obj->nextObj = aafd->Objects; + aafd->Objects = Obj; + + return Obj; +} + +static aafProperty* +newProperty (AAF_Data* aafd, aafPropertyDef* Def) +{ + aafProperty* Prop = calloc (sizeof (aafProperty), sizeof (unsigned char)); + + if (Prop == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + Prop->pid = Def->pid; + Prop->def = Def; + + return Prop; +} + +static aafPropertyDef* +propertyIdExistsInClass (aafClass* Class, aafPID_t Pid) +{ + aafPropertyDef* PDef = NULL; + + foreachPropertyDefinition (PDef, Class->Properties) if (PDef->pid == Pid) return PDef; + + return NULL; +} + +static int +setObjectStrongRefSet (aafObject* Obj, aafStrongRefSetHeader_t* Header, aafStrongRefSetEntry_t* Entry) +{ + AAF_Data* aafd = Obj->aafd; + + Obj->Header = malloc (sizeof (aafStrongRefSetHeader_t)); + + if (Obj->Header == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + memcpy (Obj->Header, Header, sizeof (aafStrongRefSetHeader_t)); + + /* Real entrySize, taking _identification into account. */ + uint32_t entrySize = sizeof (aafStrongRefSetEntry_t) + Header->_identificationSize; + + Obj->Entry = malloc (entrySize); + + if (Obj->Entry == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + memcpy (Obj->Entry, Entry, entrySize); + + return 0; +} + +static int +setObjectStrongRefVector (aafObject* Obj, aafStrongRefVectorHeader_t* Header, aafStrongRefVectorEntry_t* Entry) +{ + /* + * aafStrongRefVectorHeader_t and aafStrongRefSetHeader_t begins with the same + * data bytes, so we can safely memcpy to the first one from the second one, + * the remaining bytes simply remaining null. + * The same applies to aafStrongRefVectorEntry_t and aafStrongRefVectorHeader_t. + */ + + AAF_Data* aafd = Obj->aafd; + + Obj->Header = calloc (sizeof (aafStrongRefSetHeader_t), sizeof (unsigned char)); + + if (Obj->Header == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + memcpy (Obj->Header, Header, sizeof (aafStrongRefVectorHeader_t)); + + Obj->Entry = calloc (sizeof (aafStrongRefSetEntry_t), sizeof (unsigned char)); + + if (Obj->Entry == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + memcpy (Obj->Entry, Entry, sizeof (aafStrongRefVectorEntry_t)); + + return 0; +} + +static int +retrieveStrongReference (AAF_Data* aafd, aafProperty* Prop, aafObject* Parent) +{ + /* + * Initial property value is a wchar string holding the name of a child node. + * This child node being the object referenced, we store that object dirctly + * as the property value, instead of the initial child node name. + */ + + wchar_t name[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (name, Prop->val, Prop->len); + + free (Prop->val); + Prop->val = NULL; + + cfbNode* Node = cfb_getChildNode (aafd->cfbd, name, Parent->Node); + + if (Node == NULL) { + error ("Could not find child node."); + return -1; + } + + aafClass* Class = aafclass_getClassByID (aafd, (aafUID_t*)&Node->_clsId); + + if (Class == NULL) { + error ("Could not retrieve Class %ls @ \"%ls\".", aaft_ClassIDToText (aafd, (aafUID_t*)&Node->_clsId), aaf_get_ObjectPath (Parent)); + return -1; + } + + Prop->val = newObject (aafd, Node, Class, Parent); + + if (Prop->val == NULL) { + return -1; + } + + int rc = retrieveObjectProperties (aafd, Prop->val); + + if (rc < 0) { + return -1; + } + + return 0; +} + +static int +retrieveStrongReferenceSet (AAF_Data* aafd, aafProperty* Prop, aafObject* Parent) +{ + aafStrongRefSetHeader_t* Header = NULL; + aafStrongRefSetEntry_t* Entry = NULL; + + wchar_t refName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (refName, Prop->val, Prop->len); + + free (Prop->val); + Prop->val = NULL; + + cfbNode* Node = getStrongRefIndexNode (aafd, Parent, refName); + + if (Node == NULL) { + error ("Could not retrieve StrongReferenceSet's Index node."); + goto err; + } + + Header = getStrongRefSetList (aafd, Node, Parent); + + if (Header == NULL) { + error ("Could not retrieve StrongReferenceSet's CFB Stream."); + goto err; + } + + Entry = malloc (sizeof (aafStrongRefSetEntry_t) + Header->_identificationSize); + + if (Entry == NULL) { + error ("%s.", strerror (errno)); + goto err; + } + + memset (Entry, 0x00, sizeof (aafStrongRefSetEntry_t)); + + uint32_t i = 0; + int rc = 0; + + foreachStrongRefSetEntry (Header, (*Entry), i) + { + Node = getStrongRefEntryNode (aafd, Parent, refName, Entry->_localKey); + + if (Node == NULL) { + continue; + } + + aafClass* Class = aafclass_getClassByID (aafd, (aafUID_t*)&Node->_clsId); + + if (Class == NULL) { + error ("Could not retrieve Class %ls.", aaft_ClassIDToText (aafd, (aafUID_t*)&Node->_clsId)); + continue; + } + + aafObject* Obj = newObject (aafd, Node, Class, Parent); + + if (Obj == NULL) { + goto err; + } + + rc = setObjectStrongRefSet (Obj, Header, Entry); + + if (rc < 0) { + goto err; + } + + rc = retrieveObjectProperties (aafd, Obj); + + if (rc < 0) { + goto err; + } + + Obj->next = Prop->val; + Prop->val = Obj; + } + + rc = 0; + goto end; + +err: + rc = -1; + +end: + + if (Header) + free (Header); + + if (Entry) + free (Entry); + + return rc; +} + +static int +retrieveStrongReferenceVector (AAF_Data* aafd, aafProperty* Prop, aafObject* Parent) +{ + int rc = 0; + aafByte_t* vectorStream = NULL; + + wchar_t refName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (refName, Prop->val, Prop->len); + + free (Prop->val); + Prop->val = NULL; + + cfbNode* Node = getStrongRefIndexNode (aafd, Parent, refName); + + if (Node == NULL) { + goto err; + } + + vectorStream = getStrongRefVectorList (aafd, Node, Parent); + + if (vectorStream == NULL) { + error ("Could not retrieve StrongRefVectorList"); + goto err; + } + + aafStrongRefVectorHeader_t Header; + aafStrongRefVectorEntry_t Entry; + + memcpy (&Header, vectorStream, sizeof (aafStrongRefVectorHeader_t)); + + uint32_t i = 0; + + foreachStrongRefVectorEntry (vectorStream, Header, Entry, i) + { + Node = getStrongRefEntryNode (aafd, Parent, refName, Entry._localKey); + + if (Node == NULL) { + continue; + } + + aafClass* Class = aafclass_getClassByID (aafd, (aafUID_t*)&Node->_clsId); + + if (Class == NULL) { + warning ("Could not retrieve Class ID %ls.", aaft_ClassIDToText (aafd, (aafUID_t*)&Node->_clsId)); + continue; + } + + aafObject* Obj = newObject (aafd, Node, Class, Parent); + + if (Obj == NULL) { + goto err; + } + + rc = setObjectStrongRefVector (Obj, &Header, &Entry); + + if (rc < 0) { + goto err; + } + + rc = retrieveObjectProperties (aafd, Obj); + + if (rc < 0) { + goto err; + } + + /* + * Vectors are ordered. + */ + + if (Prop->val != NULL) { + aafObject* tmp = Prop->val; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + Obj->prev = tmp; + tmp->next = Obj; + } else { + Obj->prev = NULL; + Prop->val = Obj; + } + } + + rc = 0; + goto end; + +err: + rc = -1; + +end: + + if (vectorStream) + free (vectorStream); + + return rc; +} + +static int +retrieveProperty (AAF_Data* aafd, aafObject* Obj, aafPropertyDef* Def, aafPropertyIndexEntry_t* p, aafByte_t* v, uint8_t bo) +{ + (void)bo; // TODO: ByteOrder support ? + + aafProperty* Prop = newProperty (aafd, Def); + + if (Prop == NULL) { + return -1; + } + + Prop->sf = p->_storedForm; + + /* + TODO Prop->len / Prop->val ---> retrieveStrongReference() retrieveStrongReferenceSet() retrieveStrongReferenceVector() + only used to retrieve node name ? There could be a better approach. + */ + + Prop->len = p->_length; + + Prop->val = malloc (p->_length); + + if (Prop->val == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + memcpy (Prop->val, v, p->_length); + + Prop->next = Obj->Properties; + Obj->Properties = Prop; + + switch (p->_storedForm) { + case SF_STRONG_OBJECT_REFERENCE: + return retrieveStrongReference (aafd, Prop, Obj); + + case SF_STRONG_OBJECT_REFERENCE_SET: + return retrieveStrongReferenceSet (aafd, Prop, Obj); + + case SF_STRONG_OBJECT_REFERENCE_VECTOR: + return retrieveStrongReferenceVector (aafd, Prop, Obj); + + default: + break; + } + + return 0; +} + +static int +retrieveObjectProperties (AAF_Data* aafd, aafObject* Obj) +{ + int rc = 0; + + aafByte_t* propStream = getNodeProperties (aafd, Obj->Node); + + if (propStream == NULL) { + error ("Could not retrieve object %ls properties : %ls", aaft_ClassIDToText (aafd, Obj->Class->ID), aaf_get_ObjectPath (Obj)); + goto err; + } + + aafPropertyIndexHeader_t Header; + aafPropertyIndexEntry_t Prop; + + memcpy (&Header, propStream, sizeof (aafPropertyIndexHeader_t)); + + aafByte_t* value = NULL; + aafPropertyDef* PDef = NULL; + + int valueOffset = 0; + + uint32_t i = 0; + + foreachPropertyEntry (propStream, Header, Prop, value, valueOffset, i) + { + PDef = aafclass_getPropertyDefinitionByID (Obj->Class, Prop._pid); + + if (PDef == NULL) { + warning ("Unknown property 0x%04x (%ls) of object %ls", Prop._pid, aaft_PIDToText (aafd, Prop._pid), aaft_ClassIDToText (aafd, Obj->Class->ID)); + continue; + } + + rc = retrieveProperty (aafd, Obj, PDef, &Prop, value, Header._byteOrder); + + if (rc < 0) { + error ("Could not retrieve property %ls of object %ls", aaft_PIDToText (aafd, PDef->pid), aaft_ClassIDToText (aafd, Obj->Class->ID)); + goto err; + } + } + + rc = 0; + goto end; + +err: + rc = -1; + +end: + + if (propStream) + free (propStream); + + return rc; +} + +static cfbNode* +getStrongRefIndexNode (AAF_Data* aafd, aafObject* Parent, const wchar_t* refName) +{ + wchar_t name[CFB_NODE_NAME_SZ]; + + swprintf (name, CFB_NODE_NAME_SZ, L"%" WPRIws L" index", refName); + + cfbNode* Node = cfb_getChildNode (aafd->cfbd, name, Parent->Node); + + if (Node == NULL) { + error ("Could not retrieve Reference Set/Vector Index Node @ \"%ls/%ls index\"", aaf_get_ObjectPath (Parent), refName); + return NULL; + } + + return Node; +} + +static cfbNode* +getStrongRefEntryNode (AAF_Data* aafd, aafObject* Parent, const wchar_t* refName, uint16_t index) +{ + wchar_t name[CFB_NODE_NAME_SZ]; + + swprintf (name, CFB_NODE_NAME_SZ, L"%" WPRIws L"{%x}", refName, index); + + cfbNode* Node = cfb_getChildNode (aafd->cfbd, name, Parent->Node); + + if (Node == NULL) { + error ("Could not retrieve Reference Set/vector Entry Node @ \"%ls/%ls index\"", aaf_get_ObjectPath (Parent), refName); + return NULL; + } + + return Node; +} + +static aafByte_t* +getNodeProperties (AAF_Data* aafd, cfbNode* Node) +{ + if (Node == NULL) { + error ("Node is NULL"); + return NULL; + } + + uint64_t stream_sz = 0; + aafByte_t* stream = NULL; + + cfbNode* propNode = cfb_getChildNode (aafd->cfbd, L"properties", Node); + + if (propNode == NULL) { + error ("Could not retrieve Property Node"); + return NULL; + } + + cfb_getStream (aafd->cfbd, propNode, &stream, &stream_sz); + + if (stream == NULL) { + error ("Could not retrieve Property Stream"); + return NULL; + } + + /* + * Ensures PropHeader + all PropEntries + all PropValues matches the Stream size. + * TODO : is the following test important ? + */ + + /* + uint32_t prop_sz = sizeof(aafPropertyIndexHeader_t); + + uint32_t i = 0; + + for ( i = 0; i < ((aafPropertyIndexHeader_t*)stream)->_entryCount; i++ ) + prop_sz += (((aafPropertyIndexEntry_t*)(stream+((sizeof(aafPropertyIndexEntry_t)*i)+sizeof(aafPropertyIndexHeader_t))))->_length) + sizeof(aafPropertyIndexEntry_t); + + if ( prop_sz != stream_sz ) + warning( "Stream length (%lu Bytes) does not match property length (%u Bytes).", + stream_sz, + prop_sz ); +*/ + + return stream; +} + +static aafStrongRefSetHeader_t* +getStrongRefSetList (AAF_Data* aafd, cfbNode* Node, aafObject* Parent) +{ + if (Node == NULL) + return NULL; + + aafByte_t* stream = NULL; + uint64_t stream_sz = 0; + + cfb_getStream (aafd->cfbd, Node, &stream, &stream_sz); + + if (stream == NULL) { + wchar_t refName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (refName, Node->_ab, Node->_cb); + + error ("Could not retrieve StrongReferenceSet Index Stream @ \"%ls/%ls index\"", aaf_get_ObjectPath (Parent), refName); + + return NULL; + } + + return (aafStrongRefSetHeader_t*)stream; +} + +static aafByte_t* +getStrongRefVectorList (AAF_Data* aafd, cfbNode* Node, aafObject* Parent) +{ + if (Node == NULL) + return NULL; + + aafByte_t* stream = NULL; + uint64_t stream_sz = 0; + + cfb_getStream (aafd->cfbd, Node, &stream, &stream_sz); + + if (stream == NULL) { + wchar_t refName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (refName, Node->_ab, Node->_cb); + + error ("Could not retrieve StrongReferenceVector Index Stream \"%ls/%ls index\"", aaf_get_ObjectPath (Parent), refName); + return NULL; + } + + return stream; +} diff --git a/libs/aaf/AAFDump.c b/libs/aaf/AAFDump.c new file mode 100644 index 0000000000..a43b067017 --- /dev/null +++ b/libs/aaf/AAFDump.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "aaf/AAFDump.h" +#include "aaf/AAFToText.h" +#include "aaf/AAFTypes.h" + +#include "aaf/AAFClass.h" +#include "aaf/utils.h" + +void +aaf_dump_Header (AAF_Data* aafd) +{ + int offset = 0; + struct dbg* dbg = aafd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ByteOrder : %ls (0x%04x)\n", aaft_ByteOrderToText (aafd->Header.ByteOrder), aafd->Header.ByteOrder); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " LastModified : %ls\n", aaft_TimestampToText (aafd->Header.LastModified)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " AAF ObjSpec Version : %ls\n", aaft_VersionToText (aafd->Header.Version)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ObjectModel Version : %u\n", aafd->Header.ObjectModelVersion); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Operational Pattern : %ls\n", aaft_OPDefToText (aafd->Header.OperationalPattern)); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} + +void +aaf_dump_Identification (AAF_Data* aafd) +{ + int offset = 0; + struct dbg* dbg = aafd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " CompanyName : %ls\n", (aafd->Identification.CompanyName) ? aafd->Identification.CompanyName : L"n/a"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ProductName : %ls\n", (aafd->Identification.ProductName) ? aafd->Identification.ProductName : L"n/a"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ProductVersion : %ls\n", aaft_ProductVersionToText (aafd->Identification.ProductVersion)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ProductVersionString : %ls\n", (aafd->Identification.ProductVersionString) ? aafd->Identification.ProductVersionString : L"n/a"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ProductID : %ls\n", AUIDToText (aafd->Identification.ProductID)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Date : %ls\n", aaft_TimestampToText (aafd->Identification.Date)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " ToolkitVersion : %ls\n", aaft_ProductVersionToText (aafd->Identification.ToolkitVersion)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Platform : %ls\n", (aafd->Identification.Platform) ? aafd->Identification.Platform : L"n/a"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " GenerationAUID : %ls\n", AUIDToText (aafd->Identification.GenerationAUID)); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} + +void +aaf_dump_ObjectProperty (AAF_Data* aafd, aafProperty* Prop) +{ + int offset = 0; + struct dbg* dbg = aafd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " :.: (0x%04x) %ls (%ls)\n", Prop->pid, aaft_PIDToText (aafd, Prop->pid), aaft_StoredFormToText (Prop->sf) /*AUIDToText( &Prop->def->type ),*/ /*aaft_TypeIDToText( &(Prop->def->type) )*/); + + // WARNING : Wont print strong references (set/vector) corectly. + offset += laaf_util_dump_hex (Prop->val, Prop->len, &aafd->dbg->_dbg_msg, &aafd->dbg->_dbg_msg_size, offset); + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} + +void +aaf_dump_ObjectProperties (AAF_Data* aafd, aafObject* Obj) +{ + /* + * List the properties once they have been parsed and interpreted by AAFCore. + */ + + // int offset = 0; + // struct dbg *dbg = aafd->dbg; + + aafProperty* Prop = NULL; + + for (Prop = Obj->Properties; Prop != NULL; Prop = Prop->next) { + aaf_dump_ObjectProperty (aafd, Prop); + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " :.: (0x%04x) %ls (%ls)\n", Prop->pid, aaft_PIDToText( aafd, Prop->pid ), aaft_StoredFormToText( Prop->sf ) /*AUIDToText( &Prop->def->type ),*/ /*aaft_TypeIDToText( &(Prop->def->type) )*/ ); + // + // // WARNING : Wont print strong references (set/vector) corectly. + // laaf_util_dump_hex( Prop->val, Prop->len ); + } +} + +void +aaf_dump_rawProperties (AAF_Data* aafd, aafByte_t* propStream) +{ + int offset = 0; + struct dbg* dbg = aafd->dbg; + + if (propStream == NULL) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, + " ## Property_Header____________________________________________________\n\n" + " aafPropertyIndexHeader_t is NULL\n" + " ======================================================================\n\n"); + return; + } + + aafPropertyIndexHeader_t Header; + aafPropertyIndexEntry_t Prop; + aafByte_t* value = NULL; + + memcpy (&Header, propStream, sizeof (aafPropertyIndexHeader_t)); + + uint32_t i = 0; + uint32_t valueOffset = 0; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, + " ## Property_Header____________________________________________________\n\n" + " _byteOrder : 0x%02x\n" + " _formatVersion : 0x%02x\n" + " _entryCount : %u\n\n" + " ======================================================================\n\n", + Header._byteOrder, + Header._formatVersion, + Header._entryCount); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + /* + * Since the following for-loop macro is not intended to be user + * accessible, it has been defined as a local macro in AAFCore.c. + */ + + // foreachPropertyEntry( Header, Prop, value, i ) + for (valueOffset = sizeof (aafPropertyIndexHeader_t) + (Header._entryCount * sizeof (aafPropertyIndexEntry_t)), + i = 0; + i < Header._entryCount && + memcpy (&Prop, (propStream + ((sizeof (aafPropertyIndexHeader_t)) + (sizeof (aafPropertyIndexEntry_t) * i))), sizeof (aafPropertyIndexEntry_t)) && + (value = propStream + valueOffset); + valueOffset += Prop._length, + i++) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, + " #%u Property_Entry_____________________________________________________\n" + " _pid : 0x%04x (%ls)\n" + " _storedForm : %ls\n" + " _length : %u bytes\n", + i, + Prop._pid, aaft_PIDToText (aafd, Prop._pid), + aaft_StoredFormToText (Prop._storedForm), + Prop._length); + + offset += laaf_util_dump_hex (value, Prop._length, &aafd->dbg->_dbg_msg, &aafd->dbg->_dbg_msg_size, offset); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + } + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} + +void +aaf_dump_nodeStreamProperties (AAF_Data* aafd, cfbNode* node) +{ + /* + * List the raw properties directly from a CFB Node's stream. + */ + + aafByte_t* propStream = NULL; + + cfb_getStream (aafd->cfbd, node, &propStream, NULL); + + aaf_dump_rawProperties (aafd, propStream); + + free (propStream); +} + +void +aaf_dump_MetaDictionary (AAF_Data* aafd) +{ + /* + * NOTE Only dumps the "custom" classes/properties, since those are the only + * ones we register when parsing. That is, all standard classes/properties + * wont be printed out. + */ + + int offset = 0; + struct dbg* dbg = aafd->dbg; + + aafClass* Class = NULL; + + foreachClass (Class, aafd->Classes) + { + int print = 0; + + aafPropertyDef* PDef = NULL; + + foreachPropertyDefinition (PDef, Class->Properties) + { + if (Class->meta) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, ANSI_COLOR_YELLOW "%ls::%ls (0x%04x)\n" ANSI_COLOR_RESET, + Class->name, + PDef->name, + PDef->pid); + + print++; + } else if (PDef->meta) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls::" ANSI_COLOR_YELLOW "%ls (0x%04x)\n" ANSI_COLOR_RESET, + aaft_ClassIDToText (aafd, Class->ID), + PDef->name, + PDef->pid); + + print++; + } + } + + if (print) + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + + print = 1; + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} + +void +aaf_dump_Classes (AAF_Data* aafd) +{ + int offset = 0; + struct dbg* dbg = aafd->dbg; + + aafClass* ConcreteClass = NULL; + aafClass* Class = NULL; + + foreachClass (ConcreteClass, aafd->Classes) + { + foreachClassInheritance (Class, ConcreteClass) + { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s%ls%s", + (Class->meta) ? ANSI_COLOR_YELLOW : "", + aaft_ClassIDToText (aafd, Class->ID), + (Class->meta) ? ANSI_COLOR_RESET : ""); + + if (Class->Parent != NULL) + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " > "); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + dbg->debug_callback (dbg, (void*)aafd, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); +} diff --git a/libs/aaf/AAFIAudioFiles.c b/libs/aaf/AAFIAudioFiles.c new file mode 100644 index 0000000000..0504e7b36a --- /dev/null +++ b/libs/aaf/AAFIAudioFiles.c @@ -0,0 +1,553 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "aaf/AAFIAudioFiles.h" +#include "aaf/AAFIface.h" +#include "aaf/debug.h" + +#include "aaf/RIFFParser.h" +#include "aaf/URIParser.h" + +#include "aaf/utils.h" + +#if defined(__linux__) +#include +#include +#include +#include /* access() */ +#elif defined(__APPLE__) +#include +#include /* access() */ +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#include +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define F_OK 0 /* Test for existence. */ +#ifndef _MSC_VER +#include // access() +#endif +#endif + +#define WAV_FILE_EXT "wav" +#define AIFF_FILE_EXT "aif" + +#define debug(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +static size_t +embeddedAudioDataReaderCallback (unsigned char* buf, size_t offset, size_t reqLen, void* user1, void* user2, void* user3); +static size_t +externalAudioDataReaderCallback (unsigned char* buf, size_t offset, size_t reqLen, void* user1, void* user2, void* user3); + +char* +aafi_locate_external_essence_file (AAF_Iface* aafi, const wchar_t* original_uri_filepath, const char* search_location) +{ + /* + * Absolute Uniform Resource Locator (URL) complying with RFC 1738 or relative + * Uniform Resource Identifier (URI) complying with RFC 2396 for file containing + * the essence. If it is a relative URI, the base URI is determined from the URI + * of the AAF file itself. + * + * Informative note: A valid URL or URI uses a constrained character set and + * uses the / character as the path separator. + */ + + char* uri_filepath = NULL; + char* local_filepath = NULL; + char* aaf_path = NULL; + char* retpath = NULL; + + struct uri* uri = NULL; + + if (original_uri_filepath == NULL) { + error ("Cant locate a NULL filepath"); + goto err; + } + + size_t uri_filepath_len = wcslen (original_uri_filepath) + 1; + + uri_filepath = malloc (uri_filepath_len); + + if (uri_filepath == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + goto err; + } + + int reqlen = snprintf (uri_filepath, uri_filepath_len, "%ls", original_uri_filepath); + + if (reqlen < 0 || (unsigned)reqlen >= uri_filepath_len) { + error ("Failed converting wide char URI filepath to byte char%s", (reqlen < 0) ? " : encoding error" : ""); + goto err; + } + + // debug( "Original URI filepath : %s", uri_filepath ); + + if (search_location) { + local_filepath = laaf_util_build_path (DIR_SEP_STR, search_location, laaf_util_fop_get_file (uri_filepath), NULL); + + if (local_filepath == NULL) { + error ("Could not build search filepath"); + goto err; + } + + // debug( "Search filepath : %s", fpath ); + + if (access (local_filepath, F_OK) != -1) { + // debug( "FOUND: %s", local_filepath ); + retpath = local_filepath; + goto found; + } + + free (local_filepath); + local_filepath = NULL; + } + + /* Try AAF essence's URI */ + + if (access (uri_filepath, F_OK) != -1) { + // debug( "FOUND: %s", uri_filepath ); + retpath = uri_filepath; + goto found; + } + + /* Try part of URI */ + + uri = uriParse (uri_filepath, URI_OPT_DECODE_ALL, aafi->dbg); + + if (uri == NULL) { + error ("Could not parse URI"); + goto err; + } + + if (uri->path == NULL) { + error ("Could not retrieve out of URI"); + goto err; + } + + // debug( "URI's filepath : %s", uri->path ); + + if (access (uri->path, F_OK) != -1) { + // debug( "FOUND: %s", path ); + retpath = uri->path; + goto found; + } + + if (uri->flags & URI_T_LOCALHOST) { + // debug( "URI targets localhost : %s", uri_filepath ); + } else { + if (uri->flags & URI_T_HOST_IPV4) { + // debug( "URI targets IPV4 : %s", uri_filepath ); + } else if (uri->flags & URI_T_HOST_IPV6) { + // debug( "URI targets IPV6 : %s", uri_filepath ); + } else if (uri->flags & URI_T_HOST_REGNAME) { + // debug( "URI targets hostname : %s", uri_filepath ); + } + } + + /* + * Try to locate essence file from the AAF file location. + * + * e.g. + * - AAF filepath : /home/user/AAFFile.aaf + * - Essence URI : file://localhost/C:/Users/user/Desktop/AudioFiles/essence.wav + * = /home/user/AudioFiles/essence.file + */ + + /* extract relative path to essence file : "/" */ + + char* relativeEssencePath = NULL; + char* p = uri->path + strlen (uri->path); + + int sepcount = 0; + + while (p > uri->path) { + if (*p == '/') { /* parsing URI, so will always be '/' as separator character */ + sepcount++; + if (sepcount == 2) { + relativeEssencePath = (p + 1); + break; + } + } + p--; + } + + /* extract path to AAF file */ + + aaf_path = laaf_util_c99strdup (aafi->aafd->cfbd->file); + + if (aaf_path == NULL) { + error ("Could not duplicate AAF filepath"); + goto err; + } + + p = aaf_path + strlen (aaf_path); + + while (p > aaf_path) { + if (IS_DIR_SEP (*p)) { + *p = 0x00; + break; + } + p--; + } + + local_filepath = laaf_util_build_path (DIR_SEP_STR, aaf_path, relativeEssencePath, NULL); + + if (local_filepath == NULL) { + error ("Could not build filepath"); + goto err; + } + + // debug( "AAF relative filepath : %s", local_filepath ); + + if (access (local_filepath, F_OK) != -1) { + // debug( "FOUND: %s", filepath ); + retpath = local_filepath; + goto found; + } + + // debug("File not found"); + +found: + retpath = laaf_util_c99strdup (retpath); + goto end; + +err: + retpath = NULL; + +end: + if (uri) + uriFree (uri); + + if (uri_filepath) + free (uri_filepath); + + if (local_filepath) + free (local_filepath); + + if (aaf_path) + free (aaf_path); + + return retpath; + + /* + * AAFInfo --aaf-clips ../libaaf_testfiles/fonk_2.AAF + file://localhost/Users/horlaprod/Music/Logic/fonk_2/Audio Files_1/fonk_2_3#04.wav + + * AAFInfo --aaf-clips ../libaaf_testfiles/ADP/ADP3_51-ST-MONO-NOBREAKOUT.aaf + file:///C:/Users/Loviniou/Downloads/ChID-BLITS-EBU-Narration441-16b.wav + + * AAFInfo --aaf-clips ../libaaf_testfiles/ADP/ADP2_SEQ-FULL.aaf + file://?/E:/Adrien/ADPAAF/Sequence A Rendu.mxf + + * AAFInfo --aaf-clips ../libaaf_testfiles/TEST-AVID_COMP2977052\ \ -\ \ OFF\ PODIUM\ ETAPE\ 2.aaf + file:////C:/Users/mix_limo/Desktop/TEST2977052 - OFF PODIUM ETAPE 2.aaf + + * AAFInfo --aaf-clips ../ardio/watchfolder/3572607_RUGBY_F_1_1.aaf + file://10.87.230.71/mixage/DR2/Avid MediaFiles/MXF/1/3572607_RUGBY_F2_S65CFA3D0V.mxf + + * AAFInfo --aaf-clips ../libaaf_testfiles/ProTools/pt2MCC.aaf + file:///_system/Users/horlaprod/pt2MCCzmhsFRHQgdgsTMQX.mxf + */ +} + +int +aafi_extract_audio_essence (AAF_Iface* aafi, aafiAudioEssence* audioEssence, const char* outfilepath, const wchar_t* forcedFileName) +{ + int rc = 0; + int reqlen = 0; + FILE* fp = NULL; + char* filename = NULL; + char* filepath = NULL; + + unsigned char* data = NULL; + uint64_t datasz = 0; + + if (audioEssence->is_embedded == 0) { + warning ("Audio essence is not embedded : nothing to extract"); + return -1; + } + + /* Retrieve stream from CFB */ + + cfb_getStream (aafi->aafd->cfbd, audioEssence->node, &data, &datasz); + + if (data == NULL) { + error ("Could not retrieve audio essence stream from CFB"); + goto err; + } + + /* Build file path */ + + reqlen = snprintf (NULL, 0, "%ls.%s", (forcedFileName != NULL) ? forcedFileName : audioEssence->unique_file_name, (audioEssence->type == AAFI_ESSENCE_TYPE_AIFC) ? AIFF_FILE_EXT : WAV_FILE_EXT); + + if (reqlen < 0) { + error ("Failed to build filename"); + goto err; + } + + int filenamelen = reqlen + 1; + + filename = malloc (filenamelen); + + if (filename == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + goto err; + } + + rc = snprintf (filename, filenamelen, "%ls.%s", (forcedFileName != NULL) ? forcedFileName : audioEssence->unique_file_name, (audioEssence->type == AAFI_ESSENCE_TYPE_AIFC) ? AIFF_FILE_EXT : WAV_FILE_EXT); + + if (rc < 0 || (unsigned)rc >= (unsigned)filenamelen) { + error ("Failed to build filename"); + goto err; + } + + filepath = laaf_util_build_path (DIR_SEP_STR, outfilepath, laaf_util_clean_filename (filename), NULL); + + if (filepath == NULL) { + error ("Could not build filepath"); + goto err; + } + + fp = fopen (filepath, "wb"); + + if (fp == NULL) { + error ("Could not open '%s' for writing : %s", filepath, strerror (errno)); + goto err; + } + + if (audioEssence->type == AAFI_ESSENCE_TYPE_PCM) { + struct wavFmtChunk wavFmt; + wavFmt.channels = audioEssence->channels; + wavFmt.samples_per_sec = audioEssence->samplerate; + wavFmt.bits_per_sample = audioEssence->samplesize; + + struct wavBextChunk wavBext; + memset (&wavBext, 0x00, sizeof (wavBext)); + memcpy (wavBext.umid, audioEssence->sourceMobID, sizeof (aafMobID_t)); + if (audioEssence->mobSlotEditRate) { + wavBext.time_reference = eu2sample (audioEssence->samplerate, audioEssence->mobSlotEditRate, audioEssence->timeReference); + } + + if (datasz >= (uint32_t)-1) { + // TODO RF64 support ? + error ("Audio essence is bigger than maximum wav file size (2^32 bytes) : %" PRIu64 " bytes", datasz); + goto err; + } + + if (riff_writeWavFileHeader (fp, &wavFmt, &wavBext, (uint32_t)datasz, aafi->dbg) < 0) { + error ("Could not write wav audio header : %s", filepath); + goto err; + } + } + + uint64_t writtenBytes = fwrite (data, sizeof (unsigned char), datasz, fp); + + if (writtenBytes < datasz) { + error ("Could not write audio file (%" PRIu64 " bytes written out of %" PRIu64 " bytes) : %s", writtenBytes, datasz, filepath); + goto err; + } + + audioEssence->usable_file_path = malloc ((strlen (filepath) + 1) * sizeof (wchar_t)); + + if (audioEssence->usable_file_path == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + goto err; + } + + reqlen = swprintf (audioEssence->usable_file_path, strlen (filepath) + 1, L"%" WPRIs, filepath); + + if (reqlen < 0) { + error ("Failed setting usable_file_path"); + goto err; + } + + rc = 0; + goto end; + +err: + rc = -1; + +end: + if (filename) + free (filename); + + if (filepath) + free (filepath); + + if (data) + free (data); + + if (fp) + fclose (fp); + + return rc; +} + +int +aafi_parse_audio_summary (AAF_Iface* aafi, aafiAudioEssence* audioEssence) +{ + // laaf_util_dump_hex( audioEssence->summary->val, audioEssence->summary->len ); + + int rc = 0; + char* externalFilePath = NULL; + FILE* fp = NULL; + + struct RIFFAudioFile RIFFAudioFile; + + if (audioEssence->is_embedded) { + if (audioEssence->summary == NULL) { + warning ("TODO: Audio essence has no summary. Should try essence data stream ?"); + goto err; + } + + /* + * Adobe Premiere Pro, embedded mp3/mp4 files converted to PCM/AIFF on export, AAFClassID_AIFCDescriptor, 'COMM' is valid. + * ______________________________ Hex Dump ______________________________ + * + * 46 4f 52 4d 00 00 00 32 41 49 46 43 43 4f 4d 4d | FORM...2 AIFCCOMM + * 00 00 00 26 00 01 00 00 00 00 00 10 40 0e bb 80 | ........ ........ + * 00 00 00 00 00 00 4e 4f 4e 45 0e 4e 6f 74 20 43 | ......NO NE.Not.C + * 6f 6d 70 72 65 73 73 65 64 00 | ompresse d. + * ______________________________________________________________________ + */ + + // laaf_util_dump_hex( audioEssence->summary->val, audioEssence->summary->len ); + + rc = riff_parseAudioFile (&RIFFAudioFile, RIFF_PARSE_ONLY_HEADER, &embeddedAudioDataReaderCallback, audioEssence->summary->val, &audioEssence->summary->len, aafi, aafi->dbg); + + if (rc < 0) { + warning ("TODO: Could not parse embedded essence summary. Should try essence data stream ?"); + goto err; + } + } else { + /* TODO: can external essence have audioEssence->summary too ? If mp3 (Resolve 18.5.aaf) ? */ + + externalFilePath = aafi_locate_external_essence_file (aafi, audioEssence->original_file_path, aafi->ctx.options.media_location); + + if (externalFilePath == NULL) { + error ("Could not locate external audio essence file '%ls'", audioEssence->original_file_path); + return -1; + } + + audioEssence->usable_file_path = malloc ((strlen (externalFilePath) + 1) * sizeof (wchar_t)); + + if (audioEssence->usable_file_path == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + goto err; + } + + rc = swprintf (audioEssence->usable_file_path, strlen (externalFilePath) + 1, L"%" WPRIs, externalFilePath); + + if (rc < 0) { + error ("Failed setting usable_file_path"); + goto err; + } + + fp = fopen (externalFilePath, "rb"); + + if (fp == NULL) { + error ("Could not open external audio essence file for reading : %s", externalFilePath); + goto err; + } + + rc = riff_parseAudioFile (&RIFFAudioFile, RIFF_PARSE_ONLY_HEADER, &externalAudioDataReaderCallback, fp, externalFilePath, aafi, aafi->dbg); + + if (rc < 0) { + error ("TODO IF MP3 ? Failed parsing external essence file : %s", externalFilePath); + goto err; + } + } + + audioEssence->channels = RIFFAudioFile.channels; + audioEssence->samplerate = RIFFAudioFile.sampleRate; + audioEssence->samplesize = RIFFAudioFile.sampleSize; + audioEssence->length = RIFFAudioFile.duration; + + rc = 0; + goto end; + +err: + rc = -1; + +end: + if (fp) + fclose (fp); + + if (externalFilePath) + free (externalFilePath); + + return rc; +} + +static size_t +embeddedAudioDataReaderCallback (unsigned char* buf, size_t offset, size_t reqLen, void* user1, void* user2, void* user3) +{ + unsigned char* data = user1; + size_t datasz = *(size_t*)user2; + AAF_Iface* aafi = (AAF_Iface*)user3; + + if (offset >= datasz) { + error ("Requested data starts beyond data length"); + return -1; + } + + if (offset + reqLen >= datasz) { + reqLen = datasz - (offset + reqLen); + } + + memcpy (buf, data + offset, reqLen); + + return reqLen; +} + +static size_t +externalAudioDataReaderCallback (unsigned char* buf, size_t offset, size_t reqLen, void* user1, void* user2, void* user3) +{ + FILE* fp = (FILE*)user1; + const char* filename = (const char*)user2; + AAF_Iface* aafi = (AAF_Iface*)user3; + + if (fseek (fp, offset, SEEK_SET) < 0) { + error ("Could not seek to %zu in file '%s' : %s", offset, filename, strerror (errno)); + return -1; + } + + size_t read = fread (buf, sizeof (unsigned char), reqLen, fp); + + if (read < reqLen) { + error ("File read failed at %zu (expected %zu, read %zu) in file '%s' : %s", offset, reqLen, read, filename, strerror (errno)); + return -1; + } + + return read; +} diff --git a/libs/aaf/AAFIParser.c b/libs/aaf/AAFIParser.c new file mode 100644 index 0000000000..02e6f79494 --- /dev/null +++ b/libs/aaf/AAFIParser.c @@ -0,0 +1,4169 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * @file LibAAF/AAFIface/AAFIParser.c + * @brief AAF processing + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 27 june 2018 + * + * @ingroup AAFIface + * @addtogroup AAFIface + * + * + * + * + * @{ + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "aaf/AAFDump.h" +#include "aaf/AAFIAudioFiles.h" +#include "aaf/AAFIParser.h" +#include "aaf/AAFIface.h" +#include "aaf/AAFToText.h" +#include "aaf/debug.h" + +#include "aaf/ProTools.h" +#include "aaf/Resolve.h" + +#include "aaf/AAFDefs/AAFClassDefUIDs.h" +#include "aaf/AAFDefs/AAFPropertyIDs.h" +// #include "aaf/AAFDefs/AAFCompressionDefs.h" +#include "aaf/AAFDefs/AAFDataDefs.h" +#include "aaf/AAFDefs/AAFExtEnum.h" +#include "aaf/AAFDefs/AAFInterpolatorDefs.h" +#include "aaf/AAFDefs/AAFOperationDefs.h" +#include "aaf/AAFDefs/AAFParameterDefs.h" +#include "aaf/AAFDefs/AAFTypeDefUIDs.h" +// #include "aaf/AAFDefs/AAFFileKinds.h" +#include "aaf/AAFDefs/AAFOPDefs.h" +// #include "aaf/AAFDefs/AAFContainerDefs.h" + +#include "aaf/utils.h" + +#define debug(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +// #define trace( ... ) +// _dbg( aafi->dbg, aafi, LIB_AAF_IFACE_TRACE, 0, __VA_ARGS__ ) + +static aafRational_t AAFI_DEFAULT_TC_EDIT_RATE = { 25, 1 }; + +#define RESET_CONTEXT(ctx) \ + /*ctx.MobSlot = NULL;*/ \ + ctx.current_track = NULL; \ + /*ctx.current_pos = 0;*/ \ + ctx.current_transition = NULL; \ + ctx.current_clip_gain = NULL; \ + ctx.current_clip_automation = NULL; \ + ctx.current_essence = NULL; \ + ctx.current_clip = NULL; \ + ctx.current_clip_is_muted = 0; \ + ctx.current_clip_is_combined = 0; \ + ctx.current_combined_clip_total_channel = 0; \ + ctx.current_combined_clip_channel_num = 0; + +// ctx.current_track_is_multichannel = 0; +// ctx.current_multichannel_track_channel = 0; +// ctx.current_multichannel_track_clip_length = 0; + +// static void aafi_trace_obj( AAF_Iface *aafi, aafObject *Obj, char *color ); + +static wchar_t* +build_unique_audiofilename (AAF_Iface* aafi, aafiAudioEssence* audioEssence); +static wchar_t* +build_unique_videofilename (AAF_Iface* aafi, aafiVideoEssence* videoEssence); + +/* TODO move to AAFCore.c */ +static aafObject* +get_Object_Ancestor (AAF_Iface* aafi, aafObject* Obj, const aafUID_t* ClassID); + +static aafUID_t* +get_Component_DataDefinition (AAF_Iface* aafi, aafObject* Component); +// static aafUID_t * get_FileDescriptor_ContainerFormat( AAF_Iface *aafi, aafObject *FileDescriptor ); +static aafUID_t* +get_OperationGroup_OperationIdentification (AAF_Iface* aafi, aafObject* OperationGroup); +static aafUID_t* +get_Parameter_InterpolationIdentification (AAF_Iface* aafi, aafObject* Parameter); + +static aafObject* +get_EssenceData_By_MobID (AAF_Iface* aafi, aafMobID_t* MobID); + +// static aafiAudioEssence * getAudioEssenceBySourceMobID( AAF_Iface *aafi, aafMobID_t *sourceMobID ); +// static aafiVideoEssence * getVideoEssenceBySourceMobID( AAF_Iface *aafi, aafMobID_t *sourceMobID ); + +static int +parse_DigitalImageDescriptor (AAF_Iface* aafi, aafObject* DIDescriptor, td* __ptd); +static int +parse_CDCIDescriptor (AAF_Iface* aafi, aafObject* CDCIDescriptor, td* __ptd); + +static int +parse_EssenceDescriptor (AAF_Iface* aafi, aafObject* EssenceDesc, td* __ptd); +static int +parse_PCMDescriptor (AAF_Iface* aafi, aafObject* PCMDescriptor, td* __ptd); +static int +parse_WAVEDescriptor (AAF_Iface* aafi, aafObject* WAVEDescriptor, td* __ptd); +static int +parse_AIFCDescriptor (AAF_Iface* aafi, aafObject* AIFCDescriptor, td* __ptd); + +static int +parse_Locator (AAF_Iface* aafi, aafObject* Locator, td* __ptd); +static int +parse_NetworkLocator (AAF_Iface* aafi, aafObject* NetworkLocator, td* __ptd); + +static int +parse_EssenceData (AAF_Iface* aafi, aafObject* EssenceData, td* __ptd); + +static int +parse_Component (AAF_Iface* aafi, aafObject* Component, td* __ptd); +static int +parse_Transition (AAF_Iface* aafi, aafObject* Transition, td* __ptd); +static int +parse_NestedScope (AAF_Iface* aafi, aafObject* NestedScope, td* __ptd); +static int +parse_Filler (AAF_Iface* aafi, aafObject* Filler, td* __ptd); +static int +parse_Sequence (AAF_Iface* aafi, aafObject* Sequence, td* __ptd); +static int +parse_Timecode (AAF_Iface* aafi, aafObject* Timecode, td* __ptd); +static int +parse_OperationGroup (AAF_Iface* aafi, aafObject* OpGroup, td* __ptd); +static int +parse_SourceClip (AAF_Iface* aafi, aafObject* SourceClip, td* __ptd); +static int +parse_Selector (AAF_Iface* aafi, aafObject* Selector, td* __ptd); + +static int +parse_Parameter (AAF_Iface* aafi, aafObject* Parameter, td* __ptd); +static int +parse_ConstantValue (AAF_Iface* aafi, aafObject* ConstantValue, td* __ptd); +static int +parse_VaryingValue (AAF_Iface* aafi, aafObject* VaryingValue, td* __ptd); +static int +retrieve_ControlPoints (AAF_Iface* aafi, aafObject* Points, aafRational_t* times[], aafRational_t* values[]); + +static int +parse_Mob (AAF_Iface* aafi, aafObject* Mob); +static int +parse_CompositionMob (AAF_Iface* aafi, aafObject* CompoMob, td* __ptd); +static int +parse_SourceMob (AAF_Iface* aafi, aafObject* SourceMob, td* __ptd); + +static int +parse_MobSlot (AAF_Iface* aafi, aafObject* MobSlot, td* __ptd); + +static void +xplore_StrongObjectReferenceVector (AAF_Iface* aafi, aafObject* ObjCollection, td* __ptd); + +static void +xplore_StrongObjectReferenceVector (AAF_Iface* aafi, aafObject* ObjCollection, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + // aaf_dump_ObjectProperties( aafi->aafd, ComponentAttributeList ); + + struct dbg* dbg = aafi->dbg; + aafObject* Obj = NULL; + + aaf_foreach_ObjectInSet (&Obj, ObjCollection, NULL) + { + // aaf_dump_ObjectProperties( aafi->aafd, ObjCollection ); + int offset = 0; + /* TODO implement retrieve_TaggedValue() */ + + if (aaf_get_property (Obj, PID_TaggedValue_Name) && + aaf_get_property (Obj, PID_TaggedValue_Value)) { + wchar_t* name = aaf_get_propertyValue (Obj, PID_TaggedValue_Name, &AAFTypeID_String); + aafIndirect_t* indirect = aaf_get_propertyValue (Obj, PID_TaggedValue_Value, &AAFTypeID_Indirect); + + if (aafUIDCmp (&indirect->TypeDef, &AAFTypeID_Int32)) { + int32_t* indirectValue = aaf_get_indirectValue (aafi->aafd, indirect, &AAFTypeID_Int32); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "Tagged | Name: %ls%*s Value (%ls) : %i\n", name, 56 - (int)wcslen (name), " ", aaft_TypeIDToText (&indirect->TypeDef), *indirectValue); + } else if (aafUIDCmp (&indirect->TypeDef, &AAFTypeID_String)) { + wchar_t* indirectValue = aaf_get_indirectValue (aafi->aafd, indirect, &AAFTypeID_String); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "Tagged | Name: %ls%*s Value (%ls) : %ls\n", name, 56 - (int)wcslen (name), " ", aaft_TypeIDToText (&indirect->TypeDef), indirectValue); + free (indirectValue); + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "Tagged | Name: %ls%*s Value (%s%ls%s) : %sUNKNOWN_TYPE%s\n", name, 56 - (int)wcslen (name), " ", ANSI_COLOR_RED, aaft_TypeIDToText (&indirect->TypeDef), ANSI_COLOR_RESET, ANSI_COLOR_RED, ANSI_COLOR_RESET); + } + + dbg->debug_callback (dbg, (void*)aafi, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); + + free (name); + } else { + dbg->debug_callback (dbg, (void*)aafi, DEBUG_SRC_ID_DUMP, 0, "", "", 0, dbg->_dbg_msg, dbg->user); + + offset = 0; + aaf_dump_ObjectProperties (aafi->aafd, Obj); + } + } +} + +void +aafi_dump_obj (AAF_Iface* aafi, aafObject* Obj, struct trace_dump* __td, int state, int line, const char* fmt, ...) +{ + if (aafi->ctx.options.trace == 0) + return; + + /* Print caller line number */ + struct dbg* dbg = aafi->dbg; + int offset = 0; + + if (Obj) { + switch (state) { + case TD_ERROR: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_RED); + break; + case TD_WARNING: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_YELLOW); + break; + case TD_NOT_SUPPORTED: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_ORANGE); + break; + default: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_DARKGREY); + break; + } + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%05i", line); + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " "); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s%ls%s", ANSI_COLOR_DARKGREY, L"\u2502", ANSI_COLOR_RESET); // │ + + /* Print padding and vertical lines */ + + if (__td->lv > 0) { + for (int i = 0; i < __td->lv; i++) { + /* current level iteration has more than one entry remaining in loop */ + + if (__td->ll[i] > 1) { + /* next level iteration is current trace */ + + if (i + 1 == __td->lv) { + if (Obj) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls", L"\u251c\u2500\u2500\u25fb "); // ├──◻ + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls", L"\u2502 "); // │ + } + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls", L"\u2502 "); // │ + } + } else if (i + 1 == __td->lv && Obj) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls", L"\u2514\u2500\u2500\u25fb "); // └──◻ + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " "); + } + } + } + + if (Obj) { + switch (state) { + case TD_ERROR: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_RED); + break; + case TD_WARNING: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_YELLOW); + break; + case TD_NOT_SUPPORTED: + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_ORANGE); + break; + case TD_INFO: + case TD_OK: + if (__td->sub) + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_DARKGREY); + else + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_CYAN); + + break; + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%ls ", aaft_ClassIDToText (aafi->aafd, Obj->Class->ID)); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_RESET); + + if (aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot) && + aafUIDCmp (Obj->Parent->Class->ID, &AAFClassID_CompositionMob)) { + aafObject* Segment = aaf_get_propertyValue (Obj, PID_MobSlot_Segment, &AAFTypeID_SegmentStrongReference); + aafUID_t* DataDefinition = get_Component_DataDefinition (aafi, Segment); + wchar_t* name = aaf_get_propertyValue (Obj, PID_MobSlot_SlotName, &AAFTypeID_String); + uint32_t* slotID = aaf_get_propertyValue (Obj, PID_MobSlot_SlotID, &AAFTypeID_UInt32); + uint32_t* trackNo = aaf_get_propertyValue (Obj, PID_MobSlot_PhysicalTrackNumber, &AAFTypeID_UInt32); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "[slot:%s%i%s track:%s%i%s] (DataDef : %s%ls%s) %s%ls ", + ANSI_COLOR_BOLD, + (slotID) ? (int)(*slotID) : -1, + ANSI_COLOR_RESET, + ANSI_COLOR_BOLD, + (trackNo) ? (int)(*trackNo) : -1, + ANSI_COLOR_RESET, + ANSI_COLOR_DARKGREY, + aaft_DataDefToText (aafi->aafd, DataDefinition), + ANSI_COLOR_RESET, + (name[0] != 0x00) ? ": " : "", (name) ? name : L""); + + free (name); + } else if (aafUIDCmp (Obj->Class->ID, &AAFClassID_CompositionMob) || + aafUIDCmp (Obj->Class->ID, &AAFClassID_MasterMob) || + aafUIDCmp (Obj->Class->ID, &AAFClassID_SourceMob)) { + aafUID_t* usageCode = aaf_get_propertyValue (Obj, PID_Mob_UsageCode, &AAFTypeID_UsageType); + wchar_t* name = aaf_get_propertyValue (Obj, PID_Mob_Name, &AAFTypeID_String); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "(UsageCode: %s%ls%s) %s%ls", + ANSI_COLOR_DARKGREY, + aaft_UsageCodeToText (usageCode), + ANSI_COLOR_RESET, + (name && name[0] != 0x00) ? ": " : "", (name) ? name : L""); + + free (name); + } else if (aafUIDCmp (Obj->Class->ID, &AAFClassID_OperationGroup)) { + aafUID_t* OperationIdentification = get_OperationGroup_OperationIdentification (aafi, Obj); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "(OpIdent: %s%ls%s) ", + ANSI_COLOR_DARKGREY, + aaft_OperationDefToText (aafi->aafd, OperationIdentification), + ANSI_COLOR_RESET); + } + // else if ( aafUIDCmp( Obj->Class->ID, &AAFClassID_TapeDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_FilmDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_CDCIDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_RGBADescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_TIFFDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_SoundDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_PCMDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_AES3PCMDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_WAVEDescriptor ) || + // aafUIDCmp( Obj->Class->ID, &AAFClassID_AIFCDescriptor ) ) + // { + // aafUID_t *ContainerFormat = get_FileDescriptor_ContainerFormat( aafi, Obj ); + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "(ContainerIdent : \x1b[38;5;242m%ls\x1b[0m)", aaft_ContainerToText(ContainerFormat) ); + // } + + if (state == TD_ERROR) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, ": %s", ANSI_COLOR_RED); + } else if (state == TD_INFO) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, ": %s", ANSI_COLOR_CYAN); + } + + va_list args; + va_start (args, fmt); + + offset += laaf_util_vsnprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, fmt, &args); + + va_end (args); + // va_list args; + // va_list args2; + // va_copy( args2, args ); + // + // va_start( args2, fmt ); + // // vprintf(fmt, args); + // // offset += laaf_util_vsnprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, fmt, args ); + // int needed = vsnprintf( NULL, 0, fmt, args2 ) + 1; + // if ( needed >= dbg->_dbg_msg_size + offset ) { + // char *p = realloc( dbg->_dbg_msg, offset+needed ); + // if (p) { + // dbg->_dbg_msg = p; + // } else { + // /* TODO: realloc() faillure */ + // // free(*str); + // // *str = NULL; + // // *size = 0; + // // return -1; + // } + // } + // va_end( args2 ); + // + // va_start( args, fmt ); + // // vprintf( fmt, args ); + // offset += vsnprintf( dbg->_dbg_msg+offset, dbg->_dbg_msg_size-offset, fmt, args ); + // va_end( args ); + + if (state == TD_ERROR || state == TD_INFO) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "."); + } + + if (state == TD_NOT_SUPPORTED || (aafi->ctx.options.trace_class && wcscmp (aaft_ClassIDToText (aafi->aafd, Obj->Class->ID), aafi->ctx.options.trace_class) == 0)) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n%s", (state == TD_NOT_SUPPORTED) ? ANSI_COLOR_ORANGE : ""); + + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "CFB Object Dump : %ls\n", aaf_get_ObjectPath( Obj ) ); + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "=================\n" ); + // cfb_dump_node( aafi->aafd->cfbd, Obj->Node, 1 ); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "Properties Dump (%ls)\n", aaf_get_ObjectPath (Obj)); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "===============\n\n"); + // aaf_dump_nodeStreamProperties( aafi->aafd, Obj->Node ); + + // dbg->debug_callback( dbg, (void*)aafi, DEBUG_SRC_ID_TRACE, 0, "", "", 0, dbg->_dbg_msg, dbg->user ); + // + // offset = 0; + // aaf_dump_ObjectProperties( aafi->aafd, Obj ); + } else { + aafProperty* Prop = NULL; + int hasUnknownProps = 0; + + for (Prop = Obj->Properties; Prop != NULL; Prop = Prop->next) { + if (Prop->def->meta) { + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + + if (aafi->ctx.options.trace_meta) { + // aaf_dump_ObjectProperties( aafi->aafd, Obj ); + + // if ( Prop->pid == 0xffca ) { + if (Prop->sf == SF_STRONG_OBJECT_REFERENCE_VECTOR) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " >>> (0x%04x) %ls (%ls)\n", Prop->pid, aaft_PIDToText (aafi->aafd, Prop->pid), aaft_StoredFormToText (Prop->sf) /*AUIDToText( &Prop->def->type ),*/ /*aaft_TypeIDToText( &(Prop->def->type) )*/); + void* propValue = aaf_get_propertyValue (Obj, Prop->pid, &AAFUID_NULL); + xplore_StrongObjectReferenceVector (aafi, propValue, __td); + + // DUMP_OBJ_NO_SUPPORT( aafi, propValue, __td ); + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + aaf_dump_ObjectProperty (aafi->aafd, Prop); + } + } else { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s%s %ls[0x%04x]", ANSI_COLOR_RESET, (!hasUnknownProps) ? " (MetaProps:" : "", aaft_PIDToText (aafi->aafd, Prop->pid), Prop->pid); + // laaf_util_dump_hex( Prop->val, Prop->len ); + hasUnknownProps++; + } + } + } + if (aafi->ctx.options.trace_meta == 0 && hasUnknownProps) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, ")"); + } + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%s", ANSI_COLOR_RESET); + } + + // offset += laaf_util_snprintf_realloc( &dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n" ); + + dbg->debug_callback (dbg, (void*)aafi, DEBUG_SRC_ID_TRACE, 0, "", "", 0, dbg->_dbg_msg, dbg->user); + + /* if end of branch, print one line padding */ + if (Obj && (__td->eob || state == TD_ERROR)) + aafi_dump_obj (aafi, NULL, __td, 0, -1, ""); +} + +void +aafi_dump_obj_no_support (AAF_Iface* aafi, aafObject* Obj, struct trace_dump* __td, int line) +{ + // aafUID_t *DataDefinition = NULL; + + if (aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot) && + aafUIDCmp (Obj->Parent->Class->ID, &AAFClassID_CompositionMob)) { + /* this part is handled by aafi_dump_obj() already. */ + aafi_dump_obj (aafi, Obj, __td, TD_NOT_SUPPORTED, line, ""); + return; + // aafObject *Segment = aaf_get_propertyValue( Obj, PID_MobSlot_Segment, &AAFTypeID_SegmentStrongReference ); + // + // if ( Segment != NULL ) /* req */ { + // DataDefinition = get_Component_DataDefinition( aafi, Segment ); + // } + // } + // else { + // DataDefinition = get_Component_DataDefinition( aafi, Obj ); + } + + // DataDefinition = get_Component_DataDefinition( aafi, Obj ); + + aafi_dump_obj (aafi, Obj, __td, TD_NOT_SUPPORTED, line, ""); + + // aafi_dump_obj( aafi, Obj, __td, WARNING, line, "%s%ls%s", + // // aaft_ClassIDToText( aafi->aafd, Obj->Class->ID ), + // ((DataDefinition) ? "(Segment DataDefinition: \x1b[38;5;242m" : ""), + // ((DataDefinition) ? aaft_DataDefToText( aafi->aafd, DataDefinition ) : L""), + // ((DataDefinition) ? ") \x1b[0m" : "") ); +} + +/* +#define DUMP_OBJ( aafi, Obj, __td ) \ + aafi_dump_obj( aafi, Obj, __td, OK, __LINE__, "" ); + +#define DUMP_OBJ_ERROR( aafi, Obj, __td, ... ) \ + (__td)->eob = 1; \ + aafi_dump_obj( aafi, Obj, __td, ERROR, __LINE__, __VA_ARGS__ ); + +#define DUMP_OBJ_WARNING( aafi, Obj, __td, ... ) \ + aafi_dump_obj( aafi, Obj, __td, WARNING, __LINE__, __VA_ARGS__ ); + +#define DUMP_OBJ_INFO( aafi, Obj, __td, ... ) \ + aafi_dump_obj( aafi, Obj, __td, OK, __LINE__, __VA_ARGS__ ); + +#define DUMP_OBJ_NO_SUPPORT( aafi, Obj, __td ) \ + (__td)->eob = 1; \ + aafi_dump_obj_no_support( aafi, Obj, __td, __LINE__ ); \ + // aaf_dump_ObjectProperties( aafi->aafd, Obj ); +*/ + +static wchar_t* +build_unique_audiofilename (AAF_Iface* aafi, aafiAudioEssence* audioEssence) +{ + wchar_t* unique = NULL; + size_t unique_size = 0; + size_t file_name_len = 0; + + if (audioEssence->file_name) { + file_name_len = wcslen (audioEssence->file_name); + unique_size = file_name_len + 1 + 4; // +4 = "_001" + unique_size = (unique_size < AAFUID_PRINTED_LEN + 1) ? AAFUID_PRINTED_LEN + 1 : unique_size; + + // debug("%lu, %lu", file_name_len, unique_size); + + unique = malloc (sizeof (wchar_t) * unique_size); + + if (unique == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + return NULL; + } + + if (swprintf (unique, unique_size, L"%" WPRIws, audioEssence->file_name) < 0) { + error ("Could not prepare unique filename"); + return NULL; + } + } else { + file_name_len = strlen ("unknown"); + unique_size = file_name_len + 1 + 4; // +4 = "_001" + unique_size = (unique_size < AAFUID_PRINTED_LEN + 1) ? AAFUID_PRINTED_LEN + 1 : unique_size; + + unique = malloc (sizeof (wchar_t) * unique_size); + + if (unique == NULL) { + error ("Could not allocate memory : %s", strerror (errno)); + return NULL; + } + + if (swprintf (unique, unique_size, L"unknown") < 0) { + error ("Could not prepare unique filename"); + return NULL; + } + } + + // debug( "%ls", unique ); + + aafiAudioEssence* ae = NULL; + + if (aafi->ctx.options.forbid_nonlatin_filenames && laaf_util_wstr_contains_nonlatin (unique)) { + aafUID_t* uuid = &(audioEssence->sourceMobID->material); + + int rc = swprintf (unique, unique_size, L"%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", + uuid->Data1, + uuid->Data2, + uuid->Data3, + uuid->Data4[0], + uuid->Data4[1], + uuid->Data4[2], + uuid->Data4[3], + uuid->Data4[4], + uuid->Data4[5], + uuid->Data4[6], + uuid->Data4[7]); + + if (rc < 0) { + error ("Failed to set unique filename with SourceMobID UID"); + free (unique); + return NULL; + } + + audioEssence->unique_file_name = unique; + + return unique; + } + + int index = 0; + + foreachEssence (ae, aafi->Audio->Essences) + { + if (ae->unique_file_name != NULL && wcscmp (ae->unique_file_name, unique) == 0) { + if (swprintf (unique + file_name_len, (unique_size - file_name_len), L"_%i", ++index) < 0) { + error ("Failed to increment unique filename"); + free (unique); + return NULL; + } + + ae = aafi->Audio->Essences; // check again + // debug( "%ls", unique ); + } + } + + audioEssence->unique_file_name = unique; + + // debug( "%ls", audioEssence->wunique_file_name ); + + return unique; +} + +static wchar_t* +build_unique_videofilename (AAF_Iface* aafi, aafiVideoEssence* videoEssence) +{ + /* TODO 1024 should be a macro ! */ + + wchar_t* unique = calloc (sizeof (wchar_t), 1024); + + size_t file_name_len = wcslen (videoEssence->file_name); + + // debug( "%i", file_name_len ); + + memcpy (unique, videoEssence->file_name, (file_name_len + 1) * sizeof (wchar_t)); + + // debug( "%ls", unique ); + + aafiVideoEssence* ve = NULL; + + if (1) { + size_t i = 0; + + for (; i < file_name_len; i++) { + /* if char is out of the Basic Latin range */ + + if (unique[i] > 0xff) { + // debug( "MobID : %ls", aaft_MobIDToText( videoEssence->sourceMobID ) ); + aafUID_t* uuid = &(videoEssence->sourceMobID->material); + swprintf (unique, 1024, L"%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", + uuid->Data1, + uuid->Data2, + uuid->Data3, + uuid->Data4[0], + uuid->Data4[1], + uuid->Data4[2], + uuid->Data4[3], + uuid->Data4[4], + uuid->Data4[5], + uuid->Data4[6], + uuid->Data4[7]); + + videoEssence->unique_file_name = unique; + + return unique; + } + } + } + + int id = 0; + + foreachEssence (ve, aafi->Video->Essences) + { + if (ve->unique_file_name != NULL && wcscmp (ve->unique_file_name, unique) == 0) { + swprintf (unique + file_name_len, (1024 - file_name_len), L"_%i", ++id); + // debug( "%ls", unique ); + ve = aafi->Video->Essences; // check again + } + } + + videoEssence->unique_file_name = unique; + + // debug( "%ls", videoEssence->wunique_file_name ); + + return unique; +} + +static aafObject* +get_Object_Ancestor (AAF_Iface* aafi, aafObject* Obj, const aafUID_t* ClassID) +{ + (void)aafi; + + /* + * NOTE : AAFClassID_ContentStorage is the container of Mob and EssenceData, + * not of Identification, Dictionary and MetaDictionary. If needed, the func + * should work for them too thanks to Obj != NULL. + */ + + for (; Obj != NULL && aafUIDCmp (Obj->Class->ID, &AAFClassID_ContentStorage) == 0; Obj = Obj->Parent) { + if (aafUIDCmp (Obj->Class->ID, ClassID)) + return Obj; + /* Also work with abstract class */ + else if (aafUIDCmp (ClassID, &AAFClassID_Mob) && (aafUIDCmp (Obj->Class->ID, &AAFClassID_CompositionMob) || aafUIDCmp (Obj->Class->ID, &AAFClassID_MasterMob) || aafUIDCmp (Obj->Class->ID, &AAFClassID_SourceMob))) + return Obj; + else if (aafUIDCmp (ClassID, &AAFClassID_MobSlot) && (aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot) || aafUIDCmp (Obj->Class->ID, &AAFClassID_StaticMobSlot) || aafUIDCmp (Obj->Class->ID, &AAFClassID_EventMobSlot))) + return Obj; + } + + return NULL; +} + +/* **************************************************************************** + * D i c t i o n a r y + * ****************************************************************************/ + +static aafUID_t* +get_Component_DataDefinition (AAF_Iface* aafi, aafObject* Component) +{ + aafWeakRef_t* weakRef = aaf_get_propertyValue (Component, PID_Component_DataDefinition, &AAFTypeID_DataDefinitionWeakReference); + + if (weakRef == NULL) { + warning ("Missing Component::DataDefinition."); + return NULL; + } + + aafObject* DataDefinition = aaf_get_ObjectByWeakRef (aafi->aafd->DataDefinition, weakRef); + + if (DataDefinition == NULL) { + warning ("Could not retrieve WeakRef from Dictionary::DataDefinition."); + return NULL; + } + + aafUID_t* DataIdentification = aaf_get_propertyValue (DataDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (DataIdentification == NULL) { + warning ("Missing DataDefinition's DefinitionObject::Identification."); + return NULL; + } + + return DataIdentification; +} + +// static aafUID_t * get_FileDescriptor_ContainerFormat( AAF_Iface *aafi, aafObject *FileDescriptor ) +// { +// aafWeakRef_t *ContainerDefWeakRef = aaf_get_propertyValue( FileDescriptor, PID_FileDescriptor_ContainerFormat ); +// +// if ( ContainerDefWeakRef == NULL ) { +// warning( "Missing FileDescriptor::ContainerFormat." ); +// return NULL; +// } +// +// aafObject *ContainerDefinition = aaf_get_ObjectByWeakRef( aafi->aafd->ContainerDefinition, ContainerDefWeakRef ); +// +// if ( ContainerDefinition == NULL ) { +// warning( "Could not retrieve WeakRef from Dictionary::ContainerDefinitions." ); +// return NULL; +// } +// +// +// aafUID_t *ContainerIdentification = aaf_get_propertyValue( ContainerDefinition, PID_DefinitionObject_Identification ); +// +// if ( ContainerIdentification == NULL ) { +// warning( "Missing ContainerDefinition's DefinitionObject::Identification." ); +// return NULL; +// } +// +// +// return ContainerIdentification; +// } + +static aafUID_t* +get_OperationGroup_OperationIdentification (AAF_Iface* aafi, aafObject* OperationGroup) +{ + aafWeakRef_t* OperationDefWeakRef = aaf_get_propertyValue (OperationGroup, PID_OperationGroup_Operation, &AAFTypeID_OperationDefinitionWeakReference); + + if (OperationDefWeakRef == NULL) { + error ("Missing OperationGroup::Operation."); + return NULL; + } + + aafObject* OperationDefinition = aaf_get_ObjectByWeakRef (aafi->aafd->OperationDefinition, OperationDefWeakRef); + + if (OperationDefinition == NULL) { + error ("Could not retrieve OperationDefinition from dictionary."); + return NULL; + } + + aafUID_t* OperationIdentification = aaf_get_propertyValue (OperationDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (OperationIdentification == NULL) { + error ("Missing DefinitionObject::Identification."); + return NULL; + } + + return OperationIdentification; +} + +/* TODO not parameter ? VaryingValue ? */ +static aafUID_t* +get_Parameter_InterpolationIdentification (AAF_Iface* aafi, aafObject* Parameter) +{ + aafWeakRef_t* InterpolationDefWeakRef = aaf_get_propertyValue (Parameter, PID_VaryingValue_Interpolation, &AAFTypeID_InterpolationDefinitionWeakReference); + + if (InterpolationDefWeakRef == NULL) { + error ("Missing Parameter::Interpolation."); + return NULL; + } + + aafObject* InterpolationDefinition = aaf_get_ObjectByWeakRef (aafi->aafd->InterpolationDefinition, InterpolationDefWeakRef); + + if (InterpolationDefinition == NULL) { + error ("Could not find InterpolationDefinition."); + return NULL; + } + + aafUID_t* InterpolationIdentification = aaf_get_propertyValue (InterpolationDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (InterpolationIdentification == NULL) { + error ("Missing Parameter DefinitionObject::Identification."); + return NULL; + } + + return InterpolationIdentification; +} + +static aafObject* +get_EssenceData_By_MobID (AAF_Iface* aafi, aafMobID_t* MobID) +{ + aafMobID_t* DataMobID = NULL; + aafObject* EssenceData = NULL; + + for (EssenceData = aafi->aafd->EssenceData; EssenceData != NULL; EssenceData = EssenceData->next) { + DataMobID = aaf_get_propertyValue (EssenceData, PID_EssenceData_MobID, &AAFTypeID_MobIDType); + + if (aafMobIDCmp (DataMobID, MobID)) + break; + } + + return EssenceData; +} + +// /* TODO is this SourceMobID or SourceID (masterMobID) ??? */ +// static aafiAudioEssence * getAudioEssenceBySourceMobID( AAF_Iface *aafi, aafMobID_t *sourceMobID ) +// { +// aafiAudioEssence * audioEssence = NULL; +// +// +// for ( audioEssence = aafi->Audio->Essences; audioEssence != NULL; audioEssence = audioEssence->next ) { +// if ( aafMobIDCmp( audioEssence->masterMobID, sourceMobID ) ) +// break; +// } +// +// +// return audioEssence; +// } + +// /* TODO is this SourceMobID or SourceID (masterMobID) ??? */ +// static aafiVideoEssence * getVideoEssenceBySourceMobID( AAF_Iface *aafi, aafMobID_t *sourceMobID ) +// { +// aafiVideoEssence * videoEssence = NULL; +// +// // debug( "%p", aafi->Video->tc ); +// debug( "%p", aafi->Video->Essences ); +// debug( "%ls", aaft_MobIDToText( sourceMobID ) ); +// +// +// for ( videoEssence = aafi->Video->Essences; videoEssence != NULL; videoEssence = videoEssence->next ) { +// if ( aafMobIDCmp( videoEssence->masterMobID, sourceMobID ) ) +// break; +// } +// +// +// return videoEssence; +// } + +/* **************************************************************************** + * E s s e n c e D e s c r i p t o r + * **************************************************************************** + * + * EssenceDescriptor (abs) + * | + * |--> FileDescriptor (abs) + * | | + * | |--> WAVEDescriptor + * | |--> AIFCDescriptor + * | |--> SoundDescriptor + * | | | + * | | `--> PCMDescriptor + * | | + * | `--> DigitalImageDescriptor (abs) + * | | + * | `--> CDCIDescriptor + * | + * | + * |--> PhysicalDescriptor + * `--> TapeDescriptor + */ + +static int +parse_EssenceDescriptor (AAF_Iface* aafi, aafObject* EssenceDesc, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_PCMDescriptor)) { + parse_PCMDescriptor (aafi, EssenceDesc, &__td); + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_WAVEDescriptor)) { + parse_WAVEDescriptor (aafi, EssenceDesc, &__td); + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_AIFCDescriptor)) { + parse_AIFCDescriptor (aafi, EssenceDesc, &__td); + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_SoundDescriptor)) { + /* Compressed Audio (MP3, AAC ?). Not encountered yet */ + + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, EssenceDesc, &__td); + __td.lv--; + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_AES3PCMDescriptor)) { + /* Not described in specs, not encountered yet. */ + + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, EssenceDesc, &__td); + __td.lv--; + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_MultipleDescriptor)) { + /* + * A MultipleDescriptor contains a vector of FileDescriptor objects and is + * used when the file source consists of multiple tracks of essence (e.g MXF). + * Each essence track is described by a MobSlots object in the SourceMob and a + * FileDescriptor object. The FileDescriptor is linked to the MobSlot by + * setting the FileDescriptor::LinkedSlotID property equal to the + * MobSlot::SlotID property. + * + * -> test.aaf + */ + + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, EssenceDesc, &__td); + __td.lv--; + + } else if (aafUIDCmp (EssenceDesc->Class->ID, &AAFClassID_CDCIDescriptor)) { + parse_CDCIDescriptor (aafi, EssenceDesc, &__td); + } else { + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, EssenceDesc, &__td); + __td.lv--; + } + + /* + * Locators are a property of EssenceDescriptor. The property holds a vector of + * Locators object, that should provide information to help find a file that + * contains the essence (WAV, MXF, etc.) or to help find the physical media. + * + * A Locator can either be a NetworkLocator or a TextLocator. + * + * A NetworkLocator holds a URLString property : + * + * p.41 : Absolute Uniform Resource Locator (URL) complying with RFC 1738 or relative + * Uniform Resource Identifier (URI) complying with RFC 2396 for file containing + * the essence. If it is a relative URI, the base URI is determined from the URI + * of the AAF file itself. + * Informative note: A valid URL or URI uses a constrained character set and uses + * the / character as the path separator. + */ + + aafObject* Locator = NULL; + aafObject* Locators = aaf_get_propertyValue (EssenceDesc, PID_EssenceDescriptor_Locator, &AAFTypeID_LocatorStrongReferenceVector); /* opt */ + + __td.lv++; + int i = 0; + + aaf_foreach_ObjectInSet (&Locator, Locators, NULL) + { + /* TODO retrieve all locators, then when searching file, try all parsed locators. */ + __td.ll[__td.lv] = (Locators->Header->_entryCount > 1) ? (Locators->Header->_entryCount - i++) : 0; + parse_Locator (aafi, Locator, &__td); + } + + return 0; +} + +static int +parse_DigitalImageDescriptor (AAF_Iface* aafi, aafObject* DIDescriptor, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + /* TODO parse and save content to videoEssence */ + + aafiVideoEssence* videoEssence = aafi->ctx.current_video_essence; //(aafiVideoEssence*)aafi->ctx.current_essence; + + if (videoEssence == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "aafi->ctx.current_video_essence not set"); + return -1; + } + + aafRational_t* framerate = aaf_get_propertyValue (DIDescriptor, PID_FileDescriptor_SampleRate, &AAFTypeID_Rational); + + if (framerate == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_FileDescriptor_SampleRate"); + return -1; + } + + videoEssence->framerate = framerate; + + uint32_t* storedHeight = aaf_get_propertyValue (DIDescriptor, PID_DigitalImageDescriptor_StoredHeight, &AAFTypeID_UInt32); + + if (storedHeight == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_DigitalImageDescriptor_StoredHeight"); + return -1; + } + + // debug( "storedHeight : %u", *storedHeight ); + + uint32_t* storedWidth = aaf_get_propertyValue (DIDescriptor, PID_DigitalImageDescriptor_StoredWidth, &AAFTypeID_UInt32); + + if (storedWidth == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_DigitalImageDescriptor_StoredWidth"); + return -1; + } + + // debug( "storedWidth : %u", *storedWidth ); + + uint32_t* displayHeight = aaf_get_propertyValue (DIDescriptor, PID_DigitalImageDescriptor_DisplayHeight, &AAFTypeID_UInt32); + + if (displayHeight == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_DigitalImageDescriptor_DisplayHeight"); + return -1; + } + + // debug( "displayHeight : %u", *displayHeight ); + + uint32_t* displayWidth = aaf_get_propertyValue (DIDescriptor, PID_DigitalImageDescriptor_DisplayWidth, &AAFTypeID_UInt32); + + if (displayWidth == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_DigitalImageDescriptor_DisplayWidth"); + return -1; + } + + // debug( "displayWidth : %u", *displayWidth ); + + aafRational_t* imageAspectRatio = aaf_get_propertyValue (DIDescriptor, PID_DigitalImageDescriptor_ImageAspectRatio, &AAFTypeID_Rational); + + if (imageAspectRatio == NULL) { + DUMP_OBJ_ERROR (aafi, DIDescriptor, &__td, "Missing PID_DigitalImageDescriptor_ImageAspectRatio"); + return -1; + } + + // debug( "imageAspectRatio : %i/%i", imageAspectRatio->numerator, imageAspectRatio->denominator ); + + return 0; +} + +static int +parse_CDCIDescriptor (AAF_Iface* aafi, aafObject* CDCIDescriptor, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (!aaf_get_property (CDCIDescriptor, PID_EssenceDescriptor_Locator)) + __td.eob = 1; + + /* TODO parse CDCI class */ + + int rc = parse_DigitalImageDescriptor (aafi, CDCIDescriptor, __ptd); + + if (!rc) + DUMP_OBJ (aafi, CDCIDescriptor, &__td); + + return rc; +} + +static int +parse_PCMDescriptor (AAF_Iface* aafi, aafObject* PCMDescriptor, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (!aaf_get_property (PCMDescriptor, PID_EssenceDescriptor_Locator)) + __td.eob = 1; + + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + if (audioEssence == NULL) { + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "aafi->ctx.current_essence not set"); + return -1; + } + + audioEssence->type = AAFI_ESSENCE_TYPE_PCM; + + /* Duration of the essence in sample units (not edit units !) */ + aafPosition_t* length = aaf_get_propertyValue (PCMDescriptor, PID_FileDescriptor_Length, &AAFTypeID_PositionType); + + if (length == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "Missing PID_FileDescriptor_Length"); + return -1; + } + + audioEssence->length = *length; + + uint32_t* channels = aaf_get_propertyValue (PCMDescriptor, PID_SoundDescriptor_Channels, &AAFTypeID_UInt32); + + if (channels == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "Missing PID_SoundDescriptor_Channels"); + return -1; + } + + audioEssence->channels = *channels; + + aafRational_t* samplerate = aaf_get_propertyValue (PCMDescriptor, PID_FileDescriptor_SampleRate, &AAFTypeID_Rational); + + if (samplerate == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "Missing PID_FileDescriptor_SampleRate"); + return -1; + } + + if (samplerate->denominator != 1) { + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "PID_FileDescriptor_SampleRate should be integer but is %i/%i", samplerate->numerator, samplerate->denominator); + return -1; + } + + audioEssence->samplerate = samplerate->numerator; + + // if ( aafi->Audio->samplerate >= 0 ) { + /* Set global AAF SampleRate, if it equals preceding. Otherwise set to -1 */ + // aafi->Audio->samplerate = ( aafi->Audio->samplerate == 0 || aafi->Audio->samplerate == *samplerate ) ? *samplerate : (unsigned)-1; + // } + + uint32_t* samplesize = aaf_get_propertyValue (PCMDescriptor, PID_SoundDescriptor_QuantizationBits, &AAFTypeID_UInt32); // uint32_t in AAF std + + if (samplesize == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "Missing PID_SoundDescriptor_QuantizationBits"); + return -1; + } + + if (*samplesize >= (1 << 15)) { + DUMP_OBJ_ERROR (aafi, PCMDescriptor, &__td, "PID_SoundDescriptor_QuantizationBits value error : %u", *samplesize); + return -1; + } + + audioEssence->samplesize = (int16_t)*samplesize; + + if (aafi->Audio->samplesize >= 0) { + /* Set global AAF SampleSize, if it equals preceding. Otherwise set to -1 */ + aafi->Audio->samplesize = (aafi->Audio->samplesize == 0 || (uint16_t)aafi->Audio->samplesize == audioEssence->samplesize) ? audioEssence->samplesize : -1; + } + + /* TODO parse the rest of the class */ + + DUMP_OBJ (aafi, PCMDescriptor, &__td); + + return 0; +} + +static int +parse_WAVEDescriptor (AAF_Iface* aafi, aafObject* WAVEDescriptor, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (!aaf_get_property (WAVEDescriptor, PID_EssenceDescriptor_Locator)) + __td.eob = 1; + + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + if (audioEssence == NULL) { + DUMP_OBJ_ERROR (aafi, WAVEDescriptor, &__td, "aafi->ctx.current_essence not set"); + return -1; + } + + audioEssence->type = AAFI_ESSENCE_TYPE_WAVE; + + aafProperty* summary = aaf_get_property (WAVEDescriptor, PID_WAVEDescriptor_Summary); + + if (summary == NULL) { + DUMP_OBJ_ERROR (aafi, WAVEDescriptor, &__td, "Missing PID_WAVEDescriptor_Summary"); + return -1; + } + + audioEssence->summary = summary; + + /* + * NOTE : Summary is parsed later in "post-processing" aafi_retrieveData(), + * to be sure clips and essences are linked, so we are able to fallback on + * essence stream in case summary does not contain the full header part. + * + * TODO parse it here + */ + + DUMP_OBJ (aafi, WAVEDescriptor, &__td); + + return 0; +} + +static int +parse_AIFCDescriptor (AAF_Iface* aafi, aafObject* AIFCDescriptor, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (!aaf_get_property (AIFCDescriptor, PID_EssenceDescriptor_Locator)) + __td.eob = 1; + + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + if (audioEssence == NULL) { + DUMP_OBJ_ERROR (aafi, AIFCDescriptor, &__td, "aafi->ctx.current_essence not set"); + return -1; + } + + audioEssence->type = AAFI_ESSENCE_TYPE_AIFC; + + aafProperty* summary = aaf_get_property (AIFCDescriptor, PID_AIFCDescriptor_Summary); + + if (summary == NULL) { + DUMP_OBJ_ERROR (aafi, AIFCDescriptor, &__td, "Missing PID_AIFCDescriptor_Summary"); + return -1; + } + + audioEssence->summary = summary; + + /* + * NOTE : Summary is parsed later in "post-processing" aafi_retrieveData(), + * to be sure clips and essences are linked, so we are able to fallback on + * essence stream in case summary does not contain the full header part. + */ + + DUMP_OBJ (aafi, AIFCDescriptor, &__td); + + return 0; +} + +/* + * Locator (abs) + * | + * ,---------------. + * | | + * NetworkLocator TextLocator + */ + +static int +parse_Locator (AAF_Iface* aafi, aafObject* Locator, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + if (aafUIDCmp (Locator->Class->ID, &AAFClassID_NetworkLocator)) { + parse_NetworkLocator (aafi, Locator, &__td); + } else if (aafUIDCmp (Locator->Class->ID, &AAFClassID_TextLocator)) { + /* + * A TextLocator object provides information to the user to help locate the file + * containing the essence or to locate the physical media. The TextLocator is not + * intended for applications to use without user intervention. + * + * TODO what to do with those ??? + * never encountered anyway.. + */ + + __td.eob = 1; + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, Locator, &__td); + + // wchar_t *name = aaf_get_propertyValue( Locator, PID_TextLocator_Name, &AAFTypeID_String ); + // warning( "Got an AAFClassID_TextLocator : \"%ls\"", name ); + // free( name ); + } else { + __td.eob = 1; + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, Locator, &__td); + } + + return 0; +} + +static int +parse_NetworkLocator (AAF_Iface* aafi, aafObject* NetworkLocator, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + __td.eob = 1; + + /* + * This holds an URI pointing to the essence file, when it is not embedded. + * However, sometimes it holds an URI to the AAF file itself when essence is + * embedded so it is not a valid way to test if essence is embedded or not. + */ + + wchar_t* original_file_path = aaf_get_propertyValue (NetworkLocator, PID_NetworkLocator_URLString, &AAFTypeID_String); + + if (original_file_path == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, NetworkLocator, &__td, "Missing PID_NetworkLocator_URLString"); + return -1; + } + + // uriDecodeWString( original_file_path, NULL ); + // wurl_decode( original_file_path, original_file_path ); // TODO : What about URIParser lib ?! + + /* TODO find a better way to check if we're parsing audio */ + + if (aafi->ctx.current_essence) { + aafi->ctx.current_essence->original_file_path = original_file_path; + } else if (aafi->ctx.current_video_essence) { + aafi->ctx.current_video_essence->original_file_path = original_file_path; + } else { + DUMP_OBJ_ERROR (aafi, NetworkLocator, &__td, "aafi->ctx.current_essence AND aafi->ctx.current_video_essence not set"); + return -1; + } + + DUMP_OBJ_INFO (aafi, NetworkLocator, &__td, ": %ls", original_file_path); + + return 0; +} + +static int +parse_EssenceData (AAF_Iface* aafi, aafObject* EssenceData, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + __td.eob = 1; + + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + if (audioEssence == NULL) { + DUMP_OBJ_ERROR (aafi, EssenceData, &__td, "aafi->ctx.current_essence not set"); + return -1; + } + + /* + * The EssenceData::Data property has the stored form SF_DATA_STREAM, so + * it holds the name of the Data stream, which should be located at + * /Path/To/EssenceData/DataStream + */ + + wchar_t* StreamName = aaf_get_propertyValue (EssenceData, PID_EssenceData_Data, &AAFTypeID_String); + + if (StreamName == NULL) { + DUMP_OBJ_ERROR (aafi, EssenceData, &__td, "Missing PID_EssenceData_Data"); + return -1; + } + + wchar_t DataPath[CFB_PATH_NAME_SZ]; + memset (DataPath, 0x00, sizeof (DataPath)); + + wchar_t* path = aaf_get_ObjectPath (EssenceData); + + swprintf (DataPath, CFB_PATH_NAME_SZ, L"%" WPRIws L"/%" WPRIws, path, StreamName); + + free (StreamName); + + cfbNode* DataNode = cfb_getNodeByPath (aafi->aafd->cfbd, DataPath, 0); + + if (DataNode == NULL) { + DUMP_OBJ_ERROR (aafi, EssenceData, &__td, "Could not retrieve Data stream node %ls", DataPath); + return -1; + } + + audioEssence->node = DataNode; + + audioEssence->is_embedded = 1; /* TODO to be set elsewhere ? */ + + /* disable raw data byte length, because we want it to be the exact audio length in samples */ + + // uint64_t dataLen = cfb_getNodeStreamLen( aafi->aafd->cfbd, DataNode ); + // + // if ( dataLen == 0 ) { + // DUMP_OBJ_WARNING( aafi, EssenceData, &__td, "Got 0 Bytes Data stream length" ); + // return -1; + // } + // else { + // DUMP_OBJ( aafi, EssenceData, &__td ); + // } + // + // /* NOTE Might be tweaked by aafi_parse_audio_summary() */ + // audioEssence->length = dataLen; + + return 0; +} + +/* **************************************************************************** + * C o m p o n e n t + * **************************************************************************** + * + * Component (abs) + * | + * ,-----------. + * | | + * Transition Segment (abs) + * | + * |--> Sequence + * |--> Filler + * |--> TimeCode + * |--> OperationGroup + * `--> SourceReference (abs) + * | + * `--> SourceClip + */ + +static int +parse_Component (AAF_Iface* aafi, aafObject* Component, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + if (aafUIDCmp (Component->Class->ID, &AAFClassID_Transition)) { + /* + * A Transition between a Filler and a SourceClip sets a Fade In. + * A Transition between a SourceClip and a Filler sets a Fade Out. + * A Transition between two SourceClips sets a Cross-Fade. + * + * Since the Transition applies to the elements that suround it in + * the Sequence, the OperationGroup::InputSegments is then left unused. + */ + + parse_Transition (aafi, Component, &__td); + } else { + aafi_parse_Segment (aafi, Component, &__td); + } + + return 0; +} + +static int +parse_Transition (AAF_Iface* aafi, aafObject* Transition, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + aafUID_t* DataDefinition = get_Component_DataDefinition (aafi, Transition); + + if (DataDefinition == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Transition, &__td, "Could not retrieve DataDefinition"); + return -1; + } + + if (!aafUIDCmp (DataDefinition, &AAFDataDef_Sound) && + !aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + DUMP_OBJ_ERROR (aafi, Transition, &__td, "Current implementation only supports Transition inside Audio Tracks"); + return -1; + } + + int64_t* length = aaf_get_propertyValue (Transition, PID_Component_Length, &AAFTypeID_LengthType); + + if (length == NULL) { + DUMP_OBJ_ERROR (aafi, Transition, &__td, "Missing PID_Component_Length"); + return -1; + } + + int flags = 0; + + if (Transition->prev != NULL && aafUIDCmp (Transition->prev->Class->ID, &AAFClassID_Filler)) { + flags |= AAFI_TRANS_FADE_IN; + } else if (Transition->next != NULL && aafUIDCmp (Transition->next->Class->ID, &AAFClassID_Filler)) { + flags |= AAFI_TRANS_FADE_OUT; + } else if (Transition->next != NULL && aafUIDCmp (Transition->next->Class->ID, &AAFClassID_Filler) == 0 && + Transition->prev != NULL && aafUIDCmp (Transition->prev->Class->ID, &AAFClassID_Filler) == 0) { + flags |= AAFI_TRANS_XFADE; + } else { + DUMP_OBJ_ERROR (aafi, Transition, &__td, "Could not guess if type is FadeIn, FadeOut or xFade"); + return -1; + } + + aafiTimelineItem* Item = aafi_newTimelineItem (aafi, aafi->ctx.current_track, AAFI_TRANS); + + aafiTransition* Trans = Item->data; //(aafiTransition*)&Item->data; + + Trans->len = *length; + Trans->flags = flags; + + int missing_cutpt = 0; + + aafPosition_t* cut_point = aaf_get_propertyValue (Transition, PID_Transition_CutPoint, &AAFTypeID_PositionType); + + if (cut_point == NULL) { /* req */ + // DUMP_OBJ_WARNING( aafi, Transition, &__td, "Missing PID_Transition_CutPoint : Setting to Trans->len/2" ); + missing_cutpt = 1; + Trans->cut_pt = Trans->len / 2; // set default cutpoint to the middle of transition + } else { + Trans->cut_pt = *cut_point; + } + + aafObject* OpGroup = aaf_get_propertyValue (Transition, PID_Transition_OperationGroup, &AAFTypeID_OperationGroupStrongReference); + + if (OpGroup != NULL) { /* req */ + + if (missing_cutpt) { + DUMP_OBJ_WARNING (aafi, Transition, &__td, "Missing PID_Transition_CutPoint : Setting to Trans->len/2"); + } else { + DUMP_OBJ (aafi, Transition, &__td); + } + + /* + * Don't handle parse_OperationGroup() return code, since it should + * always fallback to default in case of failure. + */ + + aafi->ctx.current_transition = Trans; + parse_OperationGroup (aafi, OpGroup, &__td); + aafi->ctx.current_transition = NULL; + } else { + /* Setting fade to default */ + + __td.eob = 1; + + if (missing_cutpt) { + DUMP_OBJ_WARNING (aafi, Transition, &__td, "Missing PID_Transition_CutPoint AND PID_Transition_OperationGroup : Setting to Trans->len/2; Linear"); + } else { + DUMP_OBJ_WARNING (aafi, Transition, &__td, "Missing PID_Transition_OperationGroup : Setting to Linear interpolation"); + } + + Trans->flags |= (AAFI_INTERPOL_LINEAR | AAFI_TRANS_SINGLE_CURVE); + + Trans->time_a = calloc (2, sizeof (aafRational_t)); + Trans->value_a = calloc (2, sizeof (aafRational_t)); + + Trans->time_a[0].numerator = 0; + Trans->time_a[0].denominator = 0; + Trans->time_a[1].numerator = 1; + Trans->time_a[1].denominator = 1; + + if (Trans->flags & AAFI_TRANS_FADE_IN || + Trans->flags & AAFI_TRANS_XFADE) { + Trans->value_a[0].numerator = 0; + Trans->value_a[0].denominator = 0; + Trans->value_a[1].numerator = 1; + Trans->value_a[1].denominator = 1; + } else if (Trans->flags & AAFI_TRANS_FADE_OUT) { + Trans->value_a[0].numerator = 1; + Trans->value_a[0].denominator = 1; + Trans->value_a[1].numerator = 0; + Trans->value_a[1].denominator = 0; + } + } + + aafi->ctx.current_track->current_pos -= *length; + + return 0; +} + +static int +parse_NestedScope (AAF_Iface* aafi, aafObject* NestedScope, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + aafObject* Slot = NULL; + aafObject* Slots = aaf_get_propertyValue (NestedScope, PID_NestedScope_Slots, &AAFUID_NULL); + + if (Slots == NULL) { + DUMP_OBJ_ERROR (aafi, NestedScope, &__td, "Missing PID_NestedScope_Slots"); + return -1; + } + + DUMP_OBJ (aafi, NestedScope, &__td); + + int i = 0; + + aaf_foreach_ObjectInSet (&Slot, Slots, NULL) + { + __td.ll[__td.lv] = (Slots->Header->_entryCount > 1) ? (Slots->Header->_entryCount - i++) : 0; //(MobSlot->next) ? 1 : 0; + aafi_parse_Segment (aafi, Slot, &__td); + } + + /* TODO should we take aafi_parse_Segment() return code into account ? */ + + return 0; +} + +int +aafi_parse_Segment (AAF_Iface* aafi, aafObject* Segment, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + if (aafUIDCmp (Segment->Class->ID, &AAFClassID_Sequence)) { + return parse_Sequence (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_SourceClip)) { + return parse_SourceClip (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_OperationGroup)) { + return parse_OperationGroup (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_Filler)) { + return parse_Filler (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_Selector)) { + return parse_Selector (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_NestedScope)) { + return parse_NestedScope (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_Timecode)) { + /* + * TODO can contain sequence ? other Timecode SMPTE .. + */ + + return parse_Timecode (aafi, Segment, &__td); + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_DescriptiveMarker)) { + if (resolve_AAF (aafi)) { + resolve_parse_aafObject_DescriptiveMarker (aafi, Segment, &__td); + } else { + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, Segment, &__td); + return -1; + } + } else if (aafUIDCmp (Segment->Class->ID, &AAFClassID_EssenceGroup)) { + /* + * Should provide support for multiple essences representing the same + * source material with different resolution, compression, codec, etc. + * + * TODO To be tested with Avid and rendered effects. + */ + + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, Segment, &__td); + return -1; + } else { + __td.lv++; + DUMP_OBJ_NO_SUPPORT (aafi, Segment, &__td); + } + + return 0; +} + +static int +parse_Filler (AAF_Iface* aafi, aafObject* Filler, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + __td.eob = 1; + + aafUID_t* DataDefinition = get_Component_DataDefinition (aafi, Filler); + + if (DataDefinition == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Filler, &__td, "Could not retrieve DataDefinition"); + return -1; + } + + if (aafUIDCmp (Filler->Parent->Class->ID, &AAFClassID_TimelineMobSlot)) { + /* + * Just an empty track, do nothing. + */ + } else if (aafUIDCmp (Filler->Parent->Class->ID, &AAFClassID_Sequence) || + aafUIDCmp (Filler->Parent->Class->ID, &AAFClassID_Selector)) { + /* + * This represents an empty space on the timeline, between two clips + * which is Component::Length long. + */ + + int64_t* length = aaf_get_propertyValue (Filler, PID_Component_Length, &AAFTypeID_LengthType); + + if (length == NULL) { /* probably req for Filler */ + DUMP_OBJ_ERROR (aafi, Filler, &__td, "Missing PID_Component_Length"); + return -1; + } + + if (aafUIDCmp (DataDefinition, &AAFDataDef_Sound) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + aafi->ctx.current_track->current_pos += *length; + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Picture) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyPicture)) { + aafi->Video->Tracks->current_pos += *length; + } + + } else { + DUMP_OBJ_NO_SUPPORT (aafi, Filler, &__td); + return -1; + } + + DUMP_OBJ (aafi, Filler, &__td); + + return 0; +} + +static int +parse_Sequence (AAF_Iface* aafi, aafObject* Sequence, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + aafObject* Component = NULL; + aafObject* Components = aaf_get_propertyValue (Sequence, PID_Sequence_Components, &AAFTypeID_ComponentStrongReferenceVector); + + if (Components == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Sequence, &__td, "Missing PID_Sequence_Components"); + return -1; + } + + DUMP_OBJ (aafi, Sequence, &__td); + + int i = 0; + + aaf_foreach_ObjectInSet (&Component, Components, NULL) + { + __td.ll[__td.lv] = (Components->Header->_entryCount > 1) ? (Components->Header->_entryCount - i++) : 0; //(MobSlot->next) ? 1 : 0; + parse_Component (aafi, Component, &__td); + } + + return 0; +} + +static int +parse_Timecode (AAF_Iface* aafi, aafObject* Timecode, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + __td.eob = 1; + + aafPosition_t* tc_start = aaf_get_propertyValue (Timecode, PID_Timecode_Start, &AAFTypeID_PositionType); + + if (tc_start == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "Missing PID_Timecode_Start"); + return -1; + } + + uint16_t* tc_fps = aaf_get_propertyValue (Timecode, PID_Timecode_FPS, &AAFTypeID_UInt16); + + if (tc_fps == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "Missing PID_Timecode_FPS"); + return -1; + } + + uint8_t* tc_drop = aaf_get_propertyValue (Timecode, PID_Timecode_Drop, &AAFTypeID_UInt8); + + if (tc_drop == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "Missing PID_Timecode_Drop"); + return -1; + } + + /* TODO this should be retrieved directly from TimelineMobSlot */ + + aafObject* ParentMobSlot = get_Object_Ancestor (aafi, Timecode, &AAFClassID_MobSlot); + + if (ParentMobSlot == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "Could not retrieve parent MobSlot"); + return -1; + } + + aafRational_t* tc_edit_rate = aaf_get_propertyValue (ParentMobSlot, PID_TimelineMobSlot_EditRate, &AAFTypeID_Rational); + + if (tc_edit_rate == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "Missing parent MobSlot PID_TimelineMobSlot_EditRate"); + return -1; + } + + if (aafi->Timecode) { + DUMP_OBJ_WARNING (aafi, Timecode, &__td, "Timecode was already set, ignoring (%lu, %u fps)", *tc_start, *tc_fps); + return -1; + } + /* TODO allocate in specific function */ + + aafiTimecode* tc = calloc (sizeof (aafiTimecode), sizeof (unsigned char)); + + if (tc == NULL) { + DUMP_OBJ_ERROR (aafi, Timecode, &__td, "calloc() : %s", strerror (errno)); + return -1; + } + + tc->start = *tc_start; + tc->fps = *tc_fps; + tc->drop = *tc_drop; + tc->edit_rate = tc_edit_rate; + + aafi->Timecode = tc; + + DUMP_OBJ (aafi, Timecode, &__td); + + return 0; +} + +static int +parse_OperationGroup (AAF_Iface* aafi, aafObject* OpGroup, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (!aaf_get_property (OpGroup, PID_OperationGroup_InputSegments) && + !aaf_get_property (OpGroup, PID_OperationGroup_Parameters)) { + __td.eob = 1; + } + + aafObject* ParentMob = get_Object_Ancestor (aafi, OpGroup, &AAFClassID_Mob); + + if (ParentMob == NULL) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Could not retrieve parent Mob"); + return -1; + } + + if (!aafUIDCmp (ParentMob->Class->ID, &AAFClassID_CompositionMob)) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "OperationGroup parser is currently implemented for AAFClassID_CompositionMob children only"); + return -1; + } + + aafUID_t* OperationIdentification = get_OperationGroup_OperationIdentification (aafi, OpGroup); + + /* PRINT OPERATIONDEFINITIONS */ + + // aafObject * Parameters = aaf_get_propertyValue( OpGroup, PID_OperationGroup_Parameters ); + // + // if ( Parameters ) { + // aafObject * Param = NULL; + // + // aaf_foreach_ObjectInSet( &Param, Parameters, NULL ) { + // aafUID_t *ParamDef = aaf_get_propertyValue( Param, PID_Parameter_Definition, &AAFTypeID_AUID ); + // debug( " OpDef %ls (%ls) | %ls", aaft_OperationDefToText(aafi->aafd, OperationIdentification), AUIDToText( ParamDef ), aaft_ParameterToText( aafi->aafd, ParamDef ) ); + // } + // } + + // if ( aafUIDCmp( aafi->ctx.Mob->Class->ID, &AAFClassID_MasterMob ) ) { + // + // /* + // * TODO: This was seen in the spec, but never encountered in real world. + // */ + // + // aafi_trace_obj( aafi, Segment, ANSI_COLOR_RED ); + // error( "MobSlot::Segment > OperationGroup Not implemented yet." ); + // return -1; + // + // } + + int rc = 0; + + if (aafUIDCmp (OpGroup->Parent->Class->ID, &AAFClassID_Transition)) { + aafiTransition* Trans = aafi->ctx.current_transition; + + if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioDissolve)) { + /* + * Mono Audio Dissolve (Fade, Cross Fade) + * + * The same parameter (curve/level) is applied to the outgoing fade on first + * clip (if any) and to the incoming fade on second clip (if any). + */ + + // __td.eob = 1; + + Trans->flags |= AAFI_TRANS_SINGLE_CURVE; + + int set_default = 0; + + aafObject* Param = NULL; + aafObject* Parameters = aaf_get_propertyValue (OpGroup, PID_OperationGroup_Parameters, &AAFTypeID_ParameterStrongReferenceVector); /* opt */ + + if (Parameters) { + /* Retrieve AAFParameterDef_Level parameter */ + + aaf_foreach_ObjectInSet (&Param, Parameters, NULL) + { + aafUID_t* ParamDef = aaf_get_propertyValue (Param, PID_Parameter_Definition, &AAFTypeID_AUID); + + if (aafUIDCmp (ParamDef, &AAFParameterDef_Level)) + break; + } + } else { + // DUMP_OBJ_WARNING( aafi, OpGroup, &__td, "Missing PID_OperationGroup_Parameters: Falling back to Linear" ); + set_default = 1; + } + + if (Param) { + DUMP_OBJ (aafi, OpGroup, &__td); + + if (aaf_get_property (OpGroup, PID_OperationGroup_InputSegments)) { + __td.ll[__td.lv] = 2; + } + + if (parse_Parameter (aafi, Param, &__td) < 0) { + set_default = 1; + } + + __td.ll[__td.lv] = 0; + } else { + /* + * Do not notify exception since this case is standard compliant : + * + * ParameterDef_Level (optional; default is a VaryingValue object with + * two control points: Value 0 at time 0, and value 1 at time 1) + */ + + __td.eob = 1; + DUMP_OBJ (aafi, OpGroup, &__td); + + // DUMP_OBJ_WARNING( aafi, OpGroup, &__td, "Missing Parameter AAFParameterDef_Level: Setting to Linear" ); + + set_default = 1; + } + + if (set_default) { + /* + * ParameterDef_Level (optional; default is a VaryingValue object + * with two control points: Value 0 at time 0, and value 1 at time 1) + * + * This is also a fallback in case of parse_Parameter() failure. + */ + + Trans->flags |= AAFI_INTERPOL_LINEAR; + + Trans->time_a = calloc (2, sizeof (aafRational_t)); + Trans->value_a = calloc (2, sizeof (aafRational_t)); + + Trans->time_a[0].numerator = 0; + Trans->time_a[0].denominator = 0; + Trans->time_a[1].numerator = 1; + Trans->time_a[1].denominator = 1; + + if (Trans->flags & AAFI_TRANS_FADE_IN || + Trans->flags & AAFI_TRANS_XFADE) { + Trans->value_a[0].numerator = 0; + Trans->value_a[0].denominator = 0; + Trans->value_a[1].numerator = 1; + Trans->value_a[1].denominator = 1; + } else if (Trans->flags & AAFI_TRANS_FADE_OUT) { + Trans->value_a[0].numerator = 1; + Trans->value_a[0].denominator = 1; + Trans->value_a[1].numerator = 0; + Trans->value_a[1].denominator = 0; + } + } + + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_TwoParameterMonoAudioDissolve)) { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + /* Two distinct parameters are used for the outgoing and incoming fades. */ + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_StereoAudioDissolve)) { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + /* TODO Unknown usage and implementation */ + } else { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + } + + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_AudioChannelCombiner)) { + DUMP_OBJ (aafi, OpGroup, &__td); + + aafObject* InputSegment = NULL; + aafObject* InputSegments = aaf_get_propertyValue (OpGroup, PID_OperationGroup_InputSegments, &AAFTypeID_SegmentStrongReferenceVector); + + __td.ll[__td.lv] = InputSegments->Header->_entryCount; + + aafi->ctx.current_clip_is_combined = 1; + aafi->ctx.current_combined_clip_total_channel = InputSegments->Header->_entryCount; + aafi->ctx.current_combined_clip_channel_num = 0; + + aaf_foreach_ObjectInSet (&InputSegment, InputSegments, NULL) + { + aafi_parse_Segment (aafi, InputSegment, &__td); + + aafi->ctx.current_combined_clip_channel_num++; + __td.ll[__td.lv]--; + } + + /* + * Sets the track format. + */ + + aafiAudioTrack* current_track = (aafiAudioTrack*)aafi->ctx.current_track; + + aafiTrackFormat_e track_format = AAFI_TRACK_FORMAT_UNKNOWN; + + if (aafi->ctx.current_combined_clip_total_channel == 2) { + track_format = AAFI_TRACK_FORMAT_STEREO; + } else if (aafi->ctx.current_combined_clip_total_channel == 6) { + track_format = AAFI_TRACK_FORMAT_5_1; + } else if (aafi->ctx.current_combined_clip_total_channel == 8) { + track_format = AAFI_TRACK_FORMAT_7_1; + } else { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Unknown track format (%u)", aafi->ctx.current_combined_clip_total_channel); + + /* + * Reset multichannel track context. + */ + + aafi->ctx.current_clip_is_combined = 0; + aafi->ctx.current_combined_clip_total_channel = 0; + aafi->ctx.current_combined_clip_channel_num = 0; + + return -1; + } + + if (current_track->format != AAFI_TRACK_FORMAT_NOT_SET && + current_track->format != track_format) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Track format (%u) does not match current clip (%u)", current_track->format, track_format); + + /* + * Reset multichannel track context. + */ + + aafi->ctx.current_clip_is_combined = 0; + aafi->ctx.current_combined_clip_total_channel = 0; + aafi->ctx.current_combined_clip_channel_num = 0; + + return -1; + } + + current_track->format = track_format; + + /* + * Reset multichannel track context. + */ + + aafi->ctx.current_clip_is_combined = 0; + aafi->ctx.current_combined_clip_total_channel = 0; + aafi->ctx.current_combined_clip_channel_num = 0; + + // return; + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioGain)) { + aafObject* Param = NULL; + aafObject* Parameters = aaf_get_propertyValue (OpGroup, PID_OperationGroup_Parameters, &AAFTypeID_ParameterStrongReferenceVector); + + if (Parameters == NULL) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Missing PID_OperationGroup_Parameters"); + rc = -1; + goto end; // we still have to parse segments + } + + /* Retrieve AAFParameterDef_Amplitude parameter */ + + aaf_foreach_ObjectInSet (&Param, Parameters, NULL) + { + aafUID_t* ParamDef = aaf_get_propertyValue (Param, PID_Parameter_Definition, &AAFTypeID_AUID); + + if (aafUIDCmp (ParamDef, &AAFParameterDef_Amplitude)) + break; + } + + if (Param == NULL) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Missing Parameter ParameterDef_Amplitude"); + rc = -1; + goto end; // we still have to parse segments + } + + DUMP_OBJ (aafi, OpGroup, &__td); + + __td.ll[__td.lv] = 2; + + rc = parse_Parameter (aafi, Param, &__td); + + // if ( rc == 0 ) { + // DUMP_OBJ( aafi, OpGroup, &__td ); + // } + // else { + // DUMP_OBJ_ERROR( aafi, OpGroup, &__td, "Failed parsing parameter" ); + // } + + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_StereoAudioGain)) { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + /* TODO Unknown usage and implementation */ + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioPan)) { + /* TODO Should Only be Track-based (first Segment of TimelineMobSlot.) */ + + /* + * We have to loop because of custom Parameters. + * Seen in AVID Media Composer AAFs (test.aaf). TODO ParamDef PanVol_IsTrimGainEffect ? + */ + + aafObject* Param = NULL; + aafObject* Parameters = aaf_get_propertyValue (OpGroup, PID_OperationGroup_Parameters, &AAFTypeID_ParameterStrongReferenceVector); + + if (Parameters == NULL) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Missing PID_OperationGroup_Parameters"); + rc = -1; + goto end; // we still have to parse segments + } + + /* Retrieve AAFParameterDef_Pan parameter */ + + aaf_foreach_ObjectInSet (&Param, Parameters, NULL) + { + aafUID_t* ParamDef = aaf_get_propertyValue (Param, PID_Parameter_Definition, &AAFTypeID_AUID); + + if (aafUIDCmp (ParamDef, &AAFParameterDef_Pan)) + break; + } + + if (Param == NULL) { + DUMP_OBJ_ERROR (aafi, OpGroup, &__td, "Missing Parameter ParameterDef_Amplitude"); + rc = -1; + goto end; // we still have to parse segments + } + + DUMP_OBJ (aafi, OpGroup, &__td); + + __td.ll[__td.lv] = 2; + + rc = parse_Parameter (aafi, Param, &__td); + + // if ( rc == 0 ) { + // DUMP_OBJ( aafi, OpGroup, &__td ); + // } + // else { + // DUMP_OBJ_ERROR( aafi, OpGroup, &__td, "Failed parsing parameter" ); + // } + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioMixdown)) { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + /* TODO Unknown usage and implementation */ + } else { + DUMP_OBJ_NO_SUPPORT (aafi, OpGroup, &__td); + } + +end: + + /* + * Parses Segments in the OperationGroup::InputSegments, only if + * OperationGroup is not a Transition as a Transition has no InputSegments, + * and not an AudioChannelCombiner as they were already parsed. + */ + + if (aafUIDCmp (OpGroup->Parent->Class->ID, &AAFClassID_Transition) == 0 && + aafUIDCmp (OperationIdentification, &AAFOperationDef_AudioChannelCombiner) == 0) { + aafObject* InputSegment = NULL; + aafObject* InputSegments = aaf_get_propertyValue (OpGroup, PID_OperationGroup_InputSegments, &AAFTypeID_SegmentStrongReferenceVector); + + int i = 0; + __td.ll[__td.lv] = (InputSegments) ? InputSegments->Header->_entryCount : 0; + + aaf_foreach_ObjectInSet (&InputSegment, InputSegments, NULL) + { + __td.ll[__td.lv] = __td.ll[__td.lv] - i++; + aafi_parse_Segment (aafi, InputSegment, &__td); + } + } + + /* End of current OperationGroup context. */ + + aafObject* Obj = OpGroup; + for (; Obj != NULL && aafUIDCmp (Obj->Class->ID, &AAFClassID_ContentStorage) == 0; Obj = Obj->Parent) + if (!aafUIDCmp (Obj->Class->ID, &AAFClassID_OperationGroup)) + break; + + if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioGain)) { + if (!aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot)) { + if (aafi->ctx.clips_using_gain == 0) { + aafi_freeAudioGain (aafi->ctx.current_clip_gain); + } + + if (aafi->ctx.clips_using_automation == 0) { + aafi_freeAudioGain (aafi->ctx.current_clip_automation); + } + + /* Clip-based Gain */ + aafi->ctx.current_clip_is_muted = 0; + aafi->ctx.current_clip_gain = NULL; + aafi->ctx.current_clip_automation = NULL; + aafi->ctx.clips_using_gain = 0; + aafi->ctx.clips_using_automation = 0; + } + + // free( aafi->ctx.current_track->gain ); + // aafi->ctx.current_track->gain = NULL; + } + + return rc; +} + +static int +parse_SourceClip (AAF_Iface* aafi, aafObject* SourceClip, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + __td.hc = 1; // link to MasterMob, SourceMob + + aafUID_t* DataDefinition = get_Component_DataDefinition (aafi, SourceClip); + + if (DataDefinition == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve DataDefinition"); + return -1; + } + + aafObject* ParentMob = get_Object_Ancestor (aafi, SourceClip, &AAFClassID_Mob); + + if (ParentMob == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve parent Mob"); + return -1; + } + + aafMobID_t* parentMobID = aaf_get_propertyValue (ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType); + + if (parentMobID == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing parent Mob PID_Mob_MobID"); + return -1; + } + + aafMobID_t* sourceID = aaf_get_propertyValue (SourceClip, PID_SourceReference_SourceID, &AAFTypeID_MobIDType); + + if (sourceID == NULL) { /* opt */ + /* NOTE: PID_SourceReference_SourceID is optionnal, there might be none. */ + // DUMP_OBJ_ERROR( aafi, SourceClip, &__td, "Missing PID_SourceReference_SourceID" ); + // return -1; + } + + uint32_t* SourceMobSlotID = aaf_get_propertyValue (SourceClip, PID_SourceReference_SourceMobSlotID, &AAFTypeID_UInt32); + + if (SourceMobSlotID == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing PID_SourceReference_SourceMobSlotID"); + return -1; + } + + /* + * TODO: handle SourceReference::MonoSourceSlotIDs and associated conditional rules. + * (Multi-channels) + */ + + aafObject* refMob = NULL; + aafObject* refMobSlot = NULL; + + if (sourceID == NULL) { + /* + * p.49 : To create a SourceReference that refers to a MobSlot within + * the same Mob as the SourceReference, omit the SourceID property. + * + * [SourceID] Identifies the Mob being referenced. If the property has a + * value 0, it means that the Mob owning the SourceReference describes + * the original source. + * + * TODO: in that case, is MobSlots NULL ? + */ + + // sourceID = parentMobID; + // refMob = ParentMob; + } else { + refMob = aaf_get_MobByID (aafi->aafd->Mobs, sourceID); + + if (refMob == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve target Mob by ID : %ls", aaft_MobIDToText (sourceID)); + return -1; + } + + aafObject* refMobSlots = aaf_get_propertyValue (refMob, PID_Mob_Slots, &AAFTypeID_MobSlotStrongReferenceVector); + + if (refMobSlots == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing target Mob PID_Mob_Slots"); + return -1; + } + + refMobSlot = aaf_get_MobSlotBySlotID (refMobSlots, *SourceMobSlotID); + + if (refMobSlot == NULL) { + /* TODO check if there is a workaround : + * AAFInfo --aaf-clips '/home/agfline/Developpement/libaaf_testfiles/ADP/ADP_STTRACK_CLIPGAIN_TRACKGAIN_XFADE_NOOPTONEXPORT.aaf' + */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve target MobSlot ID : %u", *SourceMobSlotID); + return -1; + } + } + + /* *** Clip *** */ + + if (aafUIDCmp (ParentMob->Class->ID, &AAFClassID_CompositionMob)) { + // DUMP_OBJ( aafi, SourceClip, &__td ); + + int64_t* length = aaf_get_propertyValue (SourceClip, PID_Component_Length, &AAFTypeID_LengthType); + + if (length == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing PID_Component_Length"); + return -1; + } + + int64_t* startTime = aaf_get_propertyValue (SourceClip, PID_SourceClip_StartTime, &AAFTypeID_PositionType); + + if (startTime == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing PID_SourceClip_StartTime"); + return -1; + } + + struct aafiContext ctxBackup; + + aafUID_t* CurrentUsageCode = aaf_get_propertyValue (ParentMob, PID_Mob_UsageCode, &AAFTypeID_UsageType); + + if (CurrentUsageCode == NULL) { + /* NOTE: PID_Mob_UsageCode is optionnal, there might be none. */ + // DUMP_OBJ_ERROR( aafi, SourceClip, &__td, "Missing PID_Mob_UsageCode" ); + // return -1; + } + + // if ( aafUIDCmp( aafi->aafd->Header.OperationalPattern, &AAFOPDef_EditProtocol ) ) + { + // if ( (CurrentUsageCode && aafUIDCmp( CurrentUsageCode, &AAFUsage_SubClip )) || CurrentUsageCode == NULL ) { + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_YELLOW ); + // } + // else { + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_MAGENTA ); + // } + + /* + * If SourceClip points to a CompositionMob instead of a MasterMob, we + * are at the begining (or inside) a derivation chain. + */ + + if (aafUIDCmp (refMob->Class->ID, &AAFClassID_CompositionMob)) { + // debug( "REF TO SUBCLIP" ); + // + // debug( "SourceClip::SourceID : %ls", aaft_MobIDToText( sourceID ) ); + // debug( "CurrentMob::MobID : %ls", aaft_MobIDToText( parentMobID ) ); + // debug( "SourceClip::SourceMobSlotID : %i", *SourceMobSlotID ); + // debug( "UsageCode : %ls", aaft_UsageCodeToText( UsageCode ) ); + + if (refMobSlot == NULL) { + /* TODO isn't it already checked above ? */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing target MobSlot"); + return -1; + } + + DUMP_OBJ (aafi, SourceClip, &__td); + + /* Only to print trace */ + __td.lv++; + DUMP_OBJ (aafi, refMob, &__td); + // __td.lv++; + + memcpy (&ctxBackup, &(aafi->ctx), sizeof (struct aafiContext)); + + RESET_CONTEXT (aafi->ctx); + + aafi->ctx.current_track = ctxBackup.current_track; + aafi->ctx.is_inside_derivation_chain = 1; + + parse_MobSlot (aafi, refMobSlot, &__td); + + void* new_clip = aafi->ctx.current_clip; + + memcpy (&(aafi->ctx), &ctxBackup, sizeof (struct aafiContext)); + + if (aafUIDCmp (DataDefinition, &AAFDataDef_Sound) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + aafi->ctx.current_clip = (aafiAudioClip*)new_clip; + + if (new_clip && aafUIDCmp (CurrentUsageCode, &AAFUsage_TopLevel)) { + /* + * All derivation chain calls ended. + * + * We came back at level zero of parse_SourceClip() nested calls, so + * the clip and its source was added, we only have to set its length, + * offset and gain with correct values. + * + * TODO: aafi->current_clip pointer to new_clip instead ? + */ + + ((aafiAudioClip*)new_clip)->len = *length; + ((aafiAudioClip*)new_clip)->essence_offset = *startTime; + ((aafiAudioClip*)new_clip)->gain = aafi->ctx.current_clip_gain; + ((aafiAudioClip*)new_clip)->automation = aafi->ctx.current_clip_automation; + ((aafiAudioClip*)new_clip)->mute = aafi->ctx.current_clip_is_muted; + aafi->ctx.clips_using_gain++; + aafi->ctx.clips_using_automation++; + + aafi->ctx.current_track->current_pos += ((aafiAudioClip*)new_clip)->len; + } + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Picture) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyPicture)) { + if (new_clip && aafUIDCmp (CurrentUsageCode, &AAFUsage_TopLevel)) { + /* + * All derivation chain calls ended. + * + * We came back at level zero of parse_SourceClip() nested calls, so + * the clip and its source was added, we only have to set its length, + * offset and gain with correct values. + */ + + ((aafiVideoClip*)new_clip)->len = *length; + ((aafiVideoClip*)new_clip)->essence_offset = *startTime; + + aafi->Video->Tracks->current_pos += ((aafiVideoClip*)new_clip)->len; + } + } + + return 0; + + } else if (aafUIDCmp (refMob->Class->ID, &AAFClassID_MasterMob)) { + /* + * We are inside the derivation chain and we reached the SourceClip + * pointing to MasterMob (the audio essence). + * + * Thus, we can add the clip and parse the audio essence normaly. + */ + } + } + + if (aafUIDCmp (DataDefinition, &AAFDataDef_Sound) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + // if ( *length == 1 ) { + // /* + // * If length equals 1 EditUnit, the clip is probably a padding for "Media Composer Compatibility". + // * Therefore, we don't need it. + // * + // * TODO BUT this could also be some rendered fade.. we should find a way to distinguish between the two. + // */ + // + // // aaf_dump_ObjectProperties( aafi->aafd, SourceClip ); + // + // warning( "Got a 1 EU length clip, probably some NLE compatibility padding : Skipping." ); + // + // + // + // if ( aafi->ctx.current_track_is_multichannel == 0 ) { + // aafi->ctx.current_pos += *length; + // } + // else { + // aafi->ctx.current_multichannel_track_clip_length = *length; + // } + // + // return -1; + // } + + if (aafi->ctx.current_clip_is_combined && + aafi->ctx.current_combined_clip_channel_num > 0) { + /* + * Parsing multichannel audio clip (AAFOperationDef_AudioChannelCombiner) + * We already parsed first SourceClip in AAFOperationDef_AudioChannelCombiner. + * We just have to check everything match for all clips left (each clip represents a channel) + */ + + if (aafi->ctx.current_clip->len != *length) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "SourceClip length does not match first one in AAFOperationDef_AudioChannelCombiner"); + return -1; + } + + if (!aafMobIDCmp (aafi->ctx.current_clip->masterMobID, sourceID)) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "SourceClip SourceID does not match first one in AAFOperationDef_AudioChannelCombiner"); + return -1; + } + + DUMP_OBJ (aafi, SourceClip, &__td); + return 0; + } + + /* + * Create new clip, only if we are parsing a single mono clip, or if + * we are parsing the first SourceClip describing a multichannel clip + * inside an AAFOperationDef_AudioChannelCombiner + */ + + aafiTimelineItem* item = aafi_newTimelineItem (aafi, aafi->ctx.current_track, AAFI_AUDIO_CLIP); + + aafiAudioClip* audioClip = item->data; //(aafiAudioClip*)&item->data; + + aafi->ctx.clips_using_gain++; + aafi->ctx.clips_using_automation++; + audioClip->gain = aafi->ctx.current_clip_gain; + audioClip->automation = aafi->ctx.current_clip_automation; + audioClip->mute = aafi->ctx.current_clip_is_muted; + audioClip->pos = aafi->ctx.current_track->current_pos; + audioClip->len = *length; + + audioClip->essence_offset = *startTime; + + aafi->ctx.current_clip = audioClip; + + /* + * p.49 : To create a SourceReference that refers to a MobSlot within + * the same Mob as the SourceReference, omit the SourceID property. + * + * NOTE: This should not happen here because The "CompositionMob > SourceClip::SourceID" + * should always point to the corresponding "MasterMob", that is a different Mob. + */ + + // if ( aafMobIDCmp( aafi->ctx.current_clip->masterMobID, sourceID ) ) { + // debug( "SAME_SOURCE_ID : %ls", AUIDToText(sourceID) ); + // } else { + // debug( "DIFFERENT_SOURCE_ID : %ls", AUIDToText(sourceID) ); + // } + + audioClip->masterMobID = sourceID; + + // if ( audioClip->masterMobID == NULL ) { + // audioClip->masterMobID = aaf_get_propertyValue( ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // warning( "Missing SourceReference::SourceID, retrieving from parent Mob." ); + // } + + if (!aafi->ctx.is_inside_derivation_chain) { + /* + * We DO NOT update current pos when SourceClip belongs to a sub CompositionMob + * because in that case, current pos was already updated by initial SourceClip + * pointing to AAFClassID_CompositionMob + +04606│├──◻ AAFClassID_TimelineMobSlot [slot:16 track:8] (DataDef : AAFDataDef_LegacySound) +02064││ └──◻ AAFClassID_Sequence +02037││ ├──◻ AAFClassID_Filler + ││ │ +02502││ ├──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioGain) (MetaProps: ComponentAttributeList[0xffcc]) +03780││ │ ├──◻ AAFClassID_ConstantValue +POS UPDATED HERE --> └──◻ AAFClassID_SourceClip +02842││ │ └──◻ AAFClassID_CompositionMob (UsageCode: AAFUsage_AdjustedClip) : Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3.new.01 (MetaProps: MobAttributeList[0xfff9] ConvertFrameRate[0xfff8]) +04606││ │ └──◻ AAFClassID_TimelineMobSlot [slot:2 track:2] (DataDef : AAFDataDef_LegacySound) +02502││ │ └──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioGain) +03780││ │ ├──◻ AAFClassID_ConstantValue +POS NOT UPDATED HERE ------------------> └──◻ AAFClassID_SourceClip +03085││ │ └──◻ AAFClassID_MasterMob (UsageCode: n/a) : Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3.new.01 (MetaProps: AppCode[0xfffa]) +04705││ │ └──◻ AAFClassID_TimelineMobSlot +03305││ │ └──◻ AAFClassID_SourceClip +04412││ │ ├──◻ AAFClassID_SourceMob (UsageCode: n/a) : Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3 (MetaProps: MobAttributeList[0xfff9]) +01400││ │ │ └──◻ AAFClassID_WAVEDescriptor +01555││ │ │ └──◻ AAFClassID_NetworkLocator : file:///MEDIA2/2199_Rapport_Astellas Main Content/audio/AX TEST.aaf + ││ │ │ +01800││ ├──◻ AAFClassID_Transition +02283││ │ └──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioDissolve) (MetaProps: ComponentAttributeList[0xffcc]) +03934││ │ └──◻ AAFClassID_VaryingValue + ││ │ +02502││ ├──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioGain) (MetaProps: ComponentAttributeList[0xffcc]) +03780││ │ ├──◻ AAFClassID_ConstantValue +02836││ │ └──◻ AAFClassID_SourceClip +02842││ │ └──◻ AAFClassID_CompositionMob (UsageCode: AAFUsage_AdjustedClip) : Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3.new.01 (MetaProps: MobAttributeList[0xfff9] ConvertFrameRate[0xfff8]) +04606││ │ └──◻ AAFClassID_TimelineMobSlot [slot:2 track:2] (DataDef : AAFDataDef_LegacySound) +02502││ │ └──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioGain) +03780││ │ ├──◻ AAFClassID_ConstantValue +03080││ │ └──◻ AAFClassID_SourceClip +03085││ │ └──◻ AAFClassID_MasterMob (UsageCode: n/a) : Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3.new.01 (MetaProps: AppCode[0xfffa]) +04705││ │ └──◻ AAFClassID_TimelineMobSlot +03270││ │ └──◻ AAFClassID_SourceClip Essence already parsed: Linking with Islamic Call to Prayer - Amazing Adhan by Edris Aslami.mp3.new.01 + ││ │ +02037││ └──◻ AAFClassID_Filler + */ + + aafi->ctx.current_track->current_pos += audioClip->len; + } + + if (aafi->ctx.current_clip_is_combined == 0) { + if (aafi->ctx.current_track->format != AAFI_TRACK_FORMAT_NOT_SET && + aafi->ctx.current_track->format != AAFI_TRACK_FORMAT_MONO) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Track format (%u) does not match current clip (%u)", aafi->ctx.current_track->format, AAFI_TRACK_FORMAT_MONO); + } else { + aafi->ctx.current_track->format = AAFI_TRACK_FORMAT_MONO; + } + } + + if (aafUIDCmp (refMob->Class->ID, &AAFClassID_MasterMob)) { + if (refMobSlot == NULL) { + /* TODO isn't it already checked above ? */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing target MobSlot"); + return -1; + } + + DUMP_OBJ (aafi, SourceClip, &__td); + + /* Only to print trace */ + __td.lv++; + DUMP_OBJ (aafi, refMob, &__td); + + memcpy (&ctxBackup, &(aafi->ctx), sizeof (struct aafiContext)); + + RESET_CONTEXT (aafi->ctx); + + aafi->ctx.current_track = ctxBackup.current_track; + aafi->ctx.current_clip = audioClip; + + parse_MobSlot (aafi, refMobSlot, &__td); + + memcpy (&(aafi->ctx), &ctxBackup, sizeof (struct aafiContext)); + + } else { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "RefMob isn't MasterMob : %ls", aaft_ClassIDToText (aafi->aafd, refMob->Class->ID)); + // parse_CompositionMob( ) + return -1; + } + + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Picture) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyPicture)) { + if (aafi->Video->Tracks->Items) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Current implementation supports only one video clip"); + return -1; + } + + /* Add the new clip */ + + aafiTimelineItem* item = aafi_newTimelineItem (aafi, aafi->Video->Tracks, AAFI_VIDEO_CLIP); + + aafiVideoClip* videoClip = item->data; //(aafiVideoClip*)&item->data; + + videoClip->pos = aafi->Video->Tracks->current_pos; + videoClip->len = *length; + + videoClip->essence_offset = *startTime; + + /* + * p.49 : To create a SourceReference that refers to a MobSlot within + * the same Mob as the SourceReference, omit the SourceID property. + * + * NOTE: This should not happen here because The "CompositionMob > SourceClip::SourceID" + * should always point to the corresponding "MasterMob", that is a different Mob. + */ + + videoClip->masterMobID = sourceID; + + // if ( videoClip->masterMobID == NULL ) { + // videoClip->masterMobID = aaf_get_propertyValue( ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // warning( "Missing SourceReference::SourceID, retrieving from parent Mob." ); + // } + + if (!aafUIDCmp (aafi->aafd->Header.OperationalPattern, &AAFOPDef_EditProtocol) || + aafUIDCmp (CurrentUsageCode, &AAFUsage_TopLevel)) { + /* + * NOTE for AAFOPDef_EditProtocol only : + * + * If SourceClip belongs to a TopLevel Mob, we can update position. + * Otherwise, it means we are inside a derivation chain ( ie: TopLevelCompositionMob -> SourceClip -> SubLevel:CompositionMob -> SourceClip ) + * and the clip length is not the good one. In that case, position is updated above. + */ + + aafi->Video->Tracks->current_pos += videoClip->len; + } + + aafi->ctx.current_video_clip = videoClip; + + if (aafUIDCmp (refMob->Class->ID, &AAFClassID_MasterMob)) { + if (refMobSlot == NULL) { + /* TODO isn't it already checked above ? */ + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Missing target MobSlot"); + return -1; + } + + DUMP_OBJ (aafi, SourceClip, &__td); + + /* Only to print trace */ + __td.lv++; + DUMP_OBJ (aafi, refMob, &__td); + + // memcpy( &ctxBackup, &(aafi->ctx), sizeof(struct aafiContext) ); + // + // RESET_CONTEXT( aafi->ctx ); + + parse_MobSlot (aafi, refMobSlot, &__td); + + // memcpy( &(aafi->ctx), &ctxBackup, sizeof(struct aafiContext) ); + } + } + } + + /* *** Essence *** */ + + else if (aafUIDCmp (ParentMob->Class->ID, &AAFClassID_MasterMob)) { + aafMobID_t* masterMobID = aaf_get_propertyValue (ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType); + + if (masterMobID == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve parent Mob PID_Mob_MobID"); + return -1; + } + + aafObject* ParentMobSlot = get_Object_Ancestor (aafi, SourceClip, &AAFClassID_MobSlot); + + if (ParentMobSlot == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve parent MobSlot"); + return -1; + } + + uint32_t* masterMobSlotID = aaf_get_propertyValue (ParentMobSlot, PID_MobSlot_SlotID, &AAFTypeID_UInt32); + + // uint32_t *essenceChannelNum = aaf_get_propertyValue( ParentMobSlot, PID_MobSlot_PhysicalTrackNumber, &AAFTypeID_UInt32 ); + // + // if ( essenceChannelNum == NULL ) { /* opt */ + // debug( "PhysicalTrackNumber: NOT SET" ); + // } else { + // debug( "PhysicalTrackNumber: %u", *essenceChannelNum ); + // } + + if (aafUIDCmp (DataDefinition, &AAFDataDef_Sound) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + /* Check if this Essence has already been retrieved */ + + // int slotID = MobSlot->Entry->_localKey; + + // aafObject *Obj = aaf_get_MobByID( aafi->aafd, SourceID ); + // debug( "SourceMobID : %ls", aaft_MobIDToText(SourceID) ); + // debug( "MasterMobID : %ls", aaft_MobIDToText(mobID) ); + + if (!aafi->ctx.current_clip) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "aafi->ctx.current_clip not set"); + return -1; + } + + aafiAudioEssence* audioEssence = NULL; + + foreachEssence (audioEssence, aafi->Audio->Essences) + { + if (aafMobIDCmp (audioEssence->sourceMobID, sourceID) && audioEssence->sourceMobSlotID == (unsigned)*SourceMobSlotID) { + /* Essence already retrieved */ + aafi->ctx.current_clip->Essence = audioEssence; + __td.eob = 1; + DUMP_OBJ_INFO (aafi, SourceClip, &__td, "Essence already parsed: Linking with %ls", audioEssence->file_name); + return 0; + } + } + + /* new Essence, carry on. */ + + audioEssence = aafi_newAudioEssence (aafi); + + aafi->ctx.current_essence = audioEssence; + + audioEssence->masterMobSlotID = *masterMobSlotID; + audioEssence->masterMobID = masterMobID; + + audioEssence->file_name = aaf_get_propertyValue (ParentMob, PID_Mob_Name, &AAFTypeID_String); + + if (audioEssence->file_name == NULL) { + debug ("Missing MasterMob::PID_Mob_Name (essence file name)"); + } + + /* + * p.49 : To create a SourceReference that refers to a MobSlot within + * the same Mob as the SourceReference, omit the SourceID property. + */ + + audioEssence->sourceMobSlotID = *SourceMobSlotID; + audioEssence->sourceMobID = sourceID; + + // if ( audioEssence->sourceMobID == NULL ) { + // audioEssence->sourceMobID = aaf_get_propertyValue( ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // warning( "Could not retrieve SourceReference::SourceID, retrieving from parent Mob." ); + // } + + DUMP_OBJ (aafi, SourceClip, &__td); + + aafObject* SourceMob = aaf_get_MobByID (aafi->aafd->Mobs, audioEssence->sourceMobID); + + if (SourceMob == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve SourceMob by ID : %ls", aaft_MobIDToText (audioEssence->sourceMobID)); + return -1; + } + + audioEssence->SourceMob = SourceMob; + + aafObject* EssenceData = get_EssenceData_By_MobID (aafi, audioEssence->sourceMobID); + + if (EssenceData) + __td.ll[__td.lv] = 2; + + parse_SourceMob (aafi, SourceMob, &__td); + + __td.ll[__td.lv] = 0; + + if (EssenceData == NULL) { + /* + * It means essence is not embedded. + */ + // return -1; + } else { + parse_EssenceData (aafi, EssenceData, &__td); + } + + audioEssence->unique_file_name = build_unique_audiofilename (aafi, audioEssence); + + aafi->ctx.current_clip->Essence = audioEssence; + + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_MAGENTA ); + + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Picture) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyPicture)) { + /* Check if this Essence has already been retrieved */ + + // int slotID = MobSlot->Entry->_localKey; + + // aafObject *Obj = aaf_get_MobByID( aafi->aafd, sourceID ); + // debug( "SourceMobID : %ls", aaft_MobIDToText(sourceID) ); + // debug( "MasterMobID : %ls", aaft_MobIDToText(mobID) ); + + if (!aafi->ctx.current_video_clip) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "aafi->ctx.current_video_clip not set"); + return -1; + } + + aafiVideoEssence* videoEssence = NULL; + + foreachEssence (videoEssence, aafi->Video->Essences) + { + if (aafMobIDCmp (videoEssence->sourceMobID, sourceID) && videoEssence->sourceMobSlotID == (unsigned)*SourceMobSlotID) { + /* Essence already retrieved */ + aafi->ctx.current_video_clip->Essence = videoEssence; + return 0; + } + } + + /* new Essence, carry on. */ + + videoEssence = aafi_newVideoEssence (aafi); + + aafi->ctx.current_video_clip->Essence = videoEssence; + + videoEssence->masterMobSlotID = *masterMobSlotID; + videoEssence->masterMobID = masterMobID; + + videoEssence->file_name = aaf_get_propertyValue (ParentMob, PID_Mob_Name, &AAFTypeID_String); + + /* + * p.49 : To create a SourceReference that refers to a MobSlot within + * the same Mob as the SourceReference, omit the SourceID property. + */ + + videoEssence->sourceMobSlotID = *SourceMobSlotID; + videoEssence->sourceMobID = sourceID; + + // if ( audioEssence->sourceMobID == NULL ) { + // audioEssence->sourceMobID = aaf_get_propertyValue( ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // warning( "Could not retrieve SourceReference::SourceID, retrieving from parent Mob." ); + // } + + aafi->ctx.current_video_essence = videoEssence; + + DUMP_OBJ (aafi, SourceClip, &__td); + + aafObject* SourceMob = aaf_get_MobByID (aafi->aafd->Mobs, videoEssence->sourceMobID); + + if (SourceMob == NULL) { + DUMP_OBJ_ERROR (aafi, SourceClip, &__td, "Could not retrieve SourceMob by ID : %ls", aaft_MobIDToText (videoEssence->sourceMobID)); + return -1; + } + + videoEssence->SourceMob = SourceMob; + + parse_SourceMob (aafi, SourceMob, &__td); + + aafObject* EssenceData = get_EssenceData_By_MobID (aafi, videoEssence->sourceMobID); + + if (EssenceData == NULL) { + /* + * It means essence is not embedded. + */ + + // return -1; + } else { + parse_EssenceData (aafi, EssenceData, &__td); + } + + videoEssence->unique_file_name = build_unique_videofilename (aafi, videoEssence); + + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_MAGENTA ); + + // debug( "Master MOB SOURCE CLIP" ); + // + // aafiVideoEssence *videoEssence = aafi_newVideoEssence( aafi ); + // + // aafi->ctx.current_essence = (aafiVideoEssence*)videoEssence; + // + // + // videoEssence->file_name = aaf_get_propertyValue( /*aafi->ctx.*/ParentMob, PID_Mob_Name, &AAFTypeID_String ); + // + // + // videoEssence->masterMobID = aaf_get_propertyValue( /*aafi->ctx.*/ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // + // if ( videoEssence->masterMobID == NULL ) { + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_RED ); + // error( "Could not retrieve Mob::MobID." ); + // return -1; + // } + // + // /* + // * p.49 : To create a SourceReference that refers to a MobSlot within + // * the same Mob as the SourceReference, omit the SourceID property. + // */ + // + // videoEssence->sourceMobID = SourceID; //aaf_get_propertyValue( SourceClip, PID_SourceReference_SourceID, &AAFTypeID_MobIDType ); + // + // if ( videoEssence->sourceMobID == NULL ) { + // // aafObject *Mob = NULL; + // // + // // for ( Mob = SourceClip; Mob != NULL; Mob = Mob->Parent ) { + // // if ( aafUIDCmp( Mob->Class->ID, &AAFClassID_MasterMob ) ) + // // break; + // // } + // + // videoEssence->sourceMobID = aaf_get_propertyValue( ParentMob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // + // warning( "Could not retrieve SourceReference::SourceID, retrieving from parent Mob." ); + // } + // + // + // + // aafObject *SourceMob = aaf_get_MobByID( aafi->aafd->Mobs, videoEssence->sourceMobID ); + // + // if ( SourceMob == NULL ) { + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_RED ); + // error( "Could not retrieve SourceMob." ); + // return -1; + // } + // + // videoEssence->SourceMob = SourceMob; + // + // + // + // // parse_SourceMob( aafi, SourceMob ); + // + // + // /* TODO the following must be moved to parse_SourceMob() !!! */ + // + // aafObject *EssenceDesc = aaf_get_propertyValue( SourceMob, PID_SourceMob_EssenceDescription, &AAFTypeID_EssenceDescriptorStrongReference ); + // + // if ( EssenceDesc == NULL ) { + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_RED ); + // error( "Could not retrieve EssenceDesc." ); + // return -1; + // } + // + // + // // TODO + // parse_EssenceDescriptor( aafi, EssenceDesc ); + // + // + // + // videoEssence->unique_file_name = build_unique_videofilename( aafi, videoEssence ); + // + // + // + // /* NOTE since multiple clips can point to the same MasterMob, we have to loop. */ + // + // aafiVideoTrack * videoTrack = NULL; + // aafiTimelineItem * videoItem = NULL; + // + // foreach_videoTrack( videoTrack, aafi ) { + // foreach_Item( videoItem, videoTrack ) { + // if ( videoItem->type != AAFI_VIDEO_CLIP ) { + // continue; + // } + // + // aafiVideoClip *videoClip = (aafiVideoClip*)&videoItem->data; + // + // if ( aafMobIDCmp( videoClip->masterMobID, videoEssence->masterMobID ) ) { + // debug( "FOUND VIDEO ESSENCE CLIP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ); + // videoClip->Essence = videoEssence; + // } + // } + // } + // + // aafi_trace_obj( aafi, SourceClip, ANSI_COLOR_MAGENTA ); + // + } + } else { + DUMP_OBJ_NO_SUPPORT (aafi, SourceClip, &__td); + return -1; + } + + return 0; +} + +static int +parse_Selector (AAF_Iface* aafi, aafObject* Selector, td* __ptd) +{ + /* + * The Selector class is a sub-class of the Segment class. + * + * The Selector class provides the value of a single Segment (PID_Selector_Selected) + * while preserving references to unused alternatives (PID_Selector_Alternates) + */ + + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + if (resolve_AAF (aafi)) { + return resolve_parse_aafObject_Selector (aafi, Selector, &__td); + } + + aafObject* Selected = aaf_get_propertyValue (Selector, PID_Selector_Selected, &AAFTypeID_SegmentStrongReference); + + if (Selected == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Selector, &__td, "Missing PID_Selector_Selected"); + return -1; + } + + // aafObject *Alternate = NULL; + aafObject* Alternates = aaf_get_propertyValue (Selector, PID_Selector_Alternates, &AAFTypeID_SegmentStrongReferenceVector); + + if (Alternates == NULL) { /* opt */ + // DUMP_OBJ_WARNING( aafi, Selector, &__td, "Missing PID_Selector_Alternates" ); + } + + DUMP_OBJ (aafi, Selector, &__td); + + /* without specific software implementation we stick to Selected and forget about Alternates */ + return aafi_parse_Segment (aafi, Selected, &__td); +} + +/* + * Parameter (abs) + * | + * ,--------------. + * | | + * ConstantValue VaryingValue + * + * + * A Parameter object shall be owned by an OperationGroup object. + */ + +static int +parse_Parameter (AAF_Iface* aafi, aafObject* Parameter, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + if (aafUIDCmp (Parameter->Class->ID, &AAFClassID_ConstantValue)) { + return parse_ConstantValue (aafi, Parameter, &__td); + } else if (aafUIDCmp (Parameter->Class->ID, &AAFClassID_VaryingValue)) { + return parse_VaryingValue (aafi, Parameter, &__td); + } + + return -1; +} + +static int +parse_ConstantValue (AAF_Iface* aafi, aafObject* ConstantValue, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + // __td.sub = 1; + + if (!aaf_get_propertyValue (ConstantValue->Parent, PID_OperationGroup_InputSegments, &AAFTypeID_SegmentStrongReferenceVector)) { + __td.eob = 1; + } + + aafUID_t* ParamDef = aaf_get_propertyValue (ConstantValue, PID_Parameter_Definition, &AAFTypeID_AUID); + + if (ParamDef == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Missing PID_Parameter_Definition"); + return -1; + } + + aafUID_t* OperationIdentification = get_OperationGroup_OperationIdentification (aafi, ConstantValue->Parent); + + if (OperationIdentification == NULL) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Could not retrieve OperationIdentification"); + return -1; + } + + if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioGain) && + aafUIDCmp (ParamDef, &AAFParameterDef_Amplitude)) { + aafIndirect_t* Indirect = aaf_get_propertyValue (ConstantValue, PID_ConstantValue_Value, &AAFTypeID_Indirect); + + if (Indirect == NULL) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Missing PID_ConstantValue_Value or wrong AAFTypeID"); + return -1; + } + + aafRational_t* multiplier = aaf_get_indirectValue (aafi->aafd, Indirect, &AAFTypeID_Rational); + + if (multiplier == NULL) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Could not retrieve Indirect value for PID_ConstantValue_Value"); + return -1; + } + + aafiAudioGain* Gain = calloc (sizeof (aafiAudioGain), sizeof (unsigned char)); + + Gain->pts_cnt = 1; + Gain->value = calloc (1, sizeof (aafRational_t*)); + Gain->flags |= AAFI_AUDIO_GAIN_CONSTANT; + + memcpy (&Gain->value[0], multiplier, sizeof (aafRational_t)); + + /* + * Loop through ancestors to find out who is the parent of OperationGroup. + * If it belongs to TimelineMobSlot, that means the Parameter is attached + * to a Track. If it belongs to a Component, the Parameter is attached to + * a clip. + * + * NOTE: We can't just check the Parent since we can have nested OperationGroups + * providing different effects like Pan, Gain, CustomFx.. Therefore looping + * is required. + */ + + aafObject* Obj = ConstantValue->Parent; // Start with the last OperationGroup + for (; Obj != NULL && aafUIDCmp (Obj->Class->ID, &AAFClassID_ContentStorage) == 0; Obj = Obj->Parent) + if (!aafUIDCmp (Obj->Class->ID, &AAFClassID_OperationGroup)) + break; + + if (aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot)) { + /* Track-based Gain */ + aafi->ctx.current_track->gain = Gain; + } else { + /* Clip-based Gain */ + if (aafi->ctx.current_clip_gain) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Clip gain was already set : +%05.1lf dB", 20 * log10 (aafRationalToFloat (aafi->ctx.current_clip_gain->value[0]))); + + // for ( int i = 0; i < aafi->ctx.current_clip_gain->pts_cnt; i++ ) { + // debug( " VaryingValue: _time: %f _value: %f", + // aafRationalToFloat( aafi->ctx.current_clip_gain->time[i] ), + // aafRationalToFloat( aafi->ctx.current_clip_gain->value[i] ) ); + // } + + aafi_freeAudioGain (Gain); + return -1; + } else { + aafi->ctx.current_clip_gain = Gain; + aafi->ctx.clips_using_gain = 0; + } + } + + DUMP_OBJ (aafi, ConstantValue, &__td); + + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioPan) && + aafUIDCmp (ParamDef, &AAFParameterDef_Pan)) { + /* + * Pan automation shall be track-based. If an application has a different + * native representation (e.g., clip-based pan), it shall convert to and + * from its native representation when exporting and importing the composition. + */ + + aafIndirect_t* Indirect = aaf_get_propertyValue (ConstantValue, PID_ConstantValue_Value, &AAFTypeID_Indirect); + + if (Indirect == NULL) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Missing PID_ConstantValue_Value or wrong AAFTypeID"); + return -1; + } + + aafRational_t* multiplier = aaf_get_indirectValue (aafi->aafd, Indirect, &AAFTypeID_Rational); + + if (multiplier == NULL) { + DUMP_OBJ_ERROR (aafi, ConstantValue, &__td, "Could not retrieve Indirect value for PID_ConstantValue_Value"); + return -1; + } + + // if ( multiplier == NULL ) { + // DUMP_OBJ_ERROR( aafi, ConstantValue, &__td, "Missing PID_ConstantValue_Value or wrong AAFTypeID" ); + // return -1; + // } + + aafiAudioPan* Pan = calloc (sizeof (aafiAudioPan), sizeof (unsigned char)); + + Pan->pts_cnt = 1; + Pan->value = calloc (1, sizeof (aafRational_t*)); + Pan->flags |= AAFI_AUDIO_GAIN_CONSTANT; + + memcpy (&Pan->value[0], multiplier, sizeof (aafRational_t)); + + /* Pan is Track-based only. */ + aafi->ctx.current_track->pan = Pan; + + DUMP_OBJ (aafi, ConstantValue, &__td); + } else { + DUMP_OBJ_NO_SUPPORT (aafi, ConstantValue, &__td); + } + + return 0; +} + +static int +parse_VaryingValue (AAF_Iface* aafi, aafObject* VaryingValue, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + // __td.sub = 1; + + if (!aaf_get_propertyValue (VaryingValue->Parent, PID_OperationGroup_InputSegments, &AAFTypeID_SegmentStrongReferenceVector)) { + __td.eob = 1; + } + + aafUID_t* ParamDef = aaf_get_propertyValue (VaryingValue, PID_Parameter_Definition, &AAFTypeID_AUID); + + if (ParamDef == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Missing PID_Parameter_Definition"); + return -1; + } + + aafUID_t* OperationIdentification = get_OperationGroup_OperationIdentification (aafi, VaryingValue->Parent); + + if (OperationIdentification == NULL) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Could not retrieve OperationIdentification"); + return -1; + } + + aafiInterpolation_e interpolation = 0; + aafUID_t* InterpolationIdentification = get_Parameter_InterpolationIdentification (aafi, VaryingValue); + + if (InterpolationIdentification == NULL) { + DUMP_OBJ_WARNING (aafi, VaryingValue, &__td, "Could not retrieve InterpolationIdentification: Setting to Linear"); + interpolation = AAFI_INTERPOL_LINEAR; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_None)) { + interpolation = AAFI_INTERPOL_NONE; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_Linear)) { + interpolation = AAFI_INTERPOL_LINEAR; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_Power)) { + interpolation = AAFI_INTERPOL_POWER; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_Constant)) { + interpolation = AAFI_INTERPOL_CONSTANT; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_BSpline)) { + interpolation = AAFI_INTERPOL_BSPLINE; + } else if (aafUIDCmp (InterpolationIdentification, &AAFInterpolationDef_Log)) { + interpolation = AAFI_INTERPOL_LOG; + } else { + DUMP_OBJ_WARNING (aafi, VaryingValue, &__td, "Unknown value for InterpolationIdentification: Falling back to Linear"); + interpolation = AAFI_INTERPOL_LINEAR; + } + + aafObject* Points = aaf_get_propertyValue (VaryingValue, PID_VaryingValue_PointList, &AAFTypeID_ControlPointStrongReferenceVector); + + if (Points == NULL) { + /* + * Some files like the ProTools and LogicPro break standard by having no + * PointList entry for AAFOperationDef_MonoAudioGain. + */ + + DUMP_OBJ_WARNING (aafi, VaryingValue, &__td, "Missing PID_VaryingValue_PointList or list is empty"); + return -1; + } + + // if ( aafUIDCmp( VaryingValue->Parent->Parent->Class->ID, &AAFClassID_Transition ) ) + if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioDissolve) && + aafUIDCmp (ParamDef, &AAFParameterDef_Level)) { + aafiTransition* Trans = aafi->ctx.current_transition; + + Trans->flags |= interpolation; + Trans->pts_cnt_a = retrieve_ControlPoints (aafi, Points, &(Trans->time_a), &(Trans->value_a)); + + if (Trans->pts_cnt_a < 0) { + /* In that case, parse_OperationGroup() will set transition to default. */ + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Could not retrieve ControlPoints"); + return -1; + } + + // for ( int i = 0; i < Trans->pts_cnt_a; i++ ) { + // debug( "time_%i : %i/%i value_%i : %i/%i", i, Trans->time_a[i].numerator, Trans->time_a[i].denominator, i, Trans->value_a[i].numerator, Trans->value_a[i].denominator ); + // } + + DUMP_OBJ (aafi, VaryingValue, &__td); + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioGain) && + aafUIDCmp (ParamDef, &AAFParameterDef_Amplitude)) { + aafiAudioGain* Gain = calloc (sizeof (aafiAudioGain), sizeof (unsigned char)); + + Gain->flags |= interpolation; + Gain->pts_cnt = retrieve_ControlPoints (aafi, Points, &Gain->time, &Gain->value); + + if (Gain->pts_cnt < 0) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Could not retrieve ControlPoints"); + free (Gain); + return -1; + } + + // for ( int i = 0; i < Gain->pts_cnt; i++ ) { + // debug( "time_%i : %i/%i value_%i : %i/%i", i, Gain->time[i].numerator, Gain->time[i].denominator, i, Gain->value[i].numerator, Gain->value[i].denominator ); + // } + + /* If gain has 2 ControlPoints with both the same value, it means + * we have a flat gain curve. So we can assume constant gain here. */ + + if (Gain->pts_cnt == 2 && + (Gain->value[0].numerator == Gain->value[1].numerator) && + (Gain->value[0].denominator == Gain->value[1].denominator)) { + if (aafRationalToFloat (Gain->value[0]) == 1.0f) { + /* + * gain is null, skip it. Skipping it allows not to set a useless gain then miss the real clip gain later (Resolve 18.5.AAF) + */ + aafi_freeAudioGain (Gain); + return -1; + } + Gain->flags |= AAFI_AUDIO_GAIN_CONSTANT; + } else { + Gain->flags |= AAFI_AUDIO_GAIN_VARIABLE; + } + + /* + * Loop through ancestors to find out who is the parent of OperationGroup. + * If it belongs to TimelineMobSlot, that means the Parameter is attached + * to a Track. If it belongs to a Component, the Parameter is attached to + * a clip. + * + * NOTE: We can't just check the Parent since we can have nested OperationGroups + * providing different effects like Pan, Gain, CustomFx.. Therefore looping + * is required. + */ + + aafObject* Obj = VaryingValue->Parent; // Start with the last OperationGroup + for (; Obj != NULL && aafUIDCmp (Obj->Class->ID, &AAFClassID_ContentStorage) == 0; Obj = Obj->Parent) + if (!aafUIDCmp (Obj->Class->ID, &AAFClassID_OperationGroup)) + break; + + if (aafUIDCmp (Obj->Class->ID, &AAFClassID_TimelineMobSlot)) { + /* Track-based Gain */ + + if (aafi->ctx.current_track->gain) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Track Gain was already set"); + aafi_freeAudioGain (Gain); + return -1; + } else { + aafi->ctx.current_track->gain = Gain; + DUMP_OBJ (aafi, VaryingValue, &__td); + } + } else { + /* Clip-based Gain */ + + if (Gain->flags & AAFI_AUDIO_GAIN_CONSTANT) { + if (aafi->ctx.current_clip_gain) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Clip gain was already set"); + aafi_freeAudioGain (Gain); + return -1; + } else { + aafi->ctx.current_clip_gain = Gain; + aafi->ctx.clips_using_gain = 0; + } + } else { + if (aafi->ctx.current_clip_automation) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Clip automation was already set"); + aafi_freeAudioGain (Gain); + return -1; + } else { + aafi->ctx.current_clip_automation = Gain; + aafi->ctx.clips_using_automation = 0; + } + } + } + } else if (aafUIDCmp (OperationIdentification, &AAFOperationDef_MonoAudioPan) && + aafUIDCmp (ParamDef, &AAFParameterDef_Pan)) { + /* + * Pan automation shall be track-based. If an application has a different + * native representation (e.g., clip-based pan), it shall convert to and + * from its native representation when exporting and importing the composition. + */ + + aafiAudioPan* Pan = calloc (sizeof (aafiAudioPan), sizeof (unsigned char)); + + Pan->flags |= AAFI_AUDIO_GAIN_VARIABLE; + Pan->flags |= interpolation; + + Pan->pts_cnt = retrieve_ControlPoints (aafi, Points, &Pan->time, &Pan->value); + + if (Pan->pts_cnt < 0) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Could not retrieve ControlPoints"); + free (Pan); + return -1; + } + + // for ( int i = 0; i < Gain->pts_cnt; i++ ) { + // debug( "time_%i : %i/%i value_%i : %i/%i", i, Gain->time[i].numerator, Gain->time[i].denominator, i, Gain->value[i].numerator, Gain->value[i].denominator ); + // } + + /* If Pan has 2 ControlPoints with both the same value, it means + * we have a constant Pan curve. So we can assume constant Pan here. */ + + if (Pan->pts_cnt == 2 && + (Pan->value[0].numerator == Pan->value[1].numerator) && + (Pan->value[0].denominator == Pan->value[1].denominator)) { + // if ( aafRationalToFloat(Gain->value[0]) == 1.0f ) { + // /* + // * Pan is null, skip it. Skipping it allows not to set a useless gain then miss the real clip gain later (Resolve 18.5.AAF) + // */ + // aafi_freeAudioGain( Gain ); + // return -1; + // } + Pan->flags |= AAFI_AUDIO_GAIN_CONSTANT; + } else { + Pan->flags |= AAFI_AUDIO_GAIN_VARIABLE; + } + + if (aafi->ctx.current_track->pan) { + DUMP_OBJ_ERROR (aafi, VaryingValue, &__td, "Track Pan was already set"); + aafi_freeAudioGain (Pan); + return -1; + } else { + aafi->ctx.current_track->pan = Pan; + DUMP_OBJ (aafi, VaryingValue, &__td); + } + } else { + DUMP_OBJ (aafi, VaryingValue, &__td); + } + + return 0; +} + +static int +retrieve_ControlPoints (AAF_Iface* aafi, aafObject* Points, aafRational_t* times[], aafRational_t* values[]) +{ + *times = calloc (Points->Header->_entryCount, sizeof (aafRational_t)); + *values = calloc (Points->Header->_entryCount, sizeof (aafRational_t)); + + aafObject* Point = NULL; + + unsigned int i = 0; + + aaf_foreach_ObjectInSet (&Point, Points, &AAFClassID_ControlPoint) + { + aafRational_t* time = aaf_get_propertyValue (Point, PID_ControlPoint_Time, &AAFTypeID_Rational); + + if (time == NULL) { + // aafi_trace_obj( aafi, Points, ANSI_COLOR_RED ); + error ("Missing ControlPoint::Time."); + + free (*times); + *times = NULL; + free (*values); + *values = NULL; + + return -1; + } + + // aafRational_t *value = aaf_get_propertyIndirectValue( Point, PID_ControlPoint_Value, &AAFTypeID_Rational ); + + aafIndirect_t* Indirect = aaf_get_propertyValue (Point, PID_ControlPoint_Value, &AAFTypeID_Indirect); + + if (Indirect == NULL) { + // DUMP_OBJ_ERROR( aafi, ConstantValue, &__td, "Missing PID_ConstantValue_Value or wrong AAFTypeID" ); + error ("Missing ControlPoint::Value or wrong AAFTypeID"); + + free (*times); + *times = NULL; + free (*values); + *values = NULL; + + return -1; + } + + aafRational_t* value = aaf_get_indirectValue (aafi->aafd, Indirect, &AAFTypeID_Rational); + + if (value == NULL) { + // aafi_trace_obj( aafi, Points, ANSI_COLOR_RED ); + error ("Could not retrieve Indirect value for PID_ControlPoint_Value"); + + free (*times); + *times = NULL; + free (*values); + *values = NULL; + + return -1; + } + + memcpy ((*times + i), time, sizeof (aafRational_t)); + memcpy ((*values + i), value, sizeof (aafRational_t)); + + i++; + } + + if (Points->Header->_entryCount != i) { + // aafi_trace_obj( aafi, Points, ANSI_COLOR_YELLOW ); + warning ("Points _entryCount (%i) does not match iteration (%i).", Points->Header->_entryCount, i); + return i; + } + + // aafi_trace_obj( aafi, Points, ANSI_COLOR_MAGENTA ); + + return Points->Header->_entryCount; +} + +/* **************************************************************************** + * M o b + * **************************************************************************** + + * Mob (abs) + * | + * |--> CompositionMob + * |--> MasterMob + * `--> SourceMob + */ + +static int +parse_Mob (AAF_Iface* aafi, aafObject* Mob) +{ + // int dl = DUMP_INIT(aafi); + // __td(NULL); + static td __td; + __td.fn = __LINE__; + __td.pfn = 0; + __td.lv = 0; + __td.ll = calloc (1024, sizeof (int)); /* TODO free */ + __td.ll[0] = 0; + // aafi->ctx.trace_leveloop = __td.ll; // keep track of __td.ll for free + + aafObject* MobSlots = aaf_get_propertyValue (Mob, PID_Mob_Slots, &AAFTypeID_MobSlotStrongReferenceVector); + + if (MobSlots == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Mob, &__td, "Missing PID_Mob_Slots"); + free (__td.ll); + return -1; + } + + if (aafUIDCmp (Mob->Class->ID, &AAFClassID_CompositionMob)) { + aafUID_t* UsageCode = aaf_get_propertyValue (Mob, PID_Mob_UsageCode, &AAFTypeID_UsageType); + + if (aafUIDCmp (UsageCode, &AAFUsage_AdjustedClip)) { + DUMP_OBJ_ERROR (aafi, Mob, &__td, "Skipping AAFUsage_AdjustedClip"); + return -1; + } + + parse_CompositionMob (aafi, Mob, &__td); + } else if (aafUIDCmp (Mob->Class->ID, &AAFClassID_MasterMob)) { + DUMP_OBJ (aafi, Mob, &__td); + } else if (aafUIDCmp (Mob->Class->ID, &AAFClassID_SourceMob)) { + DUMP_OBJ (aafi, Mob, &__td); + } + + /* + * Loops through MobSlots + */ + + aafObject* MobSlot = NULL; + + int i = 0; + + aaf_foreach_ObjectInSet (&MobSlot, MobSlots, NULL) + { + __td.ll[__td.lv] = MobSlots->Header->_entryCount - i++; + parse_MobSlot (aafi, MobSlot, &__td); + } + + free (__td.ll); + + return 0; +} + +static int +parse_CompositionMob (AAF_Iface* aafi, aafObject* CompoMob, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + DUMP_OBJ (aafi, CompoMob, &__td); + + aafi->compositionName = aaf_get_propertyValue (CompoMob, PID_Mob_Name, &AAFTypeID_String); /* opt */ + + aafObject* UserComment = NULL; + aafObject* UserComments = aaf_get_propertyValue (CompoMob, PID_Mob_UserComments, &AAFTypeID_TaggedValueStrongReferenceVector); /* opt */ + + aaf_foreach_ObjectInSet (&UserComment, UserComments, NULL) + { + /* TODO: implement retrieve_TaggedValue() ? */ + + wchar_t* name = aaf_get_propertyValue (UserComment, PID_TaggedValue_Name, &AAFTypeID_String); + + if (name == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, UserComment, &__td, "Missing PID_TaggedValue_Name"); + continue; + } + + aafIndirect_t* Indirect = aaf_get_propertyValue (UserComment, PID_TaggedValue_Value, &AAFTypeID_Indirect); + + if (Indirect == NULL) { + DUMP_OBJ_ERROR (aafi, UserComment, &__td, "Missing PID_TaggedValue_Value"); + continue; + } + + wchar_t* text = aaf_get_indirectValue (aafi->aafd, Indirect, &AAFTypeID_String); + + if (text == NULL) { + DUMP_OBJ_ERROR (aafi, UserComment, &__td, "Could not retrieve Indirect value for PID_TaggedValue_Value"); + continue; + } + + aafiUserComment* Comment = aafi_newUserComment (aafi, &aafi->Comments); + + Comment->name = name; + Comment->text = text; + } + + return 0; +} + +static int +parse_SourceMob (AAF_Iface* aafi, aafObject* SourceMob, td* __ptd) +{ + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + __td.hc = 1; + + /* TODO find a better way to check if we're parsing audio */ + + // aafUID_t *DataDefinition = get_Component_DataDefinition( aafi, SourceMob ); + // + // if ( DataDefinition == NULL ) /* req */ { + // error( "Could not retrieve MobSlot::Segment DataDefinition." ); + // return -1; + // } + // + // + // + // if ( aafUIDCmp( DataDefinition, &AAFDataDef_Sound ) || + // aafUIDCmp( DataDefinition, &AAFDataDef_LegacySound ) ) + + if (aafi->ctx.current_essence) { + if (aafi->ctx.current_essence == NULL) { + DUMP_OBJ_ERROR (aafi, SourceMob, &__td, "ctx->current_essence no set"); + return -1; + } + + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + aafMobID_t* MobID = aaf_get_propertyValue (SourceMob, PID_Mob_MobID, &AAFTypeID_MobIDType); + + if (MobID == NULL) { + DUMP_OBJ_ERROR (aafi, SourceMob, &__td, "Missing PID_Mob_MobID"); + return -1; + } + + memcpy (audioEssence->umid, MobID, sizeof (aafMobID_t)); + + aafTimeStamp_t* CreationTime = aaf_get_propertyValue (SourceMob, PID_Mob_CreationTime, &AAFTypeID_TimeStamp); + + if (CreationTime == NULL) { + DUMP_OBJ_ERROR (aafi, SourceMob, &__td, "Missing PID_Mob_CreationTime"); + return -1; + } + + snprintf (audioEssence->originationDate, sizeof (audioEssence->originationDate), "%04u:%02u:%02u", + (CreationTime->date.year <= 9999) ? CreationTime->date.year : 0, + (CreationTime->date.month <= 99) ? CreationTime->date.month : 0, + (CreationTime->date.day <= 99) ? CreationTime->date.day : 0); + + snprintf (audioEssence->originationTime, sizeof (audioEssence->originationTime), "%02u:%02u:%02u", + (CreationTime->time.hour <= 99) ? CreationTime->time.hour : 0, + (CreationTime->time.minute <= 99) ? CreationTime->time.minute : 0, + (CreationTime->time.second <= 99) ? CreationTime->time.second : 0); + } + + aafObject* EssenceDesc = aaf_get_propertyValue (SourceMob, PID_SourceMob_EssenceDescription, &AAFTypeID_EssenceDescriptorStrongReference); + + if (EssenceDesc == NULL) { + DUMP_OBJ_ERROR (aafi, SourceMob, &__td, "Could not retrieve EssenceDescription"); + return -1; + } + + DUMP_OBJ (aafi, SourceMob, &__td); + + parse_EssenceDescriptor (aafi, EssenceDesc, &__td); + + return 0; +} + +static aafiAudioTrack* +get_audio_track_by_tracknumber (AAF_Iface* aafi, int tracknumber) +{ + aafiAudioTrack* audioTrack = NULL; + int count = 0; + + foreach_audioTrack (audioTrack, aafi) + { + if (++count == tracknumber) + return audioTrack; + } + + return NULL; +} + +/* **************************************************************************** + * M o b S l o t + * **************************************************************************** + * + * MobSlot (abs) + * | + * |--> TimelineMobSlot + * |--> EventMobSlot + * `--> StaticMobSlot + */ + +static int +parse_MobSlot (AAF_Iface* aafi, aafObject* MobSlot, td* __ptd) +{ + // debug( "MS : %p", __ptd->ll ); + + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + __td.hc = 1; + + aafObject* Segment = aaf_get_propertyValue (MobSlot, PID_MobSlot_Segment, &AAFTypeID_SegmentStrongReference); + + if (Segment == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Missing PID_MobSlot_Segment"); + return -1; + } + + aafUID_t* DataDefinition = get_Component_DataDefinition (aafi, Segment); + + if (DataDefinition == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Could not retrieve DataDefinition"); + return -1; + } + + aafPosition_t session_end = 0; + + if (aafUIDCmp (MobSlot->Class->ID, &AAFClassID_TimelineMobSlot)) { + /* + * Each TimelineMobSlot represents a track, either audio or video. + * + * The Timeline MobSlot::Segment should hold a Sequence of Components. + * This Sequence represents the timeline track. Therefore, each SourceClip + * contained in the Sequence::Components represents a clip on the timeline. + * + * CompositionMob can have TimelineMobSlots, StaticMobSlots, EventMobSlots + */ + + aafRational_t* edit_rate = aaf_get_propertyValue (MobSlot, PID_TimelineMobSlot_EditRate, &AAFTypeID_Rational); + + if (edit_rate == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Missing PID_TimelineMobSlot_EditRate"); + return -1; + } + + if (aafUIDCmp (/*aafi->ctx.*/ MobSlot->Parent->Class->ID, &AAFClassID_CompositionMob)) { + /* + * There should be only one Composition, since a CompositionMob represents the overall + * composition (i.e project). Observations on files confirm that. + * + * However, the AAF Edit Protocol says that there could be multiple CompositionMobs + * (Mob::UsageCode TopLevel), containing other CompositionMobs (Mob::UsageCode LowerLevel). + * This was not encountered yet, even on Avid exports with AAF_EditProtocol enabled. + * + * TODO: update note + * TODO: implement multiple TopLevel compositions support + */ + + if (aafUIDCmp (DataDefinition, &AAFDataDef_Sound) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacySound)) { + /* + * p.11 : In a CompositionMob or MasterMob, PhysicalTrackNumber is the + * output channel number that the MobSlot should be routed to when played. + */ + + if (!aafi->ctx.is_inside_derivation_chain) { + uint32_t tracknumber = 0; + uint32_t* track_num = aaf_get_propertyValue (MobSlot, PID_MobSlot_PhysicalTrackNumber, &AAFTypeID_UInt32); + + if (track_num == NULL) { /* opt */ + tracknumber = aafi->Audio->track_count + 1; + } else { + tracknumber = *track_num; + } + + aafiAudioTrack* track = get_audio_track_by_tracknumber (aafi, tracknumber); + + if (!track) { + track = aafi_newAudioTrack (aafi); + } + + track->number = tracknumber; + + aafi->Audio->track_count += 1; + + aafi->ctx.current_track = track; + + track->name = aaf_get_propertyValue (MobSlot, PID_MobSlot_SlotName, &AAFTypeID_String); + + track->edit_rate = edit_rate; + } + + // aaf_dump_ObjectProperties( aafi->aafd, MobSlot ); + + /* + * The following seems to be ProTools proprietary. + * If a track is multi-channel, it specifies its format : 2 (stereo), 6 (5.1) or 8 (7.1). + * + * In the current implementation we don't need this. We guess the format at the OperationGroup level with the + * AAFOperationDef_AudioChannelCombiner OperationDefinition, which also looks to be ProTools specific. + */ + + // aafPID_t PIDTimelineMobAttributeList = aaf_get_PropertyIDByName( aafi->aafd, "TimelineMobAttributeList" ); + // // aafPID_t PIDTimelineMobAttributeList = aaf_get_PropertyIDByName( aafi->aafd, "MobAttributeList" ); + // + // if ( PIDTimelineMobAttributeList != 0 ) { + // aafObject *TaggedValues = aaf_get_propertyValue( aafi->ctx.MobSlot, PIDTimelineMobAttributeList ); + // aafObject *TaggedValue = NULL; + // + // aaf_foreach_ObjectInSet( &TaggedValue, TaggedValues, NULL ) { + // char *name = aaf_get_propertyValueText( TaggedValue, PID_TaggedValue_Name ); + // + // debug( "TaggedValue %s", name ); + // + // if ( strncmp( "_TRACK_FORMAT", name, 13 ) == 0 ) { + // uint32_t *format = (uint32_t*)aaf_get_propertyIndirectValue( TaggedValue, PID_TaggedValue_Value ); + // + // if ( format != NULL ) + // aafi->ctx.current_track->format = *format; + // + // debug( "Format : %u", aafi->ctx.current_track->format ); + // } + // + // free( name ); + // } + // } + + DUMP_OBJ (aafi, MobSlot, &__td); + + /* Reset timeline position */ + // aafi->ctx.current_track->current_pos = 0; + + aafi_parse_Segment (aafi, Segment, &__td); + + /* update session_end if needed */ + // session_end = ( aafi->ctx.current_pos > session_end ) ? aafi->ctx.current_pos : session_end; + // debug( "AAFIParser 4286: Current pos : %lu\n", aafi->ctx.current_track->current_pos ); + session_end = (aafi->ctx.current_track->current_pos > session_end) ? aafi->ctx.current_track->current_pos : session_end; + + // debug( "SESSIon_end : %li", session_end ); + + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Timecode) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyTimecode)) { + DUMP_OBJ (aafi, MobSlot, &__td); + aafi_parse_Segment (aafi, Segment, &__td); + } else if (aafUIDCmp (DataDefinition, &AAFDataDef_Picture) || + aafUIDCmp (DataDefinition, &AAFDataDef_LegacyPicture)) { + // debug( "%ls", aaft_ClassIDToText(aafi->aafd, Segment->Class->ID) ); + + /* ADP NESTED SCOPE */ + + // aafObject *NSSegment = NULL; + // aafObject *NSSegments = aaf_get_propertyValue( Segment, PID_NestedScope_Slots ); + // + // aaf_foreach_ObjectInSet( &NSSegment, NSSegments, NULL ) { + // aaf_dump_ObjectProperties( aafi->aafd, NSSegment ); + // } + + if (aafi->Video->Tracks) { + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Current implementation supports only one video track"); + return -1; + } + + /* + * p.11 : In a CompositionMob or MasterMob, PhysicalTrackNumber is the output channel number that the + * MobSlot should be routed to when played. + */ + + uint32_t tracknumber = 0; + uint32_t* track_num = aaf_get_propertyValue (MobSlot, PID_MobSlot_PhysicalTrackNumber, &AAFTypeID_UInt32); + + if (track_num == NULL) { /* opt */ + tracknumber = 1; /* Current implementation supports only one video track. */ + } else { + tracknumber = *track_num; + } + + aafiVideoTrack* track = aafi_newVideoTrack (aafi); + + track->number = tracknumber; + + track->name = aaf_get_propertyValue (MobSlot, PID_MobSlot_SlotName, &AAFTypeID_String); + + track->edit_rate = edit_rate; + + DUMP_OBJ (aafi, MobSlot, &__td); + + aafi_parse_Segment (aafi, Segment, &__td); + + /* update session_end if needed */ + // session_end = ( aafi->ctx.current_track->current_pos > session_end ) ? aafi->ctx.current_track->current_pos : session_end; + } else { + DUMP_OBJ_NO_SUPPORT (aafi, MobSlot, &__td); + } + + } else if (aafUIDCmp (MobSlot->Parent->Class->ID, &AAFClassID_MasterMob)) { + /* Retrieve Essences */ + + // if ( aafUIDCmp( DataDefinition, &AAFDataDef_Sound ) || + // aafUIDCmp( DataDefinition, &AAFDataDef_LegacySound ) ) + // { + DUMP_OBJ (aafi, MobSlot, &__td); + aafi_parse_Segment (aafi, Segment, &__td); + + // } + // else if ( aafUIDCmp( DataDefinition, &AAFDataDef_Picture ) || + // aafUIDCmp( DataDefinition, &AAFDataDef_LegacyPicture ) ) + // { + // aafi_parse_Segment( aafi, Segment ); + // + // retrieve_EssenceData( aafi ); + // } + // else { + // aafi_trace_obj( aafi, MobSlot, ANSI_COLOR_YELLOW ); + // debug( "%ls", aaft_DataDefToText( aafi->aafd, DataDefinition ) ); + // } + } else if (aafUIDCmp (MobSlot->Parent->Class->ID, &AAFClassID_SourceMob)) { + if (aafi->ctx.current_essence != NULL) { + aafiAudioEssence* audioEssence = (aafiAudioEssence*)aafi->ctx.current_essence; + + aafPosition_t* Origin = aaf_get_propertyValue (MobSlot, PID_TimelineMobSlot_Origin, &AAFTypeID_PositionType); + + if (Origin == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Missing PID_TimelineMobSlot_Origin"); + return -1; + } + + audioEssence->timeReference = *Origin; + audioEssence->mobSlotEditRate = edit_rate; + + DUMP_OBJ (aafi, MobSlot, &__td); + } else { + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "aafi->ctx.current_essence no set"); + } + } else { + /* Not in CompositionMob, MasterMob, or SourceMob. Can not happen. */ + DUMP_OBJ_NO_SUPPORT (aafi, MobSlot, &__td); + } + + } else if (aafUIDCmp (MobSlot->Class->ID, &AAFClassID_EventMobSlot)) { + aafRational_t* edit_rate = aaf_get_propertyValue (MobSlot, PID_EventMobSlot_EditRate, &AAFTypeID_Rational); + + if (edit_rate == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, MobSlot, &__td, "Missing PID_EventMobSlot_EditRate"); + return -1; + } + + aafi->ctx.current_markers_edit_rate = edit_rate; + + DUMP_OBJ (aafi, MobSlot, &__td); + + return aafi_parse_Segment (aafi, Segment, &__td); + } else { + /* Not AAFClassID_TimelineMobSlot */ + DUMP_OBJ_NO_SUPPORT (aafi, MobSlot, &__td); + } + + /* TODO implement global (audio and video) session start and end */ + // if ( aafi->ctx.current_tree_type == AAFI_TREE_TYPE_AUDIO ) + + if (session_end > 0 && aafi->Timecode && aafi->Timecode->end < session_end) { + aafi->Timecode->end = session_end; + } + + // if ( aafi->ctx.current_tree_type == AAFI_TREE_TYPE_VIDEO ) + // if ( session_end > 0 && aafi->Video->tc ) + // aafi->Video->tc->end = session_end; + // else + // error( "MISSING aafiTimecode !" ); + + return 0; +} + +int +aafi_retrieveData (AAF_Iface* aafi) +{ + aafObject* Mob = NULL; + + aaf_foreach_ObjectInSet (&Mob, aafi->aafd->Mobs, &AAFClassID_CompositionMob) + { + aafUID_t* UsageCode = aaf_get_propertyValue (Mob, PID_Mob_UsageCode, &AAFTypeID_UsageType); + + if (aafUIDCmp (aafi->aafd->Header.OperationalPattern, &AAFOPDef_EditProtocol) && + !aafUIDCmp (UsageCode, &AAFUsage_TopLevel)) { + /* + * If we run against AAFOPDef_EditProtocol, we process only TopLevels CompositionMobs. + * If there is more than one, we have multiple Compositions in a single AAF. + */ + + // aafi_trace_obj( aafi, Mob, ANSI_COLOR_RED ); + + // // aaf_dump_ObjectProperties( aafi->aafd, aafi->ctx.Mob ); + // + // aafObject *MobSlots = aaf_get_propertyValue( aafi->ctx.Mob, PID_Mob_Slots, &AAFTypeID_MobSlotStrongReferenceVector ); + // aafObject *MobSlot = NULL; + // uint32_t SlotID = 0; + // + // aaf_foreach_ObjectInSet( &MobSlot, MobSlots, NULL ) { + // aaf_dump_ObjectProperties( aafi->aafd, MobSlot ); + // } + + continue; + } + + RESET_CONTEXT (aafi->ctx); + + parse_Mob (aafi, Mob); + } + + // aafiAudioTrack *audioTrack = NULL; + // aafiTimelineItem *audioItem = NULL; + // // aafiAudioClip *audioClip = NULL; + // + // // uint32_t i = 0; + // + // foreach_audioTrack( audioTrack, aafi ) { + // foreach_Item( audioItem, audioTrack ) { + // + // if ( audioItem->type == AAFI_TRANS ) { + // continue; + // } + // + // aafiAudioClip *audioClip = (aafiAudioClip*)&audioItem->data; + // + // if ( audioClip->masterMobID && !audioClip->Essence ) { + // debug( "E m p t y C l i p" ); + // + // aafObject *Mob = NULL; + // + // aaf_foreach_ObjectInSet( &Mob, aafi->aafd->Mobs, NULL ) { + // /* loops through Mobs */ + // aafUID_t *UsageCode = aaf_get_propertyValue( Mob, PID_Mob_UsageCode, &AAFTypeID_ ); + // + // aafMobID_t *MobID = aaf_get_propertyValue( Mob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // + // if ( !aafMobIDCmp( MobID, audioClip->masterMobID ) ) { + // continue; + // } + // + // // aaf_dump_ObjectProperties( aafi->aafd, Mob ); + // debug( "Clip SourceID : %ls", aaft_MobIDToText(MobID) ); + // + // debug( "PointedMob ClassID : %ls", aaft_ClassIDToText(aafi->aafd, Mob->Class->ID) ); + // debug( "PointedMob UsageCd : %ls", aaft_UsageCodeToText(UsageCode) ); + // debug( "PointedMob Name : %ls", aaf_get_propertyValue(Mob, PID_Mob_Name, &AAFTypeID_String) ); + // + // + // + // aafObject *MobSlots = aaf_get_propertyValue( Mob, PID_Mob_Slots, &AAFTypeID_MobSlotStrongReferenceVector ); + // aafObject *MobSlot = NULL; + // int SlotID = 1; + // aaf_foreach_ObjectInSet( &MobSlot, MobSlots, NULL ) { + // debug( " SlotID %u", SlotID ); + // + // aafObject *Segment = aaf_get_propertyValue( MobSlot, PID_MobSlot_Segment, &AAFTypeID_SegmentStrongReference ); + // + // if ( Segment == NULL ) { + // error( "Missing MobSlot::Segment." ); + // return -1; + // } + // + // + // aafUID_t *DataDefinition = get_Component_DataDefinition( aafi, Segment ); + // + // if ( DataDefinition == NULL ) { + // error( "Could not retrieve MobSlot::Segment DataDefinition." ); + // return -1; + // } + // + // // CURRENTPOINTER + // + // debug( " Segment : %ls", aaft_ClassIDToText( aafi->aafd, Segment->Class->ID ) ); + // debug( " DataDefinition : %ls", aaft_DataDefToText(aafi->aafd, DataDefinition) ); + // + // + // + // + // + // + // if ( aafUIDCmp( Segment->Class->ID, &AAFClassID_SourceClip ) ) { + // aafMobID_t *SourceID = aaf_get_propertyValue( Segment, PID_SourceReference_SourceID, &AAFTypeID_MobIDType ); + // debug( " SourceID : %ls", aaft_MobIDToText(sourceID) ); + // } + // + // SlotID++; + // } + // + // + // } + // } + // } + // } + + // aaf_foreach_ObjectInSet( &(aafi->ctx.Mob), aafi->aafd->Mobs, &AAFClassID_SourceMob ) { + // + // aafObject *MobSlots = aaf_get_propertyValue( aafi->ctx.Mob, PID_Mob_Slots, &AAFTypeID_MobSlotStrongReferenceVector ); + // + // aaf_foreach_ObjectInSet( &(aafi->ctx.MobSlot), MobSlots, NULL ) { + // + // /* + // * Check if the SourceMob was parsed. + // * If it was not, we can print the trace. + // * + // * NOTE We do it after the main loop, so we make sure all MasterMobs was parsed. + // */ + // + // aafObject *Segment = aaf_get_propertyValue( aafi->ctx.MobSlot, PID_MobSlot_Segment, &AAFTypeID_SegmentStrongReference ); + // + // aafUID_t *DataDefinition = get_Component_DataDefinition( aafi, Segment ); + // + // aafMobID_t *MobID = aaf_get_propertyValue( aafi->ctx.Mob, PID_Mob_MobID, &AAFTypeID_MobIDType ); + // + // aafiAudioEssence *audioEssence = NULL; + // + // foreachEssence( audioEssence, aafi->Audio->Essences ) { + // if ( aafMobIDCmp( MobID, audioEssence->sourceMobID ) ) + // break; + // } + // + // if ( audioEssence == NULL ) { + // aafi_trace_obj( aafi, aafi->ctx.MobSlot, ANSI_COLOR_YELLOW ); + // debug( "%ls", aaft_DataDefToText( aafi->aafd, DataDefinition ) ); + // } + // + // } + // } + + if (aafi->Timecode == NULL) { + warning ("No timecode found in file. Setting to 00:00:00:00 @ 25fps"); + + aafiTimecode* tc = calloc (sizeof (aafiTimecode), sizeof (unsigned char)); + + if (tc == NULL) { + error ("calloc() : %s", strerror (errno)); + return -1; + } + + tc->start = 0; + tc->fps = 25; + tc->drop = 0; + tc->edit_rate = &AAFI_DEFAULT_TC_EDIT_RATE; + + aafi->Timecode = tc; + } + + /* aafi->Audio->tc->end is set to composition duration. Add tc->start to set composition end time */ + + if (aafi->Timecode && aafi->Timecode->end) { + aafi->Timecode->end += aafi->Timecode->start; + } + + /* Post processing */ + + /* TODO move to parse_*() */ + /* Parse summary descriptor (WAVE/AIFC) if any */ + + aafiAudioEssence* audioEssence = NULL; + + foreachEssence (audioEssence, aafi->Audio->Essences) + { + /* TODO: rename (not only summary, can be external file too) */ + aafi_parse_audio_summary (aafi, audioEssence); + + /* TODO : check samplerate / samplesize proportions accross essences, and choose the most used values as composition values */ + if (aafi->Audio->samplerate == 0 || aafi->Audio->samplerate == audioEssence->samplerate) { + aafi->Audio->samplerate = audioEssence->samplerate; + } else { + // warning( "audioEssence '%ls' has different samplerate : %u", audioEssence->file_name, audioEssence->samplerate ); + } + + if (aafi->Audio->samplesize == 0 || aafi->Audio->samplesize == audioEssence->samplesize) { + aafi->Audio->samplesize = audioEssence->samplesize; + } else { + // warning( "audioEssence '%ls' has different samplesize : %i", audioEssence->file_name, audioEssence->samplesize ); + } + } + + aafiAudioTrack* audioTrack = NULL; + + foreach_audioTrack (audioTrack, aafi) + { + // aafiTimelineItem *audioItem = NULL; + // aafiAudioClip *audioClip = NULL; + // + // if ( audioTrack->format > 1 ) { + // + // foreach_Item( audioItem, audioTrack ) { + // + // if ( audioItem->type == AAFI_TRANS ) { + // continue; + // } + // + // audioClip = (aafiAudioClip*)&audioItem->data; + // } + // } + + if (audioTrack->current_pos > aafi->Audio->length) { + aafi->Audio->length = audioTrack->current_pos; + aafi->Audio->length_editRate.numerator = audioTrack->edit_rate->numerator; + aafi->Audio->length_editRate.denominator = audioTrack->edit_rate->denominator; + } + } + + aafiVideoTrack* videoTrack = NULL; + + foreach_videoTrack (videoTrack, aafi) + { + if (videoTrack->current_pos > aafi->Video->length) { + aafi->Video->length = videoTrack->current_pos; + aafi->Video->length_editRate.numerator = videoTrack->edit_rate->numerator; + aafi->Video->length_editRate.denominator = videoTrack->edit_rate->denominator; + } + } + + if (aafi->Audio->length > aafi->Video->length) { + aafi->compositionLength = aafi->Audio->length; + aafi->compositionLength_editRate.numerator = aafi->Audio->length_editRate.numerator; + aafi->compositionLength_editRate.denominator = aafi->Audio->length_editRate.denominator; + } else { + aafi->compositionLength = aafi->Video->length; + aafi->compositionLength_editRate.numerator = aafi->Video->length_editRate.numerator; + aafi->compositionLength_editRate.denominator = aafi->Video->length_editRate.denominator; + } + + aafi->compositionStart = aafi->Timecode->start; + aafi->compositionStart_editRate.numerator = aafi->Timecode->edit_rate->numerator; + aafi->compositionStart_editRate.denominator = aafi->Timecode->edit_rate->denominator; + + if (protools_AAF (aafi)) { + protools_post_processing (aafi); + } + + return 0; +} + +/** + * @} + */ diff --git a/libs/aaf/AAFIface.c b/libs/aaf/AAFIface.c new file mode 100644 index 0000000000..8d62450928 --- /dev/null +++ b/libs/aaf/AAFIface.c @@ -0,0 +1,848 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * @file LibAAF/AAFIface/AAFIface.c + * @brief AAF processing + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + * + * @ingroup AAFIface + * @addtogroup AAFIface + * + * The AAFIface provides the actual processing of the AAF Objects in order to show + * essences and clips in a simplified manner. Indeed, AAF has many different ways to + * store data and metadata. Thus, the AAFIface is an abstraction layer that provides + * a constant and unique representation method of essences and clips. + * + * + * + * @{ + */ + +#include +#include +#include +#include + +#include "aaf/AAFIParser.h" +#include "aaf/AAFIface.h" +#include "aaf/debug.h" +#include "aaf/utils.h" + +#ifdef _WIN32 +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif +#endif + +#define debug(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +AAF_Iface* +aafi_alloc (AAF_Data* aafd) +{ + AAF_Iface* aafi = calloc (sizeof (AAF_Iface), sizeof (unsigned char)); + + if (aafi == NULL) { + return NULL; + } + + aafi->dbg = laaf_new_debug (); + + if (aafi->dbg == NULL) { + return NULL; + } + + aafi->Audio = calloc (sizeof (aafiAudio), sizeof (unsigned char)); + + if (aafi->Audio == NULL) { + return NULL; + } + + aafi->Audio->Essences = NULL; + aafi->Audio->samplerate = 0; + aafi->Audio->samplesize = 0; + aafi->Audio->Tracks = NULL; + aafi->Audio->track_count = 0; + aafi->Audio->length = 0; + + aafi->Video = calloc (sizeof (aafiVideo), sizeof (unsigned char)); + + if (aafi->Video == NULL) { + return NULL; + } + + aafi->Video->Essences = NULL; + aafi->Video->Tracks = NULL; + aafi->Video->length = 0; + + if (aafd != NULL) { + aafi->aafd = aafd; + } else { + aafi->aafd = aaf_alloc (aafi->dbg); + } + + aafi->Markers = NULL; + + aafi->compositionName = NULL; + + aafi->ctx.is_inside_derivation_chain = 0; + aafi->ctx.options.forbid_nonlatin_filenames = 0; + aafi->ctx.options.trace = 0; + + return aafi; +} + +void +aafi_enable_windows_VT100_output (void) +{ +#ifdef _WIN32 + /* enables ANSI colors and unicode chars */ + HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE); + DWORD dwMode = 0; + GetConsoleMode (hOut, &dwMode); + SetConsoleMode (hOut, (dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)); +#endif +} + +void +aafi_set_debug (AAF_Iface* aafi, verbosityLevel_e v, FILE* fp, void (*callback) (struct dbg* dbg, void* ctxdata, int lib, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user), void* user) +{ + aafi->dbg->verb = v; + aafi->dbg->fp = fp; + + if (callback) { + aafi->dbg->debug_callback = callback; + } + + if (user) { + aafi->dbg->user = user; + } +} + +int +aafi_set_media_location (AAF_Iface* aafi, const char* path) +{ + if (aafi->ctx.options.media_location) { + free (aafi->ctx.options.media_location); + } + + aafi->ctx.options.media_location = (path) ? laaf_util_c99strdup (path) : NULL; + + return 0; +} + +int +aafi_set_trace_class (AAF_Iface* aafi, const char* className) +{ + if (aafi->ctx.options.trace_class) { + free (aafi->ctx.options.trace_class); + aafi->ctx.options.trace_class = NULL; + } + + aafi->ctx.options.trace_class = malloc ((strlen (className) + 1) * sizeof (wchar_t)); + + if (aafi->ctx.options.trace_class == NULL) { + return -1; + } + + swprintf (aafi->ctx.options.trace_class, strlen (className) + 1, L"%" WPRIs, className); + + return 0; +} + +void +aafi_release (AAF_Iface** aafi) +{ + if (*aafi == NULL) + return; + + aaf_release (&(*aafi)->aafd); + + if ((*aafi)->compositionName != NULL) { + free ((*aafi)->compositionName); + } + + if ((*aafi)->Comments) { + aafi_freeUserComments (&((*aafi)->Comments)); + } + + if ((*aafi)->Audio != NULL) { + if ((*aafi)->Audio->Tracks != NULL) { + aafi_freeAudioTracks (&(*aafi)->Audio->Tracks); + } + + if ((*aafi)->Audio->Essences != NULL) { + aafi_freeAudioEssences (&(*aafi)->Audio->Essences); + } + + free ((*aafi)->Audio); + } + + if ((*aafi)->Video != NULL) { + if ((*aafi)->Video->Tracks != NULL) { + aafi_freeVideoTracks (&(*aafi)->Video->Tracks); + } + + if ((*aafi)->Video->Essences != NULL) { + aafi_freeVideoEssences (&(*aafi)->Video->Essences); + } + + free ((*aafi)->Video); + } + + if ((*aafi)->Markers) { + aafi_freeMarkers (&(*aafi)->Markers); + } + + if ((*aafi)->ctx.options.trace_class) { + free ((*aafi)->ctx.options.trace_class); + } + + if ((*aafi)->ctx.options.media_location) { + free ((*aafi)->ctx.options.media_location); + } + + if ((*aafi)->Timecode != NULL) { + free ((*aafi)->Timecode); + } + + if ((*aafi)->dbg) { + laaf_free_debug ((*aafi)->dbg); + } + + free (*aafi); + + *aafi = NULL; +} + +int +aafi_load_file (AAF_Iface* aafi, const char* file) +{ + if (aaf_load_file (aafi->aafd, file)) { + error ("Could not load file : %s\n", file); + return 1; + } + + aafi_retrieveData (aafi); + + return 0; +} + +aafiTransition* +aafi_get_fadein (aafiTimelineItem* audioItem) +{ + if (audioItem->prev != NULL && + audioItem->prev->type == AAFI_TRANS) { + aafiTransition* Trans = audioItem->prev->data; + + if (Trans->flags & AAFI_TRANS_FADE_IN) + return Trans; + } + + return NULL; +} + +aafiTransition* +aafi_get_fadeout (aafiTimelineItem* audioItem) +{ + if (audioItem->next != NULL && + audioItem->next->type == AAFI_TRANS) { + aafiTransition* Trans = audioItem->next->data; + + if (Trans->flags & AAFI_TRANS_FADE_OUT) + return Trans; + } + + return NULL; +} + +aafiTransition* +aafi_get_xfade (aafiTimelineItem* audioItem) +{ + if (audioItem->prev != NULL && + audioItem->prev->type == AAFI_TRANS) { + aafiTransition* Trans = audioItem->prev->data; + + if (Trans->flags & AAFI_TRANS_XFADE) + return Trans; + } + + return NULL; +} + +aafiMarker* +aafi_newMarker (AAF_Iface* aafi, aafRational_t* editRate, aafPosition_t start, aafPosition_t length, wchar_t* name, wchar_t* comment, uint16_t*(RVBColor[3])) +{ + aafiMarker* marker = malloc (sizeof (aafiMarker)); + + marker->edit_rate = editRate; + marker->start = start; + marker->length = length; + + marker->name = name; + marker->comment = comment; + + marker->prev = NULL; + marker->next = NULL; + + if (RVBColor) { + marker->RVBColor[0] = (*RVBColor)[0]; + marker->RVBColor[1] = (*RVBColor)[1]; + marker->RVBColor[2] = (*RVBColor)[2]; + } + + if (aafi->Markers != NULL) { + aafiMarker* tmp = aafi->Markers; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + tmp->next = marker; + marker->prev = marker; + } else { + aafi->Markers = marker; + marker->prev = NULL; + } + + return marker; +} + +void +aafi_freeMarkers (aafiMarker** Markers) +{ + aafiMarker* marker = NULL; + aafiMarker* nextMarker = NULL; + + for (marker = (*Markers); marker != NULL; marker = nextMarker) { + nextMarker = marker->next; + + if (marker->name) + free (marker->name); + + if (marker->comment) + free (marker->comment); + + free (marker); + } + + *Markers = NULL; +} + +aafiTimelineItem* +aafi_newTimelineItem (AAF_Iface* aafi, void* track, int itemType) +{ + aafiTimelineItem* item = NULL; + + if (itemType == AAFI_AUDIO_CLIP) { + item = calloc (sizeof (aafiTimelineItem), sizeof (char)); + + if (item == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + item->type = AAFI_AUDIO_CLIP; + + item->data = calloc (sizeof (aafiAudioClip), sizeof (char)); + + aafiAudioClip* audioClip = item->data; + + audioClip->track = (aafiAudioTrack*)track; + audioClip->Item = item; + } else if (itemType == AAFI_VIDEO_CLIP) { + item = calloc (sizeof (aafiTimelineItem), sizeof (char)); + + if (item == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + item->type = AAFI_VIDEO_CLIP; + + item->data = calloc (sizeof (aafiVideoClip), sizeof (char)); + + aafiVideoClip* videoClip = item->data; + + videoClip->track = (aafiVideoTrack*)track; + } else if (itemType == AAFI_TRANS) { + item = calloc (sizeof (aafiTimelineItem), sizeof (char)); + + if (item == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + item->type = AAFI_TRANS; + + item->data = calloc (sizeof (aafiTransition), sizeof (char)); + } + + if (itemType == AAFI_AUDIO_CLIP || itemType == AAFI_TRANS) { + if (track != NULL) { + /* Add to track's item list */ + + if (((aafiAudioTrack*)track)->Items != NULL) { + aafiTimelineItem* tmp = ((aafiAudioTrack*)track)->Items; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + tmp->next = item; + item->prev = tmp; + } else { + ((aafiAudioTrack*)track)->Items = item; + item->prev = NULL; + } + } + } else if (itemType == AAFI_VIDEO_CLIP) { + if (track != NULL) { + /* Add to track's item list */ + + if (((aafiVideoTrack*)track)->Items != NULL) { + aafiTimelineItem* tmp = ((aafiVideoTrack*)track)->Items; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + tmp->next = item; + item->prev = tmp; + } else { + ((aafiVideoTrack*)track)->Items = item; + item->prev = NULL; + } + } + } + + return item; +} + +int +aafi_removeTimelineItem (AAF_Iface* aafi, aafiTimelineItem* item) +{ + if (item->prev != NULL) { + item->prev->next = item->next; + } + + if (item->next != NULL) { + item->next->prev = item->prev; + } + + aafiAudioTrack* audioTrack = NULL; + + foreach_audioTrack (audioTrack, aafi) + { + if (audioTrack->Items == item) { + audioTrack->Items = item->next; + } + } + + aafi_freeTimelineItem (&item); + + return 0; +} + +void +aafi_freeAudioGain (aafiAudioGain* gain) +{ + if (gain == NULL) { + return; + } + + if (gain->time != NULL) { + free (gain->time); + } + + if (gain->value != NULL) { + free (gain->value); + } + + free (gain); +} + +void +aafi_freeAudioPan (aafiAudioPan* pan) +{ + aafi_freeAudioGain ((aafiAudioGain*)pan); +} + +void +aafi_freeAudioClip (aafiAudioClip* audioClip) +{ + if (audioClip->gain != NULL) { + aafi_freeAudioGain (audioClip->gain); + } + + if (audioClip->automation != NULL) { + aafi_freeAudioGain (audioClip->automation); + } +} + +void +aafi_freeTimelineItem (aafiTimelineItem** item) +{ + if ((*item)->type == AAFI_TRANS) { + aafi_freeTransition ((aafiTransition*)((*item)->data)); + free ((*item)->data); + } else if ((*item)->type == AAFI_AUDIO_CLIP) { + aafi_freeAudioClip ((aafiAudioClip*)((*item)->data)); + free ((*item)->data); + } else if ((*item)->type == AAFI_VIDEO_CLIP) { + free ((*item)->data); + } + + free (*item); + + *item = NULL; +} + +void +aafi_freeTimelineItems (aafiTimelineItem** items) +{ + aafiTimelineItem* item = NULL; + aafiTimelineItem* nextItem = NULL; + + for (item = (*items); item != NULL; item = nextItem) { + nextItem = item->next; + aafi_freeTimelineItem (&item); + } + + *items = NULL; +} + +aafiUserComment* +aafi_newUserComment (AAF_Iface* aafi, aafiUserComment** CommentList) +{ + aafiUserComment* UserComment = calloc (sizeof (aafiUserComment), 1); + + if (UserComment == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + if (CommentList != NULL) { + UserComment->next = *CommentList; + *CommentList = UserComment; + } else { + *CommentList = UserComment; + } + + return UserComment; +} + +void +aafi_freeUserComments (aafiUserComment** CommentList) +{ + aafiUserComment* UserComment = *CommentList; + aafiUserComment* tmp = NULL; + + while (UserComment != NULL) { + tmp = UserComment; + UserComment = UserComment->next; + + if (tmp->name != NULL) { + free (tmp->name); + } + + if (tmp->text != NULL) { + free (tmp->text); + } + + free (tmp); + } + + *CommentList = NULL; +} + +void +aafi_freeTransition (aafiTransition* Transition) +{ + if (Transition->value_a != NULL) { + free (Transition->value_a); + } + + if (Transition->value_b != NULL) { + free (Transition->value_b); + } + + if (Transition->time_a != NULL) { + free (Transition->time_a); + } + + if (Transition->time_b != NULL) { + free (Transition->time_b); + } +} + +aafiAudioTrack* +aafi_newAudioTrack (AAF_Iface* aafi) +{ + aafiAudioTrack* track = calloc (sizeof (aafiAudioTrack), sizeof (unsigned char)); + + if (track == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + track->Audio = aafi->Audio; + track->format = AAFI_TRACK_FORMAT_NOT_SET; + track->pan = NULL; + track->gain = NULL; + track->current_pos = 0; + track->next = NULL; + + /* Add to track list */ + + if (aafi->Audio->Tracks != NULL) { + aafiAudioTrack* tmp = aafi->Audio->Tracks; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + tmp->next = track; + } else { + aafi->Audio->Tracks = track; + } + + return track; +} + +void +aafi_freeAudioTracks (aafiAudioTrack** tracks) +{ + if (*(tracks) == NULL) { + return; + } + + aafiAudioTrack* track = NULL; + aafiAudioTrack* nextTrack = NULL; + + for (track = (*tracks); track != NULL; track = nextTrack) { + nextTrack = track->next; + + if (track->name != NULL) { + free (track->name); + } + + if (track->gain != NULL) { + aafi_freeAudioGain (track->gain); + } + + if (track->pan != NULL) { + aafi_freeAudioPan (track->pan); + } + + if (track->Items != NULL) { + aafi_freeTimelineItems (&(track->Items)); + } + + free (track); + } + + *tracks = NULL; +} + +aafiVideoTrack* +aafi_newVideoTrack (AAF_Iface* aafi) +{ + aafiVideoTrack* track = calloc (sizeof (aafiVideoTrack), sizeof (unsigned char)); + + if (track == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + track->Video = aafi->Video; + track->current_pos = 0; + track->next = NULL; + + /* Add to track list */ + + if (aafi->Video->Tracks != NULL) { + aafiVideoTrack* tmp = aafi->Video->Tracks; + + for (; tmp != NULL; tmp = tmp->next) + if (tmp->next == NULL) + break; + + tmp->next = track; + } else { + aafi->Video->Tracks = track; + } + + return track; +} + +void +aafi_freeVideoTracks (aafiVideoTrack** tracks) +{ + if (*(tracks) == NULL) { + return; + } + + aafiVideoTrack* track = NULL; + aafiVideoTrack* nextTrack = NULL; + + for (track = (*tracks); track != NULL; track = nextTrack) { + nextTrack = track->next; + + if (track->name != NULL) { + free (track->name); + } + + if (track->Items != NULL) { + aafi_freeTimelineItems (&(track->Items)); + } + + free (track); + } + + *tracks = NULL; +} + +aafiAudioEssence* +aafi_newAudioEssence (AAF_Iface* aafi) +{ + aafiAudioEssence* audioEssence = calloc (sizeof (aafiAudioEssence), sizeof (char)); + + if (audioEssence == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + audioEssence->next = aafi->Audio->Essences; + + audioEssence->original_file_path = NULL; + audioEssence->usable_file_path = NULL; + audioEssence->file_name = NULL; + audioEssence->unique_file_name = NULL; + audioEssence->clip_count = 0; + audioEssence->user = NULL; + + aafi->Audio->Essences = audioEssence; + + return audioEssence; +} + +void +aafi_freeAudioEssences (aafiAudioEssence** audioEssence) +{ + if (*(audioEssence) == NULL) { + return; + } + + aafiAudioEssence* nextAudioEssence = NULL; + + for (; (*audioEssence) != NULL; *audioEssence = nextAudioEssence) { + nextAudioEssence = (*audioEssence)->next; + + if ((*audioEssence)->original_file_path != NULL) { + free ((*audioEssence)->original_file_path); + } + + if ((*audioEssence)->usable_file_path != NULL) { + free ((*audioEssence)->usable_file_path); + } + + if ((*audioEssence)->file_name != NULL) { + free ((*audioEssence)->file_name); + } + + if ((*audioEssence)->unique_file_name != NULL) { + free ((*audioEssence)->unique_file_name); + } + + free (*audioEssence); + } + + *audioEssence = NULL; +} + +aafiVideoEssence* +aafi_newVideoEssence (AAF_Iface* aafi) +{ + aafiVideoEssence* videoEssence = calloc (sizeof (aafiVideoEssence), sizeof (char)); + + if (videoEssence == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + videoEssence->next = aafi->Video->Essences; + + videoEssence->original_file_path = NULL; + videoEssence->usable_file_path = NULL; + videoEssence->file_name = NULL; + videoEssence->unique_file_name = NULL; + + aafi->Video->Essences = videoEssence; + + return videoEssence; +} + +void +aafi_freeVideoEssences (aafiVideoEssence** videoEssence) +{ + if (*(videoEssence) == NULL) { + return; + } + + aafiVideoEssence* nextVideoEssence = NULL; + + for (; (*videoEssence) != NULL; *videoEssence = nextVideoEssence) { + nextVideoEssence = (*videoEssence)->next; + + if ((*videoEssence)->original_file_path != NULL) { + free ((*videoEssence)->original_file_path); + } + + if ((*videoEssence)->usable_file_path != NULL) { + free ((*videoEssence)->usable_file_path); + } + + if ((*videoEssence)->file_name != NULL) { + free ((*videoEssence)->file_name); + } + + if ((*videoEssence)->unique_file_name != NULL) { + free ((*videoEssence)->unique_file_name); + } + + free (*videoEssence); + } + + *videoEssence = NULL; +} + +/** + * @} + */ diff --git a/libs/aaf/AAFToText.c b/libs/aaf/AAFToText.c new file mode 100644 index 0000000000..c10456c8a4 --- /dev/null +++ b/libs/aaf/AAFToText.c @@ -0,0 +1,2438 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "aaf/AAFDefs/AAFClassDefUIDs.h" +#include "aaf/AAFDefs/AAFCompressionDefs.h" +#include "aaf/AAFDefs/AAFContainerDefs.h" +#include "aaf/AAFDefs/AAFDataDefs.h" +#include "aaf/AAFDefs/AAFExtEnum.h" +#include "aaf/AAFDefs/AAFFileKinds.h" +#include "aaf/AAFDefs/AAFInterpolatorDefs.h" +#include "aaf/AAFDefs/AAFOPDefs.h" +#include "aaf/AAFDefs/AAFOperationDefs.h" +#include "aaf/AAFDefs/AAFParameterDefs.h" +#include "aaf/AAFDefs/AAFPropertyIDs.h" +#include "aaf/AAFDefs/AAFTypeDefUIDs.h" + +#include "aaf/AAFToText.h" +#include "aaf/AAFTypes.h" + +#include "aaf/AAFClass.h" +#include "aaf/utils.h" + +const wchar_t* +aaft_MobIDToText (aafMobID_t* mobid) +{ + static wchar_t str[127]; + + uint32_t i = 0; + uint32_t offset = 0; + + for (i = 0; i < sizeof (aafMobID_t); i++) { + if (i == 12) + offset += swprintf (str + offset, (2 * sizeof (aafMobID_t)), L" - "); + if (i == 13) + offset += swprintf (str + offset, (2 * sizeof (aafMobID_t)), L" - "); + if (i == 14) + offset += swprintf (str + offset, (2 * sizeof (aafMobID_t)), L" - "); + if (i == 15) + offset += swprintf (str + offset, (2 * sizeof (aafMobID_t)), L" - "); + + offset += swprintf (str + offset, 127, L"%02x", ((unsigned char*)mobid)[i]); + + if (i == 15) { + offset += swprintf (str + offset, 127, L" - "); + break; + } + } + + aafUID_t material; + + memcpy (&material, ((unsigned char*)mobid) + i, sizeof (aafUID_t)); + + offset += swprintf (str + offset, 127, L"%" WPRIws, AUIDToText (&material)); + + return str; +} + +const wchar_t* +aaft_TimestampToText (aafTimeStamp_t* ts) +{ + static wchar_t str[24]; + + if (ts == NULL) { + str[0] = 'n'; + str[1] = '/'; + str[2] = 'a'; + str[3] = '\0'; + } else { + swprintf (str, sizeof (str), L"%04i-%02u-%02u %02u:%02u:%02u.%02u", + ts->date.year, + ts->date.month, + ts->date.day, + ts->time.hour, + ts->time.minute, + ts->time.second, + ts->time.fraction); + } + + return str; +} + +const wchar_t* +aaft_VersionToText (aafVersionType_t* vers) +{ + static wchar_t str[16]; + + if (vers == NULL) { + str[0] = 'n'; + str[1] = '/'; + str[2] = 'a'; + str[3] = '\0'; + } else { + swprintf (str, sizeof (str), L"%i.%i", + vers->major, + vers->minor); + } + + return str; +} + +const wchar_t* +aaft_ProductVersionToText (aafProductVersion_t* vers) +{ + static wchar_t str[64]; + + if (vers == NULL) { + str[0] = 'n'; + str[1] = '/'; + str[2] = 'a'; + str[3] = '\0'; + } else { + swprintf (str, sizeof (str), L"%u.%u.%u.%u %" WPRIws L" (%i)", + vers->major, + vers->minor, + vers->tertiary, + vers->patchLevel, + aaft_ProductReleaseTypeToText (vers->type), + vers->type); + } + + return str; +} + +const wchar_t* +aaft_FileKindToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + /* NOTE: AAFUID_NULL = AAFFileKind_DontCare */ + if (aafUIDCmp (auid, &AAFFileKind_DontCare)) + return L"AAFFileKind_DontCare"; + if (aafUIDCmp (auid, &AAFFileKind_Aaf512Binary)) + return L"AAFFileKind_Aaf512Binary"; + if (aafUIDCmp (auid, &AAFFileKind_Aaf4KBinary)) + return L"AAFFileKind_Aaf4KBinary"; + if (aafUIDCmp (auid, &AAFFileKind_AafXmlText)) + return L"AAFFileKind_AafXmlText"; + if (aafUIDCmp (auid, &AAFFileKind_AafKlvBinary)) + return L"AAFFileKind_AafKlvBinary"; + if (aafUIDCmp (auid, &AAFFileKind_AafM512Binary)) + return L"AAFFileKind_AafM512Binary"; + if (aafUIDCmp (auid, &AAFFileKind_AafS512Binary)) + return L"AAFFileKind_AafS512Binary"; + if (aafUIDCmp (auid, &AAFFileKind_AafG512Binary)) + return L"AAFFileKind_AafG512Binary"; + if (aafUIDCmp (auid, &AAFFileKind_AafM4KBinary)) + return L"AAFFileKind_AafM4KBinary"; + if (aafUIDCmp (auid, &AAFFileKind_AafS4KBinary)) + return L"AAFFileKind_AafS4KBinary"; + if (aafUIDCmp (auid, &AAFFileKind_AafG4KBinary)) + return L"AAFFileKind_AafG4KBinary"; + if (aafUIDCmp (auid, &AAFFileKind_Pathological)) + return L"AAFFileKind_Pathological"; + + return L"Unknown AAFFileKind"; +} + +const wchar_t* +aaft_TapeCaseTypeToText (aafTapeCaseType_t t) +{ + switch (t) { + case AAFTapeCaseNull: + return L"AAFTapeCaseNull"; + case AAFThreeFourthInchVideoTape: + return L"AAFThreeFourthInchVideoTape"; + case AAFVHSVideoTape: + return L"AAFVHSVideoTape"; + case AAF8mmVideoTape: + return L"AAF8mmVideoTape"; + case AAFBetacamVideoTape: + return L"AAFBetacamVideoTape"; + case AAFCompactCassette: + return L"AAFCompactCassette"; + case AAFDATCartridge: + return L"AAFDATCartridge"; + case AAFNagraAudioTape: + return L"AAFNagraAudioTape"; + } + + return L"Unknown TapeCaseType"; +} + +const wchar_t* +aaft_VideoSignalTypeToText (aafVideoSignalType_t v) +{ + switch (v) { + case AAFVideoSignalNull: + return L"AAFVideoSignalNull"; + case AAFNTSCSignal: + return L"AAFNTSCSignal"; + case AAFPALSignal: + return L"AAFPALSignal"; + case AAFSECAMSignal: + return L"AAFSECAMSignal"; + } + + return L"Unknown VideoSignalType"; +} + +const wchar_t* +aaft_TapeFormatTypeToText (aafTapeFormatType_t t) +{ + switch (t) { + case AAFTapeFormatNull: + return L"AAFTapeFormatNull"; + case AAFBetacamFormat: + return L"AAFBetacamFormat"; + case AAFBetacamSPFormat: + return L"AAFBetacamSPFormat"; + case AAFVHSFormat: + return L"AAFVHSFormat"; + case AAFSVHSFormat: + return L"AAFSVHSFormat"; + case AAF8mmFormat: + return L"AAF8mmFormat"; + case AAFHi8Format: + return L"AAFHi8Format"; + } + + return L"Unknown TapeFormatType"; +} + +const wchar_t* +aaft_FilmTypeToText (aafFilmType_t f) +{ + switch (f) { + case AAFFtNull: + return L"AAFFtNull"; + case AAFFt35MM: + return L"AAFFt35MM"; + case AAFFt16MM: + return L"AAFFt16MM"; + case AAFFt8MM: + return L"AAFFt8MM"; + case AAFFt65MM: + return L"AAFFt65MM"; + } + + return L"Unknown FilmType"; +} + +const wchar_t* +aaft_SignalStandardToText (aafSignalStandard_t s) +{ + switch (s) { + case AAFSignalStandard_None: + return L"AAFSignalStandard_None"; + case AAFSignalStandard_ITU601: + return L"AAFSignalStandard_ITU601"; + case AAFSignalStandard_ITU1358: + return L"AAFSignalStandard_ITU1358"; + case AAFSignalStandard_SMPTE347M: + return L"AAFSignalStandard_SMPTE347M"; + case AAFSignalStandard_SMPTE274M: + return L"AAFSignalStandard_SMPTE274M"; + case AAFSignalStandard_SMPTE296M: + return L"AAFSignalStandard_SMPTE296M"; + case AAFSignalStandard_SMPTE349M: + return L"AAFSignalStandard_SMPTE349M"; + } + + return L"Unknown SignalStandard"; +} + +const wchar_t* +aaft_FieldNumberToText (aafFieldNumber_t f) +{ + switch (f) { + case AAFUnspecifiedField: + return L"AAFUnspecifiedField"; + case AAFFieldOne: + return L"AAFFieldOne"; + case AAFFieldTwo: + return L"AAFFieldTwo"; + } + + return L"Unknown FieldNumber"; +} + +const wchar_t* +aaft_AlphaTransparencyToText (aafAlphaTransparency_t a) +{ + switch (a) { + case AAFMinValueTransparent: + return L"AAFMinValueTransparent"; + case AAFMaxValueTransparent: + return L"AAFMaxValueTransparent"; + } + + return L"Unknown AlphaTransparency"; +} + +const wchar_t* +aaft_FrameLayoutToText (aafFrameLayout_t f) +{ + switch (f) { + case AAFFullFrame: + return L"AAFFullFrame"; + case AAFSeparateFields: + return L"AAFSeparateFields"; + case AAFOneField: + return L"AAFOneField"; + case AAFMixedFields: + return L"AAFMixedFields"; + case AAFSegmentedFrame: + return L"AAFSegmentedFrame"; + } + + return L"Unknown FrameLayout"; +} + +const wchar_t* +aaft_ColorSitingToText (aafColorSiting_t c) +{ + switch (c) { + case AAFCoSiting: + return L"AAFCoSiting"; + case AAFAveraging: + return L"AAFAveraging"; + case AAFThreeTap: + return L"AAFThreeTap"; + case AAFQuincunx: + return L"AAFQuincunx"; + case AAFRec601: + return L"AAFRec601"; + case AAFUnknownSiting: + return L"AAFUnknownSiting"; + } + + return L"Unknown ColorSiting"; +} + +const wchar_t* +aaft_ProductReleaseTypeToText (aafProductReleaseType_t t) +{ + switch (t) { + case AAFVersionUnknown: + return L"AAFVersionUnknown"; + case AAFVersionReleased: + return L"AAFVersionReleased"; + case AAFVersionDebug: + return L"AAFVersionDebug"; + case AAFVersionPatched: + return L"AAFVersionPatched"; + case AAFVersionBeta: + return L"AAFVersionBeta"; + case AAFVersionPrivateBuild: + return L"AAFVersionPrivateBuild"; + } + + return L"Unknown ProductReleaseType"; +} + +const wchar_t* +aaft_FadeTypeToText (aafFadeType_t f) +{ + switch (f) { + case AAFFadeNone: + return L"AAFFadeNone"; + case AAFFadeLinearAmp: + return L"AAFFadeLinearAmp"; + case AAFFadeLinearPower: + return L"AAFFadeLinearPower"; + } + + return L"Unknown FadeType"; +} + +const wchar_t* +aaft_BoolToText (aafBoolean_t b) +{ + switch (b) { + case 1: + return L"True"; + case 0: + return L"False"; + } + + return L"Unknown Boolean"; +} + +const wchar_t* +aaft_OperationCategoryToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFOperationCategory_Effect)) + return L"AAFOperationCategory_Effect"; + + return L"Unknown AAFOperationCategory"; +} + +const wchar_t* +aaft_PluginCategoryToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFPluginCategory_Effect)) + return L"AAFPluginCategory_Effect"; + if (aafUIDCmp (auid, &AAFPluginCategory_Codec)) + return L"AAFPluginCategory_Codec"; + if (aafUIDCmp (auid, &AAFPluginCategory_Interpolation)) + return L"AAFPluginCategory_Interpolation"; + + return L"Unknown AAFPluginCategory"; +} + +const wchar_t* +aaft_ScanningDirectionToText (aafScanningDirection_t s) +{ + switch (s) { + case AAFScanningDirection_LeftToRightTopToBottom: + return L"AAFScanningDirection_LeftToRightTopToBottom"; + case AAFScanningDirection_RightToLeftTopToBottom: + return L"AAFScanningDirection_RightToLeftTopToBottom"; + case AAFScanningDirection_LeftToRightBottomToTop: + return L"AAFScanningDirection_LeftToRightBottomToTop"; + case AAFScanningDirection_RightToLeftBottomToTop: + return L"AAFScanningDirection_RightToLeftBottomToTop"; + case AAFScanningDirection_TopToBottomLeftToRight: + return L"AAFScanningDirection_TopToBottomLeftToRight"; + case AAFScanningDirection_TopToBottomRightToLeft: + return L"AAFScanningDirection_TopToBottomRightToLeft"; + case AAFScanningDirection_BottomToTopLeftToRight: + return L"AAFScanningDirection_BottomToTopLeftToRight"; + case AAFScanningDirection_BottomToTopRightToLeft: + return L"AAFScanningDirection_BottomToTopRightToLeft"; + } + + return L"Unknown AAFScanningDirection"; +} + +const wchar_t* +aaft_ByteOrderToText (int16_t bo) +{ + switch (bo) { + case AAF_HEADER_BYTEORDER_LE: + case AAF_PROPERTIES_BYTEORDER_LE: + return L"Little-Endian"; + + case AAF_HEADER_BYTEORDER_BE: + case AAF_PROPERTIES_BYTEORDER_BE: + return L"Big-Endian"; + } + + return L"Unknown ByteOrder"; +} + +const wchar_t* +aaft_ElectroSpatialToText (aafElectroSpatialFormulation_t e) +{ + switch (e) { + case AAFElectroSpatialFormulation_Default: + return L"AAFElectroSpatialFormulation_Default"; + case AAFElectroSpatialFormulation_TwoChannelMode: + return L"AAFElectroSpatialFormulation_TwoChannelMode"; + case AAFElectroSpatialFormulation_SingleChannelMode: + return L"AAFElectroSpatialFormulation_SingleChannelMode"; + case AAFElectroSpatialFormulation_PrimarySecondaryMode: + return L"AAFElectroSpatialFormulation_PrimarySecondaryMode"; + case AAFElectroSpatialFormulation_StereophonicMode: + return L"AAFElectroSpatialFormulation_StereophonicMode"; + case AAFElectroSpatialFormulation_SingleChannelDoubleSamplingFrequencyMode: + return L"AAFElectroSpatialFormulation_SingleChannelDoubleSamplingFrequencyMode"; + case AAFElectroSpatialFormulation_StereoLeftChannelDoubleSamplingFrequencyMode: + return L"AAFElectroSpatialFormulation_StereoLeftChannelDoubleSamplingFrequencyMode"; + case AAFElectroSpatialFormulation_StereoRightChannelDoubleSamplingFrequencyMode: + return L"AAFElectroSpatialFormulation_StereoRightChannelDoubleSamplingFrequencyMode"; + case AAFElectroSpatialFormulation_MultiChannelMode: + return L"AAFElectroSpatialFormulation_MultiChannelMode"; + } + + return L"Unknown AAFElectroSpatialFormulation"; +} + +const wchar_t* +aaft_StoredFormToText (enum aafStoredForm_e sf) +{ + switch (sf) { + case SF_DATA: + return L"SF_DATA"; + case SF_DATA_STREAM: + return L"SF_DATA_STREAM"; + case SF_STRONG_OBJECT_REFERENCE: + return L"SF_STRONG_OBJECT_REFERENCE"; + case SF_STRONG_OBJECT_REFERENCE_VECTOR: + return L"SF_STRONG_OBJECT_REFERENCE_VECTOR"; + case SF_STRONG_OBJECT_REFERENCE_SET: + return L"SF_STRONG_OBJECT_REFERENCE_SET"; + case SF_WEAK_OBJECT_REFERENCE: + return L"SF_WEAK_OBJECT_REFERENCE"; + case SF_WEAK_OBJECT_REFERENCE_VECTOR: + return L"SF_WEAK_OBJECT_REFERENCE_VECTOR"; + case SF_WEAK_OBJECT_REFERENCE_SET: + return L"SF_WEAK_OBJECT_REFERENCE_SET"; + case SF_WEAK_OBJECT_REFERENCE_STORED_OBJECT_ID: + return L"SF_WEAK_OBJECT_REFERENCE_STORED_OBJECT_ID"; + case SF_UNIQUE_OBJECT_ID: + return L"SF_UNIQUE_OBJECT_ID"; + case SF_OPAQUE_STREAM: + return L"SF_OPAQUE_STREAM"; + } + + return L"Unknown StoredForm"; +} + +const wchar_t* +aaft_OPDefToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFOPDef_EditProtocol)) + return L"AAFOPDef_EditProtocol"; + if (aafUIDCmp (auid, &AAFOPDef_Unconstrained)) + return L"AAFOPDef_Unconstrained"; + + return L"Unknown AAFOPDef"; +} + +const wchar_t* +aaft_TypeIDToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFTypeID_UInt8)) + return L"AAFTypeID_UInt8"; + if (aafUIDCmp (auid, &AAFTypeID_UInt16)) + return L"AAFTypeID_UInt16"; + if (aafUIDCmp (auid, &AAFTypeID_UInt32)) + return L"AAFTypeID_UInt32"; + if (aafUIDCmp (auid, &AAFTypeID_UInt64)) + return L"AAFTypeID_UInt64"; + if (aafUIDCmp (auid, &AAFTypeID_Int8)) + return L"AAFTypeID_Int8"; + if (aafUIDCmp (auid, &AAFTypeID_Int16)) + return L"AAFTypeID_Int16"; + if (aafUIDCmp (auid, &AAFTypeID_Int32)) + return L"AAFTypeID_Int32"; + if (aafUIDCmp (auid, &AAFTypeID_Int64)) + return L"AAFTypeID_Int64"; + if (aafUIDCmp (auid, &AAFTypeID_PositionType)) + return L"AAFTypeID_PositionType"; + if (aafUIDCmp (auid, &AAFTypeID_LengthType)) + return L"AAFTypeID_LengthType"; + if (aafUIDCmp (auid, &AAFTypeID_JPEGTableIDType)) + return L"AAFTypeID_JPEGTableIDType"; + if (aafUIDCmp (auid, &AAFTypeID_PhaseFrameType)) + return L"AAFTypeID_PhaseFrameType"; + if (aafUIDCmp (auid, &AAFTypeID_AUID)) + return L"AAFTypeID_AUID"; + if (aafUIDCmp (auid, &AAFTypeID_MobIDType)) + return L"AAFTypeID_MobIDType"; + if (aafUIDCmp (auid, &AAFTypeID_Boolean)) + return L"AAFTypeID_Boolean"; + if (aafUIDCmp (auid, &AAFTypeID_Character)) + return L"AAFTypeID_Character"; + if (aafUIDCmp (auid, &AAFTypeID_String)) + return L"AAFTypeID_String"; + if (aafUIDCmp (auid, &AAFTypeID_ProductReleaseType)) + return L"AAFTypeID_ProductReleaseType"; + if (aafUIDCmp (auid, &AAFTypeID_TapeFormatType)) + return L"AAFTypeID_TapeFormatType"; + if (aafUIDCmp (auid, &AAFTypeID_VideoSignalType)) + return L"AAFTypeID_VideoSignalType"; + if (aafUIDCmp (auid, &AAFTypeID_TapeCaseType)) + return L"AAFTypeID_TapeCaseType"; + if (aafUIDCmp (auid, &AAFTypeID_ColorSitingType)) + return L"AAFTypeID_ColorSitingType"; + if (aafUIDCmp (auid, &AAFTypeID_EditHintType)) + return L"AAFTypeID_EditHintType"; + if (aafUIDCmp (auid, &AAFTypeID_FadeType)) + return L"AAFTypeID_FadeType"; + if (aafUIDCmp (auid, &AAFTypeID_LayoutType)) + return L"AAFTypeID_LayoutType"; + if (aafUIDCmp (auid, &AAFTypeID_TCSource)) + return L"AAFTypeID_TCSource"; + if (aafUIDCmp (auid, &AAFTypeID_PulldownDirectionType)) + return L"AAFTypeID_PulldownDirectionType"; + if (aafUIDCmp (auid, &AAFTypeID_PulldownKindType)) + return L"AAFTypeID_PulldownKindType"; + if (aafUIDCmp (auid, &AAFTypeID_EdgeType)) + return L"AAFTypeID_EdgeType"; + if (aafUIDCmp (auid, &AAFTypeID_FilmType)) + return L"AAFTypeID_FilmType"; + if (aafUIDCmp (auid, &AAFTypeID_RGBAComponentKind)) + return L"AAFTypeID_RGBAComponentKind"; + if (aafUIDCmp (auid, &AAFTypeID_ReferenceType)) + return L"AAFTypeID_ReferenceType"; + if (aafUIDCmp (auid, &AAFTypeID_AlphaTransparencyType)) + return L"AAFTypeID_AlphaTransparencyType"; + if (aafUIDCmp (auid, &AAFTypeID_FieldNumber)) + return L"AAFTypeID_FieldNumber"; + if (aafUIDCmp (auid, &AAFTypeID_ElectroSpatialFormulation)) + return L"AAFTypeID_ElectroSpatialFormulation"; + if (aafUIDCmp (auid, &AAFTypeID_EmphasisType)) + return L"AAFTypeID_EmphasisType"; + if (aafUIDCmp (auid, &AAFTypeID_AuxBitsModeType)) + return L"AAFTypeID_AuxBitsModeType"; + if (aafUIDCmp (auid, &AAFTypeID_ChannelStatusModeType)) + return L"AAFTypeID_ChannelStatusModeType"; + if (aafUIDCmp (auid, &AAFTypeID_UserDataModeType)) + return L"AAFTypeID_UserDataModeType"; + if (aafUIDCmp (auid, &AAFTypeID_SignalStandardType)) + return L"AAFTypeID_SignalStandardType"; + if (aafUIDCmp (auid, &AAFTypeID_ScanningDirectionType)) + return L"AAFTypeID_ScanningDirectionType"; + if (aafUIDCmp (auid, &AAFTypeID_ContentScanningType)) + return L"AAFTypeID_ContentScanningType"; + if (aafUIDCmp (auid, &AAFTypeID_TitleAlignmentType)) + return L"AAFTypeID_TitleAlignmentType"; + if (aafUIDCmp (auid, &AAFTypeID_OperationCategoryType)) + return L"AAFTypeID_OperationCategoryType"; + if (aafUIDCmp (auid, &AAFTypeID_TransferCharacteristicType)) + return L"AAFTypeID_TransferCharacteristicType"; + if (aafUIDCmp (auid, &AAFTypeID_PluginCategoryType)) + return L"AAFTypeID_PluginCategoryType"; + if (aafUIDCmp (auid, &AAFTypeID_UsageType)) + return L"AAFTypeID_UsageType"; + if (aafUIDCmp (auid, &AAFTypeID_ColorPrimariesType)) + return L"AAFTypeID_ColorPrimariesType"; + if (aafUIDCmp (auid, &AAFTypeID_CodingEquationsType)) + return L"AAFTypeID_CodingEquationsType"; + if (aafUIDCmp (auid, &AAFTypeID_Rational)) + return L"AAFTypeID_Rational"; + if (aafUIDCmp (auid, &AAFTypeID_ProductVersion)) + return L"AAFTypeID_ProductVersion"; + if (aafUIDCmp (auid, &AAFTypeID_VersionType)) + return L"AAFTypeID_VersionType"; + if (aafUIDCmp (auid, &AAFTypeID_RGBAComponent)) + return L"AAFTypeID_RGBAComponent"; + if (aafUIDCmp (auid, &AAFTypeID_DateStruct)) + return L"AAFTypeID_DateStruct"; + if (aafUIDCmp (auid, &AAFTypeID_TimeStruct)) + return L"AAFTypeID_TimeStruct"; + if (aafUIDCmp (auid, &AAFTypeID_TimeStamp)) + return L"AAFTypeID_TimeStamp"; + if (aafUIDCmp (auid, &AAFTypeID_UInt8Array)) + return L"AAFTypeID_UInt8Array"; + if (aafUIDCmp (auid, &AAFTypeID_UInt8Array12)) + return L"AAFTypeID_UInt8Array12"; + if (aafUIDCmp (auid, &AAFTypeID_Int32Array)) + return L"AAFTypeID_Int32Array"; + if (aafUIDCmp (auid, &AAFTypeID_Int64Array)) + return L"AAFTypeID_Int64Array"; + if (aafUIDCmp (auid, &AAFTypeID_StringArray)) + return L"AAFTypeID_StringArray"; + if (aafUIDCmp (auid, &AAFTypeID_AUIDArray)) + return L"AAFTypeID_AUIDArray"; + if (aafUIDCmp (auid, &AAFTypeID_PositionArray)) + return L"AAFTypeID_PositionArray"; + if (aafUIDCmp (auid, &AAFTypeID_UInt8Array8)) + return L"AAFTypeID_UInt8Array8"; + if (aafUIDCmp (auid, &AAFTypeID_UInt32Array)) + return L"AAFTypeID_UInt32Array"; + if (aafUIDCmp (auid, &AAFTypeID_ChannelStatusModeArray)) + return L"AAFTypeID_ChannelStatusModeArray"; + if (aafUIDCmp (auid, &AAFTypeID_UserDataModeArray)) + return L"AAFTypeID_UserDataModeArray"; + if (aafUIDCmp (auid, &AAFTypeID_RGBALayout)) + return L"AAFTypeID_RGBALayout"; + if (aafUIDCmp (auid, &AAFTypeID_AUIDSet)) + return L"AAFTypeID_AUIDSet"; + if (aafUIDCmp (auid, &AAFTypeID_UInt32Set)) + return L"AAFTypeID_UInt32Set"; + if (aafUIDCmp (auid, &AAFTypeID_DataValue)) + return L"AAFTypeID_DataValue"; + if (aafUIDCmp (auid, &AAFTypeID_Stream)) + return L"AAFTypeID_Stream"; + if (aafUIDCmp (auid, &AAFTypeID_Indirect)) + return L"AAFTypeID_Indirect"; + if (aafUIDCmp (auid, &AAFTypeID_Opaque)) + return L"AAFTypeID_Opaque"; + if (aafUIDCmp (auid, &AAFTypeID_ClassDefinitionWeakReference)) + return L"AAFTypeID_ClassDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_ContainerDefinitionWeakReference)) + return L"AAFTypeID_ContainerDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_DataDefinitionWeakReference)) + return L"AAFTypeID_DataDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_InterpolationDefinitionWeakReference)) + return L"AAFTypeID_InterpolationDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_MobWeakReference)) + return L"AAFTypeID_MobWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_OperationDefinitionWeakReference)) + return L"AAFTypeID_OperationDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterDefinitionWeakReference)) + return L"AAFTypeID_ParameterDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_TypeDefinitionWeakReference)) + return L"AAFTypeID_TypeDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_PluginDefinitionWeakReference)) + return L"AAFTypeID_PluginDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_CodecDefinitionWeakReference)) + return L"AAFTypeID_CodecDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_PropertyDefinitionWeakReference)) + return L"AAFTypeID_PropertyDefinitionWeakReference"; + if (aafUIDCmp (auid, &AAFTypeID_ContentStorageStrongReference)) + return L"AAFTypeID_ContentStorageStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_DictionaryStrongReference)) + return L"AAFTypeID_DictionaryStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_EssenceDescriptorStrongReference)) + return L"AAFTypeID_EssenceDescriptorStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_NetworkLocatorStrongReference)) + return L"AAFTypeID_NetworkLocatorStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_OperationGroupStrongReference)) + return L"AAFTypeID_OperationGroupStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_SegmentStrongReference)) + return L"AAFTypeID_SegmentStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_SourceClipStrongReference)) + return L"AAFTypeID_SourceClipStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_SourceReferenceStrongReference)) + return L"AAFTypeID_SourceReferenceStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ClassDefinitionStrongReference)) + return L"AAFTypeID_ClassDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_CodecDefinitionStrongReference)) + return L"AAFTypeID_CodecDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ComponentStrongReference)) + return L"AAFTypeID_ComponentStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ContainerDefinitionStrongReference)) + return L"AAFTypeID_ContainerDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ControlPointStrongReference)) + return L"AAFTypeID_ControlPointStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_DataDefinitionStrongReference)) + return L"AAFTypeID_DataDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_EssenceDataStrongReference)) + return L"AAFTypeID_EssenceDataStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_IdentificationStrongReference)) + return L"AAFTypeID_IdentificationStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_InterpolationDefinitionStrongReference)) + return L"AAFTypeID_InterpolationDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_LocatorStrongReference)) + return L"AAFTypeID_LocatorStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_MobStrongReference)) + return L"AAFTypeID_MobStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_MobSlotStrongReference)) + return L"AAFTypeID_MobSlotStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_OperationDefinitionStrongReference)) + return L"AAFTypeID_OperationDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterStrongReference)) + return L"AAFTypeID_ParameterStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterDefinitionStrongReference)) + return L"AAFTypeID_ParameterDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_PluginDefinitionStrongReference)) + return L"AAFTypeID_PluginDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_PropertyDefinitionStrongReference)) + return L"AAFTypeID_PropertyDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_TaggedValueStrongReference)) + return L"AAFTypeID_TaggedValueStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_TypeDefinitionStrongReference)) + return L"AAFTypeID_TypeDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_KLVDataStrongReference)) + return L"AAFTypeID_KLVDataStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_FileDescriptorStrongReference)) + return L"AAFTypeID_FileDescriptorStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_RIFFChunkStrongReference)) + return L"AAFTypeID_RIFFChunkStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_DescriptiveFrameworkStrongReference)) + return L"AAFTypeID_DescriptiveFrameworkStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_KLVDataDefinitionStrongReference)) + return L"AAFTypeID_KLVDataDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_TaggedValueDefinitionStrongReference)) + return L"AAFTypeID_TaggedValueDefinitionStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_DescriptiveObjectStrongReference)) + return L"AAFTypeID_DescriptiveObjectStrongReference"; + if (aafUIDCmp (auid, &AAFTypeID_DataDefinitionWeakReferenceSet)) + return L"AAFTypeID_DataDefinitionWeakReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterDefinitionWeakReferenceSet)) + return L"AAFTypeID_ParameterDefinitionWeakReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_PluginDefinitionWeakReferenceSet)) + return L"AAFTypeID_PluginDefinitionWeakReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_PropertyDefinitionWeakReferenceSet)) + return L"AAFTypeID_PropertyDefinitionWeakReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_OperationDefinitionWeakReferenceVector)) + return L"AAFTypeID_OperationDefinitionWeakReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_TypeDefinitionWeakReferenceVector)) + return L"AAFTypeID_TypeDefinitionWeakReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_DataDefinitionWeakReferenceVector)) + return L"AAFTypeID_DataDefinitionWeakReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_ClassDefinitionStrongReferenceSet)) + return L"AAFTypeID_ClassDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_CodecDefinitionStrongReferenceSet)) + return L"AAFTypeID_CodecDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_ContainerDefinitionStrongReferenceSet)) + return L"AAFTypeID_ContainerDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_DataDefinitionStrongReferenceSet)) + return L"AAFTypeID_DataDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_EssenceDataStrongReferenceSet)) + return L"AAFTypeID_EssenceDataStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_InterpolationDefinitionStrongReferenceSet)) + return L"AAFTypeID_InterpolationDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_MobStrongReferenceSet)) + return L"AAFTypeID_MobStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_OperationDefinitionStrongReferenceSet)) + return L"AAFTypeID_OperationDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterDefinitionStrongReferenceSet)) + return L"AAFTypeID_ParameterDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_PluginDefinitionStrongReferenceSet)) + return L"AAFTypeID_PluginDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_PropertyDefinitionStrongReferenceSet)) + return L"AAFTypeID_PropertyDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_TypeDefinitionStrongReferenceSet)) + return L"AAFTypeID_TypeDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_KLVDataDefinitionStrongReferenceSet)) + return L"AAFTypeID_KLVDataDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_TaggedValueDefinitionStrongReferenceSet)) + return L"AAFTypeID_TaggedValueDefinitionStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_DescriptiveObjectStrongReferenceSet)) + return L"AAFTypeID_DescriptiveObjectStrongReferenceSet"; + if (aafUIDCmp (auid, &AAFTypeID_ComponentStrongReferenceVector)) + return L"AAFTypeID_ComponentStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_ControlPointStrongReferenceVector)) + return L"AAFTypeID_ControlPointStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_IdentificationStrongReferenceVector)) + return L"AAFTypeID_IdentificationStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_LocatorStrongReferenceVector)) + return L"AAFTypeID_LocatorStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_MobSlotStrongReferenceVector)) + return L"AAFTypeID_MobSlotStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_SegmentStrongReferenceVector)) + return L"AAFTypeID_SegmentStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_SourceReferenceStrongReferenceVector)) + return L"AAFTypeID_SourceReferenceStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_TaggedValueStrongReferenceVector)) + return L"AAFTypeID_TaggedValueStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_KLVDataStrongReferenceVector)) + return L"AAFTypeID_KLVDataStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_ParameterStrongReferenceVector)) + return L"AAFTypeID_ParameterStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_FileDescriptorStrongReferenceVector)) + return L"AAFTypeID_FileDescriptorStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_RIFFChunkStrongReferenceVector)) + return L"AAFTypeID_RIFFChunkStrongReferenceVector"; + if (aafUIDCmp (auid, &AAFTypeID_DescriptiveObjectStrongReferenceVector)) + return L"AAFTypeID_DescriptiveObjectStrongReferenceVector"; + + return L"Unknown AAFTypeID"; +} + +const wchar_t* +aaft_DataDefToText (AAF_Data* aafd, const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFDataDef_Picture)) + return L"AAFDataDef_Picture"; + if (aafUIDCmp (auid, &AAFDataDef_LegacyPicture)) + return L"AAFDataDef_LegacyPicture"; + if (aafUIDCmp (auid, &AAFDataDef_Matte)) + return L"AAFDataDef_Matte"; + if (aafUIDCmp (auid, &AAFDataDef_PictureWithMatte)) + return L"AAFDataDef_PictureWithMatte"; + if (aafUIDCmp (auid, &AAFDataDef_Sound)) + return L"AAFDataDef_Sound"; + if (aafUIDCmp (auid, &AAFDataDef_LegacySound)) + return L"AAFDataDef_LegacySound"; + if (aafUIDCmp (auid, &AAFDataDef_Timecode)) + return L"AAFDataDef_Timecode"; + if (aafUIDCmp (auid, &AAFDataDef_LegacyTimecode)) + return L"AAFDataDef_LegacyTimecode"; + if (aafUIDCmp (auid, &AAFDataDef_Edgecode)) + return L"AAFDataDef_Edgecode"; + if (aafUIDCmp (auid, &AAFDataDef_DescriptiveMetadata)) + return L"AAFDataDef_DescriptiveMetadata"; + if (aafUIDCmp (auid, &AAFDataDef_Auxiliary)) + return L"AAFDataDef_Auxiliary"; + if (aafUIDCmp (auid, &AAFDataDef_Unknown)) + return L"AAFDataDef_Unknown"; + + static wchar_t TEXTDataDef[1024]; + + aafObject* DataDefinitions = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_DataDefinitions, &AAFTypeID_DataDefinitionStrongReferenceSet); + aafObject* DataDefinition = NULL; + + aaf_foreach_ObjectInSet (&DataDefinition, DataDefinitions, NULL) + { + aafUID_t* DataDefIdent = aaf_get_propertyValue (DataDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (DataDefIdent && aafUIDCmp (DataDefIdent, auid)) { + wchar_t* name = aaf_get_propertyValue (DataDefinition, PID_DefinitionObject_Name, &AAFTypeID_String); + swprintf (TEXTDataDef, 1024, L"%" WPRIws, name); + free (name); + + return TEXTDataDef; + } + } + + return L"Unknown AAFDataDef"; +} + +const wchar_t* +aaft_OperationDefToText (AAF_Data* aafd, const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoDissolve)) + return L"AAFOperationDef_VideoDissolve"; + if (aafUIDCmp (auid, &AAFOperationDef_SMPTEVideoWipe)) + return L"AAFOperationDef_SMPTEVideoWipe"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoSpeedControl)) + return L"AAFOperationDef_VideoSpeedControl"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoRepeat)) + return L"AAFOperationDef_VideoRepeat"; + if (aafUIDCmp (auid, &AAFOperationDef_Flip)) + return L"AAFOperationDef_Flip"; + if (aafUIDCmp (auid, &AAFOperationDef_Flop)) + return L"AAFOperationDef_Flop"; + if (aafUIDCmp (auid, &AAFOperationDef_FlipFlop)) + return L"AAFOperationDef_FlipFlop"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoPosition)) + return L"AAFOperationDef_VideoPosition"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoCrop)) + return L"AAFOperationDef_VideoCrop"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoScale)) + return L"AAFOperationDef_VideoScale"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoRotate)) + return L"AAFOperationDef_VideoRotate"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoCornerPinning)) + return L"AAFOperationDef_VideoCornerPinning"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoAlphaWithinVideoKey)) + return L"AAFOperationDef_VideoAlphaWithinVideoKey"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoSeparateAlphaKey)) + return L"AAFOperationDef_VideoSeparateAlphaKey"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoLuminanceKey)) + return L"AAFOperationDef_VideoLuminanceKey"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoChromaKey)) + return L"AAFOperationDef_VideoChromaKey"; + if (aafUIDCmp (auid, &AAFOperationDef_MonoAudioGain)) + return L"AAFOperationDef_MonoAudioGain"; + if (aafUIDCmp (auid, &AAFOperationDef_MonoAudioPan)) + return L"AAFOperationDef_MonoAudioPan"; + if (aafUIDCmp (auid, &AAFOperationDef_MonoAudioDissolve)) + return L"AAFOperationDef_MonoAudioDissolve"; + if (aafUIDCmp (auid, &AAFOperationDef_TwoParameterMonoAudioDissolve)) + return L"AAFOperationDef_TwoParameterMonoAudioDissolve"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoOpacity)) + return L"AAFOperationDef_VideoOpacity"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoTitle)) + return L"AAFOperationDef_VideoTitle"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoColor)) + return L"AAFOperationDef_VideoColor"; + if (aafUIDCmp (auid, &AAFOperationDef_Unknown)) + return L"AAFOperationDef_Unknown"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoFadeToBlack)) + return L"AAFOperationDef_VideoFadeToBlack"; + if (aafUIDCmp (auid, &AAFOperationDef_PictureWithMate)) + return L"AAFOperationDef_PictureWithMate"; + if (aafUIDCmp (auid, &AAFOperationDef_VideoFrameToMask)) + return L"AAFOperationDef_VideoFrameToMask"; + if (aafUIDCmp (auid, &AAFOperationDef_StereoAudioDissolve)) + return L"AAFOperationDef_StereoAudioDissolve"; + if (aafUIDCmp (auid, &AAFOperationDef_StereoAudioGain)) + return L"AAFOperationDef_StereoAudioGain"; + if (aafUIDCmp (auid, &AAFOperationDef_MonoAudioMixdown)) + return L"AAFOperationDef_MonoAudioMixdown"; + if (aafUIDCmp (auid, &AAFOperationDef_AudioChannelCombiner)) + return L"AAFOperationDef_AudioChannelCombiner"; + + static wchar_t TEXTOperationDef[1024]; + + aafObject* OperationDefinitions = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_OperationDefinitions, &AAFTypeID_OperationDefinitionStrongReferenceSet); + aafObject* OperationDefinition = NULL; + + aaf_foreach_ObjectInSet (&OperationDefinition, OperationDefinitions, NULL) + { + aafUID_t* OpDefIdent = aaf_get_propertyValue (OperationDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (OpDefIdent && aafUIDCmp (OpDefIdent, auid)) { + wchar_t* name = aaf_get_propertyValue (OperationDefinition, PID_DefinitionObject_Name, &AAFTypeID_String); + swprintf (TEXTOperationDef, 1024, L"%" WPRIws, name); + free (name); + + return TEXTOperationDef; + } + } + + return L"Unknown AAFOperationDef"; +} + +const wchar_t* +aaft_InterpolationToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFInterpolationDef_None)) + return L"AAFInterpolationDef_None"; + if (aafUIDCmp (auid, &AAFInterpolationDef_Linear)) + return L"AAFInterpolationDef_Linear"; + if (aafUIDCmp (auid, &AAFInterpolationDef_Constant)) + return L"AAFInterpolationDef_Constant"; + if (aafUIDCmp (auid, &AAFInterpolationDef_BSpline)) + return L"AAFInterpolationDef_BSpline"; + if (aafUIDCmp (auid, &AAFInterpolationDef_Log)) + return L"AAFInterpolationDef_Log"; + if (aafUIDCmp (auid, &AAFInterpolationDef_Power)) + return L"AAFInterpolationDef_Power"; + + return L"Unknown AAFInterpolationDef"; +} + +const wchar_t* +aaft_ParameterToText (AAF_Data* aafd, const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFParameterDef_Level)) + return L"AAFParameterDef_Level"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEWipeNumber)) + return L"AAFParameterDef_SMPTEWipeNumber"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEReverse)) + return L"AAFParameterDef_SMPTEReverse"; + if (aafUIDCmp (auid, &AAFParameterDef_SpeedRatio)) + return L"AAFParameterDef_SpeedRatio"; + if (aafUIDCmp (auid, &AAFParameterDef_PositionOffsetX)) + return L"AAFParameterDef_PositionOffsetX"; + if (aafUIDCmp (auid, &AAFParameterDef_PositionOffsetY)) + return L"AAFParameterDef_PositionOffsetY"; + if (aafUIDCmp (auid, &AAFParameterDef_CropLeft)) + return L"AAFParameterDef_CropLeft"; + if (aafUIDCmp (auid, &AAFParameterDef_CropRight)) + return L"AAFParameterDef_CropRight"; + if (aafUIDCmp (auid, &AAFParameterDef_CropTop)) + return L"AAFParameterDef_CropTop"; + if (aafUIDCmp (auid, &AAFParameterDef_CropBottom)) + return L"AAFParameterDef_CropBottom"; + if (aafUIDCmp (auid, &AAFParameterDef_ScaleX)) + return L"AAFParameterDef_ScaleX"; + if (aafUIDCmp (auid, &AAFParameterDef_ScaleY)) + return L"AAFParameterDef_ScaleY"; + if (aafUIDCmp (auid, &AAFParameterDef_Rotation)) + return L"AAFParameterDef_Rotation"; + if (aafUIDCmp (auid, &AAFParameterDef_PinTopLeftX)) + return L"AAFParameterDef_PinTopLeftX"; + if (aafUIDCmp (auid, &AAFParameterDef_PinTopLeftY)) + return L"AAFParameterDef_PinTopLeftY"; + if (aafUIDCmp (auid, &AAFParameterDef_PinTopRightX)) + return L"AAFParameterDef_PinTopRightX"; + if (aafUIDCmp (auid, &AAFParameterDef_PinTopRightY)) + return L"AAFParameterDef_PinTopRightY"; + if (aafUIDCmp (auid, &AAFParameterDef_PinBottomLeftX)) + return L"AAFParameterDef_PinBottomLeftX"; + if (aafUIDCmp (auid, &AAFParameterDef_PinBottomLeftY)) + return L"AAFParameterDef_PinBottomLeftY"; + if (aafUIDCmp (auid, &AAFParameterDef_PinBottomRightX)) + return L"AAFParameterDef_PinBottomRightX"; + if (aafUIDCmp (auid, &AAFParameterDef_PinBottomRightY)) + return L"AAFParameterDef_PinBottomRightY"; + if (aafUIDCmp (auid, &AAFParameterDef_AlphaKeyInvertAlpha)) + return L"AAFParameterDef_AlphaKeyInvertAlpha"; + if (aafUIDCmp (auid, &AAFParameterDef_LumKeyLevel)) + return L"AAFParameterDef_LumKeyLevel"; + if (aafUIDCmp (auid, &AAFParameterDef_LumKeyClip)) + return L"AAFParameterDef_LumKeyClip"; + if (aafUIDCmp (auid, &AAFParameterDef_Amplitude)) + return L"AAFParameterDef_Amplitude"; + if (aafUIDCmp (auid, &AAFParameterDef_Pan)) + return L"AAFParameterDef_Pan"; + if (aafUIDCmp (auid, &AAFParameterDef_OutgoingLevel)) + return L"AAFParameterDef_OutgoingLevel"; + if (aafUIDCmp (auid, &AAFParameterDef_IncomingLevel)) + return L"AAFParameterDef_IncomingLevel"; + if (aafUIDCmp (auid, &AAFParameterDef_OpacityLevel)) + return L"AAFParameterDef_OpacityLevel"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleText)) + return L"AAFParameterDef_TitleText"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleFontName)) + return L"AAFParameterDef_TitleFontName"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleFontSize)) + return L"AAFParameterDef_TitleFontSize"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleFontColorR)) + return L"AAFParameterDef_TitleFontColorR"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleFontColorG)) + return L"AAFParameterDef_TitleFontColorG"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleFontColorB)) + return L"AAFParameterDef_TitleFontColorB"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleAlignment)) + return L"AAFParameterDef_TitleAlignment"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleBold)) + return L"AAFParameterDef_TitleBold"; + if (aafUIDCmp (auid, &AAFParameterDef_TitleItalic)) + return L"AAFParameterDef_TitleItalic"; + if (aafUIDCmp (auid, &AAFParameterDef_TitlePositionX)) + return L"AAFParameterDef_TitlePositionX"; + if (aafUIDCmp (auid, &AAFParameterDef_TitlePositionY)) + return L"AAFParameterDef_TitlePositionY"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorSlopeR)) + return L"AAFParameterDef_ColorSlopeR"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorSlopeG)) + return L"AAFParameterDef_ColorSlopeG"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorSlopeB)) + return L"AAFParameterDef_ColorSlopeB"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorOffsetR)) + return L"AAFParameterDef_ColorOffsetR"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorOffsetG)) + return L"AAFParameterDef_ColorOffsetG"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorOffsetB)) + return L"AAFParameterDef_ColorOffsetB"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorPowerR)) + return L"AAFParameterDef_ColorPowerR"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorPowerG)) + return L"AAFParameterDef_ColorPowerG"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorPowerB)) + return L"AAFParameterDef_ColorPowerB"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorSaturation)) + return L"AAFParameterDef_ColorSaturation"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorCorrectionDescription)) + return L"AAFParameterDef_ColorCorrectionDescription"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorInputDescription)) + return L"AAFParameterDef_ColorInputDescription"; + if (aafUIDCmp (auid, &AAFParameterDef_ColorViewingDescription)) + return L"AAFParameterDef_ColorViewingDescription"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTESoft)) + return L"AAFParameterDef_SMPTESoft"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEBorder)) + return L"AAFParameterDef_SMPTEBorder"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEPosition)) + return L"AAFParameterDef_SMPTEPosition"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEModulator)) + return L"AAFParameterDef_SMPTEModulator"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEShadow)) + return L"AAFParameterDef_SMPTEShadow"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTETumble)) + return L"AAFParameterDef_SMPTETumble"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTESpotlight)) + return L"AAFParameterDef_SMPTESpotlight"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEReplicationH)) + return L"AAFParameterDef_SMPTEReplicationH"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTEReplicationV)) + return L"AAFParameterDef_SMPTEReplicationV"; + if (aafUIDCmp (auid, &AAFParameterDef_SMPTECheckerboard)) + return L"AAFParameterDef_SMPTECheckerboard"; + if (aafUIDCmp (auid, &AAFParameterDef_PhaseOffset)) + return L"AAFParameterDef_PhaseOffset"; + + /* NOTE: Seen in Avid MC and PT files : PanVol_IsTrimGainEffect */ + + static wchar_t TEXTParameterDef[1024]; + + aafObject* ParameterDefinitions = aaf_get_propertyValue (aafd->Dictionary, PID_Dictionary_ParameterDefinitions, &AAFTypeID_ParameterDefinitionStrongReferenceSet); + aafObject* ParameterDefinition = NULL; + + aaf_foreach_ObjectInSet (&ParameterDefinition, ParameterDefinitions, NULL) + { + aafUID_t* ParamDefIdent = aaf_get_propertyValue (ParameterDefinition, PID_DefinitionObject_Identification, &AAFTypeID_AUID); + + if (ParamDefIdent && aafUIDCmp (ParamDefIdent, auid)) { + wchar_t* name = aaf_get_propertyValue (ParameterDefinition, PID_DefinitionObject_Name, &AAFTypeID_String); + swprintf (TEXTParameterDef, 1024, L"%" WPRIws, name); + free (name); + + return TEXTParameterDef; + } + } + + return L"Unknown AAFParameterDef"; +} + +const wchar_t* +aaft_TransferCharacteristicToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_ITU470_PAL)) + return L"AAFTransferCharacteristic_ITU470_PAL"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_ITU709)) + return L"AAFTransferCharacteristic_ITU709"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_SMPTE240M)) + return L"AAFTransferCharacteristic_SMPTE240M"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_274M_296M)) + return L"AAFTransferCharacteristic_274M_296M"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_ITU1361)) + return L"AAFTransferCharacteristic_ITU1361"; + if (aafUIDCmp (auid, &AAFTransferCharacteristic_linear)) + return L"AAFTransferCharacteristic_linear"; + + return L"Unknown AAFTransferCharacteristic"; +} + +const wchar_t* +aaft_CodingEquationsToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFCodingEquations_ITU601)) + return L"AAFCodingEquations_ITU601"; + if (aafUIDCmp (auid, &AAFCodingEquations_ITU709)) + return L"AAFCodingEquations_ITU709"; + if (aafUIDCmp (auid, &AAFCodingEquations_SMPTE240M)) + return L"AAFCodingEquations_SMPTE240M"; + + return L"Unknown AAFCodingEquations"; +} + +const wchar_t* +aaft_ColorPrimariesToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFColorPrimaries_SMPTE170M)) + return L"AAFColorPrimaries_SMPTE170M"; + if (aafUIDCmp (auid, &AAFColorPrimaries_ITU470_PAL)) + return L"AAFColorPrimaries_ITU470_PAL"; + if (aafUIDCmp (auid, &AAFColorPrimaries_ITU709)) + return L"AAFColorPrimaries_ITU709"; + + return L"Unknown AAFColorPrimaries"; +} + +const wchar_t* +aaft_UsageCodeToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AAFUID_NULL)) + return L"AAFUID_NULL"; + if (aafUIDCmp (auid, &AAFUsage_SubClip)) + return L"AAFUsage_SubClip"; + if (aafUIDCmp (auid, &AAFUsage_AdjustedClip)) + return L"AAFUsage_AdjustedClip"; + if (aafUIDCmp (auid, &AAFUsage_TopLevel)) + return L"AAFUsage_TopLevel"; + if (aafUIDCmp (auid, &AAFUsage_LowerLevel)) + return L"AAFUsage_LowerLevel"; + if (aafUIDCmp (auid, &AAFUsage_Template)) + return L"AAFUsage_Template"; + + return L"Unknown AAFUsage"; +} + +const wchar_t* +aaft_PIDToText (AAF_Data* aafd, aafPID_t pid) +{ + switch (pid) { + case PID_Root_MetaDictionary: + return L"PID_Root_MetaDictionary"; + case PID_Root_Header: + return L"PID_Root_Header"; + case PID_InterchangeObject_ObjClass: + return L"PID_InterchangeObject_ObjClass"; + case PID_InterchangeObject_Generation: + return L"PID_InterchangeObject_Generation"; + case PID_Component_DataDefinition: + return L"PID_Component_DataDefinition"; + case PID_Component_Length: + return L"PID_Component_Length"; + case PID_Component_KLVData: + return L"PID_Component_KLVData"; + case PID_Component_UserComments: + return L"PID_Component_UserComments"; + case PID_Component_Attributes: + return L"PID_Component_Attributes"; + case PID_EdgeCode_Start: + return L"PID_EdgeCode_Start"; + case PID_EdgeCode_FilmKind: + return L"PID_EdgeCode_FilmKind"; + case PID_EdgeCode_CodeFormat: + return L"PID_EdgeCode_CodeFormat"; + case PID_EdgeCode_Header: + return L"PID_EdgeCode_Header"; + case PID_EssenceGroup_Choices: + return L"PID_EssenceGroup_Choices"; + case PID_EssenceGroup_StillFrame: + return L"PID_EssenceGroup_StillFrame"; + case PID_Event_Position: + return L"PID_Event_Position"; + case PID_Event_Comment: + return L"PID_Event_Comment"; + case PID_GPITrigger_ActiveState: + return L"PID_GPITrigger_ActiveState"; + case PID_CommentMarker_Annotation: + return L"PID_CommentMarker_Annotation"; + case PID_OperationGroup_Operation: + return L"PID_OperationGroup_Operation"; + case PID_OperationGroup_InputSegments: + return L"PID_OperationGroup_InputSegments"; + case PID_OperationGroup_Parameters: + return L"PID_OperationGroup_Parameters"; + case PID_OperationGroup_BypassOverride: + return L"PID_OperationGroup_BypassOverride"; + case PID_OperationGroup_Rendering: + return L"PID_OperationGroup_Rendering"; + case PID_NestedScope_Slots: + return L"PID_NestedScope_Slots"; + case PID_Pulldown_InputSegment: + return L"PID_Pulldown_InputSegment"; + case PID_Pulldown_PulldownKind: + return L"PID_Pulldown_PulldownKind"; + case PID_Pulldown_PulldownDirection: + return L"PID_Pulldown_PulldownDirection"; + case PID_Pulldown_PhaseFrame: + return L"PID_Pulldown_PhaseFrame"; + case PID_ScopeReference_RelativeScope: + return L"PID_ScopeReference_RelativeScope"; + case PID_ScopeReference_RelativeSlot: + return L"PID_ScopeReference_RelativeSlot"; + case PID_Selector_Selected: + return L"PID_Selector_Selected"; + case PID_Selector_Alternates: + return L"PID_Selector_Alternates"; + case PID_Sequence_Components: + return L"PID_Sequence_Components"; + case PID_SourceReference_SourceID: + return L"PID_SourceReference_SourceID"; + case PID_SourceReference_SourceMobSlotID: + return L"PID_SourceReference_SourceMobSlotID"; + case PID_SourceReference_ChannelIDs: + return L"PID_SourceReference_ChannelIDs"; + case PID_SourceReference_MonoSourceSlotIDs: + return L"PID_SourceReference_MonoSourceSlotIDs"; + case PID_SourceClip_StartTime: + return L"PID_SourceClip_StartTime"; + case PID_SourceClip_FadeInLength: + return L"PID_SourceClip_FadeInLength"; + case PID_SourceClip_FadeInType: + return L"PID_SourceClip_FadeInType"; + case PID_SourceClip_FadeOutLength: + return L"PID_SourceClip_FadeOutLength"; + case PID_SourceClip_FadeOutType: + return L"PID_SourceClip_FadeOutType"; + case PID_HTMLClip_BeginAnchor: + return L"PID_HTMLClip_BeginAnchor"; + case PID_HTMLClip_EndAnchor: + return L"PID_HTMLClip_EndAnchor"; + case PID_Timecode_Start: + return L"PID_Timecode_Start"; + case PID_Timecode_FPS: + return L"PID_Timecode_FPS"; + case PID_Timecode_Drop: + return L"PID_Timecode_Drop"; + case PID_TimecodeStream_SampleRate: + return L"PID_TimecodeStream_SampleRate"; + case PID_TimecodeStream_Source: + return L"PID_TimecodeStream_Source"; + case PID_TimecodeStream_SourceType: + return L"PID_TimecodeStream_SourceType"; + case PID_TimecodeStream12M_IncludeSync: + return L"PID_TimecodeStream12M_IncludeSync"; + case PID_Transition_OperationGroup: + return L"PID_Transition_OperationGroup"; + case PID_Transition_CutPoint: + return L"PID_Transition_CutPoint"; + case PID_ContentStorage_Mobs: + return L"PID_ContentStorage_Mobs"; + case PID_ContentStorage_EssenceData: + return L"PID_ContentStorage_EssenceData"; + case PID_ControlPoint_Value: + return L"PID_ControlPoint_Value"; + case PID_ControlPoint_Time: + return L"PID_ControlPoint_Time"; + case PID_ControlPoint_EditHint: + return L"PID_ControlPoint_EditHint"; + case PID_DefinitionObject_Identification: + return L"PID_DefinitionObject_Identification"; + case PID_DefinitionObject_Name: + return L"PID_DefinitionObject_Name"; + case PID_DefinitionObject_Description: + return L"PID_DefinitionObject_Description"; + case PID_OperationDefinition_DataDefinition: + return L"PID_OperationDefinition_DataDefinition"; + case PID_OperationDefinition_IsTimeWarp: + return L"PID_OperationDefinition_IsTimeWarp"; + case PID_OperationDefinition_DegradeTo: + return L"PID_OperationDefinition_DegradeTo"; + case PID_OperationDefinition_OperationCategory: + return L"PID_OperationDefinition_OperationCategory"; + case PID_OperationDefinition_NumberInputs: + return L"PID_OperationDefinition_NumberInputs"; + case PID_OperationDefinition_Bypass: + return L"PID_OperationDefinition_Bypass"; + case PID_OperationDefinition_ParametersDefined: + return L"PID_OperationDefinition_ParametersDefined"; + case PID_ParameterDefinition_Type: + return L"PID_ParameterDefinition_Type"; + case PID_ParameterDefinition_DisplayUnits: + return L"PID_ParameterDefinition_DisplayUnits"; + case PID_PluginDefinition_PluginCategory: + return L"PID_PluginDefinition_PluginCategory"; + case PID_PluginDefinition_VersionNumber: + return L"PID_PluginDefinition_VersionNumber"; + case PID_PluginDefinition_VersionString: + return L"PID_PluginDefinition_VersionString"; + case PID_PluginDefinition_Manufacturer: + return L"PID_PluginDefinition_Manufacturer"; + case PID_PluginDefinition_ManufacturerInfo: + return L"PID_PluginDefinition_ManufacturerInfo"; + case PID_PluginDefinition_ManufacturerID: + return L"PID_PluginDefinition_ManufacturerID"; + case PID_PluginDefinition_Platform: + return L"PID_PluginDefinition_Platform"; + case PID_PluginDefinition_MinPlatformVersion: + return L"PID_PluginDefinition_MinPlatformVersion"; + case PID_PluginDefinition_MaxPlatformVersion: + return L"PID_PluginDefinition_MaxPlatformVersion"; + case PID_PluginDefinition_Engine: + return L"PID_PluginDefinition_Engine"; + case PID_PluginDefinition_MinEngineVersion: + return L"PID_PluginDefinition_MinEngineVersion"; + case PID_PluginDefinition_MaxEngineVersion: + return L"PID_PluginDefinition_MaxEngineVersion"; + case PID_PluginDefinition_PluginAPI: + return L"PID_PluginDefinition_PluginAPI"; + case PID_PluginDefinition_MinPluginAPI: + return L"PID_PluginDefinition_MinPluginAPI"; + case PID_PluginDefinition_MaxPluginAPI: + return L"PID_PluginDefinition_MaxPluginAPI"; + case PID_PluginDefinition_SoftwareOnly: + return L"PID_PluginDefinition_SoftwareOnly"; + case PID_PluginDefinition_Accelerator: + return L"PID_PluginDefinition_Accelerator"; + case PID_PluginDefinition_Locators: + return L"PID_PluginDefinition_Locators"; + case PID_PluginDefinition_Authentication: + return L"PID_PluginDefinition_Authentication"; + case PID_PluginDefinition_DefinitionObject: + return L"PID_PluginDefinition_DefinitionObject"; + case PID_CodecDefinition_FileDescriptorClass: + return L"PID_CodecDefinition_FileDescriptorClass"; + case PID_CodecDefinition_DataDefinitions: + return L"PID_CodecDefinition_DataDefinitions"; + case PID_ContainerDefinition_EssenceIsIdentified: + return L"PID_ContainerDefinition_EssenceIsIdentified"; + case PID_Dictionary_OperationDefinitions: + return L"PID_Dictionary_OperationDefinitions"; + case PID_Dictionary_ParameterDefinitions: + return L"PID_Dictionary_ParameterDefinitions"; + case PID_Dictionary_DataDefinitions: + return L"PID_Dictionary_DataDefinitions"; + case PID_Dictionary_PluginDefinitions: + return L"PID_Dictionary_PluginDefinitions"; + case PID_Dictionary_CodecDefinitions: + return L"PID_Dictionary_CodecDefinitions"; + case PID_Dictionary_ContainerDefinitions: + return L"PID_Dictionary_ContainerDefinitions"; + case PID_Dictionary_InterpolationDefinitions: + return L"PID_Dictionary_InterpolationDefinitions"; + case PID_Dictionary_KLVDataDefinitions: + return L"PID_Dictionary_KLVDataDefinitions"; + case PID_Dictionary_TaggedValueDefinitions: + return L"PID_Dictionary_TaggedValueDefinitions"; + case PID_EssenceData_MobID: + return L"PID_EssenceData_MobID"; + case PID_EssenceData_Data: + return L"PID_EssenceData_Data"; + case PID_EssenceData_SampleIndex: + return L"PID_EssenceData_SampleIndex"; + case PID_EssenceDescriptor_Locator: + return L"PID_EssenceDescriptor_Locator"; + case PID_FileDescriptor_SampleRate: + return L"PID_FileDescriptor_SampleRate"; + case PID_FileDescriptor_Length: + return L"PID_FileDescriptor_Length"; + case PID_FileDescriptor_ContainerFormat: + return L"PID_FileDescriptor_ContainerFormat"; + case PID_FileDescriptor_CodecDefinition: + return L"PID_FileDescriptor_CodecDefinition"; + case PID_FileDescriptor_LinkedSlotID: + return L"PID_FileDescriptor_LinkedSlotID"; + case PID_AIFCDescriptor_Summary: + return L"PID_AIFCDescriptor_Summary"; + case PID_DigitalImageDescriptor_Compression: + return L"PID_DigitalImageDescriptor_Compression"; + case PID_DigitalImageDescriptor_StoredHeight: + return L"PID_DigitalImageDescriptor_StoredHeight"; + case PID_DigitalImageDescriptor_StoredWidth: + return L"PID_DigitalImageDescriptor_StoredWidth"; + case PID_DigitalImageDescriptor_SampledHeight: + return L"PID_DigitalImageDescriptor_SampledHeight"; + case PID_DigitalImageDescriptor_SampledWidth: + return L"PID_DigitalImageDescriptor_SampledWidth"; + case PID_DigitalImageDescriptor_SampledXOffset: + return L"PID_DigitalImageDescriptor_SampledXOffset"; + case PID_DigitalImageDescriptor_SampledYOffset: + return L"PID_DigitalImageDescriptor_SampledYOffset"; + case PID_DigitalImageDescriptor_DisplayHeight: + return L"PID_DigitalImageDescriptor_DisplayHeight"; + case PID_DigitalImageDescriptor_DisplayWidth: + return L"PID_DigitalImageDescriptor_DisplayWidth"; + case PID_DigitalImageDescriptor_DisplayXOffset: + return L"PID_DigitalImageDescriptor_DisplayXOffset"; + case PID_DigitalImageDescriptor_DisplayYOffset: + return L"PID_DigitalImageDescriptor_DisplayYOffset"; + case PID_DigitalImageDescriptor_FrameLayout: + return L"PID_DigitalImageDescriptor_FrameLayout"; + case PID_DigitalImageDescriptor_VideoLineMap: + return L"PID_DigitalImageDescriptor_VideoLineMap"; + case PID_DigitalImageDescriptor_ImageAspectRatio: + return L"PID_DigitalImageDescriptor_ImageAspectRatio"; + case PID_DigitalImageDescriptor_AlphaTransparency: + return L"PID_DigitalImageDescriptor_AlphaTransparency"; + case PID_DigitalImageDescriptor_TransferCharacteristic: + return L"PID_DigitalImageDescriptor_TransferCharacteristic"; + case PID_DigitalImageDescriptor_ColorPrimaries: + return L"PID_DigitalImageDescriptor_ColorPrimaries"; + case PID_DigitalImageDescriptor_CodingEquations: + return L"PID_DigitalImageDescriptor_CodingEquations"; + case PID_DigitalImageDescriptor_ImageAlignmentFactor: + return L"PID_DigitalImageDescriptor_ImageAlignmentFactor"; + case PID_DigitalImageDescriptor_FieldDominance: + return L"PID_DigitalImageDescriptor_FieldDominance"; + case PID_DigitalImageDescriptor_FieldStartOffset: + return L"PID_DigitalImageDescriptor_FieldStartOffset"; + case PID_DigitalImageDescriptor_FieldEndOffset: + return L"PID_DigitalImageDescriptor_FieldEndOffset"; + case PID_DigitalImageDescriptor_SignalStandard: + return L"PID_DigitalImageDescriptor_SignalStandard"; + case PID_DigitalImageDescriptor_StoredF2Offset: + return L"PID_DigitalImageDescriptor_StoredF2Offset"; + case PID_DigitalImageDescriptor_DisplayF2Offset: + return L"PID_DigitalImageDescriptor_DisplayF2Offset"; + case PID_DigitalImageDescriptor_ActiveFormatDescriptor: + return L"PID_DigitalImageDescriptor_ActiveFormatDescriptor"; + case PID_CDCIDescriptor_ComponentWidth: + return L"PID_CDCIDescriptor_ComponentWidth"; + case PID_CDCIDescriptor_HorizontalSubsampling: + return L"PID_CDCIDescriptor_HorizontalSubsampling"; + case PID_CDCIDescriptor_ColorSiting: + return L"PID_CDCIDescriptor_ColorSiting"; + case PID_CDCIDescriptor_BlackReferenceLevel: + return L"PID_CDCIDescriptor_BlackReferenceLevel"; + case PID_CDCIDescriptor_WhiteReferenceLevel: + return L"PID_CDCIDescriptor_WhiteReferenceLevel"; + case PID_CDCIDescriptor_ColorRange: + return L"PID_CDCIDescriptor_ColorRange"; + case PID_CDCIDescriptor_PaddingBits: + return L"PID_CDCIDescriptor_PaddingBits"; + case PID_CDCIDescriptor_VerticalSubsampling: + return L"PID_CDCIDescriptor_VerticalSubsampling"; + case PID_CDCIDescriptor_AlphaSamplingWidth: + return L"PID_CDCIDescriptor_AlphaSamplingWidth"; + case PID_CDCIDescriptor_ReversedByteOrder: + return L"PID_CDCIDescriptor_ReversedByteOrder"; + case PID_RGBADescriptor_PixelLayout: + return L"PID_RGBADescriptor_PixelLayout"; + case PID_RGBADescriptor_Palette: + return L"PID_RGBADescriptor_Palette"; + case PID_RGBADescriptor_PaletteLayout: + return L"PID_RGBADescriptor_PaletteLayout"; + case PID_RGBADescriptor_ScanningDirection: + return L"PID_RGBADescriptor_ScanningDirection"; + case PID_RGBADescriptor_ComponentMaxRef: + return L"PID_RGBADescriptor_ComponentMaxRef"; + case PID_RGBADescriptor_ComponentMinRef: + return L"PID_RGBADescriptor_ComponentMinRef"; + case PID_RGBADescriptor_AlphaMaxRef: + return L"PID_RGBADescriptor_AlphaMaxRef"; + case PID_RGBADescriptor_AlphaMinRef: + return L"PID_RGBADescriptor_AlphaMinRef"; + case PID_TIFFDescriptor_IsUniform: + return L"PID_TIFFDescriptor_IsUniform"; + case PID_TIFFDescriptor_IsContiguous: + return L"PID_TIFFDescriptor_IsContiguous"; + case PID_TIFFDescriptor_LeadingLines: + return L"PID_TIFFDescriptor_LeadingLines"; + case PID_TIFFDescriptor_TrailingLines: + return L"PID_TIFFDescriptor_TrailingLines"; + case PID_TIFFDescriptor_JPEGTableID: + return L"PID_TIFFDescriptor_JPEGTableID"; + case PID_TIFFDescriptor_Summary: + return L"PID_TIFFDescriptor_Summary"; + case PID_WAVEDescriptor_Summary: + return L"PID_WAVEDescriptor_Summary"; + case PID_FilmDescriptor_FilmFormat: + return L"PID_FilmDescriptor_FilmFormat"; + case PID_FilmDescriptor_FrameRate: + return L"PID_FilmDescriptor_FrameRate"; + case PID_FilmDescriptor_PerforationsPerFrame: + return L"PID_FilmDescriptor_PerforationsPerFrame"; + case PID_FilmDescriptor_FilmAspectRatio: + return L"PID_FilmDescriptor_FilmAspectRatio"; + case PID_FilmDescriptor_Manufacturer: + return L"PID_FilmDescriptor_Manufacturer"; + case PID_FilmDescriptor_Model: + return L"PID_FilmDescriptor_Model"; + case PID_FilmDescriptor_FilmGaugeFormat: + return L"PID_FilmDescriptor_FilmGaugeFormat"; + case PID_FilmDescriptor_FilmBatchNumber: + return L"PID_FilmDescriptor_FilmBatchNumber"; + case PID_TapeDescriptor_FormFactor: + return L"PID_TapeDescriptor_FormFactor"; + case PID_TapeDescriptor_VideoSignal: + return L"PID_TapeDescriptor_VideoSignal"; + case PID_TapeDescriptor_TapeFormat: + return L"PID_TapeDescriptor_TapeFormat"; + case PID_TapeDescriptor_Length: + return L"PID_TapeDescriptor_Length"; + case PID_TapeDescriptor_ManufacturerID: + return L"PID_TapeDescriptor_ManufacturerID"; + case PID_TapeDescriptor_Model: + return L"PID_TapeDescriptor_Model"; + case PID_TapeDescriptor_TapeBatchNumber: + return L"PID_TapeDescriptor_TapeBatchNumber"; + case PID_TapeDescriptor_TapeStock: + return L"PID_TapeDescriptor_TapeStock"; + case PID_Header_ByteOrder: + return L"PID_Header_ByteOrder"; + case PID_Header_LastModified: + return L"PID_Header_LastModified"; + case PID_Header_Content: + return L"PID_Header_Content"; + case PID_Header_Dictionary: + return L"PID_Header_Dictionary"; + case PID_Header_Version: + return L"PID_Header_Version"; + case PID_Header_IdentificationList: + return L"PID_Header_IdentificationList"; + case PID_Header_ObjectModelVersion: + return L"PID_Header_ObjectModelVersion"; + case PID_Header_OperationalPattern: + return L"PID_Header_OperationalPattern"; + case PID_Header_EssenceContainers: + return L"PID_Header_EssenceContainers"; + case PID_Header_DescriptiveSchemes: + return L"PID_Header_DescriptiveSchemes"; + case PID_Identification_CompanyName: + return L"PID_Identification_CompanyName"; + case PID_Identification_ProductName: + return L"PID_Identification_ProductName"; + case PID_Identification_ProductVersion: + return L"PID_Identification_ProductVersion"; + case PID_Identification_ProductVersionString: + return L"PID_Identification_ProductVersionString"; + case PID_Identification_ProductID: + return L"PID_Identification_ProductID"; + case PID_Identification_Date: + return L"PID_Identification_Date"; + case PID_Identification_ToolkitVersion: + return L"PID_Identification_ToolkitVersion"; + case PID_Identification_Platform: + return L"PID_Identification_Platform"; + case PID_Identification_GenerationAUID: + return L"PID_Identification_GenerationAUID"; + case PID_NetworkLocator_URLString: + return L"PID_NetworkLocator_URLString"; + case PID_TextLocator_Name: + return L"PID_TextLocator_Name"; + case PID_Mob_MobID: + return L"PID_Mob_MobID"; + case PID_Mob_Name: + return L"PID_Mob_Name"; + case PID_Mob_Slots: + return L"PID_Mob_Slots"; + case PID_Mob_LastModified: + return L"PID_Mob_LastModified"; + case PID_Mob_CreationTime: + return L"PID_Mob_CreationTime"; + case PID_Mob_UserComments: + return L"PID_Mob_UserComments"; + case PID_Mob_KLVData: + return L"PID_Mob_KLVData"; + case PID_Mob_Attributes: + return L"PID_Mob_Attributes"; + case PID_Mob_UsageCode: + return L"PID_Mob_UsageCode"; + case PID_CompositionMob_DefaultFadeLength: + return L"PID_CompositionMob_DefaultFadeLength"; + case PID_CompositionMob_DefFadeType: + return L"PID_CompositionMob_DefFadeType"; + case PID_CompositionMob_DefFadeEditUnit: + return L"PID_CompositionMob_DefFadeEditUnit"; + case PID_CompositionMob_Rendering: + return L"PID_CompositionMob_Rendering"; + case PID_SourceMob_EssenceDescription: + return L"PID_SourceMob_EssenceDescription"; + case PID_MobSlot_SlotID: + return L"PID_MobSlot_SlotID"; + case PID_MobSlot_SlotName: + return L"PID_MobSlot_SlotName"; + case PID_MobSlot_Segment: + return L"PID_MobSlot_Segment"; + case PID_MobSlot_PhysicalTrackNumber: + return L"PID_MobSlot_PhysicalTrackNumber"; + case PID_EventMobSlot_EditRate: + return L"PID_EventMobSlot_EditRate"; + case PID_EventMobSlot_EventSlotOrigin: + return L"PID_EventMobSlot_EventSlotOrigin"; + case PID_TimelineMobSlot_EditRate: + return L"PID_TimelineMobSlot_EditRate"; + case PID_TimelineMobSlot_Origin: + return L"PID_TimelineMobSlot_Origin"; + case PID_TimelineMobSlot_MarkIn: + return L"PID_TimelineMobSlot_MarkIn"; + case PID_TimelineMobSlot_MarkOut: + return L"PID_TimelineMobSlot_MarkOut"; + case PID_TimelineMobSlot_UserPos: + return L"PID_TimelineMobSlot_UserPos"; + case PID_Parameter_Definition: + return L"PID_Parameter_Definition"; + case PID_ConstantValue_Value: + return L"PID_ConstantValue_Value"; + case PID_VaryingValue_Interpolation: + return L"PID_VaryingValue_Interpolation"; + case PID_VaryingValue_PointList: + return L"PID_VaryingValue_PointList"; + case PID_TaggedValue_Name: + return L"PID_TaggedValue_Name"; + case PID_TaggedValue_Value: + return L"PID_TaggedValue_Value"; + case PID_KLVData_Value: + return L"PID_KLVData_Value"; + case PID_DescriptiveMarker_DescribedSlots: + return L"PID_DescriptiveMarker_DescribedSlots"; + case PID_DescriptiveMarker_Description: + return L"PID_DescriptiveMarker_Description"; + case PID_SoundDescriptor_AudioSamplingRate: + return L"PID_SoundDescriptor_AudioSamplingRate"; + case PID_SoundDescriptor_Locked: + return L"PID_SoundDescriptor_Locked"; + case PID_SoundDescriptor_AudioRefLevel: + return L"PID_SoundDescriptor_AudioRefLevel"; + case PID_SoundDescriptor_ElectroSpatial: + return L"PID_SoundDescriptor_ElectroSpatial"; + case PID_SoundDescriptor_Channels: + return L"PID_SoundDescriptor_Channels"; + case PID_SoundDescriptor_QuantizationBits: + return L"PID_SoundDescriptor_QuantizationBits"; + case PID_SoundDescriptor_DialNorm: + return L"PID_SoundDescriptor_DialNorm"; + case PID_SoundDescriptor_Compression: + return L"PID_SoundDescriptor_Compression"; + case PID_DataEssenceDescriptor_DataEssenceCoding: + return L"PID_DataEssenceDescriptor_DataEssenceCoding"; + case PID_MultipleDescriptor_FileDescriptors: + return L"PID_MultipleDescriptor_FileDescriptors"; + case PID_DescriptiveClip_DescribedSlotIDs: + return L"PID_DescriptiveClip_DescribedSlotIDs"; + case PID_AES3PCMDescriptor_Emphasis: + return L"PID_AES3PCMDescriptor_Emphasis"; + case PID_AES3PCMDescriptor_BlockStartOffset: + return L"PID_AES3PCMDescriptor_BlockStartOffset"; + case PID_AES3PCMDescriptor_AuxBitsMode: + return L"PID_AES3PCMDescriptor_AuxBitsMode"; + case PID_AES3PCMDescriptor_ChannelStatusMode: + return L"PID_AES3PCMDescriptor_ChannelStatusMode"; + case PID_AES3PCMDescriptor_FixedChannelStatusData: + return L"PID_AES3PCMDescriptor_FixedChannelStatusData"; + case PID_AES3PCMDescriptor_UserDataMode: + return L"PID_AES3PCMDescriptor_UserDataMode"; + case PID_AES3PCMDescriptor_FixedUserData: + return L"PID_AES3PCMDescriptor_FixedUserData"; + case PID_PCMDescriptor_BlockAlign: + return L"PID_PCMDescriptor_BlockAlign"; + case PID_PCMDescriptor_SequenceOffset: + return L"PID_PCMDescriptor_SequenceOffset"; + case PID_PCMDescriptor_AverageBPS: + return L"PID_PCMDescriptor_AverageBPS"; + case PID_PCMDescriptor_ChannelAssignment: + return L"PID_PCMDescriptor_ChannelAssignment"; + case PID_PCMDescriptor_PeakEnvelopeVersion: + return L"PID_PCMDescriptor_PeakEnvelopeVersion"; + case PID_PCMDescriptor_PeakEnvelopeFormat: + return L"PID_PCMDescriptor_PeakEnvelopeFormat"; + case PID_PCMDescriptor_PointsPerPeakValue: + return L"PID_PCMDescriptor_PointsPerPeakValue"; + case PID_PCMDescriptor_PeakEnvelopeBlockSize: + return L"PID_PCMDescriptor_PeakEnvelopeBlockSize"; + case PID_PCMDescriptor_PeakChannels: + return L"PID_PCMDescriptor_PeakChannels"; + case PID_PCMDescriptor_PeakFrames: + return L"PID_PCMDescriptor_PeakFrames"; + case PID_PCMDescriptor_PeakOfPeaksPosition: + return L"PID_PCMDescriptor_PeakOfPeaksPosition"; + case PID_PCMDescriptor_PeakEnvelopeTimestamp: + return L"PID_PCMDescriptor_PeakEnvelopeTimestamp"; + case PID_PCMDescriptor_PeakEnvelopeData: + return L"PID_PCMDescriptor_PeakEnvelopeData"; + case PID_KLVDataDefinition_KLVDataType: + return L"PID_KLVDataDefinition_KLVDataType"; + case PID_AuxiliaryDescriptor_MimeType: + return L"PID_AuxiliaryDescriptor_MimeType"; + case PID_AuxiliaryDescriptor_CharSet: + return L"PID_AuxiliaryDescriptor_CharSet"; + case PID_RIFFChunk_ChunkID: + return L"PID_RIFFChunk_ChunkID"; + case PID_RIFFChunk_ChunkLength: + return L"PID_RIFFChunk_ChunkLength"; + case PID_RIFFChunk_ChunkData: + return L"PID_RIFFChunk_ChunkData"; + case PID_BWFImportDescriptor_QltyFileSecurityReport: + return L"PID_BWFImportDescriptor_QltyFileSecurityReport"; + case PID_BWFImportDescriptor_QltyFileSecurityWave: + return L"PID_BWFImportDescriptor_QltyFileSecurityWave"; + case PID_BWFImportDescriptor_BextCodingHistory: + return L"PID_BWFImportDescriptor_BextCodingHistory"; + case PID_BWFImportDescriptor_QltyBasicData: + return L"PID_BWFImportDescriptor_QltyBasicData"; + case PID_BWFImportDescriptor_QltyStartOfModulation: + return L"PID_BWFImportDescriptor_QltyStartOfModulation"; + case PID_BWFImportDescriptor_QltyQualityEvent: + return L"PID_BWFImportDescriptor_QltyQualityEvent"; + case PID_BWFImportDescriptor_QltyEndOfModulation: + return L"PID_BWFImportDescriptor_QltyEndOfModulation"; + case PID_BWFImportDescriptor_QltyQualityParameter: + return L"PID_BWFImportDescriptor_QltyQualityParameter"; + case PID_BWFImportDescriptor_QltyOperatorComment: + return L"PID_BWFImportDescriptor_QltyOperatorComment"; + case PID_BWFImportDescriptor_QltyCueSheet: + return L"PID_BWFImportDescriptor_QltyCueSheet"; + case PID_BWFImportDescriptor_UnknownBWFChunks: + return L"PID_BWFImportDescriptor_UnknownBWFChunks"; + + /* the following is marked as "dynamic" in ref implementation : + * AAF/ref-impl/include/ref-api/AAFTypes.h + * + * case PID_MPEGVideoDescriptor_SingleSequence: + * case PID_MPEGVideoDescriptor_ConstantBPictureCount: + * case PID_MPEGVideoDescriptor_CodedContentScanning: + * case PID_MPEGVideoDescriptor_LowDelay: + * case PID_MPEGVideoDescriptor_ClosedGOP: + * case PID_MPEGVideoDescriptor_IdenticalGOP: + * case PID_MPEGVideoDescriptor_MaxGOP: + * case PID_MPEGVideoDescriptor_MaxBPictureCount: + * case PID_MPEGVideoDescriptor_BitRate: + * case PID_MPEGVideoDescriptor_ProfileAndLevel: + */ + + case PID_ClassDefinition_ParentClass: + return L"PID_ClassDefinition_ParentClass"; + case PID_ClassDefinition_Properties: + return L"PID_ClassDefinition_Properties"; + case PID_ClassDefinition_IsConcrete: + return L"PID_ClassDefinition_IsConcrete"; + case PID_PropertyDefinition_Type: + return L"PID_PropertyDefinition_Type"; + case PID_PropertyDefinition_IsOptional: + return L"PID_PropertyDefinition_IsOptional"; + case PID_PropertyDefinition_LocalIdentification: + return L"PID_PropertyDefinition_LocalIdentification"; + case PID_PropertyDefinition_IsUniqueIdentifier: + return L"PID_PropertyDefinition_IsUniqueIdentifier"; + case PID_TypeDefinitionInteger_Size: + return L"PID_TypeDefinitionInteger_Size"; + case PID_TypeDefinitionInteger_IsSigned: + return L"PID_TypeDefinitionInteger_IsSigned"; + case PID_TypeDefinitionStrongObjectReference_ReferencedType: + return L"PID_TypeDefinitionStrongObjectReference_ReferencedType"; + case PID_TypeDefinitionWeakObjectReference_ReferencedType: + return L"PID_TypeDefinitionWeakObjectReference_ReferencedType"; + case PID_TypeDefinitionWeakObjectReference_TargetSet: + return L"PID_TypeDefinitionWeakObjectReference_TargetSet"; + case PID_TypeDefinitionEnumeration_ElementType: + return L"PID_TypeDefinitionEnumeration_ElementType"; + case PID_TypeDefinitionEnumeration_ElementNames: + return L"PID_TypeDefinitionEnumeration_ElementNames"; + case PID_TypeDefinitionEnumeration_ElementValues: + return L"PID_TypeDefinitionEnumeration_ElementValues"; + case PID_TypeDefinitionFixedArray_ElementType: + return L"PID_TypeDefinitionFixedArray_ElementType"; + case PID_TypeDefinitionFixedArray_ElementCount: + return L"PID_TypeDefinitionFixedArray_ElementCount"; + case PID_TypeDefinitionVariableArray_ElementType: + return L"PID_TypeDefinitionVariableArray_ElementType"; + case PID_TypeDefinitionSet_ElementType: + return L"PID_TypeDefinitionSet_ElementType"; + case PID_TypeDefinitionString_ElementType: + return L"PID_TypeDefinitionString_ElementType"; + case PID_TypeDefinitionRecord_MemberTypes: + return L"PID_TypeDefinitionRecord_MemberTypes"; + case PID_TypeDefinitionRecord_MemberNames: + return L"PID_TypeDefinitionRecord_MemberNames"; + case PID_TypeDefinitionRename_RenamedType: + return L"PID_TypeDefinitionRename_RenamedType"; + case PID_TypeDefinitionExtendibleEnumeration_ElementNames: + return L"PID_TypeDefinitionExtendibleEnumeration_ElementNames"; + case PID_TypeDefinitionExtendibleEnumeration_ElementValues: + return L"PID_TypeDefinitionExtendibleEnumeration_ElementValues"; + case PID_MetaDefinition_Identification: + return L"PID_MetaDefinition_Identification"; + case PID_MetaDefinition_Name: + return L"PID_MetaDefinition_Name"; + case PID_MetaDefinition_Description: + return L"PID_MetaDefinition_Description"; + case PID_MetaDictionary_ClassDefinitions: + return L"PID_MetaDictionary_ClassDefinitions"; + case PID_MetaDictionary_TypeDefinitions: + return L"PID_MetaDictionary_TypeDefinitions"; + } + + static wchar_t PIDText[1024]; + + aafClass* Class = NULL; + + foreachClass (Class, aafd->Classes) + { + aafPropertyDef* PDef = NULL; + + foreachPropertyDefinition (PDef, Class->Properties) + { + if (PDef->pid == pid) { + swprintf (PIDText, 1024, L"%" WPRIs L"%" WPRIws L"%" WPRIs, + (PDef->meta) ? ANSI_COLOR_YELLOW : "", + PDef->name, + (PDef->meta) ? ANSI_COLOR_RESET : ""); + return PIDText; + } + } + } + + return L"Unknown PID_MetaDictionary"; +} + +const wchar_t* +aaft_ClassIDToText (AAF_Data* aafd, const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AUID_NULL)) + return L"AUID_NULL"; + if (aafUIDCmp (auid, &AAFClassID_Root)) + return L"AAFClassID_Root"; + if (aafUIDCmp (auid, &AAFClassID_InterchangeObject)) + return L"AAFClassID_InterchangeObject"; + if (aafUIDCmp (auid, &AAFClassID_Component)) + return L"AAFClassID_Component"; + if (aafUIDCmp (auid, &AAFClassID_Segment)) + return L"AAFClassID_Segment"; + if (aafUIDCmp (auid, &AAFClassID_EdgeCode)) + return L"AAFClassID_EdgeCode"; + if (aafUIDCmp (auid, &AAFClassID_EssenceGroup)) + return L"AAFClassID_EssenceGroup"; + if (aafUIDCmp (auid, &AAFClassID_Event)) + return L"AAFClassID_Event"; + if (aafUIDCmp (auid, &AAFClassID_GPITrigger)) + return L"AAFClassID_GPITrigger"; + if (aafUIDCmp (auid, &AAFClassID_CommentMarker)) + return L"AAFClassID_CommentMarker"; + if (aafUIDCmp (auid, &AAFClassID_Filler)) + return L"AAFClassID_Filler"; + if (aafUIDCmp (auid, &AAFClassID_OperationGroup)) + return L"AAFClassID_OperationGroup"; + if (aafUIDCmp (auid, &AAFClassID_NestedScope)) + return L"AAFClassID_NestedScope"; + if (aafUIDCmp (auid, &AAFClassID_Pulldown)) + return L"AAFClassID_Pulldown"; + if (aafUIDCmp (auid, &AAFClassID_ScopeReference)) + return L"AAFClassID_ScopeReference"; + if (aafUIDCmp (auid, &AAFClassID_Selector)) + return L"AAFClassID_Selector"; + if (aafUIDCmp (auid, &AAFClassID_Sequence)) + return L"AAFClassID_Sequence"; + if (aafUIDCmp (auid, &AAFClassID_SourceReference)) + return L"AAFClassID_SourceReference"; + if (aafUIDCmp (auid, &AAFClassID_SourceClip)) + return L"AAFClassID_SourceClip"; + if (aafUIDCmp (auid, &AAFClassID_TextClip)) + return L"AAFClassID_TextClip"; + if (aafUIDCmp (auid, &AAFClassID_HTMLClip)) + return L"AAFClassID_HTMLClip"; + if (aafUIDCmp (auid, &AAFClassID_Timecode)) + return L"AAFClassID_Timecode"; + if (aafUIDCmp (auid, &AAFClassID_TimecodeStream)) + return L"AAFClassID_TimecodeStream"; + if (aafUIDCmp (auid, &AAFClassID_TimecodeStream12M)) + return L"AAFClassID_TimecodeStream12M"; + if (aafUIDCmp (auid, &AAFClassID_Transition)) + return L"AAFClassID_Transition"; + if (aafUIDCmp (auid, &AAFClassID_ContentStorage)) + return L"AAFClassID_ContentStorage"; + if (aafUIDCmp (auid, &AAFClassID_ControlPoint)) + return L"AAFClassID_ControlPoint"; + if (aafUIDCmp (auid, &AAFClassID_DefinitionObject)) + return L"AAFClassID_DefinitionObject"; + if (aafUIDCmp (auid, &AAFClassID_DataDefinition)) + return L"AAFClassID_DataDefinition"; + if (aafUIDCmp (auid, &AAFClassID_OperationDefinition)) + return L"AAFClassID_OperationDefinition"; + if (aafUIDCmp (auid, &AAFClassID_ParameterDefinition)) + return L"AAFClassID_ParameterDefinition"; + if (aafUIDCmp (auid, &AAFClassID_PluginDefinition)) + return L"AAFClassID_PluginDefinition"; + if (aafUIDCmp (auid, &AAFClassID_CodecDefinition)) + return L"AAFClassID_CodecDefinition"; + if (aafUIDCmp (auid, &AAFClassID_ContainerDefinition)) + return L"AAFClassID_ContainerDefinition"; + if (aafUIDCmp (auid, &AAFClassID_InterpolationDefinition)) + return L"AAFClassID_InterpolationDefinition"; + if (aafUIDCmp (auid, &AAFClassID_Dictionary)) + return L"AAFClassID_Dictionary"; + if (aafUIDCmp (auid, &AAFClassID_EssenceData)) + return L"AAFClassID_EssenceData"; + if (aafUIDCmp (auid, &AAFClassID_EssenceDescriptor)) + return L"AAFClassID_EssenceDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_FileDescriptor)) + return L"AAFClassID_FileDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_AIFCDescriptor)) + return L"AAFClassID_AIFCDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_DigitalImageDescriptor)) + return L"AAFClassID_DigitalImageDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_CDCIDescriptor)) + return L"AAFClassID_CDCIDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_RGBADescriptor)) + return L"AAFClassID_RGBADescriptor"; + if (aafUIDCmp (auid, &AAFClassID_HTMLDescriptor)) + return L"AAFClassID_HTMLDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_TIFFDescriptor)) + return L"AAFClassID_TIFFDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_WAVEDescriptor)) + return L"AAFClassID_WAVEDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_FilmDescriptor)) + return L"AAFClassID_FilmDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_TapeDescriptor)) + return L"AAFClassID_TapeDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_Header)) + return L"AAFClassID_Header"; + if (aafUIDCmp (auid, &AAFClassID_Identification)) + return L"AAFClassID_Identification"; + if (aafUIDCmp (auid, &AAFClassID_Locator)) + return L"AAFClassID_Locator"; + if (aafUIDCmp (auid, &AAFClassID_NetworkLocator)) + return L"AAFClassID_NetworkLocator"; + if (aafUIDCmp (auid, &AAFClassID_TextLocator)) + return L"AAFClassID_TextLocator"; + if (aafUIDCmp (auid, &AAFClassID_Mob)) + return L"AAFClassID_Mob"; + if (aafUIDCmp (auid, &AAFClassID_CompositionMob)) + return L"AAFClassID_CompositionMob"; + if (aafUIDCmp (auid, &AAFClassID_MasterMob)) + return L"AAFClassID_MasterMob"; + if (aafUIDCmp (auid, &AAFClassID_SourceMob)) + return L"AAFClassID_SourceMob"; + if (aafUIDCmp (auid, &AAFClassID_MobSlot)) + return L"AAFClassID_MobSlot"; + if (aafUIDCmp (auid, &AAFClassID_EventMobSlot)) + return L"AAFClassID_EventMobSlot"; + if (aafUIDCmp (auid, &AAFClassID_StaticMobSlot)) + return L"AAFClassID_StaticMobSlot"; + if (aafUIDCmp (auid, &AAFClassID_TimelineMobSlot)) + return L"AAFClassID_TimelineMobSlot"; + if (aafUIDCmp (auid, &AAFClassID_Parameter)) + return L"AAFClassID_Parameter"; + if (aafUIDCmp (auid, &AAFClassID_ConstantValue)) + return L"AAFClassID_ConstantValue"; + if (aafUIDCmp (auid, &AAFClassID_VaryingValue)) + return L"AAFClassID_VaryingValue"; + if (aafUIDCmp (auid, &AAFClassID_TaggedValue)) + return L"AAFClassID_TaggedValue"; + if (aafUIDCmp (auid, &AAFClassID_KLVData)) + return L"AAFClassID_KLVData"; + if (aafUIDCmp (auid, &AAFClassID_DescriptiveMarker)) + return L"AAFClassID_DescriptiveMarker"; + if (aafUIDCmp (auid, &AAFClassID_SoundDescriptor)) + return L"AAFClassID_SoundDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_DataEssenceDescriptor)) + return L"AAFClassID_DataEssenceDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_MultipleDescriptor)) + return L"AAFClassID_MultipleDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_DescriptiveClip)) + return L"AAFClassID_DescriptiveClip"; + if (aafUIDCmp (auid, &AAFClassID_AES3PCMDescriptor)) + return L"AAFClassID_AES3PCMDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_PCMDescriptor)) + return L"AAFClassID_PCMDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_PhysicalDescriptor)) + return L"AAFClassID_PhysicalDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_ImportDescriptor)) + return L"AAFClassID_ImportDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_RecordingDescriptor)) + return L"AAFClassID_RecordingDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_TaggedValueDefinition)) + return L"AAFClassID_TaggedValueDefinition"; + if (aafUIDCmp (auid, &AAFClassID_KLVDataDefinition)) + return L"AAFClassID_KLVDataDefinition"; + if (aafUIDCmp (auid, &AAFClassID_AuxiliaryDescriptor)) + return L"AAFClassID_AuxiliaryDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_RIFFChunk)) + return L"AAFClassID_RIFFChunk"; + if (aafUIDCmp (auid, &AAFClassID_BWFImportDescriptor)) + return L"AAFClassID_BWFImportDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_MPEGVideoDescriptor)) + return L"AAFClassID_MPEGVideoDescriptor"; + if (aafUIDCmp (auid, &AAFClassID_ClassDefinition)) + return L"AAFClassID_ClassDefinition"; + if (aafUIDCmp (auid, &AAFClassID_PropertyDefinition)) + return L"AAFClassID_PropertyDefinition"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinition)) + return L"AAFClassID_TypeDefinition"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionInteger)) + return L"AAFClassID_TypeDefinitionInteger"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionStrongObjectReference)) + return L"AAFClassID_TypeDefinitionStrongObjectReference"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionWeakObjectReference)) + return L"AAFClassID_TypeDefinitionWeakObjectReference"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionEnumeration)) + return L"AAFClassID_TypeDefinitionEnumeration"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionFixedArray)) + return L"AAFClassID_TypeDefinitionFixedArray"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionVariableArray)) + return L"AAFClassID_TypeDefinitionVariableArray"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionSet)) + return L"AAFClassID_TypeDefinitionSet"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionString)) + return L"AAFClassID_TypeDefinitionString"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionStream)) + return L"AAFClassID_TypeDefinitionStream"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionRecord)) + return L"AAFClassID_TypeDefinitionRecord"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionRename)) + return L"AAFClassID_TypeDefinitionRename"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionExtendibleEnumeration)) + return L"AAFClassID_TypeDefinitionExtendibleEnumeration"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionIndirect)) + return L"AAFClassID_TypeDefinitionIndirect"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionOpaque)) + return L"AAFClassID_TypeDefinitionOpaque"; + if (aafUIDCmp (auid, &AAFClassID_TypeDefinitionCharacter)) + return L"AAFClassID_TypeDefinitionCharacter"; + if (aafUIDCmp (auid, &AAFClassID_MetaDefinition)) + return L"AAFClassID_MetaDefinition"; + if (aafUIDCmp (auid, &AAFClassID_MetaDictionary)) + return L"AAFClassID_MetaDictionary"; + if (aafUIDCmp (auid, &AAFClassID_DescriptiveObject)) + return L"AAFClassID_DescriptiveObject"; + if (aafUIDCmp (auid, &AAFClassID_DescriptiveFramework)) + return L"AAFClassID_DescriptiveFramework"; + + static wchar_t ClassIDText[1024]; + + ClassIDText[0] = '\0'; + + aafClass* Class = NULL; + + foreachClass (Class, aafd->Classes) + { + if (aafUIDCmp (Class->ID, auid)) { + swprintf (ClassIDText, 1024, L"%" WPRIs L"%" WPRIws L"%" WPRIs, + (Class->meta) ? ANSI_COLOR_YELLOW : "", + Class->name, + (Class->meta) ? ANSI_COLOR_RESET : ""); + return ClassIDText; + } + } + + return L"Unknown AAFClassID"; +} + +const wchar_t* +aaft_ContainerToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AUID_NULL)) + return L"AUID_NULL"; + if (aafUIDCmp (auid, &AAFContainerDef_External)) + return L"AAFContainerDef_External"; + if (aafUIDCmp (auid, &AAFContainerDef_OMF)) + return L"AAFContainerDef_OMF"; + if (aafUIDCmp (auid, &AAFContainerDef_AAF)) + return L"AAFContainerDef_AAF"; + if (aafUIDCmp (auid, &AAFContainerDef_AAFMSS)) + return L"AAFContainerDef_AAFMSS"; + if (aafUIDCmp (auid, &AAFContainerDef_AAFKLV)) + return L"AAFContainerDef_AAFKLV"; + if (aafUIDCmp (auid, &AAFContainerDef_AAFXML)) + return L"AAFContainerDef_AAFXML"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_DefinedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_DefinedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_ExtendedTemplate)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_ExtendedTemplate"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_PictureOnly)) + return L"AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_PictureOnly"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps_SMPTE322M)) + return L"AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps_SMPTE322M"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps_SMPTE322M)) + return L"AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps_SMPTE322M"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps_SMPTE322M)) + return L"AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps_SMPTE322M"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps_SMPTE322M)) + return L"AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps_SMPTE322M"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_IECDV_UndefinedSource_25Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_IECDV_UndefinedSource_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_IECDV_UndefinedSource_25Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_IECDV_UndefinedSource_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_25Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_25Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_25Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_25Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_25Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_50Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_50Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_50Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_50Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_50Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_50Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_50Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_50Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x5994I_100Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x5994I_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x5994I_100Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x5994I_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x50I_100Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x50I_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x50I_100Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x50I_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_720x5994P_100Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_720x5994P_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x5994P_100Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x5994P_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_720x50P_100Mbps)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_720x50P_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x50P_100Mbps)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x50P_100Mbps"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_DVbased_UndefinedSource)) + return L"AAFContainerDef_MXFGC_Framewrapped_DVbased_UndefinedSource"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_DVbased_UndefinedSource)) + return L"AAFContainerDef_MXFGC_Clipwrapped_DVbased_UndefinedSource"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_MPEGES_VideoStream0_SID)) + return L"AAFContainerDef_MXFGC_Framewrapped_MPEGES_VideoStream0_SID"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_CustomClosedGOPwrapped_MPEGES_VideoStream1_SID)) + return L"AAFContainerDef_MXFGC_CustomClosedGOPwrapped_MPEGES_VideoStream1_SID"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994I_720_422)) + return L"AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994I_720_422)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994I_720_422)) + return L"AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50I_720_422)) + return L"AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50I_720_422)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50I_720_422)) + return L"AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50I_720_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994P_960_422)) + return L"AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994P_960_422)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994P_960_422)) + return L"AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50P_960_422)) + return L"AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50P_960_422)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50P_960_422)) + return L"AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50P_960_422"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Broadcast_Wave_audio_data)) + return L"AAFContainerDef_MXFGC_Framewrapped_Broadcast_Wave_audio_data"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Broadcast_Wave_audio_data)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Broadcast_Wave_audio_data"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_AES3_audio_data)) + return L"AAFContainerDef_MXFGC_Framewrapped_AES3_audio_data"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_AES3_audio_data)) + return L"AAFContainerDef_MXFGC_Clipwrapped_AES3_audio_data"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_Alaw_Audio)) + return L"AAFContainerDef_MXFGC_Framewrapped_Alaw_Audio"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_Alaw_Audio)) + return L"AAFContainerDef_MXFGC_Clipwrapped_Alaw_Audio"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Customwrapped_Alaw_Audio)) + return L"AAFContainerDef_MXFGC_Customwrapped_Alaw_Audio"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_AVCbytestream_VideoStream0_SID)) + return L"AAFContainerDef_MXFGC_Clipwrapped_AVCbytestream_VideoStream0_SID"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_VC3)) + return L"AAFContainerDef_MXFGC_Framewrapped_VC3"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_VC3)) + return L"AAFContainerDef_MXFGC_Clipwrapped_VC3"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Framewrapped_VC1)) + return L"AAFContainerDef_MXFGC_Framewrapped_VC1"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Clipwrapped_VC1)) + return L"AAFContainerDef_MXFGC_Clipwrapped_VC1"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Generic_Essence_Multiple_Mappings)) + return L"AAFContainerDef_MXFGC_Generic_Essence_Multiple_Mappings"; + if (aafUIDCmp (auid, &AAFContainerDef_RIFFWAVE)) + return L"AAFContainerDef_RIFFWAVE"; + if (aafUIDCmp (auid, &AAFContainerDef_JFIF)) + return L"AAFContainerDef_JFIF"; + if (aafUIDCmp (auid, &AAFContainerDef_AIFFAIFC)) + return L"AAFContainerDef_AIFFAIFC"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220X_1080p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220X_1080p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_145_1080p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_145_1080p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220_1080p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220_1080p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_36_1080p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_36_1080p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220X_1080i)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220X_1080i"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_145_1080i)) + return L"AAFContainerDef_MXFGC_Avid_DNX_145_1080i"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220_1080i)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220_1080i"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_145_1440_1080i)) + return L"AAFContainerDef_MXFGC_Avid_DNX_145_1440_1080i"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220X_720p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220X_720p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_220_720p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_220_720p"; + if (aafUIDCmp (auid, &AAFContainerDef_MXFGC_Avid_DNX_145_720p)) + return L"AAFContainerDef_MXFGC_Avid_DNX_145_720p"; + + return L"Unknown AAFContainerDef"; +} + +const wchar_t* +aaft_CompressionToText (const aafUID_t* auid) +{ + if (auid == NULL) + return L"n/a"; + + if (aafUIDCmp (auid, &AUID_NULL)) + return L"AUID_NULL"; + if (aafUIDCmp (auid, &AAFCompressionDef_AAF_CMPR_FULL_JPEG)) + return L"AAFCompressionDef_AAF_CMPR_FULL_JPEG"; + if (aafUIDCmp (auid, &AAFCompressionDef_AAF_CMPR_AUNC422)) + return L"AAFCompressionDef_AAF_CMPR_AUNC422"; + if (aafUIDCmp (auid, &AAFCompressionDef_LegacyDV)) + return L"AAFCompressionDef_LegacyDV"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_50Mbps_625x50I)) + return L"AAFCompressionDef_SMPTE_D10_50Mbps_625x50I"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_50Mbps_525x5994I)) + return L"AAFCompressionDef_SMPTE_D10_50Mbps_525x5994I"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_40Mbps_625x50I)) + return L"AAFCompressionDef_SMPTE_D10_40Mbps_625x50I"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_40Mbps_525x5994I)) + return L"AAFCompressionDef_SMPTE_D10_40Mbps_525x5994I"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_30Mbps_625x50I)) + return L"AAFCompressionDef_SMPTE_D10_30Mbps_625x50I"; + if (aafUIDCmp (auid, &AAFCompressionDef_SMPTE_D10_30Mbps_525x5994I)) + return L"AAFCompressionDef_SMPTE_D10_30Mbps_525x5994I"; + if (aafUIDCmp (auid, &AAFCompressionDef_IEC_DV_525_60)) + return L"AAFCompressionDef_IEC_DV_525_60"; + if (aafUIDCmp (auid, &AAFCompressionDef_IEC_DV_625_50)) + return L"AAFCompressionDef_IEC_DV_625_50"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_25Mbps_525_60)) + return L"AAFCompressionDef_DV_Based_25Mbps_525_60"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_25Mbps_625_50)) + return L"AAFCompressionDef_DV_Based_25Mbps_625_50"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_50Mbps_525_60)) + return L"AAFCompressionDef_DV_Based_50Mbps_525_60"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_50Mbps_625_50)) + return L"AAFCompressionDef_DV_Based_50Mbps_625_50"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_100Mbps_1080x5994I)) + return L"AAFCompressionDef_DV_Based_100Mbps_1080x5994I"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_100Mbps_1080x50I)) + return L"AAFCompressionDef_DV_Based_100Mbps_1080x50I"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_100Mbps_720x5994P)) + return L"AAFCompressionDef_DV_Based_100Mbps_720x5994P"; + if (aafUIDCmp (auid, &AAFCompressionDef_DV_Based_100Mbps_720x50P)) + return L"AAFCompressionDef_DV_Based_100Mbps_720x50P"; + if (aafUIDCmp (auid, &AAFCompressionDef_VC3_1)) + return L"AAFCompressionDef_VC3_1"; + if (aafUIDCmp (auid, &AAFCompressionDef_Avid_DNxHD_Legacy)) + return L"AAFCompressionDef_Avid_DNxHD_Legacy"; + + return L"Unknown AAFCompressionDef"; +} diff --git a/libs/aaf/CFBDump.c b/libs/aaf/CFBDump.c new file mode 100644 index 0000000000..b7cb01983a --- /dev/null +++ b/libs/aaf/CFBDump.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +#include "aaf/CFBDump.h" +#include "aaf/LibCFB.h" + +#include "aaf/utils.h" + +#define debug(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_ERROR, __VA_ARGS__) + +void +cfb_dump_node (CFB_Data* cfbd, cfbNode* node, int print_stream) +{ + if (node == NULL) + return; + + if (node->_mse == STGTY_INVALID) + return; + + wchar_t nodeName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (nodeName, node->_ab, node->_cb); + + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _ab : %ls\n", nodeName); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _cb : %u\n", node->_cb); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _mse : %s\n", + node->_mse == 0 ? "STGTY_INVALID" : node->_mse == 1 ? "STGTY_STORAGE" + : node->_mse == 2 ? "STGTY_STREAM" + : node->_mse == 3 ? "STGTY_LOCKBYTES" + : node->_mse == 4 ? "STGTY_PROPERTY" + : node->_mse == 5 ? "STGTY_ROOT" + : ""); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _bflags : %s\n", node->_bflags == 1 ? "BLACK" : "RED"); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _sidLeftSib : 0x%08x\n", node->_sidLeftSib); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _sidRightSib : 0x%08x\n", node->_sidRightSib); + + if (node->_mse == STGTY_STORAGE || + node->_mse == STGTY_ROOT) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _sidChild : 0x%08x\n", node->_sidChild); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _clsid : %ls\n", cfb_CLSIDToText (&(node->_clsId))); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _dwUserFlags : 0x%08x (%d)\n", node->_dwUserFlags, node->_dwUserFlags); + } + + if (node->_mse == STGTY_INVALID) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _time (cre) : 0x%08x%08x\n", + node->_time[0].dwHighDateTime, + node->_time[0].dwLowDateTime); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _ (mod) : 0x%08x%08x\n", + node->_time[1].dwHighDateTime, + node->_time[1].dwLowDateTime); + } + + if (node->_mse == STGTY_STREAM || + node->_mse == STGTY_ROOT) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _sectStart : 0x%08x (%d)\n", node->_sectStart, node->_sectStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _ulSizeLow : 0x%08x (%d)\n", node->_ulSizeLow, node->_ulSizeLow); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " _ulSizeHigh : 0x%08x (%d)\n", node->_ulSizeHigh, node->_ulSizeHigh); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + + if (print_stream == 1) { + cfb_dump_nodeStream (cfbd, node); + } +} + +void +cfb_dump_nodePath (CFB_Data* cfbd, const wchar_t* path, int print_stream) +{ + cfbNode* node = cfb_getNodeByPath (cfbd, path, 0); + + if (node == NULL) { + error ("cfb_dump_nodePath() : Could not find node at \"%ls\"\n", path); + return; + } + + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + cfb_dump_node (cfbd, node, print_stream); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); +} + +void +cfb_dump_nodeStream (CFB_Data* cfbd, cfbNode* node) +{ + unsigned char* stream = NULL; + uint64_t stream_sz = 0; + + cfb_getStream (cfbd, node, &stream, &stream_sz); + + if (stream == NULL) { + return; + } + + laaf_util_dump_hex (stream, stream_sz, &cfbd->dbg->_dbg_msg, &cfbd->dbg->_dbg_msg_size, 0); + + free (stream); +} + +void +cfb_dump_nodePathStream (CFB_Data* cfbd, const wchar_t* path) +{ + cfbNode* node = cfb_getNodeByPath (cfbd, path, 0); + + if (node == NULL) { + error ("cfb_dump_nodePathStream() : Could not find node at \"%ls\"\n", path); + return; + } + + unsigned char* stream = NULL; + uint64_t stream_sz = 0; + + cfb_getStream (cfbd, node, &stream, &stream_sz); + + laaf_util_dump_hex (stream, stream_sz, &cfbd->dbg->_dbg_msg, &cfbd->dbg->_dbg_msg_size, 0); + + free (stream); +} + +void +cfb_dump_nodePaths (CFB_Data* cfbd, uint32_t prevPath, char* strArray[], uint32_t* str_i, cfbNode* node) +{ + if (node == NULL) { + /* the begining of the first function call. */ + node = &cfbd->nodes[0]; + strArray = calloc (cfbd->nodes_cnt, sizeof (char*)); + } + + uint32_t thisPath = (*str_i); + wchar_t nodeName[CFB_NODE_NAME_SZ]; + + cfb_w16towchar (nodeName, node->_ab, node->_cb); + + int pathlen = snprintf (NULL, 0, "%s/%ls", strArray[prevPath], nodeName); + + if (pathlen < 0) { + // TODO error + return; + } + + pathlen++; + + strArray[thisPath] = malloc (pathlen); + + snprintf (strArray[thisPath], pathlen, "%s/%ls", strArray[prevPath], nodeName); + + (*str_i)++; + + if ((int32_t)node->_sidChild > 0) + cfb_dump_nodePaths (cfbd, thisPath, strArray, str_i, &cfbd->nodes[node->_sidChild]); + + if ((int32_t)node->_sidLeftSib > 0) + cfb_dump_nodePaths (cfbd, prevPath, strArray, str_i, &cfbd->nodes[node->_sidLeftSib]); + + if ((int32_t)node->_sidRightSib > 0) + cfb_dump_nodePaths (cfbd, prevPath, strArray, str_i, &cfbd->nodes[node->_sidRightSib]); + + /* the end of the first function call, recursion is over. */ + if (node == &cfbd->nodes[0]) { + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + /* commented out because output is proper this way... why did we call qsort() in the first place ?! */ + // qsort( strArray, *str_i, sizeof(char*), compareStrings ); + + for (uint32_t i = 0; i < cfbd->nodes_cnt && strArray[i] != NULL; i++) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "%05i : %s\n", i, strArray[i]); + free (strArray[i]); + } + + free (strArray); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); + } +} + +void +cfb_dump_header (CFB_Data* cfbd) +{ + cfbHeader* cfbh = cfbd->hdr; + + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_abSig : 0x%08" PRIx64 "\n", cfbh->_abSig); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_clsId : %ls\n", cfb_CLSIDToText (&(cfbh->_clsid))); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " version : %u.%u ( 0x%04x 0x%04x )\n", + cfbh->_uMinorVersion, cfbh->_uDllVersion, + cfbh->_uMinorVersion, cfbh->_uDllVersion); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_uByteOrder : %s ( 0x%04x )\n", + cfbh->_uByteOrder == 0xFFFE ? "little-endian" : cfbh->_uByteOrder == 0xFEFF ? "big-endian" + : "?", + cfbh->_uByteOrder); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_uSectorShift : %u (%u bytes sectors)\n", + cfbh->_uSectorShift, + 1 << cfbh->_uSectorShift); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_uMiniSectorShift : %u (%u bytes mini-sectors)\n", + cfbh->_uMiniSectorShift, + 1 << cfbh->_uMiniSectorShift); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_usReserved0 : 0x%02x\n", cfbh->_usReserved); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_ulReserved1 : 0x%04x\n", cfbh->_ulReserved1); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_csectDir : %u\n", cfbh->_csectDir); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_csectFat : %u\n", cfbh->_csectFat); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_sectDirStart : %u\n", cfbh->_sectDirStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_signature : %u\n", cfbh->_signature); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_ulMiniSectorCutoff : %u\n", cfbh->_ulMiniSectorCutoff); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_sectMiniFatStart : %u\n", cfbh->_sectMiniFatStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_csectMiniFat : %u\n", cfbh->_csectMiniFat); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_sectDifStart : %u\n", cfbh->_sectDifStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_csectDif : %u\n", cfbh->_csectDif); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); +} + +void +cfb_dump_FAT (CFB_Data* cfbd) +{ + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_CFB_FAT_______________________________________________________________________________________\n\n"); + + uint32_t i = 0; + + for (i = 0; i < cfbd->fat_sz; i++) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " SECT[%u] : 0x%08x %s\n", + i, + cfbd->fat[i], + (cfbd->fat[i] == CFB_MAX_REG_SECT) ? "(CFB_MAX_REG_SECT)" : (cfbd->fat[i] == CFB_DIFAT_SECT) ? "(CFB_DIFAT_SECT)" + : (cfbd->fat[i] == CFB_FAT_SECT) ? "(CFB_FAT_SECT)" + : (cfbd->fat[i] == CFB_END_OF_CHAIN) ? "(CFB_END_OF_CHAIN)" + : (cfbd->fat[i] == CFB_FREE_SECT) ? "(CFB_FREE_SECT)" + : ""); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " End of FAT.\n\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Total FAT entries : %u\n", cfbd->fat_sz); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Count of FAT sector : %u\n", cfbd->hdr->_csectFat); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); +} + +void +cfb_dump_MiniFAT (CFB_Data* cfbd) +{ + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_CFB_MiniFAT___________________________________________________________________________________\n\n"); + + uint32_t i = 0; + + for (i = 0; i < cfbd->miniFat_sz; i++) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " SECT[%u] : 0x%08x %s\n", + i, + cfbd->miniFat[i], + (cfbd->miniFat[i] == CFB_MAX_REG_SECT) ? "(CFB_MAX_REG_SECT)" : (cfbd->miniFat[i] == CFB_DIFAT_SECT) ? "(CFB_DIFAT_SECT)" + : (cfbd->miniFat[i] == CFB_FAT_SECT) ? "(CFB_FAT_SECT)" + : (cfbd->miniFat[i] == CFB_END_OF_CHAIN) ? "(CFB_END_OF_CHAIN)" + : (cfbd->miniFat[i] == CFB_FREE_SECT) ? "(CFB_FREE_SECT)" + : ""); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " End of MiniFAT.\n\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Total MiniFAT entries : %u\n", cfbd->miniFat_sz); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " First MiniFAT sector ID : %u\n", cfbd->hdr->_sectMiniFatStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Count of MiniFAT sector : %u\n", cfbd->hdr->_csectMiniFat); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); +} + +void +cfb_dump_DiFAT (CFB_Data* cfbd) +{ + int offset = 0; + struct dbg* dbg = cfbd->dbg; + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "_CFB_DiFAT_____________________________________________________________________________________\n\n"); + + uint32_t i = 0; + + for (i = 0; i < cfbd->DiFAT_sz; i++) { + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " SECT[%u] : 0x%08x %s\n", + i, + cfbd->DiFAT[i], + (cfbd->DiFAT[i] == CFB_MAX_REG_SECT) ? "(CFB_MAX_REG_SECT)" : (cfbd->DiFAT[i] == CFB_DIFAT_SECT) ? "(CFB_DIFAT_SECT)" + : (cfbd->DiFAT[i] == CFB_FAT_SECT) ? "(CFB_FAT_SECT)" + : (cfbd->DiFAT[i] == CFB_END_OF_CHAIN) ? "(CFB_END_OF_CHAIN)" + : (cfbd->DiFAT[i] == CFB_FREE_SECT) ? "(CFB_FREE_SECT)" + : ""); + } + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " End of DiFAT.\n\n"); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Total DiFAT entries : %u\n", cfbd->DiFAT_sz); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " First DiFAT sector ID : %u\n", cfbd->hdr->_sectDifStart); + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, " Count of DiFAT sector : Header + %u\n", cfbd->hdr->_csectDif); + + offset += laaf_util_snprintf_realloc (&dbg->_dbg_msg, &dbg->_dbg_msg_size, offset, "\n\n"); +} diff --git a/libs/aaf/LibCFB.c b/libs/aaf/LibCFB.c new file mode 100644 index 0000000000..bea80a4f1b --- /dev/null +++ b/libs/aaf/LibCFB.c @@ -0,0 +1,1346 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * @file LibCFB/LibCFB.c + * @brief Compound File Binary Library + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + * + * @ingroup LibCFB + * @addtogroup LibCFB + * @{ + * @brief LibCFB is a library that allows to parse any Compound File Binary File Format + * (a.k.a *Structured Storage File Format*). + * + * The specifications of the CFB can be found at https://www.amwa.tv/projects/MS-03.shtml + * + * @note When using LibAAF, you should not have to talk to LibCFB directly.\n + * All the following steps are handled by LibAAF. + * + * Interaction with LibCFB is done through the CFB_Data structure, which is allocated + * with cfb_alloc(). + * + * The first thing you will need to do in order to parse any CFB file is to allocate + * CFB_Data with cfb_alloc(). Then, you can "load" a file by calling cfb_load_file(). + * It will open the file for reading, check if it is a regular CFB file, then retrieve + * all the CFB components (Header, DiFAT, FAT, MiniFAT) needed to later parse the file's + * directories (nodes) and streams. + * + * **Example:** + * @code + * CFB_Data *cfbd = cfb_alloc(); + * cfb_load_file( cfbd, "/path/to/file" ); + * @endcode + * + * Once the file is loaded, you can access the nodes with the functions + * cfb_getNodeByPath() and cfb_getChildNode(), and access a node's stream with the + * functions cfb_getStream() or cfb_foreachSectorInStream(). The former is prefered + * for small-size streams, since it allocates the entire stream to memory, while the + * later loops through each sector that composes a stream, better for the big ones. + * + * **Example:** + * @code + * // Get the root "directory" (node, SID 0) "directly" + * cfbNode *root = cfbd->nodes[0]; + * + * + * // Get a "file" (stream node) called "properties" inside the "Header" directory + * cfbNode *properties = cfb_getNodeByPath( cfbd, "/Header/properties", 0 ); + * + * + * // Get the "properties" node stream + * unsigned char *stream = NULL; + * uint64_t stream_sz = 0; + * + * cfb_getStream( cfbd, properties, &stream, &stream_sz ); + * + * + * // Loop through each sector that composes the "properties" stream + * cfbSectorID_t sectorID = 0; + * + * cfb_foreachSectorInStream( cfbd, properties, &stream, &stream_sz, §orID ) + * { + * // do stuff.. + * } + * @endcode + * + * Finaly, once you are done working with the file, you can close the file and free + * the CFB_Data and its content by simply calling cfb_release(). + * + * **Example:** + * @code + * cfb_release( &cfbd ); + * @endcode + */ + +#include +#include +#include // ceil() +#include +#include +#include +#include + +#include "aaf/LibCFB.h" +#include "aaf/debug.h" + +#include "aaf/utils.h" + +#define debug(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (cfbd->dbg, cfbd, DEBUG_SRC_ID_LIB_CFB, VERB_ERROR, __VA_ARGS__) + +static int +cfb_getFileSize (CFB_Data* cfbd); + +static int +cfb_openFile (CFB_Data* cfbd); + +static uint64_t +cfb_readFile (CFB_Data* cfbd, unsigned char* buf, uint64_t offset, uint64_t len); + +static void +cfb_closeFile (CFB_Data* cfbd); + +static int +cfb_is_valid (CFB_Data* cfbd); + +static int +cfb_retrieveFileHeader (CFB_Data* cfbd); + +static int +cfb_retrieveDiFAT (CFB_Data* cfbd); + +static int +cfb_retrieveFAT (CFB_Data* cfbd); + +static int +cfb_retrieveMiniFAT (CFB_Data* cfbd); + +static int +cfb_retrieveNodes (CFB_Data* cfbd); + +static cfbSID_t +getNodeCount (CFB_Data* cfbd); + +static cfbSID_t +cfb_getIDByNode (CFB_Data* cfbd, cfbNode* node); + +const wchar_t* +cfb_CLSIDToText (const cfbCLSID_t* clsid) +{ + static wchar_t str[96]; + + if (clsid == NULL) { + str[0] = 'n'; + str[1] = '/'; + str[2] = 'a'; + str[3] = '\0'; + } else { + swprintf (str, sizeof (str), L"{ 0x%08x 0x%04x 0x%04x { 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x } }", + clsid->Data1, + clsid->Data2, + clsid->Data3, + clsid->Data4[0], + clsid->Data4[1], + clsid->Data4[2], + clsid->Data4[3], + clsid->Data4[4], + clsid->Data4[5], + clsid->Data4[6], + clsid->Data4[7]); + } + + return str; +} + +/** + * Allocates a new CFB_Data structure. + * + * @return Pointer to the newly allocated CFB_Data structure. + */ + +CFB_Data* +cfb_alloc (struct dbg* dbg) +{ + CFB_Data* cfbd = calloc (sizeof (CFB_Data), sizeof (unsigned char)); + + if (cfbd == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + cfbd->dbg = dbg; + + return cfbd; +} + +/** + * fclose() the file pointer then frees all the components of + * the CFB_Data structure, including the structure itself. + * + * @param cfbd Pointer to Pointer to the CFB_Data structure. + */ + +void +cfb_release (CFB_Data** cfbd) +{ + if (cfbd == NULL || *cfbd == NULL) + return; + + cfb_closeFile (*cfbd); + + if ((*cfbd)->DiFAT != NULL) { + free ((*cfbd)->DiFAT); + (*cfbd)->DiFAT = NULL; + } + + if ((*cfbd)->fat != NULL) { + free ((*cfbd)->fat); + (*cfbd)->fat = NULL; + } + + if ((*cfbd)->miniFat != NULL) { + free ((*cfbd)->miniFat); + (*cfbd)->miniFat = NULL; + } + + if ((*cfbd)->nodes != NULL) { + free ((*cfbd)->nodes); + (*cfbd)->nodes = NULL; + } + + if ((*cfbd)->hdr != NULL) { + free ((*cfbd)->hdr); + (*cfbd)->hdr = NULL; + } + + free (*cfbd); + *cfbd = NULL; +} + +/** + * Loads a Compound File Binary File, retrieves its Header, FAT, + * MiniFAT and Nodes. then sets the CFB_Data structure so it is + * ready for parsing the file. The user should call cfb_release() + * once he's done using the file. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param file Pointer to a NULL terminated string holding the file path. + * + * @return 0 on success\n + * 1 on error + */ + +int +cfb_load_file (CFB_Data** cfbd_p, const char* file) +{ + CFB_Data* cfbd = *cfbd_p; + snprintf (cfbd->file, sizeof (((CFB_Data){ 0 }).file), "%s", file); + + if (cfb_openFile (cfbd) < 0) { + cfb_release (cfbd_p); + return -1; + } + + if (cfb_getFileSize (cfbd) < 0) { + cfb_release (cfbd_p); + return -1; + } + + if (cfb_is_valid (cfbd) == 0) { + cfb_release (cfbd_p); + return -1; + } + + if (cfb_retrieveFileHeader (cfbd) < 0) { + error ("Could not retrieve CFB header."); + cfb_release (cfbd_p); + return -1; + } + + if (cfb_retrieveDiFAT (cfbd) < 0) { + error ("Could not retrieve CFB DiFAT."); + cfb_release (cfbd_p); + return -1; + } + + if (cfb_retrieveFAT (cfbd) < 0) { + error ("Could not retrieve CFB FAT."); + cfb_release (cfbd_p); + return -1; + } + + if (cfb_retrieveMiniFAT (cfbd) < 0) { + error ("Could not retrieve CFB MiniFAT."); + cfb_release (cfbd_p); + return -1; + } + + if (cfb_retrieveNodes (cfbd) < 0) { + error ("Could not retrieve CFB Nodes."); + cfb_release (cfbd_p); + return -1; + } + + return 0; +} + +int +cfb_new_file (CFB_Data* cfbd, const char* file, int sectSize) +{ + (void)file; + + if (sectSize != 512 && + sectSize != 4096) { + error ("Only standard sector sizes (512 and 4096 bytes) are supported."); + return -1; + } + + cfbHeader* hdr = malloc (sizeof (cfbHeader)); + + if (cfbd->hdr == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + hdr->_abSig = 0xe11ab1a1e011cfd0; + + /* + * _uMinorVersion is set to 33 reference implementation. + * _uMinorVersion is set to 0x3e in all AAF files + */ + hdr->_uMinorVersion = 0x3e; + + hdr->_uDllVersion = (sectSize == 512) ? 3 : 4; + hdr->_uByteOrder = 0xfffe; + hdr->_uSectorShift = (sectSize == 512) ? 9 : 12; + hdr->_uMiniSectorShift = 6; + hdr->_usReserved = 0; + hdr->_ulReserved1 = 0; + + hdr->_csectDir = 0; + hdr->_csectFat = 0; + hdr->_sectDirStart = 0; + hdr->_signature = 0; + + hdr->_ulMiniSectorCutoff = 4096; + + hdr->_sectMiniFatStart = 0; + hdr->_csectMiniFat = 0; + hdr->_sectDifStart = 0; + hdr->_csectDif = 0; + + int i = 0; + + for (i = 0; i < 109; i++) + hdr->_sectFat[i] = CFB_FREE_SECT; + + return 0; +} + +/** + * Ensures the file is a valid Compound File Binary File. + * + * @param cfbd Pointer to the CFB_Data structure. + * + * @return 1 if the file is valid,\n + * 0 otherwise. + */ + +static int +cfb_is_valid (CFB_Data* cfbd) +{ + uint64_t signature = 0; + + if (cfbd->file_sz < sizeof (struct StructuredStorageHeader)) { + error ("Not a valid Compound File : File size is lower than header size."); + return 0; + } + + if (cfb_readFile (cfbd, (unsigned char*)&signature, 0, sizeof (uint64_t)) != sizeof (uint64_t)) { + return 0; + } + + if (signature != 0xe11ab1a1e011cfd0) { + error ("Not a valid Compound File : Wrong signature."); + return 0; + } + + return 1; +} + +/** + * Retrieves the Compound File Binary File size. + * + * @param cfbd Pointer to the CFB_Data structure. + * @return 0. + */ + +static int +cfb_getFileSize (CFB_Data* cfbd) +{ + if (fseek (cfbd->fp, 0L, SEEK_END) < 0) { + error ("fseek() failed : %s.", strerror (errno)); + return -1; + } + + cfbd->file_sz = ftell (cfbd->fp); + + if ((long)cfbd->file_sz < 0) { + error ("ftell() failed : %s.", strerror (errno)); + return -1; + } + + if (cfbd->file_sz == 0) { + error ("File is empty (0 byte)."); + return -1; + } + + return 0; +} + +/** + * Opens a given Compound File Binary File for reading. + * + * @param cfbd Pointer to the CFB_Data structure. + * @return O. + */ + +static int +cfb_openFile (CFB_Data* cfbd) +{ + cfbd->fp = fopen (cfbd->file, "rb"); + + if (cfbd->fp == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + return 0; +} + +/** + * Reads a bytes block from the file. This function is + * called by cfb_getSector() and cfb_getMiniSector() + * that will do the sector index to file offset conversion. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param buf Pointer to the buffer that will hold the len bytes read. + * @param offset Position in the file the read should start. + * @param len Number of bytes to read from the offset position. + */ + +static uint64_t +cfb_readFile (CFB_Data* cfbd, unsigned char* buf, uint64_t offset, uint64_t len) +{ + FILE* fp = cfbd->fp; + + if (len + offset > cfbd->file_sz) { + error ("Requested data goes %" PRIu64 " bytes beyond the EOF : offset %" PRIu64 " | length %" PRIu64 "", (len + offset) - cfbd->file_sz, offset, len); + return 0; + } + + int rc = fseek (fp, offset, SEEK_SET); + + if (rc < 0) { + error ("%s.", strerror (errno)); + return 0; + } + + uint64_t byteRead = fread (buf, sizeof (unsigned char), len, fp); + + if (byteRead < len) { + warning ("Could only retrieve %" PRIu64 " bytes out of %" PRIu64 " requested.", byteRead, len); + } + + return byteRead; +} + +/** + * Closes the file pointer hold by the CFB_Data.fp. + * + * @param cfbd Pointer to the CFB_Data structure. + */ + +static void +cfb_closeFile (CFB_Data* cfbd) +{ + if (cfbd == NULL || cfbd->fp == NULL) + return; + + if (fclose (cfbd->fp) != 0) { + error ("%s.", strerror (errno)); + } + + cfbd->fp = NULL; +} + +/** + * Retrieves a sector content from the FAT. + * + * @param id Index of the sector to retrieve in the FAT. + * @param cfbd Pointer to the CFB_Data structure. + * @return Pointer to the sector's data bytes. + */ + +unsigned char* +cfb_getSector (CFB_Data* cfbd, cfbSectorID_t id) +{ + /* + * foreachSectorInChain() calls cfb_getSector() before + * testing the ID, so we have to ensure the ID is valid + * before we try to actualy get the sector. + */ + + if (id >= CFB_MAX_REG_SID) + return NULL; + + if (cfbd->fat_sz > 0 && id >= cfbd->fat_sz) { + error ("Asking for an out of range FAT sector @ index %u (max FAT index is %u)", id, cfbd->fat_sz); + return NULL; + } + + uint64_t sectorSize = (1 << cfbd->hdr->_uSectorShift); + uint64_t fileOffset = (id + 1) << cfbd->hdr->_uSectorShift; + + unsigned char* buf = calloc (sectorSize, sizeof (unsigned char)); + + if (buf == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + if (cfb_readFile (cfbd, buf, fileOffset, sectorSize) == 0) { + free (buf); + return NULL; + } + + return buf; +} + +/** + * Retrieves a mini-sector content from the MiniFAT. + * + * @param id Index of the mini-sector to retrieve in the MiniFAT. + * @param cfbd Pointer to the CFB_Data structure. + * @return Pointer to the mini-sector's data bytes. + */ + +unsigned char* +cfb_getMiniSector (CFB_Data* cfbd, cfbSectorID_t id) +{ + /* + * foreachMiniSectorInChain() calls cfb_getMiniSector() before + * testing the ID, so we have to ensure the ID is valid before + * we try to actualy get the sector. + */ + + if (id >= CFB_MAX_REG_SID) + return NULL; + + if (cfbd->fat_sz > 0 && id >= cfbd->miniFat_sz) { + error ("Asking for an out of range MiniFAT sector @ index %u (0x%x) (Maximum MiniFAT index is %u)", id, id, cfbd->miniFat_sz); + return NULL; + } + + int MiniSectorSize = 1 << cfbd->hdr->_uMiniSectorShift; + int SectorSize = 1 << cfbd->hdr->_uSectorShift; + + unsigned char* buf = calloc (MiniSectorSize, sizeof (unsigned char)); + + if (buf == NULL) { + error ("%s.", strerror (errno)); + return NULL; + } + + /* Retrieve the MiniSector file offset */ + cfbSectorID_t fatId = cfbd->nodes[0]._sectStart; + uint64_t offset = 0; + uint32_t i = 0; + + /* Fat Divisor: allow to guess the number of mini-stream sectors per standard sector */ + unsigned int fatDiv = SectorSize / MiniSectorSize; + + /* move forward in the FAT's mini-stream chain to retrieve the sector we want. */ + for (i = 0; i < id / fatDiv; i++) { + fatId = cfbd->fat[fatId]; + } + + offset = ((fatId + 1) << cfbd->hdr->_uSectorShift); + offset += ((id % fatDiv) << cfbd->hdr->_uMiniSectorShift); + + if (cfb_readFile (cfbd, buf, offset, MiniSectorSize) == 0) { + free (buf); + return NULL; + } + + return buf; +} + +/** + * Retrieves a stream from a stream Node. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param node Pointer to the node to retrieve the stream from. + * @param stream Pointer to the pointer where the stream data will be saved. + * @param stream_sz Pointer to an uint64_t where the stream size will be saved. + * @return The retrieved stream size. + */ + +uint64_t +cfb_getStream (CFB_Data* cfbd, cfbNode* node, unsigned char** stream, uint64_t* stream_sz) +{ + // if ( node == NULL || node->_mse == STGTY_ROOT ) + // return; + + // Should not happen.. or could it ? + // if ( node->_ulSizeLow < 1 ) + // return; + + uint64_t stream_len = cfb_getNodeStreamLen (cfbd, node); //node->_ulSizeLow; + + if (stream_len == 0) { + return 0; + } + + *stream = calloc (stream_len, sizeof (unsigned char)); + + if (*stream == NULL) { + error ("%s.", strerror (errno)); + return 0; + } + + unsigned char* buf = NULL; + cfbSectorID_t id = node->_sectStart; + uint64_t offset = 0; + uint64_t cpy_sz = 0; + + if (stream_len < cfbd->hdr->_ulMiniSectorCutoff) { /* mini-stream */ + + cfb_foreachMiniSectorInChain (cfbd, buf, id) + { + if (!buf) { + free (*stream); + *stream = NULL; + return 0; + } + + cpy_sz = ((stream_len - offset) < (uint64_t) (1 << cfbd->hdr->_uMiniSectorShift)) ? (stream_len - offset) : (uint64_t) (1 << cfbd->hdr->_uMiniSectorShift); + + memcpy (*stream + offset, buf, cpy_sz); + + free (buf); + + offset += (1 << cfbd->hdr->_uMiniSectorShift); + } + } else { + cfb_foreachSectorInChain (cfbd, buf, id) + { + cpy_sz = ((stream_len - offset) < (uint64_t) (1 << cfbd->hdr->_uSectorShift)) ? (stream_len - offset) : (uint64_t) (1 << cfbd->hdr->_uSectorShift); + + memcpy (*stream + offset, buf, cpy_sz); + + free (buf); + + offset += (1 << cfbd->hdr->_uSectorShift); + } + } + + if (stream_sz != NULL) + *stream_sz = stream_len; + + return stream_len; +} + +/** + * Loops through all the sectors that compose a stream + * and retrieve their content. + * + * This function should be called through the macro cfb_foreachSectorInStream(). + * + * @param cfbd Pointer to the CFB_Data structure. + * @param node Pointer to the Node that hold the stream. + * @param buf Pointer to pointer to the buffer that will receive the sector's + * content. + * @param bytesRead Pointer to a size_t that will receive the number of bytes retreived. + * This should be equal to the sectorSize, except for the last sector + * in which the stream might end before the end of the sector. + * @param sectID Pointer to the Node index. + * @return 1 if we have retrieved a sector with some data, \n + * 0 if we have reached the #CFB_END_OF_CHAIN. + */ + +int +cfb__foreachSectorInStream (CFB_Data* cfbd, cfbNode* node, unsigned char** buf, size_t* bytesRead, cfbSectorID_t* sectID) +{ + if (node == NULL) + return 0; + + if (*sectID >= CFB_MAX_REG_SID) + return 0; + + /* is this possible ? */ + // if ( node->_ulSizeLow < 1 ) + // return 0; + + /* free the previously allocated buf, if any */ + if (*buf != NULL) { + free (*buf); + *buf = NULL; + } + + /* if *nodeID == 0, then it is the first function call */ + *sectID = (*sectID == 0) ? node->_sectStart : *sectID; + + size_t stream_sz = cfb_getNodeStreamLen (cfbd, node); + + if (stream_sz < cfbd->hdr->_ulMiniSectorCutoff) { + /* Mini-Stream */ + *buf = cfb_getMiniSector (cfbd, *sectID); + *bytesRead = (1 << cfbd->hdr->_uMiniSectorShift); + *sectID = cfbd->miniFat[*sectID]; + } else { + /* Stream */ + *buf = cfb_getSector (cfbd, *sectID); + *bytesRead = (1 << cfbd->hdr->_uSectorShift); + *sectID = cfbd->fat[*sectID]; + } + + // trim data length to match the EXACT stream size + + // if ( *sectID >= CFB_MAX_REG_SECT ) + // *bytesRead = ( stream_sz % *bytesRead ); + // *bytesRead = ( stream_sz % *bytesRead ); + + return 1; +} + +/** + * Retrieves the Header of the Compound File Binary. + * The Header begins at offset 0 and is 512 bytes long, + * regardless of the file's sector size. + * + * @param cfbd Pointer to the CFB_Data structure. + * @return 0 on success\n + * 1 on failure + */ + +static int +cfb_retrieveFileHeader (CFB_Data* cfbd) +{ + cfbd->hdr = calloc (sizeof (cfbHeader), sizeof (unsigned char)); + + if (cfbd->hdr == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + if (cfb_readFile (cfbd, (unsigned char*)cfbd->hdr, 0, sizeof (cfbHeader)) == 0) { + free (cfbd->hdr); + cfbd->hdr = NULL; + return -1; + } + + return 0; +} + +static int +cfb_retrieveDiFAT (CFB_Data* cfbd) +{ + cfbSectorID_t* DiFAT = NULL; + + /* + * Check DiFAT properties in header. + * (Exemple AMWA aaf files.) + */ + + cfbSectorID_t csectDif = 0; + + if (cfbd->hdr->_csectFat > 109) { + csectDif = ceil ((float)((cfbd->hdr->_csectFat - 109) * 4) / (1 << cfbd->hdr->_uSectorShift)); + } + + if (csectDif != cfbd->hdr->_csectDif) { + warning ("cfbd->hdr->_csectDif value seems wrong (%u)", cfbd->hdr->_csectDif); + // warning( "cfbd->hdr->_csectDif value seems wrong (%u). Correcting from cfbd->hdr->_csectFat.", cfbd->hdr->_csectDif ); + // cfbd->hdr->_csectDif = csectDif; + } + + if (csectDif == 0 && cfbd->hdr->_sectDifStart != CFB_END_OF_CHAIN) { + warning ("cfbd->hdr->_sectDifStart is 0x%08x (%u) but should be CFB_END_OF_CHAIN. Correcting.", cfbd->hdr->_sectDifStart, cfbd->hdr->_sectDifStart); + cfbd->hdr->_sectDifStart = CFB_END_OF_CHAIN; + } + + /* + * DiFAT size is the number of FAT sector entries in the DiFAT chain. + */ + + uint32_t DiFAT_sz = (cfbd->hdr->_csectDif) * (((1 << cfbd->hdr->_uSectorShift) / sizeof (cfbSectorID_t)) - 1) + 109; + + DiFAT = calloc (DiFAT_sz, sizeof (cfbSectorID_t)); + + if (DiFAT == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + /* + * Retrieves the 109 first DiFAT entries, from the last bytes of + * the cfbHeader structure. + */ + + memcpy (DiFAT, cfbd->hdr->_sectFat, 109 * sizeof (cfbSectorID_t)); + + unsigned char* buf = NULL; + cfbSectorID_t id = 0; //cfbd->hdr->_sectDifStart; + uint64_t offset = 109 * sizeof (cfbSectorID_t); + + uint64_t cnt = 0; + + cfb_foreachSectorInDiFATChain (cfbd, buf, id) + { + if (buf == NULL) { + error ("Error retrieving sector %u (0x%08x) out of the DiFAT chain.", id, id); + return -1; + } + + memcpy ((unsigned char*)DiFAT + offset, buf, (1 << cfbd->hdr->_uSectorShift) - 4); + + offset += (1 << cfbd->hdr->_uSectorShift) - 4; + cnt++; + + /* + * If we count more DiFAT sector when parsing than + * there should be, it means the sector list does + * not end by a proper CFB_END_OF_CHAIN. + */ + + if (cnt >= cfbd->hdr->_csectDif) + break; + } + + free (buf); + + /* + * Standard says DIFAT should end with a CFB_END_OF_CHAIN index, + * however it has been observed that some files end with CFB_FREE_SECT. + * So we consider it ok. + */ + if (id != CFB_END_OF_CHAIN /*&& id != CFB_FREE_SECT*/) + warning ("Incorrect end of DiFAT Chain 0x%08x (%d)", id, id); + + cfbd->DiFAT = DiFAT; + cfbd->DiFAT_sz = DiFAT_sz; + + return 0; +} + +/** + * Retrieves the FAT (File Allocation Table). Requires + * the DiFAT to be retrieved first. + * + * @param cfbd Pointer to the CFB_Data structure. + * @return 0. + */ + +static int +cfb_retrieveFAT (CFB_Data* cfbd) +{ + cfbSectorID_t* FAT = NULL; + uint64_t FAT_sz = (((cfbd->hdr->_csectFat) * (1 << cfbd->hdr->_uSectorShift))) / sizeof (cfbSectorID_t); + + FAT = calloc (FAT_sz, sizeof (cfbSectorID_t)); + + if (FAT == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + cfbd->fat = FAT; + cfbd->fat_sz = FAT_sz; + + unsigned char* buf = NULL; + cfbSectorID_t id = 0; + uint64_t offset = 0; + + cfb_foreachFATSectorIDInDiFAT (cfbd, id) + { + if (cfbd->DiFAT[id] == CFB_FREE_SECT) + continue; + + /* observed in fairlight's AAFs.. */ + if (cfbd->DiFAT[id] == 0x00000000 && id > 0) { + warning ("Got a NULL FAT index in the DiFAT @ %u, should be CFB_FREE_SECT.", id); + continue; + } + + buf = cfb_getSector (cfbd, cfbd->DiFAT[id]); + + if (buf == NULL) { + error ("Error retrieving FAT sector %u (0x%08x).", id, id); + return -1; + } + + memcpy (((unsigned char*)FAT) + offset, buf, (1 << cfbd->hdr->_uSectorShift)); + + free (buf); + + offset += (1 << cfbd->hdr->_uSectorShift); + } + + return 0; +} + +/** + * Retrieves the MiniFAT (Mini File Allocation Table). + * + * @param cfbd Pointer to the CFB_Data structure. + * @return 0. + */ + +static int +cfb_retrieveMiniFAT (CFB_Data* cfbd) +{ + uint64_t miniFat_sz = cfbd->hdr->_csectMiniFat * (1 << cfbd->hdr->_uSectorShift) / sizeof (cfbSectorID_t); + + cfbSectorID_t* miniFat = calloc (miniFat_sz, sizeof (cfbSectorID_t)); + + if (miniFat == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + unsigned char* buf = NULL; + cfbSectorID_t id = cfbd->hdr->_sectMiniFatStart; + uint64_t offset = 0; + + cfb_foreachSectorInChain (cfbd, buf, id) + { + if (buf == NULL) { + error ("Error retrieving MiniFAT sector %u (0x%08x).", id, id); + return -1; + } + + memcpy ((unsigned char*)miniFat + offset, buf, (1 << cfbd->hdr->_uSectorShift)); + + free (buf); + + offset += (1 << cfbd->hdr->_uSectorShift); + } + + cfbd->miniFat = miniFat; + cfbd->miniFat_sz = miniFat_sz; + + return 0; +} + +/** + * Retrieves the nodes (directories and files) of the + * Compound File Tree, as an array of cfbNodes. + * + * Each node correspond to a cfbNode struct of 128 bytes + * length. The nodes are stored in a dedicated FAT chain, + * starting at the FAT sector[cfbHeader._sectDirStart]. + * + * Once retrieved, the nodes are accessible through the + * CFB_Data.nodes pointer. Each Node is then accessible by + * its ID (a.k.a SID) : + * + * ``` + cfbNode *node = CFB_Data.nodes[ID]; + * ``` + * + * @param cfbd Pointer to the CFB_Data structure. + * @return 0. + */ + +static int +cfb_retrieveNodes (CFB_Data* cfbd) +{ + cfbd->nodes_cnt = getNodeCount (cfbd); + + cfbNode* node = calloc (cfbd->nodes_cnt, sizeof (cfbNode)); + + if (node == NULL) { + error ("%s.", strerror (errno)); + return -1; + } + + unsigned char* buf = NULL; + cfbSectorID_t id = cfbd->hdr->_sectDirStart; + cfbSID_t i = 0; + + if (cfbd->hdr->_uSectorShift == 9) { /* 512 bytes sectors */ + + cfb_foreachSectorInChain (cfbd, buf, id) + { + if (buf == NULL) { + error ("Error retrieving Directory sector %u (0x%08x).", id, id); + return -1; + } + + memcpy (&node[i++], buf, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 128, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 256, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 384, CFB_NODE_SIZE); + + free (buf); + } + } else if (cfbd->hdr->_uSectorShift == 12) { /* 4096 bytes sectors */ + + cfb_foreachSectorInChain (cfbd, buf, id) + { + if (buf == NULL) { + error ("Error retrieving Directory sector %u (0x%08x).", id, id); + return -1; + } + + memcpy (&node[i++], buf, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 128, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 256, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 384, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 512, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 640, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 768, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 896, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1024, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1152, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1280, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1408, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1536, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1664, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1792, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 1920, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2048, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2176, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2304, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2432, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2560, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2688, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2816, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 2944, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3072, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3200, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3328, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3456, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3584, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3712, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3840, CFB_NODE_SIZE); + memcpy (&node[i++], buf + 3968, CFB_NODE_SIZE); + + free (buf); + } + } else { + /* handle non-standard sector size, that is different than 512B or 4kB */ + /* TODO has not been tested yet, should not even exist anyway */ + + warning ("Parsing non-standard sector size !!! (%u bytes)", (1 << cfbd->hdr->_uSectorShift)) + uint32_t nodesPerSect = (1 << cfbd->hdr->_uMiniSectorShift) / sizeof (cfbNode); + + cfb_foreachSectorInChain (cfbd, buf, id) + { + if (buf == NULL) { + error ("Error retrieving Directory sector %u (0x%08x).", id, id); + return -1; + } + + for (i = 0; i < nodesPerSect; i++) { + memcpy (&node[i], buf + (i * CFB_NODE_SIZE), CFB_NODE_SIZE); + } + + free (buf); + } + } + + cfbd->nodes = node; + + return 0; +} + +/** + * Converts 16-bits MS/CFB wchar_t to system wchar_t. + * + * @param buf Pointer to wchar_t output buffer. If NULL, then function will allocate a new buffer. + * @param w16buf Pointer to a 16-bits MS/CFB "wchar_t" array. + * @param w16blen Size of the w16buf array in bytes, including the NULL. If it is set to + * CFB_W16TOWCHAR_STRLEN, then function will parse w16buf up to NULL to retrieve w16buf byte size + * + * @return Pointer to buf,\n + * NULL on failure. + */ + +wchar_t* +cfb_w16towchar (wchar_t* buf, uint16_t* w16buf, size_t w16blen) +{ + if (w16buf == NULL) + return NULL; + + if (w16blen == CFB_W16TOWCHAR_STRLEN) { + w16blen = 0; + while (w16buf[w16blen >> 1] != 0x0000) { + w16blen += sizeof (uint16_t); + } + w16blen += sizeof (uint16_t); /* NULL termination */ + } + + if (buf == NULL) { + buf = malloc (w16blen * sizeof (wchar_t)); + if (buf == NULL) + return NULL; + } + + for (size_t i = 0; i < w16blen >> 1; i++) { + buf[i] = ((uint16_t*)w16buf)[i]; + } + + return buf; +} + +/** + * Retrieves a Node in the Compound File Tree by path. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param path Pointer to a NULL terminated char array, holding the Node path. + * @param id Next node index. This is used internaly by the function and should + * be set to 0 when called by the user. + * + * @return Pointer to the retrieved Node,\n + * NULL on failure. + */ + +cfbNode* +cfb_getNodeByPath (CFB_Data* cfbd, const wchar_t* path, cfbSID_t id) +{ + /* + * begining of the first function call. + */ + + if (id == 0) { + if (path[0] == '/' && path[1] == 0x0000) { + return &cfbd->nodes[0]; + } + + /* + * work either with or without "/Root Entry" + */ + + if (wcsncmp (path, L"/Root Entry", 11) != 0) { + id = cfbd->nodes[0]._sidChild; + } + } + + uint32_t l = 0; + + /* + * retrieves the first node's name from path + */ + + for (l = 0; l < wcslen (path); l++) + if (l > 0 && path[l] == '/') + break; + + /* + * removes any leading '/' + */ + + if (path[0] == '/') { + path++; + l--; + } + + wchar_t ab[CFB_NODE_NAME_SZ]; + + while (1) { + if (id >= cfbd->nodes_cnt) { + error ("Out of range Node index %d, max %u.", id, cfbd->nodes_cnt); + return NULL; + } + + // laaf_util_dump_hex( cfbd->nodes[id]->_ab, cfbd->nodes[id]->_cb ); + + cfb_w16towchar (ab, cfbd->nodes[id]._ab, cfbd->nodes[id]._cb); + + int32_t rc = 0; + + if (wcslen (ab) == l) + rc = wcsncmp (path, ab, l); + else + rc = l - wcslen (ab); + + /* + * Some node in the path was found. + */ + + if (rc == 0) { + /* + * get full path length minus any terminating '/' + */ + + uint32_t pathLen = wcslen (path); + + if (path[pathLen - 1] == '/') + pathLen--; + + /* + * If pathLen equals node name length, then + * we got the target node. Else, move forward + * to next node in the path. + */ + + if (pathLen == l) + return &cfbd->nodes[id]; + else + return cfb_getNodeByPath (cfbd, path + l, cfbd->nodes[id]._sidChild); + } else if (rc > 0) + id = cfbd->nodes[id]._sidRightSib; + else if (rc < 0) + id = cfbd->nodes[id]._sidLeftSib; + + if ((int32_t)id < 0) + return NULL; + } +} + +/** + * Retrieves a child node of a parent startNode. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param name Pointer to a NULL terminated string, holding the name of the + * searched node. + * @param startNode Pointer to the parent Node of the searched node. + * + * @return Pointer to the retrieved node,\n + * NULL if not found. + */ + +cfbNode* +cfb_getChildNode (CFB_Data* cfbd, const wchar_t* name, cfbNode* startNode) +{ + int32_t rc = 0; + + /** @TODO : cfb_getIDByNode should be quiker (macro ?) */ + cfbSID_t id = cfb_getIDByNode (cfbd, &cfbd->nodes[startNode->_sidChild]); + + uint32_t nameUTF16Len = ((wcslen (name) + 1) << 1); + + wchar_t nodename[CFB_NODE_NAME_SZ]; + + while (1) { + if (id >= cfbd->nodes_cnt) { + error ("Out of range Node index %u, max %u.", id, cfbd->nodes_cnt); + return NULL; + } + + cfb_w16towchar (nodename, cfbd->nodes[id]._ab, cfbd->nodes[id]._cb); + + if (cfbd->nodes[id]._cb == nameUTF16Len) + rc = wcscmp (name, nodename); + else + rc = nameUTF16Len - cfbd->nodes[id]._cb; + + /* + * Node found + */ + + if (rc == 0) + break; + + /* + * Not found, go right + */ + + else if (rc > 0) + id = cfbd->nodes[id]._sidRightSib; + + /* + * Not found, go left + */ + + else if (rc < 0) + id = cfbd->nodes[id]._sidLeftSib; + + /* + * Not found + */ + + if (id >= CFB_MAX_REG_SID) + break; + } + + if (rc == 0) { + return &cfbd->nodes[id]; + } + + return NULL; +} + +static cfbSID_t +cfb_getIDByNode (CFB_Data* cfbd, cfbNode* node) +{ + cfbSID_t id = 0; + + for (; id < cfbd->nodes_cnt; id++) { + if (node == &cfbd->nodes[id]) { + return id; + } + } + + return -1; +} + +/** + * Loops through each FAT sector in the Directory chain + * to retrieve the total number of Directories (Nodes) + * + * @param cfbd Pointer to the CFB_Data structure. + * @return The retrieved Nodes count. + */ + +static cfbSID_t +getNodeCount (CFB_Data* cfbd) +{ + uint64_t cnt = (1 << cfbd->hdr->_uSectorShift); + cfbSectorID_t id = cfbd->hdr->_sectDirStart; + + while (id < CFB_MAX_REG_SID) { + if (id >= cfbd->fat_sz) { + error ("index (%u) > FAT size (%u).", id, cfbd->fat_sz); + break; + } + + id = cfbd->fat[id]; + + cnt += (1 << cfbd->hdr->_uSectorShift); + } + + return cnt / sizeof (cfbNode); +} + +/** + * @} + */ diff --git a/libs/aaf/ProTools.c b/libs/aaf/ProTools.c new file mode 100644 index 0000000000..6eb5b4b396 --- /dev/null +++ b/libs/aaf/ProTools.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "aaf/AAFIface.h" +#include "aaf/ProTools.h" + +#define PROTOOLS_CLIP_NAME_FADE_EN_LEN 5 // +1 +#define PROTOOLS_CLIP_NAME_FADE_DE_LEN 5 // +1 +#define PROTOOLS_CLIP_NAME_FADE_JA_LEN 5 // +1 +#define PROTOOLS_CLIP_NAME_FADE_FR_LEN 6 // +1 +#define PROTOOLS_CLIP_NAME_FADE_ES_LEN 8 // +1 +#define PROTOOLS_CLIP_NAME_FADE_ZH_CN_LEN 3 // +1 +#define PROTOOLS_CLIP_NAME_FADE_ZH_TW_LEN 3 // +1 +#define PROTOOLS_CLIP_NAME_FADE_KO_LEN 3 // +1 + +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN_LEN 20 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE_LEN 24 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES_LEN 32 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR_LEN 33 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA_LEN 8 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN_LEN 6 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW_LEN 6 // +1 +#define PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO_LEN 11 // +1 + +/* English : "Fade " (Same as JA and DE) */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_EN[] = L"\x0046\x0061\x0064\x0065\x0020\x0000"; +/* German : "Fade " (Same as JA and EN) */ +// static const wchar_t PROTOOLS_CLIP_NAME_FADE_DE[] = L"\x0046\x0061\x0064\x0065\x0020\x0000"; +/* Japanese : "Fade " (Same as EN and DE) */ +// static const wchar_t PROTOOLS_CLIP_NAME_FADE_JA[] = L"\x0046\x0061\x0064\x0065\x0020\x0000"; +/* French : "Fondu " */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_FR[] = L"\x0046\x006f\x006e\x0064\x0075\x0020\x0000"; +/* Spanish : "Fundido" */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_ES[] = L"\x0046\x0075\x006e\x0064\x0069\x0064\x006f\x0020\x0000"; +/* Chinese (S) : "淡变 " */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_ZH_CN[] = L"\x6de1\x53d8\x0020\x0000"; +/* Chinese (T) : "淡變 " */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_ZH_TW[] = L"\x6de1\x8b8a\x0020\x0000"; +/* Korean : "페이드" */ +static const wchar_t PROTOOLS_CLIP_NAME_FADE_KO[] = L"\xd398\xc774\xb4dc\x0000"; + +/* English : "Sample accurate edit" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN[] = L"\x0053\x0061\x006d\x0070\x006c\x0065\x0020\x0061\x0063\x0063\x0075\x0072\x0061\x0074\x0065\x0020\x0065\x0064\x0069\x0074\x0000"; +/* German : "Samplegenaue Bearbeitung" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE[] = L"\x0053\x0061\x006d\x0070\x006c\x0065\x0067\x0065\x006e\x0061\x0075\x0065\x0020\x0042\x0065\x0061\x0072\x0062\x0065\x0069\x0074\x0075\x006e\x0067\x0000"; +/* Spanish : "Edición con precisión de muestra" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES[] = L"\x0045\x0064\x0069\x0063\x0069\x00f3\x006e\x0020\x0063\x006f\x006e\x0020\x0070\x0072\x0065\x0063\x0069\x0073\x0069\x00f3\x006e\x0020\x0064\x0065\x0020\x006d\x0075\x0065\x0073\x0074\x0072\x0061\x0000"; +/* French : "Modification à l'échantillon près" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR[] = L"\x004d\x006f\x0064\x0069\x0066\x0069\x0063\x0061\x0074\x0069\x006f\x006e\x0020\x00e0\x0020\x006c\x0027\x00e9\x0063\x0068\x0061\x006e\x0074\x0069\x006c\x006c\x006f\x006e\x0020\x0070\x0072\x00e8\x0073\x0000"; +/* Japanese : "サンプル精度編集" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA[] = L"\x30b5\x30f3\x30d7\x30eb\x7cbe\x5ea6\x7de8\x96c6\x0000"; +/* Chinese (S) : "精确采样编辑" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN[] = L"\x7cbe\x786e\x91c7\x6837\x7f16\x8f91\x0000"; +/* Chinese (T) : "精確取樣編輯" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW[] = L"\x7cbe\x78ba\x53d6\x6a23\x7de8\x8f2f\x0000"; +/* Korean : "샘플 단위 정밀 편집" */ +static const wchar_t PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO[] = L"\xc0d8\xd50c\x0020\xb2e8\xc704\x0020\xc815\xbc00\x0020\xd3b8\xc9d1\x0000"; + +static int +is_rendered_fade (const wchar_t* clipName); +static int +is_sample_accurate_edit (const wchar_t* clipName); +static int +replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item); + +int +protools_AAF (struct AAF_Iface* aafi) +{ + int probe = 0; + + /* TODO: CompanyName is "Digidesign, Inc." in ProTools 10.3.10.613 AAF, but what about since ? */ + + // if ( aafi->aafd->Identification.CompanyName && wcscmp( aafi->aafd->Identification.CompanyName, L"Digidesign, Inc." ) == 0 ) { + // probe++; + // } + + if (aafi->aafd->Identification.ProductName && wcscmp (aafi->aafd->Identification.ProductName, L"ProTools") == 0) { + probe++; + } + + if (probe == 1) { + return 1; + } + + return 0; +} + +static int +is_rendered_fade (const wchar_t* clipName) +{ + return (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_EN, PROTOOLS_CLIP_NAME_FADE_EN_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ES, PROTOOLS_CLIP_NAME_FADE_ES_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_FR, PROTOOLS_CLIP_NAME_FADE_FR_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_CN, PROTOOLS_CLIP_NAME_FADE_ZH_CN_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_ZH_TW, PROTOOLS_CLIP_NAME_FADE_ZH_TW_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_FADE_KO, PROTOOLS_CLIP_NAME_FADE_KO_LEN) == 0); +} + +static int +is_sample_accurate_edit (const wchar_t* clipName) +{ + return (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_EN_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_DE_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ES_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_FR_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_JA_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_CN_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_ZH_TW_LEN) == 0) || + (memcmp (clipName, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO, PROTOOLS_CLIP_NAME_SAMPLE_ACCURATE_EDIT_KO_LEN) == 0); +} + +static int +replace_clipfade_with_fade (AAF_Iface* aafi, aafiTimelineItem* Item) +{ + if (Item->type != AAFI_AUDIO_CLIP) { + return -1; + } + + aafiAudioClip* audioClip = (aafiAudioClip*)Item->data; + + aafPosition_t currentpos = audioClip->pos; + aafPosition_t currentlen = audioClip->len; + + aafiTimelineItem* transItem = calloc (sizeof (aafiTimelineItem) + sizeof (aafiTransition), sizeof (char)); + + memset (transItem, 0x00, sizeof (aafiTimelineItem) + sizeof (aafiTransition)); + + transItem->type = AAFI_TRANS; + transItem->next = NULL; + transItem->prev = NULL; + + transItem->data = calloc (sizeof (aafiTransition), sizeof (char)); + + aafiTransition* trans = transItem->data; + + trans->len = audioClip->len; + trans->flags = AAFI_INTERPOL_NONE; + + // debug( "%ls", audioClip->Essence->unique_file_name ); + + aafiAudioClip* prevClip = NULL; + aafiAudioClip* nextClip = NULL; + + if (Item->prev != NULL) { + if (Item->prev->type == AAFI_AUDIO_CLIP) { + prevClip = (aafiAudioClip*)Item->prev->data; + + // debug( "PREVIOUS POS %lu", prevClip->pos + prevClip->len ); + // debug( "CURENT POS %lu", currentpos ); + + if (prevClip->pos + prevClip->len < currentpos - 1) { + prevClip = NULL; + } + } + } + + if (Item->next != NULL) { + if (Item->next->type == AAFI_AUDIO_CLIP) { + nextClip = (aafiAudioClip*)Item->next->data; + + if (is_sample_accurate_edit (nextClip->Essence->file_name)) { + if (Item->next->next != NULL) { + nextClip = (aafiAudioClip*)Item->next->next->data; + + // debug( "NEXT POS %lu", nextClip->pos ); + // debug( "CURENT POS %lu", currentpos + currentlen ); + + if (nextClip->pos != currentpos + currentlen + 1) { + nextClip = NULL; + } + } else { + nextClip = NULL; + } + } else { + // nextClip = (aafiAudioClip*)Item->next->data; + + // debug( "NEXT POS %lu", nextClip->pos ); + // debug( "CURENT POS %lu", currentpos + currentlen ); + + if (nextClip->pos != currentpos + currentlen) { + nextClip = NULL; + } + } + } + } + + trans->time_a = calloc (2, sizeof (aafRational_t)); + trans->value_a = calloc (2, sizeof (aafRational_t)); + + trans->time_a[0].numerator = 0; + trans->time_a[0].denominator = 0; + trans->time_a[1].numerator = 1; + trans->time_a[1].denominator = 1; + + if (prevClip && nextClip) { + // debug( ":: XFADE" ); + trans->flags |= AAFI_TRANS_XFADE; + + trans->value_a[0].numerator = 0; + trans->value_a[0].denominator = 0; + trans->value_a[1].numerator = 1; + trans->value_a[1].denominator = 1; + } else if (prevClip) { + // debug( ":: FADE OUT" ); + trans->flags |= AAFI_TRANS_FADE_OUT; + + trans->value_a[0].numerator = 1; + trans->value_a[0].denominator = 1; + trans->value_a[1].numerator = 0; + trans->value_a[1].denominator = 0; + } else if (nextClip) { + // debug( ":: FADE IN" ); + trans->flags |= AAFI_TRANS_FADE_IN; + + trans->value_a[0].numerator = 0; + trans->value_a[0].denominator = 0; + trans->value_a[1].numerator = 1; + trans->value_a[1].denominator = 1; + } + + if (Item->prev) { + Item->prev->next = transItem; + transItem->prev = Item->prev; + } else { + aafiAudioTrack* audioTrack = NULL; + + foreach_audioTrack (audioTrack, aafi) + { + if (audioTrack->Items == Item) { + audioTrack->Items = transItem; + } + } + + transItem->prev = NULL; + } + + if (Item->next) { + Item->next->prev = transItem; + } + + transItem->next = Item->next; + + aafi_freeTimelineItem (&Item); + + return 0; +} + +int +protools_post_processing (AAF_Iface* aafi /*, enum protools_options flags*/) +{ + aafiAudioTrack* audioTrack = NULL; + + foreach_audioTrack (audioTrack, aafi) + { + aafiTimelineItem* audioItem = audioTrack->Items; + + while (audioItem != NULL) { + if (audioItem->type != AAFI_AUDIO_CLIP) { + audioItem = audioItem->next; + continue; + } + + aafiAudioClip* audioClip = (aafiAudioClip*)audioItem->data; + + wchar_t* clipName = audioClip->Essence->file_name; + + if ((aafi->ctx.options.protools & PROTOOLS_REPLACE_CLIP_FADES) && is_rendered_fade (clipName)) { + replace_clipfade_with_fade (aafi, audioItem); + + audioItem = audioTrack->Items; + continue; + } else if ((aafi->ctx.options.protools & PROTOOLS_REMOVE_SAMPLE_ACCURATE_EDIT) && is_sample_accurate_edit (clipName)) { + aafi_removeTimelineItem (aafi, audioItem); + + audioItem = audioTrack->Items; + continue; + } + + audioItem = audioItem->next; + } + } + + return 0; +} diff --git a/libs/aaf/RIFFParser.c b/libs/aaf/RIFFParser.c new file mode 100644 index 0000000000..3ecc06d331 --- /dev/null +++ b/libs/aaf/RIFFParser.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include + +#include "aaf/RIFFParser.h" + +#define debug(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +#define BE2LE32(val) \ + (((val >> 24) & 0xff) | ((val << 8) & 0xff0000) | ((val >> 8) & 0xff00) | ((val << 24) & 0xff000000)) + +#define BE2LE16(val) \ + ((val << 8) | (val >> 8)) + +static uint32_t +beExtended2leUint32 (const unsigned char numx[10]); + +int +riff_writeWavFileHeader (FILE* fp, struct wavFmtChunk* wavFmt, struct wavBextChunk* wavBext, uint32_t audioDataSize, struct dbg* dbg) +{ + (void)dbg; + uint32_t filesize = (4 /* WAVE */) + sizeof (struct wavFmtChunk) + ((wavBext) ? sizeof (struct wavBextChunk) : 0) + (8 /*data chunk header*/) + audioDataSize; + + size_t writtenBytes = fwrite ("RIFF", sizeof (unsigned char), 4, fp); + + if (writtenBytes < 4) { + return -1; + } + + writtenBytes = fwrite (&filesize, sizeof (uint32_t), 1, fp); + + if (writtenBytes < 1) { + return -1; + } + + writtenBytes = fwrite ("WAVE", sizeof (unsigned char), 4, fp); + + if (writtenBytes < 4) { + return -1; + } + + wavFmt->ckid[0] = 'f'; + wavFmt->ckid[1] = 'm'; + wavFmt->ckid[2] = 't'; + wavFmt->ckid[3] = ' '; + wavFmt->cksz = sizeof (struct wavFmtChunk) - sizeof (struct riffChunk); + wavFmt->format_tag = 1; /* PCM */ + wavFmt->avg_bytes_per_sec = wavFmt->samples_per_sec * wavFmt->channels * wavFmt->bits_per_sample / 8; + wavFmt->block_align = wavFmt->channels * wavFmt->bits_per_sample / 8; + + writtenBytes = fwrite ((unsigned char*)wavFmt, sizeof (unsigned char), sizeof (struct wavFmtChunk), fp); + + if (writtenBytes < sizeof (struct wavFmtChunk)) { + return -1; + } + + if (wavBext) { + wavBext->ckid[0] = 'b'; + wavBext->ckid[1] = 'e'; + wavBext->ckid[2] = 'x'; + wavBext->ckid[3] = 't'; + wavBext->cksz = sizeof (struct wavBextChunk) - sizeof (struct riffChunk); + wavBext->version = 1; + + writtenBytes = fwrite ((unsigned char*)wavBext, sizeof (unsigned char), sizeof (struct wavBextChunk), fp); + + if (writtenBytes < sizeof (struct wavBextChunk)) { + return -1; + } + } + + writtenBytes = fwrite ("data", sizeof (unsigned char), 4, fp); + + if (writtenBytes < 4) { + return -1; + } + + writtenBytes = fwrite (&audioDataSize, sizeof (uint32_t), 1, fp); + + if (writtenBytes < 1) { + return -1; + } + + return 0; +} + +int +riff_parseAudioFile (struct RIFFAudioFile* RIFFAudioFile, enum RIFF_PARSER_FLAGS flags, size_t (*readerCallback) (unsigned char*, size_t, size_t, void*, void*, void*), void* user1, void* user2, void* user3, struct dbg* dbg) +{ + struct riffChunk chunk; + struct riffHeaderChunk riff; + + memset (RIFFAudioFile, 0x00, sizeof (struct RIFFAudioFile)); + + size_t bytesRead = readerCallback ((unsigned char*)&riff, 0, sizeof (riff), user1, user2, user3); + + if (bytesRead < sizeof (riff)) { + error ("Could not read file"); + return -1; + } + + int be = 0; /* big endian */ + + if (riff.format[0] == 'A' && + riff.format[1] == 'I' && + riff.format[2] == 'F' && + riff.format[3] == 'F') { + be = 1; + riff.cksz = BE2LE32 (riff.cksz); + } else if (riff.format[0] == 'A' && + riff.format[1] == 'I' && + riff.format[2] == 'F' && + riff.format[3] == 'C') { + be = 1; + riff.cksz = BE2LE32 (riff.cksz); + } else if (riff.format[0] == 'W' && + riff.format[1] == 'A' && + riff.format[2] == 'V' && + riff.format[3] == 'E') { + be = 0; + } else { + error ("File is not a valid RIFF/WAVE or RIFF/AIFF : Missing format identifier"); + return -1; + } + + // debug( "%.4s %.4s (%u bytes)", riff.ckid, riff.format, riff.cksz ); + + size_t filesize = riff.cksz + sizeof (chunk); + size_t pos = sizeof (struct riffHeaderChunk); + + while (pos < filesize) { + bytesRead = readerCallback ((unsigned char*)&chunk, pos, sizeof (chunk), user1, user2, user3); + + if (bytesRead < sizeof (chunk)) { + error ("Could not read chunk @ %" PRIu64 " (%" PRIu64 " bytes returned)", pos, bytesRead); + break; + } + + if (be) { + chunk.cksz = BE2LE32 (chunk.cksz); + } + + // debug( "Got chunk : %.4s (%u bytes)", chunk.ckid, chunk.cksz ); + + if (!be) { /* WAVE */ + + if (chunk.ckid[0] == 'f' && + chunk.ckid[1] == 'm' && + chunk.ckid[2] == 't' && + chunk.ckid[3] == ' ') { + struct wavFmtChunk wavFmtChunk; + + bytesRead = readerCallback ((unsigned char*)&wavFmtChunk, pos, sizeof (wavFmtChunk), user1, user2, user3); + + RIFFAudioFile->channels = wavFmtChunk.channels; + RIFFAudioFile->sampleSize = wavFmtChunk.bits_per_sample; + RIFFAudioFile->sampleRate = wavFmtChunk.samples_per_sec; + + if (flags & RIFF_PARSE_ONLY_HEADER) { + return 0; + } + } else if (chunk.ckid[0] == 'd' && + chunk.ckid[1] == 'a' && + chunk.ckid[2] == 't' && + chunk.ckid[3] == 'a') { + if (RIFFAudioFile->channels > 0 && RIFFAudioFile->sampleSize > 0) { + RIFFAudioFile->duration = chunk.cksz / RIFFAudioFile->channels / (RIFFAudioFile->sampleSize / 8); + } + } + } else { /* AIFF */ + + if (chunk.ckid[0] == 'C' && + chunk.ckid[1] == 'O' && + chunk.ckid[2] == 'M' && + chunk.ckid[3] == 'M') { + struct aiffCOMMChunk aiffCOMMChunk; + + bytesRead = readerCallback ((unsigned char*)&aiffCOMMChunk, pos, sizeof (aiffCOMMChunk), user1, user2, user3); + + RIFFAudioFile->channels = BE2LE16 (aiffCOMMChunk.numChannels); + RIFFAudioFile->sampleSize = BE2LE16 (aiffCOMMChunk.sampleSize); + RIFFAudioFile->sampleRate = beExtended2leUint32 (aiffCOMMChunk.sampleRate); + RIFFAudioFile->duration = BE2LE32 (aiffCOMMChunk.numSampleFrames); + + if (flags & RIFF_PARSE_ONLY_HEADER) { + return 0; + } + } + /* + * We don't care about AIFF "SSND" chunk because we already know duration + * from "COMM". Could we double check validity of duration by checking + * "SSND" chunk size, like we do with WAV "DATA" chunk ? is it possible + * with AAF audio file summary ? + */ + + // else + // if ( chunk.ckid[0] == 'S' && + // chunk.ckid[1] == 'S' && + // chunk.ckid[2] == 'N' && + // chunk.ckid[3] == 'D' ) + // { + // } + } + + pos += chunk.cksz + sizeof (chunk); + } + + return 0; +} + +static uint32_t +beExtended2leUint32 (const unsigned char numx[10]) +{ + /* + * https://stackoverflow.com/a/18854415/16400184 + */ + + unsigned char x[10]; + + /* be -> le */ + x[0] = numx[9]; + x[1] = numx[8]; + x[2] = numx[7]; + x[3] = numx[6]; + x[4] = numx[5]; + x[5] = numx[4]; + x[6] = numx[3]; + x[7] = numx[2]; + x[8] = numx[1]; + x[9] = numx[0]; + + int exponent = (((x[9] << 8) | x[8]) & 0x7FFF); + uint64_t mantissa = ((uint64_t)x[7] << 56) | ((uint64_t)x[6] << 48) | ((uint64_t)x[5] << 40) | ((uint64_t)x[4] << 32) | + ((uint64_t)x[3] << 24) | ((uint64_t)x[2] << 16) | ((uint64_t)x[1] << 8) | (uint64_t)x[0]; + unsigned char d[8] = { 0 }; + double result; + + d[7] = x[9] & 0x80; /* Set sign. */ + + if ((exponent == 0x7FFF) || (exponent == 0)) { + /* Infinite, NaN or denormal */ + if (exponent == 0x7FFF) { + /* Infinite or NaN */ + d[7] |= 0x7F; + d[6] = 0xF0; + } else { + /* Otherwise it's denormal. It cannot be represented as double. Translate as singed zero. */ + memcpy (&result, d, 8); + return result; + } + } else { + /* Normal number. */ + exponent = exponent - 0x3FFF + 0x03FF; /*< exponent for double precision. */ + + if (exponent <= -52) { /*< Too small to represent. Translate as (signed) zero. */ + memcpy (&result, d, 8); + return result; + } else if (exponent < 0) { + /* Denormal, exponent bits are already zero here. */ + } else if (exponent >= 0x7FF) { /*< Too large to represent. Translate as infinite. */ + d[7] |= 0x7F; + d[6] = 0xF0; + memset (d, 0x00, 6); + memcpy (&result, d, 8); + return result; + } else { + /* Representable number */ + d[7] |= (exponent & 0x7F0) >> 4; + d[6] |= (exponent & 0xF) << 4; + } + } + + /* Translate mantissa. */ + + mantissa >>= 11; + + if (exponent < 0) { + /* Denormal, further shifting is required here. */ + mantissa >>= (-exponent + 1); + } + + d[0] = mantissa & 0xFF; + d[1] = (mantissa >> 8) & 0xFF; + d[2] = (mantissa >> 16) & 0xFF; + d[3] = (mantissa >> 24) & 0xFF; + d[4] = (mantissa >> 32) & 0xFF; + d[5] = (mantissa >> 40) & 0xFF; + d[6] |= (mantissa >> 48) & 0x0F; + + memcpy (&result, d, 8); + + return (uint32_t)result; +} diff --git a/libs/aaf/Resolve.c b/libs/aaf/Resolve.c new file mode 100644 index 0000000000..a11e67559c --- /dev/null +++ b/libs/aaf/Resolve.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "aaf/AAFDefs/AAFPropertyIDs.h" +#include "aaf/AAFDefs/AAFTypeDefUIDs.h" +#include "aaf/AAFIParser.h" +#include "aaf/AAFToText.h" + +#include "aaf/debug.h" +#include "aaf/libaaf.h" + +#define debug(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (aafi->dbg, aafi, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +int +resolve_AAF (struct AAF_Iface* aafi) +{ + int probe = 0; + + if (aafi->aafd->Identification.CompanyName && wcsncmp (aafi->aafd->Identification.CompanyName, L"Blackmagic Design", wcslen (L"Blackmagic Design")) == 0) { + probe++; + } + + if (aafi->aafd->Identification.ProductName && wcsncmp (aafi->aafd->Identification.ProductName, L"DaVinci Resolve", wcslen (L"DaVinci Resolve")) == 0) { + probe++; + } + + if (probe == 2) { + return 1; + } + + return 0; +} + +int +resolve_parse_aafObject_Selector (struct AAF_Iface* aafi, aafObject* Selector, td* __ptd) +{ + /* + * Resolve 18.5 + * + * The Selector Object was only seen used to describe a disabled clip : + * - Selected property Object is an empty Filler + * - Alternate keeps track of the original clip. + * +03411││ ├──◻ AAFClassID_Selector +01926││ Selected --> │ └──◻ AAFClassID_Filler +02359││ Alternate -> │ └──◻ AAFClassID_OperationGroup (OpIdent: AAFOperationDef_MonoAudioGain) +03822││ │ ├──◻ AAFClassID_VaryingValue +02877││ │ └──◻ AAFClassID_SourceClip +02882││ │ └──◻ AAFClassID_MasterMob (UsageCode: n/a) : speech-sample.mp3 - disabled +04460││ │ └──◻ AAFClassID_TimelineMobSlot +03089││ │ └──◻ AAFClassID_SourceClip +04167││ │ └──◻ AAFClassID_SourceMob (UsageCode: n/a) : speech-sample.mp3 - disabled +01249││ │ └──◻ AAFClassID_PCMDescriptor +01455││ │ └──◻ AAFClassID_NetworkLocator : file:///C:/Users/user/Desktop/libAAF/test/res/speech-sample.mp3 + */ + + struct trace_dump __td; + __td_set (__td, __ptd, 0); + + aafObject* Selected = aaf_get_propertyValue (Selector, PID_Selector_Selected, &AAFTypeID_SegmentStrongReference); + + if (Selected == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, Selector, &__td, "Missing PID_Selector_Selected"); + return -1; + } + + aafObject* Alternates = aaf_get_propertyValue (Selector, PID_Selector_Alternates, &AAFTypeID_SegmentStrongReferenceVector); + + if (Alternates == NULL) { /* opt */ + DUMP_OBJ_WARNING (aafi, Selector, &__td, "Missing PID_Selector_Alternates"); + return -1; + } + + void* ComponentAttributeList = aaf_get_propertyValue (Selector, aaf_get_PropertyIDByName (aafi->aafd, L"ComponentAttributeList"), &AAFUID_NULL); + + if (ComponentAttributeList == NULL) { + DUMP_OBJ_ERROR (aafi, Selector, &__td, "Missing AAFClassID_Selector::ComponentAttributeList"); + return -1; + } + + DUMP_OBJ (aafi, Selector, &__td); + + // aaf_dump_ObjectProperties( aafi->aafd, Selector ); + // aaf_dump_ObjectProperties( aafi->aafd, ComponentAttributeList ); + + int ismuted = 0; + aafObject* ComponentAttribute = NULL; + + aaf_foreach_ObjectInSet (&ComponentAttribute, ComponentAttributeList, NULL) + { + /* TODO implement retrieve_TaggedValue() */ + + wchar_t* name = aaf_get_propertyValue (ComponentAttribute, PID_TaggedValue_Name, &AAFTypeID_String); + + if (name == NULL) { /* req */ + DUMP_OBJ_ERROR (aafi, ComponentAttribute, &__td, "Missing PID_TaggedValue_Name"); + continue; + } + + aafIndirect_t* Indirect = aaf_get_propertyValue (ComponentAttribute, PID_TaggedValue_Value, &AAFTypeID_Indirect); + + if (Indirect == NULL) { + DUMP_OBJ_ERROR (aafi, ComponentAttribute, &__td, "Missing PID_TaggedValue_Value"); + free (name); + continue; + } + + int32_t* value = aaf_get_indirectValue (aafi->aafd, Indirect, &AAFTypeID_Int32); + + if (value == NULL) { + DUMP_OBJ_ERROR (aafi, ComponentAttribute, &__td, "Could not retrieve Indirect value for PID_TaggedValue_Value"); + free (name); + continue; + } + + // debug( "Tagged | Name: %ls Value : %u", name, *value ); + + if (aafi->ctx.options.resolve & RESOLVE_INCLUDE_DISABLED_CLIPS) { + if (wcsncmp (name, L"_DISABLE_CLIP_FLAG", wcslen (L"_DISABLE_CLIP_FLAG")) == 0 && *value == 1) { + ismuted = 1; + aafi->ctx.current_clip_is_muted = 1; + + aafObject* Alternate = NULL; + + int i = 0; + aaf_foreach_ObjectInSet (&Alternate, Alternates, NULL) + { + if (i == 0) { /* there should be only one Segment in set, but still. Let's be carefull */ + aafi_parse_Segment (aafi, Alternate, &__td); + } else { + DUMP_OBJ_ERROR (aafi, Alternate, &__td, "Multiple Alternates in Davinci Resolve selector"); + } + i++; + } + } + } + + free (name); + } + + /* aafi->ctx.current_clip_is_muted was already reset at this point */ + if (ismuted == 0) { + return aafi_parse_Segment (aafi, Selected, &__td); + } + + return 0; +} + +int +resolve_parse_aafObject_DescriptiveMarker (struct AAF_Iface* aafi, aafObject* DescriptiveMarker, td* __ptd) +{ + /* + * Resolve 18.5 + */ + + struct trace_dump __td; + __td_set (__td, __ptd, 1); + + aafPosition_t* start = aaf_get_propertyValue (DescriptiveMarker, PID_Event_Position, &AAFTypeID_PositionType); + + if (start == NULL) { /* req (TODO: conditional) */ + DUMP_OBJ_ERROR (aafi, DescriptiveMarker, &__td, "Missing PID_Event_Position"); + return -1; + } + + aafPosition_t* length = aaf_get_propertyValue (DescriptiveMarker, PID_Component_Length, &AAFTypeID_PositionType); + + wchar_t* comment = aaf_get_propertyValue (DescriptiveMarker, PID_Event_Comment, &AAFTypeID_String); + + wchar_t* name = aaf_get_propertyValue (DescriptiveMarker, aaf_get_PropertyIDByName (aafi->aafd, L"CommentMarkerUser"), &AAFTypeID_String); + + uint16_t* RGBColor = NULL; + + aafProperty* RGBColorProp = aaf_get_property (DescriptiveMarker, aaf_get_PropertyIDByName (aafi->aafd, L"CommentMarkerColor")); + + if (RGBColorProp) { + if (RGBColorProp->len != sizeof (uint16_t) * 3) { + error ("CommentMarkerColor has wrong size of %u", RGBColorProp->len); + } else { + RGBColor = RGBColorProp->val; + + /* big endian to little endian */ + + RGBColor[0] = (RGBColor[0] >> 8) | (RGBColor[0] << 8); + RGBColor[1] = (RGBColor[1] >> 8) | (RGBColor[1] << 8); + RGBColor[2] = (RGBColor[2] >> 8) | (RGBColor[2] << 8); + } + } + + aafi_newMarker (aafi, aafi->ctx.current_markers_edit_rate, *start, ((length) ? *length : 0), name, comment, &RGBColor); + + DUMP_OBJ (aafi, DescriptiveMarker, &__td); + + return 0; +} diff --git a/libs/aaf/URIParser.c b/libs/aaf/URIParser.c new file mode 100644 index 0000000000..5970499139 --- /dev/null +++ b/libs/aaf/URIParser.c @@ -0,0 +1,1314 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +typedef SSIZE_T ssize_t; +#endif + +#include "aaf/URIParser.h" + +#define debug(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_DEBUG, __VA_ARGS__) + +#define warning(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_WARNING, __VA_ARGS__) + +#define error(...) \ + _dbg (dbg, NULL, DEBUG_SRC_ID_AAF_IFACE, VERB_ERROR, __VA_ARGS__) + +#define IS_LOWALPHA(c) \ + ((c >= 'a') && (c <= 'z')) + +#define IS_UPALPHA(c) \ + ((c >= 'A') && (c <= 'Z')) + +#define IS_ALPHA(c) \ + (IS_LOWALPHA (c) || IS_UPALPHA (c)) + +#define IS_DIGIT(c) \ + (c >= '0' && c <= '9') + +#define IS_ALPHANUM(c) \ + (IS_ALPHA (c) || IS_DIGIT (c)) + +#define IS_HEX(c) \ + (IS_DIGIT (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) + +/* + * RFC 2396 + * https://datatracker.ietf.org/doc/html/rfc2396#section-2.3 + */ +#define IS_MARK(c) \ + (c == '-' || c == '_' || c == '.' || c == '!' || c == '~' || c == '*' || c == '\'' || c == '(' || c == ')') + +#define IS_UNRESERVED(c) \ + (IS_ALPHANUM (c) || IS_MARK (c)) + +#define IS_ENCODED(p) \ + ((*p == '%') && IS_HEX (*(p + 1)) && IS_HEX (*(p + 2))) + +#define SCHEME_SAFE_CHAR(c) \ + (IS_ALPHANUM (c) || c == '+' || c == '.' || c == '-') + +#define USERINFO_SAFE_CHAR(p) \ + (IS_ALPHANUM (*p) || IS_ENCODED (p) || *p == ';' || *p == ':' || *p == '&' || *p == '=' || *p == '+' || *p == '$' || *p == ',') + +#define WINDOWS_DRIVE_LETTER(p) \ + (IS_ALPHA (*p) && (*(p + 1) == ':' || *(p + 1) == '|') && *(p + 2) == '/') + +#define SCHEME_ALLOW_QUERY(uri) \ + (uri->scheme_t != URI_SCHEME_T_FILE && \ + !(uri->opts & URI_OPT_IGNORE_QUERY)) + +#define SCHEME_ALLOW_FRAGMENT(uri) \ + (uri->scheme_t != URI_SCHEME_T_FILE && \ + !(uri->opts & URI_OPT_IGNORE_FRAGMENT)) + +#define URI_SET_STR(str, start, end) \ + \ + str = malloc (sizeof (char) * ((end - start) + 1)); \ + \ + if (NULL == str) { \ + error ("URI allocation failed"); \ + goto err; \ + } \ + \ + snprintf (str, (end - start) + 1, "%s", start); + +static int +_uri_parse_scheme (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_authority (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_userinfo (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_hostname (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_path (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_query (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); +static int +_uri_parse_fragment (struct uri* uri, const char** pos, const char* end, struct dbg* dbg); + +static void +_uri_scheme2schemeType (struct uri* uri); +static int +_laaf_util_snprintf_realloc (char** str, size_t* size, size_t offset, const char* format, ...); + +#ifdef BUILD_URI_TEST // gcc -g -W -Wall ./URIParser.c -D BUILD_URI_TEST +static int +_uri_cmp (const struct uri* a, const struct uri* b); +static void +_uri_dump_diff (struct uri* a, struct uri* b, int totalDifferencies); +static int +_uri_test (const char* uristr, enum uri_option optflags, struct uri expectedRes, int line); +#endif // BUILD_URI_TEST + +char* +uriDecodeString (char* src, char* dst) +{ + int inpos = 0; + int outpos = 0; + + if (src == NULL) { + return NULL; + } + + if (dst == NULL) { + dst = src; + } + + while (src[inpos]) { + if (src[inpos] == '%' && IS_HEX (src[inpos + 1]) && IS_HEX (src[inpos + 2])) { + int c = 0; + + char hex1 = src[inpos + 1]; + + if ((hex1 >= '0') && (hex1 <= '9')) + c = (hex1 - '0'); + else if ((hex1 >= 'a') && (hex1 <= 'f')) + c = (hex1 - 'a') + 10; + else if ((hex1 >= 'A') && (hex1 <= 'F')) + c = (hex1 - 'A') + 10; + + char hex2 = src[inpos + 2]; + + if ((hex2 >= '0') && (hex2 <= '9')) + c = c * 16 + (hex2 - '0'); + else if ((hex2 >= 'a') && (hex2 <= 'f')) + c = c * 16 + (hex2 - 'a') + 10; + else if ((hex2 >= 'A') && (hex2 <= 'F')) + c = c * 16 + (hex2 - 'A') + 10; + + dst[outpos] = (char)c; + inpos += 3; + } else { + dst[outpos] = src[inpos]; + inpos++; + } + + outpos++; + } + + if (inpos > outpos) { + dst[outpos] = 0x00; + } + + return dst; +} + +static int +_uri_parse_scheme (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + const char* p = *pos; + + while (p < end && *p != ':') { + if (!SCHEME_SAFE_CHAR (*p)) { + error ("uri scheme contains invalid character : '%c' (0x%02x)", *p, *p); + goto err; + } + p++; + } + + if (*pos == p) { + error ("uri is missing scheme"); + goto err; + } + + URI_SET_STR (uri->scheme, *pos, p); + + /* + * RFC 3986 - Generic + * https://datatracker.ietf.org/doc/html/rfc3986#section-3.1 + * + * « Although schemes are case- insensitive, the canonical form is lowercase + * and documents that specify schemes must do so with lowercase letters. + * An implementation should accept uppercase letters as equivalent to lowercase + * in scheme names (e.g., allow "HTTP" as well as "http") for the sake of + * robustness but should only produce lowercase scheme names for consistency.» + */ + + char* pp = uri->scheme; + + while (*pp) { + *pp = tolower (*pp); + pp++; + } + + _uri_scheme2schemeType (uri); + + *pos = ++p; /* Skips ':' */ + + return 1; + +err: + return -1; +} + +static int +_uri_parse_authority (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + /* + * RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax + * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2 + * + * « Many URI schemes include a hierarchical element for a naming + * authority so that governance of the name space defined by the + * remainder of the URI is delegated to that authority (which may, in + * turn, delegate it further). The generic syntax provides a common + * means for distinguishing an authority based on a registered name or + * server address, along with optional port and user information. + * + * The authority component is preceded by a double slash ("//") and is + * terminated by the next slash ("/"), question mark ("?"), or number + * sign ("#") character, or by the end of the URI. + * + * authority = [ userinfo "@" ] host [ ":" port ] + * + * URI producers and normalizers should omit the ":" delimiter that + * separates host from port if the port component is empty. Some + * schemes do not allow the userinfo and/or port subcomponents. + * + * If a URI contains an authority component, then the path component + * must either be empty or begin with a slash ("/") character. Non- + * validating parsers (those that merely separate a URI reference into + * its major components) will often ignore the subcomponent structure of + * authority, treating it as an opaque string from the double-slash to + * the first terminating delimiter, until such time as the URI is + * dereferenced.» + */ + + if (*(*pos) != '/' || + *((*pos) + 1) != '/') { + /* uri has no authority */ + if (uri->scheme_t == URI_SCHEME_T_FILE) { + uri->flags |= URI_T_LOCALHOST; + } + // uri->flags |= URI_T_LOCALHOST; + // uri->flags |= URI_T_HOST_EMPTY; + return 0; + } + + *pos += 2; + const char* p = *pos; + + while (p < end && + *p != '/' && + (!SCHEME_ALLOW_QUERY (uri) || *p != '?') && + (!SCHEME_ALLOW_FRAGMENT (uri) || *p != '#')) { + p++; + } + + URI_SET_STR (uri->authority, *pos, p); + + if (*uri->authority == 0x00) { + uri->flags |= URI_T_LOCALHOST; + } + + return 1; + +err: + return -1; +} + +static int +_uri_parse_userinfo (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + int hasUserinfo = 0; + int userinfoIllegalCharacters = 0; + + const char* p = *pos; + + while (p < end) { + if (*p == '@') { + hasUserinfo = 1; + break; + } + + if (!USERINFO_SAFE_CHAR (p)) { + userinfoIllegalCharacters++; + } + + p++; + } + + if (!hasUserinfo) { + return 0; + } + + if (userinfoIllegalCharacters > 0) { + error ("uri userinfo contains %i invalid char%s", userinfoIllegalCharacters, (userinfoIllegalCharacters > 1) ? "s" : ""); + goto err; + } + + /* user / pass */ + + URI_SET_STR (uri->userinfo, *pos, p); + + *pos = p + 1; // skips '@' + + const char* subpos = NULL; + p = uri->userinfo; + + while (1) { + if (!*p) { + if (subpos) { + URI_SET_STR (uri->pass, subpos, p); + } else { + URI_SET_STR (uri->user, uri->userinfo, p); + } + break; + } else if (*p == ':') { + URI_SET_STR (uri->user, uri->userinfo, p); + subpos = p + 1; + } + p++; + } + + if (uri->opts & URI_OPT_DECODE_USERINFO && uri->userinfo) { + uriDecodeString (uri->userinfo, NULL); + } + + if (uri->opts & URI_OPT_DECODE_USERPASS) { + if (uri->user) + uriDecodeString (uri->user, NULL); + if (uri->pass) + uriDecodeString (uri->pass, NULL); + } + + return 1; + +err: + return -1; +} + +static int +_uri_parse_hostname (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + const char* p = *pos; + + if (**pos == '[') { + /* + * IPv6 - RFC 2732 + * https://datatracker.ietf.org/doc/html/rfc2732 + */ + (*pos)++; // skips '[' + + while (p < end && + *p != ']') { + p++; + } + + URI_SET_STR (uri->host, *pos, p); + + char* iperr = NULL; + int rc = 0; + if ((rc = uriIsIPv6 (uri->host, strlen (uri->host), &iperr))) { + uri->flags |= URI_T_HOST_IPV6; + if (rc == 2) { + uri->flags |= URI_T_LOCALHOST; + } + } else { + error ("URI IPv6 Parser error : %s\n", iperr); + free (iperr); + goto err; + } + + p++; // skips ']' + } else if ((*p == '.' || *p == '?') && (*(p + 1) == '/')) { + /* windows "//./" and "//?/" guard */ + uri->flags |= URI_T_LOCALHOST; + return 0; + } else { + /* + * All other : IPv4, server name, local path + */ + + while (p < end && + *p != '/' && // if URI contains a path + *p != ':' && // if URI has an explicit port + (!SCHEME_ALLOW_QUERY (uri) || *p != '?') && + (!SCHEME_ALLOW_FRAGMENT (uri) || *p != '#')) { + p++; + } + + // debug( " >>> %.*s", (int)(p-*pos), p ); + + URI_SET_STR (uri->host, *pos, p); + } + + // if ( !(uri->flags & URI_T_HOST_IPV6 || uri->flags & URI_T_HOST_EMPTY) ) { + if (!(uri->flags & URI_T_HOST_IPV6) && uri->host != NULL && *uri->host != 0x00) { + if (uriIsIPv4 (uri->host, strlen (uri->host), NULL)) { + uri->flags &= ~URI_T_HOST_MASK; + uri->flags |= URI_T_HOST_IPV4; + if (strcmp (uri->host, "127.0.0.1") == 0) { + uri->flags |= URI_T_LOCALHOST; + } + } else if (strcmp (uri->host, "localhost") == 0) { + uri->flags |= URI_T_LOCALHOST; + } else { + uri->flags |= URI_T_HOST_REGNAME; + } + + if (uri->opts & URI_OPT_DECODE_HOSTNAME) { + uriDecodeString (uri->host, NULL); + } + } + // else if ( uri->host == NULL ) { + // if ( uri->scheme_t == URI_SCHEME_T_FILE ) { + // uri->flags |= URI_T_LOCALHOST; + // } + // } + + if (*p == ':') { + /* port */ + + *pos = ++p; + + while (p < end && + *p != '/' && + (!SCHEME_ALLOW_QUERY (uri) || *p != '?') && + (!SCHEME_ALLOW_FRAGMENT (uri) || *p != '#')) { + if (!IS_DIGIT (*p)) { + error ("URI port contains non-digit char : %c (0x%02x).\n", *p, *p); + goto err; + } + p++; + } + + uri->port = atoi (*pos); + } + + *pos = p; // keeps next char, first path '/' + + return 1; + +err: + return -1; +} + +static int +_uri_parse_path (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + int winDrive = 0; + + /* sanitize start of path : ignores all slashes (after already parsed '//' identifying start of authority) */ + + while (*(*pos + 1) == '/') { + (*pos)++; + } + + if (*(*pos) == '/' && WINDOWS_DRIVE_LETTER (((*pos) + 1))) { + /* + * Windows Drive (c: / c|) - RFC 8089 + * https://datatracker.ietf.org/doc/html/rfc8089#appendix-E.2.2 + */ + + (*pos)++; /* moves forward last slash before driver letter, so path starts at the letter with no slash before. */ + winDrive = 1; + } + + const char* p = *pos; + + while (p < end && + (!SCHEME_ALLOW_QUERY (uri) || *p != '?') && + (!SCHEME_ALLOW_FRAGMENT (uri) || *p != '#')) { + p++; + } + + // debug( " >>> (%i) %.*s", (int)(p-*pos), (int)(p-*pos), p ); + + URI_SET_STR (uri->path, *pos, p); + + if (winDrive) { + if (uri->path[1] == '|') { + /* + * https://datatracker.ietf.org/doc/html/rfc8089#appendix-E.2.2 + * « To update such an old URI, replace the vertical line "|" with a colon ":" » + */ + uri->path[1] = ':'; + } + } + + if (uri->opts & URI_OPT_DECODE_PATH) { + uriDecodeString (uri->path, NULL); + } + + *pos = p; + + return 1; + +err: + return -1; +} + +static int +_uri_parse_query (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + const char* p = *pos; + + if (!(uri->opts & URI_OPT_IGNORE_QUERY) && **pos == '?') { + while (p < end && *p != '#') { + p++; + } + + (*pos)++; // skips '?' + + URI_SET_STR (uri->query, *pos, p); + + if (uri->opts & URI_OPT_DECODE_QUERY) { + uriDecodeString (uri->query, NULL); + } + + *pos = p; + } + + return 1; + +err: + return -1; +} + +static int +_uri_parse_fragment (struct uri* uri, const char** pos, const char* end, struct dbg* dbg) +{ + /* + * https://datatracker.ietf.org/doc/html/draft-yevstifeyev-ftp-uri-scheme#section-3.2.4.2 + * « ... fragment identifier are allowed in any URI. + * + * The number sign ("#") characters (ASCII character 0x23), if used for + * the reason other than to delimit the fragment identifier SHALL be + * percent-encoded. » + * + * However, we've seen filenames in 'file' scheme with non encoded '#'. + * Plus, it seems impossible for a client to use fragments in a 'file' + * scheme URI. So the SCHEME_ALLOW_FRAGMENT() macro will make the parser + * treat '#' chars as a normal character, only for 'file' scheme. + */ + + const char* p = *pos; + + if (!(uri->opts & URI_OPT_IGNORE_FRAGMENT) && **pos == '#') { + while (p < end) { + p++; + } + + (*pos)++; // skips '#' + + URI_SET_STR (uri->fragment, *pos, p); + + if (uri->opts & URI_OPT_DECODE_FRAGMENT) { + uriDecodeString (uri->fragment, NULL); + } + + *pos = ++p; // skips '#' + } + + return 1; + +err: + return -1; +} + +struct uri* +uriParse (const char* uristr, enum uri_option optflags, struct dbg* dbg) +{ + if (uristr == NULL) { + return NULL; + } + + struct uri* uri = calloc (1, sizeof (struct uri)); + + if (uri == NULL) { + return NULL; + } + + size_t urilen = strlen (uristr); + + if (urilen >= MAX_URI_LENGTH) { + error ("uri is too long"); + goto err; + } + + uri->opts = optflags; + + const char* pos = uristr; + const char* end = pos + urilen; + + _uri_parse_scheme (uri, &pos, end, dbg); + + if (_uri_parse_authority (uri, &pos, end, dbg)) { + _uri_parse_userinfo (uri, &pos, end, dbg); + _uri_parse_hostname (uri, &pos, end, dbg); + } + + _uri_parse_path (uri, &pos, end, dbg); + + if (SCHEME_ALLOW_QUERY (uri)) { + _uri_parse_query (uri, &pos, end, dbg); + } + + if (SCHEME_ALLOW_FRAGMENT (uri)) { + _uri_parse_fragment (uri, &pos, end, dbg); + } + + goto end; + +err: + uriFree (uri); + uri = NULL; + +end: + + return uri; +} + +void +uriFree (struct uri* uri) +{ + if (uri == NULL) { + return; + } + if (NULL != uri->scheme) { + free (uri->scheme); + } + if (NULL != uri->userinfo) { + free (uri->userinfo); + } + if (NULL != uri->authority) { + free (uri->authority); + } + if (NULL != uri->user) { + free (uri->user); + } + if (NULL != uri->pass) { + free (uri->pass); + } + if (NULL != uri->host) { + free (uri->host); + } + if (NULL != uri->path) { + free (uri->path); + } + if (NULL != uri->query) { + free (uri->query); + } + if (NULL != uri->fragment) { + free (uri->fragment); + } + + free (uri); +} + +int +uriIsIPv4 (const char* s, int size, char** err) +{ + int octets = 0; + const char* currentOctetStart = s; + + char prev = 0; + + for (int i = 0; i <= size; i++) { + if (prev == 0) { + if (IS_DIGIT (*(s + i))) { + currentOctetStart = (s + i); + prev = 'd'; + continue; + } + + if (*(s + i) == '.') { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : can't start with a single '.'"); + } + return 0; + } + } + + if (prev == 'p') { + if (IS_DIGIT (*(s + i))) { + currentOctetStart = (s + i); + prev = 'd'; + continue; + } + + if (*(s + i) == '.') { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : can't have successive '.'"); + } + return 0; + } + } + + if (prev == 'd') { + if (IS_DIGIT (*(s + i))) { + prev = 'd'; + continue; + } + + if (i == size || *(s + i) == '.') { // period + int octet = atoi (currentOctetStart); + if (octet > 255) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : octet %i is too high : %.*s", (octets), (int)((s + i) - currentOctetStart), currentOctetStart); + } + return 0; + } + + if (i + 1 == size) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : can't end with a single '.'"); + } + return 0; + } + + prev = 'p'; + octets++; + continue; + } + } + + if (i == size) { + break; + } + + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : illegal char '%c' (0x%02x)", *(s + i), *(s + i)); + } + return 0; + } + + if (octets > 4) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : too many octets"); + } + return 0; + } + if (octets < 4) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "IPV4 parser error : not enough octets"); + } + return 0; + } + + return 1; +} + +int +uriIsIPv6 (const char* s, int size, char** err) +{ + int segmentCount = 0; + int emptySegmentCount = 0; + int curSegmentLength = 0; + int ipv4portion = 0; + + int loopback = 0; + + const char* curSegmentStart = s; + + char prev = 0; + + for (int i = 0; i <= size; i++) { + if (prev == 0) { + if (IS_HEX (*(s + i))) { + segmentCount++; + curSegmentStart = s + i; + curSegmentLength++; + prev = 'h'; // hex + + if (loopback >= 0) { + if (!IS_DIGIT (*(s + i))) { + loopback = -1; + } else { + loopback += (*(s + i) - '0'); //atoi(*(s+i)); + } + } + + continue; + } + + if (*(s + i) == ':' && *(s + (i + 1)) == ':') { + emptySegmentCount++; + prev = 'e', // empty + i++; + continue; + } + + if (*(s + i) == ':') { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "can't start with a single ':'"); + } + return 0; + } + } + + if (prev == 'h') { /* hex */ + + if (IS_HEX (*(s + i))) { + curSegmentLength++; + + if (loopback >= 0) { + if (!IS_DIGIT (*(s + i))) { + loopback = -1; + } else { + loopback += (*(s + i) - '0'); + } + } + + continue; + } + + if (*(s + i) == '.') { /* period */ + int octet = atoi (curSegmentStart); + if (octet > 255) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "ipv4 portion octet %i is too high : %.*s", (ipv4portion), curSegmentLength, curSegmentStart); + } + return 0; + } + // debug( "%i", octet ); + prev = 'p'; + ipv4portion++; + continue; + } + + if (i == size || *(s + i) == ':') { + if (curSegmentLength > 4) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "segment %i is too long : %.*s", (segmentCount - 1), curSegmentLength, curSegmentStart); + } + return 0; + } + /* here we can parse segment */ + curSegmentStart = NULL; + curSegmentLength = 0; + + if (i < size && *(s + (i + 1)) == ':') { + emptySegmentCount++; + prev = 'e', /* empty "::" */ + i++; + } else if (i + 1 == size) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "can't end with a single ':'"); + } + return 0; + } else { + prev = 'c'; /* colon ":" */ + } + continue; + } + } + + if (prev == 'e' || prev == 'c') { /* empty or colon */ + + if (IS_HEX (*(s + i))) { + segmentCount++; + curSegmentStart = s + i; + curSegmentLength++; + prev = 'h'; /* hex */ + + if (loopback >= 0) { + if (!IS_DIGIT (*(s + i))) { + loopback = -1; + } else { + loopback += (*(s + i) - '0'); + } + } + + continue; + } + + if (*(s + i) == ':') { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "can't have more than two successive ':'"); + } + return 0; + } + } + + if (prev == 'p') { + if (IS_DIGIT (*(s + i))) { + curSegmentStart = s + i; + prev = 'd'; + continue; + } + + if (*(s + i) == '.') { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "can't have successive '.'"); + } + return 0; + } + } + + if (prev == 'd') { + if (IS_DIGIT (*(s + i))) { + prev = 'd'; + continue; + } + + if (i == size || *(s + i) == '.') { /* period */ + int octet = atoi (curSegmentStart); + if (octet > 255) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "ipv4 portion octet %i is too high : %.*s", (ipv4portion), curSegmentLength, curSegmentStart); + } + return 0; + } + + // debug( "%i", octet ); + + if (i + 1 == size) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "can't end with a single '.'"); + } + return 0; + } + + prev = 'p'; + ipv4portion++; + continue; + } + } + + if (i == size) { + break; + } + + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "illegal char '%c' (0x%02x)", *(s + i), *(s + i)); + } + + return 0; + } + + // debug( "segments : %i", segmentCount ); + // debug( "empty segments : %i", emptySegmentCount ); + // debug( "ipv4portion : %i", ipv4portion ); + + if (ipv4portion > 4) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "too many octets in ipv4 portion"); + } + return 0; + } + if (ipv4portion > 0 && ipv4portion < 4) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "not enough octets in ipv4 portion"); + } + return 0; + } + if (emptySegmentCount + (segmentCount / 2) + ipv4portion > 8) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "too many segments"); + } + return 0; + } + + if (emptySegmentCount == 0 && (((ipv4portion / 2) + segmentCount) < 8)) { + if (err) { + _laaf_util_snprintf_realloc (err, NULL, 0, "not enough segments"); + } + return 0; + } + + // debug( "LOCALHOST >>>>>>> %i", loopback ); + + /* + * 1: valid ipv6 address + * 2: valid ipv6 address and is loopback + */ + + return (loopback == 1) ? 2 : 1; +} + +static void +_uri_scheme2schemeType (struct uri* uri) +{ + if (strcmp (uri->scheme, "afp") == 0) { + uri->scheme_t = URI_SCHEME_T_AFP; + } else if (strcmp (uri->scheme, "cifs") == 0) { + uri->scheme_t = URI_SCHEME_T_CIFS; + } else if (strcmp (uri->scheme, "data") == 0) { + uri->scheme_t = URI_SCHEME_T_DATA; + } else if (strcmp (uri->scheme, "dns") == 0) { + uri->scheme_t = URI_SCHEME_T_DNS; + } else if (strcmp (uri->scheme, "file") == 0) { + uri->scheme_t = URI_SCHEME_T_FILE; + } else if (strcmp (uri->scheme, "ftp") == 0) { + uri->scheme_t = URI_SCHEME_T_FTP; + } else if (strcmp (uri->scheme, "http") == 0) { + uri->scheme_t = URI_SCHEME_T_HTTP; + } else if (strcmp (uri->scheme, "https") == 0) { + uri->scheme_t = URI_SCHEME_T_HTTPS; + } else if (strcmp (uri->scheme, "imap") == 0) { + uri->scheme_t = URI_SCHEME_T_IMAP; + } else if (strcmp (uri->scheme, "irc") == 0) { + uri->scheme_t = URI_SCHEME_T_IRC; + } else if (strcmp (uri->scheme, "mailto") == 0) { + uri->scheme_t = URI_SCHEME_T_MAILTO; + } else if (strcmp (uri->scheme, "nfs") == 0) { + uri->scheme_t = URI_SCHEME_T_NFS; + } else if (strcmp (uri->scheme, "pop") == 0) { + uri->scheme_t = URI_SCHEME_T_POP; + } else if (strcmp (uri->scheme, "rtsp") == 0) { + uri->scheme_t = URI_SCHEME_T_RTSP; + } else if (strcmp (uri->scheme, "sftp") == 0) { + uri->scheme_t = URI_SCHEME_T_SFTP; + } else if (strcmp (uri->scheme, "sip") == 0) { + uri->scheme_t = URI_SCHEME_T_SIP; + } else if (strcmp (uri->scheme, "smb") == 0) { + uri->scheme_t = URI_SCHEME_T_SMB; + } else if (strcmp (uri->scheme, "ssh") == 0) { + uri->scheme_t = URI_SCHEME_T_SSH; + } else if (strcmp (uri->scheme, "tel") == 0) { + uri->scheme_t = URI_SCHEME_T_TEL; + } else if (strcmp (uri->scheme, "telnet") == 0) { + uri->scheme_t = URI_SCHEME_T_TELNET; + } else { + uri->scheme_t = URI_SCHEME_T_UNKNOWN; + } +} + +static int +_laaf_util_snprintf_realloc (char** str, size_t* size, size_t offset, const char* format, ...) +{ + size_t tmpsize = 0; + + if (!size) { + size = &tmpsize; + } + + int retval, needed; + va_list ap; + + va_start (ap, format); + + while (0 <= (retval = vsnprintf ((*str) + offset, (*size) - offset, format, ap)) && (int64_t) ((*size) - offset) < (needed = retval + 1)) { + va_end (ap); + + *size *= 2; + + if ((int64_t) ((*size) - offset) < needed) + *size = needed; + + char* p = realloc (*str, *size); + + if (p) { + *str = p; + } else { + free (*str); + *str = NULL; + *size = 0; + return -1; + } + + va_start (ap, format); + } + + va_end (ap); + + return retval; +} + +#ifdef BUILD_URI_TEST + +static int +_uri_cmp (const struct uri* a, const struct uri* b) +{ + int differenciesCount = 0; + + if (a == NULL || b == NULL) { + return -1; + } + + // if ( (strcmp((a->scheme) ? a->scheme : "", (b->scheme) ? b->scheme : "") != 0 ) ) { + // differenciesCount++; + // } + if ((strcmp ((a->userinfo) ? a->userinfo : "", (b->userinfo) ? b->userinfo : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->user) ? a->user : "", (b->user) ? b->user : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->pass) ? a->pass : "", (b->pass) ? b->pass : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->host) ? a->host : "", (b->host) ? b->host : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->path) ? a->path : "", (b->path) ? b->path : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->query) ? a->query : "", (b->query) ? b->query : "") != 0)) { + differenciesCount++; + } + if ((strcmp ((a->fragment) ? a->fragment : "", (b->fragment) ? b->fragment : "") != 0)) { + differenciesCount++; + } + if (a->port != b->port) { + differenciesCount++; + } + if (a->scheme_t != b->scheme_t) { + differenciesCount++; + } + if (a->flags != b->flags) { + differenciesCount++; + } + + return differenciesCount; +} + +static void +_uri_dump_diff (struct uri* a, struct uri* b, int totalDifferencies) +{ + int differenciesCount = 0; + + if (a == NULL || b == NULL) { + return; + } + + // if ( (strcmp((a->scheme) ? a->scheme : "", (b->scheme) ? b->scheme : "") != 0 ) ) { + // printf(" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .scheme : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->scheme, b->scheme ); + // } + if ((strcmp ((a->userinfo) ? a->userinfo : "", (b->userinfo) ? b->userinfo : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .userinfo : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->userinfo, b->userinfo); + } + if ((strcmp ((a->user) ? a->user : "", (b->user) ? b->user : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .user : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->user, b->user); + } + if ((strcmp ((a->pass) ? a->pass : "", (b->pass) ? b->pass : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .pass : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->pass, b->pass); + } + if ((strcmp ((a->host) ? a->host : "", (b->host) ? b->host : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .host : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->host, b->host); + } + if ((strcmp ((a->path) ? a->path : "", (b->path) ? b->path : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .path : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->path, b->path); + } + if ((strcmp ((a->query) ? a->query : "", (b->query) ? b->query : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .query : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->query, b->query); + } + if ((strcmp ((a->fragment) ? a->fragment : "", (b->fragment) ? b->fragment : "") != 0)) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .fragment : \"%s\" (expected: \"%s\")\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->fragment, b->fragment); + } + + if (a->port != b->port) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .port : %i (expected: %i)\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->port, b->port); + } + if (a->scheme_t != b->scheme_t) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .scheme_t : %i (expected: %i)\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->scheme_t, b->scheme_t); + } + if (a->flags != b->flags) { + printf (" \x1b[38;5;242m\u2502\x1b[0m \x1b[38;5;124m%s .flags : %i (expected: %i)\n", (++differenciesCount < totalDifferencies) ? "\u251c\u2500\u2500\u25fb" : "\u2514\u2500\u2500\u25fb", a->flags, b->flags); + } +} + +static int +_uri_test (const char* uristr, enum uri_option optflags, struct uri expectedRes, int line) +{ + struct uri* uri = uriParse (uristr, optflags); + + int differenciesCount = 0; + + if ((differenciesCount = _uri_cmp (uri, &expectedRes)) == 0) { + printf ("\x1b[38;5;242m"); // dark gray + printf ("%05i", line); + printf ("\x1b[0m"); + + printf ("\x1b[38;5;242m %s \x1b[0m", "\u2502"); + + printf ("\x1b[38;5;120m"); // green + printf ("[ok] "); + printf ("\x1b[0m"); + + printf ("\x1b[38;5;242m"); // dark gray + printf ("%s", uristr); + printf ("\x1b[0m"); + + printf ("\n"); + } else { + printf ("\x1b[38;5;124m"); // red + printf ("%05i", line); + printf ("\x1b[0m"); + + printf ("\x1b[38;5;242m %s \x1b[0m", "\u2502"); + + printf ("\x1b[38;5;124m"); // red + printf ("[er] "); + printf ("\x1b[0m"); + + printf ("\x1b[38;5;242m"); // dark gray + printf ("%s", uristr); + printf ("\x1b[0m"); + + printf ("\n"); + + printf ("\x1b[38;5;124m"); // red + _uri_dump_diff (uri, &expectedRes, differenciesCount); + printf ("\x1b[0m"); + + printf (" \x1b[38;5;242m\u2502\x1b[0m\n"); + } + + uriFree (uri); + + return differenciesCount; +} + +int +main (void) +{ + int rc = 0; + + // rc += _uri_test( "", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .host = NULL, .port = 0, .path = NULL, .query = NULL, .fragment = NULL }, __LINE__ ); + rc += _uri_test ("https://www.server.com", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://user:pass@www.server.com", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .userinfo = "user:pass", .user = "user", .pass = "pass", .host = "www.server.com", .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("HTTPS://www.server.com", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("hTtPs://www.server.com", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:8080", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 8080, .path = NULL, .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:8080?foo=bar", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 8080, .path = NULL, .query = "foo=bar", .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:8080#anchor", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 8080, .path = NULL, .query = NULL, .fragment = "anchor", .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/?foo=bar", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/", .query = "foo=bar", .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/////?foo=bar", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/", .query = "foo=bar", .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com///////", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com?foo=bar", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = NULL, .query = "foo=bar", .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com#anchor", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = NULL, .query = NULL, .fragment = "anchor", .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/path/to/file.html?foo=bar&foo2=bar2#anchor", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/path/to/file.html", .query = "foo=bar&foo2=bar2", .fragment = "anchor", .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:80/", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 80, .path = "/", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:/", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com:", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + + rc += _uri_test ("https://[8:3:1:2:1234:5678::]:8080/ipv6", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "8:3:1:2:1234:5678::", .port = 8080, .path = "/ipv6", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 }, __LINE__); + rc += _uri_test ("https://[2001:db8:0:85a3::ac1f:8001]:8080/ipv6", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "2001:db8:0:85a3::ac1f:8001", .port = 8080, .path = "/ipv6", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 }, __LINE__); + rc += _uri_test ("https://user:pass@[2001:db8:3333:4444:5555:6666:1.2.3.4]:8080/ipv6", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .userinfo = "user:pass", .user = "user", .pass = "pass", .host = "2001:db8:3333:4444:5555:6666:1.2.3.4", .port = 8080, .path = "/ipv6", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 }, __LINE__); + rc += _uri_test ("https://192.168.0.1:8080/ipv4", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "192.168.0.1", .port = 8080, .path = "/ipv4", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV4 }, __LINE__); + rc += _uri_test ("https://127.0.0.1:8080/ipv4loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "127.0.0.1", .port = 8080, .path = "/ipv4loopback", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV4 | URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("https://localhost:8080/loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "localhost", .port = 8080, .path = "/loopback", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("https://[0:0:0:0:0:0:0:1]:8080/ipv6loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "0:0:0:0:0:0:0:1", .port = 8080, .path = "/ipv6loopback", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 | URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("https://[::0:0:0:1]:8080/ipv6loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "::0:0:0:1", .port = 8080, .path = "/ipv6loopback", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 | URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("https://[::0:0000:0:001]:8080/ipv6loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "::0:0000:0:001", .port = 8080, .path = "/ipv6loopback", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 | URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("https://[::1]:8080/ipv6loopback", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "::1", .port = 8080, .path = "/ipv6loopback", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV6 | URI_T_LOCALHOST }, __LINE__); + + rc += _uri_test ("https://user:pass@192.168.0.1:8080/ipv4", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .userinfo = "user:pass", .user = "user", .pass = "pass", .host = "192.168.0.1", .port = 8080, .path = "/ipv4", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV4 }, __LINE__); + + rc += _uri_test ("file://///C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file:C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file:/C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file:///C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file://?/C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file://./C:/windows/path", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/windows/path", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + + // Examples from AAF files external essences + rc += _uri_test ("file:///C:/Users/username/Downloads/441-16b.wav", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/Users/username/Downloads/441-16b.wav", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file://?/E:/ADPAAF/Sequence A Rendu.mxf", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "E:/ADPAAF/Sequence A Rendu.mxf", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file:////C:/Users/username/Desktop/TEST2977052.aaf", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "C:/Users/username/Desktop/TEST2977052.aaf", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file://localhost/Users/username/Music/fonk_2_3#04.wav", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = "localhost", .port = 0, .path = "/Users/username/Music/fonk_2_3#04.wav", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + rc += _uri_test ("file://10.87.230.71/mixage/DR2/Avid MediaFiles/MXF/1/3572607.mxf", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = "10.87.230.71", .port = 0, .path = "/mixage/DR2/Avid MediaFiles/MXF/1/3572607.mxf", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_IPV4 }, __LINE__); + rc += _uri_test ("file:///_system/Users/username/pt2MCCzmhsFRHQgdgsTMQX.mxf", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_FILE, .host = NULL, .port = 0, .path = "/_system/Users/username/pt2MCCzmhsFRHQgdgsTMQX.mxf", .query = NULL, .fragment = NULL, .flags = URI_T_LOCALHOST }, __LINE__); + + // URL Percent Decoding + rc += _uri_test ("https://www.server.com/NON_DECODING/%C2%B0%2B%29%3D%C5%93%21%3A%3B%2C%3F.%2F%C2%A7%C3%B9%2A%24%C2%B5%C2%A3%7D%5D%E2%80%9C%23%7B%5B%7C%5E%40%5D%3C%3E", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/NON_DECODING/%C2%B0%2B%29%3D%C5%93%21%3A%3B%2C%3F.%2F%C2%A7%C3%B9%2A%24%C2%B5%C2%A3%7D%5D%E2%80%9C%23%7B%5B%7C%5E%40%5D%3C%3E", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/DECODING/%C2%B0%2B%29%3D%C5%93%21%3A%3B%2C%3F.%2F%C2%A7%C3%B9%2A%24%C2%B5%C2%A3%7D%5D%E2%80%9C%23%7B%5B%7C%5E%40%5D%3C%3E", URI_OPT_DECODE_ALL, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .host = "www.server.com", .port = 0, .path = "/DECODING/°+)=œ!:;,?./§ù*$µ£}]“#{[|^@]<>", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + rc += _uri_test ("https://www.server.com/DECODING_UTF8/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E7%B2%BE%E5%BA%A6%E7%B7%A8%E9%9B%86", URI_OPT_DECODE_ALL, (struct uri){ .scheme_t = URI_SCHEME_T_HTTPS, .userinfo = NULL, .user = NULL, .pass = NULL, .host = "www.server.com", .port = 0, .path = "/DECODING_UTF8/サンプル精度編集", .query = NULL, .fragment = NULL, .flags = URI_T_HOST_REGNAME }, __LINE__); + + // Examples from https://en.wikipedia.org/wiki/Uniform_Resource_Identifier + rc += _uri_test ("tel:+1-816-555-1212", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_TEL, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = "+1-816-555-1212", .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__); + rc += _uri_test ("mailto:John.Doe@example.com", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_MAILTO, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = "John.Doe@example.com", .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__); + rc += _uri_test ("urn:oasis:names:specification:docbook:dtd:xml:4.1.2", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = "oasis:names:specification:docbook:dtd:xml:4.1.2", .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__); + rc += _uri_test ("ldap://[2001:db8::7]/c=GB?objectClass?one", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .userinfo = NULL, .user = NULL, .pass = NULL, .host = "2001:db8::7", .port = 0, .path = "/c=GB", .query = "objectClass?one", .fragment = NULL, .flags = URI_T_HOST_IPV6 }, __LINE__); + rc += _uri_test ("news:comp.infosystems.www.servers.unix", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = "comp.infosystems.www.servers.unix", .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__); + + // rc += _uri_test( "xxxxxxxx", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__ ); + // rc += _uri_test( "xxxxxxxx", URI_OPT_NONE, (struct uri){ .scheme_t = URI_SCHEME_T_UNKNOWN, .userinfo = NULL, .user = NULL, .pass = NULL, .host = NULL, .port = 0, .path = NULL, .query = NULL, .fragment = NULL, .flags = 0 }, __LINE__ ); + + return rc; +} + +#endif // BUILD_URI_TEST diff --git a/libs/aaf/aaf/AAFClass.h b/libs/aaf/aaf/AAFClass.h new file mode 100644 index 0000000000..d0ca1ecabb --- /dev/null +++ b/libs/aaf/aaf/AAFClass.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFClass_h__ +#define __AAFClass_h__ + +/** + * @brief AAF core functions. + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + */ + +#include +#include +#include + +#include "aaf/AAFCore.h" +#include "aaf/AAFTypes.h" + +#define foreachClass(Class, Classes) \ + for (Class = Classes; Class != NULL; Class = Class->next) + +#define foreachClassInheritance(Class, Classes) \ + for (Class = Classes; Class != NULL; Class = Class->Parent) + +#define foreachPropertyDefinition(PDef, PDefs) \ + for (PDef = PDefs; PDef != NULL; PDef = PDef->next) + +int +aafclass_classExists (AAF_Data* aafd, aafUID_t* ClassID); + +aafClass* +aafclass_defineNewClass (AAF_Data* aafd, const aafUID_t* id, uint8_t isConcrete, aafClass* parent); + +aafClass* +aafclass_getClassByID (AAF_Data* aafd, const aafUID_t* id); + +aafPropertyDef* +aafclass_getPropertyDefinitionByID (aafClass* Classes, aafPID_t PID); + +void +aafclass_printClasses (aafClass* Class, int depth); // TODO move to AAFDump ? + +int +aafclass_setDefaultClasses (AAF_Data* aafd); + +#endif // ! __AAFClass_h__ diff --git a/libs/aaf/aaf/AAFCore.h b/libs/aaf/aaf/AAFCore.h new file mode 100644 index 0000000000..0e081197b1 --- /dev/null +++ b/libs/aaf/aaf/AAFCore.h @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFCore_h__ +#define __AAFCore_h__ + +/** + * @file AAFCore/AAFCore.h + * @brief Retrieves the AAF Objects Tree from the Compound File Binary. + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + * + * @ingroup AAFCore + * @addtogroup AAFCore + * @brief Retrieves the AAF Objects Tree from the Compound File Binary. + * + * The AAF file structure is based on the Compound File Binary, implemented by LibCFB + * and defined at https://www.amwa.tv/projects/MS-03.shtml + * + * The specifications of the low-level AAF can be found at https://amwa.tv/projects/MS-02.shtml + * + * The specifications of the overall AAF and standard Classes / Properties can be found at + * https://amwa.tv/projects/MS-01.shtml + * + * This is the core of the libAAF library. AAFCore is intendend to : + * - Define the standard AAF classes and properties at run time, + * - retrieve potential custom classes and properties out of the MetaDictionary, + * - retrieve the entire object tree and their properties out of the CFB Tree, + * - provide functions to navigate in the tree and access objects and properties. + * + * Therefore, AAFCore makes a bridge between the low-level Compound File Binary and the + * high level AAFIface, which is used to interpret objects and thus retrieve usable data. + * + * Even though AAFCore can be used as is, it is recommended for complex operations + * like essences and clips retrieval, to use AAFIface. + * + * ### Usage + * + * In order to use libAAF, you should start by allocating AAF_Data with aaf_alloc(), then + * you can load a file by calling aaf_load_file(). aaf_load_file() will not load the entire + * file to memory, but will instead parse the CFB Tree and set AAF_Data accordingly. + * + * @code + * AAF_Data *aafd = aaf_alloc(); + * aaf_load_file( aafd, "./path/to/file.aaf" ); + * @endcode + * + * Then, you can access the object tree thanks to the access functions, or use the AAFIface + * to extract usable data through a convenient interface. + * + * @code + * // TODO + * @endcode + * + * Once you're done, you can close the file and free the AAF_Data structure by calling + * aaf_release( &aafd ); + * + * @code + * aaf_release( &aafd ); + * @endcode + * + * @{ + */ + +#include "aaf/AAFTypes.h" +#include "aaf/LibCFB.h" + +/** + * Possible values for aafPropertyDef.isReq. + */ + +enum aafPropertyIsRequired_e { + PROP_REQUIRED = 1, + PROP_REQ = 1, + PROP_OPTIONAL = 0, + PROP_OPT = 0 +}; + +/** + * This structure defines a Class property, with a property ID + * and tells if that property is either #REQUIRED or #OPTIONAL. + * This structure is to be added to an aafClass.Properties list + * with the attachNewProperty() macro, and to be pointed to by + * the aafProperty.def field of each parsed property. + */ + +typedef struct aafPropertyDefinition { + /** + * Specifies the property ID. + * + * All the standard IDs can be found in AAFDefs/AAFPropertyIDs.h. + */ + + uint16_t pid; + + /** + * Tells if that property is either #REQUIRED or #OPTIONAL. + */ + + aafBoolean_t isReq; + + aafBoolean_t meta; + + wchar_t* name; + + /* + * Looks like nobody cares about AAF standard TypeDefinition. All observed files + * had incorrect values for Type's Name and Identification, even Avid's files. + * Thus, PDef->type should NOT be trusted + */ + + aafUID_t type; // TODO: Should be set by attachNewProperty() in AAFClass.c + + /** + * Pointer to the next aafPropertyDef in the list. + */ + + struct aafPropertyDefinition* next; + +} aafPropertyDef; + +/** + * Possible values for aafClass.isConcrete. + */ + +enum aafClassIsConcrete_e { + ABSTRACT = 0, + ABS = 0, + CONCRETE = 1, + CON = 1 +}; + +/** + * This structure defines an AAF Class. + * + * An AAF Class can be identified thanks to its ClassID. + * + * An AAF Class holds some properties. + * + * An AAF Class can inherit other Classes properties from + * its parents. + * + * An AAF Class can be either a #CONCRETE or an #ABSTRACT + * Class. It is a #CONCRETE Class if it can be directly + * retrieved from the Compound File Nodes Tree as an object. + * Else, it is an #ABSTRACT Class and has to be inherited by + * another Class for its properties to be retrieved. + */ + +typedef struct aafclass { + /** + * The ClassID of the Class. When parsing, the ClassID + * correspond to the cfbNode._clsId. + * Note that the CLSID and aafUID_t types are binary + * compatible. + * + * All the standard ClassIDs can be found in AAFDefs/AAFClassDefUIDs.h. + */ + + const aafUID_t* ID; + + /** + * Tells if the Class is either #CONCRETE or #ABSTRACT. + * + * A Class is #CONCRETE if it can be retrieved as an + * object. Else, a Class is #ABSTRACT if it can't be + * directly retrieved and can only be inherited by + * another Class, so only its memebers can be retrieved. + */ + + aafBoolean_t isConcrete; + + /** + * Pointer to a list of aafPropertyDef structs. + * + * These aafPropertyDef define the properties + * owned by the Class. + */ + + aafPropertyDef* Properties; + + /** + * Pointer to the Parent Class. If this Class has no + * Parent (is root), then the pointer shall be NULL. + */ + + struct aafclass* Parent; + + aafBoolean_t meta; + + wchar_t* name; // this is set at runtime + + /** + * Pointer to the next Class in the AAF_Data.Class list. + */ + + struct aafclass* next; + +} aafClass; + +/** + * This structure represents a property once it has been parsed. + * + * This structure is to be added to an aafObject.Properties list. + */ + +typedef struct aafProperty { + /** + * Specifies the property ID. The pid shall be the same as in the + * #def aafPropertyDef structure. + * + * All the standard IDs can be found in AAFDefs/AAFPropertyIDs.h. + */ + + uint16_t pid; + + /** + * The _storedForm identifies the “type” of representation chosen + * for this property. This field describes how the property value + * should be interpreted. Note that the stored form described here + * is not the data type of the property value, rather it is the + * type of external representation employed. The data type of a + * given property value is implied by the property ID. + * + * Can take one of the value from #aafStoredForm_e enum. + */ + + uint16_t sf; + + /** + * Holds a pointer to the corresponding property definition + * aafPropertyDef struct. + */ + + aafPropertyDef* def; + + /** + * The length, in bytes, of the #val property value. + */ + + uint16_t len; + + /** + * The actual property value, of #len length. + */ + + void* val; + + /** + * Pointer to the next property in an aafObject.Properties list. + */ + + struct aafProperty* next; + +} aafProperty; + +/** + * This structure represents an AAF Object, once it has been parsed. + * + * This structure is to be added to the AAF_Data.Objects list. + * + * Each aafObject correspond to a Compound File Tree Node. + * + * Each aafObject property correspond to a property entry in this + * Node/properties stream. + */ + +typedef struct aafObject { + /** + * Pointer to the corresponding Class, in the AAF_Data.Class list. + */ + + aafClass* Class; + + /** + * Pointer to the corresponding Node in the Compound File Tree. + */ + + cfbNode* Node; + + /** + * The name of the Node in the Compound File Tree : cfbNode._ab. + */ + + wchar_t Name[CFB_NODE_NAME_SZ]; + + /** + * Pointer to an aafProperty list. This list holds the retrieved + * Object properties. + */ + + aafProperty* Properties; + + /** + * Pointer to an aafStrongRefSetHeader_t struct. + * + * This pointer keeps track of the Index Header, when the + * Object belongs to either a Set or a Vector, else, it shall + * remain NULL. + * + * Here we can use an aafStrongRefSetHeader_t struct to hold + * an aafStrongRefVectorHeader_t, because both structs begin + * with the same bytes, exept the first one is bigger. So in + * case of a Vector, the remaining bytes will simply remain + * NULL. + */ + + aafStrongRefSetHeader_t* Header; + + /** + * Pointer to an aafStrongRefSetEntry_t struct. + * + * This pointer keeps track of the Index Entry, when the + * Object belongs to either a Set or a Vector, else, it shall + * remain NULL. + * + * Here we can use an aafStrongRefSetEntry_t struct to hold + * an aafStrongRefVectorEntry_t, because both structs begin + * with the same bytes, exept the first one is bigger. So in + * case of a Vector, the remaining bytes will simply remain + * NULL. + */ + + aafStrongRefSetEntry_t* Entry; + + /** + * Pointer to the Parent Object, that is the upper "Node" in + * the Compound File Tree. + */ + + struct aafObject* Parent; + + /** + * Pointer to the next Object in Set/Vector + */ + + struct aafObject* next; + + struct aafObject* prev; + + /** + * Pointer to the next Object in the AAF_Data.Objects list. + */ + + struct aafObject* nextObj; + + struct _aafData* aafd; // only to access aafd->verb + +} aafObject; + +/** + * This structure is the main structure when using LibAAF. + * + * It holds a pointer to the CFB_Data structure for file + * access, a pointer to the AAF Classes list, a pointer to + * the AAF Objects list and a bunch of pointers to some + * key Objects in the AAF Objects Tree called shortcuts. + * + * Those shortcuts allows to quickly retrieve some AAF + * key Objects without the need to parse the tree everytime. + */ + +typedef struct _aafData { + /** + * Pointer to the LibCFB CFB_Data structure. + */ + + CFB_Data* cfbd; + + /** + * Pointer to the AAF Classes list. + */ + + aafClass* Classes; + + /** + * Pointer to the AAF Object list. + * + * @note This list is intended to keep track of all the allocated Objects, not for + * parsing. For tree access, the AAF_Data.Root pointer should be used. + */ + + aafObject* Objects; + + struct Header { + aafObject* obj; + + int16_t ByteOrder; + aafTimeStamp_t* LastModified; + aafVersionType_t* Version; + uint32_t ObjectModelVersion; + const aafUID_t* OperationalPattern; + // EssenceContainers; TODO AUIDSet_t + // DescriptiveSchemes: TODO AUIDSet_t + + } Header; + + struct Identification { + aafObject* obj; + + wchar_t* CompanyName; + wchar_t* ProductName; + aafProductVersion_t* ProductVersion; + wchar_t* ProductVersionString; + aafUID_t* ProductID; + aafTimeStamp_t* Date; + aafProductVersion_t* ToolkitVersion; + wchar_t* Platform; + aafUID_t* GenerationAUID; + + } Identification; + + /** + * Pointer to the first Root Object, that is to the the top of the Tree. + */ + + aafObject* Root; + + /** + * (Shortcut) pointer to the Header Object in the Tree. + */ + + // aafObject *Header; + + /** + * (Shortcut) pointer to the MetaDictionary Object in the Tree. + */ + + aafObject* MetaDictionary; + + /** + * (Shortcut) pointer to the ClassDefinition Object in the Tree. + */ + + aafObject* ClassDefinition; + + /** + * (Shortcut) pointer to the TypeDefinition Object in the Tree. + */ + + aafObject* TypeDefinition; + + /** + * (Shortcut) pointer to the Identification Object in the Tree. + */ + + // aafObject *Identification; + + /** + * (Shortcut) pointer to the Content Object in the Tree. + */ + + aafObject* Content; + + /** + * (Shortcut) pointer to the Dictionary Object in the Tree. + */ + + aafObject* Dictionary; + + /** + * (Shortcut) pointer to the Mobs Object in the Tree. + */ + + aafObject* Mobs; + + /** + * (Shortcut) pointer to the EssenceData Object in the Tree. + */ + + aafObject* EssenceData; + + /** + * (Shortcut) pointer to the OperationDefinition Object in the Tree. + */ + + aafObject* OperationDefinition; + + /** + * (Shortcut) pointer to the ParameterDefinition Object in the Tree. + */ + + aafObject* ParameterDefinition; + + /** + * (Shortcut) pointer to the DataDefinition Object in the Tree. + */ + + aafObject* DataDefinition; + + /** + * (Shortcut) pointer to the PluginDefinition Object in the Tree. + */ + + aafObject* PluginDefinition; + + /** + * (Shortcut) pointer to the CodecDefinition Object in the Tree. + */ + + aafObject* CodecDefinition; + + /** + * (Shortcut) pointer to the ContainerDefinition Object in the Tree. + */ + + aafObject* ContainerDefinition; + + /** + * (Shortcut) pointer to the InterpolationDefinition Object in the Tree. + */ + + aafObject* InterpolationDefinition; + + /** + * (Shortcut) pointer to the KLVDataDefinition Object in the Tree. + */ + + aafObject* KLVDataDefinition; + + /** + * (Shortcut) pointer to the TaggedValueDefinition Object in the Tree. + */ + + aafObject* TaggedValueDefinition; + + struct dbg* dbg; + +} AAF_Data; + +/** + * Compares two aafUID_t, returns 1 if equal or 0 otherwise. + * https://github.com/Ardour/ardour/pull/805#issuecomment-1595788696 + */ + +#define aafUIDCmp(auid1, auid2) \ + ((auid1) != NULL && \ + ((auid2)) != NULL && \ + (auid1)->Data1 == (auid2)->Data1 && \ + (auid1)->Data2 == (auid2)->Data2 && \ + (auid1)->Data3 == (auid2)->Data3 && \ + (auid1)->Data4[0] == (auid2)->Data4[0] && \ + (auid1)->Data4[1] == (auid2)->Data4[1] && \ + (auid1)->Data4[2] == (auid2)->Data4[2] && \ + (auid1)->Data4[3] == (auid2)->Data4[3] && \ + (auid1)->Data4[4] == (auid2)->Data4[4] && \ + (auid1)->Data4[5] == (auid2)->Data4[5] && \ + (auid1)->Data4[6] == (auid2)->Data4[6] && \ + (auid1)->Data4[7] == (auid2)->Data4[7]) + +/** + * Compares two aafMobID_t, returns 1 if equal or 0 otherwise. + */ + +#define aafMobIDCmp(mobID1, mobID2) \ + ((mobID1) != NULL && (mobID2) != NULL && memcmp ((mobID1), (mobID2), sizeof (aafMobID_t)) == 0) + +/** + * Compares two aafSlotID_t, returns 1 if equal or 0 otherwise. + * NOTE: is unused. + */ + +#define aafSlotIDCmp(slotID1, slotID2) \ + ((slotID1) == (slotID2)) + +/** + * Converts an aafRational_t to a float number. + */ + +#define aafRationalToFloat(r) \ + (((r).denominator == 0) ? 0 : ((float)(r).numerator / (r).denominator)) + +/** + * Converts an aafRational_t to a int64 number. + * NOTE: is unused. + */ + +#define aafRationalToint64(r) \ + (((r).denominator == 0) ? 0 : (int64_t) ((r).numerator / (r).denominator)) + +/** + * @name Initialisation functions + * @{ + */ + +/** + * Allocates a new AAF_Data structure. + * + * @return A pointer to the newly allocated structure. + */ + +AAF_Data* +aaf_alloc (struct dbg* dbg); + +/** + * Loads an AAF file and sets the AAF_Data sructure accordingly. + * + * @param aafd Pointer to the AAF_Data structure. + * @param file Pointer to a null terminated string holding the filepath. + * + * @return 0 on success\n + * 1 on failure + */ + +int +aaf_load_file (AAF_Data* aafd, + const char* file); + +/** + * @} + */ + +/** + * @name Release function + * @{ + */ + +/** + * Releases the CFB_Data structure, fclose() the file and frees the AAF_Data structure. + * + * @param aafd Pointer to the AAF_Data structure. + */ + +void +aaf_release (AAF_Data** aafd); + +/** + * @} + */ + +/** + * @name Access functions + * @{ + */ + +/** + * Retrieves, for a given Object, its path in the Compound File Binary Tree. + * + * @note It is the caller responsability to free the returned pointer. + * + * @param Obj Pointer to the aafObject. + * + * @return Pointer to a null-terminated string holding the Object's path. + */ + +wchar_t* +aaf_get_ObjectPath (aafObject* Obj); + +/** + * Resolves a given WeakReference from a given Dictionary (a Set or Vector list of + * aafObjects), and returns a pointer to the corresponding Object if it was found. + * + * @param ref Pointer to the WeakReference to search for. + * @param list Pointer to the aafObject list from which the Reference will be searched for. + * + * @return A pointer to the aafObject if found,\n + * NULL otherwise. + * + */ + +aafObject* +aaf_get_ObjectByWeakRef (aafObject* list, + aafWeakRef_t* ref); + +/** + * Retrieves a Mob Object by its given MobID. + * + * @param Mobs Pointer to the Mob Object list. + * @param MobID Pointer to the MobID where're looking for. + * + * @return A pointer to the Mob aafObject if found,\n + * NULL otherwise. + */ + +aafObject* +aaf_get_MobByID (aafObject* Mobs, + aafMobID_t* MobID); + +aafObject* +aaf_get_MobSlotBySlotID (aafObject* MobSlots, + aafSlotID_t SlotID); + +/** + * Loops through each aafObject of a list, that is of a Set or Vector. It is also + * possible to filter the returned Object by ClassID. + * + * This function should be used as the conditional expression of a while loop. The + * aaf_foreach_ObjectInSet() is an implementation of this. + * + * @param Obj Pointer to pointer to an aafObject structure that will receive each + * Object of the list. + * @param head Pointer to the first Object of the list. + * @param filter Pointer to a ClassID to use as a filter, shall be NULL if unused. + * + * @return 1 if has another Object,\n + * 0 if has no more Object. + */ + +int +_aaf_foreach_ObjectInSet (aafObject** Obj, + aafObject* head, + const aafUID_t* filter); + +/** + * Convenience macro, that implements the _aaf_foreach_ObjectInSet() function. This should + * be used istead of directly calling _aaf_foreach_ObjectInSet(). + */ + +#define aaf_foreach_ObjectInSet(Obj, head, filter) \ + while (_aaf_foreach_ObjectInSet (Obj, head, filter)) + +/** + * Retrieves an Object property by ID. + * + * @param Obj Pointer to the Object to get the property from. + * @param pid Index of the requested property. + * + * @return A pointer to the property if found,\n + * NULL otherwise. + */ + +aafProperty* +aaf_get_property (aafObject* Obj, + aafPID_t pid); + +/** + * Retrieves a Property ID by its name. + * + * @param aafd Pointer to the AAF_Data structure. + * @param name Name of the property to look for. + * + * @return The PID of the property if it was found\n + * 0 otherwise. + */ + +aafPID_t +aaf_get_PropertyIDByName (AAF_Data* aafd, + const wchar_t* name); + +/** + * Retrieves an Object property by ID, and returns its value. + * + * Special case is the StrongReference, where the function returns + * the Object directly, instead of its reference. + * + * Function performs a type check before it returns. + * + * Caller must free the returned value, only if property is of type + * AAFTypeID_String. + * + * @param Obj Pointer to the Object to get the property from. + * @param pid Index of the requested property. + * + * @return A pointer to the property's value if found,\n + * NULL otherwise. + */ + +void* +aaf_get_propertyValue (aafObject* Obj, + aafPID_t pid, + const aafUID_t* typeID); + +/** + * Safely get an Indirect value, after it was retrieved using aaf_get_propertyValue(). + * Function checks value type and in case of AAFTypeID_String, performs allocation + * and conversion to system wchar_t*. + * + * Caller must free the returned value, only if Indirect is of type + * AAFTypeID_String. + * + * @param aafd Pointer to the AAF_Data structure. + * @param Indirect Pointer to the Indirect structure. + * @param typeDef Type definition expected from the Indirect. + * + * @return A pointer to the Indirect value, or a pointer to an allocated wchar_t if Indirect is AAFTypeID_String\n + * NULL in case of error. + */ + +void* +aaf_get_indirectValue (AAF_Data* aafd, + aafIndirect_t* Indirect, + const aafUID_t* typeDef); + +/** + * @} + */ + +/** + * @} + */ + +#endif // ! __AAFCore_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFClassDefUIDs.h b/libs/aaf/aaf/AAFDefs/AAFClassDefUIDs.h new file mode 100755 index 0000000000..796a6a1284 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFClassDefUIDs.h @@ -0,0 +1,461 @@ +#ifndef __AAFClassDefUIDs_h__ +#define __AAFClassDefUIDs_h__ + +#include "aaf/AAFTypes.h" + +// AAF class definition UIDs. +// + +// The AAF reference implementation uses shorter names than +// SMPTE. The names are shortened by the following aliases. +// +#define AAFClassID_ClassDef AAFClassID_ClassDefinition +#define AAFClassID_CodecDef AAFClassID_CodecDefinition +#define AAFClassID_DataDef AAFClassID_DataDefinition +#define AAFClassID_DefObject AAFClassID_DefinitionObject +#define AAFClassID_Edgecode AAFClassID_EdgeCode +#define AAFClassID_OperationDef AAFClassID_OperationDefinition +#define AAFClassID_Object AAFClassID_InterchangeObject +#define AAFClassID_ParameterDef AAFClassID_ParameterDefinition +#define AAFClassID_InterpolationDef AAFClassID_InterpolationDefinition +#define AAFClassID_PropertyDef AAFClassID_PropertyDefinition +#define AAFClassID_TypeDef AAFClassID_TypeDefinition +#define AAFClassID_TypeDefCharacter AAFClassID_TypeDefinitionCharacter +#define AAFClassID_TypeDefEnum AAFClassID_TypeDefinitionEnumeration +#define AAFClassID_TypeDefExtEnum AAFClassID_TypeDefinitionExtendibleEnumeration +#define AAFClassID_TypeDefFixedArray AAFClassID_TypeDefinitionFixedArray +#define AAFClassID_TypeDefInt AAFClassID_TypeDefinitionInteger +#define AAFClassID_TypeDefRecord AAFClassID_TypeDefinitionRecord +#define AAFClassID_TypeDefRename AAFClassID_TypeDefinitionRename +#define AAFClassID_TypeDefSet AAFClassID_TypeDefinitionSet +#define AAFClassID_TypeDefStream AAFClassID_TypeDefinitionStream +#define AAFClassID_TypeDefString AAFClassID_TypeDefinitionString +#define AAFClassID_TypeDefIndirect AAFClassID_TypeDefinitionIndirect +#define AAFClassID_TypeDefOpaque AAFClassID_TypeDefinitionOpaque +#define AAFClassID_TypeDefStrongObjRef AAFClassID_TypeDefinitionStrongObjectReference +#define AAFClassID_TypeDefVariableArray AAFClassID_TypeDefinitionVariableArray +#define AAFClassID_TypeDefWeakObjRef AAFClassID_TypeDefinitionWeakObjectReference +#define AAFClassID_ContainerDef AAFClassID_ContainerDefinition +#define AAFClassID_PluginDef AAFClassID_PluginDefinition + + + + +// https://github.com/nevali/aaf/blob/a03404ad8dc371757f3847b8dae0a9d70fff6a4e/ref-impl/include/OM/OMDictionary.h +static const aafUID_t AAFClassID_Root = +{0xb3b398a5, 0x1c90, 0x11d4, {0x80, 0x53, 0x08, 0x00, 0x36, 0x21, 0x08, 0x04}}; + + + + + +//{0d010101-0101-0100-060e-2b3402060101} +static const aafUID_t AAFClassID_InterchangeObject = +{0x0d010101, 0x0101, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0200-060e-2b3402060101} +static const aafUID_t AAFClassID_Component = +{0x0d010101, 0x0101, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0300-060e-2b3402060101} +static const aafUID_t AAFClassID_Segment = +{0x0d010101, 0x0101, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0400-060e-2b3402060101} +static const aafUID_t AAFClassID_EdgeCode = +{0x0d010101, 0x0101, 0x0400, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0500-060e-2b3402060101} +static const aafUID_t AAFClassID_EssenceGroup = +{0x0d010101, 0x0101, 0x0500, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0600-060e-2b3402060101} +static const aafUID_t AAFClassID_Event = +{0x0d010101, 0x0101, 0x0600, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0700-060e-2b3402060101} +static const aafUID_t AAFClassID_GPITrigger = +{0x0d010101, 0x0101, 0x0700, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0800-060e-2b3402060101} +static const aafUID_t AAFClassID_CommentMarker = +{0x0d010101, 0x0101, 0x0800, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0900-060e-2b3402060101} +static const aafUID_t AAFClassID_Filler = +{0x0d010101, 0x0101, 0x0900, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0a00-060e-2b3402060101} +static const aafUID_t AAFClassID_OperationGroup = +{0x0d010101, 0x0101, 0x0a00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0b00-060e-2b3402060101} +static const aafUID_t AAFClassID_NestedScope = +{0x0d010101, 0x0101, 0x0b00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0c00-060e-2b3402060101} +static const aafUID_t AAFClassID_Pulldown = +{0x0d010101, 0x0101, 0x0c00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0d00-060e-2b3402060101} +static const aafUID_t AAFClassID_ScopeReference = +{0x0d010101, 0x0101, 0x0d00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0e00-060e-2b3402060101} +static const aafUID_t AAFClassID_Selector = +{0x0d010101, 0x0101, 0x0e00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-0f00-060e-2b3402060101} +static const aafUID_t AAFClassID_Sequence = +{0x0d010101, 0x0101, 0x0f00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1000-060e-2b3402060101} +static const aafUID_t AAFClassID_SourceReference = +{0x0d010101, 0x0101, 0x1000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1100-060e-2b3402060101} +static const aafUID_t AAFClassID_SourceClip = +{0x0d010101, 0x0101, 0x1100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1200-060e-2b3402060101} +static const aafUID_t AAFClassID_TextClip = +{0x0d010101, 0x0101, 0x1200, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1300-060e-2b3402060101} +static const aafUID_t AAFClassID_HTMLClip = +{0x0d010101, 0x0101, 0x1300, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1400-060e-2b3402060101} +static const aafUID_t AAFClassID_Timecode = +{0x0d010101, 0x0101, 0x1400, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1500-060e-2b3402060101} +static const aafUID_t AAFClassID_TimecodeStream = +{0x0d010101, 0x0101, 0x1500, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1600-060e-2b3402060101} +static const aafUID_t AAFClassID_TimecodeStream12M = +{0x0d010101, 0x0101, 0x1600, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1700-060e-2b3402060101} +static const aafUID_t AAFClassID_Transition = +{0x0d010101, 0x0101, 0x1700, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1800-060e-2b3402060101} +static const aafUID_t AAFClassID_ContentStorage = +{0x0d010101, 0x0101, 0x1800, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1900-060e-2b3402060101} +static const aafUID_t AAFClassID_ControlPoint = +{0x0d010101, 0x0101, 0x1900, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1a00-060e-2b3402060101} +static const aafUID_t AAFClassID_DefinitionObject = +{0x0d010101, 0x0101, 0x1a00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1b00-060e-2b3402060101} +static const aafUID_t AAFClassID_DataDefinition = +{0x0d010101, 0x0101, 0x1b00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1c00-060e-2b3402060101} +static const aafUID_t AAFClassID_OperationDefinition = +{0x0d010101, 0x0101, 0x1c00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1d00-060e-2b3402060101} +static const aafUID_t AAFClassID_ParameterDefinition = +{0x0d010101, 0x0101, 0x1d00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1e00-060e-2b3402060101} +static const aafUID_t AAFClassID_PluginDefinition = +{0x0d010101, 0x0101, 0x1e00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-1f00-060e-2b3402060101} +static const aafUID_t AAFClassID_CodecDefinition = +{0x0d010101, 0x0101, 0x1f00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2000-060e-2b3402060101} +static const aafUID_t AAFClassID_ContainerDefinition = +{0x0d010101, 0x0101, 0x2000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2100-060e-2b3402060101} +static const aafUID_t AAFClassID_InterpolationDefinition = +{0x0d010101, 0x0101, 0x2100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2200-060e-2b3402060101} +static const aafUID_t AAFClassID_Dictionary = +{0x0d010101, 0x0101, 0x2200, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2300-060e-2b3402060101} +static const aafUID_t AAFClassID_EssenceData = +{0x0d010101, 0x0101, 0x2300, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2400-060e-2b3402060101} +static const aafUID_t AAFClassID_EssenceDescriptor = +{0x0d010101, 0x0101, 0x2400, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2500-060e-2b3402060101} +static const aafUID_t AAFClassID_FileDescriptor = +{0x0d010101, 0x0101, 0x2500, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2600-060e-2b3402060101} +static const aafUID_t AAFClassID_AIFCDescriptor = +{0x0d010101, 0x0101, 0x2600, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2700-060e-2b3402060101} +static const aafUID_t AAFClassID_DigitalImageDescriptor = +{0x0d010101, 0x0101, 0x2700, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2800-060e-2b3402060101} +static const aafUID_t AAFClassID_CDCIDescriptor = +{0x0d010101, 0x0101, 0x2800, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2900-060e-2b3402060101} +static const aafUID_t AAFClassID_RGBADescriptor = +{0x0d010101, 0x0101, 0x2900, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2a00-060e-2b3402060101} +static const aafUID_t AAFClassID_HTMLDescriptor = +{0x0d010101, 0x0101, 0x2a00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2b00-060e-2b3402060101} +static const aafUID_t AAFClassID_TIFFDescriptor = +{0x0d010101, 0x0101, 0x2b00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2c00-060e-2b3402060101} +static const aafUID_t AAFClassID_WAVEDescriptor = +{0x0d010101, 0x0101, 0x2c00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2d00-060e-2b3402060101} +static const aafUID_t AAFClassID_FilmDescriptor = +{0x0d010101, 0x0101, 0x2d00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2e00-060e-2b3402060101} +static const aafUID_t AAFClassID_TapeDescriptor = +{0x0d010101, 0x0101, 0x2e00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-2f00-060e-2b3402060101} +static const aafUID_t AAFClassID_Header = +{0x0d010101, 0x0101, 0x2f00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3000-060e-2b3402060101} +static const aafUID_t AAFClassID_Identification = +{0x0d010101, 0x0101, 0x3000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3100-060e-2b3402060101} +static const aafUID_t AAFClassID_Locator = +{0x0d010101, 0x0101, 0x3100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3200-060e-2b3402060101} +static const aafUID_t AAFClassID_NetworkLocator = +{0x0d010101, 0x0101, 0x3200, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3300-060e-2b3402060101} +static const aafUID_t AAFClassID_TextLocator = +{0x0d010101, 0x0101, 0x3300, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3400-060e-2b3402060101} +static const aafUID_t AAFClassID_Mob = +{0x0d010101, 0x0101, 0x3400, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3500-060e-2b3402060101} +static const aafUID_t AAFClassID_CompositionMob = +{0x0d010101, 0x0101, 0x3500, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3600-060e-2b3402060101} +static const aafUID_t AAFClassID_MasterMob = +{0x0d010101, 0x0101, 0x3600, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3700-060e-2b3402060101} +static const aafUID_t AAFClassID_SourceMob = +{0x0d010101, 0x0101, 0x3700, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3800-060e-2b3402060101} +static const aafUID_t AAFClassID_MobSlot = +{0x0d010101, 0x0101, 0x3800, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3900-060e-2b3402060101} +static const aafUID_t AAFClassID_EventMobSlot = +{0x0d010101, 0x0101, 0x3900, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3a00-060e-2b3402060101} +static const aafUID_t AAFClassID_StaticMobSlot = +{0x0d010101, 0x0101, 0x3a00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3b00-060e-2b3402060101} +static const aafUID_t AAFClassID_TimelineMobSlot = +{0x0d010101, 0x0101, 0x3b00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3c00-060e-2b3402060101} +static const aafUID_t AAFClassID_Parameter = +{0x0d010101, 0x0101, 0x3c00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3d00-060e-2b3402060101} +static const aafUID_t AAFClassID_ConstantValue = +{0x0d010101, 0x0101, 0x3d00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3e00-060e-2b3402060101} +static const aafUID_t AAFClassID_VaryingValue = +{0x0d010101, 0x0101, 0x3e00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-3f00-060e-2b3402060101} +static const aafUID_t AAFClassID_TaggedValue = +{0x0d010101, 0x0101, 0x3f00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4000-060e-2b3402060101} +static const aafUID_t AAFClassID_KLVData = +{0x0d010101, 0x0101, 0x4000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4100-060e-2b3402060101} +static const aafUID_t AAFClassID_DescriptiveMarker = +{0x0d010101, 0x0101, 0x4100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4200-060e-2b3402060101} +static const aafUID_t AAFClassID_SoundDescriptor = +{0x0d010101, 0x0101, 0x4200, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4300-060e-2b3402060101} +static const aafUID_t AAFClassID_DataEssenceDescriptor = +{0x0d010101, 0x0101, 0x4300, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4400-060e-2b3402060101} +static const aafUID_t AAFClassID_MultipleDescriptor = +{0x0d010101, 0x0101, 0x4400, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4500-060e-2b3402060101} +static const aafUID_t AAFClassID_DescriptiveClip = +{0x0d010101, 0x0101, 0x4500, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4700-060e-2b3402060101} +static const aafUID_t AAFClassID_AES3PCMDescriptor = +{0x0d010101, 0x0101, 0x4700, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4800-060e-2b3402060101} +static const aafUID_t AAFClassID_PCMDescriptor = +{0x0d010101, 0x0101, 0x4800, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4900-060e-2b3402060101} +static const aafUID_t AAFClassID_PhysicalDescriptor = +{0x0d010101, 0x0101, 0x4900, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4a00-060e-2b3402060101} +static const aafUID_t AAFClassID_ImportDescriptor = +{0x0d010101, 0x0101, 0x4a00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4b00-060e-2b3402060101} +static const aafUID_t AAFClassID_RecordingDescriptor = +{0x0d010101, 0x0101, 0x4b00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4c00-060e-2b3402060101} +static const aafUID_t AAFClassID_TaggedValueDefinition = +{0x0d010101, 0x0101, 0x4c00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4d00-060e-2b3402060101} +static const aafUID_t AAFClassID_KLVDataDefinition = +{0x0d010101, 0x0101, 0x4d00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4e00-060e-2b3402060101} +static const aafUID_t AAFClassID_AuxiliaryDescriptor = +{0x0d010101, 0x0101, 0x4e00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-4f00-060e-2b3402060101} +static const aafUID_t AAFClassID_RIFFChunk = +{0x0d010101, 0x0101, 0x4f00, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-5000-060e-2b3402060101} +static const aafUID_t AAFClassID_BWFImportDescriptor = +{0x0d010101, 0x0101, 0x5000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0101-5100-060e-2b3402060101} +static const aafUID_t AAFClassID_MPEGVideoDescriptor = +{0x0d010101, 0x0101, 0x5100, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0201-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_ClassDefinition = +{0x0d010101, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0202-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_PropertyDefinition = +{0x0d010101, 0x0202, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0203-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinition = +{0x0d010101, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0204-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionInteger = +{0x0d010101, 0x0204, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0205-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionStrongObjectReference = +{0x0d010101, 0x0205, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0206-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionWeakObjectReference = +{0x0d010101, 0x0206, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0207-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionEnumeration = +{0x0d010101, 0x0207, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0208-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionFixedArray = +{0x0d010101, 0x0208, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0209-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionVariableArray = +{0x0d010101, 0x0209, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-020a-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionSet = +{0x0d010101, 0x020a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-020b-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionString = +{0x0d010101, 0x020b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-020c-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionStream = +{0x0d010101, 0x020c, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-020d-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionRecord = +{0x0d010101, 0x020d, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-020e-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionRename = +{0x0d010101, 0x020e, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0220-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionExtendibleEnumeration = +{0x0d010101, 0x0220, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0221-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionIndirect = +{0x0d010101, 0x0221, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0222-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionOpaque = +{0x0d010101, 0x0222, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0223-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_TypeDefinitionCharacter = +{0x0d010101, 0x0223, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0224-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_MetaDefinition = +{0x0d010101, 0x0224, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010101-0225-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_MetaDictionary = +{0x0d010101, 0x0225, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010400-0000-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_DescriptiveObject = +{0x0d010400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + +//{0d010401-0000-0000-060e-2b3402060101} +static const aafUID_t AAFClassID_DescriptiveFramework = +{0x0d010401, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x02, 0x06, 0x01, 0x01}}; + + +#endif // ! __AAFClassDefUIDs_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFCodecDefs.h b/libs/aaf/aaf/AAFDefs/AAFCodecDefs.h new file mode 100755 index 0000000000..56436ce6bc --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFCodecDefs.h @@ -0,0 +1,223 @@ +#ifndef __CodecDefinition_h__ +#define __CodecDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known CodecDefinition instances +// + +//{568fb761-9458-11d2-8089-006008143e6f} +static const aafUID_t kAAFCodecDef_None = +{0x568fb761, 0x9458, 0x11d2, {0x80, 0x89, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{90ac17c8-e3e2-4596-9e9e-a6dd1c70c892} +static const aafUID_t kAAFCodecDef_PCM = +{0x90ac17c8, 0xe3e2, 0x4596, {0x9e, 0x9e, 0xa6, 0xdd, 0x1c, 0x70, 0xc8, 0x92}}; + + +//{820f09b1-eb9b-11d2-809f-006008143e6f} +static const aafUID_t kAAFCodecDef_WAVE = +{0x820f09b1, 0xeb9b, 0x11d2, {0x80, 0x9f, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{4b1c1a45-03f2-11d4-80fb-006008143e6f} +static const aafUID_t kAAFCodecDef_AIFC = +{0x4b1c1a45, 0x03f2, 0x11d4, {0x80, 0xfb, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{18634f8c-3bab-11d3-bfd6-00104bc9156d} +static const aafUID_t kAAFCodecDef_JPEG = +{0x18634f8c, 0x3bab, 0x11d3, {0xbf, 0xd6, 0x00, 0x10, 0x4b, 0xc9, 0x15, 0x6d}}; + + +//{4e84045e-0f29-11d4-a359-009027dfca6a} +static const aafUID_t kAAFCodecDef_CDCI = +{0x4e84045e, 0x0f29, 0x11d4, {0xa3, 0x59, 0x00, 0x90, 0x27, 0xdf, 0xca, 0x6a}}; + + +//{4e84045f-0f29-11d4-a359-009027dfca6a} +static const aafUID_t kAAFCodecDef_RGBA = +{0x4e84045f, 0x0f29, 0x11d4, {0xa3, 0x59, 0x00, 0x90, 0x27, 0xdf, 0xca, 0x6a}}; + + +//{6c2a61c2-e7a2-46ee-8d90-6a1d06e15f41} +static const aafUID_t kAAFCodecDef_VC3 = +{0x6c2a61c2, 0xe7a2, 0x46ee, {0x8d, 0x90, 0x6a, 0x1d, 0x06, 0xe1, 0x5f, 0x41}}; + + +//{8ef593f6-9521-4344-9ede-b84e8cfdc7da} +static const aafUID_t kAAFCodecDef_DNxHD = +{0x8ef593f6, 0x9521, 0x4344, {0x9e, 0xde, 0xb8, 0x4e, 0x8c, 0xfd, 0xc7, 0xda}}; + + +//{1b31f3b1-9450-11d2-8089-006008143e6f} +static const aafUID_t kAAFCodecFlavour_None = +{0x1b31f3b1, 0x9450, 0x11d2, {0x80, 0x89, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{af4de587-23d7-4c8a-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_100Mbps_1080x50I = +{0xaf4de587, 0x23d7, 0x4c8a, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c8b-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_100Mbps_1080x5994I = +{0xaf4de587, 0x23d7, 0x4c8b, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c8c-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_100Mbps_720x50P = +{0xaf4de587, 0x23d7, 0x4c8c, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c8d-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_100Mbps_720x5994P = +{0xaf4de587, 0x23d7, 0x4c8d, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c80-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_25Mbps_525_60 = +{0xaf4de587, 0x23d7, 0x4c80, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c81-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_25Mbps_625_50 = +{0xaf4de587, 0x23d7, 0x4c81, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c82-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_50Mbps_525_60 = +{0xaf4de587, 0x23d7, 0x4c82, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c83-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_DV_Based_50Mbps_625_50 = +{0xaf4de587, 0x23d7, 0x4c83, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c7f-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_IEC_DV_525_60 = +{0xaf4de587, 0x23d7, 0x4c7f, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c7e-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_IEC_DV_625_50 = +{0xaf4de587, 0x23d7, 0x4c7e, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c7d-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_LegacyDV_525_60 = +{0xaf4de587, 0x23d7, 0x4c7d, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c7c-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_LegacyDV_625_50 = +{0xaf4de587, 0x23d7, 0x4c7c, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c84-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_50Mbps_625x50I = +{0xaf4de587, 0x23d7, 0x4c84, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c85-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_50Mbps_525x5994I = +{0xaf4de587, 0x23d7, 0x4c85, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c86-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_40Mbps_625x50I = +{0xaf4de587, 0x23d7, 0x4c86, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c87-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_40Mbps_525x5994I = +{0xaf4de587, 0x23d7, 0x4c87, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c88-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_30Mbps_625x50I = +{0xaf4de587, 0x23d7, 0x4c88, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{af4de587-23d7-4c89-b37b-c1c13870e711} +static const aafUID_t kAAFCodecFlavour_SMPTE_D10_30Mbps_525x5994I = +{0xaf4de587, 0x23d7, 0x4c89, {0xb3, 0x7b, 0xc1, 0xc1, 0x38, 0x70, 0xe7, 0x11}}; + + +//{effdb6b4-fe99-4768-88fe-3422a5762961} +static const aafUID_t kAAFCodecFlavour_VC3_1235 = +{0xeffdb6b4, 0xfe99, 0x4768, {0x88, 0xfe, 0x34, 0x22, 0xa5, 0x76, 0x29, 0x61}}; + + +//{21b15f27-2781-4656-aa1b-dc5e63862738} +static const aafUID_t kAAFCodecFlavour_VC3_1237 = +{0x21b15f27, 0x2781, 0x4656, {0xaa, 0x1b, 0xdc, 0x5e, 0x63, 0x86, 0x27, 0x38}}; + + +//{62f37363-b1d1-4fa0-9fb7-6e7044371396} +static const aafUID_t kAAFCodecFlavour_VC3_1238 = +{0x62f37363, 0xb1d1, 0x4fa0, {0x9f, 0xb7, 0x6e, 0x70, 0x44, 0x37, 0x13, 0x96}}; + + +//{1e9b855a-323e-4999-b0fa-8444267a63a7} +static const aafUID_t kAAFCodecFlavour_VC3_1241 = +{0x1e9b855a, 0x323e, 0x4999, {0xb0, 0xfa, 0x84, 0x44, 0x26, 0x7a, 0x63, 0xa7}}; + + +//{8b4c29cf-b255-4ef0-bf79-b5b616479238} +static const aafUID_t kAAFCodecFlavour_VC3_1242 = +{0x8b4c29cf, 0xb255, 0x4ef0, {0xbf, 0x79, 0xb5, 0xb6, 0x16, 0x47, 0x92, 0x38}}; + + +//{e063fd16-6a70-4128-936d-ac776f2630cf} +static const aafUID_t kAAFCodecFlavour_VC3_1243 = +{0xe063fd16, 0x6a70, 0x4128, {0x93, 0x6d, 0xac, 0x77, 0x6f, 0x26, 0x30, 0xcf}}; + + +//{c80d0143-be86-45fd-aacc-7f612b4b9139} +static const aafUID_t kAAFCodecFlavour_VC3_1244 = +{0xc80d0143, 0xbe86, 0x45fd, {0xaa, 0xcc, 0x7f, 0x61, 0x2b, 0x4b, 0x91, 0x39}}; + + +//{47eb10b5-72fa-4dbb-9801-e0fe9ab8d9f0} +static const aafUID_t kAAFCodecFlavour_VC3_1250 = +{0x47eb10b5, 0x72fa, 0x4dbb, {0x98, 0x01, 0xe0, 0xfe, 0x9a, 0xb8, 0xd9, 0xf0}}; + + +//{26cf3984-c716-4315-9de7-9228b5c0f922} +static const aafUID_t kAAFCodecFlavour_VC3_1251 = +{0x26cf3984, 0xc716, 0x4315, {0x9d, 0xe7, 0x92, 0x28, 0xb5, 0xc0, 0xf9, 0x22}}; + + +//{0909cf52-475a-4abc-9e13-0ddb9d60d16c} +static const aafUID_t kAAFCodecFlavour_VC3_1252 = +{0x0909cf52, 0x475a, 0x4abc, {0x9e, 0x13, 0x0d, 0xdb, 0x9d, 0x60, 0xd1, 0x6c}}; + + +//{7f5d77dd-5402-45e0-9128-038016f55406} +static const aafUID_t kAAFCodecFlavour_VC3_1253 = +{0x7f5d77dd, 0x5402, 0x45e0, {0x91, 0x28, 0x03, 0x80, 0x16, 0xf5, 0x54, 0x06}}; + + +//{a362d3cb-dcef-4ffb-bb35-be72a16561ce} +static const aafUID_t kAAFCodecFlavour_VC3_1254 = +{0xa362d3cb, 0xdcef, 0x4ffb, {0xbb, 0x35, 0xbe, 0x72, 0xa1, 0x65, 0x61, 0xce}}; + + +// AAF CodecDefinition legacy aliases +// + +static const aafUID_t kAAFNoCodec = kAAFCodecDef_None; +static const aafUID_t kAAFCodecPCM = kAAFCodecDef_PCM; +static const aafUID_t kAAFCodecWAVE = kAAFCodecDef_WAVE; +static const aafUID_t kAAFCODEC_AIFC = kAAFCodecDef_AIFC; +static const aafUID_t kAAFCodecJPEG = kAAFCodecDef_JPEG; +static const aafUID_t kAAFCodecCDCI = kAAFCodecDef_CDCI; +static const aafUID_t kAAFCodecRGBA = kAAFCodecDef_RGBA; +static const aafUID_t kAAFCodecVC3 = kAAFCodecDef_VC3; +static const aafUID_t kAAFCodecDNxHD = kAAFCodecDef_DNxHD; +static const aafUID_t kAAFNilCodecFlavour = kAAFCodecFlavour_None; + +#endif // ! __CodecDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFCompressionDefs.h b/libs/aaf/aaf/AAFDefs/AAFCompressionDefs.h new file mode 100755 index 0000000000..6d84889dee --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFCompressionDefs.h @@ -0,0 +1,120 @@ +#ifndef __CompressionDefinition_h__ +#define __CompressionDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known CompressionDefinition instances +// + +//{edb35383-6d30-11d3-a036-006094eb75cb} +static const aafUID_t AAFCompressionDef_AAF_CMPR_FULL_JPEG = +{0xedb35383, 0x6d30, 0x11d3, {0xa0, 0x36, 0x00, 0x60, 0x94, 0xeb, 0x75, 0xcb}}; + + +//{edb35391-6d30-11d3-a036-006094eb75cb} +static const aafUID_t AAFCompressionDef_AAF_CMPR_AUNC422 = +{0xedb35391, 0x6d30, 0x11d3, {0xa0, 0x36, 0x00, 0x60, 0x94, 0xeb, 0x75, 0xcb}}; + + +//{edb35390-6d30-11d3-a036-006094eb75cb} +static const aafUID_t AAFCompressionDef_LegacyDV = +{0xedb35390, 0x6d30, 0x11d3, {0xa0, 0x36, 0x00, 0x60, 0x94, 0xeb, 0x75, 0xcb}}; + + +//{04010202-0102-0101-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_50Mbps_625x50I = +{0x04010202, 0x0102, 0x0101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0102-0102-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_50Mbps_525x5994I = +{0x04010202, 0x0102, 0x0102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0102-0103-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_40Mbps_625x50I = +{0x04010202, 0x0102, 0x0103, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0102-0104-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_40Mbps_525x5994I = +{0x04010202, 0x0102, 0x0104, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0102-0105-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_30Mbps_625x50I = +{0x04010202, 0x0102, 0x0105, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0102-0106-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_SMPTE_D10_30Mbps_525x5994I = +{0x04010202, 0x0102, 0x0106, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0201-0100-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_IEC_DV_525_60 = +{0x04010202, 0x0201, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0201-0200-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_IEC_DV_625_50 = +{0x04010202, 0x0201, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0100-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_25Mbps_525_60 = +{0x04010202, 0x0202, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0200-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_25Mbps_625_50 = +{0x04010202, 0x0202, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0300-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_50Mbps_525_60 = +{0x04010202, 0x0202, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0400-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_50Mbps_625_50 = +{0x04010202, 0x0202, 0x0400, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0500-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_100Mbps_1080x5994I = +{0x04010202, 0x0202, 0x0500, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0600-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_100Mbps_1080x50I = +{0x04010202, 0x0202, 0x0600, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0700-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_100Mbps_720x5994P = +{0x04010202, 0x0202, 0x0700, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-0202-0800-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_DV_Based_100Mbps_720x50P = +{0x04010202, 0x0202, 0x0800, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{04010202-7100-0000-060e-2b340401010a} +static const aafUID_t AAFCompressionDef_VC3_1 = +{0x04010202, 0x7100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0e040201-0204-0100-060e-2b3404010101} +static const aafUID_t AAFCompressionDef_Avid_DNxHD_Legacy = +{0x0e040201, 0x0204, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +// AAF CompressionDefinition legacy aliases +// + +//static const aafUID_t AAF_CMPR_FULL_JPEG = AAFCompressionDef_AAF_CMPR_FULL_JPEG; +//static const aafUID_t AAF_CMPR_AUNC422 = AAFCompressionDef_AAF_CMPR_AUNC422; + +#endif // ! __CompressionDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFContainerDefs.h b/libs/aaf/aaf/AAFDefs/AAFContainerDefs.h new file mode 100755 index 0000000000..0b51c88854 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFContainerDefs.h @@ -0,0 +1,484 @@ +#ifndef __ContainerDefinition_h__ +#define __ContainerDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known ContainerDefinition instances +// + +//{4313b572-d8ba-11d2-809b-006008143e6f} +static const aafUID_t AAFContainerDef_External = +{0x4313b572, 0xd8ba, 0x11d2, {0x80, 0x9b, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{4b1c1a46-03f2-11d4-80fb-006008143e6f} +static const aafUID_t AAFContainerDef_OMF = +{0x4b1c1a46, 0x03f2, 0x11d4, {0x80, 0xfb, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{4313b571-d8ba-11d2-809b-006008143e6f} +static const aafUID_t AAFContainerDef_AAF = +{0x4313b571, 0xd8ba, 0x11d2, {0x80, 0x9b, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{42464141-000d-4d4f-060e-2b34010101ff} +static const aafUID_t AAFContainerDef_AAFMSS = +{0x42464141, 0x000d, 0x4d4f, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff}}; + + +//{4b464141-000d-4d4f-060e-2b34010101ff} +static const aafUID_t AAFContainerDef_AAFKLV = +{0x4b464141, 0x000d, 0x4d4f, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff}}; + + +//{58464141-000d-4d4f-060e-2b34010101ff} +static const aafUID_t AAFContainerDef_AAFXML = +{0x58464141, 0x000d, 0x4d4f, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff}}; + + +//{0d010301-0201-0101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-017f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_50Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x017f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0201-0201-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0201, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0202-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0202, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-027f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_50Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x027f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0201-0301-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0301, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0302-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0302, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-037f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_40Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x037f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0201-0401-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0401, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0402-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0402, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-047f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_40Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x047f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0201-0501-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0501, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0502-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0502, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-057f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_625x50I_30Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x057f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0201-0601-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_DefinedTemplate = +{0x0d010301, 0x0201, 0x0601, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-0602-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_ExtendedTemplate = +{0x0d010301, 0x0201, 0x0602, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0201-067f-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_SMPTE_D10_525x5994I_30Mbps_PictureOnly = +{0x0d010301, 0x0201, 0x067f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0202-0101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps = +{0x0d010301, 0x0202, 0x0101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps = +{0x0d010301, 0x0202, 0x0102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0201-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps = +{0x0d010301, 0x0202, 0x0201, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0202-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps = +{0x0d010301, 0x0202, 0x0202, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0301-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_IECDV_525x5994I_25Mbps_SMPTE322M = +{0x0d010301, 0x0202, 0x0301, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0302-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_IECDV_525x5994I_25Mbps_SMPTE322M = +{0x0d010301, 0x0202, 0x0302, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0401-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_IECDV_625x50I_25Mbps_SMPTE322M = +{0x0d010301, 0x0202, 0x0401, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-0402-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_IECDV_625x50I_25Mbps_SMPTE322M = +{0x0d010301, 0x0202, 0x0402, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-3f01-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_IECDV_UndefinedSource_25Mbps = +{0x0d010301, 0x0202, 0x3f01, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-3f02-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_IECDV_UndefinedSource_25Mbps = +{0x0d010301, 0x0202, 0x3f02, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-4001-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_25Mbps = +{0x0d010301, 0x0202, 0x4001, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-4002-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_25Mbps = +{0x0d010301, 0x0202, 0x4002, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-4101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_25Mbps = +{0x0d010301, 0x0202, 0x4101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-4102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_25Mbps = +{0x0d010301, 0x0202, 0x4102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-5001-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_525x5994I_50Mbps = +{0x0d010301, 0x0202, 0x5001, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-5002-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_525x5994I_50Mbps = +{0x0d010301, 0x0202, 0x5002, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-5101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_625x50I_50Mbps = +{0x0d010301, 0x0202, 0x5101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-5102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_625x50I_50Mbps = +{0x0d010301, 0x0202, 0x5102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6001-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x5994I_100Mbps = +{0x0d010301, 0x0202, 0x6001, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6002-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x5994I_100Mbps = +{0x0d010301, 0x0202, 0x6002, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_1080x50I_100Mbps = +{0x0d010301, 0x0202, 0x6101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_1080x50I_100Mbps = +{0x0d010301, 0x0202, 0x6102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6201-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_720x5994P_100Mbps = +{0x0d010301, 0x0202, 0x6201, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6202-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x5994P_100Mbps = +{0x0d010301, 0x0202, 0x6202, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6301-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_720x50P_100Mbps = +{0x0d010301, 0x0202, 0x6301, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-6302-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_720x50P_100Mbps = +{0x0d010301, 0x0202, 0x6302, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-7f01-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_DVbased_UndefinedSource = +{0x0d010301, 0x0202, 0x7f01, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0202-7f02-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_DVbased_UndefinedSource = +{0x0d010301, 0x0202, 0x7f02, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0204-6001-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_MPEGES_VideoStream0_SID = +{0x0d010301, 0x0204, 0x6001, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0204-6107-060e-2b3404010102} +static const aafUID_t AAFContainerDef_MXFGC_CustomClosedGOPwrapped_MPEGES_VideoStream1_SID = +{0x0d010301, 0x0204, 0x6107, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02}}; + + +//{0d010301-0205-0101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994I_720_422 = +{0x0d010301, 0x0205, 0x0101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994I_720_422 = +{0x0d010301, 0x0205, 0x0102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0103-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994I_720_422 = +{0x0d010301, 0x0205, 0x0103, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0105-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50I_720_422 = +{0x0d010301, 0x0205, 0x0105, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0106-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50I_720_422 = +{0x0d010301, 0x0205, 0x0106, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0107-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50I_720_422 = +{0x0d010301, 0x0205, 0x0107, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-0119-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Uncompressed_525x5994P_960_422 = +{0x0d010301, 0x0205, 0x0119, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-011a-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_525x5994P_960_422 = +{0x0d010301, 0x0205, 0x011a, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-011b-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Linewrapped_Uncompressed_525x5994P_960_422 = +{0x0d010301, 0x0205, 0x011b, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-011d-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Uncompressed_625x50P_960_422 = +{0x0d010301, 0x0205, 0x011d, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-011e-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Uncompressed_625x50P_960_422 = +{0x0d010301, 0x0205, 0x011e, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0205-011f-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Linewrapped_Uncompressed_625x50P_960_422 = +{0x0d010301, 0x0205, 0x011f, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0206-0100-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Broadcast_Wave_audio_data = +{0x0d010301, 0x0206, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0206-0200-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Broadcast_Wave_audio_data = +{0x0d010301, 0x0206, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0206-0300-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_AES3_audio_data = +{0x0d010301, 0x0206, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-0206-0400-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_AES3_audio_data = +{0x0d010301, 0x0206, 0x0400, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0d010301-020a-0100-060e-2b3404010103} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_Alaw_Audio = +{0x0d010301, 0x020a, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x03}}; + + +//{0d010301-020a-0200-060e-2b3404010103} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_Alaw_Audio = +{0x0d010301, 0x020a, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x03}}; + + +//{0d010301-020a-0300-060e-2b3404010103} +static const aafUID_t AAFContainerDef_MXFGC_Customwrapped_Alaw_Audio = +{0x0d010301, 0x020a, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x03}}; + + +//{0d010301-0210-6002-060e-2b340401010a} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_AVCbytestream_VideoStream0_SID = +{0x0d010301, 0x0210, 0x6002, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0d010301-0211-0100-060e-2b340401010a} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_VC3 = +{0x0d010301, 0x0211, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0d010301-0211-0200-060e-2b340401010a} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_VC3 = +{0x0d010301, 0x0211, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0d010301-0212-0100-060e-2b340401010a} +static const aafUID_t AAFContainerDef_MXFGC_Framewrapped_VC1 = +{0x0d010301, 0x0212, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0d010301-0212-0200-060e-2b340401010a} +static const aafUID_t AAFContainerDef_MXFGC_Clipwrapped_VC1 = +{0x0d010301, 0x0212, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x0a}}; + + +//{0d010301-027f-0100-060e-2b3404010103} +static const aafUID_t AAFContainerDef_MXFGC_Generic_Essence_Multiple_Mappings = +{0x0d010301, 0x027f, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x03}}; + + +//{0d011301-0101-0100-060e-2b3404010106} +static const aafUID_t AAFContainerDef_RIFFWAVE = +{0x0d011301, 0x0101, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x06}}; + + +//{0d011301-0102-0200-060e-2b3404010107} +static const aafUID_t AAFContainerDef_JFIF = +{0x0d011301, 0x0102, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07}}; + + +//{0d011301-0104-0100-060e-2b3404010106} +static const aafUID_t AAFContainerDef_AIFFAIFC = +{0x0d011301, 0x0104, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x06}}; + + +//{0e040301-0206-0101-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220X_1080p = +{0x0e040301, 0x0206, 0x0101, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0102-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_145_1080p = +{0x0e040301, 0x0206, 0x0102, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0103-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220_1080p = +{0x0e040301, 0x0206, 0x0103, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0104-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_36_1080p = +{0x0e040301, 0x0206, 0x0104, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0201-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220X_1080i = +{0x0e040301, 0x0206, 0x0201, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0202-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_145_1080i = +{0x0e040301, 0x0206, 0x0202, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0203-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220_1080i = +{0x0e040301, 0x0206, 0x0203, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0204-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_145_1440_1080i = +{0x0e040301, 0x0206, 0x0204, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0301-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220X_720p = +{0x0e040301, 0x0206, 0x0301, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0302-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_220_720p = +{0x0e040301, 0x0206, 0x0302, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{0e040301-0206-0303-060e-2b3404010101} +static const aafUID_t AAFContainerDef_MXFGC_Avid_DNX_145_720p = +{0x0e040301, 0x0206, 0x0303, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +// AAF ContainerDefinition legacy aliases +// + +// const aafUID_t ContainerFile = kAAFContainerDef_External; +// const aafUID_t ContainerOMF = kAAFContainerDef_OMF; +// const aafUID_t ContainerAAF = kAAFContainerDef_AAF; +// const aafUID_t ContainerAAFMSS = kAAFContainerDef_AAFMSS; +// const aafUID_t ContainerAAFKLV = kAAFContainerDef_AAFKLV; +// const aafUID_t ContainerAAFXML = kAAFContainerDef_AAFXML; + +#endif // ! __ContainerDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFDataDefs.h b/libs/aaf/aaf/AAFDefs/AAFDataDefs.h new file mode 100755 index 0000000000..14558581e0 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFDataDefs.h @@ -0,0 +1,81 @@ +#ifndef __DataDefinition_h__ +#define __DataDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known DataDefinition instances +// + +//{01030202-0100-0000-060e-2b3404010101} +static const aafUID_t AAFDataDef_Picture = +{0x01030202, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{6f3c8ce1-6cef-11d2-807d-006008143e6f} +static const aafUID_t AAFDataDef_LegacyPicture = +{0x6f3c8ce1, 0x6cef, 0x11d2, {0x80, 0x7d, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{05cba731-1daa-11d3-80ad-006008143e6f} +static const aafUID_t AAFDataDef_Matte = +{0x05cba731, 0x1daa, 0x11d3, {0x80, 0xad, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{05cba732-1daa-11d3-80ad-006008143e6f} +static const aafUID_t AAFDataDef_PictureWithMatte = +{0x05cba732, 0x1daa, 0x11d3, {0x80, 0xad, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{01030202-0200-0000-060e-2b3404010101} +static const aafUID_t AAFDataDef_Sound = +{0x01030202, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{78e1ebe1-6cef-11d2-807d-006008143e6f} +static const aafUID_t AAFDataDef_LegacySound = +{0x78e1ebe1, 0x6cef, 0x11d2, {0x80, 0x7d, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{01030201-0100-0000-060e-2b3404010101} +static const aafUID_t AAFDataDef_Timecode = +{0x01030201, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{7f275e81-77e5-11d2-807f-006008143e6f} +static const aafUID_t AAFDataDef_LegacyTimecode = +{0x7f275e81, 0x77e5, 0x11d2, {0x80, 0x7f, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{d2bb2af0-d234-11d2-89ee-006097116212} +static const aafUID_t AAFDataDef_Edgecode = +{0xd2bb2af0, 0xd234, 0x11d2, {0x89, 0xee, 0x00, 0x60, 0x97, 0x11, 0x62, 0x12}}; + + +//{01030201-1000-0000-060e-2b3404010101} +static const aafUID_t AAFDataDef_DescriptiveMetadata = +{0x01030201, 0x1000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +//{01030203-0100-0000-060e-2b3404010105} +static const aafUID_t AAFDataDef_Auxiliary = +{0x01030203, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05}}; + + +//{851419d0-2e4f-11d3-8a5b-0050040ef7d2} +static const aafUID_t AAFDataDef_Unknown = +{0x851419d0, 0x2e4f, 0x11d3, {0x8a, 0x5b, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +// AAF DataDefinition legacy aliases +// + +/* +static const aafUID_t DDEF_Picture = AAFDataDef_LegacyPicture; +static const aafUID_t DDEF_Matte = AAFDataDef_Matte; +static const aafUID_t DDEF_PictureWithMatte = AAFDataDef_PictureWithMatte; +static const aafUID_t DDEF_Sound = AAFDataDef_LegacySound; +static const aafUID_t DDEF_Timecode = AAFDataDef_LegacyTimecode; +static const aafUID_t DDEF_Edgecode = AAFDataDef_Edgecode; +static const aafUID_t DDEF_Unknown = AAFDataDef_Unknown; +*/ +#endif // ! __DataDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFExtEnum.h b/libs/aaf/aaf/AAFDefs/AAFExtEnum.h new file mode 100755 index 0000000000..834c867eb1 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFExtEnum.h @@ -0,0 +1,106 @@ +#ifndef __AAFExtEnum_h__ +#define __AAFExtEnum_h__ + +#include "aaf/AAFTypes.h" + +// AAF extensible enumeration member UIDs. +// + +// Members of OperationCategoryType +// +//{0d010102-0101-0100-060e-2b3404010101} +static const aafUID_t AAFOperationCategory_Effect = +{0x0d010102, 0x0101, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +// Members of TransferCharacteristicType +// +//{04010101-0101-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_ITU470_PAL = +{0x04010101, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0102-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_ITU709 = +{0x04010101, 0x0102, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0103-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_SMPTE240M = +{0x04010101, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0104-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_274M_296M = +{0x04010101, 0x0104, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0105-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_ITU1361 = +{0x04010101, 0x0105, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0106-0000-060e-2b3404010101} +static const aafUID_t AAFTransferCharacteristic_linear = +{0x04010101, 0x0106, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +// Members of PluginCategoryType +// +//{0d010102-0101-0200-060e-2b3404010101} +static const aafUID_t AAFPluginCategory_Effect = +{0x0d010102, 0x0101, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0300-060e-2b3404010101} +static const aafUID_t AAFPluginCategory_Codec = +{0x0d010102, 0x0101, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0400-060e-2b3404010101} +static const aafUID_t AAFPluginCategory_Interpolation = +{0x0d010102, 0x0101, 0x0400, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +// Members of UsageType +// +//{0d010102-0101-0500-060e-2b3404010101} +static const aafUID_t AAFUsage_SubClip = +{0x0d010102, 0x0101, 0x0500, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0600-060e-2b3404010101} +static const aafUID_t AAFUsage_AdjustedClip = +{0x0d010102, 0x0101, 0x0600, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0700-060e-2b3404010101} +static const aafUID_t AAFUsage_TopLevel = +{0x0d010102, 0x0101, 0x0700, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0800-060e-2b3404010101} +static const aafUID_t AAFUsage_LowerLevel = +{0x0d010102, 0x0101, 0x0800, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{0d010102-0101-0900-060e-2b3404010101} +static const aafUID_t AAFUsage_Template = +{0x0d010102, 0x0101, 0x0900, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +// Members of ColorPrimariesType +// +//{04010101-0301-0000-060e-2b3404010106} +static const aafUID_t AAFColorPrimaries_SMPTE170M = +{0x04010101, 0x0301, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x06}}; + +//{04010101-0302-0000-060e-2b3404010106} +static const aafUID_t AAFColorPrimaries_ITU470_PAL = +{0x04010101, 0x0302, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x06}}; + +//{04010101-0303-0000-060e-2b3404010106} +static const aafUID_t AAFColorPrimaries_ITU709 = +{0x04010101, 0x0303, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x06}}; + +// Members of CodingEquationsType +// +//{04010101-0201-0000-060e-2b3404010101} +static const aafUID_t AAFCodingEquations_ITU601 = +{0x04010101, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0202-0000-060e-2b3404010101} +static const aafUID_t AAFCodingEquations_ITU709 = +{0x04010101, 0x0202, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + +//{04010101-0203-0000-060e-2b3404010101} +static const aafUID_t AAFCodingEquations_SMPTE240M = +{0x04010101, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01}}; + + +#endif // ! __AAFExtEnum_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFFileKinds.h b/libs/aaf/aaf/AAFDefs/AAFFileKinds.h new file mode 100755 index 0000000000..6d1bf9d45f --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFFileKinds.h @@ -0,0 +1,146 @@ +#ifndef __AAFFileKinds_h__ +#define __AAFFileKinds_h__ + +#include "aaf/AAFTypes.h" + +// +// The following enumerations select the file encoding type without +// specifying the implementation (in cases where multiple +// implementations are available) +// +// New code should use one of these encodings. +// + +// AAF file encoded using the default encoding for the particular SDK +// release. +static const aafUID_t AAFFileKind_DontCare = +{0,0,0,{0,0,0,0,0,0,0,0}}; + + +// AAF files encoded as structured storage with a 512 bytes sector size +static const aafUID_t AAFFileKind_Aaf512Binary = +{ 0x42464141, 0x000d, 0x4d4f, { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff } }; + +// AAF files structured storage with a 4096 bytes sector size +static const aafUID_t AAFFileKind_Aaf4KBinary = +{ 0x92b02efb, 0xaf40, 0x4896, { 0xa5, 0x8e, 0xd1, 0x57, 0x2f, 0x42, 0x2b, 0x58 } }; + +/* +Looks like Avid's Media Composer own AAFFileKind_Aaf4KBinary : + +{ 0x0d010201, 0x0200, 0x0000, { 0x06, 0x0e, 0x2b, 0x34, 0x03, 0x02, 0x01, 0x01 } } + +_CFB_Header____________________________________________________________________________________ + +_abSig : 0xe11ab1a1e011cfd0 +_clsId : {0x0d010201, 0x0200, 0x0000, { 0x06 0x0e 0x2b 0x34 0x03 0x02 0x01 0x01 }} + version : 62.4 ( 0x003e 0x0004 ) +_uByteOrder : little-endian ( 0xfffe ) +_uSectorShift : 12 (4096 bytes sectors) +_uMiniSectorShift : 6 (64 bytes mini-sectors) +_usReserved0 : 0x00 +_ulReserved1 : 0x0000 +_csectDir : 92 +_csectFat : 3 +_sectDirStart : 1 +_signature : 0 +_ulMiniSectorCutoff : 4096 +_sectMiniFatStart : 2721 +_csectMiniFat : 4 +_sectDifStart : -2 +_csectDif : 0 + + + + ByteOrder : Little-Endian (0x4949) + LastModified : 2017-09-23 09:38:53.00 + AAF ObjSpec Version : 1.1 + ObjectModel Version : 1 + Operational Pattern : AAFOPDef_EditProtocol + + + CompanyName : Avid Technology, Inc. + ProductName : Avid Media Composer 8.4.5 + ProductVersion : 8.4.0.0 (1) + ProductVersionString : Unknown version + ProductID : {d0b7c06e cd3d 4ad7 {ac fb f0 3a 4f 42 a2 31}} + Date : 2017-09-23 09:38:53.00 + ToolkitVersion : 1.1.6.8635 (0) + Platform : AAFSDK (Win64) + GenerationAUID : {feadd9ba e1d3 474d {8b 3f 6a 79 a6 29 1d 2f}} + +*/ + + +// AAF files encoded as XML (text) +static const aafUID_t AAFFileKind_AafXmlText = +{ 0xfe0d0101, 0x60e1, 0x4e78, { 0xb2, 0xcd, 0x2b, 0x03, 0xdb, 0xb0, 0xfa, 0x87 } }; + +// AAF files encoded as KLV (binary) (MXF) +// +static const aafUID_t AAFFileKind_AafKlvBinary = +{0x4b464141, 0x000d, 0x4d4f, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0xff } }; + +// the enum to select the default implementation with 4096 byte sectors + + +// +// The following encodings select a specific encoding implementation +// in cases where multiple implementations are available. It is not +// advisable to use these in new code. The exist primarily for test +// purposes. +// + +// the enum to select the Microsoft implementation with 512 byte sectors +static const aafUID_t AAFFileKind_AafM512Binary = +{ 0xc95e8ee6, 0xa6ec, 0x4e53, { 0x92, 0x28, 0xbd, 0x9b, 0x57, 0x23, 0x57, 0xe5 } }; + +// the enum to select the SchemaSoft implementation with 512 byte sectors +static const aafUID_t AAFFileKind_AafS512Binary = +{ 0xbb153a22, 0xc2ed, 0x4b2e, { 0xbb, 0x69, 0x19, 0xbd, 0x58, 0x9d, 0xf6, 0xdc } }; + +// the enum to select the GSF implementation with 512 byte sectors +static const aafUID_t AAFFileKind_AafG512Binary = +{ 0xb965c7f1, 0xf89d, 0x4490, { 0xbd, 0x22, 0x77, 0x35, 0x69, 0xb4, 0xd3, 0x61 } }; + +// the enum to select the Microsoft implementation with 4096 byte sectors +static const aafUID_t AAFFileKind_AafM4KBinary = +{ 0x7653a218, 0x3e03, 0x4ecf, { 0x87, 0x98, 0xf4, 0x5f, 0xc1, 0x17, 0x11, 0x78 } }; + +// the enum to select the SchemaSoft implementation with 4096 byte sectors +static const aafUID_t AAFFileKind_AafS4KBinary = +{ 0xa8ab424a, 0xc5a0, 0x48d0, { 0x9e, 0xea, 0x96, 0x69, 0x69, 0x75, 0xc6, 0xd0 } }; + +// the enum to select the GSF implementation with 4096 byte sectors +static const aafUID_t AAFFileKind_AafG4KBinary = +{ 0xb44818b, 0xc3dd, 0x4f0a, { 0xad, 0x37, 0xe9, 0x71, 0x0, 0x7a, 0x88, 0xe8 } }; + + +// +// The folloing enumerations exist for testing purposes only and will +// trigger anb error if used. +// + +static const aafUID_t AAFFileKind_Pathological = +{0xff,0xff,0xff,{0,0,0,0,0,0,0,0}}; + + +// +// Old deprecated symbols which may be removed in a future release. +// Don't use these in new code. +// +/* +static const aafUID_t aafFileKindDontCare = AAFFileKind_DontCare; +static const aafUID_t aafFileKindPathalogical = AAFFileKind_Pathological; +static const aafUID_t aafFileKindAafKlvBinary = AAFFileKind_AafKlvBinary; +static const aafUID_t aafFileKindAafMSSBinary = AAFFileKind_AafM512Binary; +static const aafUID_t aafFileKindAafM4KBinary = AAFFileKind_AafM4KBinary; +static const aafUID_t aafFileKindAafSSSBinary = AAFFileKind_AafS512Binary; +static const aafUID_t aafFileKindAafS4KBinary = AAFFileKind_AafS4KBinary; +static const aafUID_t aafFileKindAafXmlText = AAFFileKind_AafXmlText; +static const aafUID_t aafFileKindAafSSBinary = AAFFileKind_Aaf512Binary; +static const aafUID_t aafFileKindAaf4KBinary = AAFFileKind_Aaf4KBinary; +*/ + + +#endif // ! __AAFFileKinds_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFInterpolatorDefs.h b/libs/aaf/aaf/AAFDefs/AAFInterpolatorDefs.h new file mode 100755 index 0000000000..67ef0b25f6 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFInterpolatorDefs.h @@ -0,0 +1,49 @@ +#ifndef __InterpolationDefinition_h__ +#define __InterpolationDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known InterpolationDefinition instances +// + +//{5b6c85a3-0ede-11d3-80a9-006008143e6f} +static const aafUID_t AAFInterpolationDef_None = +{0x5b6c85a3, 0x0ede, 0x11d3, {0x80, 0xa9, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{5b6c85a4-0ede-11d3-80a9-006008143e6f} +static const aafUID_t AAFInterpolationDef_Linear = +{0x5b6c85a4, 0x0ede, 0x11d3, {0x80, 0xa9, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{5b6c85a5-0ede-11d3-80a9-006008143e6f} +static const aafUID_t AAFInterpolationDef_Constant = +{0x5b6c85a5, 0x0ede, 0x11d3, {0x80, 0xa9, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{5b6c85a6-0ede-11d3-80a9-006008143e6f} +static const aafUID_t AAFInterpolationDef_BSpline = +{0x5b6c85a6, 0x0ede, 0x11d3, {0x80, 0xa9, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{15829ec3-1f24-458a-960d-c65bb23c2aa1} +static const aafUID_t AAFInterpolationDef_Log = +{0x15829ec3, 0x1f24, 0x458a, {0x96, 0x0d, 0xc6, 0x5b, 0xb2, 0x3c, 0x2a, 0xa1}}; + + +//{c09153f7-bd18-4e5a-ad09-cbdd654fa001} +static const aafUID_t AAFInterpolationDef_Power = +{0xc09153f7, 0xbd18, 0x4e5a, {0xad, 0x09, 0xcb, 0xdd, 0x65, 0x4f, 0xa0, 0x01}}; + + +// AAF InterpolationDefinition legacy aliases +// +/* +static const aafUID_t NoInterpolator = AAFInterpolationDef_None; +static const aafUID_t LinearInterpolator = AAFInterpolationDef_Linear; +static const aafUID_t ConstantInterpolator = AAFInterpolationDef_Constant; +static const aafUID_t BSplineInterpolator = AAFInterpolationDef_BSpline; +static const aafUID_t LogInterpolator = AAFInterpolationDef_Log; +static const aafUID_t PowerInterpolator = AAFInterpolationDef_Power; +*/ +#endif // ! __InterpolationDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFOPDefs.h b/libs/aaf/aaf/AAFDefs/AAFOPDefs.h new file mode 100755 index 0000000000..c4fcb3d7e1 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFOPDefs.h @@ -0,0 +1,23 @@ +#ifndef __OPDefinition_h__ +#define __OPDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known OPDefinition instances +// + +//{0d011201-0100-0000-060e-2b3404010105} +static const aafUID_t AAFOPDef_EditProtocol = +{0x0d011201, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x05}}; + + +//{0d011201-0200-0000-060e-2b3404010109} +static const aafUID_t AAFOPDef_Unconstrained = +{0x0d011201, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x09}}; + + +// AAF OPDefinition legacy aliases +// + + +#endif // ! __OPDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFOperationDefs.h b/libs/aaf/aaf/AAFDefs/AAFOperationDefs.h new file mode 100755 index 0000000000..72e9fffbac --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFOperationDefs.h @@ -0,0 +1,171 @@ +#ifndef __OperationDefinition_h__ +#define __OperationDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known OperationDefinition instances +// + +//{0c3bea40-fc05-11d2-8a29-0050040ef7d2} +static const aafUID_t AAFOperationDef_VideoDissolve = +{0x0c3bea40, 0xfc05, 0x11d2, {0x8a, 0x29, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{0c3bea44-fc05-11d2-8a29-0050040ef7d2} +static const aafUID_t AAFOperationDef_SMPTEVideoWipe = +{0x0c3bea44, 0xfc05, 0x11d2, {0x8a, 0x29, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9d2ea890-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_VideoSpeedControl = +{0x9d2ea890, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9d2ea891-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_VideoRepeat = +{0x9d2ea891, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{f1db0f32-8d64-11d3-80df-006008143e6f} +static const aafUID_t AAFOperationDef_Flip = +{0xf1db0f32, 0x8d64, 0x11d3, {0x80, 0xdf, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{f1db0f34-8d64-11d3-80df-006008143e6f} +static const aafUID_t AAFOperationDef_Flop = +{0xf1db0f34, 0x8d64, 0x11d3, {0x80, 0xdf, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{f1db0f33-8d64-11d3-80df-006008143e6f} +static const aafUID_t AAFOperationDef_FlipFlop = +{0xf1db0f33, 0x8d64, 0x11d3, {0x80, 0xdf, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{86f5711e-ee72-450c-a118-17cf3b175dff} +static const aafUID_t AAFOperationDef_VideoPosition = +{0x86f5711e, 0xee72, 0x450c, {0xa1, 0x18, 0x17, 0xcf, 0x3b, 0x17, 0x5d, 0xff}}; + + +//{f5826680-26c5-4149-8554-43d3c7a3bc09} +static const aafUID_t AAFOperationDef_VideoCrop = +{0xf5826680, 0x26c5, 0x4149, {0x85, 0x54, 0x43, 0xd3, 0xc7, 0xa3, 0xbc, 0x09}}; + + +//{2e0a119d-e6f7-4bee-b5dc-6dd42988687e} +static const aafUID_t AAFOperationDef_VideoScale = +{0x2e0a119d, 0xe6f7, 0x4bee, {0xb5, 0xdc, 0x6d, 0xd4, 0x29, 0x88, 0x68, 0x7e}}; + + +//{f2ca330d-8d45-4db4-b1b5-136ab055586f} +static const aafUID_t AAFOperationDef_VideoRotate = +{0xf2ca330d, 0x8d45, 0x4db4, {0xb1, 0xb5, 0x13, 0x6a, 0xb0, 0x55, 0x58, 0x6f}}; + + +//{21d5c51a-8acb-46d5-9392-5cae640c8836} +static const aafUID_t AAFOperationDef_VideoCornerPinning = +{0x21d5c51a, 0x8acb, 0x46d5, {0x93, 0x92, 0x5c, 0xae, 0x64, 0x0c, 0x88, 0x36}}; + + +//{14db900e-d537-49f6-889b-012568fcc234} +static const aafUID_t AAFOperationDef_VideoAlphaWithinVideoKey = +{0x14db900e, 0xd537, 0x49f6, {0x88, 0x9b, 0x01, 0x25, 0x68, 0xfc, 0xc2, 0x34}}; + + +//{e599cb0f-ba5f-4192-9356-51eb19c08589} +static const aafUID_t AAFOperationDef_VideoSeparateAlphaKey = +{0xe599cb0f, 0xba5f, 0x4192, {0x93, 0x56, 0x51, 0xeb, 0x19, 0xc0, 0x85, 0x89}}; + + +//{38ff7903-69e5-476b-be5a-eafc2000f011} +static const aafUID_t AAFOperationDef_VideoLuminanceKey = +{0x38ff7903, 0x69e5, 0x476b, {0xbe, 0x5a, 0xea, 0xfc, 0x20, 0x00, 0xf0, 0x11}}; + + +//{30a315c2-71e5-4e82-a4ef-0513ee056b65} +static const aafUID_t AAFOperationDef_VideoChromaKey = +{0x30a315c2, 0x71e5, 0x4e82, {0xa4, 0xef, 0x05, 0x13, 0xee, 0x05, 0x6b, 0x65}}; + + +//{9d2ea894-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_MonoAudioGain = +{0x9d2ea894, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9d2ea893-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_MonoAudioPan = +{0x9d2ea893, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{0c3bea41-fc05-11d2-8a29-0050040ef7d2} +static const aafUID_t AAFOperationDef_MonoAudioDissolve = +{0x0c3bea41, 0xfc05, 0x11d2, {0x8a, 0x29, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{2311bd90-b5da-4285-aa3a-8552848779b3} +static const aafUID_t AAFOperationDef_TwoParameterMonoAudioDissolve = +{0x2311bd90, 0xb5da, 0x4285, {0xaa, 0x3a, 0x85, 0x52, 0x84, 0x87, 0x79, 0xb3}}; + + +//{9bb90dfd-2aad-49af-b09c-8ba6cd5281d1} +static const aafUID_t AAFOperationDef_VideoOpacity = +{0x9bb90dfd, 0x2aad, 0x49af, {0xb0, 0x9c, 0x8b, 0xa6, 0xcd, 0x52, 0x81, 0xd1}}; + + +//{2c50831c-572e-4042-b1dd-55ed0b7c49df} +static const aafUID_t AAFOperationDef_VideoTitle = +{0x2c50831c, 0x572e, 0x4042, {0xb1, 0xdd, 0x55, 0xed, 0x0b, 0x7c, 0x49, 0xdf}}; + + +//{5aba98f8-f389-471f-8fee-dfde7ec7f9bb} +static const aafUID_t AAFOperationDef_VideoColor = +{0x5aba98f8, 0xf389, 0x471f, {0x8f, 0xee, 0xdf, 0xde, 0x7e, 0xc7, 0xf9, 0xbb}}; + + +//{1575e350-fca3-11d2-8a2a-0050040ef7d2} +static const aafUID_t AAFOperationDef_Unknown = +{0x1575e350, 0xfca3, 0x11d2, {0x8a, 0x2a, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{0c3bea43-fc05-11d2-8a29-0050040ef7d2} +static const aafUID_t AAFOperationDef_VideoFadeToBlack = +{0x0c3bea43, 0xfc05, 0x11d2, {0x8a, 0x29, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{0a3c75e0-fd82-11d2-8a2b-0050040ef7d2} +static const aafUID_t AAFOperationDef_PictureWithMate = +{0x0a3c75e0, 0xfd82, 0x11d2, {0x8a, 0x2b, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9d2ea892-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_VideoFrameToMask = +{0x9d2ea892, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{0c3bea42-fc05-11d2-8a29-0050040ef7d2} +static const aafUID_t AAFOperationDef_StereoAudioDissolve = +{0x0c3bea42, 0xfc05, 0x11d2, {0x8a, 0x29, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9d2ea895-0968-11d3-8a38-0050040ef7d2} +static const aafUID_t AAFOperationDef_StereoAudioGain = +{0x9d2ea895, 0x0968, 0x11d3, {0x8a, 0x38, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{8d896ad0-2261-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFOperationDef_MonoAudioMixdown = +{0x8d896ad0, 0x2261, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + + + +/* + * NOTE looks like it is the way ProTools represents Stereo (5.1, 7.1 ???) Tracks + * whenever "Export Stereo, 5.1 and 7.1 tracks as multi-channel" is enabled. + */ + +static const aafUID_t AAFOperationDef_AudioChannelCombiner = +{0x6b46dd7a, 0x132d, 0x4856, {0xab, 0x21, 0x8b, 0x75, 0x1d, 0x84, 0x62, 0xec}}; + + + +#endif // ! __OperationDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFParameterDefs.h b/libs/aaf/aaf/AAFDefs/AAFParameterDefs.h new file mode 100644 index 0000000000..7c7abbf916 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFParameterDefs.h @@ -0,0 +1,356 @@ +#ifndef __ParameterDefinition_h__ +#define __ParameterDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known ParameterDefinition instances +// + +//{e4962320-2267-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_Level = +{0xe4962320, 0x2267, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{e4962323-2267-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEWipeNumber = +{0xe4962323, 0x2267, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba0-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEReverse = +{0x9c894ba0, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{72559a80-24d7-11d3-8a50-0050040ef7d2} +static const aafUID_t AAFParameterDef_SpeedRatio = +{0x72559a80, 0x24d7, 0x11d3, {0x8a, 0x50, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{c573a510-071a-454f-b617-ad6ae69054c2} +static const aafUID_t AAFParameterDef_PositionOffsetX = +{0xc573a510, 0x071a, 0x454f, {0xb6, 0x17, 0xad, 0x6a, 0xe6, 0x90, 0x54, 0xc2}}; + + +//{82e27478-1336-4ea3-bcb9-6b8f17864c42} +static const aafUID_t AAFParameterDef_PositionOffsetY = +{0x82e27478, 0x1336, 0x4ea3, {0xbc, 0xb9, 0x6b, 0x8f, 0x17, 0x86, 0x4c, 0x42}}; + + +//{d47b3377-318c-4657-a9d8-75811b6dc3d1} +static const aafUID_t AAFParameterDef_CropLeft = +{0xd47b3377, 0x318c, 0x4657, {0xa9, 0xd8, 0x75, 0x81, 0x1b, 0x6d, 0xc3, 0xd1}}; + + +//{5ecc9dd5-21c1-462b-9fec-c2bd85f14033} +static const aafUID_t AAFParameterDef_CropRight = +{0x5ecc9dd5, 0x21c1, 0x462b, {0x9f, 0xec, 0xc2, 0xbd, 0x85, 0xf1, 0x40, 0x33}}; + + +//{8170a539-9b55-4051-9d4e-46598d01b914} +static const aafUID_t AAFParameterDef_CropTop = +{0x8170a539, 0x9b55, 0x4051, {0x9d, 0x4e, 0x46, 0x59, 0x8d, 0x01, 0xb9, 0x14}}; + + +//{154ba82b-990a-4c80-9101-3037e28839a1} +static const aafUID_t AAFParameterDef_CropBottom = +{0x154ba82b, 0x990a, 0x4c80, {0x91, 0x01, 0x30, 0x37, 0xe2, 0x88, 0x39, 0xa1}}; + + +//{8d568129-847e-11d5-935a-50f857c10000} +static const aafUID_t AAFParameterDef_ScaleX = +{0x8d568129, 0x847e, 0x11d5, {0x93, 0x5a, 0x50, 0xf8, 0x57, 0xc1, 0x00, 0x00}}; + + +//{8d56812a-847e-11d5-935a-50f857c10000} +static const aafUID_t AAFParameterDef_ScaleY = +{0x8d56812a, 0x847e, 0x11d5, {0x93, 0x5a, 0x50, 0xf8, 0x57, 0xc1, 0x00, 0x00}}; + + +//{062cfbd8-f4b1-4a50-b944-f39e2fc73c17} +static const aafUID_t AAFParameterDef_Rotation = +{0x062cfbd8, 0xf4b1, 0x4a50, {0xb9, 0x44, 0xf3, 0x9e, 0x2f, 0xc7, 0x3c, 0x17}}; + + +//{72a3b4a2-873d-4733-9052-9f83a706ca5b} +static const aafUID_t AAFParameterDef_PinTopLeftX = +{0x72a3b4a2, 0x873d, 0x4733, {0x90, 0x52, 0x9f, 0x83, 0xa7, 0x06, 0xca, 0x5b}}; + + +//{29e4d78f-a502-4ebb-8c07-ed5a0320c1b0} +static const aafUID_t AAFParameterDef_PinTopLeftY = +{0x29e4d78f, 0xa502, 0x4ebb, {0x8c, 0x07, 0xed, 0x5a, 0x03, 0x20, 0xc1, 0xb0}}; + + +//{a95296c0-1ed9-4925-8481-2096c72e818d} +static const aafUID_t AAFParameterDef_PinTopRightX = +{0xa95296c0, 0x1ed9, 0x4925, {0x84, 0x81, 0x20, 0x96, 0xc7, 0x2e, 0x81, 0x8d}}; + + +//{ce1757ae-7a0b-45d9-b3f3-3686adff1e2d} +static const aafUID_t AAFParameterDef_PinTopRightY = +{0xce1757ae, 0x7a0b, 0x45d9, {0xb3, 0xf3, 0x36, 0x86, 0xad, 0xff, 0x1e, 0x2d}}; + + +//{08b2bc81-9b1b-4c01-ba73-bba3554ed029} +static const aafUID_t AAFParameterDef_PinBottomLeftX = +{0x08b2bc81, 0x9b1b, 0x4c01, {0xba, 0x73, 0xbb, 0xa3, 0x55, 0x4e, 0xd0, 0x29}}; + + +//{c163f2ff-cd83-4655-826e-3724ab7fa092} +static const aafUID_t AAFParameterDef_PinBottomLeftY = +{0xc163f2ff, 0xcd83, 0x4655, {0x82, 0x6e, 0x37, 0x24, 0xab, 0x7f, 0xa0, 0x92}}; + + +//{53bc5884-897f-479e-b833-191f8692100d} +static const aafUID_t AAFParameterDef_PinBottomRightX = +{0x53bc5884, 0x897f, 0x479e, {0xb8, 0x33, 0x19, 0x1f, 0x86, 0x92, 0x10, 0x0d}}; + + +//{812fb15b-0b95-4406-878d-efaa1cffc129} +static const aafUID_t AAFParameterDef_PinBottomRightY = +{0x812fb15b, 0x0b95, 0x4406, {0x87, 0x8d, 0xef, 0xaa, 0x1c, 0xff, 0xc1, 0x29}}; + + +//{a2667f65-65d8-4abf-a179-0b9b93413949} +static const aafUID_t AAFParameterDef_AlphaKeyInvertAlpha = +{0xa2667f65, 0x65d8, 0x4abf, {0xa1, 0x79, 0x0b, 0x9b, 0x93, 0x41, 0x39, 0x49}}; + + +//{21ed5b0f-b7a0-43bc-b779-c47f85bf6c4d} +static const aafUID_t AAFParameterDef_LumKeyLevel = +{0x21ed5b0f, 0xb7a0, 0x43bc, {0xb7, 0x79, 0xc4, 0x7f, 0x85, 0xbf, 0x6c, 0x4d}}; + + +//{cbd39b25-3ece-441e-ba2c-da473ab5cc7c} +static const aafUID_t AAFParameterDef_LumKeyClip = +{0xcbd39b25, 0x3ece, 0x441e, {0xba, 0x2c, 0xda, 0x47, 0x3a, 0xb5, 0xcc, 0x7c}}; + + +//{e4962321-2267-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_Amplitude = +{0xe4962321, 0x2267, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{e4962322-2267-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_Pan = +{0xe4962322, 0x2267, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9e610007-1be2-41e1-bb11-c95de9964d03} +static const aafUID_t AAFParameterDef_OutgoingLevel = +{0x9e610007, 0x1be2, 0x41e1, {0xbb, 0x11, 0xc9, 0x5d, 0xe9, 0x96, 0x4d, 0x03}}; + + +//{48cea642-a8f9-455b-82b3-86c814b797c7} +static const aafUID_t AAFParameterDef_IncomingLevel = +{0x48cea642, 0xa8f9, 0x455b, {0x82, 0xb3, 0x86, 0xc8, 0x14, 0xb7, 0x97, 0xc7}}; + + +//{cb7c0ec4-f45f-4ee6-aef0-c63ddb134924} +static const aafUID_t AAFParameterDef_OpacityLevel = +{0xcb7c0ec4, 0xf45f, 0x4ee6, {0xae, 0xf0, 0xc6, 0x3d, 0xdb, 0x13, 0x49, 0x24}}; + + +//{7b92827b-5ae3-465e-b5f9-5ee21b070859} +static const aafUID_t AAFParameterDef_TitleText = +{0x7b92827b, 0x5ae3, 0x465e, {0xb5, 0xf9, 0x5e, 0xe2, 0x1b, 0x07, 0x08, 0x59}}; + + +//{e8eb7f50-602f-4a2f-8fb2-86c8826ccf24} +static const aafUID_t AAFParameterDef_TitleFontName = +{0xe8eb7f50, 0x602f, 0x4a2f, {0x8f, 0xb2, 0x86, 0xc8, 0x82, 0x6c, 0xcf, 0x24}}; + + +//{01c55287-31b3-4f8f-bb87-c92f06eb7f5a} +static const aafUID_t AAFParameterDef_TitleFontSize = +{0x01c55287, 0x31b3, 0x4f8f, {0xbb, 0x87, 0xc9, 0x2f, 0x06, 0xeb, 0x7f, 0x5a}}; + + +//{dfe86f24-8a71-4dc5-83a2-988f583af711} +static const aafUID_t AAFParameterDef_TitleFontColorR = +{0xdfe86f24, 0x8a71, 0x4dc5, {0x83, 0xa2, 0x98, 0x8f, 0x58, 0x3a, 0xf7, 0x11}}; + + +//{f9f41222-36d9-4650-bd5a-a17866cf86b9} +static const aafUID_t AAFParameterDef_TitleFontColorG = +{0xf9f41222, 0x36d9, 0x4650, {0xbd, 0x5a, 0xa1, 0x78, 0x66, 0xcf, 0x86, 0xb9}}; + + +//{f5ba87fa-cf72-4f37-a736-d7096fcb06f1} +static const aafUID_t AAFParameterDef_TitleFontColorB = +{0xf5ba87fa, 0xcf72, 0x4f37, {0xa7, 0x36, 0xd7, 0x09, 0x6f, 0xcb, 0x06, 0xf1}}; + + +//{47c1733f-6afb-4168-9b6d-476adfbae7ab} +static const aafUID_t AAFParameterDef_TitleAlignment = +{0x47c1733f, 0x6afb, 0x4168, {0x9b, 0x6d, 0x47, 0x6a, 0xdf, 0xba, 0xe7, 0xab}}; + + +//{8b5732c0-be8e-4332-aa71-5d866add777d} +static const aafUID_t AAFParameterDef_TitleBold = +{0x8b5732c0, 0xbe8e, 0x4332, {0xaa, 0x71, 0x5d, 0x86, 0x6a, 0xdd, 0x77, 0x7d}}; + + +//{e4a3c91b-f96a-4dd4-91d8-1ba32000ab72} +static const aafUID_t AAFParameterDef_TitleItalic = +{0xe4a3c91b, 0xf96a, 0x4dd4, {0x91, 0xd8, 0x1b, 0xa3, 0x20, 0x00, 0xab, 0x72}}; + + +//{a25061da-db25-402e-89ff-a6d0efa39444} +static const aafUID_t AAFParameterDef_TitlePositionX = +{0xa25061da, 0xdb25, 0x402e, {0x89, 0xff, 0xa6, 0xd0, 0xef, 0xa3, 0x94, 0x44}}; + + +//{6151541f-9d3f-4a0e-a3f9-24cc60eea969} +static const aafUID_t AAFParameterDef_TitlePositionY = +{0x6151541f, 0x9d3f, 0x4a0e, {0xa3, 0xf9, 0x24, 0xcc, 0x60, 0xee, 0xa9, 0x69}}; + + +//{be2033da-723b-4146-ace0-3299e0ff342e} +static const aafUID_t AAFParameterDef_ColorSlopeR = +{0xbe2033da, 0x723b, 0x4146, {0xac, 0xe0, 0x32, 0x99, 0xe0, 0xff, 0x34, 0x2e}}; + + +//{7ca8e01b-c6d8-4b3f-b251-28a53e5b958f} +static const aafUID_t AAFParameterDef_ColorSlopeG = +{0x7ca8e01b, 0xc6d8, 0x4b3f, {0xb2, 0x51, 0x28, 0xa5, 0x3e, 0x5b, 0x95, 0x8f}}; + + +//{1aeb007b-3cd5-4814-87b5-cbd6a3cdfe8d} +static const aafUID_t AAFParameterDef_ColorSlopeB = +{0x1aeb007b, 0x3cd5, 0x4814, {0x87, 0xb5, 0xcb, 0xd6, 0xa3, 0xcd, 0xfe, 0x8d}}; + + +//{4d1e65e0-85fc-4bb9-a264-13cf320a8539} +static const aafUID_t AAFParameterDef_ColorOffsetR = +{0x4d1e65e0, 0x85fc, 0x4bb9, {0xa2, 0x64, 0x13, 0xcf, 0x32, 0x0a, 0x85, 0x39}}; + + +//{76f783e4-0bbd-41d7-b01e-f418c1602a6f} +static const aafUID_t AAFParameterDef_ColorOffsetG = +{0x76f783e4, 0x0bbd, 0x41d7, {0xb0, 0x1e, 0xf4, 0x18, 0xc1, 0x60, 0x2a, 0x6f}}; + + +//{57110628-522d-4b48-8a28-75477ced984d} +static const aafUID_t AAFParameterDef_ColorOffsetB = +{0x57110628, 0x522d, 0x4b48, {0x8a, 0x28, 0x75, 0x47, 0x7c, 0xed, 0x98, 0x4d}}; + + +//{c2d79c3a-9263-40d9-827d-953ac6b88813} +static const aafUID_t AAFParameterDef_ColorPowerR = +{0xc2d79c3a, 0x9263, 0x40d9, {0x82, 0x7d, 0x95, 0x3a, 0xc6, 0xb8, 0x88, 0x13}}; + + +//{524d52e6-86a3-4f41-864b-fb53b15b1d5d} +static const aafUID_t AAFParameterDef_ColorPowerG = +{0x524d52e6, 0x86a3, 0x4f41, {0x86, 0x4b, 0xfb, 0x53, 0xb1, 0x5b, 0x1d, 0x5d}}; + + +//{5f0cc7dc-907d-4153-bf00-1f3cdf3c05bb} +static const aafUID_t AAFParameterDef_ColorPowerB = +{0x5f0cc7dc, 0x907d, 0x4153, {0xbf, 0x00, 0x1f, 0x3c, 0xdf, 0x3c, 0x05, 0xbb}}; + + +//{0b135705-3312-4d03-ba89-be9ef45e5470} +static const aafUID_t AAFParameterDef_ColorSaturation = +{0x0b135705, 0x3312, 0x4d03, {0xba, 0x89, 0xbe, 0x9e, 0xf4, 0x5e, 0x54, 0x70}}; + + +//{f3b9466a-2579-4168-beb5-66b996919a3f} +static const aafUID_t AAFParameterDef_ColorCorrectionDescription = +{0xf3b9466a, 0x2579, 0x4168, {0xbe, 0xb5, 0x66, 0xb9, 0x96, 0x91, 0x9a, 0x3f}}; + + +//{b0124dbe-7f97-443c-ae39-c49c1c53d728} +static const aafUID_t AAFParameterDef_ColorInputDescription = +{0xb0124dbe, 0x7f97, 0x443c, {0xae, 0x39, 0xc4, 0x9c, 0x1c, 0x53, 0xd7, 0x28}}; + + +//{5a9dfc6f-611f-4db8-8eff-3b9cdb6e1220} +static const aafUID_t AAFParameterDef_ColorViewingDescription = +{0x5a9dfc6f, 0x611f, 0x4db8, {0x8e, 0xff, 0x3b, 0x9c, 0xdb, 0x6e, 0x12, 0x20}}; + + +//{9c894ba1-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTESoft = +{0x9c894ba1, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba2-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEBorder = +{0x9c894ba2, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba3-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEPosition = +{0x9c894ba3, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba4-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEModulator = +{0x9c894ba4, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba5-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEShadow = +{0x9c894ba5, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba6-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTETumble = +{0x9c894ba6, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba7-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTESpotlight = +{0x9c894ba7, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba8-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEReplicationH = +{0x9c894ba8, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894ba9-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTEReplicationV = +{0x9c894ba9, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{9c894baa-2277-11d3-8a4c-0050040ef7d2} +static const aafUID_t AAFParameterDef_SMPTECheckerboard = +{0x9c894baa, 0x2277, 0x11d3, {0x8a, 0x4c, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +//{5f1c2560-2415-11d3-8a4f-0050040ef7d2} +static const aafUID_t AAFParameterDef_PhaseOffset = +{0x5f1c2560, 0x2415, 0x11d3, {0x8a, 0x4f, 0x00, 0x50, 0x04, 0x0e, 0xf7, 0xd2}}; + + +// AAF ParameterDefinition legacy aliases +// +/* +static const aafUID_t AAFParameterDefLevel = AAFParameterDef_Level; +static const aafUID_t AAFParameterDefSMPTEWipeNumber = AAFParameterDef_SMPTEWipeNumber; +static const aafUID_t AAFParameterDefSMPTEReverse = AAFParameterDef_SMPTEReverse; +static const aafUID_t AAFParameterDefSpeedRatio = AAFParameterDef_SpeedRatio; +static const aafUID_t AAFParameterDefAmplitude = AAFParameterDef_Amplitude; +static const aafUID_t AAFParameterDefPan = AAFParameterDef_Pan; +static const aafUID_t AAFParameterDefSMPTESoft = AAFParameterDef_SMPTESoft; +static const aafUID_t AAFParameterDefSMPTEBorder = AAFParameterDef_SMPTEBorder; +static const aafUID_t AAFParameterDefSMPTEPosition = AAFParameterDef_SMPTEPosition; +static const aafUID_t AAFParameterDefSMPTEModulator = AAFParameterDef_SMPTEModulator; +static const aafUID_t AAFParameterDefSMPTEShadow = AAFParameterDef_SMPTEShadow; +static const aafUID_t AAFParameterDefSMPTETumble = AAFParameterDef_SMPTETumble; +static const aafUID_t AAFParameterDefSMPTESpotlight = AAFParameterDef_SMPTESpotlight; +static const aafUID_t AAFParameterDefSMPTEReplicationH = AAFParameterDef_SMPTEReplicationH; +static const aafUID_t AAFParameterDefSMPTEReplicationV = AAFParameterDef_SMPTEReplicationV; +static const aafUID_t AAFParameterDefSMPTECheckerboard = AAFParameterDef_SMPTECheckerboard; +static const aafUID_t AAFParameterDefPhaseOffset = AAFParameterDef_PhaseOffset; +*/ + +/* Seen in Avid and PT files */ +// static const aafUID_t PanVol_IsTrimGainEffect = +// {0x922d458d, 0x8f22, 0x11d4, {0xa0, 0x3c, 0x00, 0x04, 0xac, 0x96, 0x9f, 0x50}}; + + +#endif // ! __ParameterDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFPluginDefs.h b/libs/aaf/aaf/AAFDefs/AAFPluginDefs.h new file mode 100755 index 0000000000..ed4788d6b1 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFPluginDefs.h @@ -0,0 +1,37 @@ +#ifndef __PluginDefinition_h__ +#define __PluginDefinition_h__ + +#include "aaf/AAFTypes.h" + +// AAF well-known PluginDefinition instances +// + +//{3d1dd891-e793-11d2-809e-006008143e6f} +static const aafUID_t kAAFPlatform_Independent = +{0x3d1dd891, 0xe793, 0x11d2, {0x80, 0x9e, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{9fdef8c1-e847-11d2-809e-006008143e6f} +static const aafUID_t kAAFEngine_None = +{0x9fdef8c1, 0xe847, 0x11d2, {0x80, 0x9e, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{69c870a1-e793-11d2-809e-006008143e6f} +static const aafUID_t kAAFPluginAPI_EssenceAccess = +{0x69c870a1, 0xe793, 0x11d2, {0x80, 0x9e, 0x00, 0x60, 0x08, 0x14, 0x3e, 0x6f}}; + + +//{56905e0b-537d-11d4-a36c-009027dfca6a} +static const aafUID_t kAAFPluginCategory_Codec = +{0x56905e0b, 0x537d, 0x11d4, {0xa3, 0x6c, 0x00, 0x90, 0x27, 0xdf, 0xca, 0x6a}}; + + +// AAF PluginDefinition legacy aliases +// + +static const aafUID_t kAAFPlatformIndependant = kAAFPlatform_Independent; +static const aafUID_t kAAFNoEngine = kAAFEngine_None; +static const aafUID_t kAAFEssencePluginAPI = kAAFPluginAPI_EssenceAccess; +static const aafUID_t kAAFPluginNoCategory = kAAFPluginCategory_Codec; + +#endif // ! __PluginDefinition_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFPropertyDefs.h b/libs/aaf/aaf/AAFDefs/AAFPropertyDefs.h new file mode 100755 index 0000000000..dac96438c9 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFPropertyDefs.h @@ -0,0 +1,1306 @@ +#ifndef __AAFPropertyDefs_h__ +#define __AAFPropertyDefs_h__ + +#include "aaf/AAFTypes.h" + +// AAF property definition UIDs. +// + +//{06010104-0101-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_InterchangeObject_ObjClass = +{0x06010104, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0800-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_InterchangeObject_Generation = +{0x05200701, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04070100-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Component_DataDefinition = +{0x04070100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020201-0103-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Component_Length = +{0x07020201, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010210-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Component_KLVData = +{0x03010210, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020102-1600-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Component_UserComments = +{0x03020102, 0x1600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{03010210-0800-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Component_Attributes = +{0x03010210, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{01040901-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EdgeCode_Start = +{0x01040901, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0109-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EdgeCode_FilmKind = +{0x04100103, 0x0109, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0102-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_EdgeCode_CodeFormat = +{0x04100103, 0x0102, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{01030201-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EdgeCode_Header = +{0x01030201, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0601-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceGroup_Choices = +{0x06010104, 0x0601, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0208-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceGroup_StillFrame = +{0x06010104, 0x0208, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-0303-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Event_Position = +{0x07020103, 0x0303, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300404-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Event_Comment = +{0x05300404, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300401-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_GPITrigger_ActiveState = +{0x05300401, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-020a-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CommentMarker_Annotation = +{0x06010104, 0x020a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300506-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationGroup_Operation = +{0x05300506, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0602-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationGroup_InputSegments = +{0x06010104, 0x0602, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-060a-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationGroup_Parameters = +{0x06010104, 0x060a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0530050c-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationGroup_BypassOverride = +{0x0530050c, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0206-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationGroup_Rendering = +{0x06010104, 0x0206, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0607-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_NestedScope_Slots = +{0x06010104, 0x0607, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0207-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Pulldown_InputSegment = +{0x06010104, 0x0207, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05401001-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Pulldown_PulldownKind = +{0x05401001, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05401001-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Pulldown_PulldownDirection = +{0x05401001, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05401001-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Pulldown_PhaseFrame = +{0x05401001, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ScopeReference_RelativeScope = +{0x06010103, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ScopeReference_RelativeSlot = +{0x06010103, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0209-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Selector_Selected = +{0x06010104, 0x0209, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0608-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Selector_Alternates = +{0x06010104, 0x0608, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0609-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Sequence_Components = +{0x06010104, 0x0609, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceReference_SourceID = +{0x06010103, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceReference_SourceMobSlotID = +{0x06010103, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0700-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_SourceReference_ChannelIDs = +{0x06010103, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{06010103-0800-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_SourceReference_MonoSourceSlotIDs = +{0x06010103, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{07020103-0104-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceClip_StartTime = +{0x07020103, 0x0104, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020201-0105-0200-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceClip_FadeInLength = +{0x07020201, 0x0105, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300501-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_SourceClip_FadeInType = +{0x05300501, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{07020201-0105-0300-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceClip_FadeOutLength = +{0x07020201, 0x0105, 0x0300, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300502-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_SourceClip_FadeOutType = +{0x05300502, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{05300601-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_HTMLClip_BeginAnchor = +{0x05300601, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300602-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_HTMLClip_EndAnchor = +{0x05300602, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-0105-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Timecode_Start = +{0x07020103, 0x0105, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04040101-0206-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Timecode_FPS = +{0x04040101, 0x0206, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04040101-0500-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_Timecode_Drop = +{0x04040101, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04040101-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TimecodeStream_SampleRate = +{0x04040101, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04070300-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TimecodeStream_Source = +{0x04070300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04040201-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_TimecodeStream_SourceType = +{0x04040201, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04040101-0400-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_TimecodeStream12M_IncludeSync = +{0x04040101, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0205-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Transition_OperationGroup = +{0x06010104, 0x0205, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-0106-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Transition_CutPoint = +{0x07020103, 0x0106, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0501-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ContentStorage_Mobs = +{0x06010104, 0x0501, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0502-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ContentStorage_EssenceData = +{0x06010104, 0x0502, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0530050d-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ControlPoint_Value = +{0x0530050d, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-1002-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_ControlPoint_Time = +{0x07020103, 0x1002, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300508-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ControlPoint_EditHint = +{0x05300508, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01011503-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DefinitionObject_Identification = +{0x01011503, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01070102-0301-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DefinitionObject_Name = +{0x01070102, 0x0301, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020301-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DefinitionObject_Description = +{0x03020301, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300509-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationDefinition_DataDefinition = +{0x05300509, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300503-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_OperationDefinition_IsTimeWarp = +{0x05300503, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0401-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationDefinition_DegradeTo = +{0x06010104, 0x0401, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0530050a-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationDefinition_OperationCategory = +{0x0530050a, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300504-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_OperationDefinition_NumberInputs = +{0x05300504, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{05300505-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_OperationDefinition_Bypass = +{0x05300505, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0302-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_OperationDefinition_ParametersDefined = +{0x06010104, 0x0302, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0106-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ParameterDefinition_Type = +{0x06010104, 0x0106, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0530050b-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ParameterDefinition_DisplayUnits = +{0x0530050b, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200901-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_PluginCategory = +{0x05200901, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03030301-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_VersionNumber = +{0x03030301, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03030301-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_VersionString = +{0x03030301, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{010a0101-0101-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Manufacturer = +{0x010a0101, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-020b-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_ManufacturerInfo = +{0x06010104, 0x020b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{010a0101-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_ManufacturerID = +{0x010a0101, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200902-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Platform = +{0x05200902, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200903-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MinPlatformVersion = +{0x05200903, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200904-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MaxPlatformVersion = +{0x05200904, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200905-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Engine = +{0x05200905, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200906-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MinEngineVersion = +{0x05200906, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200907-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MaxEngineVersion = +{0x05200907, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200908-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_PluginAPI = +{0x05200908, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200909-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MinPluginAPI = +{0x05200909, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090a-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_MaxPluginAPI = +{0x0520090a, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090b-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_SoftwareOnly = +{0x0520090b, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090c-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Accelerator = +{0x0520090c, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090d-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Locators = +{0x0520090d, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090e-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_Authentication = +{0x0520090e, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0520090f-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PluginDefinition_DefinitionObject = +{0x0520090f, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0107-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CodecDefinition_FileDescriptorClass = +{0x06010104, 0x0107, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0301-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CodecDefinition_DataDefinitions = +{0x06010104, 0x0301, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010201-0300-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_ContainerDefinition_EssenceIsIdentified = +{0x03010201, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0503-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_OperationDefinitions = +{0x06010104, 0x0503, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0504-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_ParameterDefinitions = +{0x06010104, 0x0504, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0505-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_DataDefinitions = +{0x06010104, 0x0505, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0506-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_PluginDefinitions = +{0x06010104, 0x0506, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0507-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_CodecDefinitions = +{0x06010104, 0x0507, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0508-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_ContainerDefinitions = +{0x06010104, 0x0508, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0509-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Dictionary_InterpolationDefinitions = +{0x06010104, 0x0509, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-050a-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Dictionary_KLVDataDefinitions = +{0x06010104, 0x050a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{06010104-050b-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Dictionary_TaggedValueDefinitions = +{0x06010104, 0x050b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{06010106-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceData_MobID = +{0x06010106, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04070200-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceData_Data = +{0x04070200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010102-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceData_SampleIndex = +{0x06010102, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0603-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EssenceDescriptor_Locator = +{0x06010104, 0x0603, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04060101-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_FileDescriptor_SampleRate = +{0x04060101, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04060102-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_FileDescriptor_Length = +{0x04060102, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0102-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FileDescriptor_ContainerFormat = +{0x06010104, 0x0102, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0103-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FileDescriptor_CodecDefinition = +{0x06010104, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010103-0500-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_FileDescriptor_LinkedSlotID = +{0x06010103, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{03030302-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_AIFCDescriptor_Summary = +{0x03030302, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010601-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_Compression = +{0x04010601, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010502-0100-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_StoredHeight = +{0x04010502, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010502-0200-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_StoredWidth = +{0x04010502, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0700-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_SampledHeight = +{0x04010501, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0800-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_SampledWidth = +{0x04010501, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0900-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_SampledXOffset = +{0x04010501, 0x0900, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0a00-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_SampledYOffset = +{0x04010501, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0b00-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_DisplayHeight = +{0x04010501, 0x0b00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0c00-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_DisplayWidth = +{0x04010501, 0x0c00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0d00-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_DisplayXOffset = +{0x04010501, 0x0d00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0e00-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_DisplayYOffset = +{0x04010501, 0x0e00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010301-0400-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_FrameLayout = +{0x04010301, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010302-0500-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_VideoLineMap = +{0x04010302, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010101-0100-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_ImageAspectRatio = +{0x04010101, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{05200102-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_AlphaTransparency = +{0x05200102, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010201-0101-0200-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_TransferCharacteristic = +{0x04010201, 0x0101, 0x0200, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010201-0106-0100-060e-2b3401010109} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_ColorPrimaries = +{0x04010201, 0x0106, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x09}}; + +//{04010201-0103-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_CodingEquations = +{0x04010201, 0x0103, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04180101-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_ImageAlignmentFactor = +{0x04180101, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010301-0600-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_FieldDominance = +{0x04010301, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04180102-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_FieldStartOffset = +{0x04180102, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04180103-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_FieldEndOffset = +{0x04180103, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04050113-0000-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_SignalStandard = +{0x04050113, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010302-0800-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_StoredF2Offset = +{0x04010302, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010302-0700-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_DisplayF2Offset = +{0x04010302, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010302-0900-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DigitalImageDescriptor_ActiveFormatDescriptor = +{0x04010302, 0x0900, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0a00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CDCIDescriptor_ComponentWidth = +{0x04010503, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010501-0500-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_CDCIDescriptor_HorizontalSubsampling = +{0x04010501, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010501-0600-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_CDCIDescriptor_ColorSiting = +{0x04010501, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010503-0300-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_CDCIDescriptor_BlackReferenceLevel = +{0x04010503, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010503-0400-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_CDCIDescriptor_WhiteReferenceLevel = +{0x04010503, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010503-0500-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CDCIDescriptor_ColorRange = +{0x04010503, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04180104-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CDCIDescriptor_PaddingBits = +{0x04180104, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010501-1000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CDCIDescriptor_VerticalSubsampling = +{0x04010501, 0x1000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010503-0700-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CDCIDescriptor_AlphaSamplingWidth = +{0x04010503, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010201-0a00-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_CDCIDescriptor_ReversedByteOrder = +{0x03010201, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0600-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_RGBADescriptor_PixelLayout = +{0x04010503, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010503-0800-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_RGBADescriptor_Palette = +{0x04010503, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010503-0900-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_RGBADescriptor_PaletteLayout = +{0x04010503, 0x0900, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010404-0100-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_RGBADescriptor_ScanningDirection = +{0x04010404, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0b00-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_RGBADescriptor_ComponentMaxRef = +{0x04010503, 0x0b00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0c00-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_RGBADescriptor_ComponentMinRef = +{0x04010503, 0x0c00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0d00-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_RGBADescriptor_AlphaMaxRef = +{0x04010503, 0x0d00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010503-0e00-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_RGBADescriptor_AlphaMinRef = +{0x04010503, 0x0e00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{05020103-0101-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TIFFDescriptor_IsUniform = +{0x05020103, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06080201-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_TIFFDescriptor_IsContiguous = +{0x06080201, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010302-0300-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_TIFFDescriptor_LeadingLines = +{0x04010302, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04010302-0400-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_TIFFDescriptor_TrailingLines = +{0x04010302, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{05020103-0102-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TIFFDescriptor_JPEGTableID = +{0x05020103, 0x0102, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03030302-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TIFFDescriptor_Summary = +{0x03030302, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03030302-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_WAVEDescriptor_Summary = +{0x03030302, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0108-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_FilmFormat = +{0x04100103, 0x0108, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010802-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_FrameRate = +{0x04010802, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0103-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_PerforationsPerFrame = +{0x04100103, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0203-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_FilmAspectRatio = +{0x04100103, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0106-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_Manufacturer = +{0x04100103, 0x0106, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0105-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_Model = +{0x04100103, 0x0105, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0104-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_FilmGaugeFormat = +{0x04100103, 0x0104, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100103-0107-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_FilmDescriptor_FilmBatchNumber = +{0x04100103, 0x0107, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0101-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_FormFactor = +{0x04100101, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04010401-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_VideoSignal = +{0x04010401, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0d010101-0101-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_TapeFormat = +{0x0d010101, 0x0101, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_Length = +{0x04100101, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0401-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_ManufacturerID = +{0x04100101, 0x0401, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_Model = +{0x04100101, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0601-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_TapeBatchNumber = +{0x04100101, 0x0601, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04100101-0501-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TapeDescriptor_TapeStock = +{0x04100101, 0x0501, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010201-0200-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_Header_ByteOrder = +{0x03010201, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{07020110-0204-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_LastModified = +{0x07020110, 0x0204, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_Content = +{0x06010104, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0202-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_Dictionary = +{0x06010104, 0x0202, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010201-0500-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_Version = +{0x03010201, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0604-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_IdentificationList = +{0x06010104, 0x0604, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010201-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Header_ObjectModelVersion = +{0x03010201, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01020203-0000-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_Header_OperationalPattern = +{0x01020203, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{01020210-0201-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_Header_EssenceContainers = +{0x01020210, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{01020210-0202-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_Header_DescriptiveSchemes = +{0x01020210, 0x0202, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{05200701-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_CompanyName = +{0x05200701, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0301-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_ProductName = +{0x05200701, 0x0301, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_ProductVersion = +{0x05200701, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0501-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_ProductVersionString = +{0x05200701, 0x0501, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0700-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_ProductID = +{0x05200701, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020110-0203-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_Date = +{0x07020110, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0a00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_ToolkitVersion = +{0x05200701, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0601-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_Platform = +{0x05200701, 0x0601, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05200701-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Identification_GenerationAUID = +{0x05200701, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01020101-0100-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_NetworkLocator_URLString = +{0x01020101, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{01040102-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TextLocator_Name = +{0x01040102, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01011510-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_Mob_MobID = +{0x01011510, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{01030302-0100-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_Mob_Name = +{0x01030302, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{06010104-0605-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Mob_Slots = +{0x06010104, 0x0605, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020110-0205-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Mob_LastModified = +{0x07020110, 0x0205, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020110-0103-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Mob_CreationTime = +{0x07020110, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020102-0c00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Mob_UserComments = +{0x03020102, 0x0c00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010210-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Mob_KLVData = +{0x03010210, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010210-0700-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Mob_Attributes = +{0x03010210, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{05010108-0000-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_Mob_UsageCode = +{0x05010108, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{07020201-0105-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_CompositionMob_DefaultFadeLength = +{0x07020201, 0x0105, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300201-0000-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_CompositionMob_DefFadeType = +{0x05300201, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{05300403-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_CompositionMob_DefFadeEditUnit = +{0x05300403, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-010a-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_CompositionMob_Rendering = +{0x06010104, 0x010a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{06010104-0203-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_SourceMob_EssenceDescription = +{0x06010104, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01070101-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MobSlot_SlotID = +{0x01070101, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01070102-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MobSlot_SlotName = +{0x01070102, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0204-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MobSlot_Segment = +{0x06010104, 0x0204, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01040103-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MobSlot_PhysicalTrackNumber = +{0x01040103, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300402-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_EventMobSlot_EditRate = +{0x05300402, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-010b-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_EventMobSlot_EventSlotOrigin = +{0x07020103, 0x010b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{05300405-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TimelineMobSlot_EditRate = +{0x05300405, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-0103-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TimelineMobSlot_Origin = +{0x07020103, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{07020103-010c-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_TimelineMobSlot_MarkIn = +{0x07020103, 0x010c, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{07020103-0203-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_TimelineMobSlot_MarkOut = +{0x07020103, 0x0203, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{07020103-010d-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_TimelineMobSlot_UserPos = +{0x07020103, 0x010d, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{06010104-0104-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_Parameter_Definition = +{0x06010104, 0x0104, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{05300507-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ConstantValue_Value = +{0x05300507, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0105-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_VaryingValue_Interpolation = +{0x06010104, 0x0105, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010104-0606-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_VaryingValue_PointList = +{0x06010104, 0x0606, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020102-0901-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TaggedValue_Name = +{0x03020102, 0x0901, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020102-0a01-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TaggedValue_Value = +{0x03020102, 0x0a01, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010210-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_KLVData_Value = +{0x03010210, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{01070105-0000-0000-060e-2b3401010104} +static const aafUID_t kAAFPropID_DescriptiveMarker_DescribedSlots = +{0x01070105, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04}}; + +//{06010104-020c-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DescriptiveMarker_Description = +{0x06010104, 0x020c, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020301-0101-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_SoundDescriptor_AudioSamplingRate = +{0x04020301, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020301-0400-0000-060e-2b3401010104} +static const aafUID_t kAAFPropID_SoundDescriptor_Locked = +{0x04020301, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04}}; + +//{04020101-0300-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_SoundDescriptor_AudioRefLevel = +{0x04020101, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04020101-0100-0000-060e-2b3401010101} +static const aafUID_t kAAFPropID_SoundDescriptor_ElectroSpatial = +{0x04020101, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01}}; + +//{04020101-0400-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_SoundDescriptor_Channels = +{0x04020101, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020303-0400-0000-060e-2b3401010104} +static const aafUID_t kAAFPropID_SoundDescriptor_QuantizationBits = +{0x04020303, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04}}; + +//{04020701-0000-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_SoundDescriptor_DialNorm = +{0x04020701, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020402-0000-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_SoundDescriptor_Compression = +{0x04020402, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{04030302-0000-0000-060e-2b3401010103} +static const aafUID_t kAAFPropID_DataEssenceDescriptor_DataEssenceCoding = +{0x04030302, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x03}}; + +//{06010104-060b-0000-060e-2b3401010104} +static const aafUID_t kAAFPropID_MultipleDescriptor_FileDescriptors = +{0x06010104, 0x060b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x04}}; + +//{01070106-0000-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_DescriptiveClip_DescribedSlotIDs = +{0x01070106, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0600-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_Emphasis = +{0x04020501, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020302-0300-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_BlockStartOffset = +{0x04020302, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0100-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_AuxBitsMode = +{0x04020501, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0200-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_ChannelStatusMode = +{0x04020501, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0300-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_FixedChannelStatusData = +{0x04020501, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0400-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_UserDataMode = +{0x04020501, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020501-0500-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_AES3PCMDescriptor_FixedUserData = +{0x04020501, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020302-0100-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_PCMDescriptor_BlockAlign = +{0x04020302, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020302-0200-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_PCMDescriptor_SequenceOffset = +{0x04020302, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020303-0500-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_PCMDescriptor_AverageBPS = +{0x04020303, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020101-0500-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_PCMDescriptor_ChannelAssignment = +{0x04020101, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{04020301-0600-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakEnvelopeVersion = +{0x04020301, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0700-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakEnvelopeFormat = +{0x04020301, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0800-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PointsPerPeakValue = +{0x04020301, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0900-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakEnvelopeBlockSize = +{0x04020301, 0x0900, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0a00-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakChannels = +{0x04020301, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0b00-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakFrames = +{0x04020301, 0x0b00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0c00-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakOfPeaksPosition = +{0x04020301, 0x0c00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0d00-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakEnvelopeTimestamp = +{0x04020301, 0x0d00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020301-0e00-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_PCMDescriptor_PeakEnvelopeData = +{0x04020301, 0x0e00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{06010104-0109-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_KLVDataDefinition_KLVDataType = +{0x06010104, 0x0109, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{04090201-0000-0000-060e-2b3401010107} +static const aafUID_t kAAFPropID_AuxiliaryDescriptor_MimeType = +{0x04090201, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x07}}; + +//{04090300-0000-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_AuxiliaryDescriptor_CharSet = +{0x04090300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04060802-0000-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_RIFFChunk_ChunkID = +{0x04060802, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04060903-0000-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_RIFFChunk_ChunkLength = +{0x04060903, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04070400-0000-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_RIFFChunk_ChunkData = +{0x04070400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04020302-0500-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyFileSecurityReport = +{0x04020302, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020302-0600-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyFileSecurityWave = +{0x04020302, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0101-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_BextCodingHistory = +{0x04020502, 0x0101, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0201-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyBasicData = +{0x04020502, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0301-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyStartOfModulation = +{0x04020502, 0x0301, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0401-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyQualityEvent = +{0x04020502, 0x0401, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0501-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyEndOfModulation = +{0x04020502, 0x0501, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0601-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyQualityParameter = +{0x04020502, 0x0601, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0701-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyOperatorComment = +{0x04020502, 0x0701, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04020502-0801-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_BWFImportDescriptor_QltyCueSheet = +{0x04020502, 0x0801, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{06010104-060f-0000-060e-2b3401010108} +static const aafUID_t kAAFPropID_BWFImportDescriptor_UnknownBWFChunks = +{0x06010104, 0x060f, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x08}}; + +//{04010602-0102-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_SingleSequence = +{0x04010602, 0x0102, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0103-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_ConstantBPictureCount = +{0x04010602, 0x0103, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0104-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_CodedContentScanning = +{0x04010602, 0x0104, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0105-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_LowDelay = +{0x04010602, 0x0105, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0106-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_ClosedGOP = +{0x04010602, 0x0106, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0107-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_IdenticalGOP = +{0x04010602, 0x0107, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0108-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_MaxGOP = +{0x04010602, 0x0108, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-0109-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_MaxBPictureCount = +{0x04010602, 0x0109, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-010b-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_BitRate = +{0x04010602, 0x010b, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{04010602-010a-0000-060e-2b3401010105} +static const aafUID_t kAAFPropID_MPEGVideoDescriptor_ProfileAndLevel = +{0x04010602, 0x010a, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x05}}; + +//{06010107-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ClassDefinition_ParentClass = +{0x06010107, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ClassDefinition_Properties = +{0x06010107, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_ClassDefinition_IsConcrete = +{0x06010107, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PropertyDefinition_Type = +{0x06010107, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010202-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PropertyDefinition_IsOptional = +{0x03010202, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0500-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PropertyDefinition_LocalIdentification = +{0x06010107, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0600-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_PropertyDefinition_IsUniqueIdentifier = +{0x06010107, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionInteger_Size = +{0x03010203, 0x0100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionInteger_IsSigned = +{0x03010203, 0x0200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0900-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionStrongObjectReference_ReferencedType = +{0x06010107, 0x0900, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0a00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionWeakObjectReference_ReferencedType = +{0x06010107, 0x0a00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0b00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionWeakObjectReference_TargetSet = +{0x03010203, 0x0b00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0b00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionEnumeration_ElementType = +{0x06010107, 0x0b00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0400-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionEnumeration_ElementNames = +{0x03010203, 0x0400, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0500-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionEnumeration_ElementValues = +{0x03010203, 0x0500, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0c00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionFixedArray_ElementType = +{0x06010107, 0x0c00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionFixedArray_ElementCount = +{0x03010203, 0x0300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0d00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionVariableArray_ElementType = +{0x06010107, 0x0d00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0e00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionSet_ElementType = +{0x06010107, 0x0e00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0f00-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionString_ElementType = +{0x06010107, 0x0f00, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-1100-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionRecord_MemberTypes = +{0x06010107, 0x1100, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0600-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionRecord_MemberNames = +{0x03010203, 0x0600, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-1200-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionRename_RenamedType = +{0x06010107, 0x1200, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0700-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionExtendibleEnumeration_ElementNames = +{0x03010203, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03010203-0800-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_TypeDefinitionExtendibleEnumeration_ElementValues = +{0x03010203, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-1300-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MetaDefinition_Identification = +{0x06010107, 0x1300, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{03020401-0201-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MetaDefinition_Name = +{0x03020401, 0x0201, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-1401-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MetaDefinition_Description = +{0x06010107, 0x1401, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0700-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MetaDictionary_ClassDefinitions = +{0x06010107, 0x0700, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{06010107-0800-0000-060e-2b3401010102} +static const aafUID_t kAAFPropID_MetaDictionary_TypeDefinitions = +{0x06010107, 0x0800, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +// Special property definition ids used for specifying the +// starting strong reference in the target list of a +// weak reference. +// +//{0d010301-0101-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_Root_MetaDictionary = +{0x0d010301, 0x0101, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + +//{0d010301-0102-0100-060e-2b3401010102} +static const aafUID_t kAAFPropID_Root_Header = +{0x0d010301, 0x0102, 0x0100, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x02}}; + + +#endif // ! __AAFPropertyDefs_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFPropertyIDs.h b/libs/aaf/aaf/AAFDefs/AAFPropertyIDs.h new file mode 100755 index 0000000000..6a0c223f80 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFPropertyIDs.h @@ -0,0 +1,364 @@ +#ifndef __AAFPropertyIDs_h__ +#define __AAFPropertyIDs_h__ + +// https://github.com/nevali/aaf/blob/a03404ad8dc371757f3847b8dae0a9d70fff6a4e/ref-impl/include/OM/OMDictionary.h +#define PID_Root_MetaDictionary 0x0001 +#define PID_Root_Header 0x0002 + + + + +// AAF property identifiers (PIDs). +// + +// A property is identified by a globally unique 16-byte +// identifier. To save space in an AAF file we store a +// 2-byte file unique PID with each property. +// The mapping for a particular file is recorded in the +// dictionary contained in that file. +// For the predefined properties we optimize by using a +// fixed, compiled-in mapping. +// This file defines that mapping. +// +#define PID_InterchangeObject_ObjClass 0x0101 +#define PID_InterchangeObject_Generation 0x0102 +#define PID_Component_DataDefinition 0x0201 +#define PID_Component_Length 0x0202 +#define PID_Component_KLVData 0x0203 +#define PID_Component_UserComments 0x0204 +#define PID_Component_Attributes 0x0205 +#define PID_EdgeCode_Start 0x0401 +#define PID_EdgeCode_FilmKind 0x0402 +#define PID_EdgeCode_CodeFormat 0x0403 +#define PID_EdgeCode_Header 0x0404 +#define PID_EssenceGroup_Choices 0x0501 +#define PID_EssenceGroup_StillFrame 0x0502 +#define PID_Event_Position 0x0601 +#define PID_Event_Comment 0x0602 +#define PID_GPITrigger_ActiveState 0x0801 +#define PID_CommentMarker_Annotation 0x0901 +#define PID_OperationGroup_Operation 0x0B01 +#define PID_OperationGroup_InputSegments 0x0B02 +#define PID_OperationGroup_Parameters 0x0B03 +#define PID_OperationGroup_BypassOverride 0x0B04 +#define PID_OperationGroup_Rendering 0x0B05 +#define PID_NestedScope_Slots 0x0C01 +#define PID_Pulldown_InputSegment 0x0D01 +#define PID_Pulldown_PulldownKind 0x0D02 +#define PID_Pulldown_PulldownDirection 0x0D03 +#define PID_Pulldown_PhaseFrame 0x0D04 +#define PID_ScopeReference_RelativeScope 0x0E01 +#define PID_ScopeReference_RelativeSlot 0x0E02 +#define PID_Selector_Selected 0x0F01 +#define PID_Selector_Alternates 0x0F02 +#define PID_Sequence_Components 0x1001 +#define PID_SourceReference_SourceID 0x1101 +#define PID_SourceReference_SourceMobSlotID 0x1102 +#define PID_SourceReference_ChannelIDs 0x1103 +#define PID_SourceReference_MonoSourceSlotIDs 0x1104 +#define PID_SourceClip_StartTime 0x1201 +#define PID_SourceClip_FadeInLength 0x1202 +#define PID_SourceClip_FadeInType 0x1203 +#define PID_SourceClip_FadeOutLength 0x1204 +#define PID_SourceClip_FadeOutType 0x1205 +#define PID_HTMLClip_BeginAnchor 0x1401 +#define PID_HTMLClip_EndAnchor 0x1402 +#define PID_Timecode_Start 0x1501 +#define PID_Timecode_FPS 0x1502 +#define PID_Timecode_Drop 0x1503 +#define PID_TimecodeStream_SampleRate 0x1601 +#define PID_TimecodeStream_Source 0x1602 +#define PID_TimecodeStream_SourceType 0x1603 +#define PID_TimecodeStream12M_IncludeSync 0x1701 +#define PID_Transition_OperationGroup 0x1801 +#define PID_Transition_CutPoint 0x1802 +#define PID_ContentStorage_Mobs 0x1901 +#define PID_ContentStorage_EssenceData 0x1902 +#define PID_ControlPoint_Value 0x1A02 +#define PID_ControlPoint_Time 0x1A03 +#define PID_ControlPoint_EditHint 0x1A04 +#define PID_DefinitionObject_Identification 0x1B01 +#define PID_DefinitionObject_Name 0x1B02 +#define PID_DefinitionObject_Description 0x1B03 +#define PID_OperationDefinition_DataDefinition 0x1E01 +#define PID_OperationDefinition_IsTimeWarp 0x1E02 +#define PID_OperationDefinition_DegradeTo 0x1E03 +#define PID_OperationDefinition_OperationCategory 0x1E06 +#define PID_OperationDefinition_NumberInputs 0x1E07 +#define PID_OperationDefinition_Bypass 0x1E08 +#define PID_OperationDefinition_ParametersDefined 0x1E09 +#define PID_ParameterDefinition_Type 0x1F01 +#define PID_ParameterDefinition_DisplayUnits 0x1F03 +#define PID_PluginDefinition_PluginCategory 0x2203 +#define PID_PluginDefinition_VersionNumber 0x2204 +#define PID_PluginDefinition_VersionString 0x2205 +#define PID_PluginDefinition_Manufacturer 0x2206 +#define PID_PluginDefinition_ManufacturerInfo 0x2207 +#define PID_PluginDefinition_ManufacturerID 0x2208 +#define PID_PluginDefinition_Platform 0x2209 +#define PID_PluginDefinition_MinPlatformVersion 0x220A +#define PID_PluginDefinition_MaxPlatformVersion 0x220B +#define PID_PluginDefinition_Engine 0x220C +#define PID_PluginDefinition_MinEngineVersion 0x220D +#define PID_PluginDefinition_MaxEngineVersion 0x220E +#define PID_PluginDefinition_PluginAPI 0x220F +#define PID_PluginDefinition_MinPluginAPI 0x2210 +#define PID_PluginDefinition_MaxPluginAPI 0x2211 +#define PID_PluginDefinition_SoftwareOnly 0x2212 +#define PID_PluginDefinition_Accelerator 0x2213 +#define PID_PluginDefinition_Locators 0x2214 +#define PID_PluginDefinition_Authentication 0x2215 +#define PID_PluginDefinition_DefinitionObject 0x2216 +#define PID_CodecDefinition_FileDescriptorClass 0x2301 +#define PID_CodecDefinition_DataDefinitions 0x2302 +#define PID_ContainerDefinition_EssenceIsIdentified 0x2401 +#define PID_Dictionary_OperationDefinitions 0x2603 +#define PID_Dictionary_ParameterDefinitions 0x2604 +#define PID_Dictionary_DataDefinitions 0x2605 +#define PID_Dictionary_PluginDefinitions 0x2606 +#define PID_Dictionary_CodecDefinitions 0x2607 +#define PID_Dictionary_ContainerDefinitions 0x2608 +#define PID_Dictionary_InterpolationDefinitions 0x2609 +#define PID_Dictionary_KLVDataDefinitions 0x260A +#define PID_Dictionary_TaggedValueDefinitions 0x260B +#define PID_EssenceData_MobID 0x2701 +#define PID_EssenceData_Data 0x2702 +#define PID_EssenceData_SampleIndex 0x2B01 +#define PID_EssenceDescriptor_Locator 0x2F01 +#define PID_FileDescriptor_SampleRate 0x3001 +#define PID_FileDescriptor_Length 0x3002 +#define PID_FileDescriptor_ContainerFormat 0x3004 +#define PID_FileDescriptor_CodecDefinition 0x3005 +#define PID_FileDescriptor_LinkedSlotID 0x3006 +#define PID_AIFCDescriptor_Summary 0x3101 +#define PID_DigitalImageDescriptor_Compression 0x3201 +#define PID_DigitalImageDescriptor_StoredHeight 0x3202 +#define PID_DigitalImageDescriptor_StoredWidth 0x3203 +#define PID_DigitalImageDescriptor_SampledHeight 0x3204 +#define PID_DigitalImageDescriptor_SampledWidth 0x3205 +#define PID_DigitalImageDescriptor_SampledXOffset 0x3206 +#define PID_DigitalImageDescriptor_SampledYOffset 0x3207 +#define PID_DigitalImageDescriptor_DisplayHeight 0x3208 +#define PID_DigitalImageDescriptor_DisplayWidth 0x3209 +#define PID_DigitalImageDescriptor_DisplayXOffset 0x320A +#define PID_DigitalImageDescriptor_DisplayYOffset 0x320B +#define PID_DigitalImageDescriptor_FrameLayout 0x320C +#define PID_DigitalImageDescriptor_VideoLineMap 0x320D +#define PID_DigitalImageDescriptor_ImageAspectRatio 0x320E +#define PID_DigitalImageDescriptor_AlphaTransparency 0x320F +#define PID_DigitalImageDescriptor_TransferCharacteristic 0x3210 +#define PID_DigitalImageDescriptor_ColorPrimaries 0x3219 +#define PID_DigitalImageDescriptor_CodingEquations 0x321A +#define PID_DigitalImageDescriptor_ImageAlignmentFactor 0x3211 +#define PID_DigitalImageDescriptor_FieldDominance 0x3212 +#define PID_DigitalImageDescriptor_FieldStartOffset 0x3213 +#define PID_DigitalImageDescriptor_FieldEndOffset 0x3214 +#define PID_DigitalImageDescriptor_SignalStandard 0x3215 +#define PID_DigitalImageDescriptor_StoredF2Offset 0x3216 +#define PID_DigitalImageDescriptor_DisplayF2Offset 0x3217 +#define PID_DigitalImageDescriptor_ActiveFormatDescriptor 0x3218 +#define PID_CDCIDescriptor_ComponentWidth 0x3301 +#define PID_CDCIDescriptor_HorizontalSubsampling 0x3302 +#define PID_CDCIDescriptor_ColorSiting 0x3303 +#define PID_CDCIDescriptor_BlackReferenceLevel 0x3304 +#define PID_CDCIDescriptor_WhiteReferenceLevel 0x3305 +#define PID_CDCIDescriptor_ColorRange 0x3306 +#define PID_CDCIDescriptor_PaddingBits 0x3307 +#define PID_CDCIDescriptor_VerticalSubsampling 0x3308 +#define PID_CDCIDescriptor_AlphaSamplingWidth 0x3309 +#define PID_CDCIDescriptor_ReversedByteOrder 0x330B +#define PID_RGBADescriptor_PixelLayout 0x3401 +#define PID_RGBADescriptor_Palette 0x3403 +#define PID_RGBADescriptor_PaletteLayout 0x3404 +#define PID_RGBADescriptor_ScanningDirection 0x3405 +#define PID_RGBADescriptor_ComponentMaxRef 0x3406 +#define PID_RGBADescriptor_ComponentMinRef 0x3407 +#define PID_RGBADescriptor_AlphaMaxRef 0x3408 +#define PID_RGBADescriptor_AlphaMinRef 0x3409 +#define PID_TIFFDescriptor_IsUniform 0x3701 +#define PID_TIFFDescriptor_IsContiguous 0x3702 +#define PID_TIFFDescriptor_LeadingLines 0x3703 +#define PID_TIFFDescriptor_TrailingLines 0x3704 +#define PID_TIFFDescriptor_JPEGTableID 0x3705 +#define PID_TIFFDescriptor_Summary 0x3706 +#define PID_WAVEDescriptor_Summary 0x3801 +#define PID_FilmDescriptor_FilmFormat 0x3901 +#define PID_FilmDescriptor_FrameRate 0x3902 +#define PID_FilmDescriptor_PerforationsPerFrame 0x3903 +#define PID_FilmDescriptor_FilmAspectRatio 0x3904 +#define PID_FilmDescriptor_Manufacturer 0x3905 +#define PID_FilmDescriptor_Model 0x3906 +#define PID_FilmDescriptor_FilmGaugeFormat 0x3907 +#define PID_FilmDescriptor_FilmBatchNumber 0x3908 +#define PID_TapeDescriptor_FormFactor 0x3A01 +#define PID_TapeDescriptor_VideoSignal 0x3A02 +#define PID_TapeDescriptor_TapeFormat 0x3A03 +#define PID_TapeDescriptor_Length 0x3A04 +#define PID_TapeDescriptor_ManufacturerID 0x3A05 +#define PID_TapeDescriptor_Model 0x3A06 +#define PID_TapeDescriptor_TapeBatchNumber 0x3A07 +#define PID_TapeDescriptor_TapeStock 0x3A08 +#define PID_Header_ByteOrder 0x3B01 +#define PID_Header_LastModified 0x3B02 +#define PID_Header_Content 0x3B03 +#define PID_Header_Dictionary 0x3B04 +#define PID_Header_Version 0x3B05 +#define PID_Header_IdentificationList 0x3B06 +#define PID_Header_ObjectModelVersion 0x3B07 +#define PID_Header_OperationalPattern 0x3B09 +#define PID_Header_EssenceContainers 0x3B0A +#define PID_Header_DescriptiveSchemes 0x3B0B +#define PID_Identification_CompanyName 0x3C01 +#define PID_Identification_ProductName 0x3C02 +#define PID_Identification_ProductVersion 0x3C03 +#define PID_Identification_ProductVersionString 0x3C04 +#define PID_Identification_ProductID 0x3C05 +#define PID_Identification_Date 0x3C06 +#define PID_Identification_ToolkitVersion 0x3C07 +#define PID_Identification_Platform 0x3C08 +#define PID_Identification_GenerationAUID 0x3C09 +#define PID_NetworkLocator_URLString 0x4001 +#define PID_TextLocator_Name 0x4101 +#define PID_Mob_MobID 0x4401 +#define PID_Mob_Name 0x4402 +#define PID_Mob_Slots 0x4403 +#define PID_Mob_LastModified 0x4404 +#define PID_Mob_CreationTime 0x4405 +#define PID_Mob_UserComments 0x4406 +#define PID_Mob_KLVData 0x4407 +#define PID_Mob_Attributes 0x4409 +#define PID_Mob_UsageCode 0x4408 +#define PID_CompositionMob_DefaultFadeLength 0x4501 +#define PID_CompositionMob_DefFadeType 0x4502 +#define PID_CompositionMob_DefFadeEditUnit 0x4503 +#define PID_CompositionMob_Rendering 0x4504 +#define PID_SourceMob_EssenceDescription 0x4701 +#define PID_MobSlot_SlotID 0x4801 +#define PID_MobSlot_SlotName 0x4802 +#define PID_MobSlot_Segment 0x4803 +#define PID_MobSlot_PhysicalTrackNumber 0x4804 +#define PID_EventMobSlot_EditRate 0x4901 +#define PID_EventMobSlot_EventSlotOrigin 0x4902 +#define PID_TimelineMobSlot_EditRate 0x4B01 +#define PID_TimelineMobSlot_Origin 0x4B02 +#define PID_TimelineMobSlot_MarkIn 0x4B03 +#define PID_TimelineMobSlot_MarkOut 0x4B04 +#define PID_TimelineMobSlot_UserPos 0x4B05 +#define PID_Parameter_Definition 0x4C01 +#define PID_ConstantValue_Value 0x4D01 +#define PID_VaryingValue_Interpolation 0x4E01 +#define PID_VaryingValue_PointList 0x4E02 +#define PID_TaggedValue_Name 0x5001 +#define PID_TaggedValue_Value 0x5003 +#define PID_KLVData_Value 0x5101 +#define PID_DescriptiveMarker_DescribedSlots 0x6102 +#define PID_DescriptiveMarker_Description 0x6101 +#define PID_SoundDescriptor_AudioSamplingRate 0x3D03 +#define PID_SoundDescriptor_Locked 0x3D02 +#define PID_SoundDescriptor_AudioRefLevel 0x3D04 +#define PID_SoundDescriptor_ElectroSpatial 0x3D05 +#define PID_SoundDescriptor_Channels 0x3D07 +#define PID_SoundDescriptor_QuantizationBits 0x3D01 +#define PID_SoundDescriptor_DialNorm 0x3D0C +#define PID_SoundDescriptor_Compression 0x3D06 +#define PID_DataEssenceDescriptor_DataEssenceCoding 0x3E01 +#define PID_MultipleDescriptor_FileDescriptors 0x3F01 +#define PID_DescriptiveClip_DescribedSlotIDs 0x6103 +#define PID_AES3PCMDescriptor_Emphasis 0x3D0D +#define PID_AES3PCMDescriptor_BlockStartOffset 0x3D0F +#define PID_AES3PCMDescriptor_AuxBitsMode 0x3D08 +#define PID_AES3PCMDescriptor_ChannelStatusMode 0x3D10 +#define PID_AES3PCMDescriptor_FixedChannelStatusData 0x3D11 +#define PID_AES3PCMDescriptor_UserDataMode 0x3D12 +#define PID_AES3PCMDescriptor_FixedUserData 0x3D13 +#define PID_PCMDescriptor_BlockAlign 0x3D0A +#define PID_PCMDescriptor_SequenceOffset 0x3D0B +#define PID_PCMDescriptor_AverageBPS 0x3D09 +#define PID_PCMDescriptor_ChannelAssignment 0x3D32 +#define PID_PCMDescriptor_PeakEnvelopeVersion 0x3D29 +#define PID_PCMDescriptor_PeakEnvelopeFormat 0x3D2A +#define PID_PCMDescriptor_PointsPerPeakValue 0x3D2B +#define PID_PCMDescriptor_PeakEnvelopeBlockSize 0x3D2C +#define PID_PCMDescriptor_PeakChannels 0x3D2D +#define PID_PCMDescriptor_PeakFrames 0x3D2E +#define PID_PCMDescriptor_PeakOfPeaksPosition 0x3D2F +#define PID_PCMDescriptor_PeakEnvelopeTimestamp 0x3D30 +#define PID_PCMDescriptor_PeakEnvelopeData 0x3D31 +#define PID_KLVDataDefinition_KLVDataType 0x4D12 +#define PID_AuxiliaryDescriptor_MimeType 0x4E11 +#define PID_AuxiliaryDescriptor_CharSet 0x4E12 +#define PID_RIFFChunk_ChunkID 0x4F01 +#define PID_RIFFChunk_ChunkLength 0x4F02 +#define PID_RIFFChunk_ChunkData 0x4F03 +#define PID_BWFImportDescriptor_QltyFileSecurityReport 0x3D15 +#define PID_BWFImportDescriptor_QltyFileSecurityWave 0x3D16 +#define PID_BWFImportDescriptor_BextCodingHistory 0x3D21 +#define PID_BWFImportDescriptor_QltyBasicData 0x3D22 +#define PID_BWFImportDescriptor_QltyStartOfModulation 0x3D23 +#define PID_BWFImportDescriptor_QltyQualityEvent 0x3D24 +#define PID_BWFImportDescriptor_QltyEndOfModulation 0x3D25 +#define PID_BWFImportDescriptor_QltyQualityParameter 0x3D26 +#define PID_BWFImportDescriptor_QltyOperatorComment 0x3D27 +#define PID_BWFImportDescriptor_QltyCueSheet 0x3D28 +#define PID_BWFImportDescriptor_UnknownBWFChunks 0x3D33 + +#define PID_MPEGVideoDescriptor_SingleSequence 0x0000 +#define PID_MPEGVideoDescriptor_ConstantBPictureCount 0x0000 +#define PID_MPEGVideoDescriptor_CodedContentScanning 0x0000 +#define PID_MPEGVideoDescriptor_LowDelay 0x0000 +#define PID_MPEGVideoDescriptor_ClosedGOP 0x0000 +#define PID_MPEGVideoDescriptor_IdenticalGOP 0x0000 +#define PID_MPEGVideoDescriptor_MaxGOP 0x0000 +#define PID_MPEGVideoDescriptor_MaxBPictureCount 0x0000 +#define PID_MPEGVideoDescriptor_BitRate 0x0000 +#define PID_MPEGVideoDescriptor_ProfileAndLevel 0x0000 + +/* MULTIPLE_VALUE_MATCHES + https://sourceforge.net/p/aaf/mailman/aaf-commits/?viewmonth=200704&page=4 + "Log message : Set MPEGVideoDescriptor PIDs to 0x0000 (dynamic)" + +! const int PID_MPEGVideoDescriptor_SingleSequence = 0xFF01; +! const int PID_MPEGVideoDescriptor_ConstantBPictureCount = 0xFF02; +! const int PID_MPEGVideoDescriptor_CodedContentScanning = 0xFF03; +! const int PID_MPEGVideoDescriptor_LowDelay = 0xFF04; +! const int PID_MPEGVideoDescriptor_ClosedGOP = 0xFF05; +! const int PID_MPEGVideoDescriptor_IdenticalGOP = 0xFF06; +! const int PID_MPEGVideoDescriptor_MaxGOP = 0xFF07; +! const int PID_MPEGVideoDescriptor_MaxBPictureCount = 0xFF08; +! const int PID_MPEGVideoDescriptor_BitRate = 0xFF09; +! const int PID_MPEGVideoDescriptor_ProfileAndLevel = 0xFF10; +*/ + + +#define PID_ClassDefinition_ParentClass 0x0008 +#define PID_ClassDefinition_Properties 0x0009 +#define PID_ClassDefinition_IsConcrete 0x000A +#define PID_PropertyDefinition_Type 0x000B +#define PID_PropertyDefinition_IsOptional 0x000C +#define PID_PropertyDefinition_LocalIdentification 0x000D +#define PID_PropertyDefinition_IsUniqueIdentifier 0x000E +#define PID_TypeDefinitionInteger_Size 0x000F +#define PID_TypeDefinitionInteger_IsSigned 0x0010 +#define PID_TypeDefinitionStrongObjectReference_ReferencedType 0x0011 +#define PID_TypeDefinitionWeakObjectReference_ReferencedType 0x0012 +#define PID_TypeDefinitionWeakObjectReference_TargetSet 0x0013 +#define PID_TypeDefinitionEnumeration_ElementType 0x0014 +#define PID_TypeDefinitionEnumeration_ElementNames 0x0015 +#define PID_TypeDefinitionEnumeration_ElementValues 0x0016 +#define PID_TypeDefinitionFixedArray_ElementType 0x0017 +#define PID_TypeDefinitionFixedArray_ElementCount 0x0018 +#define PID_TypeDefinitionVariableArray_ElementType 0x0019 +#define PID_TypeDefinitionSet_ElementType 0x001A +#define PID_TypeDefinitionString_ElementType 0x001B +#define PID_TypeDefinitionRecord_MemberTypes 0x001C +#define PID_TypeDefinitionRecord_MemberNames 0x001D +#define PID_TypeDefinitionRename_RenamedType 0x001E +#define PID_TypeDefinitionExtendibleEnumeration_ElementNames 0x001F +#define PID_TypeDefinitionExtendibleEnumeration_ElementValues 0x0020 +#define PID_MetaDefinition_Identification 0x0005 +#define PID_MetaDefinition_Name 0x0006 +#define PID_MetaDefinition_Description 0x0007 +#define PID_MetaDictionary_ClassDefinitions 0x0003 +#define PID_MetaDictionary_TypeDefinitions 0x0004 + +#endif // ! __AAFPropertyIDs_h__ diff --git a/libs/aaf/aaf/AAFDefs/AAFTypeDefUIDs.h b/libs/aaf/aaf/AAFDefs/AAFTypeDefUIDs.h new file mode 100755 index 0000000000..c1a8bb4bb9 --- /dev/null +++ b/libs/aaf/aaf/AAFDefs/AAFTypeDefUIDs.h @@ -0,0 +1,627 @@ +#ifndef __AAFTypeDefUIDs_h__ +#define __AAFTypeDefUIDs_h__ + +#include "aaf/AAFTypes.h" + +// AAF type definition UIDs. +// + +//{01010100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt8 = +{0x01010100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt16 = +{0x01010200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt32 = +{0x01010300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt64 = +{0x01010400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int8 = +{0x01010500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int16 = +{0x01010600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int32 = +{0x01010700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01010800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int64 = +{0x01010800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01012001-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PositionType = +{0x01012001, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01012002-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_LengthType = +{0x01012002, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01012003-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_JPEGTableIDType = +{0x01012003, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01012300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PhaseFrameType = +{0x01012300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01030100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_AUID = +{0x01030100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01030200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobIDType = +{0x01030200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01040100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Boolean = +{0x01040100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01100100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Character = +{0x01100100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{01100200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_String = +{0x01100200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010101-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ProductReleaseType = +{0x02010101, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010102-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TapeFormatType = +{0x02010102, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010103-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_VideoSignalType = +{0x02010103, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010104-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TapeCaseType = +{0x02010104, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010105-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ColorSitingType = +{0x02010105, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010106-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EditHintType = +{0x02010106, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010107-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_FadeType = +{0x02010107, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010108-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_LayoutType = +{0x02010108, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010109-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TCSource = +{0x02010109, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010a-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PulldownDirectionType = +{0x0201010a, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010b-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PulldownKindType = +{0x0201010b, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010c-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EdgeType = +{0x0201010c, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010d-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_FilmType = +{0x0201010d, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010e-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_RGBAComponentKind = +{0x0201010e, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201010f-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ReferenceType = +{0x0201010f, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010120-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_AlphaTransparencyType = +{0x02010120, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010121-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_FieldNumber = +{0x02010121, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010122-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ElectroSpatialFormulation = +{0x02010122, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010123-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EmphasisType = +{0x02010123, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010124-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_AuxBitsModeType = +{0x02010124, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010125-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ChannelStatusModeType = +{0x02010125, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010126-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UserDataModeType = +{0x02010126, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010127-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SignalStandardType = +{0x02010127, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02010128-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ScanningDirectionType = +{0x02010128, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201012a-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ContentScanningType = +{0x0201012a, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{0201012b-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TitleAlignmentType = +{0x0201012b, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020101-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationCategoryType = +{0x02020101, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020102-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TransferCharacteristicType = +{0x02020102, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020103-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PluginCategoryType = +{0x02020103, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020104-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UsageType = +{0x02020104, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020105-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ColorPrimariesType = +{0x02020105, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{02020106-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_CodingEquationsType = +{0x02020106, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Rational = +{0x03010100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ProductVersion = +{0x03010200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_VersionType = +{0x03010300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_RGBAComponent = +{0x03010400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DateStruct = +{0x03010500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TimeStruct = +{0x03010600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{03010700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TimeStamp = +{0x03010700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt8Array = +{0x04010100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt8Array12 = +{0x04010200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int32Array = +{0x04010300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Int64Array = +{0x04010400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_StringArray = +{0x04010500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_AUIDArray = +{0x04010600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PositionArray = +{0x04010700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt8Array8 = +{0x04010800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt32Array = +{0x04010900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ChannelStatusModeArray = +{0x04010a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04010b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UserDataModeArray = +{0x04010b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04020100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_RGBALayout = +{0x04020100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04030100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_AUIDSet = +{0x04030100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04030200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_UInt32Set = +{0x04030200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04100100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataValue = +{0x04100100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04100200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Stream = +{0x04100200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04100300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Indirect = +{0x04100300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{04100400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_Opaque = +{0x04100400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ClassDefinitionWeakReference = +{0x05010100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ContainerDefinitionWeakReference = +{0x05010200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataDefinitionWeakReference = +{0x05010300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_InterpolationDefinitionWeakReference = +{0x05010500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobWeakReference = +{0x05010600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationDefinitionWeakReference = +{0x05010700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterDefinitionWeakReference = +{0x05010800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TypeDefinitionWeakReference = +{0x05010900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PluginDefinitionWeakReference = +{0x05010a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_CodecDefinitionWeakReference = +{0x05010b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05010c00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PropertyDefinitionWeakReference = +{0x05010c00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ContentStorageStrongReference = +{0x05020100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DictionaryStrongReference = +{0x05020200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EssenceDescriptorStrongReference = +{0x05020300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_NetworkLocatorStrongReference = +{0x05020400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationGroupStrongReference = +{0x05020500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SegmentStrongReference = +{0x05020600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SourceClipStrongReference = +{0x05020700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SourceReferenceStrongReference = +{0x05020800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ClassDefinitionStrongReference = +{0x05020900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_CodecDefinitionStrongReference = +{0x05020a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ComponentStrongReference = +{0x05020b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020c00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ContainerDefinitionStrongReference = +{0x05020c00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020d00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ControlPointStrongReference = +{0x05020d00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020e00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataDefinitionStrongReference = +{0x05020e00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05020f00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EssenceDataStrongReference = +{0x05020f00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021000-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_IdentificationStrongReference = +{0x05021000, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_InterpolationDefinitionStrongReference = +{0x05021100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_LocatorStrongReference = +{0x05021200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobStrongReference = +{0x05021300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobSlotStrongReference = +{0x05021400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationDefinitionStrongReference = +{0x05021500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterStrongReference = +{0x05021600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterDefinitionStrongReference = +{0x05021700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PluginDefinitionStrongReference = +{0x05021800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PropertyDefinitionStrongReference = +{0x05021900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TaggedValueStrongReference = +{0x05021a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TypeDefinitionStrongReference = +{0x05021b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021c00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_KLVDataStrongReference = +{0x05021c00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021d00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_FileDescriptorStrongReference = +{0x05021d00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021e00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_RIFFChunkStrongReference = +{0x05021e00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05021f00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DescriptiveFrameworkStrongReference = +{0x05021f00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05022000-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_KLVDataDefinitionStrongReference = +{0x05022000, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05022100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TaggedValueDefinitionStrongReference = +{0x05022100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05022200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DescriptiveObjectStrongReference = +{0x05022200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05030d00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataDefinitionWeakReferenceSet = +{0x05030d00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05030e00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterDefinitionWeakReferenceSet = +{0x05030e00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05030f00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PluginDefinitionWeakReferenceSet = +{0x05030f00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05031000-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PropertyDefinitionWeakReferenceSet = +{0x05031000, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05040100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationDefinitionWeakReferenceVector = +{0x05040100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05040200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TypeDefinitionWeakReferenceVector = +{0x05040200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05040300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataDefinitionWeakReferenceVector = +{0x05040300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ClassDefinitionStrongReferenceSet = +{0x05050100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_CodecDefinitionStrongReferenceSet = +{0x05050200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ContainerDefinitionStrongReferenceSet = +{0x05050300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DataDefinitionStrongReferenceSet = +{0x05050400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_EssenceDataStrongReferenceSet = +{0x05050500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_InterpolationDefinitionStrongReferenceSet = +{0x05050600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobStrongReferenceSet = +{0x05050700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_OperationDefinitionStrongReferenceSet = +{0x05050800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterDefinitionStrongReferenceSet = +{0x05050900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PluginDefinitionStrongReferenceSet = +{0x05050a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_PropertyDefinitionStrongReferenceSet = +{0x05050b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050c00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TypeDefinitionStrongReferenceSet = +{0x05050c00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050d00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_KLVDataDefinitionStrongReferenceSet = +{0x05050d00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050e00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TaggedValueDefinitionStrongReferenceSet = +{0x05050e00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05050f00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DescriptiveObjectStrongReferenceSet = +{0x05050f00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060100-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ComponentStrongReferenceVector = +{0x05060100, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060200-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ControlPointStrongReferenceVector = +{0x05060200, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060300-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_IdentificationStrongReferenceVector = +{0x05060300, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060400-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_LocatorStrongReferenceVector = +{0x05060400, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060500-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_MobSlotStrongReferenceVector = +{0x05060500, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060600-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SegmentStrongReferenceVector = +{0x05060600, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060700-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_SourceReferenceStrongReferenceVector = +{0x05060700, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060800-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_TaggedValueStrongReferenceVector = +{0x05060800, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060900-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_KLVDataStrongReferenceVector = +{0x05060900, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060a00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_ParameterStrongReferenceVector = +{0x05060a00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060b00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_FileDescriptorStrongReferenceVector = +{0x05060b00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060c00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_RIFFChunkStrongReferenceVector = +{0x05060c00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + +//{05060d00-0000-0000-060e-2b3401040101} +static const aafUID_t AAFTypeID_DescriptiveObjectStrongReferenceVector = +{0x05060d00, 0x0000, 0x0000, {0x06, 0x0e, 0x2b, 0x34, 0x01, 0x04, 0x01, 0x01}}; + + + +#endif // ! __AAFTypeDefUIDs_h__ diff --git a/libs/aaf/aaf/AAFDump.h b/libs/aaf/aaf/AAFDump.h new file mode 100644 index 0000000000..9ced4b6ad7 --- /dev/null +++ b/libs/aaf/aaf/AAFDump.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFDump_h__ +#define __AAFDump_h__ + +#include "aaf/AAFCore.h" +#include "aaf/AAFTypes.h" +#include "aaf/LibCFB.h" + +void +aaf_dump_Header (AAF_Data* aafd); + +void +aaf_dump_Identification (AAF_Data* aafd); + +void +aaf_dump_rawProperties (AAF_Data* aafd, aafByte_t* propStream); + +void +aaf_dump_ObjectProperty (AAF_Data* aafd, aafProperty* Prop); + +void +aaf_dump_ObjectProperties (AAF_Data* aafd, aafObject* Obj); + +void +aaf_dump_nodeStreamProperties (AAF_Data* aafd, cfbNode* node); + +void +aaf_dump_MetaDictionary (AAF_Data* aafd); + +void +aaf_dump_Classes (AAF_Data* aafd); + +#endif // ! __AAFDump_h__ diff --git a/libs/aaf/aaf/AAFIAudioFiles.h b/libs/aaf/aaf/AAFIAudioFiles.h new file mode 100644 index 0000000000..c27007dc78 --- /dev/null +++ b/libs/aaf/aaf/AAFIAudioFiles.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFIAudioFiles_h__ +#define __AAFIAudioFiles_h__ + +#include + +#include "aaf/AAFIface.h" + +char* +aafi_locate_external_essence_file (AAF_Iface* aafi, const wchar_t* original_file_path, const char* search_location); + +int +aafi_extract_audio_essence (AAF_Iface* aafi, aafiAudioEssence* audioEssence, const char* outfilepath, const wchar_t* forcedFileName); + +int +aafi_parse_audio_summary (AAF_Iface* aafi, aafiAudioEssence* audioEssence); + +#endif // !__AAFIAudioFiles_h__ diff --git a/libs/aaf/aaf/AAFIParser.h b/libs/aaf/aaf/AAFIParser.h new file mode 100644 index 0000000000..304894bb92 --- /dev/null +++ b/libs/aaf/aaf/AAFIParser.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFIParser_h__ +#define __AAFIParser_h__ + +/** + * @file LibAAF/AAFIface/AAFIParser.h + * @brief AAF processing + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 27 june 2018 + * + * @ingroup AAFIface + * @addtogroup AAFIface + * @{ + */ + +#include "aaf/AAFCore.h" +#include "aaf/AAFIface.h" + +enum trace_dump_state { + TD_OK = 0, + TD_INFO, + TD_WARNING, + TD_ERROR, + TD_NOT_SUPPORTED +}; + +typedef struct trace_dump { + int fn; // line number of current __td + int pfn; // line number of previous __td + int lv; // current level + int* ll; // level loop : each entry correspond to a level and tell if there is more to print + int eob; // end of branch + int hc; // have children + int sub; +} td; + +#define __td_set(__td, __ptd, offset) \ + __td.fn = __LINE__; \ + __td.pfn = __ptd->fn; \ + __td.lv = __ptd->lv + offset; \ + __td.ll = __ptd->ll; \ + __td.ll[__td.lv] = (offset > 0) ? 0 : __td.ll[__td.lv]; \ + __td.eob = 0; \ + __td.hc = 0; \ + __td.sub = 0; + +#define DUMP_OBJ(aafi, Obj, __td) \ + aafi_dump_obj (aafi, Obj, __td, TD_OK, __LINE__, ""); + +#define DUMP_OBJ_INFO(aafi, Obj, __td, ...) \ + aafi_dump_obj (aafi, Obj, __td, TD_OK, __LINE__, __VA_ARGS__); + +#define DUMP_OBJ_WARNING(aafi, Obj, __td, ...) \ + aafi_dump_obj (aafi, Obj, __td, TD_WARNING, __LINE__, __VA_ARGS__); + +#define DUMP_OBJ_ERROR(aafi, Obj, __td, ...) \ + (__td)->eob = 1; \ + aafi_dump_obj (aafi, Obj, __td, TD_ERROR, __LINE__, __VA_ARGS__); + +#define DUMP_OBJ_NO_SUPPORT(aafi, Obj, __td) \ + (__td)->eob = 1; \ + aafi_dump_obj_no_support (aafi, Obj, __td, __LINE__); + +int +aafi_retrieveData (AAF_Iface* aafi); + +/* + * The following functions are declared beyond AAFIparser.c scope, + * so they are accessible to vendor-specific files (Resolve.c, ProTools.c, etc.) + */ + +void +aafi_dump_obj (AAF_Iface* aafi, aafObject* Obj, struct trace_dump* __td, int state, int line, const char* fmt, ...); + +void +aafi_dump_obj_no_support (AAF_Iface* aafi, aafObject* Obj, struct trace_dump* __td, int line); + +void +aafi_trace_obj (AAF_Iface* aafi, aafObject* Obj, const char* color); + +int +aafi_parse_Segment (AAF_Iface* aafi, aafObject* Segment, td* __ptd); + +#endif // !__AAFIParser_h__ diff --git a/libs/aaf/aaf/AAFIface.h b/libs/aaf/aaf/AAFIface.h new file mode 100644 index 0000000000..4f074006dd --- /dev/null +++ b/libs/aaf/aaf/AAFIface.h @@ -0,0 +1,861 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFIface_h__ +#define __AAFIface_h__ + +/** + * @file LibAAF/AAFIface/AAFIface.h + * @brief AAF processing + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + * + * @ingroup AAFIface + * @addtogroup AAFIface + * @{ + * @brief Abstraction layer to interpret the Objects/Class and retrieve data. + */ + +#include "aaf/AAFCore.h" +#include "aaf/AAFTypes.h" + +enum aafiEssenceType { + AAFI_ESSENCE_TYPE_PCM = 0x01, + AAFI_ESSENCE_TYPE_WAVE = 0x02, + AAFI_ESSENCE_TYPE_AIFC = 0x03, + AAFI_ESSENCE_TYPE_BWAV = 0x04, +}; + +/** + * Flags for aafiAudioGain.flags. + */ + +typedef enum aafiAudioGain_e { + AAFI_AUDIO_GAIN_CONSTANT = 1 << 0, //0x0001 + AAFI_AUDIO_GAIN_VARIABLE = 1 << 1, //0x0002 + +} aafiAudioGain_e; + +#define AAFI_AUDIO_GAIN_MASK ( \ + AAFI_AUDIO_GAIN_CONSTANT | AAFI_AUDIO_GAIN_VARIABLE) + +/** + * Flags for aafiTransition.flags. + */ + +typedef enum aafiTransition_e { + AAFI_TRANS_SINGLE_CURVE = 1 << 4, //0x0010 + AAFI_TRANS_TWO_CURVE = 1 << 5, //0x0020 + + AAFI_TRANS_FADE_IN = 1 << 6, //0x0040 + AAFI_TRANS_FADE_OUT = 1 << 7, //0x0080 + AAFI_TRANS_XFADE = 1 << 8, //0x0100 + +} aafiTransition_e; + +#define AAFI_TRANS_CURVE_COUNT_MASK ( \ + AAFI_TRANS_SINGLE_CURVE | AAFI_TRANS_TWO_CURVE) + +#define AAFI_TRANS_FADE_MASK ( \ + AAFI_TRANS_FADE_IN | AAFI_TRANS_FADE_OUT | AAFI_TRANS_XFADE) + +/** + * Flags for aafiTransition.flags and aafiAudioGain.flags + */ + +typedef enum aafiInterpolation_e { + AAFI_INTERPOL_NONE = 1 << 10, //0x0400 + AAFI_INTERPOL_LINEAR = 1 << 11, //0x0800 + AAFI_INTERPOL_LOG = 1 << 12, //0x1000 + AAFI_INTERPOL_CONSTANT = 1 << 13, //0x2000 + AAFI_INTERPOL_POWER = 1 << 14, //0x4000 + AAFI_INTERPOL_BSPLINE = 1 << 15, //0x8000 + +} aafiInterpolation_e; + +#define AAFI_INTERPOL_MASK ( \ + AAFI_INTERPOL_NONE | AAFI_INTERPOL_LINEAR | AAFI_INTERPOL_LOG | AAFI_INTERPOL_CONSTANT | AAFI_INTERPOL_POWER | AAFI_INTERPOL_BSPLINE) + +/** + * Specifies a Transition that can be a fade in, a fade out or a Cross fade, and that can + * have one or two curves. + * + * With a single curve (AAFI_TRANS_SINGLE_CURVE), the same curve is mirrored and applied + * as fade in and fade out to obtain a cross fade. + * + * Having two curves (AAFI_TRANS_TWO_CURVE) allows a cross fade to have one curve per fade. + * + * A transition should have at least two points, one at time zero and one at time 1. + * TODO To finish + */ + +typedef struct aafiTransition { + /** + * Should hold the transition type (either single param or two param), + * the transition fade type (in, out, x) and the interpolation used. + */ + + int flags; + + /** + * Length of the transition, in edit units. + */ + + aafPosition_t len; + + /** + * The cut point. In the case the transition is removed or cannot be played, the + * cut point specifies where in the transition, the preceding segment should end + * and where the following segment should start. + */ + + aafPosition_t cut_pt; + + /** + * Points count for the single curve, or the first one of the two. This specifies + * both the number of points (time/value) in the transition curve, and consequently + * the size of time_a[] and value_a[] arrays. + */ + + int pts_cnt_a; + + /** + * Array of time points, where the corresponding level value should apply either to + * the single curve, or to the first one of the two. + */ + + aafRational_t* time_a; + + /** + * Multiplier level values, each one applying at the corresponding indexed time for + * either the single curve, or the first one of the two. + * The interval between two points shall be calculated using the specified + * interpolation. + */ + + aafRational_t* value_a; + + /** + * Points count for the second curve, only when Transition has the AAFI_TRANS_TWO_CURVE + * flag. This specifies both the number of points (time/value) in the transition curve, + * and consequently the size of time_b[] and value_b[] arrays. + */ + + int pts_cnt_b; + + /** + * Array of time points, where the corresponding level value should apply to the + * second curve. Used only if Transition has the AAFI_TRANS_TWO_CURVE flag. + */ + + aafRational_t** time_b; + + /** + * Multiplier level values, each one applying at the corresponding indexed time. + * The interval between two points shall be calculated using the specified + * interpolation. Used only if Transitions has the AAFI_TRANS_TWO_CURVE flag. + */ + + aafRational_t** value_b; + +} aafiTransition; + +/** + * Specifies a Gain to apply either to a Clip (aafiAudioClip.gain) or to an entire Track + * (aafiAudioTrack.gain), that is to all the Clips contained by that Track. + * + * A Gain can be of to types : + * + * * Constant (AAFI_AUDIO_GAIN_CONSTANT) : A Constant gain specifies a single value + * as a multiplier to be applied to the Clip or Track. + * + * * Variable (AAFI_AUDIO_GAIN_VARIABLE) : A Variable gain specifies multiple points + * ( time / value ) that form all together the automation curve. The values between + * two points are calculated by interpolating between the two values. + * + * Both the Gain type and the interpolation mode are specified in the aafiAudioGain.flags + * with the values from aafiAudioGain_e and aafiInterpolation_e. + * + * In the case of a Constant Gain, the single multiplier value should be retrieved from + * aafiAudioGain.value[0]. + */ + +typedef struct aafiAudioGain { + /** + * Should hold the gain type (either Constant or Variable), and if it is Variable, + * the interpolation used to calculate the values between two time points. + */ + + uint16_t flags; // Type : Constant (single multiplier for entire clip) or + // Variable (automation) + // Interpolation : Linear, Log, Constant, Power, BSpline + + /** + * Points count. This specifies both the number of points (time/value) in the + * gain automation, and is consequently the size of time[] and value[] arrays. + */ + + int64_t pts_cnt; + + /** + * Array of time points, where the corresponding level value should apply. + */ + + aafRational_t* time; + + /** + * Multiplier level values, each one applying at the corresponding indexed time. + * The interval between two points shall be calculated using the specified + * interpolation. + */ + + aafRational_t* value; + +} aafiAudioGain; + +typedef struct aafiAudioGain aafiAudioPan; + +typedef struct aafiAudioEssence { + wchar_t* original_file_path; // NetworkLocator::URLString the original URI hold in AAF + wchar_t* usable_file_path; // Holds a real usable file path, once an embedded essence has been extracted, or once en external essence has been found. + wchar_t* file_name; // MasterMob::Name the original file name. Might be NULL if MasterMob has no name. One should always use unique_file_name which is guaranted to be set. + wchar_t* unique_file_name; // unique name generated from file_name. Sometimes, multiple files share the same names so this unique name should be used on export. + + uint16_t clip_count; // number of clips with this essence + + /* total samples for 1 channel (no matter channel count). (duration / sampleRate) = duration in seconds */ + uint64_t length; // Length of Essence Data + + cfbNode* node; // The node holding the audio stream if embedded + + aafMobID_t* sourceMobID; // Holds the SourceMob Mob::ID references this EssenceData + uint32_t sourceMobSlotID; // SlotID of the MobSlot inside MasterMob (CompoMob's Sequence SourceClip::SourceMobSlotID) + aafMobID_t* masterMobID; // Holds the MasterMob Mob::ID (used by CompoMob's Sequence SourceClip::SourceID) + uint32_t masterMobSlotID; // SlotID of the MobSlot inside MasterMob (CompoMob's Sequence SourceClip::SourceMobSlotID) + + aafObject* SourceMob; + + enum aafiEssenceType type; // depends on PCMDescriptor WAVEDescriptor AIFCDescriptor + + uint8_t is_embedded; + + aafProperty* summary; // WAVEDescriptor AIFCDescriptor + + // uint32_t format; + uint32_t samplerate; + int16_t samplesize; + int16_t channels; + + aafRational_t* mobSlotEditRate; + + // BWF BEXT chunk data + char description[256]; + char originator[32]; // could be set with header::ProductName + char originatorReference[32]; + uint64_t timeReference; // SourceMob TimelineMobSlot::Origin + unsigned char umid[64]; // SourceMob::MobID (32 Bytes, basic form) + char originationDate[10 + 1]; // SourceMob::CreationDate + char originationTime[8 + 1]; // SourceMob::CreationTime + + void* user; + // TODO peakEnveloppe + struct aafiAudioEssence* next; + +} aafiAudioEssence; + +typedef struct aafiVideoEssence { + wchar_t* original_file_path; // NetworkLocator::URLString should point to original essence file if external (and in some cases, points to the AAF itself if internal..) + wchar_t* usable_file_path; // TODO, not that used.. to be tweaked. ---- Holds the file path, once the essence has been exported, copied or linked. + wchar_t* file_name; // MasterMob::Name -> file name + wchar_t* unique_file_name; // unique name generated from file_name. Sometimes, multiple files share the same names so this unique name should be used on export. + + uint64_t length; // Length of Essence Data + + cfbNode* node; // The node holding the audio stream if embedded + + aafRational_t* framerate; + + aafMobID_t* sourceMobID; // Holds the SourceMob Mob::ID references this EssenceData + uint32_t sourceMobSlotID; // SlotID of the MobSlot inside MasterMob (CompoMob's Sequence SourceClip::SourceMobSlotID) + aafMobID_t* masterMobID; // Holds the MasterMob Mob::ID (used by CompoMob's Sequence SourceClip::SourceID) + uint32_t masterMobSlotID; // SlotID of the MobSlot inside MasterMob (CompoMob's Sequence SourceClip::SourceMobSlotID) + + aafObject* SourceMob; + + // uint16_t type; // depends on PCMDescriptor WAVEDescriptor AIFCDescriptor + + uint8_t is_embedded; + + aafProperty* summary; + + // TODO peakEnveloppe + struct aafiVideoEssence* next; + +} aafiVideoEssence; + +/* forward declaration */ +struct aafiAudioTrack; +struct aafiVideoTrack; + +typedef struct aafiAudioClip { + struct aafiAudioTrack* track; + + aafiAudioEssence* Essence; + + /* + * Some editors (like Resolve) support automation attached to a clip AND a fixed value clip gain + */ + aafiAudioGain* gain; + aafiAudioGain* automation; + + int mute; + + int channel_count; + + aafPosition_t pos; /* in edit unit, edit rate definition is aafiAudioTrack->edit_rate */ + + aafPosition_t len; /* in edit unit, edit rate definition is aafiAudioTrack->edit_rate */ + + /* + * Start position in source file, set from SourceClip::StartTime + * + * « Specifies the offset from the origin of the referenced Mob MobSlot in edit units + * determined by the SourceClip object’s context. + * + * A SourceClip’s StartTime and Length values are in edit units determined by the slot + * owning the SourceClip. + + * Informative note: If the SourceClip references a MobSlot that specifies a different + * edit rate than the MobSlot owning the SourceClip, the StartTime and Length are in + * edit units of the slot owning the SourceClip, and not edit units of the referenced slot.» + */ + + aafPosition_t essence_offset; /* in edit unit, edit rate definition is aafiAudioTrack->edit_rate */ + + struct aafiTimelineItem* Item; // Corresponding timeline item, currently used in ardour to retrieve fades/x-fades + + aafMobID_t* masterMobID; // MobID of the associated MasterMob (PID_SourceReference_SourceID) + +} aafiAudioClip; + +typedef struct aafiVideoClip { + struct aafiVideoTrack* track; + + aafiVideoEssence* Essence; + + aafPosition_t pos; + + aafPosition_t len; + + aafPosition_t essence_offset; // start position in the source file + + aafMobID_t* masterMobID; // MobID of the associated MasterMob (PID_SourceReference_SourceID) + +} aafiVideoClip; + +typedef enum aafiTimelineItem_type_e { + AAFI_AUDIO_CLIP = 0x0001, + AAFI_VIDEO_CLIP = 0x0002, + AAFI_TRANS = 0x0003, + +} aafiTimelineItem_type_e; + +/** + * This structure can old either an aafiAudioClip, aafiVideoClip or an aafiTransition struct. + */ + +typedef struct aafiTimelineItem { + int type; + + struct aafiTimelineItem* next; + struct aafiTimelineItem* prev; + + void* data; /* aafiTransition or aafiAudioClip or aafiVideoClip */ + +} aafiTimelineItem; + +/** + * + */ + +typedef struct aafiTimecode { + /** + * Timecode start in EditUnit. (session start) + */ + + aafPosition_t start; + + /** + * Timecode end in EditUnit. (session end) + */ + + aafPosition_t end; + + /** + * Frame per second. + */ + + uint16_t fps; + + /** + * Indicates whether the timecode is drop (True value) or nondrop (False value) + */ + + uint8_t drop; + + /** + * Keeps track of the TimelineMobSlot EditRate. + * TODO do we care ? + */ + + aafRational_t* edit_rate; + +} aafiTimecode; + +/** + * Values for aafiAudioTrack.format. + */ + +typedef enum aafiTrackFormat_e { + AAFI_TRACK_FORMAT_NOT_SET = 0, + AAFI_TRACK_FORMAT_MONO = 1, + AAFI_TRACK_FORMAT_STEREO = 2, + AAFI_TRACK_FORMAT_5_1 = 6, + AAFI_TRACK_FORMAT_7_1 = 8, + AAFI_TRACK_FORMAT_UNKNOWN = 99 + +} aafiTrackFormat_e; + +/* forward declaration */ +struct aafiAudio; +struct aafiVideo; + +typedef struct aafiAudioTrack { + /** + * Track number + * TODO Should it start at one ? + * TODO Optional, should have a guess (i++) option. + */ + + uint32_t number; + + uint16_t format; // aafiTrackFormat_e, value = channel count + + /** + * Track name + */ + + wchar_t* name; + + /** + * Holds the Gain to apply on that track, that is the track volume Fader. + */ + + aafiAudioGain* gain; + + aafiAudioPan* pan; + + /** + * Holds the timeline items of that track, that is aafiAudioClip and aafiTransition + * structures. + */ + + struct aafiTimelineItem* Items; + + /** + * The edit rate of all the contained Clips, Transitions, also lengths and track->current_pos; + */ + + aafRational_t* edit_rate; + + /** + * Pointer to the aafiAudio for convenient access. + */ + + struct aafiAudio* Audio; + + /** + * Pointer to the next aafiAudioTrack structure in the aafiAudio.Tracks list. + */ + + aafPosition_t current_pos; + + struct aafiAudioTrack* next; + +} aafiAudioTrack; + +typedef struct aafiVideoTrack { + /** + * Track number + * TODO Should it start at one ? + * TODO Optional, should have a guess (i++) option. + */ + + uint32_t number; + + /** + * Track name + */ + + wchar_t* name; + + /** + * Holds the timeline items of that track, that is aafiVideoClip and aafiTransition + * structures. + */ + + struct aafiTimelineItem* Items; + + /** + * The edit rate of all the contained Clips and Transitions. + */ + + aafRational_t* edit_rate; + + /** + * Pointer to the aafiVideo for convenient access. + */ + + struct aafiVideo* Video; + + /** + * Pointer to the next aafiVideoTrack structure in the aafiVideo.Tracks list. + */ + + aafPosition_t current_pos; + + struct aafiVideoTrack* next; + +} aafiVideoTrack; + +typedef struct aafiUserComment { + wchar_t* name; + + wchar_t* text; + + struct aafiUserComment* next; + +} aafiUserComment; + +typedef struct aafiAudio { + /** + * Holds the sequence start timecode. + */ + + aafPosition_t start; + aafPosition_t length; + aafRational_t length_editRate; + + int64_t samplerate; + int16_t samplesize; + + /** + * Holds the Essence list. + */ + + aafiAudioEssence* Essences; + + /** + * Holds the Track list. + */ + + aafiAudioTrack* Tracks; + uint32_t track_count; + +} aafiAudio; + +typedef struct aafiVideo { + /** + * Holds the sequence start timecode. + */ + + aafPosition_t start; + aafPosition_t length; + aafRational_t length_editRate; + + /** + * Holds the Essence list. + */ + + aafiVideoEssence* Essences; + + /** + * Holds the Track list. + */ + + aafiVideoTrack* Tracks; + +} aafiVideo; + +typedef struct aafiMarker { + /* + * TODO: link marker to specific track ? (optional in AAF standard, not yet seen in AAF files) + */ + + aafPosition_t start; + aafPosition_t length; + aafRational_t* edit_rate; + + wchar_t* name; + wchar_t* comment; + uint16_t RVBColor[3]; + + struct aafiMarker* prev; + struct aafiMarker* next; + +} aafiMarker; + +// typedef enum aafiCurrentTreeType_e +// { +// AAFI_TREE_TYPE_AUDIO = 0, +// AAFI_TREE_TYPE_VIDEO = 1 +// +// } aafiCurrentTreeType_e; + +typedef struct aafiContext { + /* Set in parse_MobSlot(), specifies if we're inside an audio or video context */ + // aafiCurrentTreeType_e current_tree_type; + + /* + * Current MobSlot Segment's DataDefinition + * Mob::Slots > MobSlot::Segment > Component::DataDefinition + */ + + // aafUID_t *DataDef; + + /* Clip */ + + aafiAudioTrack* current_track; + + /* Must be casted to aafiAudioTrack or aafiVideoTrack, according to aafiContext::current_tree_type */ + // void * current_track; + // int current_track_number; // used only when missing MobSlot::PhysicalTrackNumber + + // aafPosition_t current_pos; + aafiAudioClip* current_clip; + aafiVideoClip* current_video_clip; + int current_clip_is_muted; + + int current_clip_is_combined; // Inside OperationGroup::AAFOperationDef_AudioChannelCombiner + int current_combined_clip_total_channel; + int current_combined_clip_channel_num; // current SourceClip represents channel num + + /* Transition */ + + aafiTransition* current_transition; + + /* Gain */ + + aafiAudioGain* current_clip_gain; + aafiAudioGain* current_clip_automation; + int clips_using_gain; // if none then free( current_clip_gain ); + int clips_using_automation; + + /* Essence */ + + // aafiAudioEssence *current_audioEssence; + // void *current_essence; + aafiAudioEssence* current_essence; + aafiVideoEssence* current_video_essence; + + aafRational_t* current_markers_edit_rate; + + int is_inside_derivation_chain; + + struct options { + verbosityLevel_e verb; + int trace; + int trace_meta; + wchar_t* trace_class; + char* media_location; + char forbid_nonlatin_filenames; + /* vendor specific */ + uint32_t resolve; + uint32_t protools; + } options; + +} aafiContext; + +typedef struct AAF_Iface { + aafiContext ctx; + + /** + * Keeps track of the AAF_Data structure. + */ + + AAF_Data* aafd; + + aafiAudio* Audio; + + aafiVideo* Video; + + aafiTimecode* Timecode; + + aafiMarker* Markers; + + wchar_t* compositionName; + + aafPosition_t compositionStart; // set from aafi->Timecode->start + aafRational_t compositionStart_editRate; + + aafPosition_t compositionLength; + aafRational_t compositionLength_editRate; + + aafiUserComment* Comments; + + struct dbg* dbg; + +} AAF_Iface; + +#define foreach_audioTrack(audioTrack, aafi) \ + for (audioTrack = aafi->Audio->Tracks; \ + audioTrack != NULL; \ + audioTrack = audioTrack->next) + +#define foreach_videoTrack(videoTrack, aafi) \ + for (videoTrack = aafi->Video->Tracks; \ + videoTrack != NULL; \ + videoTrack = videoTrack->next) + +#define foreach_Item(item, track) \ + for (item = track->Items; \ + item != NULL; \ + item = item->next) + +#define foreachEssence(essence, essenceList) \ + for (essence = essenceList; essence != NULL; essence = essence->next) + +#define foreachMarker(marker, aafi) \ + for (marker = aafi->Markers; marker != NULL; marker = marker->next) + +#define aeDuration_h(audioEssence) \ + ((audioEssence->samplerate == 0) ? 0 : ((uint16_t) (audioEssence->length / audioEssence->samplerate / (audioEssence->samplesize / 8)) / 3600)) + +#define aeDuration_m(audioEssence) \ + ((audioEssence->samplerate == 0) ? 0 : ((uint16_t) (audioEssence->length / audioEssence->samplerate / (audioEssence->samplesize / 8)) % 3600 / 60)) + +#define aeDuration_s(audioEssence) \ + ((audioEssence->samplerate == 0) ? 0 : ((uint16_t) (audioEssence->length / audioEssence->samplerate / (audioEssence->samplesize / 8)) % 3600 % 60)) + +#define aeDuration_ms(audioEssence) \ + ((audioEssence->samplerate == 0) ? 0 : ((uint16_t) (audioEssence->length / (audioEssence->samplerate / 1000) / (audioEssence->samplesize / 8)) % 3600000 % 60000 % 1000)) + +#define convertEditUnit(val, fromRate, toRate) \ + (int64_t) ((val) * (aafRationalToFloat ((toRate)) * (1 / aafRationalToFloat ((fromRate))))) + +#define eu2sample(samplerate, edit_rate, val) \ + (int64_t) (val * (samplerate * (1 / aafRationalToFloat ((*edit_rate))))) + +void +aafi_enable_windows_VT100_output (void); + +void +aafi_set_debug (AAF_Iface* aafi, verbosityLevel_e v, FILE* fp, void (*callback) (struct dbg* dbg, void* ctxdata, int lib, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user), void* user); + +AAF_Iface* +aafi_alloc (AAF_Data* aafd); + +int +aafi_set_media_location (AAF_Iface* aafi, const char* path); + +int +aafi_set_trace_class (AAF_Iface* aafi, const char* className); + +void +aafi_release (AAF_Iface** aafi); + +int +aafi_load_file (AAF_Iface* aafi, const char* file); + +aafiTransition* +aafi_get_fadein (aafiTimelineItem* audioItem); + +aafiTransition* +aafi_get_fadeout (aafiTimelineItem* audioItem); + +aafiTransition* +aafi_get_xfade (aafiTimelineItem* audioItem); + +aafiMarker* +aafi_newMarker (AAF_Iface* aafi, aafRational_t* editRate, aafPosition_t start, aafPosition_t length, wchar_t* name, wchar_t* comment, uint16_t* RVBColor[3]); + +void +aafi_freeMarkers (aafiMarker** aafi); + +aafiAudioTrack* +aafi_newAudioTrack (AAF_Iface* aafi); + +void +aafi_freeAudioTracks (aafiAudioTrack** tracks); + +aafiVideoTrack* +aafi_newVideoTrack (AAF_Iface* aafi); + +void +aafi_freeVideoTracks (aafiVideoTrack** tracks); + +aafiTimelineItem* +aafi_newTimelineItem (AAF_Iface* aafi, void* track, int itemType); + +int +aafi_removeTimelineItem (AAF_Iface* aafi, aafiTimelineItem* item); + +void +aafi_freeAudioGain (aafiAudioGain* gain); + +void +aafi_freeAudioPan (aafiAudioPan* pan); + +void +aafi_freeAudioClip (aafiAudioClip* audioClip); + +void +aafi_freeTimelineItem (aafiTimelineItem** item); + +void +aafi_freeTimelineItems (aafiTimelineItem** items); + +aafiUserComment* +aafi_newUserComment (AAF_Iface* aafi, aafiUserComment** CommentList); + +void +aafi_freeUserComments (aafiUserComment** CommentList); + +void +aafi_freeTransition (aafiTransition* trans); + +aafiAudioEssence* +aafi_newAudioEssence (AAF_Iface* aafi); + +void +aafi_freeAudioEssences (aafiAudioEssence** essences); + +aafiVideoEssence* +aafi_newVideoEssence (AAF_Iface* aafi); + +void +aafi_freeVideoEssences (aafiVideoEssence** videoEssence); + +/** + * @} + */ + +#endif // !__AAFIface_h__ diff --git a/libs/aaf/aaf/AAFToText.h b/libs/aaf/aaf/AAFToText.h new file mode 100644 index 0000000000..def7a4a5fa --- /dev/null +++ b/libs/aaf/aaf/AAFToText.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFToText_h__ +#define __AAFToText_h__ + +#include +#include + +#include "aaf/AAFCore.h" +#include "aaf/AAFTypes.h" +#include "aaf/LibCFB.h" + +#define AUIDToText(auid) \ + cfb_CLSIDToText ((const cfbCLSID_t*)auid) + +const wchar_t* +aaft_MobIDToText (aafMobID_t* mobid); + +const wchar_t* +aaft_TimestampToText (aafTimeStamp_t* ts); + +const wchar_t* +aaft_VersionToText (aafVersionType_t* vers); + +const wchar_t* +aaft_ProductVersionToText (aafProductVersion_t* vers); + +const wchar_t* +aaft_FileKindToText (const aafUID_t* auid); + +const wchar_t* +aaft_TapeCaseTypeToText (aafTapeCaseType_t t); + +const wchar_t* +aaft_VideoSignalTypeToText (aafVideoSignalType_t v); + +const wchar_t* +aaft_TapeFormatTypeToText (aafTapeFormatType_t t); + +const wchar_t* +aaft_FilmTypeToText (aafFilmType_t f); + +const wchar_t* +aaft_SignalStandardToText (aafSignalStandard_t s); + +const wchar_t* +aaft_FieldNumberToText (aafFieldNumber_t f); + +const wchar_t* +aaft_AlphaTransparencyToText (aafAlphaTransparency_t a); + +const wchar_t* +aaft_FrameLayoutToText (aafFrameLayout_t f); + +const wchar_t* +aaft_ColorSitingToText (aafColorSiting_t c); + +const wchar_t* +aaft_ProductReleaseTypeToText (aafProductReleaseType_t t); + +const wchar_t* +aaft_FadeTypeToText (aafFadeType_t f); + +const wchar_t* +aaft_BoolToText (aafBoolean_t b); + +const wchar_t* +aaft_OperationCategoryToText (const aafUID_t* auid); + +const wchar_t* +aaft_PluginCategoryToText (const aafUID_t* auid); + +const wchar_t* +aaft_ScanningDirectionToText (aafScanningDirection_t s); + +const wchar_t* +aaft_ByteOrderToText (int16_t e); + +const wchar_t* +aaft_ElectroSpatialToText (aafElectroSpatialFormulation_t e); + +const wchar_t* +aaft_TypeIDToText (const aafUID_t* auid); + +const wchar_t* +aaft_StoredFormToText (enum aafStoredForm_e sf); + +const wchar_t* +aaft_OPDefToText (const aafUID_t* auid); + +const wchar_t* +aaft_DataDefToText (AAF_Data* aafd, const aafUID_t* auid); + +const wchar_t* +aaft_OperationDefToText (AAF_Data* aafd, const aafUID_t* auid); + +const wchar_t* +aaft_InterpolationToText (const aafUID_t* auid); + +const wchar_t* +aaft_ParameterToText (AAF_Data* aafd, const aafUID_t* auid); + +const wchar_t* +aaft_TransferCharacteristicToText (const aafUID_t* auid); + +const wchar_t* +aaft_CodingEquationsToText (const aafUID_t* auid); + +const wchar_t* +aaft_ColorPrimariesToText (const aafUID_t* auid); + +const wchar_t* +aaft_UsageCodeToText (const aafUID_t* auid); + +const wchar_t* +aaft_PIDToText (AAF_Data* aafd, aafPID_t pid); + +const wchar_t* +aaft_ClassIDToText (AAF_Data* aafd, const aafUID_t* auid); + +const wchar_t* +aaft_ContainerToText (const aafUID_t* auid); + +const wchar_t* +aaft_CompressionToText (const aafUID_t* auid); + +#endif // !__AAFToText_h__ diff --git a/libs/aaf/aaf/AAFTypes.h b/libs/aaf/aaf/AAFTypes.h new file mode 100644 index 0000000000..c137b2105b --- /dev/null +++ b/libs/aaf/aaf/AAFTypes.h @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __AAFTypes_h__ +#define __AAFTypes_h__ + +#include + +#ifdef __GNUC__ +#define PACK(__Declaration__) __Declaration__ __attribute__ ((__packed__)) +#endif + +#ifdef _MSC_VER +#define PACK(__Declaration__) __pragma (pack (push, 1)) __Declaration__ __pragma (pack (pop)) +#endif + +#define AAF_HEADER_BYTEORDER_LE 0x4949 // II +#define AAF_HEADER_BYTEORDER_BE 0x4D4D // MM + +#define AAF_PROPERTIES_BYTEORDER_LE 0x4c // L +#define AAF_PROPERTIES_BYTEORDER_BE 0x42 // B +#define AAF_PROPERTIES_BYTEORDER_UNSPECIFIED 0x55 // U + +typedef enum aafStoredForm_e { + SF_DATA = 0x0082, + SF_DATA_STREAM = 0x0042, + SF_STRONG_OBJECT_REFERENCE = 0x0022, + SF_STRONG_OBJECT_REFERENCE_VECTOR = 0x0032, + SF_STRONG_OBJECT_REFERENCE_SET = 0x003A, + SF_WEAK_OBJECT_REFERENCE = 0x0002, + SF_WEAK_OBJECT_REFERENCE_VECTOR = 0x0012, + SF_WEAK_OBJECT_REFERENCE_SET = 0x001A, + SF_WEAK_OBJECT_REFERENCE_STORED_OBJECT_ID = 0x0003, + SF_UNIQUE_OBJECT_ID = 0x0086, + SF_OPAQUE_STREAM = 0x0040 + +} aafStoredForm_e; + +/* +typedef int32_t AAFTypeCategory_t; +typedef enum _eAAFTypeCategory_e +{ + AAFTypeCatUnknown = 0, // can only occur in damaged files + AAFTypeCatInt = 1, // any integral type + AAFTypeCatCharacter = 2, // any character type + AAFTypeCatStrongObjRef = 3, // strong object reference + AAFTypeCatWeakObjRef = 4, // weak object reference + AAFTypeCatRename = 5, // renamed type + AAFTypeCatEnum = 6, // enumerated type + AAFTypeCatFixedArray = 7, // fixed-size array + AAFTypeCatVariableArray = 8, // variably-sized array + AAFTypeCatSet = 9, // set of strong object references or + // set of weak object references + AAFTypeCatRecord = 10, // a structured type + AAFTypeCatStream = 11, // potentially huge amount of data + AAFTypeCatString = 12, // null-terminated variably-sized + // array of characters + AAFTypeCatExtEnum = 13, // extendible enumerated type + AAFTypeCatIndirect = 14, // type must be determined at runtime + AAFTypeCatOpaque = 15, // type can be determined at runtime + AAFTypeCatEncrypted = 16 // type can be determined at runtime + // but bits are encrypted +} AAFTypeCategory_e; +*/ + +/* + * :: Types Definition + * see Git nevali/aaf/ref-impl/include/ref-api/AAFTypes.h +*/ + +typedef unsigned char aafByte_t; + +typedef char* aafString_t; + +typedef uint16_t aafPID_t; + +typedef int64_t aafLength_t; + +typedef uint8_t aafBoolean_t; + +typedef int64_t aafPosition_t; + +typedef uint32_t aafSlotID_t; + +typedef struct _aafStream_t { + uint64_t size; + aafByte_t* data; + +} aafStream_t; + +typedef int32_t aafJPEGTableID_t; /* for TIFF objects */ + +typedef struct _aafRational_t { + int32_t numerator; + int32_t denominator; + +} aafRational_t; + +typedef struct _aafDateStruct_t { + int16_t year; /* range -32,767 to +32767 */ + uint8_t month; /* range: 1-12, inclusive */ + uint8_t day; /* range: 1-31, inclusive */ + +} aafDateStruct_t; + +typedef struct _aafTimeStruct_t { + uint8_t hour; /* range 0-23 inclusive */ + uint8_t minute; /* range 0-59 inclusive */ + uint8_t second; /* range 0-59 inclusive */ + uint8_t fraction; /* range 0..99 inclusive; accuracy: .01 sec */ + +} aafTimeStruct_t; + +typedef struct _aafTimeStamp_t { + aafDateStruct_t date; + aafTimeStruct_t time; + +} aafTimeStamp_t; + +// TODO is int32_t in the original AAFTypes.h, but does not match when parsing.. +typedef int8_t aafProductReleaseType_t; + +typedef enum _aafProductReleaseType_e { + AAFVersionUnknown = 0, + AAFVersionReleased = 1, + AAFVersionDebug = 2, + AAFVersionPatched = 3, + AAFVersionBeta = 4, + AAFVersionPrivateBuild = 5 + +} aafProductReleaseType_e; + +/* Version Format for ObjHeader->Version */ +typedef PACK (struct _aafVersionType_t { + int8_t major; + int8_t minor; +}) aafVersionType_t; + +/* Version Format for ObjIdentification->ProductVersion */ +typedef PACK (struct _aafProductVersion_t { + uint16_t major; + uint16_t minor; + uint16_t tertiary; + uint16_t patchLevel; + int8_t type; +}) aafProductVersion_t; + +/* aafFadeType_t: describes values for SCLP fadein and fadeout types */ +typedef int32_t aafFadeType_t; +typedef enum _aafFadeType_e { + AAFFadeNone = 0, + AAFFadeLinearAmp = 1, + AAFFadeLinearPower = 2 + +} aafFadeType_e; + +/* binary compatibility with GUID/CLSID and IID structures. */ +typedef struct _aafUID_t { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; + +} aafUID_t; + +#define AAFUID_PRINTED_LEN 35 // excluding NULL terminating char + +static const aafUID_t AUID_NULL = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; + +typedef struct _aafMobID_t { + uint8_t SMPTELabel[12]; // 12-bytes of label prefix + uint8_t length; + uint8_t instanceHigh; + uint8_t instanceMid; + uint8_t instanceLow; + aafUID_t material; // 16 bytes + +} aafMobID_t; // 32 bytes total + +typedef struct _aafIndirect_t { + /* + * byteOrder disabled for memory alignement and to avoid -Waddress-of-packed-member + * It is always little-endian (0x4c), or unspecified (0x55) but LE, anyway. + */ + // uint8_t byteOrder; // 0x4c, 0x42, 0x55 + aafUID_t TypeDef; + aafByte_t Value[]; + +} /*__attribute__((packed))*/ aafIndirect_t; + +typedef int32_t aafElectroSpatialFormulation_t; + +typedef enum _aafElectroSpatialFormulation_e { + AAFElectroSpatialFormulation_Default = 0, + AAFElectroSpatialFormulation_TwoChannelMode = 1, + AAFElectroSpatialFormulation_SingleChannelMode = 2, + AAFElectroSpatialFormulation_PrimarySecondaryMode = 3, + AAFElectroSpatialFormulation_StereophonicMode = 4, + AAFElectroSpatialFormulation_SingleChannelDoubleSamplingFrequencyMode = 7, + AAFElectroSpatialFormulation_StereoLeftChannelDoubleSamplingFrequencyMode = 8, + AAFElectroSpatialFormulation_StereoRightChannelDoubleSamplingFrequencyMode = 9, + AAFElectroSpatialFormulation_MultiChannelMode = 15 + +} aafElectroSpatialFormulation_e; + +typedef int32_t aafFrameLayout_t; + +typedef enum _aafFrameLayout_e { + AAFFullFrame = 0, + AAFSeparateFields = 1, + AAFOneField = 2, + AAFMixedFields = 3, + AAFSegmentedFrame = 4 + +} aafFrameLayout_e; + +typedef int32_t aafAlphaTransparency_t; + +typedef enum _aafAlphaTransparency_e { + AAFMinValueTransparent = 0, + AAFMaxValueTransparent = 1 + +} aafAlphaTransparency_e; + +typedef int32_t aafFieldNumber_t; + +typedef enum _aafFieldNumber_e { + AAFUnspecifiedField = 0, + AAFFieldOne = 1, + AAFFieldTwo = 2 + +} aafFieldNumber_e; + +typedef int32_t aafSignalStandard_t; + +typedef enum _aafSignalStandard_e { + AAFSignalStandard_None = 0, + AAFSignalStandard_ITU601 = 1, + AAFSignalStandard_ITU1358 = 2, + AAFSignalStandard_SMPTE347M = 3, + AAFSignalStandard_SMPTE274M = 4, + AAFSignalStandard_SMPTE296M = 5, + AAFSignalStandard_SMPTE349M = 6 + +} aafSignalStandard_e; + +typedef int32_t aafContentScanningType_t; + +typedef enum _aafContentScanningType_e { + kAAFContentScanning_NotKnown = 0, + kAAFContentScanning_Progressive = 1, + kAAFContentScanning_Interlace = 2, + kAAFContentScanning_Mixed = 3 + +} aafContentScanningType_e; + +typedef int32_t aafColorSiting_t; + +typedef enum _aafColorSiting_e { + AAFCoSiting = 0, + AAFAveraging = 1, + AAFThreeTap = 2, + AAFQuincunx = 3, + AAFRec601 = 4, + AAFUnknownSiting = 255 + +} aafColorSiting_e; + +typedef int32_t aafScanningDirection_t; + +typedef enum _aafScanningDirection_e { + AAFScanningDirection_LeftToRightTopToBottom = 0, + AAFScanningDirection_RightToLeftTopToBottom = 1, + AAFScanningDirection_LeftToRightBottomToTop = 2, + AAFScanningDirection_RightToLeftBottomToTop = 3, + AAFScanningDirection_TopToBottomLeftToRight = 4, + AAFScanningDirection_TopToBottomRightToLeft = 5, + AAFScanningDirection_BottomToTopLeftToRight = 6, + AAFScanningDirection_BottomToTopRightToLeft = 7 + +} aafScanningDirection_e; + +typedef int32_t aafFilmType_t; + +typedef enum _aafFilmType_e { + AAFFtNull = 0, + AAFFt35MM = 1, + AAFFt16MM = 2, + AAFFt8MM = 3, + AAFFt65MM = 4 + +} aafFilmType_e; + +typedef int32_t aafTapeCaseType_t; + +typedef enum _aafTapeCaseType_e { + AAFTapeCaseNull = 0, + AAFThreeFourthInchVideoTape = 1, + AAFVHSVideoTape = 2, + AAF8mmVideoTape = 3, + AAFBetacamVideoTape = 4, + AAFCompactCassette = 5, + AAFDATCartridge = 6, + AAFNagraAudioTape = 7 + +} aafTapeCaseType_e; + +typedef int32_t aafVideoSignalType_t; + +typedef enum _aafVideoSignalType_e { + AAFVideoSignalNull = 0, + AAFNTSCSignal = 1, + AAFPALSignal = 2, + AAFSECAMSignal = 3 + +} aafVideoSignalType_e; + +typedef int32_t aafTapeFormatType_t; + +typedef enum _aafTapeFormatType_e { + AAFTapeFormatNull = 0, + AAFBetacamFormat = 1, + AAFBetacamSPFormat = 2, + AAFVHSFormat = 3, + AAFSVHSFormat = 4, + AAF8mmFormat = 5, + AAFHi8Format = 6 + +} aafTapeFormatType_e; + +typedef int32_t aafRGBAComponentKind_t; + +typedef enum _aafRGBAComponentKind_e { + AAFCompNone = 0x30, + AAFCompAlpha = 0x41, + AAFCompBlue = 0x42, + AAFCompFill = 0x46, + AAFCompGreen = 0x47, + AAFCompPalette = 0x50, + AAFCompRed = 0x52, + AAFCompNull = 0x00 + +} aafRGBAComponentKind_e; + +typedef struct _aafRGBAComponent_t { + aafRGBAComponentKind_t Code; + uint8_t Size; + +} aafRGBAComponent_t; + +//typedef aafRGBAComponent_t aafRGBALayout[8]; + +static const aafUID_t AAFUID_NULL = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; + +/** + * This structure map the first bytes in a **properties** stream + * node. + * + * This Header is followed by #_entryCount aafPropertyIndexEntry_t + * structures, which are then followed by aafPropertyIndexHeader_t._entryCount variable + * sized property values. + */ + +typedef struct aafPropertyIndexHeader_t { + /** + * The byte order of : + * - the remaining fields of the aafPropertyIndexHeader_t struct + * - the aafPropertyIndexEntry_t structs that follow + * - the actual property data + * + * Currently unused when parsing. + */ + + uint8_t _byteOrder; + + /** + * The version number of the stored format. This allows + * for otherwise incompatible changes to the stored format. + * + * Currently unused when parsing. + */ + + uint8_t _formatVersion; + + /** + * The number of aafPropertyIndexEntry_t structs that follow. + */ + + uint16_t _entryCount; + +} /* __attribute__((packed)) */ aafPropertyIndexHeader_t; + +/** + * This structure represents one property entry inside a + * **properties** stream node. The actual property value + * is located bellow all the property entries. + * + * The offset to the property values is calculated by : + * + * @code + * + * int offset = sizeof(aafPropertyIndexHeader_t) + (aafPropertyIndexHeader_t._entryCount * sizeof(aafPropertyIndexEntry_t)) + * + * @endcode + * The offset inside the property values is calculated by : + * + * + * ``` + * for( PropEntry[i]; PropEntry[i] < i; i++ ) + * offset += PropEntry. _length; + * ``` + */ + +typedef struct aafPropertyIndexEntry_t { + /** + * The ID that describes the property. + * + * All the standard IDs can be found in AAFDefs/AAFPropertyIDs.h. + */ + + aafPID_t _pid; + + /** + * Identifies the “type” of representation chosen for this + * property. Note that the stored form described here is not + * the data type of the property value, rather it is the type + * of external representation employed. The data type of a + * given property value is implied by the property ID. + * + * Can take one of the value from #aafStoredForm_e enum. + * + * Even though only 1 byte is needed, _storedForm is 2 bytes + * in size in order to keep each property index entry an even + * number of bytes in size. + */ + + uint16_t _storedForm; + + /** + * The length, in bytes, of the property value in the property + * value stream. + */ + + uint16_t _length; + +} /* __attribute__((packed)) */ aafPropertyIndexEntry_t; + +/** + * An unordered collection of strongly referenced (contained) + * uniquely identified objects, each of which can be : + * - efficiently located by key - O(lg N) + * - the target of a weak reference + * + * Each set index consists of an aafStrongRefSetHeader_t + * followed by #_entryCount aafStrongRefSetEntry_t structs. + */ + +typedef PACK (struct aafStrongRefSetHeader_t { + /** + * The number of aafStrongRefSetEntry_t structs that follow. + */ + + uint32_t _entryCount; + + /** + * The next local key that will be assigned in this set. + */ + + uint32_t _firstFreeKey; + + /** + * The highest unassigned key above #_firstFreeKey. The keys + * between #_firstFreeKey and #_lastFreeKey are unassigned, + * while there may be other gaps in key assignement this + * represents the largest one. + */ + + uint32_t _lastFreeKey; + + /** + * The property id of each aafStrongRefSetEntry_t._identification field + * @TODO Understand that field.. + */ + + aafPID_t _identificationPid; + + /** + * The length, in bytes, of each aafStrongRefSetEntry_t._identification + * field. + */ + + uint8_t _identificationSize; +}) aafStrongRefSetHeader_t; + +typedef struct aafStrongRefSetEntry_t { + /** + * The #_localKey uniquely identifies this strong reference + * within this collection independently of its position + * within this collection. The #_localKey is used to form + * the name assigned to the element in this set at the + * corresponding ordinal position. That is, the #_localKey + * of the first aafStrongRefSetEntry_t is used to + * form the name of the first element in the set and so + * on. The #_localKey is an insertion key. + */ + + uint32_t _localKey; + + /** + * The count of weak references to this object. + */ + + uint32_t _referenceCount; + + /** + * The type of the #_identification field varies from one instance + * of a StrongReferenceSet to another. The value of the #_identification + * field uniquely identifies this object within the set. It is the + * search key. + */ + + aafByte_t _identification[]; + +} /* __attribute__((packed)) */ aafStrongRefSetEntry_t; + +/** + * An ordered collection of strongly referenced (contained) objects. + * Each vector index consists of an aafStrongRefVectorHeader_t + * followed by #_entryCount aafStrongRefVectorEntry_t structs. + */ + +typedef struct aafStrongRefVectorHeader_t { + /** + * The number of aafStrongRefVectorEntry_t structs that follow. + */ + + uint32_t _entryCount; + + /** + * The next local key that will be assigned in this vector. + */ + + uint32_t _firstFreeKey; + + /** + * The highest unassigned key above #_firstFreeKey. The keys + * between #_firstFreeKey and #_lastFreeKey are unassigned, + * while there may be other gaps in key assignement this + * represents the largest one. + */ + + uint32_t _lastFreeKey; + +} /* __attribute__((packed)) */ aafStrongRefVectorHeader_t; + +/** + * An ordered collection of strongly referenced (contained) objects. + * Each vector index consists of an aafStrongRefVectorHeader_t + * followed by aafStrongRefVectorHeader_t._entryCount aafStrongRefVectorEntry_t structs. + */ + +typedef struct aafStrongRefVectorEntry_t { + /** + * The _localKey uniquely identifies this strong reference + * within this collection independently of its position + * within this collection. The #_localKey is used to form + * the name assigned to the element in this vector at the + * corresponding ordinal position. That is, the #_localKey + * of the first aafStrongRefVectorEntry_t is used to + * form the name of the first element in the vector and so + * on. The #_localKey is an insertion key. + */ + + uint32_t _localKey; + +} /* __attribute__((packed)) */ aafStrongRefVectorEntry_t; + +/** + * A weak object reference is a persistent data type that denotes + * a weak reference to a uniquely identified object. In memory, + * weak references are similar to pointers. When persisted, weak + * references contain the unique identifier of the referenced object. + * + * An aafWeakRef_t can appears as a property value with the + * stored form #SF_WEAK_OBJECT_REFERENCE, as an entry into + * a weak reference vector index or set index. + */ + +typedef struct _WeakObjectReference { + /** + * The index into the referenced property table of + * the path to the property (a strong reference set) + * containing the referenced object. + */ + + uint16_t _referencedPropertyIndex; + + /** + * The property id of the #_identification field + * @TODO Understand that field.. + */ + + aafPID_t _identificationPid; + + /** + * The length, in bytes, of the #_identification field. + */ + + uint8_t _identificationSize; + + /** + * The type of the #_identification field varies from one instance + * of a WeakObjectReference to another. The #_identification field + * uniquely identifies the object within the target set. + */ + + aafByte_t _identification[]; + +} /* __attribute__((packed)) */ aafWeakRef_t; + +/** + * An ordered collection of aafWeakRef_t. The aafWeakRefHeader_t + * is common to weak reference Set and Vector. + * + */ + +typedef struct _WeakReferenceIndexHeader { + /** + * The number of aafWeakRef_t structs that follow. + */ + + uint32_t _entryCount; + + /** + * The index into the referenced property table of + * the path to the property (a strong reference set) + * containing the referenced object. + * @TODO Understand that field.. + */ + + uint16_t _referencedPropertyIndex; + + /** + * The property id of each aafStrongRefSetEntry_t._identification field. + * @TODO Understand that field.. + */ + + uint16_t _identificationPid; + + /** + * The length, in bytes, of each aafWeakRef_t._identification + * field. + */ + + uint8_t _identificationSize; + +} /* __attribute__((packed)) */ aafWeakRefHeader_t; + +/* TODO : indirect vs opaque types ? */ +/* +typedef struct _aafIndirect_t +{ + int type; + size_t size; + aafByte_t *data; +} aafIndirect_t; + +typedef struct _AAF_TaggedValueClass +{ + aafString_t Name; + aafIndirect_t Value; +} AAF_ObjTaggedValue; +*/ + +#endif diff --git a/libs/aaf/aaf/CFBDump.h b/libs/aaf/aaf/CFBDump.h new file mode 100644 index 0000000000..0283119199 --- /dev/null +++ b/libs/aaf/aaf/CFBDump.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CFBDump_h__ +#define __CFBDump_h__ + +#include +#include + +#include "aaf/LibCFB.h" + +void +cfb_dump_node (CFB_Data* cfbd, cfbNode* node, int print_stream); + +void +cfb_dump_nodePath (CFB_Data* cfbd, const wchar_t* path, int print_stream); + +void +cfb_dump_nodeStream (CFB_Data* cfbd, cfbNode* node); + +void +cfb_dump_nodePathStream (CFB_Data* cfbd, const wchar_t* path); + +void +cfb_dump_nodePaths (CFB_Data* cfbd, uint32_t prevPath, char* strArray[], uint32_t* str_i, cfbNode* node); + +void +cfb_dump_header (CFB_Data* cfbd); + +void +cfb_dump_FAT (CFB_Data* cfbd); + +void +cfb_dump_MiniFAT (CFB_Data* cfbd); + +void +cfb_dump_DiFAT (CFB_Data* cfbd); + +#endif // !__CFBDump_h__ diff --git a/libs/aaf/aaf/LibCFB.h b/libs/aaf/aaf/LibCFB.h new file mode 100644 index 0000000000..6d2a35247c --- /dev/null +++ b/libs/aaf/aaf/LibCFB.h @@ -0,0 +1,817 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __LibCFB_h__ +#define __LibCFB_h__ + +#include +#include + +#include "aaf/debug.h" + +#if defined(__linux__) +#include +#elif defined(__APPLE__) +#include +#elif defined(_MSC_VER) // MSVC +#include // MAX_PATH +#include +#define PATH_MAX MAX_PATH // TODO: can we get rid of it ? +#elif defined(_WIN32) +#include // MAX_PATH +#include +#endif + +/** + * @file LibCFB/LibCFB.h + * @brief Compound File Binary Library + * @author Adrien Gesta-Fline + * @version 0.1 + * @date 04 october 2017 + * + * @ingroup LibCFB + * @addtogroup LibCFB + * @{ + */ + +#define CFB_W16TOWCHAR_STRLEN SIZE_MAX + +/** + * Class Identifier structure. + * + * Used by cfbHeader._clsid and cfbNode._clsId. + * + * 16-byte long, binary compatible with GUID and AAF's AUID. + */ + +struct cfbCLSID_t { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; // __attribute__((packed)); + +typedef struct cfbCLSID_t cfbCLSID_t; + +/** + * 64-bit value representing number of 100 nanoseconds since January 1, 1601. + * + * Used in cfbNode. + */ + +struct cfbFiletime_t { + uint32_t dwLowDateTime; + uint32_t dwHighDateTime; +}; // __attribute__((packed)); + +typedef struct cfbFiletime_t cfbFiletime_t; + +/** + * A sector ID, that is an index into the FAT or the MiniFAT. + */ + +typedef uint32_t cfbSectorID_t; + +/** + * A stream identifier, that is an index into the array of nodes (directory entries). + */ + +typedef uint32_t cfbSID_t; + +/** + * This enum defines sector IDs and storage IDs (SID) with special meanings. + * NOTE: enum was turned to MACRO, because of -Wpedantic (and even though they are valid 32bits...) + */ + +#define CFB_MAX_REG_SECT 0xfffffffa + +/** + * Denotes a DiFAT sector ID in the FAT or MiniFAT. + */ + +#define CFB_DIFAT_SECT 0xfffffffc + +/** + * Denotes a FAT sector ID in the FAT or MiniFAT. + */ + +#define CFB_FAT_SECT 0xfffffffd + +/** + * End of a virtual stream chain. + */ + +#define CFB_END_OF_CHAIN 0xfffffffe + +/** + * Unallocated FAT or MiniFAT sector. + */ + +#define CFB_FREE_SECT 0xffffffff + +/** + * Maximum directory entry ID. + */ + +#define CFB_MAX_REG_SID 0xfffffffa + +/** + * Unallocated directory entry. + */ + +#define CFB_NO_STREAM 0xffffffff + +// typedef enum cfbSpecialSectorID_e +// { +// /** +// * Maximum sector ID. +// */ +// +// CFB_MAX_REG_SECT = 0xfffffffa, +// +// +// /** +// * Denotes a DiFAT sector ID in the FAT or MiniFAT. +// */ +// +// CFB_DIFAT_SECT = 0xfffffffc, +// +// +// /** +// * Denotes a FAT sector ID in the FAT or MiniFAT. +// */ +// +// CFB_FAT_SECT = 0xfffffffd, +// +// +// /** +// * End of a virtual stream chain. +// */ +// +// CFB_END_OF_CHAIN = 0xfffffffe, +// +// +// /** +// * Unallocated FAT or MiniFAT sector. +// */ +// +// CFB_FREE_SECT = 0xffffffff, +// +// +// /** +// * Maximum directory entry ID. +// */ +// +// CFB_MAX_REG_SID = 0xfffffffa, +// +// +// /** +// * Unallocated directory entry. +// */ +// +// CFB_NO_STREAM = 0xffffffff +// +// } cfbSpecialSectorID_e; + +/** + * Storage Type. These are the values used by cfbNode._mse + * to specify the type of the node. + * + * NOTE: microsoft already define enum tagSTGTY, but it lacks of STGTY_INVALID and STGTY_ROOT. + */ + +typedef enum customTagSTGTY { + /** + * Unknown storage type. + */ + + STGTY_INVALID = 0, + +#ifndef _WIN32 + /** + * The node is a storage object, that is a "directory" node. + * + * For AAF, this node represents an aafObject. + */ + + STGTY_STORAGE = 1, + + /** + * The node is a stream object, that is a "file" node. + * + * For AAF, this node can be a "Properties" node, a StrongRefSet, + * a StrongRefVector or a data stream containing some essence. + */ + + STGTY_STREAM = 2, + + /** + * The node is an ILockBytes object. + * + * TODO What is an ILockBytes object ? + */ + + STGTY_LOCKBYTES = 3, + + /** + * The node is an IPropertyStorage object. + * + * TODO What is an IPropertyStorage object ? + */ + + STGTY_PROPERTY = 4, + +#endif + /** + * The node is the Root node (SID 0). + */ + + STGTY_ROOT = 5 + +} cfbStorageType_e; + +/** + * This enum defines the colors for the red/black Tree. + * + * Used by cfbNode._bflags. + */ + +typedef enum tagDECOLOR { + CFB_RED = 0, + CFB_BLACK = 1 +} cfbColor_e; + +/** + * This enum defines the values for cfbHeader._uByteOrder. + */ + +typedef enum cfbByteOrder_e { + CFB_BYTE_ORDER_LE = 0xfffe, + CFB_BYTE_ORDER_BE = 0xfeff +} cfbByteOrder_e; + +/** + * The length of the cfbNode._ab uint16_t array holding the node's UTF-16 name, including + * the NULL terminating Unicode. + */ + +#define CFB_NODE_NAME_SZ 32 + +/** + * This is an arbitrary length chosen for defining a char array to store a path in the + * directory Tree. + */ + +#define CFB_PATH_NAME_SZ CFB_NODE_NAME_SZ * 64 + +/** + * This is the header of the Compound File. It corresponds to the first 512 bytes of the + * file starting at offset zero. If the sector size is greater than 512 bytes, then the + * header is padded to the sector size with zeroes. + */ + +typedef struct StructuredStorageHeader { + /** + * File Signature. Shall be {0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1}. + * + * The file signature should be `uint8_t _abSig[8]`, but we define + * it as uint64_t for quick comparison. + */ + + uint64_t _abSig; + + /** + * CFB spec says this should be set to zero, however AAF gets the file kind from + * this CLSID. Thus, this CLSID should match one of the AAFFileKind_* from + * AAFDefs/AAFFileKinds.h + */ + + cfbCLSID_t _clsid; + + /** + * Minor version of the format. 33 is written by reference implementation. + * + * This field is unused by this library. + */ + + uint16_t _uMinorVersion; + + /** + * Major version of the dll/format. 3 for 512-byte sectors, 4 for 4kB sectors. + * + * This field is unused by this library. + */ + + uint16_t _uDllVersion; + + /** + * File's byte ordering. Should be either CFB_BYTE_ORDER_LE (0xfffe) or + * CFB_BYTE_ORDER_BE (0xfeff). + * + * The spec says this field should always be little-endian byte ordering for + * maximum file portability. This implementation does not support big-endian + * byte ordering. + */ + + uint16_t _uByteOrder; + + /** + * Size of sectors in power-of-two. Typical values are 9 (512-byte sectors) + * and 12 (4096-byte sectors). + */ + + uint16_t _uSectorShift; + + /** + * Size of mini-sectors in power-of-two. Typical value is 6 (64-byte mini-sectors) + */ + + uint16_t _uMiniSectorShift; + + /** + * Reserved, must be zero. + */ + + uint16_t _usReserved; + + /** + * Reserved, must be zero. + */ + + uint32_t _ulReserved1; + + /** + * Number of sector IDs in directory chain for 4 KB sectors. Must be zero for + * 512-byte sectors. + */ + + cfbSectorID_t _csectDir; + + /** + * Number of sector IDs in the FAT chain. + */ + + cfbSectorID_t _csectFat; + + /** + * First sector ID in the directory chain. + */ + + cfbSectorID_t _sectDirStart; + + /** + * Signature used for transactions, must be zero. The reference implementation + * does not support transactions. + * + * This field is unused by this library. + * + * TODO What is a transaction ??? + */ + + uint32_t _signature; + + /** + * Maximum size for a mini-stream, typically 4096 bytes. If a streamNode + * size is below this treshold, then it is stored in the mini-stream and + * will be retrieved from the MiniFAT. Otherwise the stream is a regular + * stream, that will be retrieved from the FAT. + */ + + uint32_t _ulMiniSectorCutoff; + + /** + * First sector ID in the MiniFAT chain. + */ + + cfbSectorID_t _sectMiniFatStart; + + /** + * Number of sector IDs in the MiniFAT chain. + */ + + cfbSectorID_t _csectMiniFat; + + /** + * First sector ID in the DiFAT chain. + */ + + cfbSectorID_t _sectDifStart; + + /** + * Number of sector IDs in the DiFAT chain. + */ + + cfbSectorID_t _csectDif; + + /** + * Array of the first 109 FAT sector IDs. + * + * These are the first entries in the DiFAT. If the _csectDif is zero, then this + * is the entire DiFAT. + */ + + cfbSectorID_t _sectFat[109]; + +} cfbHeader; // __attribute__((packed)) cfbHeader; + +/** + * This structure represents a Node in the Directory stream and thus a node in the + * Directory Tree. The Compound File Directory spec calls a "Node" a "Directory". + * + * The Directory stream starts at sector ID cfbHeader._sectDirStart in the FAT and + * ends at sector ID CFB_NO_STREAM. Each directory sector is an array of directory + * entries (cfbNode), so the entire directory stream forms the array of nodes. + * An index into that array is called a stream identifier (SID). + * + * A cfbNode structure always being 128-byte long, there are `sectorSize / 128` + * cfbNode per directory sector, that is 4 cfbNode per 512-byte sector, and 32 + * cfbNode per 4-kB sector. + * + * The Directory Tree forms a red/black Tree composed of each cfbNode, in which the + * root node is the first cfbNode entry (SID 0). + */ + +/* An index used in that sector chain is called a stream identifier (SID). */ + +typedef struct StructuredStorageDirectoryEntry { + /** + * The node's name, as a Unicode string. + * + * A 64-byte array, for a maximum of 32 Unicode characters including a terminating + * Unicode NULL character. The string shall be padded with zeros to fill the array. + * + * Should be wchar_t, but on linux wchar_t is 32 bits wide as opposed to windows + * (and thus CFB) defining wchar_t to 16 bits. Conversion is done by cfb_w16towchar() + */ + + uint16_t _ab[CFB_NODE_NAME_SZ]; + + /** + * Length of the node's name in bytes, including the Unicode NULL terminating byte. + */ + + uint16_t _cb; + + /** + * Type of the node. TODO + * + * Value taken from the cfbStorageType_e enumeration. + */ + + uint8_t _mse; + + /** + * "Color" of the node. Shall be either CFB_RED or CFB_BLACK. + */ + + uint8_t _bflags; + + /** + * SID of the left-sibling of this node in the directory tree. + */ + + cfbSID_t _sidLeftSib; + + /** + * SID of the right-sibling of this node in the directory tree. + */ + + cfbSID_t _sidRightSib; + + /** + * SID of the child acting as the root node of all the children of this node. + * + * Only if _mse is STGTY_STORAGE or STGTY_ROOT. + */ + + cfbSID_t _sidChild; + + /** + * CLSID of this node. + * + * Only if _mse is STGTY_STORAGE or STGTY_ROOT. + */ + + cfbCLSID_t _clsId; + + /** + * User flags of this node. + * + * Don't know what that is, maybe some custom user flags. Looks like it + * is left unused by the AAF anyway. + * + * Only if _mse is STGTY_STORAGE or STGTY_ROOT.\n + * This field is unused by this library. + */ + + uint32_t _dwUserFlags; + + /** + * Array of two cfbFiletime_t struct. The first one holds the creation date/time, + * the second the modification date/time. + * + * Only if _mse is STGTY_STORAGE. + */ + + cfbFiletime_t _time[2]; + + /** + * First sector ID of the stream. + * + * Only if _mse is STGTY_STREAM. + */ + + cfbSectorID_t _sectStart; + + /** + * Low part of the 64-bit stream size in bytes. + * + * Only if _mse is STGTY_STREAM. + */ + + uint32_t _ulSizeLow; + + /** + * High part of 64-bit stream size. + * + * Only if _mse is STGTY_STREAM and when sector size is 4kB. Shall be zero for + * 512-byte sectors. + */ + + uint32_t _ulSizeHigh; + +} cfbNode; // __attribute__((packed)) cfbNode; + +/* Node size matching CFB file */ +#define CFB_NODE_SIZE 128 + +/** + * This structure is the main structure when using LibCFB. + */ + +typedef struct CFB_Data { + /** + * CFB file path. + */ + + char file[PATH_MAX + 1]; + + /** + * CFB file size. + */ + + size_t file_sz; + + /** + * CFB file pointer. + */ + + FILE* fp; + + /** + * Pointer to the cfbHeader structure. + */ + + cfbHeader* hdr; + + /** + * Number of (FAT) sector entries in the DiFAT. + */ + + uint32_t DiFAT_sz; + + /** + * Array of FAT sector IDs, that is sectors holding the FAT. + */ + + cfbSectorID_t* DiFAT; + + /** + * Number of sector entries in the FAT. + */ + + uint32_t fat_sz; + + /** + * Array of sector IDs. + */ + + cfbSectorID_t* fat; + + /** + * Number of mini-sector entries in the MiniFAT. + */ + + uint32_t miniFat_sz; + + /** + * Array of mini-sector IDs. + */ + + cfbSectorID_t* miniFat; + + /** + * Number of cfbNode pointers in the CFB_Data.nodes array. + */ + + uint32_t nodes_cnt; + + /** + * Array of pointers to cfbNodes. + */ + + cfbNode* nodes; + + struct dbg* dbg; + +} CFB_Data; + +/** + * @name Function macros + * @{ + */ + +/** + * Loops through each sector from a given Chain in the FAT, + * starting at sector index id. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param buf Pointer to the buffer that will hold each sector data bytes. + * @param id Index of the first sector in the Chain. + */ + +#define cfb_foreachSectorInChain(cfbd, buf, id) \ + for (buf = cfb_getSector (cfbd, id); \ + id < CFB_MAX_REG_SECT && \ + buf != NULL; \ + id = cfbd->fat[id], \ + buf = cfb_getSector (cfbd, id)) + +/** + * Loops through each sector from a given Chain in the MiniFAT, + * starting at mini-sector index id. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param buf Pointer to the buffer that will hold each mini-sector data bytes. + * @param id Index of the first mini-sector in the Chain. + */ + +#define cfb_foreachMiniSectorInChain(cfbd, buf, id) \ + for (buf = cfb_getMiniSector (cfbd, id); \ + id < CFB_MAX_REG_SECT; \ + id = cfbd->miniFat[id], \ + buf = cfb_getMiniSector (cfbd, id)) + +/** + * Loops through each DiFAT sector. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param buf Pointer to the buffer that will hold each DiFAT sector data bytes. + * @param id Index of each DiFAT sector. The first index is retrieved from the Compound + * File Binary Header, so user can pass any value (usualy 0). Then, the ID of + * the next DiFAT sector is retrieved from the last 4 bytes of each DiFAT + * sector data. + */ + +#define cfb_foreachSectorInDiFATChain(cfbd, buf, id) \ + for (id = cfbd->hdr->_sectDifStart, \ + buf = cfb_getSector (cfbd, id); \ + id < CFB_MAX_REG_SECT; \ + memcpy (&id, (buf + (1 << cfbd->hdr->_uSectorShift) - 4), sizeof (uint32_t)), \ + free (buf), \ + buf = cfb_getSector (cfbd, id)) + +/** + * Loops through each FAT sector ID in the DiFAT. + * + * @param cfbd Pointer to the CFB_Data structure. + * @param id Index of each FAT sector. + */ + +#define cfb_foreachFATSectorIDInDiFAT(cfbd, id) \ + for (id = 0; \ + id < cfbd->DiFAT_sz && \ + id < cfbd->hdr->_csectFat; \ + id++) + +/** + * Retrieves the full stream length of a streamNode. + * When 512 bytes sectors we don't care about _ulSizeHigh. + */ + +#define cfb_getNodeStreamLen(cfbd, node) \ + ((cfbd->hdr->_uSectorShift > 9) ? (uint64_t) (((uint64_t) (node->_ulSizeHigh) << 32) | (node->_ulSizeLow)) : node->_ulSizeLow) + +#define cfb_getStreamSectorShift(cfbd, node) \ + ((cfb_getNodeStreamLen (cfbd, node) < cfbd->hdr->_ulMiniSectorCutoff) ? cfbd->hdr->_uMiniSectorShift : cfbd->hdr->_uSectorShift) + +/* + * @} + */ + +const wchar_t* +cfb_CLSIDToText (const cfbCLSID_t* clsid); + +wchar_t* +cfb_w16towchar (wchar_t* buf, uint16_t* w16buf, size_t w16blen); + +/** + * @name Constructor function + * The first function to be called when using LibCFB. + * @{ + */ + +CFB_Data* +cfb_alloc (struct dbg* dbg); + +/** + * @} + * + * @name Destructor function + * The last function to be called when using LibCFB. + * @{ + */ + +void +cfb_release (CFB_Data** cfbd); + +/** + * @} + * + * @name Initialization function + * One of these function shall be called after cfb_alloc(). + * @{ + */ + +int +cfb_load_file (CFB_Data** cfbd, const char* file); + +int +cfb_new_file (CFB_Data* cfbd, const char* file, int sectSize); + +/** + * @name File parsing functions + * @{ + */ + +unsigned char* +cfb_getSector (CFB_Data* cfbd, cfbSectorID_t id); + +unsigned char* +cfb_getMiniSector (CFB_Data* cfbd, cfbSectorID_t id); + +uint64_t +cfb_getStream (CFB_Data* cfbd, cfbNode* node, unsigned char** stream, uint64_t* stream_sz); + +int +cfb__foreachSectorInStream (CFB_Data* cfbd, cfbNode* node, unsigned char** buf, size_t* bytesRead, cfbSectorID_t* sectID); + +#define cfb_foreachSectorInStream(cfbd, node, buf, bytesRead, sectID) \ + while (cfb__foreachSectorInStream (cfbd, node, buf, bytesRead, sectID)) + +/** + * @} + * + * @name Nodes access functions + * @{ + */ + +cfbNode* +cfb_getNodeByPath (CFB_Data* cfbd, const wchar_t* name, cfbSID_t id); + +cfbNode* +cfb_getChildNode (CFB_Data* cfbd, const wchar_t* name, cfbNode* startNode); + +/** + * @} + * + * @name Misc functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif // ! __LibCFB_h__ diff --git a/libs/aaf/aaf/ProTools.h b/libs/aaf/aaf/ProTools.h new file mode 100644 index 0000000000..07e92e45b9 --- /dev/null +++ b/libs/aaf/aaf/ProTools.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __ProTools_h__ +#define __ProTools_h__ + +#include "aaf/AAFIParser.h" +#include "aaf/AAFIface.h" + +enum protools_options { + PROTOOLS_REMOVE_SAMPLE_ACCURATE_EDIT = 1 << 0, + PROTOOLS_REPLACE_CLIP_FADES = 1 << 1, +}; + +#define PROTOOLS_ALL (PROTOOLS_REMOVE_SAMPLE_ACCURATE_EDIT | PROTOOLS_REPLACE_CLIP_FADES) + +int +protools_AAF (struct AAF_Iface* aafi); + +int +protools_post_processing (AAF_Iface* aafi); + +#endif // ! __ProTools_h__ diff --git a/libs/aaf/aaf/RIFFParser.h b/libs/aaf/aaf/RIFFParser.h new file mode 100644 index 0000000000..2cd57ecba6 --- /dev/null +++ b/libs/aaf/aaf/RIFFParser.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __RIFFParser__ +#define __RIFFParser__ + +#include "aaf/debug.h" + +#ifdef __GNUC__ +#define PACK(__Declaration__) __Declaration__ __attribute__ ((__packed__)) +#endif + +#ifdef _MSC_VER +#define PACK(__Declaration__) __pragma (pack (push, 1)) __Declaration__ __pragma (pack (pop)) +#endif + +enum RIFF_PARSER_FLAGS { + RIFF_PARSE_ONLY_HEADER = (1 << 0), +}; + +struct RIFFAudioFile { + /* common to wave/aiff */ + uint32_t sampleRate; + uint16_t sampleSize; + uint16_t channels; + uint64_t duration; /* total samples for 1 channel (no matter channel count). (duration / sampleRate) = duration in seconds */ +}; + +PACK (struct riffHeaderChunk { + char ckid[4]; + uint32_t cksz; + + char format[4]; + unsigned char data[]; +}); + +PACK (struct riffChunk { + char ckid[4]; + uint32_t cksz; + + unsigned char data[]; +}); + +PACK (struct wavFmtChunk { + char ckid[4]; //'fmt ' + uint32_t cksz; + + uint16_t format_tag; + uint16_t channels; + uint32_t samples_per_sec; + uint32_t avg_bytes_per_sec; + uint16_t block_align; + uint16_t bits_per_sample; +}); + +PACK (struct wavBextChunk { + char ckid[4]; //'bext' + uint32_t cksz; + + char description[256]; + + char originator[32]; + char originator_reference[32]; + char origination_date[10]; + char origination_time[8]; + + uint64_t time_reference; + + uint16_t version; + + /* since bext v1 (2001) */ + unsigned char umid[64]; + + /* since bext v2 (2011) + * + * If any loudness parameter is not + * being used, its value shall be + * set to 0x7fff. Any value outside + * valid ranges shall be ignored. + */ + int16_t loudness_value; // 0xd8f1 - 0xffff (-99.99 -0.1) and 0x000 0x270f (0.00 99.99) + int16_t loudness_range; // 0x0000 - 0x270f (0.00 99.99) + int16_t max_true_peak_level; // 0xd8f1 - 0xffff (-99.99 -0.1) and 0x000 0x270f (0.00 99.99) + int16_t max_momentary_loudness; // 0xd8f1 - 0xffff (-99.99 -0.1) and 0x000 0x270f (0.00 99.99) + int16_t max_short_term_loudness; // 0xd8f1 - 0xffff (-99.99 -0.1) and 0x000 0x270f (0.00 99.99) + + char reserved[180]; + + /* + Because it is variable size, we + do not include coding history + in the bext structure. However, + we know it starts at the end + of bext structure when parsing. + */ +}); + +PACK (struct aiffCOMMChunk { + char ckid[4]; //'COMM' + uint32_t cksz; + + uint16_t numChannels; + uint32_t numSampleFrames; + uint16_t sampleSize; + unsigned char sampleRate[10]; // 80 bit IEEE Standard 754 floating point number +}); + +int +riff_parseAudioFile (struct RIFFAudioFile* RIFFAudioFile, enum RIFF_PARSER_FLAGS flags, size_t (*readerCallback) (unsigned char*, size_t, size_t, void*, void*, void*), void* user1, void* user2, void* user3, struct dbg* dbg); + +int +riff_writeWavFileHeader (FILE* fp, struct wavFmtChunk* wavFmt, struct wavBextChunk* wavBext, uint32_t audioDataSize, struct dbg* dbg); + +#endif // ! __RIFFParser__ diff --git a/libs/aaf/aaf/Resolve.h b/libs/aaf/aaf/Resolve.h new file mode 100644 index 0000000000..682330cd5d --- /dev/null +++ b/libs/aaf/aaf/Resolve.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __Resolve_h__ +#define __Resolve_h__ + +#include "aaf/AAFIParser.h" +#include "aaf/AAFIface.h" + +enum resolve_options { + RESOLVE_INCLUDE_DISABLED_CLIPS = 1 << 0, +}; + +#define RESOLVE_ALL (RESOLVE_INCLUDE_DISABLED_CLIPS) + +int +resolve_AAF (struct AAF_Iface* aafi); + +int +resolve_parse_aafObject_Selector (struct AAF_Iface* aafi, aafObject* Selector, td* __ptd); + +int +resolve_parse_aafObject_DescriptiveMarker (struct AAF_Iface* aafi, aafObject* DescriptiveMarker, td* __ptd); + +#endif // !__Resolve_h__ diff --git a/libs/aaf/aaf/URIParser.h b/libs/aaf/aaf/URIParser.h new file mode 100644 index 0000000000..629bc5e2f1 --- /dev/null +++ b/libs/aaf/aaf/URIParser.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef URI_PARSER_H +#define URI_PARSER_H + +#include "aaf/debug.h" + +#define MAX_URI_LENGTH 64000 + +enum uri_option { + + URI_OPT_NONE = 0, + + URI_OPT_IGNORE_USERPASS = (1 << 0), + URI_OPT_IGNORE_QUERY = (1 << 1), + URI_OPT_IGNORE_FRAGMENT = (1 << 2), + + URI_OPT_DECODE_HOSTNAME = (1 << 3), + URI_OPT_DECODE_USERINFO = (1 << 4), + URI_OPT_DECODE_USERPASS = (1 << 5), + URI_OPT_DECODE_PATH = (1 << 6), + URI_OPT_DECODE_QUERY = (1 << 7), + URI_OPT_DECODE_FRAGMENT = (1 << 8) +}; + +#define URI_OPT_DECODE_ALL ( \ + URI_OPT_DECODE_HOSTNAME | \ + URI_OPT_DECODE_USERINFO | \ + URI_OPT_DECODE_USERPASS | \ + URI_OPT_DECODE_PATH | \ + URI_OPT_DECODE_QUERY | \ + URI_OPT_DECODE_FRAGMENT) + +enum uri_type { + + URI_T_GUESSED_OS_LINUX = (1 << 0), + URI_T_GUESSED_OS_APPLE = (1 << 1), + URI_T_GUESSED_OS_WINDOWS = (1 << 2), + + URI_T_HOST_EMPTY = (1 << 3), + URI_T_HOST_IPV4 = (1 << 4), + URI_T_HOST_IPV6 = (1 << 5), + URI_T_HOST_REGNAME = (1 << 6), + + URI_T_LOCALHOST = (1 << 7), +}; + +#define URI_T_GUESSED_OS_MASK ( \ + URI_T_GUESSED_OS_LINUX | \ + URI_T_GUESSED_OS_APPLE | \ + URI_T_GUESSED_OS_WINDOWS) + +#define URI_T_HOST_MASK ( \ + URI_T_HOST_EMPTY | \ + URI_T_HOST_IPV4 | \ + URI_T_HOST_IPV6 | \ + URI_T_HOST_REGNAME) + +enum uri_scheme_type { + + URI_SCHEME_T_UNKNOWN = 0, + URI_SCHEME_T_AFP, + URI_SCHEME_T_CIFS, + URI_SCHEME_T_DATA, + URI_SCHEME_T_DNS, + URI_SCHEME_T_FILE, + URI_SCHEME_T_FTP, + URI_SCHEME_T_HTTP, + URI_SCHEME_T_HTTPS, + URI_SCHEME_T_IMAP, + URI_SCHEME_T_IRC, + URI_SCHEME_T_MAILTO, + URI_SCHEME_T_NFS, + URI_SCHEME_T_POP, + URI_SCHEME_T_RTSP, + URI_SCHEME_T_SFTP, + URI_SCHEME_T_SIP, + URI_SCHEME_T_SMB, + URI_SCHEME_T_SSH, + URI_SCHEME_T_TEL, + URI_SCHEME_T_TELNET, +}; + +struct uri { + char* scheme; + char* authority; + char* userinfo; + char* user; + char* pass; + char* host; + int port; + char* path; + char* query; + char* fragment; + + enum uri_scheme_type scheme_t; + + enum uri_option opts; + enum uri_type flags; +}; + +struct uri* +uriParse (const char*, enum uri_option, struct dbg* dbg); + +void +uriFree (struct uri*); + +/* + * if dst is NULL of equals src, then encoded source string will be overwritten + * by decoded string. + */ +char* +uriDecodeString (char* src, char* dst); + +char* +uriDecodeWString (wchar_t* src, wchar_t* dst); + +int +uriIsIPv4 (const char* s, int size, char** err); + +int +uriIsIPv6 (const char* s, int size, char** err); + +#endif // ! URI_PARSER_H diff --git a/libs/aaf/aaf/debug.h b/libs/aaf/aaf/debug.h new file mode 100644 index 0000000000..0e05e3849b --- /dev/null +++ b/libs/aaf/aaf/debug.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __debug_h__ +#define __debug_h__ + +#include +#include +#include +#include + +#define __FILENAME__ (strrchr (__FILE__, '/') ? strrchr (__FILE__, '/') + 1 : __FILE__) + +enum debug_source_id { + DEBUG_SRC_ID_LIB_CFB, + DEBUG_SRC_ID_AAF_CORE, + DEBUG_SRC_ID_AAF_IFACE, + DEBUG_SRC_ID_TRACE, + DEBUG_SRC_ID_DUMP +}; + +typedef enum verbosityLevel_e { + VERB_QUIET = 0, + VERB_ERROR, + VERB_WARNING, + VERB_DEBUG, + MAX_VERB +} verbosityLevel_e; + +struct dbg { + void (*debug_callback) (struct dbg* dbg, void* ctxdata, int lib, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user); + + FILE* fp; + verbosityLevel_e verb; + + char* _dbg_msg; + int _dbg_msg_size; + + void* user; +}; + +#define _dbg(dbg, ctxdata, lib, type, ...) \ + { \ + const char* dbgfile = __FILENAME__; \ + const char* dbgfunc = __func__; \ + int dbgline = __LINE__; \ + if (dbg && dbg->verb >= type && dbg->debug_callback) { \ + int msgsize = snprintf (NULL, 0, __VA_ARGS__) + 1; \ + if (msgsize >= dbg->_dbg_msg_size) { \ + char* msgtmp = realloc (dbg->_dbg_msg, msgsize); \ + if (msgtmp) { \ + dbg->_dbg_msg = msgtmp; \ + dbg->_dbg_msg_size = msgsize; \ + snprintf (dbg->_dbg_msg, dbg->_dbg_msg_size, __VA_ARGS__); \ + dbg->debug_callback (dbg, (void*)ctxdata, lib, type, dbgfile, dbgfunc, dbgline, dbg->_dbg_msg, dbg->user); \ + } else { \ + /* Should we print error to stderr ? */ \ + } \ + } else { \ + snprintf (dbg->_dbg_msg, dbg->_dbg_msg_size, __VA_ARGS__); \ + dbg->debug_callback (dbg, (void*)ctxdata, lib, type, dbgfile, dbgfunc, dbgline, dbg->_dbg_msg, dbg->user); \ + } \ + } \ + } + +struct dbg* +laaf_new_debug (void); + +void +laaf_free_debug (struct dbg* dbg); + +void +laaf_debug_callback (struct dbg* dbg, void* ctxdata, int lib, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user); + +#endif // !__debug_h__ diff --git a/libs/aaf/aaf/libaaf.h b/libs/aaf/aaf/libaaf.h new file mode 100644 index 0000000000..5d6f54299a --- /dev/null +++ b/libs/aaf/aaf/libaaf.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef libaaf_h +#define libaaf_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "aaf/version.h" + +#include "aaf/AAFCore.h" +#include "aaf/AAFIAudioFiles.h" +#include "aaf/AAFIface.h" +#include "aaf/LibCFB.h" + +#include "aaf/AAFDump.h" +#include "aaf/CFBDump.h" + +#include "aaf/ProTools.h" +#include "aaf/Resolve.h" + +#ifdef __cplusplus +} +#endif + +#endif // ! libaaf_h diff --git a/libs/aaf/aaf/utils.h b/libs/aaf/aaf/utils.h new file mode 100644 index 0000000000..01ebef67aa --- /dev/null +++ b/libs/aaf/aaf/utils.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __utils_h__ +#define __utils_h__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#define DIR_SEP '\\' +#define DIR_SEP_STR "\\" +/* + * swprintf() specific string format identifiers + * https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-170#type + */ +#define WPRIs L"S" // char* +#define WPRIws L"s" // wchar_t* +#else +#define DIR_SEP '/' +#define DIR_SEP_STR "/" +/* + * swprintf() specific string format identifiers + * https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-170#type + */ +#define WPRIs L"s" // char* +#define WPRIws L"ls" // wchar_t* +#endif + +#define IS_DIR_SEP(c) \ + ((((c) == DIR_SEP) || ((c) == '/'))) + +#define ANSI_COLOR_RED "\033[38;5;124m" //"\x1b[31m" +#define ANSI_COLOR_GREEN "\x1b[92m" +#define ANSI_COLOR_YELLOW "\x1b[33m" //"\x1b[93m" +#define ANSI_COLOR_ORANGE "\033[38;5;130m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_CYAN "\033[38;5;81m" //"\x1b[36m" +#define ANSI_COLOR_DARKGREY "\x1b[38;5;242m" +#define ANSI_COLOR_BOLD "\x1b[1m" +#define ANSI_COLOR_RESET "\x1b[0m" + +int +laaf_util_wstr_contains_nonlatin (const wchar_t* str); + +char* +laaf_util_clean_filename (char* filename); + +const char* +laaf_util_fop_get_file (const char* filepath); + +char* +laaf_util_build_path (const char* sep, const char* first, ...); + +int +laaf_util_snprintf_realloc (char** str, int* size, size_t offset, const char* format, ...); + +int +laaf_util_vsnprintf_realloc (char** str, int* size, int offset, const char* fmt, va_list* args); + +char* +laaf_util_c99strdup (const char* src); + +int +laaf_util_dump_hex (const unsigned char* stream, size_t stream_sz, char** buf, int* bufsz, int offset); + +#ifdef __cplusplus +} +#endif + +#endif // ! __utils_h__ diff --git a/libs/aaf/aaf/version.h b/libs/aaf/aaf/version.h new file mode 100644 index 0000000000..51132ec249 --- /dev/null +++ b/libs/aaf/aaf/version.h @@ -0,0 +1,2 @@ +#pragma once +#define LIBAAF_VERSION "v0.1-85-g3e4c2cd" diff --git a/libs/aaf/debug.c b/libs/aaf/debug.c new file mode 100644 index 0000000000..7ab5f31832 --- /dev/null +++ b/libs/aaf/debug.c @@ -0,0 +1,98 @@ +#include + +#include "aaf/debug.h" + +#include "aaf/AAFCore.h" +#include "aaf/AAFIParser.h" +#include "aaf/AAFIface.h" +#include "aaf/LibCFB.h" + +#include "aaf/utils.h" + +struct dbg* +laaf_new_debug (void) +{ + struct dbg* dbg = calloc (sizeof (struct dbg), sizeof (char)); + + dbg->debug_callback = &laaf_debug_callback; + dbg->fp = stdout; + + return dbg; +} + +void +laaf_free_debug (struct dbg* dbg) +{ + if (dbg->_dbg_msg) { + free (dbg->_dbg_msg); + } + + free (dbg); +} + +void +laaf_debug_callback (struct dbg* dbg, void* ctxdata, int libid, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user) +{ + AAF_Iface* aafi = NULL; + AAF_Data* aafd = NULL; + CFB_Data* cfbd = NULL; + + const char* lib = ""; + const char* typestr = ""; + const char* color = ""; + + if (dbg->fp == NULL) { + return; + } + + switch (libid) { + case DEBUG_SRC_ID_LIB_CFB: + lib = "libCFB"; + aafi = (AAF_Iface*)ctxdata; + break; + case DEBUG_SRC_ID_AAF_CORE: + lib = "AAFCore"; + aafd = (AAF_Data*)ctxdata; + break; + case DEBUG_SRC_ID_AAF_IFACE: + lib = "AAFIface"; + cfbd = (CFB_Data*)ctxdata; + break; + case DEBUG_SRC_ID_TRACE: + lib = "trace"; + aafi = (AAF_Iface*)ctxdata; + break; + case DEBUG_SRC_ID_DUMP: + lib = "dump"; + break; + } + + switch (type) { + case VERB_ERROR: + typestr = " error "; + color = ANSI_COLOR_RED; + break; + case VERB_WARNING: + typestr = "warning"; + color = ANSI_COLOR_YELLOW; + break; + case VERB_DEBUG: + typestr = " debug "; + color = ANSI_COLOR_DARKGREY; + break; + } + + if (libid != DEBUG_SRC_ID_TRACE && libid != DEBUG_SRC_ID_DUMP) { + fprintf (dbg->fp, "[%s%s%s] ", color, typestr, ANSI_COLOR_RESET); + fprintf (dbg->fp, "%s%s:%i in %s()%s : ", ANSI_COLOR_DARKGREY, srcfile, lineno, srcfunc, ANSI_COLOR_RESET); + } + + fprintf (dbg->fp, "%s\n", msg); + + /* avoids -Wunused-parameter -Wunused-but-set-variable */ + (void)aafi; + (void)aafd; + (void)cfbd; + (void)lib; + (void)user; +} diff --git a/libs/aaf/utils.c b/libs/aaf/utils.c new file mode 100644 index 0000000000..2abf3795b4 --- /dev/null +++ b/libs/aaf/utils.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2017-2023 Adrien Gesta-Fline + * + * This file is part of libAAF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "aaf/utils.h" + +#define BUILD_PATH_DEFAULT_BUF_SIZE 1024 + +int +laaf_util_wstr_contains_nonlatin (const wchar_t* str) +{ + for (size_t i = 0; str[i] != 0x0000; i++) { + /* if char is out of the Basic Latin range */ + if (str[i] > 0xff) { + return 1; + } + } + + return 0; +} + +char* +laaf_util_clean_filename (char* fname) +{ + /* + * sanitize file/dir name + * https://stackoverflow.com/a/31976060 + */ + size_t len = strlen (fname); + + for (size_t i = 0; i < len; i++) { + unsigned char c = fname[i]; + + if (c == '/' || + c == '<' || + c == '>' || + c == ':' || + c == '"' || + c == '|' || + c == '?' || + c == '*' || + c == '\\' || + (c > 0 && c < 0x20)) { + fname[i] = '_'; + } + } + + /* windows filenames can't end with ' ' or '.' */ + for (int i = len - 1; i > 0; i--) { + char c = fname[i]; + if (c != ' ' && c != '.') { + break; + } + fname[i] = '_'; + } + + return fname; +} + +const char* +laaf_util_fop_get_file (const char* filepath) +{ + if (filepath == NULL) { + return NULL; + } + + const char* end = filepath + strlen (filepath); + + while (end > filepath && !IS_DIR_SEP (*end)) { + --end; + } + + return (IS_DIR_SEP (*end)) ? end + 1 : end; +} + +char* +laaf_util_build_path (const char* sep, const char* first, ...) +{ + char* str = malloc (BUILD_PATH_DEFAULT_BUF_SIZE); + + if (str == NULL) { + return NULL; + } + + size_t len = BUILD_PATH_DEFAULT_BUF_SIZE; + size_t offset = 0; + + va_list args; + + if (!sep) { + sep = DIR_SEP_STR; + } + + int element_count = 0; + + va_start (args, first); + + const char* arg = first; + + do { + int arglen = strlen (arg); + int argstart = 0; + int has_leading_sep = 0; + + /* trim leading DIR_SEP */ + for (int i = 0; arg[i] != 0x00; i++) { + if (IS_DIR_SEP (arg[i])) { + has_leading_sep = 1; + argstart++; + } else { + break; + } + } + + /* trim trailing DIR_SEP */ + for (int i = arglen - 1; i >= argstart; i--) { + if (IS_DIR_SEP (arg[i])) { + arglen--; + } else { + break; + } + } + + /* TODO ? */ + if (element_count == 0 && has_leading_sep) { + } else { + } + + size_t reqlen = snprintf (NULL, 0, "%.*s", arglen - argstart, arg + argstart) + 1; + + if (offset + reqlen >= len) { + reqlen = ((offset + reqlen) > (len + BUILD_PATH_DEFAULT_BUF_SIZE)) ? (offset + reqlen) : (len + BUILD_PATH_DEFAULT_BUF_SIZE); + + char* tmp = realloc (str, (offset + reqlen)); + + if (tmp) { + str = tmp; + len = (offset + reqlen); + } else { + free (str); + return NULL; + } + } + + offset += snprintf (str + offset, len - offset, "%s%.*s", + ((element_count == 0 && has_leading_sep) || (element_count > 0)) ? sep : "", + arglen - argstart, + arg + argstart); + + element_count++; + + } while ((arg = va_arg (args, char*)) != NULL); + + va_end (args); + + return str; +} + +int +laaf_util_snprintf_realloc (char** str, int* size, size_t offset, const char* format, ...) +{ + int tmpsize = 0; + + if (!size) { + size = &tmpsize; + } + + int retval, needed; + va_list ap; + + va_start (ap, format); + + while (0 <= (retval = vsnprintf ((*str) + offset, (*size) - offset, format, ap)) && (int64_t) ((*size) - offset) < (needed = retval + 1)) { + va_end (ap); + + *size *= 2; + + if ((int64_t) ((*size) - offset) < needed) + *size = needed + offset; + + char* p = realloc (*str, *size); + + if (p) { + *str = p; + } else { + free (*str); + *str = NULL; + *size = 0; + return -1; + } + + va_start (ap, format); + } + + va_end (ap); + + return retval; +} + +int +laaf_util_vsnprintf_realloc (char** str, int* size, int offset, const char* fmt, va_list* args) +{ + va_list args2, args3; + + va_copy (args2, *args); + va_copy (args3, *args); + + int needed = vsnprintf (NULL, 0, fmt, args2) + 1; + + if (needed >= (*size) - offset) { + char* p = realloc (*str, offset + needed); + + if (p) { + *str = p; + *size = offset + needed; + } else { + /* If realloc() fails, the original block is left untouched; it is not freed or moved. */ + va_end (args2); + va_end (args3); + + return -1; + } + } + va_end (args2); + + int written = vsnprintf ((*str) + offset, (*size) - offset, fmt, args3); + + va_end (args3); + + return written; +} + +char* +laaf_util_c99strdup (const char* src) +{ + if (!src) { + return NULL; + } + + int len = 0; + + while (src[len]) { + len++; + } + + char* str = malloc (len + 1); + + if (!str) + return NULL; + + char* p = str; + + while (*src) { + *(p++) = *(src++); + } + + *p = '\0'; + + return str; +} + +int +laaf_util_dump_hex (const unsigned char* stream, size_t stream_sz, char** buf, int* bufsz, int offset) +{ + if (stream == NULL) { + return -1; + } + + int initialOffset = offset; + uint32_t i = 0; + + char hex[49]; + char ascii[19]; + + uint32_t count = 0; + + offset += laaf_util_snprintf_realloc (buf, bufsz, offset, " ______________________________ Hex Dump ______________________________\n\n"); + + while (count < stream_sz) { + uint32_t lineLen = (stream_sz - count) / 16; + + if (lineLen <= 0) + lineLen = (stream_sz) % 16; + else + lineLen = 16; + + memset (&hex, 0x20, sizeof (hex)); + memset (&ascii, 0x00, sizeof (ascii)); + + uint32_t linepos = 0; + + for (i = 0; i < lineLen; i++) { + linepos += snprintf (&hex[linepos], sizeof (hex) - (linepos), "%02x%s", *(const unsigned char*)(stream + count + i), (i == 7) ? " " : " "); + + if (i < 8) { + if (isalnum (*(stream + count + i))) + ascii[i] = *(const unsigned char*)(stream + count + i); + else + ascii[i] = '.'; + } else if (i > 8) { + if (isalnum (*(stream + count + i))) + ascii[i + 1] = *(const unsigned char*)(stream + count + i); + else + ascii[i + 1] = '.'; + } else { + if (isalnum (*(stream + count + i))) { + ascii[i] = ' '; + ascii[i + 1] = *(const unsigned char*)(stream + count + i); + } else { + ascii[i] = ' '; + ascii[i + 1] = '.'; + } + } + } + + /* Fill with blank the rest of the line */ + if (lineLen < 16) { + for (i = linepos; i < 48; i++) { + hex[linepos++] = 0x20; + } + } + + /* terminate the line */ + hex[48] = 0x00; + + count += lineLen; + + offset += laaf_util_snprintf_realloc (buf, bufsz, offset, " %s | %s\n", hex, ascii); + } + + offset += laaf_util_snprintf_realloc (buf, bufsz, offset, " ______________________________________________________________________\n\n"); + + return offset - initialOffset; /* bytes written */ +}