/work/obj-fuzz/dist/include/MediaInfo.h
Line | Count | Source (jump to first uncovered line) |
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 |
8 | | |
9 | | #include "mozilla/UniquePtr.h" |
10 | | #include "mozilla/RefPtr.h" |
11 | | #include "nsDataHashtable.h" |
12 | | #include "nsString.h" |
13 | | #include "nsTArray.h" |
14 | | #include "AudioConfig.h" |
15 | | #include "ImageTypes.h" |
16 | | #include "MediaData.h" |
17 | | #include "TrackID.h" // for TrackID |
18 | | #include "TimeUnits.h" |
19 | | #include "mozilla/gfx/Point.h" // for gfx::IntSize |
20 | | #include "mozilla/gfx/Rect.h" // for gfx::IntRect |
21 | | |
22 | | namespace mozilla { |
23 | | |
24 | | class AudioInfo; |
25 | | class VideoInfo; |
26 | | class TextInfo; |
27 | | |
28 | | class MetadataTag |
29 | | { |
30 | | public: |
31 | | MetadataTag(const nsACString& aKey, |
32 | | const nsACString& aValue) |
33 | | : mKey(aKey) |
34 | | , mValue(aValue) |
35 | 0 | { |
36 | 0 | } |
37 | | nsCString mKey; |
38 | | nsCString mValue; |
39 | | }; |
40 | | |
41 | | typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags; |
42 | | |
43 | | class TrackInfo |
44 | | { |
45 | | public: |
46 | | enum TrackType |
47 | | { |
48 | | kUndefinedTrack, |
49 | | kAudioTrack, |
50 | | kVideoTrack, |
51 | | kTextTrack |
52 | | }; |
53 | | TrackInfo(TrackType aType, |
54 | | const nsAString& aId, |
55 | | const nsAString& aKind, |
56 | | const nsAString& aLabel, |
57 | | const nsAString& aLanguage, |
58 | | bool aEnabled, |
59 | | TrackID aTrackId) |
60 | | : mId(aId) |
61 | | , mKind(aKind) |
62 | | , mLabel(aLabel) |
63 | | , mLanguage(aLanguage) |
64 | | , mEnabled(aEnabled) |
65 | | , mTrackId(aTrackId) |
66 | | , mIsRenderedExternally(false) |
67 | | , mType(aType) |
68 | 0 | { |
69 | 0 | MOZ_COUNT_CTOR(TrackInfo); |
70 | 0 | } |
71 | | |
72 | | // Only used for backward compatibility. Do not use in new code. |
73 | | void Init(const nsAString& aId, |
74 | | const nsAString& aKind, |
75 | | const nsAString& aLabel, |
76 | | const nsAString& aLanguage, |
77 | | bool aEnabled) |
78 | 0 | { |
79 | 0 | mId = aId; |
80 | 0 | mKind = aKind; |
81 | 0 | mLabel = aLabel; |
82 | 0 | mLanguage = aLanguage; |
83 | 0 | mEnabled = aEnabled; |
84 | 0 | } |
85 | | |
86 | | // Fields common with MediaTrack object. |
87 | | nsString mId; |
88 | | nsString mKind; |
89 | | nsString mLabel; |
90 | | nsString mLanguage; |
91 | | bool mEnabled; |
92 | | |
93 | | TrackID mTrackId; |
94 | | |
95 | | nsCString mMimeType; |
96 | | media::TimeUnit mDuration; |
97 | | media::TimeUnit mMediaTime; |
98 | | CryptoTrack mCrypto; |
99 | | |
100 | | nsTArray<MetadataTag> mTags; |
101 | | |
102 | | // True if the track is gonna be (decrypted)/decoded and |
103 | | // rendered directly by non-gecko components. |
104 | | bool mIsRenderedExternally; |
105 | | |
106 | | virtual AudioInfo* GetAsAudioInfo() |
107 | 0 | { |
108 | 0 | return nullptr; |
109 | 0 | } |
110 | | virtual VideoInfo* GetAsVideoInfo() |
111 | 0 | { |
112 | 0 | return nullptr; |
113 | 0 | } |
114 | | virtual TextInfo* GetAsTextInfo() |
115 | 0 | { |
116 | 0 | return nullptr; |
117 | 0 | } |
118 | | virtual const AudioInfo* GetAsAudioInfo() const |
119 | 0 | { |
120 | 0 | return nullptr; |
121 | 0 | } |
122 | | virtual const VideoInfo* GetAsVideoInfo() const |
123 | 0 | { |
124 | 0 | return nullptr; |
125 | 0 | } |
126 | | virtual const TextInfo* GetAsTextInfo() const |
127 | 0 | { |
128 | 0 | return nullptr; |
129 | 0 | } |
130 | | |
131 | | bool IsAudio() const |
132 | 0 | { |
133 | 0 | return !!GetAsAudioInfo(); |
134 | 0 | } |
135 | | bool IsVideo() const |
136 | 0 | { |
137 | 0 | return !!GetAsVideoInfo(); |
138 | 0 | } |
139 | | bool IsText() const |
140 | 0 | { |
141 | 0 | return !!GetAsTextInfo(); |
142 | 0 | } |
143 | | TrackType GetType() const |
144 | 0 | { |
145 | 0 | return mType; |
146 | 0 | } |
147 | | |
148 | | bool virtual IsValid() const = 0; |
149 | | |
150 | | virtual UniquePtr<TrackInfo> Clone() const = 0; |
151 | | |
152 | | virtual ~TrackInfo() |
153 | 0 | { |
154 | 0 | MOZ_COUNT_DTOR(TrackInfo); |
155 | 0 | } |
156 | | |
157 | | protected: |
158 | | TrackInfo(const TrackInfo& aOther) |
159 | 0 | { |
160 | 0 | mId = aOther.mId; |
161 | 0 | mKind = aOther.mKind; |
162 | 0 | mLabel = aOther.mLabel; |
163 | 0 | mLanguage = aOther.mLanguage; |
164 | 0 | mEnabled = aOther.mEnabled; |
165 | 0 | mTrackId = aOther.mTrackId; |
166 | 0 | mMimeType = aOther.mMimeType; |
167 | 0 | mDuration = aOther.mDuration; |
168 | 0 | mMediaTime = aOther.mMediaTime; |
169 | 0 | mCrypto = aOther.mCrypto; |
170 | 0 | mIsRenderedExternally = aOther.mIsRenderedExternally; |
171 | 0 | mType = aOther.mType; |
172 | 0 | mTags = aOther.mTags; |
173 | 0 | MOZ_COUNT_CTOR(TrackInfo); |
174 | 0 | } |
175 | | |
176 | | private: |
177 | | TrackType mType; |
178 | | }; |
179 | | |
180 | | // String version of track type. |
181 | | const char* TrackTypeToStr(TrackInfo::TrackType aTrack); |
182 | | |
183 | | // Stores info relevant to presenting media frames. |
184 | | class VideoInfo : public TrackInfo |
185 | | { |
186 | | public: |
187 | | enum Rotation |
188 | | { |
189 | | kDegree_0 = 0, |
190 | | kDegree_90 = 90, |
191 | | kDegree_180 = 180, |
192 | | kDegree_270 = 270, |
193 | | }; |
194 | | VideoInfo() |
195 | | : VideoInfo(-1, -1) |
196 | 0 | { |
197 | 0 | } |
198 | | |
199 | | explicit VideoInfo(int32_t aWidth, int32_t aHeight) |
200 | | : VideoInfo(gfx::IntSize(aWidth, aHeight)) |
201 | 0 | { |
202 | 0 | } |
203 | | |
204 | | explicit VideoInfo(const gfx::IntSize& aSize) |
205 | | : TrackInfo(kVideoTrack, |
206 | | NS_LITERAL_STRING("2"), |
207 | | NS_LITERAL_STRING("main"), |
208 | | EmptyString(), |
209 | | EmptyString(), |
210 | | true, |
211 | | 2) |
212 | | , mDisplay(aSize) |
213 | | , mStereoMode(StereoMode::MONO) |
214 | | , mImage(aSize) |
215 | | , mCodecSpecificConfig(new MediaByteBuffer) |
216 | | , mExtraData(new MediaByteBuffer) |
217 | | , mRotation(kDegree_0) |
218 | | , mImageRect(gfx::IntRect(gfx::IntPoint(), aSize)) |
219 | 0 | { |
220 | 0 | } |
221 | | |
222 | | VideoInfo(const VideoInfo& aOther) |
223 | | : TrackInfo(aOther) |
224 | | , mDisplay(aOther.mDisplay) |
225 | | , mStereoMode(aOther.mStereoMode) |
226 | | , mImage(aOther.mImage) |
227 | | , mCodecSpecificConfig(aOther.mCodecSpecificConfig) |
228 | | , mExtraData(aOther.mExtraData) |
229 | | , mRotation(aOther.mRotation) |
230 | | , mBitDepth(aOther.mBitDepth) |
231 | | , mImageRect(aOther.mImageRect) |
232 | | , mAlphaPresent(aOther.mAlphaPresent) |
233 | 0 | { |
234 | 0 | } |
235 | | |
236 | | bool IsValid() const override |
237 | 0 | { |
238 | 0 | return mDisplay.width > 0 && mDisplay.height > 0; |
239 | 0 | } |
240 | | |
241 | | VideoInfo* GetAsVideoInfo() override |
242 | 0 | { |
243 | 0 | return this; |
244 | 0 | } |
245 | | |
246 | | const VideoInfo* GetAsVideoInfo() const override |
247 | 0 | { |
248 | 0 | return this; |
249 | 0 | } |
250 | | |
251 | | UniquePtr<TrackInfo> Clone() const override |
252 | 0 | { |
253 | 0 | return MakeUnique<VideoInfo>(*this); |
254 | 0 | } |
255 | | |
256 | | void SetAlpha(bool aAlphaPresent) |
257 | 0 | { |
258 | 0 | mAlphaPresent = aAlphaPresent; |
259 | 0 | } |
260 | | |
261 | | bool HasAlpha() const |
262 | 0 | { |
263 | 0 | return mAlphaPresent; |
264 | 0 | } |
265 | | |
266 | | gfx::IntRect ImageRect() const |
267 | 0 | { |
268 | 0 | if (mImageRect.Width() < 0 || mImageRect.Height() < 0) { |
269 | 0 | return gfx::IntRect(0, 0, mImage.width, mImage.height); |
270 | 0 | } |
271 | 0 | return mImageRect; |
272 | 0 | } |
273 | | |
274 | 0 | void SetImageRect(const gfx::IntRect& aRect) { mImageRect = aRect; } |
275 | | |
276 | | // Returned the crop rectangle scaled to aWidth/aHeight size relative to |
277 | | // mImage size. |
278 | | // If aWidth and aHeight are identical to the original mImage.width/mImage.height |
279 | | // then the scaling ratio will be 1. |
280 | | // This is used for when the frame size is different from what the container |
281 | | // reports. This is legal in WebM, and we will preserve the ratio of the crop |
282 | | // rectangle as it was reported relative to the picture size reported by the |
283 | | // container. |
284 | | gfx::IntRect ScaledImageRect(int64_t aWidth, int64_t aHeight) const |
285 | 0 | { |
286 | 0 | if ((aWidth == mImage.width && aHeight == mImage.height) || |
287 | 0 | !mImage.width || |
288 | 0 | !mImage.height) { |
289 | 0 | return ImageRect(); |
290 | 0 | } |
291 | 0 | |
292 | 0 | gfx::IntRect imageRect = ImageRect(); |
293 | 0 | int64_t w = (aWidth * imageRect.Width()) / mImage.width; |
294 | 0 | int64_t h = (aHeight * imageRect.Height()) / mImage.height; |
295 | 0 | if (!w || !h) { |
296 | 0 | return imageRect; |
297 | 0 | } |
298 | 0 | |
299 | 0 | imageRect.x = (imageRect.x * aWidth) / mImage.width; |
300 | 0 | imageRect.y = (imageRect.y * aHeight) / mImage.height; |
301 | 0 | imageRect.SetWidth(w); |
302 | 0 | imageRect.SetHeight(h); |
303 | 0 | return imageRect; |
304 | 0 | } |
305 | | |
306 | | Rotation ToSupportedRotation(int32_t aDegree) const |
307 | 0 | { |
308 | 0 | switch (aDegree) { |
309 | 0 | case 90: |
310 | 0 | return kDegree_90; |
311 | 0 | case 180: |
312 | 0 | return kDegree_180; |
313 | 0 | case 270: |
314 | 0 | return kDegree_270; |
315 | 0 | default: |
316 | 0 | NS_WARNING_ASSERTION(aDegree == 0, "Invalid rotation degree, ignored"); |
317 | 0 | return kDegree_0; |
318 | 0 | } |
319 | 0 | } |
320 | | |
321 | | // Size in pixels at which the video is rendered. This is after it has |
322 | | // been scaled by its aspect ratio. |
323 | | gfx::IntSize mDisplay; |
324 | | |
325 | | // Indicates the frame layout for single track stereo videos. |
326 | | StereoMode mStereoMode; |
327 | | |
328 | | // Size of the decoded video's image. |
329 | | gfx::IntSize mImage; |
330 | | |
331 | | RefPtr<MediaByteBuffer> mCodecSpecificConfig; |
332 | | RefPtr<MediaByteBuffer> mExtraData; |
333 | | |
334 | | // Describing how many degrees video frames should be rotated in clock-wise to |
335 | | // get correct view. |
336 | | Rotation mRotation; |
337 | | |
338 | | // Should be 8, 10 or 12. Default value is 8. |
339 | | uint8_t mBitDepth = 8; |
340 | | |
341 | | private: |
342 | | // mImage may be cropped; currently only used with the WebM container. |
343 | | // A negative width or height indicate that no cropping is to occur. |
344 | | gfx::IntRect mImageRect; |
345 | | |
346 | | // Indicates whether or not frames may contain alpha information. |
347 | | bool mAlphaPresent = false; |
348 | | }; |
349 | | |
350 | | class AudioInfo : public TrackInfo |
351 | | { |
352 | | public: |
353 | | AudioInfo() |
354 | | : TrackInfo(kAudioTrack, NS_LITERAL_STRING("1"), NS_LITERAL_STRING("main"), |
355 | | EmptyString(), EmptyString(), true, 1) |
356 | | , mRate(0) |
357 | | , mChannels(0) |
358 | | , mChannelMap(AudioConfig::ChannelLayout::UNKNOWN_MAP) |
359 | | , mBitDepth(0) |
360 | | , mProfile(0) |
361 | | , mExtendedProfile(0) |
362 | | , mCodecSpecificConfig(new MediaByteBuffer) |
363 | | , mExtraData(new MediaByteBuffer) |
364 | 0 | { |
365 | 0 | } |
366 | | |
367 | | AudioInfo(const AudioInfo& aOther) |
368 | | : TrackInfo(aOther) |
369 | | , mRate(aOther.mRate) |
370 | | , mChannels(aOther.mChannels) |
371 | | , mChannelMap(aOther.mChannelMap) |
372 | | , mBitDepth(aOther.mBitDepth) |
373 | | , mProfile(aOther.mProfile) |
374 | | , mExtendedProfile(aOther.mExtendedProfile) |
375 | | , mCodecSpecificConfig(aOther.mCodecSpecificConfig) |
376 | | , mExtraData(aOther.mExtraData) |
377 | 0 | { |
378 | 0 | } |
379 | | |
380 | | static const uint32_t MAX_RATE = 640000; |
381 | | |
382 | | bool IsValid() const override |
383 | 0 | { |
384 | 0 | return mChannels > 0 && mRate > 0 && mRate <= MAX_RATE; |
385 | 0 | } |
386 | | |
387 | | AudioInfo* GetAsAudioInfo() override |
388 | 0 | { |
389 | 0 | return this; |
390 | 0 | } |
391 | | |
392 | | const AudioInfo* GetAsAudioInfo() const override |
393 | 0 | { |
394 | 0 | return this; |
395 | 0 | } |
396 | | |
397 | | UniquePtr<TrackInfo> Clone() const override |
398 | 0 | { |
399 | 0 | return MakeUnique<AudioInfo>(*this); |
400 | 0 | } |
401 | | |
402 | | // Sample rate. |
403 | | uint32_t mRate; |
404 | | |
405 | | // Number of audio channels. |
406 | | uint32_t mChannels; |
407 | | // The AudioConfig::ChannelLayout map. Channels are ordered as per SMPTE |
408 | | // definition. A value of UNKNOWN_MAP indicates unknown layout. |
409 | | // ChannelMap is an unsigned bitmap compatible with Windows' WAVE and FFmpeg |
410 | | // channel map. |
411 | | AudioConfig::ChannelLayout::ChannelMap mChannelMap; |
412 | | |
413 | | // Bits per sample. |
414 | | uint32_t mBitDepth; |
415 | | |
416 | | // Codec profile. |
417 | | int8_t mProfile; |
418 | | |
419 | | // Extended codec profile. |
420 | | int8_t mExtendedProfile; |
421 | | |
422 | | RefPtr<MediaByteBuffer> mCodecSpecificConfig; |
423 | | RefPtr<MediaByteBuffer> mExtraData; |
424 | | }; |
425 | | |
426 | | class EncryptionInfo |
427 | | { |
428 | | public: |
429 | | EncryptionInfo() |
430 | | : mEncrypted(false) |
431 | 0 | { |
432 | 0 | } |
433 | | |
434 | | struct InitData |
435 | | { |
436 | | template<typename AInitDatas> |
437 | | InitData(const nsAString& aType, AInitDatas&& aInitData) |
438 | | : mType(aType) |
439 | | , mInitData(std::forward<AInitDatas>(aInitData)) |
440 | 0 | { |
441 | 0 | } Unexecuted instantiation: mozilla::EncryptionInfo::InitData::InitData<nsTArray<unsigned char> const&>(nsTSubstring<char16_t> const&, nsTArray<unsigned char> const&) Unexecuted instantiation: mozilla::EncryptionInfo::InitData::InitData<nsTArray<unsigned char>&>(nsTSubstring<char16_t> const&, nsTArray<unsigned char>&) |
442 | | |
443 | | // Encryption type to be passed to JS. Usually `cenc'. |
444 | | nsString mType; |
445 | | |
446 | | // Encryption data. |
447 | | nsTArray<uint8_t> mInitData; |
448 | | }; |
449 | | typedef nsTArray<InitData> InitDatas; |
450 | | |
451 | | // True if the stream has encryption metadata |
452 | | bool IsEncrypted() const |
453 | 0 | { |
454 | 0 | return mEncrypted; |
455 | 0 | } |
456 | | |
457 | | void Reset() |
458 | 0 | { |
459 | 0 | mEncrypted = false; |
460 | 0 | mInitDatas.Clear(); |
461 | 0 | } |
462 | | |
463 | | template<typename AInitDatas> |
464 | | void AddInitData(const nsAString& aType, AInitDatas&& aInitData) |
465 | 0 | { |
466 | 0 | mInitDatas.AppendElement(InitData(aType, std::forward<AInitDatas>(aInitData))); |
467 | 0 | mEncrypted = true; |
468 | 0 | } Unexecuted instantiation: void mozilla::EncryptionInfo::AddInitData<nsTArray<unsigned char> const&>(nsTSubstring<char16_t> const&, nsTArray<unsigned char> const&) Unexecuted instantiation: void mozilla::EncryptionInfo::AddInitData<nsTArray<unsigned char>&>(nsTSubstring<char16_t> const&, nsTArray<unsigned char>&) |
469 | | |
470 | | void AddInitData(const EncryptionInfo& aInfo) |
471 | 0 | { |
472 | 0 | mInitDatas.AppendElements(aInfo.mInitDatas); |
473 | 0 | mEncrypted = !!mInitDatas.Length(); |
474 | 0 | } |
475 | | |
476 | | // One 'InitData' per encrypted buffer. |
477 | | InitDatas mInitDatas; |
478 | | private: |
479 | | bool mEncrypted; |
480 | | }; |
481 | | |
482 | | class MediaInfo |
483 | | { |
484 | | public: |
485 | | bool HasVideo() const |
486 | 0 | { |
487 | 0 | return mVideo.IsValid(); |
488 | 0 | } |
489 | | |
490 | | void EnableVideo() |
491 | 0 | { |
492 | 0 | if (HasVideo()) { |
493 | 0 | return; |
494 | 0 | } |
495 | 0 | // Set dummy values so that HasVideo() will return true; |
496 | 0 | // See VideoInfo::IsValid() |
497 | 0 | mVideo.mDisplay = gfx::IntSize(1, 1); |
498 | 0 | } |
499 | | |
500 | | bool HasAudio() const |
501 | 0 | { |
502 | 0 | return mAudio.IsValid(); |
503 | 0 | } |
504 | | |
505 | | void EnableAudio() |
506 | 0 | { |
507 | 0 | if (HasAudio()) { |
508 | 0 | return; |
509 | 0 | } |
510 | 0 | // Set dummy values so that HasAudio() will return true; |
511 | 0 | // See AudioInfo::IsValid() |
512 | 0 | mAudio.mChannels = 2; |
513 | 0 | mAudio.mRate = 44100; |
514 | 0 | } |
515 | | |
516 | | bool IsEncrypted() const |
517 | 0 | { |
518 | 0 | return (HasAudio() && mAudio.mCrypto.mValid) || |
519 | 0 | (HasVideo() && mVideo.mCrypto.mValid); |
520 | 0 | } |
521 | | |
522 | | bool HasValidMedia() const |
523 | 0 | { |
524 | 0 | return HasVideo() || HasAudio(); |
525 | 0 | } |
526 | | |
527 | | void AssertValid() const |
528 | 0 | { |
529 | 0 | NS_ASSERTION(!HasAudio() || mAudio.mTrackId != TRACK_INVALID, |
530 | 0 | "Audio track ID must be valid"); |
531 | 0 | NS_ASSERTION(!HasVideo() || mVideo.mTrackId != TRACK_INVALID, |
532 | 0 | "Audio track ID must be valid"); |
533 | 0 | NS_ASSERTION(!HasAudio() || !HasVideo() || |
534 | 0 | mAudio.mTrackId != mVideo.mTrackId, |
535 | 0 | "Duplicate track IDs"); |
536 | 0 | } |
537 | | |
538 | | // TODO: Store VideoInfo and AudioIndo in arrays to support multi-tracks. |
539 | | VideoInfo mVideo; |
540 | | AudioInfo mAudio; |
541 | | |
542 | | // If the metadata includes a duration, we store it here. |
543 | | media::NullableTimeUnit mMetadataDuration; |
544 | | |
545 | | // The Ogg reader tries to kinda-sorta compute the duration by seeking to the |
546 | | // end and determining the timestamp of the last frame. This isn't useful as |
547 | | // a duration until we know the start time, so we need to track it separately. |
548 | | media::NullableTimeUnit mUnadjustedMetadataEndTime; |
549 | | |
550 | | // True if the media is seekable (i.e. supports random access). |
551 | | bool mMediaSeekable = true; |
552 | | |
553 | | // True if the media is only seekable within its buffered ranges. |
554 | | bool mMediaSeekableOnlyInBufferedRanges = false; |
555 | | |
556 | | EncryptionInfo mCrypto; |
557 | | |
558 | | // The minimum of start times of audio and video tracks. |
559 | | // Use to map the zero time on the media timeline to the first frame. |
560 | | media::TimeUnit mStartTime; |
561 | | }; |
562 | | |
563 | | class TrackInfoSharedPtr |
564 | | { |
565 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TrackInfoSharedPtr) |
566 | | public: |
567 | | TrackInfoSharedPtr(const TrackInfo& aOriginal, uint32_t aStreamID) |
568 | | : mInfo(aOriginal.Clone()) |
569 | | , mStreamSourceID(aStreamID) |
570 | | , mMimeType(mInfo->mMimeType) |
571 | 0 | { |
572 | 0 | } |
573 | | |
574 | | uint32_t GetID() const |
575 | | { |
576 | | return mStreamSourceID; |
577 | | } |
578 | | |
579 | | operator const TrackInfo*() const |
580 | | { |
581 | | return mInfo.get(); |
582 | | } |
583 | | |
584 | | const TrackInfo* operator*() const |
585 | 0 | { |
586 | 0 | return mInfo.get(); |
587 | 0 | } |
588 | | |
589 | | const TrackInfo* operator->() const |
590 | | { |
591 | | MOZ_ASSERT(mInfo.get(), "dereferencing a UniquePtr containing nullptr"); |
592 | | return mInfo.get(); |
593 | | } |
594 | | |
595 | | const AudioInfo* GetAsAudioInfo() const |
596 | 0 | { |
597 | 0 | return mInfo ? mInfo->GetAsAudioInfo() : nullptr; |
598 | 0 | } |
599 | | |
600 | | const VideoInfo* GetAsVideoInfo() const |
601 | 0 | { |
602 | 0 | return mInfo ? mInfo->GetAsVideoInfo() : nullptr; |
603 | 0 | } |
604 | | |
605 | | const TextInfo* GetAsTextInfo() const |
606 | 0 | { |
607 | 0 | return mInfo ? mInfo->GetAsTextInfo() : nullptr; |
608 | 0 | } |
609 | | |
610 | | private: |
611 | 0 | ~TrackInfoSharedPtr() { } |
612 | | UniquePtr<TrackInfo> mInfo; |
613 | | // A unique ID, guaranteed to change when changing streams. |
614 | | uint32_t mStreamSourceID; |
615 | | |
616 | | public: |
617 | | const nsCString& mMimeType; |
618 | | }; |
619 | | |
620 | | } // namespace mozilla |
621 | | |
622 | | #endif // MediaInfo_h |