[xiph-commits] r8912 - in trunk/oggdsf/src/lib: core/ogg/libOOOggSeek helper/libOOOggChef

ozone at motherfish-iii.xiph.org ozone at motherfish-iii.xiph.org
Mon Feb 14 06:15:37 PST 2005


Author: ozone
Date: 2005-02-14 06:15:33 -0800 (Mon, 14 Feb 2005)
New Revision: 8912

Modified:
   trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.cpp
   trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.h
   trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.cpp
   trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.h
Log:
oggdsf:
 * Make libOOOOggSeek and libOOOggChef work with Annodex V3



Modified: trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.cpp
===================================================================
--- trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.cpp	2005-02-14 10:18:38 UTC (rev 8911)
+++ trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.cpp	2005-02-14 14:15:33 UTC (rev 8912)
@@ -1,60 +1,147 @@
 #include "stdafx.h"
 #include <libOOOggSeek/AutoAnxSeekTable.h>
 
+#define DEBUG
+
 AutoAnxSeekTable::AutoAnxSeekTable(string inFileName)
 	:	AutoOggSeekTable(inFileName)
 	,	mAnxPackets(0)
 	,	mSeenAnything(false)
+	,	mAnnodexMajorVersion(0)
 	,	mAnnodexSerialNo(0)
 	,	mReadyForOgg(false)
 	,	mSkippedCMML(false)
 {
+#ifdef DEBUG
+	mDebugFile.open("G:\\Logs\\AutoAnxSeekTable.log", ios_base::out);
+	mDebugFile << "AutoAnxSeekTable 1" << endl;
+#endif
 }
 
 AutoAnxSeekTable::~AutoAnxSeekTable(void)
 {
 	mFile.close();
+
+#ifdef DEBUG
+	mDebugFile.close();
+#endif
 }
 
 //IOggCallback interface
 bool AutoAnxSeekTable::acceptOggPage(OggPage* inOggPage) {
 	//FIX::: This is serious mess !
+
+	unsigned char* locPacketData;
+	if (		inOggPage != NULL
+			&&	inOggPage->getPacket(0) != NULL
+			&&	inOggPage->getPacket(0)->packetData() != NULL) {
+		locPacketData = inOggPage->getPacket(0)->packetData();
+	} else {
+		// Empty page: skip it
+		mFilePos += inOggPage->pageSize();
+		delete inOggPage;
+		return true;
+	}
+
 	if (mSeenAnything == false) {
-		if (strncmp((const char*)inOggPage->getPacket(0)->packetData(), "Annodex", 7) == 0) {
+
+		// Scan for Annodex v2 header
+		if (strncmp((const char*)locPacketData, "Annodex", 7) == 0) {
 			mAnnodexSerialNo = inOggPage->header()->StreamSerialNo();
 			mSeenAnything = true;
+			mAnnodexMajorVersion = 2;
 			mFilePos += inOggPage->pageSize();
+#ifdef DEBUG
+			mDebugFile << "Found Annodex: serialno is " << mAnnodexSerialNo << endl;
+#endif
 			delete inOggPage;
 			return true;
 			//Need to grab other info here.
+		} else if (strncmp((const char*)locPacketData, "fishead", 7) == 0) {
+			mAnnodexSerialNo = inOggPage->header()->StreamSerialNo();
+			mSeenAnything = true;
+			mAnnodexMajorVersion = 3;
+			mFilePos += inOggPage->pageSize();
+			mReadyForOgg = true;
+#ifdef DEBUG
+			mDebugFile << "Found fishead: serialno is " << mAnnodexSerialNo << endl;
+#endif
+			delete inOggPage;
+			return true;
 		} else {
+			mFilePos += inOggPage->pageSize();
 			delete inOggPage;
 			return false;
 		}
 	}
 
-	if ((mAnnodexSerialNo == inOggPage->header()->StreamSerialNo()) && ((inOggPage->header()->HeaderFlags() & 4) != 0)) {
-		//This is the EOS o the annodex section... everything that follows is ogg like
-		mReadyForOgg = true;
-		mFilePos += inOggPage->pageSize();
-		delete inOggPage;
-		return true;
-	}
+	// If we got up to this point, either the Annodex header (v2) or fishead (v2)
+	// has been seen.  What we do now depends on whether we're dealing with a v2
+	// or v3 file ...
 
+	if (mAnnodexMajorVersion == 2) {
 
-	if (mReadyForOgg) {
-		if (mSkippedCMML == false) {
-			mSkippedCMML = true;
+		if (	(mAnnodexSerialNo == inOggPage->header()->StreamSerialNo())
+			&& ((inOggPage->header()->HeaderFlags() & 4) != 0)) {
+			//This is the EOS of the annodex section... everything that follows is ogg like
+#ifdef DEBUG
+			mDebugFile << "Found Annodex EOS" << endl;
+#endif
+			mReadyForOgg = true;
 			mFilePos += inOggPage->pageSize();
 			delete inOggPage;
 			return true;
+		}
+
+		if (mReadyForOgg) {
+			// FIXME: Should we be skipping all CMML packets up to the <head> packet?
+
+			if (mSkippedCMML == false) {
+				mSkippedCMML = true;
+				mFilePos += inOggPage->pageSize();
+			} else {
+				return AutoOggSeekTable::acceptOggPage(inOggPage);		//Gives away page.
+			}
 		} else {
-			return AutoOggSeekTable::acceptOggPage(inOggPage);		//Gives away page.
+			mFilePos += inOggPage->pageSize();
 		}
+
+	} else if (mAnnodexMajorVersion == 3) {
+
+		if (mAnnodexSerialNo == inOggPage->header()->StreamSerialNo()) {
+			// We found a page with the Annodex serialno, but no EOS flag set on it.
+			// This is impossible for an Annodex v2 file (since the Annodex track
+			// consists of only the "Annodex" header packet and an EOS packet), but
+			// can be true for an Annodex v3 track.  Skip all pages in this track,
+			// otherwise we'll confuse AutoOggSeekTable.
+#ifdef DEBUG
+			mDebugFile << "Found page belonging to Annodex v3 skeleton; skipping" << endl;
+#endif
+			mFilePos += inOggPage->pageSize();
+		} else if (		locPacketData != NULL
+					&&	memcmp((const char*)locPacketData, "CMML\0\0\0\0", 8) == 0) {
+			// Found the CMML track: remember it since we need to skip the header packets
+			mCMMLSerialNo = inOggPage->header()->StreamSerialNo();
+			// We should really get this value from the fisbone packets, but what the hell!
+			mCMMLPacketsToSkip = 2;
+			mFilePos += inOggPage->pageSize();
+		} else if (mCMMLPacketsToSkip > 0 && mCMMLSerialNo == inOggPage->header()->StreamSerialNo()) {
+			// Found a CMML header page: ignore it
+			mCMMLPacketsToSkip--;
+			mFilePos += inOggPage->pageSize();
+		} else {
+			return AutoOggSeekTable::acceptOggPage(inOggPage);
+		}
+
 	} else {
-		mFilePos += inOggPage->pageSize();
+		// Encountered non-v2 and non-v3 file: we should never get here!
+#ifdef DEBUG
+		mDebugFile << "Annodex major version number " << mAnnodexMajorVersion << "?" << endl;
+#endif
+		delete inOggPage;
+		return false;
 	}
+
 	delete inOggPage;
 	return true;
-
 }

Modified: trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.h
===================================================================
--- trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.h	2005-02-14 10:18:38 UTC (rev 8911)
+++ trunk/oggdsf/src/lib/core/ogg/libOOOggSeek/AutoAnxSeekTable.h	2005-02-14 14:15:33 UTC (rev 8912)
@@ -27,5 +27,11 @@
 	bool mReadyForOgg;
 	bool mSkippedCMML;
 
-	
+	unsigned short mAnnodexMajorVersion;
+
+	// V3-related member variables
+	unsigned long mCMMLSerialNo;
+	unsigned long mCMMLPacketsToSkip;
+
+	fstream mDebugFile;
 };

Modified: trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.cpp
===================================================================
--- trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.cpp	2005-02-14 10:18:38 UTC (rev 8911)
+++ trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.cpp	2005-02-14 14:15:33 UTC (rev 8912)
@@ -189,8 +189,8 @@
 	}
 
 #ifdef DEBUG
-	for (unsigned int i = 0; i < mWantedStreamSerialNumbers.size(); i++) {
-		mDebugFile << "Serialno: " << mWantedStreamSerialNumbers[i].first << endl;
+	for (set<tSerial_HeadCountPair>::iterator i = mWantedStreamSerialNumbers.begin(); i != mWantedStreamSerialNumbers.end(); i++) {
+		mDebugFile << "Serialno: " << i->first << endl;
 	}
 
 	mDebugFile << "mDemuxState before LOOK_FOR_BODY is " << mDemuxState << endl;
@@ -240,6 +240,16 @@
 		   );
 }
 
+bool isFisheadPage (OggPage *inOggPage)
+{
+	return (
+			inOggPage->numPackets() == 1
+		&&	inOggPage->header()->isBOS()
+		&&	strncmp((char*)inOggPage->getPacket(0)->packetData(),
+		            "fishead\0", 8) == 0
+		   );
+}
+
 bool isAnxDataPage (OggPage *inOggPage)
 {
 	return (
@@ -258,32 +268,76 @@
 		   );
 }
 
-unsigned long secondaryHeaders(OggPacket* inPacket)
+unsigned long secondaryHeaders(OggPacket* inPacket, const unsigned short inAnnodexMajorVersion)
 {
-	const unsigned short NUM_SEC_HEADERS_OFFSET = 24;
+	if (inAnnodexMajorVersion == 2) {
 
-	return iLE_Math::charArrToULong(inPacket->packetData() +
-									NUM_SEC_HEADERS_OFFSET);
+		const unsigned short NUM_SEC_HEADERS_OFFSET = 24;
 
+		return iLE_Math::charArrToULong(inPacket->packetData() +
+										NUM_SEC_HEADERS_OFFSET);
+
+	} else if (inAnnodexMajorVersion == 3) {
+
+		// We're hardcoding the codec types in here for now: see the comment
+		// above the mimeType function for why.
+
+		unsigned long locSecondaryHeaders = 0;
+
+		char* locPacketData = (char*) inPacket->packetData();
+		if (memcmp(locPacketData, "\001vorbis", 7) == 0) {
+			locSecondaryHeaders = 3;
+		} else if (memcmp(locPacketData, "\200theora", 7) == 0) {
+			locSecondaryHeaders = 3;
+		} else if (memcmp(locPacketData, "CMML\0\0\0\0", 8) == 0) {
+			locSecondaryHeaders = 3;
+		} else {
+			locSecondaryHeaders = 3;
+		}
+
+		return locSecondaryHeaders;
+
+	} else {
+		// Neither V2 nor V3: ack!
+		return 0;
+	}
 }
 
-void setPresentationTimeOnAnnodexBOSPage (OggPage *inOggPage, LOOG_UINT64 inPresentationTime)
+void setPresentationTimeOnAnnodexHeaderPage (OggPage *inOggPage, LOOG_UINT64 inPresentationTime)
 {
-	// Sanity check that this is actually an Annodex BOS page
-	if (!isAnnodexBOSPage(inOggPage)) {
+	// Offsets for Annodex v2 (the "timebase" field)
+	const unsigned short V2_PRESENTATION_TIME_NUMERATOR_OFFSET = 12;
+	const unsigned short V2_PRESENTATION_TIME_DENOMINATOR_OFFSET =
+		V2_PRESENTATION_TIME_NUMERATOR_OFFSET + 8;
+
+	// Offsets for Annodex v3 (the "presentation time" field)
+	const unsigned short V3_PRESENTATION_TIME_NUMERATOR_OFFSET = 12;
+	const unsigned short V3_PRESENTATION_TIME_DENOMINATOR_OFFSET =
+		V3_PRESENTATION_TIME_NUMERATOR_OFFSET + 8;
+
+	// Figure out whether we're dealing with V2 or V3 and set the presentation
+	// time offsets appropriately
+	unsigned short locPresentationTimeNumeratorOffset = 0;
+	unsigned short locPresentationTimeDenominatorOffset = 0;
+	if (isAnnodexBOSPage(inOggPage)) {
+		// Annodex V2
+		locPresentationTimeNumeratorOffset = V2_PRESENTATION_TIME_NUMERATOR_OFFSET;
+		locPresentationTimeDenominatorOffset = V2_PRESENTATION_TIME_DENOMINATOR_OFFSET;
+	} else if (isFisheadPage(inOggPage)) {
+		// Annodex V3
+		locPresentationTimeNumeratorOffset = V3_PRESENTATION_TIME_NUMERATOR_OFFSET;
+		locPresentationTimeDenominatorOffset = V3_PRESENTATION_TIME_DENOMINATOR_OFFSET;
+	} else {
+		// We don't recognise this page: return early before we do anything
+		// harmful
 		return;
 	}
 
-	// Offsets for Annodex v2 (the "timebase" field)
-	const unsigned short PRESENTATION_TIME_NUMERATOR_OFFSET = 12;
-	const unsigned short PRESENTATION_TIME_DENOMINATOR_OFFSET =
-		PRESENTATION_TIME_NUMERATOR_OFFSET + 8;
-
 	unsigned char* locPacketData = inOggPage->getPacket(0)->packetData();
 
 	// Get pointers for the offsets into the packet
-	unsigned char* locNumeratorPointer = locPacketData + PRESENTATION_TIME_NUMERATOR_OFFSET;
-	unsigned char* locDenominatorPointer = locPacketData + PRESENTATION_TIME_DENOMINATOR_OFFSET;
+	unsigned char* locNumeratorPointer = locPacketData + locPresentationTimeNumeratorOffset;
+	unsigned char* locDenominatorPointer = locPacketData + locPresentationTimeDenominatorOffset;
 	
 	// Set the presentation time on the packet in DirectSeconds (using the
 	// denominator to indicate that the units are in DirectSeconds)
@@ -297,19 +351,47 @@
 #ifdef WIN32
 # define strncasecmp _strnicmp
 #endif /* will be undef'ed below */
-string mimeType(OggPacket* inPacket)
+string mimeType(OggPacket* inPacket, const unsigned short inAnnodexMajorVersion)
 {
-	const unsigned short CONTENT_TYPE_OFFSET = 28;
+	if (inAnnodexMajorVersion == 2) {
+		const unsigned short CONTENT_TYPE_OFFSET = 28;
 
-	if (strncasecmp((char *) inPacket->packetData() + CONTENT_TYPE_OFFSET,
-	    "Content-Type: ", 14) == 0)
-	{
-		const unsigned short MIME_TYPE_OFFSET = 28 + 14;
-		const unsigned short MAX_MIME_TYPE_LENGTH = 256;
-		char *locMimeType = new char[MAX_MIME_TYPE_LENGTH];
-		sscanf((char *) inPacket->packetData() + MIME_TYPE_OFFSET, "%s\r\n", locMimeType);
+		if (strncasecmp((char *) inPacket->packetData() + CONTENT_TYPE_OFFSET,
+			"Content-Type: ", 14) == 0)
+		{
+			const unsigned short MIME_TYPE_OFFSET = 28 + 14;
+			const unsigned short MAX_MIME_TYPE_LENGTH = 256;
+			char *locMimeType = new char[MAX_MIME_TYPE_LENGTH];
+			sscanf((char *) inPacket->packetData() + MIME_TYPE_OFFSET, "%s\r\n", locMimeType);
+			return locMimeType;
+		} else {
+			return NULL;
+		}
+	} else if (inAnnodexMajorVersion == 3) {
+		// Ahem, we should _really_ peek into the fisbone track to do this
+		// properly, but considering that you need to understand the codecs to
+		// build the seek table anyway, yet another codec dependency here
+		// isn't going to kill us.  Obviously this is a very bad long-term
+		// solution since the V3 Annodex skeleton is meant to be completely
+		// codec-independent, but too much of this framework is currently
+		// littered with codec knowledge.
+		string locMimeType;
+
+		char* locPacketData = (char*) inPacket->packetData();
+		if (memcmp(locPacketData, "\001vorbis", 7) == 0) {
+			locMimeType = "audio/x-vorbis";
+		} else if (memcmp(locPacketData, "\200theora", 7) == 0) {
+			locMimeType = "video/x-theora";
+		} else if (memcmp(locPacketData, "CMML\0\0\0\0", 8) == 0) {
+			locMimeType = "text/x-cmml";
+		} else if (memcmp(locPacketData, "fisbone\0", 8) == 0) {
+			locMimeType = "_skeleton";
+		}
+
 		return locMimeType;
+
 	} else {
+		// Neither V2 nor V3: exit with extreme prejudice
 		return NULL;
 	}
 }
@@ -324,17 +406,30 @@
 		switch (mDemuxState) {
 
 			case SEEN_NOTHING:
-				if (isAnnodexBOSPage(inOggPage)) {
+				if (isAnnodexBOSPage(inOggPage) || isFisheadPage(inOggPage)) {
 					mDemuxState = SEEN_ANNODEX_BOS;
 
+					// Do we have a V2 or V3 Annodex file?
+					if (isAnnodexBOSPage(inOggPage)) {
+#ifdef DEBUG
+						mDebugFile << "Found Annodex v2 file" << endl;
+#endif
+						mAnnodexMajorVersion = 2;
+					} else if (isFisheadPage(inOggPage)) {
+#ifdef DEBUG
+						mDebugFile << "Found Annodex v3 file" << endl;
+#endif
+						mAnnodexMajorVersion = 3;
+					}
+
 					// Remember the Annodex stream's serial number, so we can output it later
 					mAnnodexSerialNumber = inOggPage->header()->StreamSerialNo();
-					mWantedStreamSerialNumbers.push_back(make_pair<unsigned long, unsigned long>(mAnnodexSerialNumber, 0));
+					mWantedStreamSerialNumbers.insert(make_pair<unsigned long, unsigned long>(mAnnodexSerialNumber, 0));
 
 					// Fix up the presentation time of the Annodex BOS page if we're not
 					// serving out the data from time 0
 					if (mRequestedStartTime != 0) {
-						setPresentationTimeOnAnnodexBOSPage(inOggPage, mRequestedStartTime);
+						setPresentationTimeOnAnnodexHeaderPage(inOggPage, mRequestedStartTime);
 					}
 
 					if (!wantOnlyPacketBody(mWantedMIMETypes)) {
@@ -345,16 +440,28 @@
 						delete locRawPageData;
 					}
 				} else {
-					// The Annodex BOS page should always be the very first page of
+					// The Annodex/Fishead BOS page should always be the very first page of
 					// the stream, so if we don't see it, the stream's invalid
 					mDemuxState = INVALID;
 				}
 				break;
 
 			case SEEN_ANNODEX_BOS:
-				if (isAnxDataPage(inOggPage)) {
+				if (isAnnodexEOSPage(inOggPage, mAnnodexSerialNumber)) {
+#ifdef DEBUG
+					mDebugFile << "Seen Annodex skeleton EOS" << endl;
+#endif
+					mDemuxState = SEEN_ANNODEX_EOS;
+					if (!wantOnlyPacketBody(mWantedMIMETypes)) {
+						unsigned char *locRawPageData = inOggPage->createRawPageData();
+						mBufferWriter(locRawPageData,
+							inOggPage->pageSize(), mBufferWriterUserData);
+						delete locRawPageData;
+					}
+				} else if ((	mAnnodexMajorVersion == 2 && isAnxDataPage(inOggPage))
+							||	mAnnodexMajorVersion == 3) {
 					unsigned long locSerialNumber = inOggPage->header()->StreamSerialNo();
-					string locMimeType = mimeType(inOggPage->getPacket(0));
+					string locMimeType = mimeType(inOggPage->getPacket(0), mAnnodexMajorVersion);
 
 					for (unsigned int i = 0; i < mWantedMIMETypes->size(); i++) {
 						const string locWantedMIMEType = mWantedMIMETypes->at(i);
@@ -364,13 +471,14 @@
 							// Create an association of serial no and num headers
 							tSerial_HeadCountPair locMap;
 							locMap.first = locSerialNumber;
-							locMap.second = secondaryHeaders(inOggPage->getPacket(0));
+							locMap.second = secondaryHeaders(inOggPage->getPacket(0), mAnnodexMajorVersion);
 
 							// Add the association to our stream list
-							mWantedStreamSerialNumbers.push_back(locMap);
+							if ((mWantedStreamSerialNumbers.insert(locMap)).second) {
 #ifdef DEBUG
-							mDebugFile << "Added serialno " << locSerialNumber << " to mWantedStreamSerialNumbers" << endl;
+								mDebugFile << "Added " << locSerialNumber << " with " << locMap.second << " to mWantedStreamSerialNumbers" << endl;
 #endif
+							}
 
 							if (!wantOnlyPacketBody(mWantedMIMETypes)) {
 								unsigned char *locRawPageData = inOggPage->createRawPageData();
@@ -380,28 +488,21 @@
 							}
 						}
 					}
-				} else if (isAnnodexEOSPage(inOggPage, mAnnodexSerialNumber)) {
-					mDemuxState = SEEN_ANNODEX_EOS;
-					if (!wantOnlyPacketBody(mWantedMIMETypes)) {
-						unsigned char *locRawPageData = inOggPage->createRawPageData();
-						mBufferWriter(locRawPageData,
-							inOggPage->pageSize(), mBufferWriterUserData);
-						delete locRawPageData;
-					}
 				} else {
-					// We didn't spot either an AnxData page or the Annodex EOS: WTF?
+					// We didn't spot either an AnxData page or the Annodex
+					// EOS (v2), or a fisbone/header page (v3).  WTF?
 					mDemuxState = INVALID;
 				}
 				break;
 
 			case SEEN_ANNODEX_EOS:
-				{
+				if (mAnnodexMajorVersion == 2) {
 					// Only output headers for the streams that the user wants
 					// in their request
-					for (unsigned int i = 0; i < mWantedStreamSerialNumbers.size(); i++) {
-						if (mWantedStreamSerialNumbers[i].first == inOggPage->header()->StreamSerialNo()) {
-							if (mWantedStreamSerialNumbers[i].second >= 1) {
-								mWantedStreamSerialNumbers[i].second--;
+					for (set<tSerial_HeadCountPair>::iterator i = mWantedStreamSerialNumbers.begin(); i != mWantedStreamSerialNumbers.end(); i++) {
+						if (i->first == inOggPage->header()->StreamSerialNo()) {
+							if (i->second >= 1) {
+								i->second--;
 								if (wantOnlyPacketBody(mWantedMIMETypes)) {
 									OggPacket* locPacket = inOggPage->getPacket(0);
 									mBufferWriter(locPacket->packetData(),
@@ -413,17 +514,12 @@
 									delete locRawPageData;
 								}
 							} 
-#if 0
-							else {
-								mDemuxState = INVALID;
-							}
-#endif
 						}
 					}
 
 					bool allEmpty = true;
-					for (unsigned int i = 0; i < mWantedStreamSerialNumbers.size(); i++) {
-						if (mWantedStreamSerialNumbers[i].second != 0) {
+					for (set<tSerial_HeadCountPair>::iterator i = mWantedStreamSerialNumbers.begin(); i != mWantedStreamSerialNumbers.end(); i++) {
+						if (i->second != 0) {
 							allEmpty = false;
 						}
 					}
@@ -431,6 +527,9 @@
 					if (allEmpty) {
 						mDemuxState = SEEN_ALL_CODEC_HEADERS;
 					}
+				} else if (mAnnodexMajorVersion == 3) {
+					// Annodex V3: once we hit the Annodex EOS, all the page headers are done
+					mDemuxState = SEEN_ALL_CODEC_HEADERS;
 				}
 				break;
 			case SEEN_ALL_CODEC_HEADERS:
@@ -447,7 +546,7 @@
 		switch (mDemuxState) {
 
 			case SEEN_NOTHING:
-				if (isAnnodexBOSPage(inOggPage)) {
+				if (isAnnodexBOSPage(inOggPage) || isFisheadPage(inOggPage)) {
 					mDemuxState = SEEN_ANNODEX_BOS;
 				} else {
 					// The Annodex BOS page should always be the very first page of
@@ -457,10 +556,11 @@
 				break;
 
 			case SEEN_ANNODEX_BOS:
-				if (isAnxDataPage(inOggPage)) {
+				if (isAnnodexEOSPage(inOggPage, mAnnodexSerialNumber)) {
+					mDemuxState = SEEN_ANNODEX_EOS;
+				} else if (		(mAnnodexMajorVersion == 2 && isAnxDataPage(inOggPage))
+							||	 mAnnodexMajorVersion == 3) {
 					// Do nothing
-				} else if (isAnnodexEOSPage(inOggPage, mAnnodexSerialNumber)) {
-					mDemuxState = SEEN_ANNODEX_EOS;
 				} else {
 					// We didn't spot either an AnxData page or the Annodex EOS: WTF?
 					mDemuxState = INVALID;
@@ -470,7 +570,6 @@
 			case SEEN_ANNODEX_EOS:
 				mDemuxState = SEEN_ALL_CODEC_HEADERS;
 				// Fallthrough!
-
 			case SEEN_ALL_CODEC_HEADERS:
 				{
 					// Ignore any header packets which we may encounter
@@ -479,15 +578,11 @@
 					}
 
 					// Only output streams which the user requested
-					for (unsigned int i = 0; i < mWantedStreamSerialNumbers.size(); i++) {
+					for (set<tSerial_HeadCountPair>::iterator i = mWantedStreamSerialNumbers.begin(); i != mWantedStreamSerialNumbers.end(); i++) {
+						if (i->first ==	inOggPage->header()->StreamSerialNo()) {
 #ifdef DEBUG
-						mDebugFile << "Encountered page with serialno " << inOggPage->header()->StreamSerialNo() << endl;
+							mDebugFile << "Outputting page for serialno " << i->first << endl;
 #endif
-						if (	mWantedStreamSerialNumbers[i].first
-							==	inOggPage->header()->StreamSerialNo()) {
-#ifdef DEBUG
-							mDebugFile << "Outputting page for serialno " << mWantedStreamSerialNumbers[i].first << endl;
-#endif
 							if (wantOnlyPacketBody(mWantedMIMETypes)) {
 								for (unsigned long j = 0; j < inOggPage->numPackets(); j++) {
 									OggPacket* locPacket = inOggPage->getPacket(j);

Modified: trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.h
===================================================================
--- trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.h	2005-02-14 10:18:38 UTC (rev 8911)
+++ trunk/oggdsf/src/lib/helper/libOOOggChef/AnnodexRecomposer.h	2005-02-14 14:15:33 UTC (rev 8912)
@@ -40,6 +40,7 @@
 #include <libOOOgg/libOOOgg.h>
 #include <libOOOggChef/libOOOggChef.h>
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -88,8 +89,10 @@
 	eDemuxState mDemuxState;
 	eDemuxParserState mDemuxParserState;
 
-	vector<tSerial_HeadCountPair> mWantedStreamSerialNumbers;
+	set<tSerial_HeadCountPair> mWantedStreamSerialNumbers;
 	const vector<string>* mWantedMIMETypes;
 
 	LOOG_UINT64 mRequestedStartTime;
+
+	unsigned short mAnnodexMajorVersion;
 };



More information about the commits mailing list