Created
March 21, 2012 09:02
-
-
Save oneman/2145713 to your computer and use it in GitHub Desktop.
New Ogg Vorbis chaining kludge, works, no audio glitch, but if you seek, you will surely seg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/content/media/ogg/nsOggReader.cpp b/content/media/ogg/nsOggReader.cpp | |
index 7575e08..e61e6da 100644 | |
--- a/content/media/ogg/nsOggReader.cpp | |
+++ b/content/media/ogg/nsOggReader.cpp | |
@@ -108,7 +108,8 @@ nsOggReader::nsOggReader(nsBuiltinDecoder* aDecoder) | |
mSkeletonState(nsnull), | |
mVorbisSerial(0), | |
mTheoraSerial(0), | |
- mPageOffset(0) | |
+ mPageOffset(0), | |
+ mChainKludgeState(0) | |
{ | |
MOZ_COUNT_CTOR(nsOggReader); | |
memset(&mTheoraInfo, 0, sizeof(mTheoraInfo)); | |
@@ -410,8 +411,13 @@ bool nsOggReader::DecodeAudioData() | |
// We've encountered an end of bitstream packet, or we've hit the end of | |
// file while trying to decode, so inform the audio queue that there'll | |
// be no more samples. | |
- mAudioQueue.Finish(); | |
- return false; | |
+ if (HasAudio() && !HasVideo()) { | |
+ mChainKludgeState = 2; | |
+ printf("End of vorbis logical stream\n"); | |
+ } else { | |
+ mAudioQueue.Finish(); | |
+ return false; | |
+ } | |
} | |
return true; | |
@@ -580,9 +586,28 @@ ogg_packet* nsOggReader::NextOggPacket(nsOggCodecState* aCodecState) | |
ogg_packet* packet; | |
while ((packet = aCodecState->PacketOut()) == nsnull) { | |
+ | |
+ ogg_page page; | |
+ while (mChainKludgeState) { | |
+ if (ReadOggPage(&page) == -1) { | |
+ return nsnull; | |
+ } | |
+ if (mChainKludgeState == 2) { | |
+ nsOggCodecState* orig_codecState = nsnull; | |
+ //PRUint32 old_serial = mVorbisSerial; | |
+ mCodecStates.Get(mVorbisSerial, &orig_codecState); | |
+ mVorbisSerial = ogg_page_serialno(&page); | |
+ mCodecStates.Put(mVorbisSerial, orig_codecState); | |
+ //mCodecStates.Remove(old_serial); | |
+ mVorbisState->mSerial = mVorbisSerial; | |
+ mKnownStreams.AppendElement(mVorbisSerial); | |
+ ogg_stream_reset_serialno(&mVorbisState->mState, mVorbisState->mSerial); | |
+ vorbis_synthesis_restart(&mVorbisState->mDsp); | |
+ } | |
+ mChainKludgeState--; | |
+ } | |
// The codec state does not have any buffered pages, so try to read another | |
// page from the channel. | |
- ogg_page page; | |
if (ReadOggPage(&page) == -1) { | |
return nsnull; | |
} | |
diff --git a/content/media/ogg/nsOggReader.h b/content/media/ogg/nsOggReader.h | |
index 54302b3..b79d311 100644 | |
--- a/content/media/ogg/nsOggReader.h | |
+++ b/content/media/ogg/nsOggReader.h | |
@@ -218,8 +218,8 @@ private: | |
// Decodes a packet of Theora data, and inserts its frame into the | |
// video queue. May return NS_ERROR_OUT_OF_MEMORY. Caller must have obtained | |
- // the reader's monitor. aTimeThreshold is the current playback position | |
- // in media time in microseconds. Frames with an end time before this will | |
+ // the reader's monitor. aTimeThreshold is the current playback position | |
+ // in media time in microseconds. Frames with an end time before this will | |
// not be enqueued. | |
nsresult DecodeTheora(ogg_packet* aPacket, PRInt64 aTimeThreshold); | |
@@ -259,6 +259,7 @@ private: | |
// Ogg decoding state. | |
ogg_sync_state mOggState; | |
+ int mChainKludgeState; | |
// Vorbis/Theora data used to compute timestamps. This is written on the | |
// decoder thread and read on the main thread. All reading on the main | |
// thread must be done after metadataloaded. We can't use the existing |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment