Bug 1941046 - Part 4: Send a callback request for impression and clicks of MARS Top...
[gecko.git] / dom / media / VideoSegment.h
blobc29c373c676b7cb639021d942159d483f40f81f7
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef MOZILLA_VIDEOSEGMENT_H_
7 #define MOZILLA_VIDEOSEGMENT_H_
9 #include "MediaSegment.h"
10 #include "nsCOMPtr.h"
11 #include "gfxPoint.h"
12 #include "ImageContainer.h"
13 #include "TimeUnits.h"
15 namespace mozilla {
17 namespace layers {
18 class Image;
19 } // namespace layers
21 class VideoFrame {
22 public:
23 typedef mozilla::layers::Image Image;
25 VideoFrame(already_AddRefed<Image> aImage,
26 const gfx::IntSize& aIntrinsicSize);
27 VideoFrame();
28 ~VideoFrame();
30 bool operator==(const VideoFrame& aFrame) const {
31 return mIntrinsicSize == aFrame.mIntrinsicSize &&
32 mForceBlack == aFrame.mForceBlack &&
33 ((mForceBlack && aFrame.mForceBlack) || mImage == aFrame.mImage) &&
34 mPrincipalHandle == aFrame.mPrincipalHandle;
36 bool operator!=(const VideoFrame& aFrame) const {
37 return !operator==(aFrame);
40 Image* GetImage() const { return mImage; }
41 void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; }
42 bool GetForceBlack() const { return mForceBlack; }
43 void SetPrincipalHandle(PrincipalHandle aPrincipalHandle) {
44 mPrincipalHandle = std::forward<PrincipalHandle>(aPrincipalHandle);
46 const PrincipalHandle& GetPrincipalHandle() const { return mPrincipalHandle; }
47 const gfx::IntSize& GetIntrinsicSize() const { return mIntrinsicSize; }
48 void SetNull();
49 void TakeFrom(VideoFrame* aFrame);
51 // Create a planar YCbCr black image.
52 static already_AddRefed<Image> CreateBlackImage(const gfx::IntSize& aSize);
54 protected:
55 // mImage can be null to indicate "no video" (aka "empty frame"). It can
56 // still have an intrinsic size in this case.
57 RefPtr<Image> mImage;
58 // The desired size to render the video frame at.
59 gfx::IntSize mIntrinsicSize;
60 bool mForceBlack;
61 // principalHandle for the image in this frame.
62 // This can be compared to an nsIPrincipal when back on main thread.
63 PrincipalHandle mPrincipalHandle;
66 struct VideoChunk {
67 void SliceTo(TrackTime aStart, TrackTime aEnd) {
68 NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
69 "Slice out of bounds");
70 mDuration = aEnd - aStart;
72 TrackTime GetDuration() const { return mDuration; }
73 bool CanCombineWithFollowing(const VideoChunk& aOther) const {
74 return aOther.mFrame == mFrame;
76 bool IsNull() const { return !mFrame.GetImage(); }
77 void SetNull(TrackTime aDuration) {
78 mDuration = aDuration;
79 mFrame.SetNull();
80 mTimeStamp = TimeStamp();
82 void SetForceBlack(bool aForceBlack) { mFrame.SetForceBlack(aForceBlack); }
84 size_t SizeOfExcludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const {
85 // Future:
86 // - mFrame
87 return 0;
90 const PrincipalHandle& GetPrincipalHandle() const {
91 return mFrame.GetPrincipalHandle();
94 TrackTime mDuration;
95 VideoFrame mFrame;
96 TimeStamp mTimeStamp;
97 media::TimeUnit mProcessingDuration;
98 media::TimeUnit mMediaTime;
99 layers::ContainerCaptureTime mWebrtcCaptureTime = AsVariant(Nothing());
100 layers::ContainerReceiveTime mWebrtcReceiveTime;
101 layers::ContainerRtpTimestamp mRtpTimestamp;
104 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
105 public:
106 typedef mozilla::layers::Image Image;
107 typedef mozilla::gfx::IntSize IntSize;
109 VideoSegment();
110 VideoSegment(VideoSegment&& aSegment);
112 VideoSegment(const VideoSegment&) = delete;
113 VideoSegment& operator=(const VideoSegment&) = delete;
115 ~VideoSegment();
117 void AppendFrame(const VideoChunk& aChunk,
118 const Maybe<bool>& aForceBlack = Nothing(),
119 const Maybe<TimeStamp>& aTimeStamp = Nothing());
120 void AppendFrame(
121 already_AddRefed<Image>&& aImage, const IntSize& aIntrinsicSize,
122 const PrincipalHandle& aPrincipalHandle, bool aForceBlack = false,
123 TimeStamp aTimeStamp = TimeStamp::Now(),
124 media::TimeUnit aProcessingDuration = media::TimeUnit::Invalid(),
125 media::TimeUnit aMediaTime = media::TimeUnit::Invalid());
126 void AppendWebrtcRemoteFrame(already_AddRefed<Image>&& aImage,
127 const IntSize& aIntrinsicSize,
128 const PrincipalHandle& aPrincipalHandle,
129 bool aForceBlack, TimeStamp aTimeStamp,
130 media::TimeUnit aProcessingDuration,
131 uint32_t aRtpTimestamp,
132 int64_t aWebrtcCaptureTimeNtp,
133 int64_t aWebrtcReceiveTimeUs);
134 void AppendWebrtcLocalFrame(already_AddRefed<Image>&& aImage,
135 const IntSize& aIntrinsicSize,
136 const PrincipalHandle& aPrincipalHandle,
137 bool aForceBlack, TimeStamp aTimeStamp,
138 media::TimeUnit aProcessingDuration,
139 TimeStamp aWebrtcCaptureTime);
140 void ExtendLastFrameBy(TrackTime aDuration) {
141 if (aDuration <= 0) {
142 return;
144 if (mChunks.IsEmpty()) {
145 mChunks.AppendElement()->SetNull(aDuration);
146 } else {
147 mChunks[mChunks.Length() - 1].mDuration += aDuration;
149 mDuration += aDuration;
151 const VideoFrame* GetLastFrame(TrackTime* aStart = nullptr) {
152 VideoChunk* c = GetLastChunk();
153 if (!c) {
154 return nullptr;
156 if (aStart) {
157 *aStart = mDuration - c->mDuration;
159 return &c->mFrame;
161 VideoChunk* FindChunkContaining(const TimeStamp& aTime) {
162 VideoChunk* previousChunk = nullptr;
163 for (VideoChunk& c : mChunks) {
164 if (c.mTimeStamp.IsNull()) {
165 continue;
167 if (c.mTimeStamp > aTime) {
168 return previousChunk;
170 previousChunk = &c;
172 return previousChunk;
174 void ForgetUpToTime(const TimeStamp& aTime) {
175 VideoChunk* chunk = FindChunkContaining(aTime);
176 if (!chunk) {
177 return;
179 TrackTime duration = 0;
180 size_t chunksToRemove = 0;
181 for (const VideoChunk& c : mChunks) {
182 if (c.mTimeStamp >= chunk->mTimeStamp) {
183 break;
185 duration += c.GetDuration();
186 ++chunksToRemove;
188 mChunks.RemoveElementsAt(0, chunksToRemove);
189 mDuration -= duration;
190 MOZ_ASSERT(mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
191 "Capacity must be retained after removing chunks");
193 // Override default impl
194 void ReplaceWithDisabled() override {
195 for (ChunkIterator i(*this); !i.IsEnded(); i.Next()) {
196 VideoChunk& chunk = *i;
197 chunk.SetForceBlack(true);
201 // Segment-generic methods not in MediaSegmentBase
202 static Type StaticType() { return VIDEO; }
204 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
205 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
209 } // namespace mozilla
211 #endif /* MOZILLA_VIDEOSEGMENT_H_ */