void AxCreateCompositionExample( AxFile& axFile, AxCmdLineArgs& args ) { // FIXME - This function is too long. // As usual, the header and dictionary are required. AxHeader axHeader( axFile.getHeader() ); AxDictionary axDictionary( axHeader.GetDictionary() ); AxContentStorage axContentStorage( axHeader.GetContentStorage() ); aafSearchCrit_t criteria; criteria.searchTag = kAAFByMobKind; criteria.tags.mobKind = kAAFMasterMob; AxMobIter axMobIter( axContentStorage.GetMobs( &criteria ) ); IAAFSmartPointer2<IAAFMob> nextMob; bool notAtEnd; typedef std::map< AxString, IAAFMasterMobSP > MobMap; MobMap mobMap; for( notAtEnd = axMobIter.NextOne( nextMob ); notAtEnd; notAtEnd = axMobIter.NextOne( nextMob ) ) { AxMasterMob axMasterMob( AxQueryInterface<IAAFMob,IAAFMasterMob>( nextMob ) ); mobMap[ axMasterMob.GetName() ] = axMasterMob; } AxString audioA( L"Audio Mob A" ); AxString audioB( L"Audio Mob B" ); AxString videoA( L"Video Mob A" ); AxString videoB( L"Video Mob B" ); // Verify our mobs exist... if ( mobMap.find( audioA ) == mobMap.end() || mobMap.find( audioB ) == mobMap.end() || mobMap.find( videoA ) == mobMap.end() || mobMap.find( videoB ) == mobMap.end() ) { throw AxEx( L"mob not found" ); } // Create the composition mob off which we with hang our // audio source clips, video source clips and transitions. AxCompositionMob axCompMob( AxCreateInstance<IAAFCompositionMob>( axDictionary ) ); axCompMob.SetName( L"Example Composition" ); axHeader.AddMob( axCompMob ); aafRational_t editRate = {25, 1}; int videoSlotID = 1; AxString videoSlotName( L"Video Timeline" ); int audioSlotID = 2; AxString audioSlotName( L"Audio Timeline" ); // // Create one sequence for each time line (i.e. track). // AxDataDef axAudioDataDef( axDictionary.LookupDataDef( kAAFDataDef_Sound ) ); AxSequence axAudioSequence( AxCreateInstance<IAAFSequence>( axDictionary ) ); axAudioSequence.Initialize( axAudioDataDef ); AxDataDef axVideoDataDef( axDictionary.LookupDataDef( kAAFDataDef_Picture ) ); AxSequence axVideoSequence( AxCreateInstance<IAAFSequence>( axDictionary ) ); axVideoSequence.Initialize( axVideoDataDef ); // // Append one timeline slot per sequence to the composition mob. // axCompMob.AppendNewTimelineSlot( editRate, axVideoSequence, videoSlotID, videoSlotName, 0 // origin (aafPosition_t) ); axCompMob.AppendNewTimelineSlot( editRate, axAudioSequence, audioSlotID, audioSlotName, 0 // origin (aafPosition_t) ); // // Create source clips and transitions. // // First audio.... AxMasterMob axAudioMobA( mobMap[ audioA ] ); AxMasterMob axAudioMobB( mobMap[ audioB ] ); AxSourceClip axAudioClipA ( CreateSourceClipToAppendToSequence( axDictionary, axAudioMobA, axAudioSequence ) ); AxSourceClip axAudioClipB ( CreateSourceClipToAppendToSequence( axDictionary, axAudioMobB, axAudioSequence ) ); // If the operation definition is not in the dictionary already, then it is // the programmers job to create the operation definition, initialize it, // and register it. if ( !axDictionary.isKnownOperationDef( kAAFEffectMonoAudioDissolve ) ) { AxOperationDef axOpDef( AxCreateInstance<IAAFOperationDef> ( axDictionary ) ); axOpDef.Initialize( kAAFEffectMonoAudioDissolve, L"Example Mono Audio Dissolve", L"No timewarp, bypass track 0, 2 mono audio inputs" ); axOpDef.SetIsTimeWarp( false ); axOpDef.SetCategory( kAAFEffectMonoAudioDissolve ); axOpDef.SetBypass( 0 ); axOpDef.SetNumberInputs( 2 ); axOpDef.SetDataDef( axAudioDataDef ); axDictionary.RegisterOperationDef( axOpDef ); } AxOperationDef axMonoAudioDslvOpDef( axDictionary.LookupOperationDef( kAAFEffectMonoAudioDissolve ) ); AxOperationGroup axMonoAudioDslvOpGroup( AxCreateInstance<IAAFOperationGroup>( axDictionary ) ); // FIXME - Duration... that's in samples - right? // We will overlap the segment by 1 pal frame (at 44100 samples/sec). // FIXME - Assumed rate and duration of source material. axMonoAudioDslvOpGroup.Initialize( axAudioDataDef, 44100/25, axMonoAudioDslvOpDef ); AxTransition axMonoAudioDslvTransition( AxCreateInstance<IAAFTransition>( axDictionary ) ); axMonoAudioDslvTransition.Initialize( axAudioDataDef, 44100/25, 0, axMonoAudioDslvOpGroup ); // Next video... AxMasterMob axVideoMobA( mobMap[ videoA ] ); AxMasterMob axVideoMobB( mobMap[ videoB ] ); AxSourceClip axVideoClipA ( CreateSourceClipToAppendToSequence( axDictionary, axVideoMobA, axVideoSequence ) ); AxSourceClip axVideoClipB ( CreateSourceClipToAppendToSequence( axDictionary, axVideoMobB, axVideoSequence ) ); // // Setup a video dissolve // // If the operation definition is not in the dictionary already, then it is // the programmers job to create the operation definition, initialize it, // and register it. if ( !axDictionary.isKnownOperationDef( kAAFEffectVideoDissolve ) ) { AxOperationDef axOpDef( AxCreateInstance<IAAFOperationDef> ( axDictionary ) ); axOpDef.Initialize( kAAFEffectVideoDissolve, L"Example Video Dissolve", L"No timewarp, bypass track 0, 2 video inputs" ); axOpDef.SetIsTimeWarp( false ); axOpDef.SetCategory( kAAFEffectVideoDissolve ); axOpDef.SetBypass( 0 ); axOpDef.SetNumberInputs( 2 ); axOpDef.SetDataDef( axAudioDataDef ); axDictionary.RegisterOperationDef( axOpDef ); } AxOperationDef axVideoDslvOpDef( axDictionary.LookupOperationDef( kAAFEffectVideoDissolve ) ); AxOperationGroup axVideoDslvOpGroup( AxCreateInstance<IAAFOperationGroup>( axDictionary ) ); // Overlap by one frame. // FIXME - Hardcoded. axVideoDslvOpGroup.Initialize( axVideoDataDef, 1, axVideoDslvOpDef ); AxTransition axVideoDslvTransition( AxCreateInstance<IAAFTransition>( axDictionary ) ); axVideoDslvTransition.Initialize( axVideoDataDef, 1, 0, axVideoDslvOpGroup ); // // Append the series of components to the sequences to form each // track. The components order is: // [first segment of essence] [transition] [second segment of essence] // axAudioSequence.AppendComponent( axAudioClipA ); axAudioSequence.AppendComponent( axMonoAudioDslvTransition ); axAudioSequence.AppendComponent( axAudioClipB ); axVideoSequence.AppendComponent( axVideoClipA ); axVideoSequence.AppendComponent( axVideoDslvTransition ); axVideoSequence.AppendComponent( axVideoClipB ); }
int main( int argc, char* argv[] ) { using namespace std; try { // Second command line argument is the filename AxCmdLineArgs args( argc, argv ); // pair<bool, const char*> fileArg = args.get(1); pair<bool, int> fileOpArg = args.get( "-file" ); if ( !fileOpArg.first ) { throwUsage(); } pair<bool, const char*> fileNameArg = args.get( fileOpArg.second + 1 ); if ( !fileNameArg.first ) { throwUsage(); } AxString fileName( AxStringUtil::mbtowc( fileNameArg.second ) ); // One time init stuff. Including loading the com api library. AxInit initObj; // Open the file. AxFile axFile; axFile.OpenExistingRead( fileName ); // Get the header to use as a root object from which to begin iteration. // Any object, property, or property value can be used as a root object. // Generally, you probably not start with the header - you would start // with the ContentStorage object, or the Mobs or EssenceData properties // of the ContentStorage object. AxHeader axHeader( axFile.getHeader() ); wcout << axHeader << endl; AxDictionary axDictionary( axHeader.GetDictionary() ); // The header must be wrapped up by a AxBaseSolitaryObjIter instance // in order to be used a root for the recursive iterator. // If you follow the code, you will see that the header object is, ultimately, // cast to AxObject so that the IAAFObject interface of the header can be used // to access its properties. { auto_ptr< AxBaseObjIterPrtcl > axHeaderIter( new AxBaseSolitaryObjIter<AxHeader>(axHeader) ); // Create a recursive iterator... AxBaseObjRecIter recIter( axHeaderIter ); // ... and run through all values registering // a renamed type for each opaque type. wcout << L"Rename Pesky Opaques:" << endl; int count = renamePeskyOpaques( axDictionary, recIter ); wcout << L"\tOpaques reported by dictionary: " << axDictionary.CountOpaqueTypeDefs() << endl; wcout << L"\tOpaques found and renamed: " << count << endl; } { auto_ptr< AxBaseObjIterPrtcl > axHeaderIter( new AxBaseSolitaryObjIter<AxHeader>(axHeader) ); // Create a recursive iterator... AxBaseObjRecIter recIter( axHeaderIter ); // ... and dump all objects. wcout << endl << L"Recursive Dump:" << endl; wcout << endl << L" Item Level Desc. Detail" << endl; dumpBaseObjects( axDictionary, recIter, args ); } // That's all folks. axFile.Close(); wcout << L"That's all folks." << endl; } catch ( const AxEx& ex ) { wcout << ex.what() << endl; } return 0; }