diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/nsTextFragment.cpp | 40 | ||||
-rw-r--r-- | dom/cache/DBAction.cpp | 3 | ||||
-rw-r--r-- | dom/cache/Manager.cpp | 36 | ||||
-rw-r--r-- | dom/canvas/CanvasImageCache.cpp | 62 | ||||
-rw-r--r-- | dom/canvas/CanvasImageCache.h | 15 | ||||
-rw-r--r-- | dom/canvas/CanvasRenderingContext2D.cpp | 7 | ||||
-rw-r--r-- | dom/media/MediaInfo.h | 27 | ||||
-rw-r--r-- | dom/media/gmp/GMPVideoDecoderChild.cpp | 55 | ||||
-rw-r--r-- | dom/media/gmp/GMPVideoDecoderChild.h | 1 | ||||
-rw-r--r-- | dom/media/gmp/GMPVideoEncoderChild.cpp | 43 | ||||
-rw-r--r-- | dom/media/gmp/GMPVideoEncoderChild.h | 1 |
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; |