[xiph-commits] r11271 - in trunk/xiph-qt: OggImport OggImport/OggImport.xcodeproj OggImport/src common

arek at svn.xiph.org arek at svn.xiph.org
Mon Apr 24 15:13:03 PDT 2006


Author: arek
Date: 2006-04-24 15:12:39 -0700 (Mon, 24 Apr 2006)
New Revision: 11271

Added:
   trunk/xiph-qt/OggImport/src/stream_theora.c
   trunk/xiph-qt/OggImport/src/stream_theora.h
   trunk/xiph-qt/OggImport/src/stream_types_theora.h
Modified:
   trunk/xiph-qt/OggImport/Info.plist
   trunk/xiph-qt/OggImport/OggImport.xcodeproj/project.pbxproj
   trunk/xiph-qt/OggImport/src/OggImport.c
   trunk/xiph-qt/OggImport/src/OggImport.r
   trunk/xiph-qt/OggImport/src/importer_types.h
   trunk/xiph-qt/OggImport/src/stream_flac.c
   trunk/xiph-qt/OggImport/src/stream_flac.h
   trunk/xiph-qt/OggImport/src/stream_speex.h
   trunk/xiph-qt/OggImport/src/stream_types_flac.h
   trunk/xiph-qt/OggImport/src/stream_types_speex.h
   trunk/xiph-qt/OggImport/src/stream_types_vorbis.h
   trunk/xiph-qt/OggImport/src/stream_vorbis.c
   trunk/xiph-qt/OggImport/src/stream_vorbis.h
   trunk/xiph-qt/OggImport/src/versions.h
   trunk/xiph-qt/common/data_types.h
Log:
A numer of offline-accumulated changes:
 * tags handling in FLAC importer;
 * a bit more 'validation' in FLAC code;
 * code to save FLAC metadata blocks in 'cookie';
 * added Annodex mime-type to importer configuration resources;
 * marking of first audio data page for Vorbis;
 * and intruducing Theora importing support.

Some other small changes, as well.


Modified: trunk/xiph-qt/OggImport/Info.plist
===================================================================
--- trunk/xiph-qt/OggImport/Info.plist	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/Info.plist	2006-04-24 22:12:39 UTC (rev 11271)
@@ -6,6 +6,8 @@
 	<string>English</string>
 	<key>CFBundleExecutable</key>
 	<string>OggImport</string>
+	<key>CFBundleGetInfoString</key>
+	<string>QuickTime Ogg Importer Component 0.1.6, Copyright © 2005-2006 Arek Korbik</string>
 	<key>CFBundleIconFile</key>
 	<string></string>
 	<key>CFBundleIdentifier</key>
@@ -15,11 +17,13 @@
 	<key>CFBundlePackageType</key>
 	<string>BNDL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>0.1.3</string>
+	<string>0.1.6</string>
 	<key>CFBundleSignature</key>
 	<string>eat </string>
 	<key>CFBundleVersion</key>
-	<string>0.1.3</string>
+	<string>0.1.6</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>QuickTime Ogg Importer Component 0.1.6, Copyright © 2005-2006 Arek Korbik</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 </dict>

Modified: trunk/xiph-qt/OggImport/OggImport.xcodeproj/project.pbxproj
===================================================================
--- trunk/xiph-qt/OggImport/OggImport.xcodeproj/project.pbxproj	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/OggImport.xcodeproj/project.pbxproj	2006-04-24 22:12:39 UTC (rev 11271)
@@ -19,7 +19,8 @@
 		73182D9F090AB83F00C25A13 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73182D9E090AB83F00C25A13 /* Vorbis.framework */; };
 		73182E37090AD49700C25A13 /* stream_vorbis.c in Sources */ = {isa = PBXBuildFile; fileRef = 73182E35090AD49700C25A13 /* stream_vorbis.c */; };
 		73A515E509844E1D0018101A /* stream_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 73A515E209844E1D0018101A /* stream_flac.c */; };
-		73DDD2B3093E665C001E170C /* config.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 73DDD2B2093E665C001E170C /* config.h */; };
+		73BED3E709D77E8500ACC195 /* stream_theora.c in Sources */ = {isa = PBXBuildFile; fileRef = 73BED3E409D77E8500ACC195 /* stream_theora.c */; };
+		73BED41A09D780F300ACC195 /* Theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73BED41909D780F300ACC195 /* Theora.framework */; };
 		73E8B16D090BE13600686EE5 /* stream_speex.c in Sources */ = {isa = PBXBuildFile; fileRef = 73E8B16A090BE13600686EE5 /* stream_speex.c */; };
 		8D01CCCA0486CAD60068D4B7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
 		8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */; };
@@ -57,7 +58,6 @@
 			dstSubfolderSpec = 1;
 			files = (
 				73182D90090AB6D500C25A13 /* PkgInfo in CopyFiles */,
-				73DDD2B3093E665C001E170C /* config.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -94,6 +94,10 @@
 		73A515E209844E1D0018101A /* stream_flac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_flac.c; path = src/stream_flac.c; sourceTree = "<group>"; };
 		73A515E309844E1D0018101A /* stream_flac.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stream_flac.h; path = src/stream_flac.h; sourceTree = "<group>"; };
 		73A515E409844E1D0018101A /* stream_types_flac.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stream_types_flac.h; path = src/stream_types_flac.h; sourceTree = "<group>"; };
+		73BED3E409D77E8500ACC195 /* stream_theora.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_theora.c; path = src/stream_theora.c; sourceTree = "<group>"; };
+		73BED3E509D77E8500ACC195 /* stream_theora.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stream_theora.h; path = src/stream_theora.h; sourceTree = "<group>"; };
+		73BED3E609D77E8500ACC195 /* stream_types_theora.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = stream_types_theora.h; path = src/stream_types_theora.h; sourceTree = "<group>"; };
+		73BED41909D780F300ACC195 /* Theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Theora.framework; path = /Library/Frameworks/Theora.framework; sourceTree = "<absolute>"; };
 		73DDD2B2093E665C001E170C /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../common/config.h; sourceTree = SOURCE_ROOT; };
 		73E8B10F090BCB6100686EE5 /* data_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = data_types.h; path = ../common/data_types.h; sourceTree = SOURCE_ROOT; };
 		73E8B16A090BE13600686EE5 /* stream_speex.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = stream_speex.c; path = src/stream_speex.c; sourceTree = "<group>"; };
@@ -113,6 +117,7 @@
 				73182D74090AB07400C25A13 /* QuickTime.framework in Frameworks */,
 				73182D76090AB09000C25A13 /* Ogg.framework in Frameworks */,
 				73182D9F090AB83F00C25A13 /* Vorbis.framework in Frameworks */,
+				73BED41A09D780F300ACC195 /* Theora.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -133,6 +138,7 @@
 		089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
 			isa = PBXGroup;
 			children = (
+				73BED41909D780F300ACC195 /* Theora.framework */,
 				73182D9E090AB83F00C25A13 /* Vorbis.framework */,
 				73182D75090AB09000C25A13 /* Ogg.framework */,
 				73182D71090AB07400C25A13 /* CoreFoundation.framework */,
@@ -159,6 +165,7 @@
 		08FB77ADFE841716C02AAC07 /* Source */ = {
 			isa = PBXGroup;
 			children = (
+				73BED3E309D77E6300ACC195 /* theora */,
 				73A515E109844DF70018101A /* flac */,
 				73E8B169090BE11D00686EE5 /* speex */,
 				73E8B162090BDE5D00686EE5 /* vorbis */,
@@ -199,6 +206,16 @@
 			name = flac;
 			sourceTree = "<group>";
 		};
+		73BED3E309D77E6300ACC195 /* theora */ = {
+			isa = PBXGroup;
+			children = (
+				73BED3E409D77E8500ACC195 /* stream_theora.c */,
+				73BED3E509D77E8500ACC195 /* stream_theora.h */,
+				73BED3E609D77E8500ACC195 /* stream_types_theora.h */,
+			);
+			name = theora;
+			sourceTree = "<group>";
+		};
 		73E8B162090BDE5D00686EE5 /* vorbis */ = {
 			isa = PBXGroup;
 			children = (
@@ -325,6 +342,7 @@
 				73182E37090AD49700C25A13 /* stream_vorbis.c in Sources */,
 				73E8B16D090BE13600686EE5 /* stream_speex.c in Sources */,
 				73A515E509844E1D0018101A /* stream_flac.c in Sources */,
+				73BED3E709D77E8500ACC195 /* stream_theora.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/xiph-qt/OggImport/src/OggImport.c
===================================================================
--- trunk/xiph-qt/OggImport/src/OggImport.c	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/OggImport.c	2006-04-24 22:12:39 UTC (rev 11271)
@@ -65,6 +65,7 @@
 #include "stream_vorbis.h"
 #include "stream_speex.h"
 #include "stream_flac.h"
+#include "stream_theora.h"
 
 static stream_format_handle_funcs s_formats[] = {
 #if defined(_HAVE__VORBIS_SUPPORT)
@@ -76,6 +77,9 @@
 #if defined(_HAVE__SPEEX_SUPPORT)
     HANDLE_FUNCTIONS__SPEEX,
 #endif
+#if defined(_HAVE__THEORA_SUPPORT)
+    HANDLE_FUNCTIONS__THEORA,
+#endif
 
     HANDLE_FUNCTIONS__NULL
 };
@@ -314,6 +318,8 @@
         si->MDmapping = NULL;
         si->UDmapping = NULL;
 
+        // si->sampleOffset = 0;
+
         globals->numTracksStarted++;
     }
 
@@ -689,7 +695,10 @@
         if (err == noErr)
         {
             dbg_printf("! -- SampleDescription created OK\n");
-            si->theTrack = NewMovieTrack(globals->theMovie, 0, 0, kFullVolume);
+            if (si->sfhf->track != NULL)
+                /* err = */ (*si->sfhf->track)(globals, si);
+            else
+                si->theTrack = NewMovieTrack(globals->theMovie, 0, 0, kFullVolume);
             if (si->theTrack)
             {
                 Handle data_ref = globals->dataRef;
@@ -702,9 +711,14 @@
                     err = DataHGetDataRef(globals->dataReader, &data_ref);
 
                 if (err == noErr) {
-                    dbg_printf("! -- calling => NewTrackMedia(%lx)\n", si->rate);
-                    si->theMedia = NewTrackMedia(si->theTrack, SoundMediaType,
-                                                 si->rate, data_ref, globals->dataRefType);
+                    if (si->sfhf->track_media != NULL)
+                        /* err = */ (*si->sfhf->track_media)(globals, si, data_ref);
+                    else {
+                        dbg_printf("! -- calling => NewTrackMedia(%lx)\n", si->rate);
+                        si->theMedia = NewTrackMedia(si->theTrack, SoundMediaType,
+                                                     si->rate, data_ref, globals->dataRefType);
+                    }
+
                     if (data_ref != globals->dataRef)
                         DisposeHandle(data_ref);
                 }

Modified: trunk/xiph-qt/OggImport/src/OggImport.r
===================================================================
--- trunk/xiph-qt/OggImport/src/OggImport.r	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/OggImport.r	2006-04-24 22:12:39 UTC (rev 11271)
@@ -188,6 +188,31 @@
     'thnr', kImporterResID, 0
 };
 
+// Component Alias
+resource 'thga' (kImporterResID + 3, OggImporterName, purgeable) {
+    kImporterComponentType,             // Type
+    'ANX ',                             // Subtype - this must be in uppercase.
+                                        // It will match an ".anx" suffix case-insensitively.
+    'soun',                             // Manufacturer
+    kImporterFlags | movieImportSubTypeIsFileExtension,	// The subtype is a file name suffix
+    0,                                  // Component Flags Mask
+    0,                                  // Code Type
+    0,                                  // Code ID
+    'STR ',                             // Name Type
+    kImporterNameStringResID,           // Name ID
+    'STR ',                             // Info Type
+    kImporterInfoStringResID,           // Info ID
+    0,                                  // Icon Type
+    0,                                  // Icon ID
+                // TARGET COMPONENT ---------------
+    kImporterComponentType,             // Type
+    kCodecFormat,                       // SubType
+    'soun',                             // Manufaturer
+    kImporterFlags,                     // Component Flags
+    0,                                  // Component Flags Mask
+    'thnr', kImporterResID, 0
+};
+
 resource 'thnr' (kImporterResID, OggImporterName, purgeable) {
     {
         'mime', 1, 0, 'mime', kImporterResID, cmpResourceNoFlags,
@@ -221,14 +246,17 @@
         kMimeInfoMimeTypeTag,      2, "application/x-ogg";
         kMimeInfoMimeTypeTag,      3, "audio/x-speex";
         kMimeInfoMimeTypeTag,      4, "audio/speex";
+        kMimeInfoMimeTypeTag,      5, "application/x-annodex";
         kMimeInfoFileExtensionTag, 1, "ogg";
         kMimeInfoFileExtensionTag, 2, "ogg";
         kMimeInfoFileExtensionTag, 3, "spx";
         kMimeInfoFileExtensionTag, 4, "spx";
+        kMimeInfoFileExtensionTag, 5, "anx";
         kMimeInfoDescriptionTag,   1, "Ogg Vorbis";
         kMimeInfoDescriptionTag,   2, "Ogg Vorbis";
         kMimeInfoDescriptionTag,   3, "Ogg Speex";
         kMimeInfoDescriptionTag,   4, "Ogg Speex";
+        kMimeInfoDescriptionTag,   5, "Annodex";
     };
 };
 
@@ -293,6 +321,35 @@
             "audio/x-speex";
             "audio/speex";
         };
+//    };
+//    {
+        kQTMediaConfigAudioGroupID,
+        kQTMediaConfigBinaryFile | \
+            kQTMediaConfigCanUseApp | kQTMediaConfigCanUsePlugin | \
+            kQTMediaConfigUsePluginByDefault,
+        'OggS',
+        'TVOD',	/* we don't have a creator code for our files, hijack QT player */
+        kImporterComponentType, kCodecFormat, kSoundComponentManufacturer,
+        0, 0,
+        'ANX ',
+        kQTMediaInfoNetGroup,
+
+        /* no synonyms */
+        {
+        },
+
+        {
+            "Annodex media file",
+            "anx",
+            "QuickTime Player",
+            "Annodex file importer",
+            "",
+        },
+
+        /* mime types array */
+        {
+            "application/x-annodex";
+        };
     };
 };
 

Modified: trunk/xiph-qt/OggImport/src/importer_types.h
===================================================================
--- trunk/xiph-qt/OggImport/src/importer_types.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/importer_types.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -67,6 +67,7 @@
 #include "stream_types_vorbis.h"
 #include "stream_types_speex.h"
 #include "stream_types_flac.h"
+#include "stream_types_theora.h"
 
 #define INCOMPLETE_PAGE_DURATION 1
 
@@ -105,6 +106,7 @@
 
     TimeValue           insertTime;
     TimeValue           streamOffset;
+    // SInt32              sampleOffset;
 
     CFDictionaryRef		MDmapping;
     CFDictionaryRef		UDmapping;
@@ -121,6 +123,9 @@
 #if defined(_HAVE__FLAC_SUPPORT)
         StreamInfo__flac si_flac;
 #endif
+#if defined(_HAVE__THEORA_SUPPORT)
+        StreamInfo__theora si_theora;
+#endif
     };
 
 } StreamInfo, *StreamInfoPtr;
@@ -205,6 +210,8 @@
 typedef int (*initialize_stream) (StreamInfo *si);
 typedef void (*clear_stream) (StreamInfo *si);
 typedef ComponentResult (*create_sample_description) (StreamInfo *si);
+typedef ComponentResult (*create_track) (OggImportGlobals *globals, StreamInfo *si);
+typedef ComponentResult (*create_track_media) (OggImportGlobals *globals, StreamInfo *si, Handle data_ref);
 
 typedef int (*process_first_packet) (StreamInfo *si, ogg_page *op, ogg_packet *opckt);
 typedef ComponentResult (*process_stream_page) (OggImportGlobals *globals, StreamInfo *si, ogg_page *opg);
@@ -218,11 +225,13 @@
 
     process_first_packet                first_packet;
     create_sample_description           sample_description;
+    create_track                        track;
+    create_track_media                  track_media;
 
     initialize_stream                   initialize;
     clear_stream                        clear;
 } stream_format_handle_funcs;
 
-#define HANDLE_FUNCTIONS__NULL { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+#define HANDLE_FUNCTIONS__NULL { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 
 #endif /* __importer_types_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_flac.c
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_flac.c	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_flac.c	2006-04-24 22:12:39 UTC (rev 11271)
@@ -41,6 +41,40 @@
 #include "data_types.h"
 
 
+static int unpack_vorbis_coments(vorbis_comment *vc, const void *data, UInt32 data_size)
+{
+    int i;
+    char *dptr = (char *) data;
+    char *dend = dptr + data_size;
+    int len = EndianU32_LtoN(*(UInt32 *)dptr);
+    int commnum = 0;
+    char save;
+
+    dptr += 4 + len;
+    if (len >= 0 && dptr < dend) {
+        commnum = EndianU32_LtoN(*(UInt32 *)dptr);
+        if (commnum >= 0) {
+            dptr += 4;
+
+            for (i = 0; i < commnum && dptr <= dend; i++) {
+                len = EndianU32_LtoN(*(UInt32 *)dptr);
+                dptr += 4;
+                if (dptr + len > dend)
+                    break;
+
+                save = *(dptr + len);
+                *(dptr + len) = '\0';
+                vorbis_comment_add(vc, dptr);
+                dptr += len;
+                *dptr = save;
+            }
+        }
+    }
+
+    //vorbis_comment_clear(vc);
+    return 0;
+}
+
 int recognize_header__flac(ogg_page *op)
 {
     char fh[] = {0x7f, 'F', 'L', 'A', 'C', '\0'};
@@ -51,9 +85,16 @@
     return 1;
 };
 
-int verify_header__flac(ogg_page *op) //?
+int verify_header__flac(ogg_page *op)
 {
-    // TODO: check mapping version, etc.?
+    char nfh[] = "fLaC";
+    dbg_printf("! -- - flac_verify_header: mapping ver: %d.%d\n", (int)((char *)op->body)[5], (int)((char *)op->body)[6]);
+    if ((int)((char *)op->body)[5] != FLAC_MAPPING_SUPPORTED_MAJOR)
+        return -1;
+    if (strncmp(nfh, ((char *)op->body) + 9, 4))
+        return -1;
+
+    // anything else to check?
     return 0;
 };
 
@@ -91,7 +132,8 @@
     asbd.mBytesPerFrame = 0;
     asbd.mChannelsPerFrame = si->numChannels;
     //asbd.mBitsPerChannel = 16;
-    asbd.mBitsPerChannel = 0;
+    //asbd.mBitsPerChannel = 0;
+    asbd.mBitsPerChannel = si->si_flac.bps;
     asbd.mReserved = 0;
 
     if (si->numChannels == 1)
@@ -118,10 +160,8 @@
 {
     unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo),
                                       EndianS32_NtoB(ogg_page_serialno(op)) };
-    //unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeSpeexHeader) };
+    unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeFLACStreaminfo) };
 
-    //vorbis_synthesis_headerin(&si->si_vorbis.vi, &si->si_vorbis.vc, opckt); //check errors?
-
     si->si_flac.metablocks =  (SInt32) EndianU16_BtoN(* (UInt16 *) (((char *)opckt->packet) + 7));
     UInt32 sib = EndianU32_BtoN(* (UInt32 *) (((char *)opckt->packet) + 27));
 
@@ -131,11 +171,11 @@
     si->numChannels = (sib & 0x07) + 1;
     si->rate = (sib >> 3) & 0xfffff;
 
-    dbg_printf("! -- - flac_first_packet: ch: %d, rate: %ld\n", si->numChannels, si->rate);
+    dbg_printf("! -- - flac_first_packet: ch: %d, rate: %ld, bps: %ld\n", si->numChannels, si->rate, si->si_flac.bps);
 
     PtrAndHand(serialnoatom, si->soundDescExtension, sizeof(serialnoatom)); //check errors?
-    //PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors?
-    //PtrAndHand(opckt->packet, si->soundDescExtension, opckt->bytes); //check errors?
+    PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors?
+    PtrAndHand((((char *)opckt->packet) + 13), si->soundDescExtension, opckt->bytes - 13); //check errors?
 
     si->si_flac.state = kFStateReadingComments;
 
@@ -170,20 +210,34 @@
             } else if (ovret < 1) {
                 loop = false;
             } else {
-                //unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeSpeexComments) };
-
-                //PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
-                //PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
-                //vorbis_synthesis_headerin(&si->si_vorbis.vi, &si->si_vorbis.vc, &op);
-
                 ret = CreateTrackAndMedia(globals, si, opg);
                 if (ret != noErr) {
                     dbg_printf("??? -- CreateTrackAndMedia failed?: %ld\n", (long)ret);
+                    loop = false;
+                    break;
                 }
 
-                // /*err =*/ DecodeCommentsQT(globals, si, &si->si_vorbis.vc);
-                //NotifyMovieChanged(globals);
+                if (si->si_flac.metablocks == 0 && (*((unsigned char*) op.packet) == 0xff)) {
+                    si->si_flac.metablocks = si->si_flac.skipped;
+                    si->si_flac.state = kFStateReadingAdditionalMDBlocks;
+                    break;
+                }
 
+                {
+                    unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeFLACMetadata) };
+
+                    PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
+                    PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
+                }
+
+                if (((* (char *) op.packet) & 0x7f) == 4) {
+                    dbg_printf("!  > - flac_stream_page - mb: %ld, skipped: %ld, h: %02x\n", si->si_flac.metablocks, si->si_flac.skipped,
+                               (*(char *) op.packet) & 0x7f);
+                    unpack_vorbis_coments(&si->si_flac.vc, ((char *) op.packet) + 4, op.bytes - 4);
+                    /*err =*/ DecodeCommentsQT(globals, si, &si->si_flac.vc);
+                    //NotifyMovieChanged(globals);
+                }
+
                 si->si_flac.skipped += 1;
                 si->si_flac.state = kFStateReadingAdditionalMDBlocks;
             }
@@ -192,7 +246,7 @@
 
         case kFStateReadingAdditionalMDBlocks:
             dbg_printf("! -- - flac_stream_page - mb: %ld, skipped: %ld\n", si->si_flac.metablocks, si->si_flac.skipped);
-            if (si->si_flac.skipped >= si->si_flac.metablocks) {
+            if (si->si_flac.metablocks > 0 && si->si_flac.skipped >= si->si_flac.metablocks) {
                 unsigned long endAtom[2] = { EndianU32_NtoB(sizeof(endAtom)), EndianU32_NtoB(kAudioTerminatorAtomType) };
 
                 ret = PtrAndHand(endAtom, si->soundDescExtension, sizeof(endAtom));
@@ -209,7 +263,7 @@
                 si->incompleteCompensation = 0;
                 si->si_flac.state = kFStateReadingFirstPacket;
 
-                loop = false; // ??!
+                loop = false; // the audio data is supposed to start on a fresh page
                 break;
             }
 
@@ -222,16 +276,31 @@
                 loop = false;
             } else {
                 // not much here so far, basically just skip the extra header packet
-                //unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeSpeexExtraHeader) };
-                //PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
-                //PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
+                unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeFLACMetadata) };
 
+                if (si->si_flac.metablocks == 0 && (* (unsigned char*) op.packet) == 0xff) {
+                    si->si_flac.metablocks = si->si_flac.skipped;
+                    break;
+                }
+
+                PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
+                PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
+
+                if (((* (unsigned char *) op.packet) & 0x7f) == 4) {
+                    dbg_printf("!  > - flac_stream_page - mb: %ld, skipped: %ld, h: %02x\n", si->si_flac.metablocks, si->si_flac.skipped,
+                               (*(char *) op.packet) & 0x7f);
+                    unpack_vorbis_coments(&si->si_flac.vc, ((char *) op.packet) + 4, op.bytes - 4);
+                    /*err =*/ DecodeCommentsQT(globals, si, &si->si_flac.vc);
+                    //NotifyMovieChanged(globals);
+                }
+
                 si->si_flac.skipped += 1;
             }
 
             break;
 
         case kFStateReadingFirstPacket:
+            // what to do with this one? is it needed at all??
             if (ogg_page_pageno(opg) > 2 && false) {
                 si->lastGranulePos = ogg_page_granulepos(opg);
                 dbg_printf("----==< skipping: %llx, %lx\n", si->lastGranulePos, ogg_page_pageno(opg));

Modified: trunk/xiph-qt/OggImport/src/stream_flac.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_flac.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_flac.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -35,6 +35,9 @@
 
 #include "importer_types.h"
 
+#define FLAC_MAPPING_SUPPORTED_MAJOR 1
+
+
 extern int recognize_header__flac(ogg_page *op);
 extern int verify_header__flac(ogg_page *op);
 
@@ -47,7 +50,7 @@
 
 #define HANDLE_FUNCTIONS__FLAC { &process_stream_page__flac, &recognize_header__flac, \
             &verify_header__flac, &process_first_packet__flac, &create_sample_description__flac, \
-            &initialize_stream__flac, &clear_stream__flac }
+            NULL, NULL, &initialize_stream__flac, &clear_stream__flac }
 
 
 #endif /* __stream_flac_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_speex.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_speex.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_speex.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -48,7 +48,7 @@
 
 #define HANDLE_FUNCTIONS__SPEEX { &process_stream_page__speex, &recognize_header__speex, \
             &verify_header__speex, &process_first_packet__speex, &create_sample_description__speex, \
-            &initialize_stream__speex, &clear_stream__speex }
+            NULL, NULL, &initialize_stream__speex, &clear_stream__speex }
 
 
 #endif /* __stream_vorbis_h__ */

Copied: trunk/xiph-qt/OggImport/src/stream_theora.c (from rev 10963, trunk/xiph-qt/OggImport/src/stream_vorbis.c)
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_vorbis.c	2006-03-04 00:07:06 UTC (rev 10963)
+++ trunk/xiph-qt/OggImport/src/stream_theora.c	2006-04-24 22:12:39 UTC (rev 11271)
@@ -0,0 +1,533 @@
+/*
+ *  stream_theora.c
+ *
+ *    Theora format related part of OggImporter.
+ *
+ *
+ *  Copyright (c) 2006  Arek Korbik
+ *
+ *  This file is part of XiphQT, the Xiph QuickTime Components.
+ *
+ *  XiphQT is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  XiphQT 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with XiphQT; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ *  Last modified: $Id$
+ *
+ */
+
+
+#include "stream_theora.h"
+
+#include "debug.h"
+#define logg_page_last_packet_incomplete(op) (((unsigned char *)(op)->header)[26 + ((unsigned char *)(op)->header)[26]] == 255)
+
+#include "OggImport.h"
+
+#include "fccs.h"
+#include "data_types.h"
+
+
+/*
+ * Euclid's GCD algorithm
+ * de-recursified, with input check suitable for Theora fps a/b
+ */
+UInt32 gcd(UInt32 a, UInt32 b)
+{
+    UInt32 tmp;
+
+    if (b == 0)
+        return 0;
+
+    while (b > 0) {
+        // python: a, b = b, a % b
+        tmp = a;
+        a = b;
+        b = tmp % b;
+    }
+
+    return a;
+}
+
+
+int recognize_header__theora(ogg_page *op)
+{
+    dbg_printf("! -- - theora_recognise_header: '%4.4s'\n", ((char *)op->body) + 1);
+    if (!strncmp("\x80theora", (char *)op->body, 7))
+        return 0;
+
+    return 1;
+};
+
+int verify_header__theora(ogg_page *op) //?
+{
+    OSErr err = noErr;
+
+    ogg_stream_state os;
+    ogg_packet       opk;
+
+    theora_info      ti;
+    theora_comment   tc;
+
+    ogg_stream_init(&os, ogg_page_serialno(op));
+
+    theora_info_init(&ti);
+    theora_comment_init(&tc);
+
+    if (ogg_stream_pagein(&os, op) < 0)
+        err = invalidMedia;
+    else if (ogg_stream_packetout(&os, &opk) != 1)
+        err = invalidMedia;
+    else if (theora_decode_header(&ti, &tc, &opk) < 0)
+        err = noSoundTrackInMovieErr;
+
+    ogg_stream_clear(&os);
+
+    theora_comment_clear(&tc);
+    theora_info_clear(&ti);
+
+    return err;
+};
+
+int initialize_stream__theora(StreamInfo *si)
+{
+    theora_info_init(&si->si_theora.ti);
+    theora_comment_init(&si->si_theora.tc);
+
+    si->si_theora.state = kTStateInitial;
+
+    return 0;
+};
+
+void clear_stream__theora(StreamInfo *si)
+{
+    theora_info_clear(&si->si_theora.ti);
+    theora_comment_clear(&si->si_theora.tc);
+};
+
+ComponentResult create_sample_description__theora(StreamInfo *si)
+{
+    ComponentResult err = noErr;
+    Handle desc = NewHandleClear(sizeof(ImageDescription));
+    ImageDescriptionPtr imgdsc = (ImageDescriptionPtr) *desc;
+
+    imgdsc->idSize = sizeof(ImageDescription);
+    imgdsc->cType = 'XiTh';
+    imgdsc->version = 1; //major ver num
+    imgdsc->revisionLevel = 1; //minor ver num
+    imgdsc->vendor = 'XiQT';
+    imgdsc->temporalQuality = codecMaxQuality;
+    imgdsc->spatialQuality = codecMaxQuality;
+    imgdsc->width = si->si_theora.ti.frame_width;
+    imgdsc->height = si->si_theora.ti.frame_height;
+    imgdsc->hRes = 72<<16;
+    imgdsc->vRes = 72<<16;
+    imgdsc->depth = 24;
+    imgdsc->clutID = -1;
+
+    si->sampleDesc = (SampleDescriptionHandle) desc;
+
+    return err;
+};
+
+ComponentResult create_track__theora(OggImportGlobals *globals, StreamInfo *si)
+{
+    ComponentResult ret = noErr;
+    dbg_printf("! -T calling => NewMovieTrack()\n");
+    UInt32 frame_width = si->si_theora.ti.frame_width;
+    UInt32 frame_width_fraction = 0;
+
+    if (si->si_theora.ti.aspect_numerator != si->si_theora.ti.aspect_denominator) {
+        frame_width_fraction = (frame_width * si->si_theora.ti.aspect_numerator % si->si_theora.ti.aspect_denominator) * 0x10000 / si->si_theora.ti.aspect_denominator;
+        frame_width = frame_width * si->si_theora.ti.aspect_numerator / si->si_theora.ti.aspect_denominator;
+    }
+    si->theTrack = NewMovieTrack(globals->theMovie,
+                                 frame_width << 16 | (frame_width_fraction & 0xffff),
+                                 si->si_theora.ti.frame_height << 16, 0);
+
+    return ret;
+};
+
+ComponentResult create_track_media__theora(OggImportGlobals *globals, StreamInfo *si, Handle data_ref)
+{
+    ComponentResult ret = noErr;
+    dbg_printf("! -T calling => NewTrackMedia(%lx)\n", si->rate);
+    si->theMedia = NewTrackMedia(si->theTrack, VideoMediaType, si->rate, data_ref, globals->dataRefType);
+
+    return ret;
+};
+
+#define MAX_FPS_DENOMINATOR 20
+#define DESIRED_MULTIPLIER 19
+
+int process_first_packet__theora(StreamInfo *si, ogg_page *op, ogg_packet *opckt)
+{
+    unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo),
+                                      EndianS32_NtoB(ogg_page_serialno(op)) };
+    unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeTheoraHeader) };
+    unsigned long fps_gcd = 1, multiplier = 1;
+    UInt32 fps_N, fps_D;
+
+    theora_decode_header(&si->si_theora.ti, &si->si_theora.tc, opckt); //check errors?
+
+    si->numChannels = 0;
+
+    fps_N = si->si_theora.ti.fps_numerator;
+    fps_D = si->si_theora.ti.fps_denominator;
+
+    fps_gcd = gcd(fps_N, fps_D);
+    if (fps_gcd < 1)
+        return -1; // return some reasonable error code?
+
+    if (fps_D / fps_gcd > MAX_FPS_DENOMINATOR) {
+        UInt64 remainder;
+        fps_N = U32SetU(U64Divide(U64Multiply(U64Set(fps_N), U64Set(MAX_FPS_DENOMINATOR)), U64Set(fps_D), &remainder));
+        if (U64Compare(remainder, U64Set(MAX_FPS_DENOMINATOR / 2)) > 0)
+            fps_N += 1;
+        fps_D = MAX_FPS_DENOMINATOR;
+        fps_gcd = gcd(fps_N, fps_D);
+    }
+
+    multiplier = DESIRED_MULTIPLIER / (fps_D / fps_gcd) + 1;
+    si->si_theora.fps_framelen = (fps_D / fps_gcd) * multiplier;
+    si->rate = (fps_N / fps_gcd) * multiplier;
+
+    dbg_printf("! -T   setting FPS values: [gcd: %8ld, mult: %8ld] fl: %8ld, rate: %8ld (N: %8ld, D: %8ld) (nN: %8ld, nD: %8ld)\n",
+               fps_gcd, multiplier, si->si_theora.fps_framelen, si->rate, si->si_theora.ti.fps_numerator, si->si_theora.ti.fps_denominator,
+               fps_N, fps_D);
+    si->si_theora.granulepos_shift = theora_granule_shift(&si->si_theora.ti);
+
+    PtrAndHand(serialnoatom, si->soundDescExtension, sizeof(serialnoatom)); //check errors?
+    PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors?
+    PtrAndHand(opckt->packet, si->soundDescExtension, opckt->bytes); //check errors?
+
+    si->si_theora.state = kTStateReadingComments;
+
+    return 0;
+};
+
+ComponentResult process_stream_page__theora(OggImportGlobals *globals, StreamInfo *si, ogg_page *opg)
+{
+    ComponentResult ret = noErr;
+    int ovret = 0;
+    Boolean loop = true;
+    Boolean movie_changed = false;
+
+    ogg_packet op;
+
+    switch(si->si_theora.state) {
+    case kTStateReadingComments:
+    case kTStateReadingCodebooks:
+    case kTStateReadingPackets:
+        ogg_stream_pagein(&si->os, opg);
+        break;
+    default:
+        break;
+    }
+
+    do {
+        switch(si->si_theora.state) {
+        case kTStateReadingComments:
+            ovret = ogg_stream_packetout(&si->os, &op);
+            if (ovret < 0) {
+                loop = false;
+                ret = invalidMedia;
+            } else if (ovret < 1) {
+                loop = false;
+            } else {
+                unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeTheoraComments) };
+
+                PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
+                PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
+                theora_decode_header(&si->si_theora.ti, &si->si_theora.tc, &op);
+
+                ret = CreateTrackAndMedia(globals, si, opg);
+                if (ret != noErr) {
+                    dbg_printf("??? -- CreateTrackAndMedia failed?: %ld\n", (long)ret);
+                }
+
+                /*err =*/ DecodeCommentsQT(globals, si, &si->si_theora.tc);
+                //NotifyMovieChanged(globals);
+
+                si->si_theora.state = kTStateReadingCodebooks;
+            }
+            break;
+
+        case kTStateReadingCodebooks:
+            ovret = ogg_stream_packetout(&si->os, &op);
+            if (ovret < 0) {
+                loop = false;
+                ret = invalidMedia;
+            } else if (ovret < 1) {
+                loop = false;
+            } else {
+                unsigned long atomhead[2] = { EndianU32_NtoB(op.bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeTheoraCodebooks) };
+                PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead));
+                PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
+
+                theora_decode_header(&si->si_theora.ti, &si->si_theora.tc, &op);
+                {
+                    unsigned long endAtom[2] = { EndianU32_NtoB(sizeof(endAtom)), EndianU32_NtoB(kAudioTerminatorAtomType) };
+
+                    ret = PtrAndHand(endAtom, si->soundDescExtension, sizeof(endAtom));
+                    if (ret == noErr) {
+                        ret = AddImageDescriptionExtension((ImageDescriptionHandle) si->sampleDesc,
+                                                           si->soundDescExtension, 'XYZ?' /* siDecompressionParams */);
+                        //dbg_printf("??? -- Adding extension: %ld\n", ret);
+                    } else {
+                        //dbg_printf("??? -- Hmm, something went wrong: %ld\n", ret);
+                    }
+                }
+
+                si->si_theora.state = kTStateReadingFirstPacket;
+                si->insertTime = 0;
+                si->streamOffset = globals->currentGroupOffset;
+                si->incompleteCompensation = 0;
+                loop = false; //there should be an end of page here according to specs...
+            }
+            break;
+
+        case kTStateReadingFirstPacket:
+            if (ogg_page_pageno(opg) > 3) {
+                si->lastGranulePos = ogg_page_granulepos(opg);
+                dbg_printf("----==< skipping: %llx, %lx\n", si->lastGranulePos, ogg_page_pageno(opg));
+                loop = false;
+
+                if (si->lastGranulePos < 0)
+                    si->lastGranulePos = 0;
+            }
+            si->si_theora.state = kTStateReadingPackets;
+#if 0
+            {
+                Handle h = NewHandleClear(sizeof(si->si_theora));
+                ret = BeginMediaEdits(si->theMedia);
+                dbg_printf("! -T-XXX:: ret = %ld\n", ret);
+                ret = AddMediaSample(si->theMedia, h, 0, sizeof(si->si_theora), 249, si->sampleDesc, 1, 0, NULL);
+                dbg_printf("! -T-XXX:: ret = %ld\n", ret);
+                ret = EndMediaEdits(si->theMedia);
+                dbg_printf("! -T-XXX:: ret = %ld\n", ret);
+                ret = InsertMediaIntoTrack(si->theTrack, si->insertTime /*inserted*/, /* si->lastGranulePos */ 0,
+                                           249, fixed1);
+                dbg_printf("! -T-XXX:: ret = %ld\n", ret);
+                si->insertTime = -1;
+            }
+#endif /* 0 */
+            break;
+
+        case kTStateReadingPackets:
+            {
+                ogg_int64_t pos       = ogg_page_granulepos(opg);
+                int         len       = opg->header_len + opg->body_len;
+                TimeValue   duration  = 0;
+                TimeValue   inserted  = -1;
+                short       smp_flags = 0;
+
+                int packet_count = 0;
+                long psize = 0, poffset = 0;
+                int i, segments;
+                Boolean continued = ogg_page_continued(opg);
+                SampleReference64Record sampleRec;
+                ogg_int64_t last_packet_pos = si->lastGranulePos >> si->si_theora.granulepos_shift;
+                last_packet_pos += si->lastGranulePos - (last_packet_pos << si->si_theora.granulepos_shift);
+
+#if 0
+                if (ogg_page_continued(opg) || si->incompleteCompensation != 0)
+                    smp_flags |= mediaSampleNotSync;
+
+                if (duration <= 0) {
+                    duration = INCOMPLETE_PAGE_DURATION;
+                    si->incompleteCompensation -= INCOMPLETE_PAGE_DURATION;
+                } else if (si->incompleteCompensation != 0) {
+                    duration += si->incompleteCompensation;
+                    si->incompleteCompensation = 0;
+                    if (duration <= 0) {
+                        ret = badFileFormat;
+                        loop = false;
+                        break;
+                    }
+                }
+#endif /* 0 */
+
+                if (continued)
+                    smp_flags |= mediaSampleNotSync;
+
+                segments = opg->header[26];
+                for (i = 0; i < segments; i++) {
+                    int val = opg->header[27 + i];
+                    int incomplete = (i == segments - 1) && (val == 255);
+                    TimeValue pduration = 0;
+                    psize += val;
+                    if (val < 255 || incomplete) {
+                        pduration = si->si_theora.fps_framelen;
+                        if (incomplete) {
+                            pduration = 1;
+                            si->incompleteCompensation -= 1;
+                            psize += 4; // this should allow decoder to see that if (packet_len % 255 == 4) and
+                                        // last 4 bytes contain 'OggS' sync pattern then that's an incomplete packet
+                        } else if (continued) {
+                            pduration += si->incompleteCompensation;
+                            si->incompleteCompensation = 0;
+                            /* QT doesn't like zero-size samples, do this: */
+                            if (val == 0) {
+                                psize = 1;
+                                poffset -= 1;
+                            }
+                            /* */
+                        }
+                        if ((opg->body[poffset] & 0x40) != 0)
+                            smp_flags |= mediaSampleNotSync;
+                        memset(&sampleRec, 0, sizeof(sampleRec));
+                        sampleRec.dataOffset = SInt64ToWide(globals->dataOffset + S64Set(poffset + opg->header_len));
+                        sampleRec.dataSize = psize;
+                        sampleRec.sampleFlags = smp_flags;
+                        sampleRec.durationPerSample = pduration;
+                        sampleRec.numberOfSamples = 1;
+                        dbg_printf("   T   :++: adding sampleRef: %8lld, len: %8d, dur: %8d, fl: %08x\n",
+                                   sampleRec.dataOffset, psize, pduration, smp_flags);
+                        ret = AddMediaSampleReferences64(si->theMedia, si->sampleDesc, 1, &sampleRec, inserted == -1 ? &inserted : NULL);
+                        if (ret != noErr)
+                            break;
+                        duration += pduration;
+                        packet_count += 1;
+                        poffset += psize;
+
+                        psize = 0;
+                        continued = false;
+                        smp_flags = 0;
+                    }
+                }
+
+#if 0
+                while ((ovret = ogg_stream_packetout(&si->os, &op)) > 0) {
+                    packet_count += 1;
+                    last_packet_pos += 1;
+                    memset(&sampleRec, 0, sizeof(sampleRec));
+                    sampleRec.dataOffset = SInt64ToWide(globals->dataOffset + S64Set(opg->header_len + op->packet - opg->body)); // + packet offset within the page! - :/
+                    sampleRec.dataSize = op.bytes;
+                    sampleRec.sampleFlags = smp_flags;
+                    sampleRec.durationPerSample = si->si_theora.ti.fps_denominator;
+                    sampleRec.numberOfSamples = 1;
+                    dbg_printf("   -   :++: adding sampleRef: %lld, len: %d, dur: %d\n", globals->dataOffset, len, duration);
+                    ret = AddMediaSampleReferences64(si->theMedia, si->sampleDesc, 1, &sampleRec, inserted == -1 ? &inserted : NULL);
+                    if (ret != noErr)
+                        break;
+                }
+#endif /* 0 */
+                loop = false;
+                if (ovret < 0) {
+                    ret = invalidMedia;
+                    break;
+                }
+
+                
+                if (ret == noErr && packet_count > 0) {
+                    TimeValue timeLoaded;
+
+                    dbg_printf("   -   :><: added page %04ld at %14ld (size: %5ld, tsize: %6d), f: %d\n",
+                               ogg_page_pageno(opg), inserted,
+                               opg->body_len, len, !logg_page_last_packet_incomplete(opg));
+                    //dbg_printf("   -   :/>: inserting media: %ld, mt: %lld, dur: %d\n", si->insertTime, si->lastGranulePos, duration);
+                    dbg_printf("   -   :/>: inserting media: %ld, mt: %ld, dur: %ld\n", si->insertTime, inserted, duration);
+                    ret = InsertMediaIntoTrack(si->theTrack, si->insertTime /*inserted*/, /* si->lastGranulePos */ inserted,
+                                               duration, fixed1);
+                    if (si->insertTime == 0) {
+                        if (si->streamOffset != 0) {
+                            SetTrackOffset(si->theTrack, si->streamOffset);
+                            dbg_printf("   # -- SetTrackOffset(%ld) = %ld --> %ld\n",
+                                       si->streamOffset, GetMoviesError(),
+                                       GetTrackOffset(si->theTrack));
+                            if (globals->dataIsStream) {
+                                SetTrackEnabled(si->theTrack, false);
+                                SetTrackEnabled(si->theTrack, true);
+                            }
+                        }
+                        if (GetMovieTimeScale(globals->theMovie) < GetMediaTimeScale(si->theMedia)) {
+                            dbg_printf("   # - changing movie time scale: %ld --> %ld\n",
+                                       GetMovieTimeScale(globals->theMovie), GetMediaTimeScale(si->theMedia));
+                            SetMovieTimeScale(globals->theMovie, GetMediaTimeScale(si->theMedia));
+                        }
+                    }
+                    si->insertTime = -1;
+                    timeLoaded = GetTrackDuration(si->theTrack);
+
+                    dbg_printf("   -   :><: added page %04ld at %14ld; offset: %ld, duration: %ld (%ld, %ld), mediats: %ld; moviets: %ld, ret = %ld\n",
+                               ogg_page_pageno(opg), inserted,
+                               GetTrackOffset(si->theTrack), GetTrackDuration(si->theTrack), timeLoaded,
+                               (duration * GetMovieTimeScale(globals->theMovie)) / GetMediaTimeScale(si->theMedia),
+                               GetMediaTimeScale(si->theMedia), GetMovieTimeScale(globals->theMovie), ret);
+                    if (globals->timeLoaded < timeLoaded)
+                        globals->timeLoaded = timeLoaded;
+
+                    movie_changed = true;
+                }
+                
+#if 0
+                dbg_printf("   -   :++: adding sampleRef: %lld, len: %d, dur: %d\n", globals->dataOffset, len, duration);
+                ret = AddMediaSampleReference(si->theMedia, S32Set(globals->dataOffset),
+                                              len, duration, si->sampleDesc, 1, smp_flags, &inserted); //@@@@ 64-bit enable
+                if (ret == noErr) {
+                    TimeValue timeLoaded;
+
+                    dbg_printf("   -   :><: added page %04ld at %14ld (size: %5ld, tsize: %6d), f: %d\n",
+                               ogg_page_pageno(opg), inserted,
+                               opg->header_len + opg->body_len, len, !logg_page_last_packet_incomplete(opg));
+                    dbg_printf("   -   :/>: inserting media: %ld, mt: %lld, dur: %d\n", si->insertTime, si->lastGranulePos, duration);
+                    ret = InsertMediaIntoTrack(si->theTrack, si->insertTime /*inserted*/, /* si->lastGranulePos */ inserted,
+                                               duration, fixed1);
+                    if (si->insertTime == 0) {
+                        if (si->streamOffset != 0) {
+                            SetTrackOffset(si->theTrack, si->streamOffset);
+                            dbg_printf("   # -- SetTrackOffset(%ld) = %ld --> %ld\n",
+                                       si->streamOffset, GetMoviesError(),
+                                       GetTrackOffset(si->theTrack));
+                            if (globals->dataIsStream) {
+                                SetTrackEnabled(si->theTrack, false);
+                                SetTrackEnabled(si->theTrack, true);
+                            }
+                        }
+                        if (GetMovieTimeScale(globals->theMovie) < GetMediaTimeScale(si->theMedia)) {
+                            dbg_printf("   # - changing movie time scale: %ld --> %ld\n",
+                                       GetMovieTimeScale(globals->theMovie), GetMediaTimeScale(si->theMedia));
+                            SetMovieTimeScale(globals->theMovie, GetMediaTimeScale(si->theMedia));
+                        }
+                    }
+                    si->insertTime = -1;
+                    timeLoaded = GetTrackDuration(si->theTrack);
+
+                    dbg_printf("   -   :><: added page %04ld at %14ld; offset: %ld, duration: %ld (%ld, %ld), mediats: %ld; moviets: %ld, ret = %ld\n",
+                               ogg_page_pageno(opg), inserted,
+                               GetTrackOffset(si->theTrack), GetTrackDuration(si->theTrack), timeLoaded,
+                               (duration * GetMovieTimeScale(globals->theMovie)) / GetMediaTimeScale(si->theMedia),
+                               GetMediaTimeScale(si->theMedia), GetMovieTimeScale(globals->theMovie), ret);
+                    if (globals->timeLoaded < timeLoaded)
+                        globals->timeLoaded = timeLoaded;
+
+                    movie_changed = true;
+                }
+#endif /* 0 */
+                si->lastGranulePos = pos;
+            }
+            loop = false;
+            break;
+
+        default:
+            loop = false;
+        }
+    } while(loop);
+
+    if (movie_changed)
+        NotifyMovieChanged(globals);
+
+    return ret;
+};

Copied: trunk/xiph-qt/OggImport/src/stream_theora.h (from rev 10963, trunk/xiph-qt/OggImport/src/stream_vorbis.h)
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_vorbis.h	2006-03-04 00:07:06 UTC (rev 10963)
+++ trunk/xiph-qt/OggImport/src/stream_theora.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -0,0 +1,57 @@
+/*
+ *  stream_theora.h
+ *
+ *    Declaration of Theora format related functions of OggImporter.
+ *
+ *
+ *  Copyright (c) 2006  Arek Korbik
+ *
+ *  This file is part of XiphQT, the Xiph QuickTime Components.
+ *
+ *  XiphQT is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  XiphQT 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with XiphQT; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ *  Last modified: $Id$
+ *
+ */
+
+
+#if !defined(__stream_theora_h__)
+#define __stream_theora_h__
+
+#include <Ogg/ogg.h>
+#include <Theora/theora.h>
+
+#include "importer_types.h"
+
+extern int recognize_header__theora(ogg_page *op);
+extern int verify_header__theora(ogg_page *op); //?
+
+extern int initialize_stream__theora(StreamInfo *si);
+extern void clear_stream__theora(StreamInfo *si);
+
+extern ComponentResult create_sample_description__theora(StreamInfo *si);
+extern ComponentResult create_track__theora(OggImportGlobals *globals, StreamInfo *si);
+extern ComponentResult create_track_media__theora(OggImportGlobals *globals, StreamInfo *si, Handle data_ref);
+
+extern int process_first_packet__theora(StreamInfo *si, ogg_page *op, ogg_packet *opckt);
+extern ComponentResult process_stream_page__theora(OggImportGlobals *globals, StreamInfo *si, ogg_page *opg);
+
+#define HANDLE_FUNCTIONS__THEORA { &process_stream_page__theora, &recognize_header__theora, \
+            &verify_header__theora, &process_first_packet__theora, &create_sample_description__theora, \
+            &create_track__theora, &create_track_media__theora, &initialize_stream__theora, &clear_stream__theora }
+
+
+#endif /* __stream_theora_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_types_flac.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_types_flac.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_types_flac.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -32,8 +32,8 @@
 #define __stream_types_flac_h__
 
 
-#include <Speex/speex.h>
-#include <Speex/speex_header.h>
+#if !defined(_NO_FLAC_SUPPORT)
+#include <Vorbis/codec.h>
 
 typedef enum FLACImportStates {
     kFStateInitial,
@@ -55,5 +55,6 @@
 
 
 #define _HAVE__FLAC_SUPPORT 1
+#endif
 
 #endif /* __stream_types_flac_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_types_speex.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_types_speex.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_types_speex.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -4,7 +4,7 @@
  *    Definition of Speex specific data structures.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -32,6 +32,8 @@
 #define __stream_types_speex_h__
 
 
+#if !defined(_NO_SPEEX_SUPPORT)
+#include <Vorbis/codec.h>
 #include <Speex/speex.h>
 #include <Speex/speex_header.h>
 
@@ -53,5 +55,6 @@
 
 
 #define _HAVE__SPEEX_SUPPORT 1
+#endif
 
 #endif /* __stream_types_speex_h__ */

Copied: trunk/xiph-qt/OggImport/src/stream_types_theora.h (from rev 10963, trunk/xiph-qt/OggImport/src/stream_types_vorbis.h)
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_types_vorbis.h	2006-03-04 00:07:06 UTC (rev 10963)
+++ trunk/xiph-qt/OggImport/src/stream_types_theora.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -0,0 +1,61 @@
+/*
+ *  stream_types_theora.h
+ *
+ *    Definition of Theora specific data structures.
+ *
+ *
+ *  Copyright (c) 2006  Arek Korbik
+ *
+ *  This file is part of XiphQT, the Xiph QuickTime Components.
+ *
+ *  XiphQT is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  XiphQT 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with XiphQT; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ *  Last modified: $Id$
+ *
+ */
+
+
+#if !defined(__stream_types_theora_h__)
+#define __stream_types_theora_h__
+
+
+#if !defined(_NO_THEORA_SUPPORT)
+#include <Theora/theora.h>
+
+typedef enum TheoraImportStates {
+    kTStateInitial,
+    kTStateReadingComments,
+    kTStateReadingCodebooks,
+    kTStateReadingFirstPacket,
+    //kTStateSeekingLastPacket,
+    kTStateReadingPackets
+} TheoraImportStates;
+
+typedef struct {
+    TheoraImportStates state;
+
+    theora_info ti;
+    theora_comment tc;
+
+    UInt32 granulepos_shift;
+    UInt32 fps_framelen;
+} StreamInfo__theora;
+
+
+#define _HAVE__THEORA_SUPPORT 1
+#endif
+
+#endif /* __stream_types_theora_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_types_vorbis.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_types_vorbis.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_types_vorbis.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -4,7 +4,7 @@
  *    Definition of Vorbis specific data structures.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -32,6 +32,7 @@
 #define __stream_types_vorbis_h__
 
 
+#if !defined(_NO_VORBIS_SUPPORT)
 #include <Vorbis/codec.h>
 
 typedef enum VorbisImportStates {
@@ -52,5 +53,6 @@
 
 
 #define _HAVE__VORBIS_SUPPORT 1
+#endif
 
 #endif /* __stream_types_vorbis_h__ */

Modified: trunk/xiph-qt/OggImport/src/stream_vorbis.c
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_vorbis.c	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_vorbis.c	2006-04-24 22:12:39 UTC (rev 11271)
@@ -4,7 +4,7 @@
  *    Vorbis format related part of OggImporter.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -213,19 +213,7 @@
                 PtrAndHand(op.packet, si->soundDescExtension, op.bytes);
 
                 vorbis_synthesis_headerin(&si->si_vorbis.vi, &si->si_vorbis.vc, &op);
-                {
-                    unsigned long endAtom[2] = { EndianU32_NtoB(sizeof(endAtom)), EndianU32_NtoB(kAudioTerminatorAtomType) };
 
-                    ret = PtrAndHand(endAtom, si->soundDescExtension, sizeof(endAtom));
-                    if (ret == noErr) {
-                        ret = AddSoundDescriptionExtension((SoundDescriptionHandle) si->sampleDesc,
-                                                           si->soundDescExtension, siDecompressionParams);
-                        //dbg_printf("??? -- Adding extension: %ld\n", ret);
-                    } else {
-                        //dbg_printf("??? -- Hmm, something went wrong: %ld\n", ret);
-                    }
-                }
-
                 si->si_vorbis.state = kVStateReadingFirstPacket;
                 si->insertTime = 0;
                 si->streamOffset = globals->currentGroupOffset;
@@ -243,6 +231,21 @@
                 if (si->lastGranulePos < 0)
                     si->lastGranulePos = 0;
             }
+            {
+                unsigned long pagenoatom[3] = { EndianU32_NtoB(sizeof(pagenoatom)), EndianU32_NtoB(kCookieTypeVorbisFirstPageNo),
+                                                EndianU32_NtoB(ogg_page_pageno(opg)) };
+                unsigned long endAtom[2] = { EndianU32_NtoB(sizeof(endAtom)), EndianU32_NtoB(kAudioTerminatorAtomType) };
+                PtrAndHand(pagenoatom, si->soundDescExtension, sizeof(pagenoatom)); //check errors?
+                ret = PtrAndHand(endAtom, si->soundDescExtension, sizeof(endAtom));
+                if (ret == noErr) {
+                    ret = AddSoundDescriptionExtension((SoundDescriptionHandle) si->sampleDesc,
+                                                       si->soundDescExtension, siDecompressionParams);
+                    //dbg_printf("??? -- Adding extension: %ld\n", ret);
+                } else {
+                    //dbg_printf("??? -- Hmm, something went wrong: %ld\n", ret);
+                }
+            }
+
             si->si_vorbis.state = kVStateReadingPackets;
             break;
 
@@ -293,11 +296,13 @@
                                 SetTrackEnabled(si->theTrack, true);
                             }
                         }
+                        /*
                         if (GetMovieTimeScale(globals->theMovie) < GetMediaTimeScale(si->theMedia)) {
                             dbg_printf("   # - changing movie time scale: %ld --> %ld\n",
                                        GetMovieTimeScale(globals->theMovie), GetMediaTimeScale(si->theMedia));
                             SetMovieTimeScale(globals->theMovie, GetMediaTimeScale(si->theMedia));
                         }
+                        */
                     }
                     si->insertTime = -1;
                     timeLoaded = GetTrackDuration(si->theTrack);

Modified: trunk/xiph-qt/OggImport/src/stream_vorbis.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_vorbis.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/stream_vorbis.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -4,7 +4,7 @@
  *    Declaration of Vorbis format related functions of OggImporter.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -48,7 +48,7 @@
 
 #define HANDLE_FUNCTIONS__VORBIS { &process_stream_page__vorbis, &recognize_header__vorbis, \
             &verify_header__vorbis, &process_first_packet__vorbis, &create_sample_description__vorbis, \
-            &initialize_stream__vorbis, &clear_stream__vorbis }
+            NULL, NULL, &initialize_stream__vorbis, &clear_stream__vorbis }
 
 
 #endif /* __stream_vorbis_h__ */

Modified: trunk/xiph-qt/OggImport/src/versions.h
===================================================================
--- trunk/xiph-qt/OggImport/src/versions.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/OggImport/src/versions.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -4,7 +4,7 @@
  *    The current version of the OggImport component.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -32,9 +32,9 @@
 #define __versions_h__
 
 #ifdef DEBUG
-#define kOgg_eat__Version		(0x00FF0103)
+#define kOgg_eat__Version		(0x00FF0106)
 #else
-#define kOgg_eat__Version		(0x00000103)
+#define kOgg_eat__Version		(0x00000106)
 #endif /* DEBUG */
 
 #endif /* __versions_h__ */

Modified: trunk/xiph-qt/common/data_types.h
===================================================================
--- trunk/xiph-qt/common/data_types.h	2006-04-24 21:48:03 UTC (rev 11270)
+++ trunk/xiph-qt/common/data_types.h	2006-04-24 22:12:39 UTC (rev 11271)
@@ -5,7 +5,7 @@
  *    components.
  *
  *
- *  Copyright (c) 2005  Arek Korbik
+ *  Copyright (c) 2005-2006  Arek Korbik
  *
  *  This file is part of XiphQT, the Xiph QuickTime Components.
  *
@@ -42,7 +42,8 @@
 enum {
     kCookieTypeVorbisHeader = 'vCtH',
     kCookieTypeVorbisComments = 'vCt#',
-    kCookieTypeVorbisCodebooks = 'vCtC'
+    kCookieTypeVorbisCodebooks = 'vCtC',
+    kCookieTypeVorbisFirstPageNo = 'vCtN'
 };
 
 enum {
@@ -51,7 +52,17 @@
     kCookieTypeSpeexExtraHeader	= 'sCtX'
 };
 
+enum {
+    kCookieTypeTheoraHeader = 'tCtH',
+    kCookieTypeTheoraComments = 'tCt#',
+    kCookieTypeTheoraCodebooks = 'tCtC'
+};
 
+enum {
+    kCookieTypeFLACStreaminfo = 'fCtS',
+    kCookieTypeFLACMetadata = 'fCtM'
+};
+
 struct OggSerialNoAtom {
     long size;			// = sizeof(OggSerialNoAtom)
     long type;			// = kOggCookieSerialNoType



More information about the commits mailing list