зеркало из https://github.com/mozilla/gecko-dev.git
Bug 672755 - Add memory reporters for decoded video and audio queues. r=cpearce r=joe
This commit is contained in:
Родитель
dae69287ef
Коммит
2f39e6408b
|
@ -327,6 +327,9 @@ public:
|
|||
|
||||
virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
|
||||
|
||||
virtual PRInt64 VideoQueueMemoryInUse() = 0;
|
||||
virtual PRInt64 AudioQueueMemoryInUse() = 0;
|
||||
|
||||
virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) = 0;
|
||||
|
||||
// Causes the state machine to switch to buffering state, and to
|
||||
|
@ -471,6 +474,20 @@ class nsBuiltinDecoder : public nsMediaDecoder
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
virtual PRInt64 VideoQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->VideoQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual PRInt64 AudioQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->AudioQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
|
||||
return mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ using namespace mozilla;
|
|||
using mozilla::layers::ImageContainer;
|
||||
using mozilla::layers::PlanarYCbCrImage;
|
||||
|
||||
using mozilla::layers::PlanarYCbCrImage;
|
||||
|
||||
// Verify these values are sane. Once we've checked the frame sizes, we then
|
||||
// can do less integer overflow checking.
|
||||
PR_STATIC_ASSERT(MAX_VIDEO_WIDTH < PlanarYCbCrImage::MAX_DIMENSION);
|
||||
|
|
|
@ -390,8 +390,13 @@ template <class T> class MediaQueue : private nsDeque {
|
|||
return last->mTime - first->mTime;
|
||||
}
|
||||
|
||||
void LockedForEach(nsDequeFunctor& aFunctor) const {
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
ForEach(aFunctor);
|
||||
}
|
||||
|
||||
private:
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
mutable ReentrantMonitor mReentrantMonitor;
|
||||
|
||||
// PR_TRUE when we've decoded the last frame of data in the
|
||||
// bitstream for which we're queueing sample-data.
|
||||
|
@ -465,6 +470,48 @@ public:
|
|||
virtual nsresult GetBuffered(nsTimeRanges* aBuffered,
|
||||
PRInt64 aStartTime) = 0;
|
||||
|
||||
class VideoQueueMemoryFunctor : public nsDequeFunctor {
|
||||
public:
|
||||
VideoQueueMemoryFunctor() : mResult(0) {}
|
||||
|
||||
virtual void* operator()(void* anObject) {
|
||||
const VideoData* v = static_cast<const VideoData*>(anObject);
|
||||
NS_ASSERTION(v->mImage->GetFormat() == mozilla::layers::Image::PLANAR_YCBCR,
|
||||
"Wrong format?");
|
||||
mozilla::layers::PlanarYCbCrImage* vi = static_cast<mozilla::layers::PlanarYCbCrImage*>(v->mImage.get());
|
||||
|
||||
mResult += vi->GetDataSize();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt64 mResult;
|
||||
};
|
||||
|
||||
PRInt64 VideoQueueMemoryInUse() {
|
||||
VideoQueueMemoryFunctor functor;
|
||||
mVideoQueue.LockedForEach(functor);
|
||||
return functor.mResult;
|
||||
}
|
||||
|
||||
class AudioQueueMemoryFunctor : public nsDequeFunctor {
|
||||
public:
|
||||
AudioQueueMemoryFunctor() : mResult(0) {}
|
||||
|
||||
virtual void* operator()(void* anObject) {
|
||||
const SoundData* soundData = static_cast<const SoundData*>(anObject);
|
||||
mResult += soundData->mSamples * soundData->mChannels * sizeof(SoundDataValue);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt64 mResult;
|
||||
};
|
||||
|
||||
PRInt64 AudioQueueMemoryInUse() {
|
||||
AudioQueueMemoryFunctor functor;
|
||||
mAudioQueue.LockedForEach(functor);
|
||||
return functor.mResult;
|
||||
}
|
||||
|
||||
// Only used by nsWebMReader for now, so stub here rather than in every
|
||||
// reader than inherits from nsBuiltinDecoderReader.
|
||||
virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {}
|
||||
|
|
|
@ -228,6 +228,20 @@ public:
|
|||
|
||||
nsresult GetBuffered(nsTimeRanges* aBuffered);
|
||||
|
||||
PRInt64 VideoQueueMemoryInUse() {
|
||||
if (mReader) {
|
||||
return mReader->VideoQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt64 AudioQueueMemoryInUse() {
|
||||
if (mReader) {
|
||||
return mReader->AudioQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
mReader->NotifyDataArrived(aBuffer, aLength, aOffset);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsDOMError.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -81,11 +82,13 @@ nsMediaDecoder::nsMediaDecoder() :
|
|||
mShuttingDown(PR_FALSE)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsMediaDecoder);
|
||||
MediaMemoryReporter::AddMediaDecoder(this);
|
||||
}
|
||||
|
||||
nsMediaDecoder::~nsMediaDecoder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsMediaDecoder);
|
||||
MediaMemoryReporter::RemoveMediaDecoder(this);
|
||||
}
|
||||
|
||||
PRBool nsMediaDecoder::Init(nsHTMLMediaElement* aElement)
|
||||
|
@ -305,3 +308,37 @@ PRBool nsMediaDecoder::CanPlayThrough()
|
|||
return stats.mTotalBytes == stats.mDownloadPosition ||
|
||||
stats.mDownloadPosition > stats.mPlaybackPosition + readAheadMargin;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MediaMemoryReporter* MediaMemoryReporter::sUniqueInstance;
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedVideoMemory,
|
||||
"explicit/media/decoded-video",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
MediaMemoryReporter::GetDecodedVideoMemory,
|
||||
"Memory used by decoded video frames.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedAudioMemory,
|
||||
"explicit/media/decoded-audio",
|
||||
KIND_HEAP,
|
||||
UNITS_BYTES,
|
||||
MediaMemoryReporter::GetDecodedAudioMemory,
|
||||
"Memory used by decoded audio chunks.")
|
||||
|
||||
MediaMemoryReporter::MediaMemoryReporter()
|
||||
: mMediaDecodedVideoMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedVideoMemory))
|
||||
, mMediaDecodedAudioMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedAudioMemory))
|
||||
{
|
||||
NS_RegisterMemoryReporter(mMediaDecodedVideoMemory);
|
||||
NS_RegisterMemoryReporter(mMediaDecodedAudioMemory);
|
||||
}
|
||||
|
||||
MediaMemoryReporter::~MediaMemoryReporter()
|
||||
{
|
||||
NS_UnregisterMemoryReporter(mMediaDecodedVideoMemory);
|
||||
NS_UnregisterMemoryReporter(mMediaDecodedAudioMemory);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "ImageLayers.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
class nsHTMLMediaElement;
|
||||
class nsMediaStream;
|
||||
|
@ -369,6 +370,11 @@ public:
|
|||
// to buffer, given the current download and playback rates.
|
||||
PRBool CanPlayThrough();
|
||||
|
||||
// Returns the size, in bytes, of the heap memory used by the currently
|
||||
// queued decoded video and audio data.
|
||||
virtual PRInt64 VideoQueueMemoryInUse() = 0;
|
||||
virtual PRInt64 AudioQueueMemoryInUse() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
// Start timer to update download progress information.
|
||||
|
@ -458,4 +464,62 @@ protected:
|
|||
PRPackedBool mShuttingDown;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
class MediaMemoryReporter
|
||||
{
|
||||
MediaMemoryReporter();
|
||||
~MediaMemoryReporter();
|
||||
static MediaMemoryReporter* sUniqueInstance;
|
||||
|
||||
static MediaMemoryReporter* UniqueInstance() {
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new MediaMemoryReporter;
|
||||
}
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
typedef nsTArray<nsMediaDecoder*> DecodersArray;
|
||||
static DecodersArray& Decoders() {
|
||||
return UniqueInstance()->mDecoders;
|
||||
}
|
||||
|
||||
DecodersArray mDecoders;
|
||||
|
||||
nsCOMPtr<nsIMemoryReporter> mMediaDecodedVideoMemory;
|
||||
nsCOMPtr<nsIMemoryReporter> mMediaDecodedAudioMemory;
|
||||
|
||||
public:
|
||||
static void AddMediaDecoder(nsMediaDecoder* aDecoder) {
|
||||
Decoders().AppendElement(aDecoder);
|
||||
}
|
||||
|
||||
static void RemoveMediaDecoder(nsMediaDecoder* aDecoder) {
|
||||
DecodersArray& decoders = Decoders();
|
||||
decoders.RemoveElement(aDecoder);
|
||||
if (decoders.IsEmpty()) {
|
||||
delete sUniqueInstance;
|
||||
sUniqueInstance = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static PRInt64 GetDecodedVideoMemory() {
|
||||
DecodersArray& decoders = Decoders();
|
||||
PRInt64 result = 0;
|
||||
for (size_t i = 0; i < decoders.Length(); ++i) {
|
||||
result += decoders[i]->VideoQueueMemoryInUse();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetDecodedAudioMemory() {
|
||||
DecodersArray& decoders = Decoders();
|
||||
PRInt64 result = 0;
|
||||
for (size_t i = 0; i < decoders.Length(); ++i) {
|
||||
result += decoders[i]->AudioQueueMemoryInUse();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace mozilla
|
||||
#endif
|
||||
|
|
|
@ -454,6 +454,11 @@ public:
|
|||
|
||||
virtual PRUint8* AllocateBuffer(PRUint32 aSize);
|
||||
|
||||
/**
|
||||
* Return the number of bytes of heap memory used to store this image.
|
||||
*/
|
||||
virtual PRUint32 GetDataSize() = 0;
|
||||
|
||||
protected:
|
||||
PlanarYCbCrImage(void* aImplData) : Image(aImplData, PLANAR_YCBCR) {}
|
||||
};
|
||||
|
|
|
@ -129,6 +129,8 @@ public:
|
|||
void SetOffscreenFormat(gfxImageFormat aFormat) { mOffscreenFormat = aFormat; }
|
||||
gfxImageFormat GetOffscreenFormat() { return mOffscreenFormat; }
|
||||
|
||||
PRUint32 GetDataSize() { return mBuffer ? mDelayedConversion ? mBufferSize : mSize.height * mStride : 0; }
|
||||
|
||||
protected:
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
nsCountedRef<nsMainThreadSurfaceRef> mSurface;
|
||||
|
|
|
@ -371,6 +371,7 @@ ImageLayerD3D10::RenderLayer()
|
|||
|
||||
PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(ID3D10Device1 *aDevice)
|
||||
: PlanarYCbCrImage(static_cast<ImageD3D10*>(this))
|
||||
, mBufferSize(0)
|
||||
, mDevice(aDevice)
|
||||
, mHasData(PR_FALSE)
|
||||
{
|
||||
|
@ -379,8 +380,7 @@ PlanarYCbCrImageD3D10::PlanarYCbCrImageD3D10(ID3D10Device1 *aDevice)
|
|||
void
|
||||
PlanarYCbCrImageD3D10::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
PRUint32 dummy;
|
||||
mBuffer = CopyData(mData, mSize, dummy, aData);
|
||||
mBuffer = CopyData(mData, mSize, mBufferSize, aData);
|
||||
|
||||
AllocateTextures();
|
||||
|
||||
|
|
|
@ -114,9 +114,12 @@ public:
|
|||
|
||||
PRBool HasData() { return mHasData; }
|
||||
|
||||
PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
PRUint32 mBufferSize;
|
||||
nsRefPtr<ID3D10Device1> mDevice;
|
||||
Data mData;
|
||||
gfxIntSize mSize;
|
||||
|
|
|
@ -397,6 +397,7 @@ ImageLayerD3D9::RenderLayer()
|
|||
|
||||
PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9()
|
||||
: PlanarYCbCrImage(static_cast<ImageD3D9*>(this))
|
||||
, mBufferSize(0)
|
||||
, mHasData(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
@ -404,8 +405,7 @@ PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9()
|
|||
void
|
||||
PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
PRUint32 dummy;
|
||||
mBuffer = CopyData(mData, mSize, dummy, aData);
|
||||
mBuffer = CopyData(mData, mSize, mBufferSize, aData);
|
||||
|
||||
mHasData = PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -124,9 +124,12 @@ public:
|
|||
void FreeTextures();
|
||||
PRBool HasData() { return mHasData; }
|
||||
|
||||
PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
PRUint32 mBufferSize;
|
||||
LayerManagerD3D9 *mManager;
|
||||
Data mData;
|
||||
gfxIntSize mSize;
|
||||
|
|
|
@ -211,6 +211,8 @@ public:
|
|||
return mRecycleBin->GetBuffer(aSize);
|
||||
}
|
||||
|
||||
PRUint32 GetDataSize() { return mBuffer ? mBufferSize : 0; }
|
||||
|
||||
nsAutoArrayPtr<PRUint8> mBuffer;
|
||||
PRUint32 mBufferSize;
|
||||
nsRefPtr<RecycleBin> mRecycleBin;
|
||||
|
|
Загрузка…
Ссылка в новой задаче