Bug 566501 - Remove unnecessary seek from the video decoder base class. r=cpearce
authorChris Double <chris.double@double.co.nz>
Fri, 21 May 2010 09:13:01 +1200
changeset 42513 4f43e5fbd0fc0905a5ab0f9578673e4c5576a5e6
parent 42512 26052d8585953638cc3c4d71ff12f6ff7b3200d5
child 42514 a8c70cdbf50bda4a1d6c59ca4e83e2c7f2027e61
push idunknown
push userunknown
push dateunknown
reviewerscpearce
bugs566501
milestone1.9.3a5pre
Bug 566501 - Remove unnecessary seek from the video decoder base class. r=cpearce
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -261,19 +261,16 @@ nsBuiltinDecoderReader::GetSeekRange(con
   return aExact ? ByteRange() : ByteRange(so, eo, st, et);
 }
 
 VideoData* nsBuiltinDecoderReader::FindStartTime(PRInt64 aOffset,
                                       PRInt64& aOutStartTime)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on state machine thread.");
 
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
-
-  stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
   if (NS_FAILED(ResetDecode())) {
     return nsnull;
   }
 
   // Extract the start times of the bitstreams in order to calculate
   // the duration.
   PRInt64 videoStartTime = PR_INT64_MAX;
   PRInt64 audioStartTime = PR_INT64_MAX;
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -424,18 +424,18 @@ public:
   // Read header data for all bitstreams in the file. Fills mInfo with
   // the data required to present the media. Returns NS_OK on success,
   // or NS_ERROR_FAILURE on failure.
   virtual nsresult ReadMetadata() = 0;
 
 
   // Stores the presentation time of the first sample in the stream in
   // aOutStartTime, and returns the first video sample, if we have video.
-  VideoData* FindStartTime(PRInt64 aOffset,
-                           PRInt64& aOutStartTime);
+  virtual VideoData* FindStartTime(PRInt64 aOffset,
+                                   PRInt64& aOutStartTime);
 
   // Returns the end time of the last page which occurs before aEndOffset.
   // This will not read past aEndOffset. Returns -1 on failure.
   virtual PRInt64 FindEndTime(PRInt64 aEndOffset) = 0;
 
   // Moves the decode head to aTime milliseconds. aStartTime and aEndTime
   // denote the start and end times of the media.
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime) = 0;
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -1208,22 +1208,16 @@ void nsBuiltinDecoderStateMachine::FindE
   {
     MonitorAutoExit exitMon(mDecoder->GetMonitor());
     endTime = mReader->FindEndTime(length);
   }
   if (endTime != -1) {
     mEndTime = endTime;
   }
 
-  NS_ASSERTION(mReader->GetInfo().mDataOffset > 0,
-               "Should have offset of first non-header page");
-  {
-    MonitorAutoExit exitMon(mDecoder->GetMonitor());
-    stream->Seek(nsISeekableStream::NS_SEEK_SET, mReader->GetInfo().mDataOffset);
-  }
   LOG(PR_LOG_DEBUG, ("%p Media end time is %lldms", mDecoder, mEndTime));   
 }
 
 void nsBuiltinDecoderStateMachine::UpdateReadyState() {
   mDecoder->GetMonitor().AssertCurrentThreadIn();
 
   nsCOMPtr<nsIRunnable> event;
   switch (GetNextFrameStatus()) {
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -795,16 +795,26 @@ GetChecksum(ogg_page* page)
   const unsigned char* p = page->header + 22;
   PRUint32 c =  p[0] +
                (p[1] << 8) + 
                (p[2] << 16) +
                (p[3] << 24);
   return c;
 }
 
+VideoData* nsOggReader::FindStartTime(PRInt64 aOffset,
+                                      PRInt64& aOutStartTime)
+{
+  NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on state machine thread.");
+
+  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
+  return nsBuiltinDecoderReader::FindStartTime(aOffset, aOutStartTime);
+}
+
 PRInt64 nsOggReader::FindEndTime(PRInt64 aEndOffset)
 {
   MonitorAutoEnter mon(mMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on state machine thread.");
 
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   ogg_sync_reset(&mOggState);
 
@@ -909,16 +919,20 @@ PRInt64 nsOggReader::FindEndTime(PRInt64
     PRInt64 t = codecState ? codecState->Time(granulepos) : -1;
     if (t != -1) {
       endTime = t;
     }
   }
 
   ogg_sync_reset(&mOggState);
 
+  NS_ASSERTION(mDataOffset > 0,
+               "Should have offset of first non-header page");
+  stream->Seek(nsISeekableStream::NS_SEEK_SET, mDataOffset);
+
   return endTime;
 }
 
 nsresult nsOggReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime)
 {
   MonitorAutoEnter mon(mMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
--- a/content/media/ogg/nsOggReader.h
+++ b/content/media/ogg/nsOggReader.h
@@ -57,16 +57,18 @@ public:
   virtual nsresult ResetDecode();
   virtual PRBool DecodeAudioData();
 
   // If the Theora granulepos has not been captured, it may read several packets
   // until one with a granulepos has been captured, to ensure that all packets
   // read have valid time info.  
   virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
                                   PRInt64 aTimeThreshold);
+  virtual VideoData* FindStartTime(PRInt64 aOffset,
+                                   PRInt64& aOutStartTime);
   virtual PRInt64 FindEndTime(PRInt64 aEndOffset);
 
   virtual PRBool HasAudio()
   {
     mozilla::MonitorAutoEnter mon(mMonitor);
     return mVorbisState != 0 && mVorbisState->mActive;
   }