VideoFrameContainer.h (6255B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef VIDEOFRAMECONTAINER_H_ 8 #define VIDEOFRAMECONTAINER_H_ 9 10 #include "ImageContainer.h" 11 #include "MediaSegment.h" 12 #include "VideoSegment.h" 13 #include "gfxPoint.h" 14 #include "mozilla/Mutex.h" 15 #include "mozilla/TimeStamp.h" 16 #include "nsCOMPtr.h" 17 18 namespace mozilla { 19 20 class MediaDecoderOwner; 21 22 /** 23 * This object is used in the decoder backend threads and the main thread 24 * to manage the "current video frame" state. This state includes timing data 25 * and an intrinsic size (see below). 26 * This has to be a thread-safe object since it's accessed by resource decoders 27 * and other off-main-thread components. So we can't put this state in the media 28 * element itself ... well, maybe we could, but it could be risky and/or 29 * confusing. 30 */ 31 class VideoFrameContainer { 32 virtual ~VideoFrameContainer(); 33 34 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoFrameContainer) 35 36 public: 37 typedef layers::ImageContainer ImageContainer; 38 typedef layers::Image Image; 39 40 VideoFrameContainer(MediaDecoderOwner* aOwner, 41 already_AddRefed<ImageContainer> aContainer); 42 43 void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, 44 const TimeStamp& aTargetTime, 45 const media::TimeUnit& aProcessingDuration, 46 const media::TimeUnit& aMediaTime); 47 // Returns the last principalHandle we notified mElement about. 48 PrincipalHandle GetLastPrincipalHandle(); 49 PrincipalHandle GetLastPrincipalHandleLocked() MOZ_REQUIRES(mMutex); 50 // We will notify mElement that aPrincipalHandle has been applied when all 51 // FrameIDs prior to aFrameID have been flushed out. 52 // aFrameID is ignored if aPrincipalHandle already is our pending 53 // principalHandle. 54 void UpdatePrincipalHandleForFrameID(const PrincipalHandle& aPrincipalHandle, 55 const ImageContainer::FrameID& aFrameID); 56 void UpdatePrincipalHandleForFrameIDLocked( 57 const PrincipalHandle& aPrincipalHandle, 58 const ImageContainer::FrameID& aFrameID) MOZ_REQUIRES(mMutex); 59 void SetCurrentFrames( 60 const gfx::IntSize& aIntrinsicSize, 61 const nsTArray<ImageContainer::NonOwningImage>& aImages); 62 63 // Make the current frame the only frame in the container, i.e. discard 64 // all future frames. 65 void ClearFutureFrames(TimeStamp aNow = TimeStamp::Now()); 66 // Time in seconds by which the last painted video frame was late by. 67 // E.g. if the last painted frame should have been painted at time t, 68 // but was actually painted at t+n, this returns n in seconds. Threadsafe. 69 double GetFrameDelay(); 70 71 // Clear any resources in client that are not immediately necessary. 72 void ClearCachedResources(); 73 74 // Clear images in host. 75 void ClearImagesInHost(layers::ClearImagesType aType); 76 77 // Returns a new frame ID for SetCurrentFrames(). The client must either 78 // call this on only one thread or provide barriers. Do not use together 79 // with SetCurrentFrame(). 80 ImageContainer::FrameID NewFrameID() { return ++mFrameID; } 81 82 // Call on main thread 83 enum { INVALIDATE_DEFAULT, INVALIDATE_FORCE }; 84 void Invalidate() { InvalidateWithFlags(INVALIDATE_DEFAULT); } 85 void InvalidateWithFlags(uint32_t aFlags); 86 ImageContainer* GetImageContainer(); 87 void ForgetElement() { mOwner = nullptr; } 88 89 uint32_t GetDroppedImageCount() { 90 MutexAutoLock lock(mMutex); 91 return mImageContainer->GetDroppedImageCount(); 92 } 93 94 Maybe<gfx::IntSize> CurrentIntrinsicSize() { 95 MutexAutoLock lock(mMutex); 96 return mIntrinsicSize; 97 } 98 99 bool SupportsOnly8BitImage() const { return mSupportsOnly8BitImage; } 100 101 protected: 102 void SetCurrentFramesLocked( 103 const gfx::IntSize& aIntrinsicSize, 104 const nsTArray<ImageContainer::NonOwningImage>& aImages) 105 MOZ_REQUIRES(mMutex); 106 107 // Non-addreffed pointer to the owner. The owner calls ForgetElement 108 // to clear this reference when the owner is destroyed. 109 MediaDecoderOwner* mOwner; 110 RefPtr<ImageContainer> mImageContainer; 111 112 struct { 113 // True when the Image size has changed since the last time Invalidate() was 114 // called. When set, the next call to Invalidate() will ensure that the 115 // frame is fully invalidated instead of just invalidating for the image 116 // change in the ImageLayer. 117 bool mImageSizeChanged = false; 118 // The main thread mirror of the member of the same name below, in case it 119 // has changed. 120 // Set to some size when the intrinsic size has been changed by 121 // SetCurrentFrame() since the last call to Invalidate(). 122 // The next call to Invalidate() will recalculate and update the intrinsic 123 // size on the element, request a frame reflow and then reset this to 124 // Nothing. 125 Maybe<gfx::IntSize> mNewIntrinsicSize; 126 } mMainThreadState; 127 128 Mutex mMutex; 129 // The intrinsic size is the ideal size which we should render the 130 // ImageContainer's current Image at. 131 // This can differ from the Image's actual size when the media resource 132 // specifies that the Image should be stretched to have the correct aspect 133 // ratio. 134 Maybe<gfx::IntSize> mIntrinsicSize MOZ_GUARDED_BY(mMutex); 135 // We maintain our own mFrameID which is auto-incremented at every 136 // SetCurrentFrame() or NewFrameID() call. 137 ImageContainer::FrameID mFrameID; 138 // The last PrincipalHandle we notified mElement about. 139 PrincipalHandle mLastPrincipalHandle MOZ_GUARDED_BY(mMutex); 140 // The PrincipalHandle the client has notified us is changing with FrameID 141 // mFrameIDForPendingPrincipalHandle. 142 PrincipalHandle mPendingPrincipalHandle MOZ_GUARDED_BY(mMutex); 143 // The FrameID for which mPendingPrincipal is first valid. 144 ImageContainer::FrameID mFrameIDForPendingPrincipalHandle 145 MOZ_GUARDED_BY(mMutex); 146 147 const RefPtr<AbstractThread> mMainThread; 148 149 // True when Android GL implementation support only 8-bit texture. 150 const bool mSupportsOnly8BitImage; 151 }; 152 153 } // namespace mozilla 154 155 #endif /* VIDEOFRAMECONTAINER_H_ */