tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_ */