Bug 592833 - Remove nsBuiltinDecoderReader monitor. r=roc

This commit is contained in:
Chris Pearce 2011-07-12 15:39:28 +12:00
Родитель 1346ea4166
Коммит 34f14edcfc
7 изменённых файлов: 40 добавлений и 89 удалений

Просмотреть файл

@ -190,8 +190,7 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
}
nsBuiltinDecoderReader::nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder)
: mReentrantMonitor("media.decoderreader"),
mDecoder(aDecoder)
: mDecoder(aDecoder)
{
MOZ_COUNT_CTOR(nsBuiltinDecoderReader);
}
@ -275,7 +274,6 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
PRBool skip = PR_FALSE;
eof = !DecodeVideoFrame(skip, 0);
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
return NS_ERROR_FAILURE;
@ -300,7 +298,6 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
}
}
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
return NS_ERROR_FAILURE;
@ -320,7 +317,6 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
while (!eof && mAudioQueue.GetSize() == 0) {
eof = !DecodeAudioData();
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
return NS_ERROR_FAILURE;

Просмотреть файл

@ -398,12 +398,10 @@ private:
PRBool mEndOfStream;
};
// Encapsulates the decoding and reading of media data. Reading can be done
// on either the state machine thread (when loading and seeking) or on
// the reader thread (when it's reading and decoding). The reader encapsulates
// the reading state and maintains it's own monitor to ensure thread safety
// and correctness. Never hold the nsBuiltinDecoder's monitor when calling into
// this class.
// Encapsulates the decoding and reading of media data. Reading can only be
// done on the decode thread thread. Never hold the decoder monitor when
// calling into this class. Unless otherwise specified, methods and fields of
// this class can only be accessed on the decode thread.
class nsBuiltinDecoderReader : public nsRunnable {
public:
typedef mozilla::ReentrantMonitor ReentrantMonitor;
@ -452,10 +450,12 @@ public:
PRInt64 aEndTime,
PRInt64 aCurrentTime) = 0;
// Queue of audio samples. This queue is threadsafe.
// Queue of audio samples. This queue is threadsafe, and is accessed from
// the audio, decoder, state machine, and main threads.
MediaQueue<SoundData> mAudioQueue;
// Queue of video samples. This queue is threadsafe.
// Queue of video samples. This queue is threadsafe, and is accessed from
// the decoder, state machine, and main threads.
MediaQueue<VideoData> mVideoQueue;
// Populates aBuffered with the time ranges which are buffered. aStartTime
@ -492,16 +492,10 @@ protected:
return DecodeVideoFrame(f, 0);
}
// The lock which we hold whenever we read or decode. This ensures the thread
// safety of the reader and its data fields.
ReentrantMonitor mReentrantMonitor;
// Reference to the owning decoder object. Do not hold the
// reader's monitor when accessing this.
// Reference to the owning decoder object.
nsBuiltinDecoder* mDecoder;
// Stores presentation info required for playback. The reader's monitor
// must be held when accessing this.
// Stores presentation info required for playback.
nsVideoInfo mInfo;
};

Просмотреть файл

@ -140,23 +140,20 @@ nsresult nsOggReader::Init(nsBuiltinDecoderReader* aCloneDonor) {
nsresult nsOggReader::ResetDecode()
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
nsresult res = NS_OK;
if (NS_FAILED(nsBuiltinDecoderReader::ResetDecode())) {
res = NS_ERROR_FAILURE;
}
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// Discard any previously buffered packets/pages.
ogg_sync_reset(&mOggState);
if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
res = NS_ERROR_FAILURE;
}
if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
res = NS_ERROR_FAILURE;
}
// Discard any previously buffered packets/pages.
ogg_sync_reset(&mOggState);
if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
res = NS_ERROR_FAILURE;
}
if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
res = NS_ERROR_FAILURE;
}
return res;
@ -179,7 +176,6 @@ PRBool nsOggReader::ReadHeaders(nsOggCodecState* aState)
nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// We read packets until all bitstreams have read all their header packets.
// We record the offset of the first non-header page so that we know
@ -318,8 +314,7 @@ nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
}
PRInt64 duration = 0;
if (NS_SUCCEEDED(mSkeletonState->GetDuration(tracks, duration))) {
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->GetStateMachine()->SetDuration(duration);
LOG(PR_LOG_DEBUG, ("Got duration from Skeleton index %lld", duration));
}
@ -327,8 +322,7 @@ nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
}
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
nsMediaStream* stream = mDecoder->GetCurrentStream();
if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
@ -402,7 +396,6 @@ nsresult nsOggReader::DecodeVorbis(ogg_packet* aPacket) {
PRBool nsOggReader::DecodeAudioData()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
NS_ASSERTION(mVorbisState!=0, "Need Vorbis state to decode audio");
@ -479,9 +472,6 @@ nsresult nsOggReader::DecodeTheora(ogg_packet* aPacket, PRInt64 aTimeThreshold)
b.mPlanes[i].mStride = buffer[i].stride;
}
// Need the monitor to be held to be able to use mInfo. This
// is held by our caller.
mReentrantMonitor.AssertCurrentThreadIn();
VideoData *v = VideoData::Create(mInfo,
mDecoder->GetImageContainer(),
mPageOffset,
@ -505,7 +495,6 @@ nsresult nsOggReader::DecodeTheora(ogg_packet* aPacket, PRInt64 aTimeThreshold)
PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
PRInt64 aTimeThreshold)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
// Record number of frames decoded and parsed. Automatically update the
@ -556,7 +545,6 @@ PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
PRInt64 nsOggReader::ReadOggPage(ogg_page* aPage)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
mReentrantMonitor.AssertCurrentThreadIn();
int ret = 0;
while((ret = ogg_sync_pageseek(&mOggState, aPage)) <= 0) {
@ -595,7 +583,6 @@ PRInt64 nsOggReader::ReadOggPage(ogg_page* aPage)
ogg_packet* nsOggReader::NextOggPacket(nsOggCodecState* aCodecState)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
mReentrantMonitor.AssertCurrentThreadIn();
if (!aCodecState || !aCodecState->mActive) {
return nsnull;
@ -638,8 +625,7 @@ GetChecksum(ogg_page* page)
PRInt64 nsOggReader::RangeStartTime(PRInt64 aOffset)
{
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine or decode thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
nsMediaStream* stream = mDecoder->GetCurrentStream();
NS_ENSURE_TRUE(stream != nsnull, nsnull);
nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
@ -661,7 +647,6 @@ struct nsAutoOggSyncState {
PRInt64 nsOggReader::RangeEndTime(PRInt64 aEndOffset)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine or decode thread.");
@ -794,7 +779,6 @@ PRInt64 nsOggReader::RangeEndTime(PRInt64 aStartOffset,
nsresult nsOggReader::GetSeekRanges(nsTArray<SeekRange>& aRanges)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
mReentrantMonitor.AssertCurrentThreadIn();
nsTArray<nsByteRange> cached;
nsresult res = mDecoder->GetCurrentStream()->GetCachedRanges(cached);
NS_ENSURE_SUCCESS(res, res);
@ -971,8 +955,7 @@ nsresult nsOggReader::SeekInBufferedRange(PRInt64 aTarget,
PRBool skip = PR_FALSE;
eof = !DecodeVideoFrame(skip, 0);
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
return NS_ERROR_FAILURE;
}
@ -1046,7 +1029,6 @@ nsresult nsOggReader::Seek(PRInt64 aTarget,
PRInt64 aEndTime,
PRInt64 aCurrentTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
nsresult res;
@ -1065,8 +1047,7 @@ nsresult nsOggReader::Seek(PRInt64 aTarget,
NS_ASSERTION(aStartTime != -1, "mStartTime should be known");
{
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->UpdatePlaybackPosition(aStartTime);
}
} else if (CanDecodeToTarget(aTarget, aCurrentTime)) {

Просмотреть файл

@ -71,15 +71,11 @@ public:
virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
PRInt64 aTimeThreshold);
virtual PRBool HasAudio()
{
mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
virtual PRBool HasAudio() {
return mVorbisState != 0 && mVorbisState->mActive;
}
virtual PRBool HasVideo()
{
mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
virtual PRBool HasVideo() {
return mTheoraState != 0 && mTheoraState->mActive;
}
@ -89,9 +85,7 @@ public:
private:
PRBool HasSkeleton()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
PRBool HasSkeleton() {
return mSkeletonState != 0 && mSkeletonState->mActive;
}

Просмотреть файл

@ -153,7 +153,6 @@ nsresult nsWaveReader::Init(nsBuiltinDecoderReader* aCloneDonor)
nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
PRBool loaded = LoadRIFFChunk() && LoadFormatChunk() && FindDataOffset();
if (!loaded) {
@ -167,8 +166,7 @@ nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
*aInfo = mInfo;
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->GetStateMachine()->SetDuration(
static_cast<PRInt64>(BytesToTime(GetDataLength()) * USECS_PER_S));
@ -178,9 +176,7 @@ nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
PRBool nsWaveReader::DecodeAudioData()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine thread or decode thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
PRInt64 pos = GetPosition() - mWavePCMOffset;
PRInt64 len = GetDataLength();
@ -246,16 +242,13 @@ PRBool nsWaveReader::DecodeAudioData()
PRBool nsWaveReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
PRInt64 aTimeThreshold)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine or decode thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
return PR_FALSE;
}
nsresult nsWaveReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
if (NS_FAILED(ResetDecode())) {

Просмотреть файл

@ -209,8 +209,7 @@ void nsWebMReader::Cleanup()
nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on state machine thread.");
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
nestegg_io io;
io.read = webm_read;
@ -225,8 +224,7 @@ nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
uint64_t duration = 0;
r = nestegg_duration(mContext, &duration);
if (r == 0) {
ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->GetStateMachine()->SetDuration(duration / NS_PER_USEC);
}
@ -411,7 +409,7 @@ ogg_packet nsWebMReader::InitOggPacket(unsigned char* aData,
PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
{
mReentrantMonitor.AssertCurrentThreadIn();
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
int r = 0;
unsigned int count = 0;
@ -589,9 +587,8 @@ nsReturnRef<NesteggPacketHolder> nsWebMReader::NextPacket(TrackType aTrackType)
PRBool nsWebMReader::DecodeAudioData()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine thread or decode thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
nsAutoRef<NesteggPacketHolder> holder(NextPacket(AUDIO));
if (!holder) {
mAudioQueue.Finish();
@ -604,9 +601,7 @@ PRBool nsWebMReader::DecodeAudioData()
PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
PRInt64 aTimeThreshold)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
"Should be on state machine or decode thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
// Record number of frames decoded and parsed. Automatically update the
// stats counters using the AutoNotifyDecoded stack-based class.
@ -652,7 +647,6 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
}
mVideoPackets.PushFront(next_holder.disown());
} else {
ReentrantMonitorAutoExit exitMon(mReentrantMonitor);
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
nsBuiltinDecoderStateMachine* s =
static_cast<nsBuiltinDecoderStateMachine*>(mDecoder->GetStateMachine());
@ -766,9 +760,8 @@ PRBool nsWebMReader::CanDecodeToTarget(PRInt64 aTarget,
nsresult nsWebMReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime,
PRInt64 aCurrentTime)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(),
"Should be on state machine thread.");
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
if (CanDecodeToTarget(aTarget, aCurrentTime)) {
LOG(PR_LOG_DEBUG, ("%p Seek target (%lld) is close to current time (%lld), "

Просмотреть файл

@ -143,13 +143,13 @@ public:
virtual PRBool HasAudio()
{
mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
return mHasAudio;
}
virtual PRBool HasVideo()
{
mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
return mHasVideo;
}