|
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/. */ |
|
5 |
|
6 #ifndef MOZILLA_VIDEOSEGMENT_H_ |
|
7 #define MOZILLA_VIDEOSEGMENT_H_ |
|
8 |
|
9 #include "MediaSegment.h" |
|
10 #include "nsCOMPtr.h" |
|
11 #include "gfxPoint.h" |
|
12 #include "nsAutoPtr.h" |
|
13 #include "ImageContainer.h" |
|
14 |
|
15 namespace mozilla { |
|
16 |
|
17 namespace layers { |
|
18 class Image; |
|
19 } |
|
20 |
|
21 class VideoFrame { |
|
22 public: |
|
23 typedef mozilla::layers::Image Image; |
|
24 |
|
25 VideoFrame(already_AddRefed<Image>& aImage, const gfxIntSize& aIntrinsicSize); |
|
26 VideoFrame(); |
|
27 ~VideoFrame(); |
|
28 |
|
29 bool operator==(const VideoFrame& aFrame) const |
|
30 { |
|
31 return mIntrinsicSize == aFrame.mIntrinsicSize && |
|
32 mForceBlack == aFrame.mForceBlack && |
|
33 ((mForceBlack && aFrame.mForceBlack) || mImage == aFrame.mImage); |
|
34 } |
|
35 bool operator!=(const VideoFrame& aFrame) const |
|
36 { |
|
37 return !operator==(aFrame); |
|
38 } |
|
39 |
|
40 Image* GetImage() const { return mImage; } |
|
41 void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; } |
|
42 bool GetForceBlack() const { return mForceBlack; } |
|
43 const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; } |
|
44 void SetNull(); |
|
45 void TakeFrom(VideoFrame* aFrame); |
|
46 |
|
47 protected: |
|
48 // mImage can be null to indicate "no video" (aka "empty frame"). It can |
|
49 // still have an intrinsic size in this case. |
|
50 nsRefPtr<Image> mImage; |
|
51 // The desired size to render the video frame at. |
|
52 gfxIntSize mIntrinsicSize; |
|
53 bool mForceBlack; |
|
54 }; |
|
55 |
|
56 struct VideoChunk { |
|
57 VideoChunk(); |
|
58 ~VideoChunk(); |
|
59 void SliceTo(TrackTicks aStart, TrackTicks aEnd) |
|
60 { |
|
61 NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration, |
|
62 "Slice out of bounds"); |
|
63 mDuration = aEnd - aStart; |
|
64 } |
|
65 TrackTicks GetDuration() const { return mDuration; } |
|
66 bool CanCombineWithFollowing(const VideoChunk& aOther) const |
|
67 { |
|
68 return aOther.mFrame == mFrame; |
|
69 } |
|
70 bool IsNull() const { return !mFrame.GetImage(); } |
|
71 void SetNull(TrackTicks aDuration) |
|
72 { |
|
73 mDuration = aDuration; |
|
74 mFrame.SetNull(); |
|
75 mTimeStamp = TimeStamp(); |
|
76 } |
|
77 void SetForceBlack(bool aForceBlack) { mFrame.SetForceBlack(aForceBlack); } |
|
78 |
|
79 size_t SizeOfExcludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const |
|
80 { |
|
81 // Future: |
|
82 // - mFrame |
|
83 return 0; |
|
84 } |
|
85 |
|
86 TrackTicks mDuration; |
|
87 VideoFrame mFrame; |
|
88 mozilla::TimeStamp mTimeStamp; |
|
89 }; |
|
90 |
|
91 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> { |
|
92 public: |
|
93 typedef mozilla::layers::Image Image; |
|
94 typedef mozilla::gfx::IntSize IntSize; |
|
95 |
|
96 VideoSegment(); |
|
97 ~VideoSegment(); |
|
98 |
|
99 void AppendFrame(already_AddRefed<Image>&& aImage, TrackTicks aDuration, |
|
100 const IntSize& aIntrinsicSize); |
|
101 const VideoFrame* GetFrameAt(TrackTicks aOffset, TrackTicks* aStart = nullptr) |
|
102 { |
|
103 VideoChunk* c = FindChunkContaining(aOffset, aStart); |
|
104 if (!c) { |
|
105 return nullptr; |
|
106 } |
|
107 return &c->mFrame; |
|
108 } |
|
109 const VideoFrame* GetLastFrame(TrackTicks* aStart = nullptr) |
|
110 { |
|
111 VideoChunk* c = GetLastChunk(); |
|
112 if (!c) { |
|
113 return nullptr; |
|
114 } |
|
115 if (aStart) { |
|
116 *aStart = mDuration - c->mDuration; |
|
117 } |
|
118 return &c->mFrame; |
|
119 } |
|
120 // Override default impl |
|
121 virtual void ReplaceWithDisabled() MOZ_OVERRIDE { |
|
122 for (ChunkIterator i(*this); |
|
123 !i.IsEnded(); i.Next()) { |
|
124 VideoChunk& chunk = *i; |
|
125 chunk.SetForceBlack(true); |
|
126 } |
|
127 } |
|
128 |
|
129 // Segment-generic methods not in MediaSegmentBase |
|
130 static Type StaticType() { return VIDEO; } |
|
131 |
|
132 virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE |
|
133 { |
|
134 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); |
|
135 } |
|
136 }; |
|
137 |
|
138 } |
|
139 |
|
140 #endif /* MOZILLA_VIDEOSEGMENT_H_ */ |