[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