summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/base/nsTextFragment.cpp40
-rw-r--r--dom/cache/DBAction.cpp3
-rw-r--r--dom/cache/Manager.cpp36
-rw-r--r--dom/canvas/CanvasImageCache.cpp62
-rw-r--r--dom/canvas/CanvasImageCache.h15
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp7
-rw-r--r--dom/media/MediaInfo.h27
-rw-r--r--dom/media/gmp/GMPVideoDecoderChild.cpp55
-rw-r--r--dom/media/gmp/GMPVideoDecoderChild.h1
-rw-r--r--dom/media/gmp/GMPVideoEncoderChild.cpp43
-rw-r--r--dom/media/gmp/GMPVideoEncoderChild.h1
11 files changed, 218 insertions, 72 deletions
diff --git a/dom/base/nsTextFragment.cpp b/dom/base/nsTextFragment.cpp
index 5cba2577b8..c3f3d388be 100644
--- a/dom/base/nsTextFragment.cpp
+++ b/dom/base/nsTextFragment.cpp
@@ -198,23 +198,22 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
}
if (aForce2b && mState.mIs2b && !m2b->IsReadonly()) {
+ // Try to re-use our existing StringBuffer.
uint32_t storageSize = m2b->StorageSize();
uint32_t neededSize = aLength * sizeof(char16_t);
if (!neededSize) {
if (storageSize < AutoStringDefaultStorageSize) {
// If we're storing small enough nsStringBuffer, let's preserve it.
-
static_cast<char16_t*>(m2b->Data())[0] = char16_t(0);
mState.mLength = 0;
mState.mIsBidi = false;
return true;
}
- } else if ((neededSize < storageSize) &&
- ((storageSize / 2) <
- (neededSize + AutoStringDefaultStorageSize))) {
- // Don't try to reuse the existing nsStringBuffer, if it would have
- // lots of unused space.
-
+ } else if (neededSize < storageSize &&
+ (storageSize / 2) <
+ (neededSize + AutoStringDefaultStorageSize)) {
+ // Don't try to reuse the existing nsStringBuffer, if it would have lots
+ // of unused space.
memcpy(m2b->Data(), aBuffer, neededSize);
static_cast<char16_t*>(m2b->Data())[aLength] = char16_t(0);
mState.mLength = aLength;
@@ -226,19 +225,18 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
}
}
- ReleaseText();
-
if (aLength == 0) {
+ ReleaseText();
return true;
}
char16_t firstChar = *aBuffer;
if (!aForce2b && aLength == 1 && firstChar < 256) {
+ ReleaseText();
m1b = sSingleCharSharedString + firstChar;
mState.mInHeap = false;
mState.mIs2b = false;
mState.mLength = 1;
-
return true;
}
@@ -266,6 +264,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
if (ucp == uend && endNewLine - start <= TEXTFRAG_MAX_NEWLINES &&
ucp - endNewLine <= TEXTFRAG_WHITE_AFTER_NEWLINE) {
+ ReleaseText();
char** strings = space == ' ' ? sSpaceSharedString : sTabSharedString;
m1b = strings[endNewLine - start];
@@ -287,27 +286,29 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
if (first16bit != -1) { // aBuffer contains no non-8bit character
// Use ucs2 storage because we have to
- CheckedUint32 m2bSize = CheckedUint32(aLength) + 1;
- if (!m2bSize.isValid()) {
+ CheckedUint32 size = CheckedUint32(aLength) + 1;
+ if (!size.isValid()) {
return false;
}
- m2bSize *= sizeof(char16_t);
- if (!m2bSize.isValid()) {
+ size *= sizeof(char16_t);
+ if (!size.isValid()) {
return false;
}
- m2b = nsStringBuffer::Alloc(m2bSize.value()).take();
- if (!m2b) {
+ RefPtr<nsStringBuffer> newBuffer = nsStringBuffer::Alloc(size.value());
+ if (!newBuffer) {
return false;
}
- memcpy(m2b->Data(), aBuffer, aLength * sizeof(char16_t));
- static_cast<char16_t*>(m2b->Data())[aLength] = char16_t(0);
+ ReleaseText();
+ memcpy(newBuffer->Data(), aBuffer, aLength * sizeof(char16_t));
+ static_cast<char16_t*>(newBuffer->Data())[aLength] = char16_t(0);
+
+ m2b = newBuffer.forget().take();
mState.mIs2b = true;
if (aUpdateBidi) {
UpdateBidiFlag(aBuffer + first16bit, aLength - first16bit);
}
-
} else {
// Use 1 byte storage because we can
char* buff = static_cast<char*>(malloc(aLength));
@@ -315,6 +316,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
return false;
}
+ ReleaseText();
// Copy data
LossyConvertUtf16toLatin1(Span(aBuffer, aLength), Span(buff, aLength));
m1b = buff;
diff --git a/dom/cache/DBAction.cpp b/dom/cache/DBAction.cpp
index 0a51260fe5..218ceb1808 100644
--- a/dom/cache/DBAction.cpp
+++ b/dom/cache/DBAction.cpp
@@ -14,6 +14,7 @@
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/ResultExtensions.h"
#include "mozilla/net/nsFileProtocolHandler.h"
+#include "mozilla/AppShutdown.h"
#include "mozIStorageConnection.h"
#include "mozIStorageService.h"
#include "mozStorageCID.h"
@@ -67,7 +68,7 @@ void DBAction::RunOnTarget(
MOZ_DIAGNOSTIC_ASSERT(aDirectoryMetadata);
MOZ_DIAGNOSTIC_ASSERT(aDirectoryMetadata->mDir);
- if (IsCanceled()) {
+ if (IsCanceled() || AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownQM)) {
aResolver->Resolve(NS_ERROR_ABORT);
return;
}
diff --git a/dom/cache/Manager.cpp b/dom/cache/Manager.cpp
index ab9b878ae0..fec6637255 100644
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -632,6 +632,15 @@ class Manager::CacheMatchAction final : public Manager::BaseAction {
BodyOpen(aDirectoryMetadata, *aDBDir, mResponse.mBodyId));
}
+ // If we entered shutdown on the main thread while we were doing IO,
+ // bail out now.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownQM)) {
+ if (stream) {
+ stream->Close();
+ }
+ return NS_ERROR_ABORT;
+ }
+
mStreamList->Add(mResponse.mBodyId, std::move(stream));
return NS_OK;
@@ -694,6 +703,15 @@ class Manager::CacheMatchAllAction final : public Manager::BaseAction {
mSavedResponses[i].mBodyId));
}
+ // If we entered shutdown on the main thread while we were doing IO,
+ // bail out now.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownQM)) {
+ if (stream) {
+ stream->Close();
+ }
+ return NS_ERROR_ABORT;
+ }
+
mStreamList->Add(mSavedResponses[i].mBodyId, std::move(stream));
}
@@ -1215,6 +1233,15 @@ class Manager::CacheKeysAction final : public Manager::BaseAction {
mSavedRequests[i].mBodyId));
}
+ // If we entered shutdown on the main thread while we were doing IO,
+ // bail out now.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownQM)) {
+ if (stream) {
+ stream->Close();
+ }
+ return NS_ERROR_ABORT;
+ }
+
mStreamList->Add(mSavedRequests[i].mBodyId, std::move(stream));
}
@@ -1280,6 +1307,15 @@ class Manager::StorageMatchAction final : public Manager::BaseAction {
mSavedResponse.mBodyId));
}
+ // If we entered shutdown on the main thread while we were doing IO,
+ // bail out now.
+ if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownQM)) {
+ if (stream) {
+ stream->Close();
+ }
+ return NS_ERROR_ABORT;
+ }
+
mStreamList->Add(mSavedResponse.mBodyId, std::move(stream));
return NS_OK;
diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp
index 96a1505a40..62fe40dfb7 100644
--- a/dom/canvas/CanvasImageCache.cpp
+++ b/dom/canvas/CanvasImageCache.cpp
@@ -9,7 +9,6 @@
#include "imgIRequest.h"
#include "mozilla/dom/Element.h"
#include "nsTHashtable.h"
-#include "mozilla/dom/HTMLCanvasElement.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_canvas.h"
@@ -27,11 +26,11 @@ using namespace gfx;
* due to CORS security.
*/
struct ImageCacheKey {
- ImageCacheKey(imgIContainer* aImage, HTMLCanvasElement* aCanvas,
+ ImageCacheKey(imgIContainer* aImage, CanvasRenderingContext2D* aContext,
BackendType aBackendType)
- : mImage(aImage), mCanvas(aCanvas), mBackendType(aBackendType) {}
+ : mImage(aImage), mContext(aContext), mBackendType(aBackendType) {}
nsCOMPtr<imgIContainer> mImage;
- HTMLCanvasElement* mCanvas;
+ CanvasRenderingContext2D* mContext;
BackendType mBackendType;
};
@@ -42,14 +41,14 @@ struct ImageCacheKey {
struct ImageCacheEntryData {
ImageCacheEntryData(const ImageCacheEntryData& aOther)
: mImage(aOther.mImage),
- mCanvas(aOther.mCanvas),
+ mContext(aOther.mContext),
mBackendType(aOther.mBackendType),
mSourceSurface(aOther.mSourceSurface),
mSize(aOther.mSize),
mIntrinsicSize(aOther.mIntrinsicSize) {}
explicit ImageCacheEntryData(const ImageCacheKey& aKey)
: mImage(aKey.mImage),
- mCanvas(aKey.mCanvas),
+ mContext(aKey.mContext),
mBackendType(aKey.mBackendType) {}
nsExpirationState* GetExpirationState() { return &mState; }
@@ -57,7 +56,7 @@ struct ImageCacheEntryData {
// Key
nsCOMPtr<imgIContainer> mImage;
- HTMLCanvasElement* mCanvas;
+ CanvasRenderingContext2D* mContext;
BackendType mBackendType;
// Value
RefPtr<SourceSurface> mSourceSurface;
@@ -78,13 +77,13 @@ class ImageCacheEntry : public PLDHashEntryHdr {
~ImageCacheEntry() = default;
bool KeyEquals(KeyTypePointer key) const {
- return mData->mImage == key->mImage && mData->mCanvas == key->mCanvas &&
+ return mData->mImage == key->mImage && mData->mContext == key->mContext &&
mData->mBackendType == key->mBackendType;
}
static KeyTypePointer KeyToPointer(KeyType& key) { return &key; }
static PLDHashNumber HashKey(KeyTypePointer key) {
- return HashGeneric(key->mImage.get(), key->mCanvas, key->mBackendType);
+ return HashGeneric(key->mImage.get(), key->mContext, key->mBackendType);
}
enum { ALLOW_MEMMOVE = true };
@@ -152,7 +151,7 @@ class ImageCache final : public nsExpirationTracker<ImageCacheEntryData, 4> {
AllCanvasImageCacheKey(aObject->mImage, aObject->mBackendType));
// Deleting the entry will delete aObject since the entry owns aObject.
- mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mCanvas,
+ mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mContext,
aObject->mBackendType));
}
@@ -266,13 +265,35 @@ static already_AddRefed<imgIContainer> GetImageContainer(dom::Element* aImage) {
return imgContainer.forget();
}
+void CanvasImageCache::NotifyCanvasDestroyed(
+ CanvasRenderingContext2D* aContext) {
+ MOZ_ASSERT(aContext);
+
+ if (!NS_IsMainThread() || !gImageCache) {
+ return;
+ }
+
+ for (auto i = gImageCache->mCache.Iter(); !i.Done(); i.Next()) {
+ ImageCacheEntryData* data = i.Get()->mData.get();
+ if (data->mContext == aContext) {
+ gImageCache->RemoveObject(data);
+ gImageCache->mAllCanvasCache.RemoveEntry(
+ AllCanvasImageCacheKey(data->mImage, data->mBackendType));
+ i.Remove();
+ }
+ }
+}
+
void CanvasImageCache::NotifyDrawImage(Element* aImage,
- HTMLCanvasElement* aCanvas,
+ CanvasRenderingContext2D* aContext,
DrawTarget* aTarget,
SourceSurface* aSource,
const IntSize& aSize,
const IntSize& aIntrinsicSize) {
- if (!aTarget) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aContext);
+
+ if (!aTarget || !aContext) {
return;
}
@@ -289,7 +310,7 @@ void CanvasImageCache::NotifyDrawImage(Element* aImage,
BackendType backendType = aTarget->GetBackendType();
AllCanvasImageCacheKey allCanvasCacheKey(imgContainer, backendType);
- ImageCacheKey canvasCacheKey(imgContainer, aCanvas, backendType);
+ ImageCacheKey canvasCacheKey(imgContainer, aContext, backendType);
ImageCacheEntry* entry = gImageCache->mCache.PutEntry(canvasCacheKey);
if (entry) {
@@ -326,6 +347,8 @@ void CanvasImageCache::NotifyDrawImage(Element* aImage,
SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage,
DrawTarget* aTarget) {
+ MOZ_ASSERT(NS_IsMainThread());
+
if (!gImageCache || !aTarget) {
return nullptr;
}
@@ -344,11 +367,12 @@ SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage,
return entry->mSourceSurface;
}
-SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage,
- HTMLCanvasElement* aCanvas,
- DrawTarget* aTarget,
- IntSize* aSizeOut,
- IntSize* aIntrinsicSizeOut) {
+SourceSurface* CanvasImageCache::LookupCanvas(
+ Element* aImage, CanvasRenderingContext2D* aContext, DrawTarget* aTarget,
+ IntSize* aSizeOut, IntSize* aIntrinsicSizeOut) {
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aContext);
+
if (!gImageCache || !aTarget) {
return nullptr;
}
@@ -365,7 +389,7 @@ SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage,
// optimized surface given to a Skia backend would cause a readback. For
// details, see bug 1794442.
ImageCacheEntry* entry = gImageCache->mCache.GetEntry(
- ImageCacheKey(imgContainer, aCanvas, aTarget->GetBackendType()));
+ ImageCacheKey(imgContainer, aContext, aTarget->GetBackendType()));
if (!entry) {
return nullptr;
}
diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h
index 58486c5a8d..c860951fb7 100644
--- a/dom/canvas/CanvasImageCache.h
+++ b/dom/canvas/CanvasImageCache.h
@@ -12,7 +12,7 @@
namespace mozilla {
namespace dom {
class Element;
-class HTMLCanvasElement;
+class CanvasRenderingContext2D;
} // namespace dom
namespace gfx {
class DrawTarget;
@@ -28,18 +28,23 @@ class CanvasImageCache {
public:
/**
- * Notify that image element aImage was drawn to aCanvas element
+ * Notify that image element aImage was drawn to aContext canvas
* using the first frame of aRequest's image. The data for the surface is
* in aSurface, and the image size is in aSize. aIntrinsicSize is the size
* the surface is intended to be rendered at.
*/
static void NotifyDrawImage(dom::Element* aImage,
- dom::HTMLCanvasElement* aCanvas,
+ dom::CanvasRenderingContext2D* aContext,
gfx::DrawTarget* aTarget, SourceSurface* aSource,
const gfx::IntSize& aSize,
const gfx::IntSize& aIntrinsicSize);
/**
+ * Notify that aContext is being destroyed.
+ */
+ static void NotifyCanvasDestroyed(dom::CanvasRenderingContext2D* aContext);
+
+ /**
* Check whether aImage has recently been drawn any canvas. If we return
* a non-null surface, then the same image was recently drawn into a canvas.
*/
@@ -47,11 +52,11 @@ class CanvasImageCache {
gfx::DrawTarget* aTarget);
/**
- * Like the top above, but restricts the lookup to only aCanvas. This is
+ * Like the top above, but restricts the lookup to only aContext. This is
* required for CORS security.
*/
static SourceSurface* LookupCanvas(dom::Element* aImage,
- dom::HTMLCanvasElement* aCanvas,
+ dom::CanvasRenderingContext2D* aContext,
gfx::DrawTarget* aTarget,
gfx::IntSize* aSizeOut,
gfx::IntSize* aIntrinsicSizeOut);
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 83fe205e35..cf20f4f7c3 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1074,6 +1074,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(
}
CanvasRenderingContext2D::~CanvasRenderingContext2D() {
+ CanvasImageCache::NotifyCanvasDestroyed(this);
RemovePostRefreshObserver();
RemoveShutdownObserver();
ResetBitmap();
@@ -5221,8 +5222,8 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
element = video;
}
- srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, mTarget,
- &imgSize, &intrinsicImgSize);
+ srcSurf = CanvasImageCache::LookupCanvas(element, this, mTarget, &imgSize,
+ &intrinsicImgSize);
}
DirectDrawInfo drawInfo;
@@ -5267,7 +5268,7 @@ void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
if (res.mSourceSurface) {
if (res.mImageRequest) {
- CanvasImageCache::NotifyDrawImage(element, mCanvasElement, mTarget,
+ CanvasImageCache::NotifyDrawImage(element, this, mTarget,
res.mSourceSurface, imgSize,
intrinsicImgSize);
}
diff --git a/dom/media/MediaInfo.h b/dom/media/MediaInfo.h
index c692b94d64..4dba606420 100644
--- a/dom/media/MediaInfo.h
+++ b/dom/media/MediaInfo.h
@@ -351,7 +351,32 @@ class VideoInfo : public TrackInfo {
mExtraData(new MediaByteBuffer),
mRotation(kDegree_0) {}
- VideoInfo(const VideoInfo& aOther) = default;
+ VideoInfo(const VideoInfo& aOther) : TrackInfo(aOther) {
+ if (aOther.mCodecSpecificConfig) {
+ mCodecSpecificConfig = new MediaByteBuffer();
+ mCodecSpecificConfig->AppendElements(
+ reinterpret_cast<uint8_t*>(aOther.mCodecSpecificConfig->Elements()),
+ aOther.mCodecSpecificConfig->Length());
+ }
+ if (aOther.mExtraData) {
+ mExtraData = new MediaByteBuffer();
+ mExtraData->AppendElements(
+ reinterpret_cast<uint8_t*>(aOther.mExtraData->Elements()),
+ aOther.mExtraData->Length());
+ }
+ mDisplay = aOther.mDisplay;
+ mStereoMode = aOther.mStereoMode;
+ mImage = aOther.mImage;
+ mRotation = aOther.mRotation;
+ mColorDepth = aOther.mColorDepth;
+ mColorSpace = aOther.mColorSpace;
+ mColorPrimaries = aOther.mColorPrimaries;
+ mTransferFunction = aOther.mTransferFunction;
+ mColorRange = aOther.mColorRange;
+ mImageRect = aOther.mImageRect;
+ mAlphaPresent = aOther.mAlphaPresent;
+ mFrameRate = aOther.mFrameRate;
+ };
bool operator==(const VideoInfo& rhs) const;
diff --git a/dom/media/gmp/GMPVideoDecoderChild.cpp b/dom/media/gmp/GMPVideoDecoderChild.cpp
index 0f605cca9b..f60952ee51 100644
--- a/dom/media/gmp/GMPVideoDecoderChild.cpp
+++ b/dom/media/gmp/GMPVideoDecoderChild.cpp
@@ -36,12 +36,17 @@ void GMPVideoDecoderChild::Init(GMPVideoDecoder* aDecoder) {
GMPVideoHostImpl& GMPVideoDecoderChild::Host() { return mVideoHost; }
void GMPVideoDecoderChild::Decoded(GMPVideoi420Frame* aDecodedFrame) {
- MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
-
if (!aDecodedFrame) {
MOZ_CRASH("Not given a decoded frame!");
}
+ if (NS_WARN_IF(!mPlugin)) {
+ aDecodedFrame->Destroy();
+ return;
+ }
+
+ MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
+
auto df = static_cast<GMPVideoi420FrameImpl*>(aDecodedFrame);
GMPVideoi420FrameData frameData;
@@ -53,36 +58,60 @@ void GMPVideoDecoderChild::Decoded(GMPVideoi420Frame* aDecodedFrame) {
void GMPVideoDecoderChild::ReceivedDecodedReferenceFrame(
const uint64_t aPictureId) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendReceivedDecodedReferenceFrame(aPictureId);
}
void GMPVideoDecoderChild::ReceivedDecodedFrame(const uint64_t aPictureId) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendReceivedDecodedFrame(aPictureId);
}
void GMPVideoDecoderChild::InputDataExhausted() {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendInputDataExhausted();
}
void GMPVideoDecoderChild::DrainComplete() {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendDrainComplete();
}
void GMPVideoDecoderChild::ResetComplete() {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendResetComplete();
}
void GMPVideoDecoderChild::Error(GMPErr aError) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendError(aError);
@@ -121,9 +150,9 @@ mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDecode(
mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvChildShmemForPool(
Shmem&& aFrameBuffer) {
- if (aFrameBuffer.IsWritable()) {
- mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData,
- aFrameBuffer);
+ GMPSharedMemManager* memMgr = mVideoHost.SharedMemMgr();
+ if (memMgr && aFrameBuffer.IsWritable()) {
+ memMgr->MgrDeallocShmem(GMPSharedMem::kGMPFrameData, aFrameBuffer);
}
return IPC_OK();
}
@@ -153,6 +182,7 @@ mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDrain() {
}
mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDecodingComplete() {
+ MOZ_ASSERT(mPlugin);
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
if (mNeedShmemIntrCount) {
@@ -163,6 +193,13 @@ mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDecodingComplete() {
mPendingDecodeComplete = true;
return IPC_OK();
}
+
+ // This will call ActorDestroy.
+ Unused << Send__delete__(this);
+ return IPC_OK();
+}
+
+void GMPVideoDecoderChild::ActorDestroy(ActorDestroyReason why) {
if (mVideoDecoder) {
// Ignore any return code. It is OK for this to fail without killing the
// process.
@@ -173,13 +210,13 @@ mozilla::ipc::IPCResult GMPVideoDecoderChild::RecvDecodingComplete() {
mVideoHost.DoneWithAPI();
mPlugin = nullptr;
-
- Unused << Send__delete__(this);
-
- return IPC_OK();
}
bool GMPVideoDecoderChild::Alloc(size_t aSize, Shmem* aMem) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return false;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
bool rv;
diff --git a/dom/media/gmp/GMPVideoDecoderChild.h b/dom/media/gmp/GMPVideoDecoderChild.h
index 3c74e5f02c..527d6cad44 100644
--- a/dom/media/gmp/GMPVideoDecoderChild.h
+++ b/dom/media/gmp/GMPVideoDecoderChild.h
@@ -59,6 +59,7 @@ class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
mozilla::ipc::IPCResult RecvReset();
mozilla::ipc::IPCResult RecvDrain();
mozilla::ipc::IPCResult RecvDecodingComplete();
+ void ActorDestroy(ActorDestroyReason why) override;
GMPContentChild* mPlugin;
GMPVideoDecoder* mVideoDecoder;
diff --git a/dom/media/gmp/GMPVideoEncoderChild.cpp b/dom/media/gmp/GMPVideoEncoderChild.cpp
index 19a96b5efe..01a913f920 100644
--- a/dom/media/gmp/GMPVideoEncoderChild.cpp
+++ b/dom/media/gmp/GMPVideoEncoderChild.cpp
@@ -38,6 +38,11 @@ GMPVideoHostImpl& GMPVideoEncoderChild::Host() { return mVideoHost; }
void GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength) {
+ if (NS_WARN_IF(!mPlugin)) {
+ aEncodedFrame->Destroy();
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
auto ef = static_cast<GMPVideoEncodedFrameImpl*>(aEncodedFrame);
@@ -53,6 +58,10 @@ void GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
}
void GMPVideoEncoderChild::Error(GMPErr aError) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendError(aError);
@@ -95,9 +104,9 @@ mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvEncode(
mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvChildShmemForPool(
Shmem&& aEncodedBuffer) {
- if (aEncodedBuffer.IsWritable()) {
- mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData,
- aEncodedBuffer);
+ GMPSharedMemManager* memMgr = mVideoHost.SharedMemMgr();
+ if (memMgr && aEncodedBuffer.IsWritable()) {
+ memMgr->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData, aEncodedBuffer);
}
return IPC_OK();
}
@@ -142,6 +151,7 @@ mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvSetPeriodicKeyFrames(
}
mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvEncodingComplete() {
+ MOZ_ASSERT(mPlugin);
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
if (mNeedShmemIntrCount) {
@@ -153,26 +163,29 @@ mozilla::ipc::IPCResult GMPVideoEncoderChild::RecvEncodingComplete() {
return IPC_OK();
}
- if (!mVideoEncoder) {
- // There is not much to clean up anymore.
- Unused << Send__delete__(this);
- return IPC_OK();
- }
+ // This will call ActorDestroy.
+ Unused << Send__delete__(this);
+ return IPC_OK();
+}
- // Ignore any return code. It is OK for this to fail without killing the
- // process.
- mVideoEncoder->EncodingComplete();
+void GMPVideoEncoderChild::ActorDestroy(ActorDestroyReason why) {
+ if (mVideoEncoder) {
+ // Ignore any return code. It is OK for this to fail without killing the
+ // process.
+ mVideoEncoder->EncodingComplete();
+ mVideoEncoder = nullptr;
+ }
mVideoHost.DoneWithAPI();
mPlugin = nullptr;
-
- Unused << Send__delete__(this);
-
- return IPC_OK();
}
bool GMPVideoEncoderChild::Alloc(size_t aSize, Shmem* aMem) {
+ if (NS_WARN_IF(!mPlugin)) {
+ return false;
+ }
+
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
bool rv;
diff --git a/dom/media/gmp/GMPVideoEncoderChild.h b/dom/media/gmp/GMPVideoEncoderChild.h
index dd3c0fdf37..344a55b388 100644
--- a/dom/media/gmp/GMPVideoEncoderChild.h
+++ b/dom/media/gmp/GMPVideoEncoderChild.h
@@ -59,6 +59,7 @@ class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
const uint32_t& aFrameRate);
mozilla::ipc::IPCResult RecvSetPeriodicKeyFrames(const bool& aEnable);
mozilla::ipc::IPCResult RecvEncodingComplete();
+ void ActorDestroy(ActorDestroyReason why) override;
GMPContentChild* mPlugin;
GMPVideoEncoder* mVideoEncoder;