Bug 1093654 - Fix various memory leaks in MediaDecoders. r=jwwang

Change various function prototyping to make object ownership more explicit.
This commit is contained in:
Jean-Yves Avenard 2014-11-06 19:17:05 +11:00
parent be860b7026
commit 76d6d44c61
17 changed files with 91 additions and 87 deletions

View File

@ -2886,11 +2886,11 @@ void HTMLMediaElement::ProcessMediaFragmentURI()
}
void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
const MetadataTags* aTags)
nsAutoPtr<const MetadataTags> aTags)
{
mHasAudio = aInfo->HasAudio();
mHasVideo = aInfo->HasVideo();
mTags = aTags;
mTags = aTags.forget();
mLoadedDataFired = false;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));

View File

@ -160,7 +160,7 @@ public:
// when it has read the metadata containing video dimensions,
// etc.
virtual void MetadataLoaded(const MediaInfo* aInfo,
const MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
nsAutoPtr<const MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
// Called by the decoder object, on the main thread,
// when it has read the first frame of the video or audio.

View File

@ -88,9 +88,9 @@ public:
// Return true if the transport layer supports seeking.
virtual bool IsMediaSeekable() = 0;
virtual void MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags) = 0;
virtual void QueueMetadata(int64_t aTime, MediaInfo* aInfo, MetadataTags* aTags) = 0;
virtual void FirstFrameLoaded(MediaInfo* aInfo) = 0;
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) = 0;
virtual void QueueMetadata(int64_t aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) = 0;
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo) = 0;
virtual void RemoveMediaTracks() = 0;
@ -154,15 +154,29 @@ public:
#endif
};
class MetadataEventRunner : public nsRunnable
class MetadataContainer
{
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
public:
MetadataEventRunner(AbstractMediaDecoder* aDecoder, MediaInfo* aInfo, MetadataTags* aTags)
: mDecoder(aDecoder),
mInfo(aInfo),
mTags(aTags)
protected:
MetadataContainer(AbstractMediaDecoder* aDecoder,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
: mDecoder(aDecoder),
mInfo(aInfo),
mTags(aTags)
{}
nsRefPtr<AbstractMediaDecoder> mDecoder;
nsAutoPtr<MediaInfo> mInfo;
nsAutoPtr<MetadataTags> mTags;
};
class MetadataEventRunner : public nsRunnable, private MetadataContainer
{
public:
MetadataEventRunner(AbstractMediaDecoder* aDecoder,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
: MetadataContainer(aDecoder, aInfo, aTags)
{}
NS_IMETHOD Run() MOZ_OVERRIDE
@ -170,22 +184,14 @@ class MetadataEventRunner : public nsRunnable
mDecoder->MetadataLoaded(mInfo, mTags);
return NS_OK;
}
// The ownership is transferred to MediaDecoder.
MediaInfo* mInfo;
// The ownership is transferred to its owning element.
MetadataTags* mTags;
};
class FirstFrameLoadedEventRunner : public nsRunnable
class FirstFrameLoadedEventRunner : public nsRunnable, private MetadataContainer
{
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
public:
FirstFrameLoadedEventRunner(AbstractMediaDecoder* aDecoder, MediaInfo* aInfo)
: mDecoder(aDecoder),
mInfo(aInfo)
public:
FirstFrameLoadedEventRunner(AbstractMediaDecoder* aDecoder,
nsAutoPtr<MediaInfo> aInfo)
: MetadataContainer(aDecoder, aInfo, nsAutoPtr<MetadataTags>(nullptr))
{}
NS_IMETHOD Run() MOZ_OVERRIDE
@ -193,36 +199,25 @@ class FirstFrameLoadedEventRunner : public nsRunnable
mDecoder->FirstFrameLoaded(mInfo);
return NS_OK;
}
// The ownership is transferred to MediaDecoder.
MediaInfo* mInfo;
};
class MetadataUpdatedEventRunner : public nsRunnable
class MetadataUpdatedEventRunner : public nsRunnable, private MetadataContainer
{
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
public:
MetadataUpdatedEventRunner(AbstractMediaDecoder* aDecoder, MediaInfo* aInfo, MetadataTags* aTags)
: mDecoder(aDecoder),
mInfo(aInfo),
mTags(aTags)
public:
MetadataUpdatedEventRunner(AbstractMediaDecoder* aDecoder,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
: MetadataContainer(aDecoder, aInfo, aTags)
{}
NS_IMETHOD Run() MOZ_OVERRIDE
{
nsAutoPtr<MediaInfo> info(new MediaInfo());
*info = *mInfo;
mDecoder->MetadataLoaded(info.forget(), mTags);
mDecoder->MetadataLoaded(info, mTags);
mDecoder->FirstFrameLoaded(mInfo);
return NS_OK;
}
// The ownership is transferred to MediaDecoder.
MediaInfo* mInfo;
// The ownership is transferred to its owning element.
MetadataTags* mTags;
};
class RemoveMediaTracksEventRunner : public nsRunnable

View File

@ -668,8 +668,8 @@ already_AddRefed<nsIPrincipal> MediaDecoder::GetCurrentPrincipal()
}
void MediaDecoder::QueueMetadata(int64_t aPublishTime,
MediaInfo* aInfo,
MetadataTags* aTags)
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
GetReentrantMonitor().AssertCurrentThreadIn();
@ -684,9 +684,11 @@ MediaDecoder::IsDataCachedToEndOfResource()
mResource->IsDataCachedToEndOfResource(mDecoderPosition));
}
void MediaDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
void MediaDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown) {
return;
}
@ -712,20 +714,21 @@ void MediaDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
SetInfinite(true);
}
mInfo = aInfo;
mInfo = aInfo.forget();
ConstructMediaTracks();
if (mOwner) {
// Make sure the element and the frame (if any) are told about
// our new size.
Invalidate();
mOwner->MetadataLoaded(aInfo, aTags);
mOwner->MetadataLoaded(mInfo, nsAutoPtr<const MetadataTags>(aTags.forget()));
}
}
void MediaDecoder::FirstFrameLoaded(MediaInfo* aInfo)
void MediaDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo)
{
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown) {
return;
}
@ -738,7 +741,7 @@ void MediaDecoder::FirstFrameLoaded(MediaInfo* aInfo)
return;
}
mInfo = aInfo;
mInfo = aInfo.forget();
if (mOwner) {
Invalidate();

View File

@ -762,8 +762,8 @@ public:
// main thread to be presented when the |currentTime| of the media is greater
// or equal to aPublishTime.
void QueueMetadata(int64_t aPublishTime,
MediaInfo* aInfo,
MetadataTags* aTags);
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags);
int64_t GetSeekTime() { return mRequestedSeekTarget.mTime; }
void ResetSeekTime() { mRequestedSeekTarget.Reset(); }
@ -788,12 +788,12 @@ public:
// Called when the metadata from the media file has been loaded by the
// state machine. Call on the main thread only.
virtual void MetadataLoaded(MediaInfo* aInfo,
MetadataTags* aTags);
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags);
// Called when the first audio and/or video from the media file has been loaded
// by the state machine. Call on the main thread only.
virtual void FirstFrameLoaded(MediaInfo* aInfo);
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo);
// Called from MetadataLoaded(). Creates audio tracks and adds them to its
// owner's audio track list, and implies to video tracks respectively.

View File

@ -51,8 +51,9 @@ public:
// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
// Must take ownership of MetadataTags aTags argument.
virtual void MetadataLoaded(const MediaInfo* aInfo,
const MetadataTags* aTags) = 0;
nsAutoPtr<const MetadataTags> aTags) = 0;
// Called by the decoder object, on the main thread,
// when it has read the first frame of the video or audio.

View File

@ -2049,7 +2049,7 @@ MediaDecoderStateMachine::EnqueueLoadedMetadataEvent()
nsAutoPtr<MediaInfo> info(new MediaInfo());
*info = mInfo;
nsCOMPtr<nsIRunnable> metadataLoadedEvent =
new MetadataEventRunner(mDecoder, info.forget(), mMetadataTags.forget());
new MetadataEventRunner(mDecoder, info, mMetadataTags);
NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL);
}
@ -2165,12 +2165,12 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
// FirstFrame event.
event =
new MetadataUpdatedEventRunner(mDecoder,
info.forget(),
mMetadataTags.forget());
info,
mMetadataTags);
} else {
// Inform the element that we've loaded the first frame.
event =
new FirstFrameLoadedEventRunner(mDecoder, info.forget());
new FirstFrameLoadedEventRunner(mDecoder, info);
}
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
@ -3249,15 +3249,15 @@ bool MediaDecoderStateMachine::IsShutdown()
}
void MediaDecoderStateMachine::QueueMetadata(int64_t aPublishTime,
MediaInfo* aInfo,
MetadataTags* aTags)
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
AssertCurrentThreadInMonitor();
TimedMetadata* metadata = new TimedMetadata;
metadata->mPublishTime = aPublishTime;
metadata->mInfo = aInfo;
metadata->mTags = aTags;
metadata->mInfo = aInfo.forget();
metadata->mTags = aTags.forget();
mMetadataManager.QueueMetadata(metadata);
}

View File

@ -336,7 +336,9 @@ public:
// shutting down. The decoder monitor must be held while calling this.
bool IsShutdown();
void QueueMetadata(int64_t aPublishTime, MediaInfo* aInfo, MetadataTags* aTags);
void QueueMetadata(int64_t aPublishTime,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags);
// Returns true if we're currently playing. The decoder monitor must
// be held.

View File

@ -53,8 +53,8 @@ namespace mozilla {
nsCOMPtr<nsIRunnable> metadataUpdatedEvent =
new MetadataUpdatedEventRunner(aDecoder,
metadata->mInfo.forget(),
metadata->mTags.forget());
metadata->mInfo,
metadata->mTags);
NS_DispatchToMainThread(metadataUpdatedEvent);
delete mMetadataQueue.popFirst();
metadata = mMetadataQueue.getFirst();

View File

@ -24,8 +24,8 @@ public:
}
virtual void FireTimeUpdate(bool aPeriodic) MOZ_OVERRIDE {}
virtual bool GetPaused() MOZ_OVERRIDE { return false; }
virtual void MetadataLoaded(const MediaInfo* aInfo, const MetadataTags* aTags)
MOZ_OVERRIDE
virtual void MetadataLoaded(const MediaInfo* aInfo,
nsAutoPtr<const MetadataTags> aTags) MOZ_OVERRIDE
{
}
virtual void NetworkError() MOZ_OVERRIDE {}

View File

@ -90,19 +90,22 @@ SourceBufferDecoder::IsMediaSeekable()
}
void
SourceBufferDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
SourceBufferDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MSE_DEBUG("SourceBufferDecoder(%p)::MetadataLoaded UNIMPLEMENTED", this);
}
void
SourceBufferDecoder::FirstFrameLoaded(MediaInfo* aInfo)
SourceBufferDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo)
{
MSE_DEBUG("SourceBufferDecoder(%p)::FirstFrameLoaded UNIMPLEMENTED", this);
}
void
SourceBufferDecoder::QueueMetadata(int64_t aTime, MediaInfo* aInfo, MetadataTags* aTags)
SourceBufferDecoder::QueueMetadata(int64_t aTime,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MSE_DEBUG("SourceBufferDecoder(%p)::QueueMetadata UNIMPLEMENTED", this);
}

View File

@ -47,14 +47,14 @@ public:
virtual SourceBufferResource* GetResource() const MOZ_FINAL MOZ_OVERRIDE;
virtual ReentrantMonitor& GetReentrantMonitor() MOZ_FINAL MOZ_OVERRIDE;
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
virtual void MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void FirstFrameLoaded(MediaInfo* aInfo) MOZ_FINAL MOZ_OVERRIDE;
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
virtual void NotifyWaitingForResourcesStatusChanged() MOZ_FINAL MOZ_OVERRIDE;
virtual void OnReadMetadataCompleted() MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, MediaInfo* aInfo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void RemoveMediaTracks() MOZ_FINAL MOZ_OVERRIDE;
virtual void SetMediaDuration(int64_t aDuration) MOZ_FINAL MOZ_OVERRIDE;
virtual void SetMediaEndTime(int64_t aTime) MOZ_FINAL MOZ_OVERRIDE;

View File

@ -753,7 +753,7 @@ bool OggReader::ReadOggChain()
OpusState* newOpusState = nullptr;
#endif /* MOZ_OPUS */
VorbisState* newVorbisState = nullptr;
MetadataTags* tags = nullptr;
nsAutoPtr<MetadataTags> tags;
if (HasVideo() || HasSkeleton() || !HasAudio()) {
return false;
@ -846,7 +846,7 @@ bool OggReader::ReadOggChain()
*info = mInfo;
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->QueueMetadata((mDecodedAudioFrames * USECS_PER_S) / mInfo.mAudio.mRate,
info.forget(), tags);
info, tags);
}
return true;
}

View File

@ -57,7 +57,7 @@ MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
}
void
MediaOmxCommonDecoder::FirstFrameLoaded(MediaInfo* aInfo)
MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo)
{
MOZ_ASSERT(NS_IsMainThread());
MediaDecoder::FirstFrameLoaded(aInfo);

View File

@ -23,7 +23,7 @@ class MediaOmxCommonDecoder : public MediaDecoder
public:
MediaOmxCommonDecoder();
virtual void FirstFrameLoaded(MediaInfo* aInfo);
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo);
virtual void ChangeState(PlayState aState);
virtual void ApplyStateToStateMachine(PlayState aState);
virtual void SetVolume(double aVolume);

View File

@ -140,19 +140,19 @@ BufferDecoder::IsMediaSeekable()
}
void
BufferDecoder::MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags)
BufferDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags)
{
// ignore
}
void
BufferDecoder::FirstFrameLoaded(MediaInfo* aInfo)
BufferDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo)
{
// ignore
}
void
BufferDecoder::QueueMetadata(int64_t aTime, MediaInfo* aInfo, MetadataTags* aTags)
BufferDecoder::QueueMetadata(int64_t aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags)
{
// ignore
}

View File

@ -58,9 +58,9 @@ public:
virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE;
virtual void MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, MediaInfo* aInfo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void FirstFrameLoaded(MediaInfo* aInfo) MOZ_FINAL MOZ_OVERRIDE;
virtual void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void QueueMetadata(int64_t aTime, nsAutoPtr<MediaInfo> aInfo, nsAutoPtr<MetadataTags> aTags) MOZ_FINAL MOZ_OVERRIDE;
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo) MOZ_FINAL MOZ_OVERRIDE;
virtual void RemoveMediaTracks() MOZ_FINAL MOZ_OVERRIDE;