diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /dom/media/VideoFrameContainer.h | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/VideoFrameContainer.h')
-rw-r--r-- | dom/media/VideoFrameContainer.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/dom/media/VideoFrameContainer.h b/dom/media/VideoFrameContainer.h new file mode 100644 index 0000000000..efa1ad8491 --- /dev/null +++ b/dom/media/VideoFrameContainer.h @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef VIDEOFRAMECONTAINER_H_ +#define VIDEOFRAMECONTAINER_H_ + +#include "mozilla/Mutex.h" +#include "mozilla/TimeStamp.h" +#include "gfxPoint.h" +#include "nsCOMPtr.h" +#include "ImageContainer.h" +#include "MediaSegment.h" +#include "VideoSegment.h" + +namespace mozilla { + +class MediaDecoderOwner; + +/** + * This object is used in the decoder backend threads and the main thread + * to manage the "current video frame" state. This state includes timing data + * and an intrinsic size (see below). + * This has to be a thread-safe object since it's accessed by resource decoders + * and other off-main-thread components. So we can't put this state in the media + * element itself ... well, maybe we could, but it could be risky and/or + * confusing. + */ +class VideoFrameContainer { + virtual ~VideoFrameContainer(); + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameContainer) + + public: + typedef layers::ImageContainer ImageContainer; + typedef layers::Image Image; + + VideoFrameContainer(MediaDecoderOwner* aOwner, + already_AddRefed<ImageContainer> aContainer); + + void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, + const TimeStamp& aTargetTime); + // Returns the last principalHandle we notified mElement about. + PrincipalHandle GetLastPrincipalHandle(); + PrincipalHandle GetLastPrincipalHandleLocked(); + // We will notify mElement that aPrincipalHandle has been applied when all + // FrameIDs prior to aFrameID have been flushed out. + // aFrameID is ignored if aPrincipalHandle already is our pending + // principalHandle. + void UpdatePrincipalHandleForFrameID(const PrincipalHandle& aPrincipalHandle, + const ImageContainer::FrameID& aFrameID); + void UpdatePrincipalHandleForFrameIDLocked( + const PrincipalHandle& aPrincipalHandle, + const ImageContainer::FrameID& aFrameID); + void SetCurrentFrames( + const gfx::IntSize& aIntrinsicSize, + const nsTArray<ImageContainer::NonOwningImage>& aImages); + void ClearCurrentFrame(const gfx::IntSize& aIntrinsicSize) { + SetCurrentFrames(aIntrinsicSize, + nsTArray<ImageContainer::NonOwningImage>()); + } + + // Make the current frame the only frame in the container, i.e. discard + // all future frames. + void ClearFutureFrames(TimeStamp aNow = TimeStamp::Now()); + // Time in seconds by which the last painted video frame was late by. + // E.g. if the last painted frame should have been painted at time t, + // but was actually painted at t+n, this returns n in seconds. Threadsafe. + double GetFrameDelay(); + + // Clear any resources that are not immediately necessary. + void ClearCachedResources(); + + // Returns a new frame ID for SetCurrentFrames(). The client must either + // call this on only one thread or provide barriers. Do not use together + // with SetCurrentFrame(). + ImageContainer::FrameID NewFrameID() { return ++mFrameID; } + + // Call on main thread + enum { INVALIDATE_DEFAULT, INVALIDATE_FORCE }; + void Invalidate() { InvalidateWithFlags(INVALIDATE_DEFAULT); } + void InvalidateWithFlags(uint32_t aFlags); + ImageContainer* GetImageContainer(); + void ForgetElement() { mOwner = nullptr; } + + uint32_t GetDroppedImageCount() { + MutexAutoLock lock(mMutex); + return mImageContainer->GetDroppedImageCount(); + } + + protected: + void SetCurrentFramesLocked( + const gfx::IntSize& aIntrinsicSize, + const nsTArray<ImageContainer::NonOwningImage>& aImages); + + // Non-addreffed pointer to the owner. The owner calls ForgetElement + // to clear this reference when the owner is destroyed. + MediaDecoderOwner* mOwner; + RefPtr<ImageContainer> mImageContainer; + + struct { + // True when the Image size has changed since the last time Invalidate() was + // called. When set, the next call to Invalidate() will ensure that the + // frame is fully invalidated instead of just invalidating for the image + // change in the ImageLayer. + bool mImageSizeChanged = false; + // The main thread mirror of the member of the same name below. + gfx::IntSize mIntrinsicSize; + // True when the intrinsic size has been changed by SetCurrentFrame() since + // the last call to Invalidate(). + // The next call to Invalidate() will recalculate + // and update the intrinsic size on the element, request a frame reflow and + // then reset this flag. + bool mIntrinsicSizeChanged = false; + } mMainThreadState; + + // mMutex protects all the fields below. + Mutex mMutex MOZ_UNANNOTATED; + // The intrinsic size is the ideal size which we should render the + // ImageContainer's current Image at. + // This can differ from the Image's actual size when the media resource + // specifies that the Image should be stretched to have the correct aspect + // ratio. + gfx::IntSize mIntrinsicSize; + // We maintain our own mFrameID which is auto-incremented at every + // SetCurrentFrame() or NewFrameID() call. + ImageContainer::FrameID mFrameID; + // The last PrincipalHandle we notified mElement about. + PrincipalHandle mLastPrincipalHandle; + // The PrincipalHandle the client has notified us is changing with FrameID + // mFrameIDForPendingPrincipalHandle. + PrincipalHandle mPendingPrincipalHandle; + // The FrameID for which mPendingPrincipal is first valid. + ImageContainer::FrameID mFrameIDForPendingPrincipalHandle; + + const RefPtr<AbstractThread> mMainThread; +}; + +} // namespace mozilla + +#endif /* VIDEOFRAMECONTAINER_H_ */ |