Bug 1190592 - Part 1: Add mediasource memory reporter. r=jya

This adds asyncrounous reporting of MSE resources.
This commit is contained in:
Eric Rahm 2015-08-20 18:10:33 -04:00
Родитель dffd99184c
Коммит 88d7e6c28e
8 изменённых файлов: 124 добавлений и 10 удалений

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

@ -1307,6 +1307,13 @@ MediaDecoder::SizeOfAudioQueue() {
return 0;
}
void MediaDecoder::AddSizeOfResources(ResourceSizes* aSizes) {
MOZ_ASSERT(NS_IsMainThread());
if (GetResource()) {
aSizes->mByteSize += GetResource()->SizeOfIncludingThis(aSizes->mMallocSizeOf);
}
}
void
MediaDecoder::NotifyDataArrived(uint32_t aLength,
int64_t aOffset,
@ -1503,16 +1510,40 @@ MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
{
int64_t video = 0, audio = 0;
size_t resources = 0;
// NB: When resourceSizes' ref count goes to 0 the promise will report the
// resources memory and finish the asynchronous memory report.
nsRefPtr<MediaDecoder::ResourceSizes> resourceSizes =
new MediaDecoder::ResourceSizes(MediaMemoryTracker::MallocSizeOf);
nsCOMPtr<nsIHandleReportCallback> handleReport = aHandleReport;
nsCOMPtr<nsISupports> data = aData;
resourceSizes->Promise()->Then(
AbstractThread::MainThread(), __func__,
[handleReport, data] (size_t size) {
handleReport->Callback(
EmptyCString(), NS_LITERAL_CSTRING("explicit/media/resources"),
KIND_HEAP, UNITS_BYTES, size,
NS_LITERAL_CSTRING("Memory used by media resources including "
"streaming buffers, caches, etc."),
data);
nsCOMPtr<nsIMemoryReporterManager> imgr =
do_GetService("@mozilla.org/memory-reporter-manager;1");
if (imgr) {
imgr->EndReport();
}
},
[] (size_t) { /* unused reject function */ });
DecodersArray& decoders = Decoders();
for (size_t i = 0; i < decoders.Length(); ++i) {
MediaDecoder* decoder = decoders[i];
video += decoder->SizeOfVideoQueue();
audio += decoder->SizeOfAudioQueue();
if (decoder->GetResource()) {
resources += decoder->GetResource()->SizeOfIncludingThis(MallocSizeOf);
}
decoder->AddSizeOfResources(resourceSizes);
}
#define REPORT(_path, _amount, _desc) \
@ -1530,10 +1561,6 @@ MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
REPORT("explicit/media/decoded/audio", audio,
"Memory used by decoded audio chunks.");
REPORT("explicit/media/resources", resources,
"Memory used by media resources including streaming buffers, caches, "
"etc.");
#undef REPORT
return NS_OK;
@ -1620,7 +1647,7 @@ MediaMemoryTracker::MediaMemoryTracker()
void
MediaMemoryTracker::InitMemoryReporter()
{
RegisterWeakMemoryReporter(this);
RegisterWeakAsyncMemoryReporter(this);
}
MediaMemoryTracker::~MediaMemoryTracker()

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

@ -188,6 +188,7 @@ destroying the MediaDecoder object.
#include "mozilla/CDMProxy.h"
#endif
#include "mozilla/Atomics.h"
#include "mozilla/MozPromise.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/StateMirroring.h"
@ -530,6 +531,39 @@ public:
size_t SizeOfVideoQueue();
size_t SizeOfAudioQueue();
// Helper struct for accumulating resource sizes that need to be measured
// asynchronously. Once all references are dropped the callback will be
// invoked.
struct ResourceSizes
{
typedef MozPromise<size_t, size_t, true> SizeOfPromise;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResourceSizes)
explicit ResourceSizes(MallocSizeOf aMallocSizeOf)
: mMallocSizeOf(aMallocSizeOf)
, mByteSize(0)
, mCallback()
{
}
mozilla::MallocSizeOf mMallocSizeOf;
mozilla::Atomic<size_t> mByteSize;
nsRefPtr<SizeOfPromise> Promise()
{
return mCallback.Ensure(__func__);
}
private:
~ResourceSizes()
{
mCallback.ResolveIfExists(mByteSize, __func__);
}
MozPromiseHolder<SizeOfPromise> mCallback;
};
virtual void AddSizeOfResources(ResourceSizes* aSizes);
VideoFrameContainer* GetVideoFrameContainer() final override
{
return mVideoFrameContainer;

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

@ -176,6 +176,15 @@ MediaSourceDecoder::Ended(bool aEnded)
mEnded = true;
}
void
MediaSourceDecoder::AddSizeOfResources(ResourceSizes* aSizes)
{
MOZ_ASSERT(NS_IsMainThread());
if (GetDemuxer()) {
GetDemuxer()->AddSizeOfResources(aSizes);
}
}
void
MediaSourceDecoder::SetInitialDuration(int64_t aDuration)
{

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

@ -75,6 +75,8 @@ public:
// buffered data. Used for debugging purposes.
void GetMozDebugReaderData(nsAString& aString);
void AddSizeOfResources(ResourceSizes* aSizes) override;
private:
void DoSetMediaSourceDuration(double aDuration);

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

@ -53,6 +53,24 @@ MediaSourceDemuxer::AttemptInit()
return p;
}
void
MediaSourceDemuxer::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
{
MOZ_ASSERT(NS_IsMainThread());
// NB: The track buffers must only be accessed on the TaskQueue.
nsRefPtr<MediaSourceDemuxer> self = this;
nsRefPtr<MediaSourceDecoder::ResourceSizes> sizes = aSizes;
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction([self, sizes] () {
for (TrackBuffersManager* manager : self->mSourceBuffers) {
manager->AddSizeOfResources(sizes);
}
});
GetTaskQueue()->Dispatch(task.forget());
}
void MediaSourceDemuxer::NotifyDataArrived()
{
nsRefPtr<MediaSourceDemuxer> self = this;

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

@ -53,6 +53,8 @@ public:
// buffered data. Used for debugging purposes.
void GetMozDebugReaderData(nsAString& aString);
void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes);
private:
~MediaSourceDemuxer();
friend class MediaSourceTrackDemuxer;

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

@ -2123,6 +2123,24 @@ TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack)
return media::TimeUnit::FromInfinity();
}
void
TrackBuffersManager::TrackData::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
{
for (TrackBuffer& buffer : mBuffers) {
for (MediaRawData* data : buffer) {
aSizes->mByteSize += data->SizeOfIncludingThis(aSizes->mMallocSizeOf);
}
}
}
void
TrackBuffersManager::AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes)
{
MOZ_ASSERT(OnTaskQueue());
mVideoTracks.AddSizeOfResources(aSizes);
mAudioTracks.AddSizeOfResources(aSizes);
}
} // namespace mozilla
#undef MSE_DEBUG
#undef MSE_DEBUGV

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

@ -102,6 +102,8 @@ public:
void Dump(const char* aPath) override;
#endif
void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes);
private:
// for MediaSourceDemuxer::GetMozDebugReaderData
friend class MediaSourceDemuxer;
@ -281,6 +283,8 @@ private:
mLongestFrameDuration.reset();
mNextInsertionIndex.reset();
}
void AddSizeOfResources(MediaSourceDecoder::ResourceSizes* aSizes);
};
void CheckSequenceDiscontinuity(const media::TimeUnit& aPresentationTime);