Skip to content

Commit

Permalink
Bug 962154 - Use MallocSizeOf to report decoded-video memory. r=cpear…
Browse files Browse the repository at this point in the history
…ce,njn
  • Loading branch information
EricRahm committed Mar 19, 2014
1 parent e2451db commit 1d7253b
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 50 deletions.
16 changes: 16 additions & 0 deletions content/media/MediaData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions content/media/MediaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ class VideoData : public MediaData {

~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.
Expand Down
6 changes: 3 additions & 3 deletions content/media/MediaDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion content/media/MediaDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ class MediaDecoder : public nsIObserver,

// 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
Expand Down
48 changes: 40 additions & 8 deletions content/media/MediaDecoderReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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;
Expand Down
40 changes: 6 additions & 34 deletions content/media/MediaDecoderReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,41 +132,13 @@ class MediaDecoderReader {
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.
Expand Down
6 changes: 3 additions & 3 deletions content/media/MediaDecoderStateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,16 @@ class MediaDecoderStateMachine : public nsRunnable
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;
}
Expand Down
16 changes: 15 additions & 1 deletion content/media/gtest/TestAudioCompactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions gfx/layers/ImageContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
6 changes: 6 additions & 0 deletions gfx/layers/ImageContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,12 @@ class PlanarYCbCrImage : public Image {
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.
Expand Down
12 changes: 12 additions & 0 deletions gfx/layers/basic/BasicImages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ class BasicPlanarYCbCrImage : public PlanarYCbCrImage
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;
Expand Down
11 changes: 11 additions & 0 deletions gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
7 changes: 7 additions & 0 deletions gfx/layers/ipc/SharedPlanarYCbCrImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ class SharedPlanarYCbCrImage : public PlanarYCbCrImage

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;
Expand Down

0 comments on commit 1d7253b

Please sign in to comment.