Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/VideoFrameContainer.h
Line
Count
Source (jump to first uncovered line)
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 "mozilla/Mutex.h"
11
#include "mozilla/TimeStamp.h"
12
#include "gfxPoint.h"
13
#include "nsCOMPtr.h"
14
#include "ImageContainer.h"
15
#include "MediaSegment.h"
16
#include "MediaStreamVideoSink.h"
17
#include "VideoSegment.h"
18
19
namespace mozilla {
20
21
class MediaDecoderOwner;
22
23
/**
24
 * This object is used in the decoder backend threads and the main thread
25
 * to manage the "current video frame" state. This state includes timing data
26
 * and an intrinsic size (see below).
27
 * This has to be a thread-safe object since it's accessed by resource decoders
28
 * and other off-main-thread components. So we can't put this state in the media
29
 * element itself ... well, maybe we could, but it could be risky and/or
30
 * confusing.
31
 */
32
class VideoFrameContainer : public MediaStreamVideoSink {
33
  virtual ~VideoFrameContainer();
34
35
public:
36
  typedef layers::ImageContainer ImageContainer;
37
  typedef layers::Image Image;
38
39
  VideoFrameContainer(MediaDecoderOwner* aOwner,
40
                      already_AddRefed<ImageContainer> aContainer);
41
42
  // Call on any thread
43
  virtual void SetCurrentFrames(const VideoSegment& aSegment) override;
44
  virtual void ClearFrames() override;
45
  void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage,
46
                       const TimeStamp& aTargetTime);
47
  // Returns the last principalHandle we notified mElement about.
48
  PrincipalHandle GetLastPrincipalHandle();
49
  PrincipalHandle GetLastPrincipalHandleLocked();
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 principalHandle.
53
  void UpdatePrincipalHandleForFrameID(const PrincipalHandle& aPrincipalHandle,
54
                                       const ImageContainer::FrameID& aFrameID);
55
  void UpdatePrincipalHandleForFrameIDLocked(const PrincipalHandle& aPrincipalHandle,
56
                                             const ImageContainer::FrameID& aFrameID);
57
  void SetCurrentFrames(const gfx::IntSize& aIntrinsicSize,
58
                        const nsTArray<ImageContainer::NonOwningImage>& aImages);
59
  void ClearCurrentFrame(const gfx::IntSize& aIntrinsicSize)
60
0
  {
61
0
    SetCurrentFrames(aIntrinsicSize, nsTArray<ImageContainer::NonOwningImage>());
62
0
  }
63
0
  VideoFrameContainer* AsVideoFrameContainer() override { return this; }
64
65
  void ClearCurrentFrame();
66
  // Make the current frame the only frame in the container, i.e. discard
67
  // all future frames.
68
  void ClearFutureFrames();
69
  // Time in seconds by which the last painted video frame was late by.
70
  // E.g. if the last painted frame should have been painted at time t,
71
  // but was actually painted at t+n, this returns n in seconds. Threadsafe.
72
  double GetFrameDelay();
73
74
  // Clear any resources that are not immediately necessary.
75
  void ClearCachedResources();
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()
81
0
  {
82
0
    return ++mFrameID;
83
0
  }
84
85
  // Call on main thread
86
  enum {
87
    INVALIDATE_DEFAULT,
88
    INVALIDATE_FORCE
89
  };
90
0
  void Invalidate() override { InvalidateWithFlags(INVALIDATE_DEFAULT); }
91
  void InvalidateWithFlags(uint32_t aFlags);
92
  ImageContainer* GetImageContainer();
93
0
  void ForgetElement() { mOwner = nullptr; }
94
95
0
  uint32_t GetDroppedImageCount() { return mImageContainer->GetDroppedImageCount(); }
96
97
protected:
98
  void SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicSize,
99
                              const nsTArray<ImageContainer::NonOwningImage>& aImages);
100
101
  // Non-addreffed pointer to the owner. The ownenr calls ForgetElement
102
  // to clear this reference when the owner is destroyed.
103
  MediaDecoderOwner* mOwner;
104
  RefPtr<ImageContainer> mImageContainer;
105
106
  struct
107
  {
108
    // True when the Image size has changed since the last time Invalidate() was
109
    // called. When set, the next call to Invalidate() will ensure that the
110
    // frame is fully invalidated instead of just invalidating for the image change
111
    // in the ImageLayer.
112
    bool mImageSizeChanged = false;
113
    // The main thread mirror of the member of the same name below.
114
    gfx::IntSize mIntrinsicSize;
115
    // True when the intrinsic size has been changed by SetCurrentFrame() since
116
    // the last call to Invalidate().
117
    // The next call to Invalidate() will recalculate
118
    // and update the intrinsic size on the element, request a frame reflow and
119
    // then reset this flag.
120
    bool mIntrinsicSizeChanged = false;
121
  } mMainThreadState;
122
123
  // mMutex protects all the fields below.
124
  Mutex mMutex;
125
  // Once the frame is forced to black, we initialize mBlackImage for following
126
  // frames.
127
  RefPtr<Image> mBlackImage;
128
  // The intrinsic size is the ideal size which we should render the
129
  // ImageContainer's current Image at.
130
  // This can differ from the Image's actual size when the media resource
131
  // specifies that the Image should be stretched to have the correct aspect
132
  // ratio.
133
  gfx::IntSize mIntrinsicSize;
134
  // We maintain our own mFrameID which is auto-incremented at every
135
  // SetCurrentFrame() or NewFrameID() call.
136
  ImageContainer::FrameID mFrameID;
137
  // We record the last played video frame to avoid playing the frame again
138
  // with a different frame id.
139
  VideoFrame mLastPlayedVideoFrame;
140
  // The last PrincipalHandle we notified mElement about.
141
  PrincipalHandle mLastPrincipalHandle;
142
  // The PrincipalHandle the client has notified us is changing with FrameID
143
  // mFrameIDForPendingPrincipalHandle.
144
  PrincipalHandle mPendingPrincipalHandle;
145
  // The FrameID for which mPendingPrincipal is first valid.
146
  ImageContainer::FrameID mFrameIDForPendingPrincipalHandle;
147
148
  const RefPtr<AbstractThread> mMainThread;
149
};
150
151
} // namespace mozilla
152
153
#endif /* VIDEOFRAMECONTAINER_H_ */