Bug 1708422: part 16) Rename `mozInlineSpellChecker::SpellCheckerTimeSlice` to `mozIn...
[gecko.git] / dom / media / MediaInfo.h
blob8676e8a2a3cd9e431e3f5b740bdc77878ab02866
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #if !defined(MediaInfo_h)
7 # define MediaInfo_h
9 # include "mozilla/UniquePtr.h"
10 # include "mozilla/RefPtr.h"
11 # include "nsTHashMap.h"
12 # include "nsString.h"
13 # include "nsTArray.h"
14 # include "AudioConfig.h"
15 # include "ImageTypes.h"
16 # include "MediaData.h"
17 # include "TimeUnits.h"
18 # include "mozilla/gfx/Point.h" // for gfx::IntSize
19 # include "mozilla/gfx/Rect.h" // for gfx::IntRect
20 # include "mozilla/gfx/Types.h" // for gfx::ColorDepth
22 namespace mozilla {
24 class AudioInfo;
25 class VideoInfo;
26 class TextInfo;
28 class MetadataTag {
29 public:
30 MetadataTag(const nsACString& aKey, const nsACString& aValue)
31 : mKey(aKey), mValue(aValue) {}
32 nsCString mKey;
33 nsCString mValue;
34 bool operator==(const MetadataTag& rhs) const {
35 return mKey == rhs.mKey && mValue == rhs.mValue;
39 typedef nsTHashMap<nsCStringHashKey, nsCString> MetadataTags;
41 class TrackInfo {
42 public:
43 enum TrackType { kUndefinedTrack, kAudioTrack, kVideoTrack, kTextTrack };
44 TrackInfo(TrackType aType, const nsAString& aId, const nsAString& aKind,
45 const nsAString& aLabel, const nsAString& aLanguage, bool aEnabled,
46 uint32_t aTrackId)
47 : mId(aId),
48 mKind(aKind),
49 mLabel(aLabel),
50 mLanguage(aLanguage),
51 mEnabled(aEnabled),
52 mTrackId(aTrackId),
53 mIsRenderedExternally(false),
54 mType(aType) {
55 MOZ_COUNT_CTOR(TrackInfo);
58 // Only used for backward compatibility. Do not use in new code.
59 void Init(const nsAString& aId, const nsAString& aKind,
60 const nsAString& aLabel, const nsAString& aLanguage,
61 bool aEnabled) {
62 mId = aId;
63 mKind = aKind;
64 mLabel = aLabel;
65 mLanguage = aLanguage;
66 mEnabled = aEnabled;
69 // Fields common with MediaTrack object.
70 nsString mId;
71 nsString mKind;
72 nsString mLabel;
73 nsString mLanguage;
74 bool mEnabled;
76 uint32_t mTrackId;
78 nsCString mMimeType;
79 media::TimeUnit mDuration;
80 media::TimeUnit mMediaTime;
81 CryptoTrack mCrypto;
83 CopyableTArray<MetadataTag> mTags;
85 // True if the track is gonna be (decrypted)/decoded and
86 // rendered directly by non-gecko components.
87 bool mIsRenderedExternally;
89 virtual AudioInfo* GetAsAudioInfo() { return nullptr; }
90 virtual VideoInfo* GetAsVideoInfo() { return nullptr; }
91 virtual TextInfo* GetAsTextInfo() { return nullptr; }
92 virtual const AudioInfo* GetAsAudioInfo() const { return nullptr; }
93 virtual const VideoInfo* GetAsVideoInfo() const { return nullptr; }
94 virtual const TextInfo* GetAsTextInfo() const { return nullptr; }
96 bool IsAudio() const { return !!GetAsAudioInfo(); }
97 bool IsVideo() const { return !!GetAsVideoInfo(); }
98 bool IsText() const { return !!GetAsTextInfo(); }
99 TrackType GetType() const { return mType; }
101 bool virtual IsValid() const = 0;
103 virtual UniquePtr<TrackInfo> Clone() const = 0;
105 MOZ_COUNTED_DTOR_VIRTUAL(TrackInfo)
107 protected:
108 TrackInfo(const TrackInfo& aOther) {
109 mId = aOther.mId;
110 mKind = aOther.mKind;
111 mLabel = aOther.mLabel;
112 mLanguage = aOther.mLanguage;
113 mEnabled = aOther.mEnabled;
114 mTrackId = aOther.mTrackId;
115 mMimeType = aOther.mMimeType;
116 mDuration = aOther.mDuration;
117 mMediaTime = aOther.mMediaTime;
118 mCrypto = aOther.mCrypto;
119 mIsRenderedExternally = aOther.mIsRenderedExternally;
120 mType = aOther.mType;
121 mTags = aOther.mTags.Clone();
122 MOZ_COUNT_CTOR(TrackInfo);
124 bool IsEqualTo(const TrackInfo& rhs) const;
126 private:
127 TrackType mType;
130 // String version of track type.
131 const char* TrackTypeToStr(TrackInfo::TrackType aTrack);
133 // Stores info relevant to presenting media frames.
134 class VideoInfo : public TrackInfo {
135 public:
136 enum Rotation {
137 kDegree_0 = 0,
138 kDegree_90 = 90,
139 kDegree_180 = 180,
140 kDegree_270 = 270,
142 VideoInfo() : VideoInfo(-1, -1) {}
144 VideoInfo(int32_t aWidth, int32_t aHeight)
145 : VideoInfo(gfx::IntSize(aWidth, aHeight)) {}
147 explicit VideoInfo(const gfx::IntSize& aSize)
148 : TrackInfo(kVideoTrack, u"2"_ns, u"main"_ns, u""_ns, u""_ns, true, 2),
149 mDisplay(aSize),
150 mStereoMode(StereoMode::MONO),
151 mImage(aSize),
152 mCodecSpecificConfig(new MediaByteBuffer),
153 mExtraData(new MediaByteBuffer),
154 mRotation(kDegree_0) {}
156 VideoInfo(const VideoInfo& aOther) = default;
158 bool operator==(const VideoInfo& rhs) const;
160 bool IsValid() const override {
161 return mDisplay.width > 0 && mDisplay.height > 0;
164 VideoInfo* GetAsVideoInfo() override { return this; }
166 const VideoInfo* GetAsVideoInfo() const override { return this; }
168 UniquePtr<TrackInfo> Clone() const override {
169 return MakeUnique<VideoInfo>(*this);
172 void SetAlpha(bool aAlphaPresent) { mAlphaPresent = aAlphaPresent; }
174 bool HasAlpha() const { return mAlphaPresent; }
176 gfx::IntRect ImageRect() const {
177 if (!mImageRect) {
178 return gfx::IntRect(0, 0, mImage.width, mImage.height);
180 return *mImageRect;
183 void SetImageRect(const gfx::IntRect& aRect) { mImageRect = Some(aRect); }
184 void ResetImageRect() { mImageRect.reset(); }
186 // Returned the crop rectangle scaled to aWidth/aHeight size relative to
187 // mImage size.
188 // If aWidth and aHeight are identical to the original
189 // mImage.width/mImage.height then the scaling ratio will be 1. This is used
190 // for when the frame size is different from what the container reports. This
191 // is legal in WebM, and we will preserve the ratio of the crop rectangle as
192 // it was reported relative to the picture size reported by the container.
193 gfx::IntRect ScaledImageRect(int64_t aWidth, int64_t aHeight) const {
194 if ((aWidth == mImage.width && aHeight == mImage.height) || !mImage.width ||
195 !mImage.height) {
196 return ImageRect();
199 gfx::IntRect imageRect = ImageRect();
200 int64_t w = (aWidth * imageRect.Width()) / mImage.width;
201 int64_t h = (aHeight * imageRect.Height()) / mImage.height;
202 if (!w || !h) {
203 return imageRect;
206 imageRect.x = (imageRect.x * aWidth) / mImage.width;
207 imageRect.y = (imageRect.y * aHeight) / mImage.height;
208 imageRect.SetWidth(w);
209 imageRect.SetHeight(h);
210 return imageRect;
213 Rotation ToSupportedRotation(int32_t aDegree) const {
214 switch (aDegree) {
215 case 90:
216 return kDegree_90;
217 case 180:
218 return kDegree_180;
219 case 270:
220 return kDegree_270;
221 default:
222 NS_WARNING_ASSERTION(aDegree == 0, "Invalid rotation degree, ignored");
223 return kDegree_0;
227 // Size in pixels at which the video is rendered. This is after it has
228 // been scaled by its aspect ratio.
229 gfx::IntSize mDisplay;
231 // Indicates the frame layout for single track stereo videos.
232 StereoMode mStereoMode;
234 // Size of the decoded video's image.
235 gfx::IntSize mImage;
237 RefPtr<MediaByteBuffer> mCodecSpecificConfig;
238 RefPtr<MediaByteBuffer> mExtraData;
240 // Describing how many degrees video frames should be rotated in clock-wise to
241 // get correct view.
242 Rotation mRotation;
244 // Should be 8, 10 or 12. Default value is 8.
245 gfx::ColorDepth mColorDepth = gfx::ColorDepth::COLOR_8;
247 Maybe<gfx::YUVColorSpace> mColorSpace;
249 // True indicates no restriction on Y, U, V values (otherwise 16-235 for 8
250 // bits etc)
251 gfx::ColorRange mColorRange = gfx::ColorRange::LIMITED;
253 Maybe<int32_t> GetFrameRate() const { return mFrameRate; }
254 void SetFrameRate(int32_t aRate) { mFrameRate = Some(aRate); }
256 private:
257 friend struct IPC::ParamTraits<VideoInfo>;
259 // mImage may be cropped; currently only used with the WebM container.
260 // If unset, no cropping is to occur.
261 Maybe<gfx::IntRect> mImageRect;
263 // Indicates whether or not frames may contain alpha information.
264 bool mAlphaPresent = false;
266 Maybe<int32_t> mFrameRate;
269 class AudioInfo : public TrackInfo {
270 public:
271 AudioInfo()
272 : TrackInfo(kAudioTrack, u"1"_ns, u"main"_ns, u""_ns, u""_ns, true, 1),
273 mRate(0),
274 mChannels(0),
275 mChannelMap(AudioConfig::ChannelLayout::UNKNOWN_MAP),
276 mBitDepth(0),
277 mProfile(0),
278 mExtendedProfile(0),
279 mCodecSpecificConfig(new MediaByteBuffer),
280 mExtraData(new MediaByteBuffer) {}
282 AudioInfo(const AudioInfo& aOther) = default;
284 bool operator==(const AudioInfo& rhs) const;
286 static const uint32_t MAX_RATE = 640000;
288 bool IsValid() const override {
289 return mChannels > 0 && mRate > 0 && mRate <= MAX_RATE;
292 AudioInfo* GetAsAudioInfo() override { return this; }
294 const AudioInfo* GetAsAudioInfo() const override { return this; }
296 UniquePtr<TrackInfo> Clone() const override {
297 return MakeUnique<AudioInfo>(*this);
300 // Sample rate.
301 uint32_t mRate;
303 // Number of audio channels.
304 uint32_t mChannels;
305 // The AudioConfig::ChannelLayout map. Channels are ordered as per SMPTE
306 // definition. A value of UNKNOWN_MAP indicates unknown layout.
307 // ChannelMap is an unsigned bitmap compatible with Windows' WAVE and FFmpeg
308 // channel map.
309 AudioConfig::ChannelLayout::ChannelMap mChannelMap;
311 // Bits per sample.
312 uint32_t mBitDepth;
314 // Codec profile.
315 int8_t mProfile;
317 // Extended codec profile.
318 int8_t mExtendedProfile;
320 RefPtr<MediaByteBuffer> mCodecSpecificConfig;
321 RefPtr<MediaByteBuffer> mExtraData;
324 class EncryptionInfo {
325 public:
326 EncryptionInfo() : mEncrypted(false) {}
328 struct InitData {
329 template <typename AInitDatas>
330 InitData(const nsAString& aType, AInitDatas&& aInitData)
331 : mType(aType), mInitData(std::forward<AInitDatas>(aInitData)) {}
333 // Encryption type to be passed to JS. Usually `cenc'.
334 nsString mType;
336 // Encryption data.
337 CopyableTArray<uint8_t> mInitData;
339 typedef CopyableTArray<InitData> InitDatas;
341 // True if the stream has encryption metadata
342 bool IsEncrypted() const { return mEncrypted; }
344 void Reset() {
345 mEncrypted = false;
346 mInitDatas.Clear();
349 template <typename AInitDatas>
350 void AddInitData(const nsAString& aType, AInitDatas&& aInitData) {
351 mInitDatas.AppendElement(
352 InitData(aType, std::forward<AInitDatas>(aInitData)));
353 mEncrypted = true;
356 void AddInitData(const EncryptionInfo& aInfo) {
357 mInitDatas.AppendElements(aInfo.mInitDatas);
358 mEncrypted = !!mInitDatas.Length();
361 // One 'InitData' per encrypted buffer.
362 InitDatas mInitDatas;
364 private:
365 bool mEncrypted;
368 class MediaInfo {
369 public:
370 bool HasVideo() const { return mVideo.IsValid(); }
372 void EnableVideo() {
373 if (HasVideo()) {
374 return;
376 // Set dummy values so that HasVideo() will return true;
377 // See VideoInfo::IsValid()
378 mVideo.mDisplay = gfx::IntSize(1, 1);
381 bool HasAudio() const { return mAudio.IsValid(); }
383 void EnableAudio() {
384 if (HasAudio()) {
385 return;
387 // Set dummy values so that HasAudio() will return true;
388 // See AudioInfo::IsValid()
389 mAudio.mChannels = 2;
390 mAudio.mRate = 44100;
393 bool IsEncrypted() const {
394 return (HasAudio() && mAudio.mCrypto.IsEncrypted()) ||
395 (HasVideo() && mVideo.mCrypto.IsEncrypted());
398 bool HasValidMedia() const { return HasVideo() || HasAudio(); }
400 // TODO: Store VideoInfo and AudioIndo in arrays to support multi-tracks.
401 VideoInfo mVideo;
402 AudioInfo mAudio;
404 // If the metadata includes a duration, we store it here.
405 media::NullableTimeUnit mMetadataDuration;
407 // The Ogg reader tries to kinda-sorta compute the duration by seeking to the
408 // end and determining the timestamp of the last frame. This isn't useful as
409 // a duration until we know the start time, so we need to track it separately.
410 media::NullableTimeUnit mUnadjustedMetadataEndTime;
412 // True if the media is seekable (i.e. supports random access).
413 bool mMediaSeekable = true;
415 // True if the media is only seekable within its buffered ranges.
416 bool mMediaSeekableOnlyInBufferedRanges = false;
418 EncryptionInfo mCrypto;
420 // The minimum of start times of audio and video tracks.
421 // Use to map the zero time on the media timeline to the first frame.
422 media::TimeUnit mStartTime;
425 class TrackInfoSharedPtr {
426 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TrackInfoSharedPtr)
427 public:
428 TrackInfoSharedPtr(const TrackInfo& aOriginal, uint32_t aStreamID)
429 : mInfo(aOriginal.Clone()),
430 mStreamSourceID(aStreamID),
431 mMimeType(mInfo->mMimeType) {}
433 uint32_t GetID() const { return mStreamSourceID; }
435 operator const TrackInfo*() const { return mInfo.get(); }
437 const TrackInfo* operator*() const { return mInfo.get(); }
439 const TrackInfo* operator->() const {
440 MOZ_ASSERT(mInfo.get(), "dereferencing a UniquePtr containing nullptr");
441 return mInfo.get();
444 const AudioInfo* GetAsAudioInfo() const {
445 return mInfo ? mInfo->GetAsAudioInfo() : nullptr;
448 const VideoInfo* GetAsVideoInfo() const {
449 return mInfo ? mInfo->GetAsVideoInfo() : nullptr;
452 const TextInfo* GetAsTextInfo() const {
453 return mInfo ? mInfo->GetAsTextInfo() : nullptr;
456 private:
457 ~TrackInfoSharedPtr() = default;
458 UniquePtr<TrackInfo> mInfo;
459 // A unique ID, guaranteed to change when changing streams.
460 uint32_t mStreamSourceID;
462 public:
463 const nsCString& mMimeType;
466 } // namespace mozilla
468 #endif // MediaInfo_h