Bug 962154 - Use MallocSizeOf to report decoded-video memory. r=cpearce,njn

This commit is contained in:
Eric Rahm 2014-03-19 14:33:12 -07:00
parent 242dcf017a
commit 4c96c88496
13 changed files with 142 additions and 50 deletions

View File

@ -89,6 +89,22 @@ VideoData::~VideoData()
MOZ_COUNT_DTOR(VideoData);
}
size_t
VideoData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t size = aMallocSizeOf(this);
// Currently only PLANAR_YCBCR has a well defined function for determining
// it's size, so reporting is limited to that type.
if (mImage && mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
const mozilla::layers::PlanarYCbCrImage* img =
static_cast<const mozilla::layers::PlanarYCbCrImage*>(mImage.get());
size += img->SizeOfIncludingThis(aMallocSizeOf);
}
return size;
}
/* static */
VideoData* VideoData::ShallowCopyUpdateDuration(VideoData* aOther,
int64_t aDuration)

View File

@ -225,6 +225,8 @@ public:
~VideoData();
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
// Dimensions at which to display the video frame. The picture region
// will be scaled to this size. This is should be the picture region's
// dimensions scaled with respect to its aspect ratio.

View File

@ -1564,9 +1564,9 @@ nsresult MediaDecoder::GetBuffered(dom::TimeRanges* aBuffered) {
return NS_ERROR_FAILURE;
}
int64_t MediaDecoder::VideoQueueMemoryInUse() {
size_t MediaDecoder::SizeOfVideoQueue() {
if (mDecoderStateMachine) {
return mDecoderStateMachine->VideoQueueMemoryInUse();
return mDecoderStateMachine->SizeOfVideoQueue();
}
return 0;
}
@ -1836,7 +1836,7 @@ MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
DecodersArray& decoders = Decoders();
for (size_t i = 0; i < decoders.Length(); ++i) {
MediaDecoder* decoder = decoders[i];
video += decoder->VideoQueueMemoryInUse();
video += decoder->SizeOfVideoQueue();
audio += decoder->SizeOfAudioQueue();
if (decoder->GetResource()) {

View File

@ -646,7 +646,7 @@ public:
// Returns the size, in bytes, of the heap memory used by the currently
// queued decoded video and audio data.
virtual int64_t VideoQueueMemoryInUse();
size_t SizeOfVideoQueue();
size_t SizeOfAudioQueue();
VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE

View File

@ -31,18 +31,36 @@ extern PRLogModuleInfo* gMediaDecoderLog;
#define SEEK_LOG(type, msg)
#endif
void* MediaDecoderReader::VideoQueueMemoryFunctor::operator()(void* anObject) {
const VideoData* v = static_cast<const VideoData*>(anObject);
if (!v->mImage) {
class VideoQueueMemoryFunctor : public nsDequeFunctor {
public:
VideoQueueMemoryFunctor() : mSize(0) {}
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
virtual void* operator()(void* aObject) {
const VideoData* v = static_cast<const VideoData*>(aObject);
mSize += v->SizeOfIncludingThis(MallocSizeOf);
return nullptr;
}
if (v->mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
mozilla::layers::PlanarYCbCrImage* vi = static_cast<mozilla::layers::PlanarYCbCrImage*>(v->mImage.get());
mResult += vi->GetDataSize();
size_t mSize;
};
class AudioQueueMemoryFunctor : public nsDequeFunctor {
public:
AudioQueueMemoryFunctor() : mSize(0) {}
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
virtual void* operator()(void* aObject) {
const AudioData* audioData = static_cast<const AudioData*>(aObject);
mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
return nullptr;
}
return nullptr;
}
size_t mSize;
};
MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
: mAudioCompactor(mAudioQueue),
@ -58,6 +76,20 @@ MediaDecoderReader::~MediaDecoderReader()
MOZ_COUNT_DTOR(MediaDecoderReader);
}
size_t MediaDecoderReader::SizeOfVideoQueueInBytes() const
{
VideoQueueMemoryFunctor functor;
mVideoQueue.LockedForEach(functor);
return functor.mSize;
}
size_t MediaDecoderReader::SizeOfAudioQueueInBytes() const
{
AudioQueueMemoryFunctor functor;
mAudioQueue.LockedForEach(functor);
return functor.mSize;
}
nsresult MediaDecoderReader::ResetDecode()
{
nsresult res = NS_OK;

View File

@ -132,41 +132,13 @@ public:
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered,
int64_t aStartTime);
class VideoQueueMemoryFunctor : public nsDequeFunctor {
public:
VideoQueueMemoryFunctor() : mResult(0) {}
// Returns the number of bytes of memory allocated by structures/frames in
// the video queue.
size_t SizeOfVideoQueueInBytes() const;
virtual void* operator()(void* anObject);
int64_t mResult;
};
virtual int64_t VideoQueueMemoryInUse() {
VideoQueueMemoryFunctor functor;
mVideoQueue.LockedForEach(functor);
return functor.mResult;
}
class AudioQueueMemoryFunctor : public nsDequeFunctor {
public:
AudioQueueMemoryFunctor() : mSize(0) {}
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
virtual void* operator()(void* anObject) {
const AudioData* audioData = static_cast<const AudioData*>(anObject);
mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
return nullptr;
}
size_t mSize;
};
size_t SizeOfAudioQueue() {
AudioQueueMemoryFunctor functor;
mAudioQueue.LockedForEach(functor);
return functor.mSize;
}
// Returns the number of bytes of memory allocated by structures/frames in
// the audio queue.
size_t SizeOfAudioQueueInBytes() const;
// Only used by WebMReader and MediaOmxReader for now, so stub here rather
// than in every reader than inherits from MediaDecoderReader.

View File

@ -266,16 +266,16 @@ public:
void SetPlaybackRate(double aPlaybackRate);
void SetPreservesPitch(bool aPreservesPitch);
int64_t VideoQueueMemoryInUse() {
size_t SizeOfVideoQueue() {
if (mReader) {
return mReader->VideoQueueMemoryInUse();
return mReader->SizeOfVideoQueueInBytes();
}
return 0;
}
size_t SizeOfAudioQueue() {
if (mReader) {
return mReader->SizeOfAudioQueue();
return mReader->SizeOfAudioQueueInBytes();
}
return 0;
}

View File

@ -13,6 +13,20 @@ using mozilla::AudioDataValue;
using mozilla::MediaDecoderReader;
using mozilla::MediaQueue;
class MemoryFunctor : public nsDequeFunctor {
public:
MemoryFunctor() : mSize(0) {}
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
virtual void* operator()(void* anObject) {
const AudioData* audioData = static_cast<const AudioData*>(anObject);
mSize += audioData->SizeOfIncludingThis(MallocSizeOf);
return nullptr;
}
size_t mSize;
};
class TestCopy
{
public:
@ -60,7 +74,7 @@ static void TestAudioCompactor(size_t aBytes)
EXPECT_GT(callCount, 0U) << "copy functor never called";
EXPECT_EQ(frames, frameCount) << "incorrect number of frames copied";
MediaDecoderReader::AudioQueueMemoryFunctor memoryFunc;
MemoryFunctor memoryFunc;
queue.LockedForEach(memoryFunc);
size_t allocSize = memoryFunc.mSize - (callCount * sizeof(AudioData));
size_t slop = allocSize - aBytes;

View File

@ -472,6 +472,26 @@ PlanarYCbCrImage::~PlanarYCbCrImage()
}
}
size_t
PlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
// Ignoring:
// - mData - just wraps mBuffer
// - Surfaces should be reported under gfx-surfaces-*:
// - mDeprecatedSurface
// - mSourceSurface
// - Base class:
// - mImplData is not used
// Not owned:
// - mRecycleBin
size_t size = mBuffer.SizeOfExcludingThis(aMallocSizeOf);
// Could add in the future:
// - mBackendData (from base class)
return size;
}
uint8_t*
PlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
{

View File

@ -863,6 +863,12 @@ public:
virtual SharedPlanarYCbCrImage *AsSharedPlanarYCbCrImage() { return nullptr; }
virtual DeprecatedSharedPlanarYCbCrImage *AsDeprecatedSharedPlanarYCbCrImage() { return nullptr; }
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
protected:
/**
* Make a copy of the YCbCr data into local storage.

View File

@ -55,6 +55,18 @@ public:
already_AddRefed<gfxASurface> DeprecatedGetAsSurface();
TemporaryRef<gfx::SourceSurface> GetAsSourceSurface();
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
size_t size = PlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
size += mDecodedBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
private:
nsAutoArrayPtr<uint8_t> mDecodedBuffer;
gfx::IntSize mScaleHint;

View File

@ -62,6 +62,17 @@ DeprecatedSharedPlanarYCbCrImage::~DeprecatedSharedPlanarYCbCrImage() {
}
}
size_t
SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
// NB: Explicitly skipping mTextureClient, the memory is already reported
// at time of allocation in GfxMemoryImageReporter.
// Not owned:
// - mCompositable
size_t size = PlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
return size;
}
TextureClient*
SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient)
{

View File

@ -113,6 +113,13 @@ public:
virtual bool IsValid() MOZ_OVERRIDE;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
private:
RefPtr<BufferTextureClient> mTextureClient;
RefPtr<ImageClient> mCompositable;