Line data Source code
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 "nsRect.h"
11 : #include "mozilla/RefPtr.h"
12 : #include "nsSize.h"
13 : #include "nsString.h"
14 : #include "nsTArray.h"
15 : #include "ImageTypes.h"
16 : #include "MediaData.h"
17 : #include "StreamTracks.h" // for TrackID
18 : #include "TimeUnits.h"
19 :
20 : namespace mozilla {
21 :
22 : class AudioInfo;
23 : class VideoInfo;
24 : class TextInfo;
25 :
26 0 : class MetadataTag
27 : {
28 : public:
29 0 : MetadataTag(const nsACString& aKey,
30 : const nsACString& aValue)
31 0 : : mKey(aKey)
32 0 : , mValue(aValue)
33 : {
34 0 : }
35 : nsCString mKey;
36 : nsCString mValue;
37 : };
38 :
39 : // Maximum channel number we can currently handle (7.1)
40 : #define MAX_AUDIO_CHANNELS 8
41 :
42 0 : class TrackInfo
43 : {
44 : public:
45 : enum TrackType
46 : {
47 : kUndefinedTrack,
48 : kAudioTrack,
49 : kVideoTrack,
50 : kTextTrack
51 : };
52 2 : TrackInfo(TrackType aType,
53 : const nsAString& aId,
54 : const nsAString& aKind,
55 : const nsAString& aLabel,
56 : const nsAString& aLanguage,
57 : bool aEnabled,
58 : TrackID aTrackId)
59 2 : : mId(aId)
60 : , mKind(aKind)
61 : , mLabel(aLabel)
62 : , mLanguage(aLanguage)
63 : , mEnabled(aEnabled)
64 : , mTrackId(aTrackId)
65 : , mIsRenderedExternally(false)
66 2 : , mType(aType)
67 : {
68 2 : MOZ_COUNT_CTOR(TrackInfo);
69 2 : }
70 :
71 : // Only used for backward compatibility. Do not use in new code.
72 0 : void Init(const nsAString& aId,
73 : const nsAString& aKind,
74 : const nsAString& aLabel,
75 : const nsAString& aLanguage,
76 : bool aEnabled)
77 : {
78 0 : mId = aId;
79 0 : mKind = aKind;
80 0 : mLabel = aLabel;
81 0 : mLanguage = aLanguage;
82 0 : mEnabled = aEnabled;
83 0 : }
84 :
85 : // Fields common with MediaTrack object.
86 : nsString mId;
87 : nsString mKind;
88 : nsString mLabel;
89 : nsString mLanguage;
90 : bool mEnabled;
91 :
92 : TrackID mTrackId;
93 :
94 : nsCString mMimeType;
95 : media::TimeUnit mDuration;
96 : media::TimeUnit mMediaTime;
97 : CryptoTrack mCrypto;
98 :
99 : nsTArray<MetadataTag> mTags;
100 :
101 : // True if the track is gonna be (decrypted)/decoded and
102 : // rendered directly by non-gecko components.
103 : bool mIsRenderedExternally;
104 :
105 0 : virtual AudioInfo* GetAsAudioInfo()
106 : {
107 0 : return nullptr;
108 : }
109 0 : virtual VideoInfo* GetAsVideoInfo()
110 : {
111 0 : return nullptr;
112 : }
113 0 : virtual TextInfo* GetAsTextInfo()
114 : {
115 0 : return nullptr;
116 : }
117 0 : virtual const AudioInfo* GetAsAudioInfo() const
118 : {
119 0 : return nullptr;
120 : }
121 0 : virtual const VideoInfo* GetAsVideoInfo() const
122 : {
123 0 : return nullptr;
124 : }
125 0 : virtual const TextInfo* GetAsTextInfo() const
126 : {
127 0 : return nullptr;
128 : }
129 :
130 0 : bool IsAudio() const
131 : {
132 0 : return !!GetAsAudioInfo();
133 : }
134 0 : bool IsVideo() const
135 : {
136 0 : return !!GetAsVideoInfo();
137 : }
138 : bool IsText() const
139 : {
140 : return !!GetAsTextInfo();
141 : }
142 0 : TrackType GetType() const
143 : {
144 0 : return mType;
145 : }
146 :
147 : bool virtual IsValid() const = 0;
148 :
149 : virtual UniquePtr<TrackInfo> Clone() const = 0;
150 :
151 0 : virtual ~TrackInfo()
152 0 : {
153 0 : MOZ_COUNT_DTOR(TrackInfo);
154 0 : }
155 :
156 : protected:
157 0 : TrackInfo(const TrackInfo& aOther)
158 0 : {
159 0 : mId = aOther.mId;
160 0 : mKind = aOther.mKind;
161 0 : mLabel = aOther.mLabel;
162 0 : mLanguage = aOther.mLanguage;
163 0 : mEnabled = aOther.mEnabled;
164 0 : mTrackId = aOther.mTrackId;
165 0 : mMimeType = aOther.mMimeType;
166 0 : mDuration = aOther.mDuration;
167 0 : mMediaTime = aOther.mMediaTime;
168 0 : mCrypto = aOther.mCrypto;
169 0 : mIsRenderedExternally = aOther.mIsRenderedExternally;
170 0 : mType = aOther.mType;
171 0 : mTags = aOther.mTags;
172 0 : MOZ_COUNT_CTOR(TrackInfo);
173 0 : }
174 :
175 : private:
176 : TrackType mType;
177 : };
178 :
179 : // String version of track type.
180 : const char* TrackTypeToStr(TrackInfo::TrackType aTrack);
181 :
182 : // Stores info relevant to presenting media frames.
183 0 : class VideoInfo : public TrackInfo
184 : {
185 : public:
186 : enum Rotation
187 : {
188 : kDegree_0 = 0,
189 : kDegree_90 = 90,
190 : kDegree_180 = 180,
191 : kDegree_270 = 270,
192 : };
193 1 : VideoInfo()
194 1 : : VideoInfo(-1, -1)
195 : {
196 1 : }
197 :
198 1 : explicit VideoInfo(int32_t aWidth, int32_t aHeight)
199 1 : : VideoInfo(nsIntSize(aWidth, aHeight))
200 : {
201 1 : }
202 :
203 1 : explicit VideoInfo(const nsIntSize& aSize)
204 4 : : TrackInfo(kVideoTrack, NS_LITERAL_STRING("2"), NS_LITERAL_STRING("main"),
205 2 : EmptyString(), EmptyString(), true, 2)
206 : , mDisplay(aSize)
207 : , mStereoMode(StereoMode::MONO)
208 : , mImage(aSize)
209 1 : , mCodecSpecificConfig(new MediaByteBuffer)
210 1 : , mExtraData(new MediaByteBuffer)
211 : , mRotation(kDegree_0)
212 7 : , mImageRect(nsIntRect(nsIntPoint(), aSize))
213 : {
214 1 : }
215 :
216 0 : VideoInfo(const VideoInfo& aOther)
217 0 : : TrackInfo(aOther)
218 : , mDisplay(aOther.mDisplay)
219 0 : , mStereoMode(aOther.mStereoMode)
220 : , mImage(aOther.mImage)
221 : , mCodecSpecificConfig(aOther.mCodecSpecificConfig)
222 : , mExtraData(aOther.mExtraData)
223 0 : , mRotation(aOther.mRotation)
224 : , mImageRect(aOther.mImageRect)
225 0 : , mAlphaPresent(aOther.mAlphaPresent)
226 : {
227 0 : }
228 :
229 0 : bool IsValid() const override
230 : {
231 0 : return mDisplay.width > 0 && mDisplay.height > 0;
232 : }
233 :
234 0 : VideoInfo* GetAsVideoInfo() override
235 : {
236 0 : return this;
237 : }
238 :
239 0 : const VideoInfo* GetAsVideoInfo() const override
240 : {
241 0 : return this;
242 : }
243 :
244 0 : UniquePtr<TrackInfo> Clone() const override
245 : {
246 0 : return MakeUnique<VideoInfo>(*this);
247 : }
248 :
249 0 : void SetAlpha(bool aAlphaPresent)
250 : {
251 0 : mAlphaPresent = aAlphaPresent;
252 0 : }
253 :
254 0 : bool HasAlpha() const
255 : {
256 0 : return mAlphaPresent;
257 : }
258 :
259 0 : nsIntRect ImageRect() const
260 : {
261 0 : if (mImageRect.width < 0 || mImageRect.height < 0) {
262 0 : return nsIntRect(0, 0, mImage.width, mImage.height);
263 : }
264 0 : return mImageRect;
265 : }
266 :
267 0 : void SetImageRect(const nsIntRect& aRect)
268 : {
269 0 : mImageRect = aRect;
270 0 : }
271 :
272 : // Returned the crop rectangle scaled to aWidth/aHeight size relative to
273 : // mImage size.
274 : // If aWidth and aHeight are identical to the original mImage.width/mImage.height
275 : // then the scaling ratio will be 1.
276 : // This is used for when the frame size is different from what the container
277 : // reports. This is legal in WebM, and we will preserve the ratio of the crop
278 : // rectangle as it was reported relative to the picture size reported by the
279 : // container.
280 0 : nsIntRect ScaledImageRect(int64_t aWidth, int64_t aHeight) const
281 : {
282 0 : if ((aWidth == mImage.width && aHeight == mImage.height)
283 0 : || !mImage.width
284 0 : || !mImage.height) {
285 0 : return ImageRect();
286 : }
287 0 : nsIntRect imageRect = ImageRect();
288 0 : imageRect.x = (imageRect.x * aWidth) / mImage.width;
289 0 : imageRect.y = (imageRect.y * aHeight) / mImage.height;
290 0 : imageRect.width = (aWidth * imageRect.width) / mImage.width;
291 0 : imageRect.height = (aHeight * imageRect.height) / mImage.height;
292 0 : return imageRect;
293 : }
294 :
295 0 : Rotation ToSupportedRotation(int32_t aDegree)
296 : {
297 0 : switch (aDegree) {
298 : case 90:
299 0 : return kDegree_90;
300 : case 180:
301 0 : return kDegree_180;
302 : case 270:
303 0 : return kDegree_270;
304 : default:
305 0 : NS_WARNING_ASSERTION(aDegree == 0, "Invalid rotation degree, ignored");
306 0 : return kDegree_0;
307 : }
308 : }
309 :
310 : // Size in pixels at which the video is rendered. This is after it has
311 : // been scaled by its aspect ratio.
312 : nsIntSize mDisplay;
313 :
314 : // Indicates the frame layout for single track stereo videos.
315 : StereoMode mStereoMode;
316 :
317 : // Size of the decoded video's image.
318 : nsIntSize mImage;
319 :
320 : RefPtr<MediaByteBuffer> mCodecSpecificConfig;
321 : RefPtr<MediaByteBuffer> mExtraData;
322 :
323 : // Describing how many degrees video frames should be rotated in clock-wise to
324 : // get correct view.
325 : Rotation mRotation;
326 :
327 : private:
328 : // mImage may be cropped; currently only used with the WebM container.
329 : // A negative width or height indicate that no cropping is to occur.
330 : nsIntRect mImageRect;
331 :
332 : // Indicates whether or not frames may contain alpha information.
333 : bool mAlphaPresent = false;
334 : };
335 :
336 0 : class AudioInfo : public TrackInfo
337 : {
338 : public:
339 1 : AudioInfo()
340 4 : : TrackInfo(kAudioTrack, NS_LITERAL_STRING("1"), NS_LITERAL_STRING("main"),
341 2 : EmptyString(), EmptyString(), true, 1)
342 : , mRate(0)
343 : , mChannels(0)
344 : , mBitDepth(0)
345 : , mProfile(0)
346 : , mExtendedProfile(0)
347 1 : , mCodecSpecificConfig(new MediaByteBuffer)
348 7 : , mExtraData(new MediaByteBuffer)
349 : {
350 1 : }
351 :
352 0 : AudioInfo(const AudioInfo& aOther)
353 0 : : TrackInfo(aOther)
354 0 : , mRate(aOther.mRate)
355 0 : , mChannels(aOther.mChannels)
356 0 : , mBitDepth(aOther.mBitDepth)
357 0 : , mProfile(aOther.mProfile)
358 0 : , mExtendedProfile(aOther.mExtendedProfile)
359 : , mCodecSpecificConfig(aOther.mCodecSpecificConfig)
360 0 : , mExtraData(aOther.mExtraData)
361 : {
362 0 : }
363 :
364 : static const uint32_t MAX_RATE = 640000;
365 :
366 1 : bool IsValid() const override
367 : {
368 1 : return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS
369 1 : && mRate > 0 && mRate <= MAX_RATE;
370 : }
371 :
372 0 : AudioInfo* GetAsAudioInfo() override
373 : {
374 0 : return this;
375 : }
376 :
377 0 : const AudioInfo* GetAsAudioInfo() const override
378 : {
379 0 : return this;
380 : }
381 :
382 0 : UniquePtr<TrackInfo> Clone() const override
383 : {
384 0 : return MakeUnique<AudioInfo>(*this);
385 : }
386 :
387 : // Sample rate.
388 : uint32_t mRate;
389 :
390 : // Number of audio channels.
391 : uint32_t mChannels;
392 :
393 : // Bits per sample.
394 : uint32_t mBitDepth;
395 :
396 : // Codec profile.
397 : int8_t mProfile;
398 :
399 : // Extended codec profile.
400 : int8_t mExtendedProfile;
401 :
402 : RefPtr<MediaByteBuffer> mCodecSpecificConfig;
403 : RefPtr<MediaByteBuffer> mExtraData;
404 : };
405 :
406 0 : class EncryptionInfo
407 : {
408 : public:
409 2 : EncryptionInfo()
410 2 : : mEncrypted(false)
411 : {
412 2 : }
413 :
414 0 : struct InitData
415 : {
416 : template<typename AInitDatas>
417 0 : InitData(const nsAString& aType, AInitDatas&& aInitData)
418 : : mType(aType)
419 0 : , mInitData(Forward<AInitDatas>(aInitData))
420 : {
421 0 : }
422 :
423 : // Encryption type to be passed to JS. Usually `cenc'.
424 : nsString mType;
425 :
426 : // Encryption data.
427 : nsTArray<uint8_t> mInitData;
428 : };
429 : typedef nsTArray<InitData> InitDatas;
430 :
431 : // True if the stream has encryption metadata
432 0 : bool IsEncrypted() const
433 : {
434 0 : return mEncrypted;
435 : }
436 :
437 0 : void Reset()
438 : {
439 0 : mEncrypted = false;
440 0 : mInitDatas.Clear();
441 0 : }
442 :
443 : template<typename AInitDatas>
444 0 : void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
445 : {
446 0 : mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
447 0 : mEncrypted = true;
448 0 : }
449 :
450 : void AddInitData(const EncryptionInfo& aInfo)
451 : {
452 : mInitDatas.AppendElements(aInfo.mInitDatas);
453 : mEncrypted = !!mInitDatas.Length();
454 : }
455 :
456 : // One 'InitData' per encrypted buffer.
457 : InitDatas mInitDatas;
458 : private:
459 : bool mEncrypted;
460 : };
461 :
462 1 : class MediaInfo
463 : {
464 : public:
465 0 : bool HasVideo() const
466 : {
467 0 : return mVideo.IsValid();
468 : }
469 :
470 0 : void EnableVideo()
471 : {
472 0 : if (HasVideo()) {
473 0 : return;
474 : }
475 : // Set dummy values so that HasVideo() will return true;
476 : // See VideoInfo::IsValid()
477 0 : mVideo.mDisplay = nsIntSize(1, 1);
478 : }
479 :
480 1 : bool HasAudio() const
481 : {
482 1 : return mAudio.IsValid();
483 : }
484 :
485 0 : void EnableAudio()
486 : {
487 0 : if (HasAudio()) {
488 0 : return;
489 : }
490 : // Set dummy values so that HasAudio() will return true;
491 : // See AudioInfo::IsValid()
492 0 : mAudio.mChannels = 2;
493 0 : mAudio.mRate = 44100;
494 : }
495 :
496 0 : bool IsEncrypted() const
497 : {
498 0 : return (HasAudio() && mAudio.mCrypto.mValid)
499 0 : || (HasVideo() && mVideo.mCrypto.mValid);
500 : }
501 :
502 0 : bool HasValidMedia() const
503 : {
504 0 : return HasVideo() || HasAudio();
505 : }
506 :
507 0 : void AssertValid() const
508 : {
509 0 : NS_ASSERTION(!HasAudio() || mAudio.mTrackId != TRACK_INVALID,
510 : "Audio track ID must be valid");
511 0 : NS_ASSERTION(!HasVideo() || mVideo.mTrackId != TRACK_INVALID,
512 : "Audio track ID must be valid");
513 0 : NS_ASSERTION(!HasAudio()
514 : || !HasVideo()
515 : || mAudio.mTrackId != mVideo.mTrackId,
516 : "Duplicate track IDs");
517 0 : }
518 :
519 : // TODO: Store VideoInfo and AudioIndo in arrays to support multi-tracks.
520 : VideoInfo mVideo;
521 : AudioInfo mAudio;
522 :
523 : // If the metadata includes a duration, we store it here.
524 : media::NullableTimeUnit mMetadataDuration;
525 :
526 : // The Ogg reader tries to kinda-sorta compute the duration by seeking to the
527 : // end and determining the timestamp of the last frame. This isn't useful as
528 : // a duration until we know the start time, so we need to track it separately.
529 : media::NullableTimeUnit mUnadjustedMetadataEndTime;
530 :
531 : // True if the media is seekable (i.e. supports random access).
532 : bool mMediaSeekable = true;
533 :
534 : // True if the media is only seekable within its buffered ranges.
535 : bool mMediaSeekableOnlyInBufferedRanges = false;
536 :
537 : EncryptionInfo mCrypto;
538 :
539 : // The minimum of start times of audio and video tracks.
540 : // Use to map the zero time on the media timeline to the first frame.
541 : media::TimeUnit mStartTime;
542 : };
543 :
544 : class TrackInfoSharedPtr
545 : {
546 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TrackInfoSharedPtr)
547 : public:
548 0 : TrackInfoSharedPtr(const TrackInfo& aOriginal, uint32_t aStreamID)
549 0 : : mInfo(aOriginal.Clone())
550 : , mStreamSourceID(aStreamID)
551 0 : , mMimeType(mInfo->mMimeType)
552 : {
553 0 : }
554 :
555 0 : uint32_t GetID() const
556 : {
557 0 : return mStreamSourceID;
558 : }
559 :
560 : operator const TrackInfo*() const
561 : {
562 : return mInfo.get();
563 : }
564 :
565 : const TrackInfo* operator*() const
566 : {
567 : return mInfo.get();
568 : }
569 :
570 : const TrackInfo* operator->() const
571 : {
572 : MOZ_ASSERT(mInfo.get(), "dereferencing a UniquePtr containing nullptr");
573 : return mInfo.get();
574 : }
575 :
576 0 : const AudioInfo* GetAsAudioInfo() const
577 : {
578 0 : return mInfo ? mInfo->GetAsAudioInfo() : nullptr;
579 : }
580 :
581 0 : const VideoInfo* GetAsVideoInfo() const
582 : {
583 0 : return mInfo ? mInfo->GetAsVideoInfo() : nullptr;
584 : }
585 :
586 : const TextInfo* GetAsTextInfo() const
587 : {
588 : return mInfo ? mInfo->GetAsTextInfo() : nullptr;
589 : }
590 :
591 : private:
592 0 : ~TrackInfoSharedPtr() { }
593 : UniquePtr<TrackInfo> mInfo;
594 : // A unique ID, guaranteed to change when changing streams.
595 : uint32_t mStreamSourceID;
596 :
597 : public:
598 : const nsCString& mMimeType;
599 : };
600 :
601 0 : class AudioConfig
602 : {
603 : public:
604 : enum Channel
605 : {
606 : CHANNEL_INVALID = -1,
607 : CHANNEL_MONO = 0,
608 : CHANNEL_LEFT,
609 : CHANNEL_RIGHT,
610 : CHANNEL_CENTER,
611 : CHANNEL_LS,
612 : CHANNEL_RS,
613 : CHANNEL_RLS,
614 : CHANNEL_RCENTER,
615 : CHANNEL_RRS,
616 : CHANNEL_LFE,
617 : };
618 :
619 0 : class ChannelLayout
620 : {
621 : public:
622 0 : ChannelLayout() : mChannelMap(0), mValid(false) { }
623 0 : explicit ChannelLayout(uint32_t aChannels)
624 0 : : ChannelLayout(aChannels, SMPTEDefault(aChannels))
625 : {
626 0 : }
627 0 : ChannelLayout(uint32_t aChannels, const Channel* aConfig)
628 0 : : ChannelLayout()
629 : {
630 0 : if (!aConfig) {
631 0 : mValid = false;
632 0 : return;
633 : }
634 0 : mChannels.AppendElements(aConfig, aChannels);
635 0 : UpdateChannelMap();
636 : }
637 0 : bool operator==(const ChannelLayout& aOther) const
638 : {
639 0 : return mChannels == aOther.mChannels;
640 : }
641 0 : bool operator!=(const ChannelLayout& aOther) const
642 : {
643 0 : return mChannels != aOther.mChannels;
644 : }
645 0 : const Channel& operator[](uint32_t aIndex) const
646 : {
647 0 : return mChannels[aIndex];
648 : }
649 0 : uint32_t Count() const
650 : {
651 0 : return mChannels.Length();
652 : }
653 0 : uint32_t Map() const
654 : {
655 0 : return mChannelMap;
656 : }
657 : // Calculate the mapping table from the current layout to aOther such that
658 : // one can easily go from one layout to the other by doing:
659 : // out[channel] = in[map[channel]].
660 : // Returns true if the reordering is possible or false otherwise.
661 : // If true, then aMap, if set, will be updated to contain the mapping table
662 : // allowing conversion from the current layout to aOther.
663 : // If aMap is nullptr, then MappingTable can be used to simply determine if
664 : // the current layout can be easily reordered to aOther.
665 : // aMap must be an array of size MAX_AUDIO_CHANNELS.
666 : bool MappingTable(const ChannelLayout& aOther, uint8_t* aMap = nullptr) const;
667 0 : bool IsValid() const { return mValid; }
668 : bool HasChannel(Channel aChannel) const
669 : {
670 : return mChannelMap & (1 << aChannel);
671 : }
672 : private:
673 : void UpdateChannelMap();
674 : const Channel* SMPTEDefault(uint32_t aChannels) const;
675 : AutoTArray<Channel, MAX_AUDIO_CHANNELS> mChannels;
676 : uint32_t mChannelMap;
677 : bool mValid;
678 : };
679 :
680 : enum SampleFormat
681 : {
682 : FORMAT_NONE = 0,
683 : FORMAT_U8,
684 : FORMAT_S16,
685 : FORMAT_S24LSB,
686 : FORMAT_S24,
687 : FORMAT_S32,
688 : FORMAT_FLT,
689 : #if defined(MOZ_SAMPLE_TYPE_FLOAT32)
690 : FORMAT_DEFAULT = FORMAT_FLT
691 : #elif defined(MOZ_SAMPLE_TYPE_S16)
692 : FORMAT_DEFAULT = FORMAT_S16
693 : #else
694 : #error "Not supported audio type"
695 : #endif
696 : };
697 :
698 : AudioConfig(const ChannelLayout& aChannelLayout, uint32_t aRate,
699 : AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
700 : bool aInterleaved = true);
701 : // Will create a channel configuration from default SMPTE ordering.
702 : AudioConfig(uint32_t aChannels, uint32_t aRate,
703 : AudioConfig::SampleFormat aFormat = FORMAT_DEFAULT,
704 : bool aInterleaved = true);
705 :
706 0 : const ChannelLayout& Layout() const
707 : {
708 0 : return mChannelLayout;
709 : }
710 0 : uint32_t Channels() const
711 : {
712 0 : if (!mChannelLayout.IsValid()) {
713 0 : return mChannels;
714 : }
715 0 : return mChannelLayout.Count();
716 : }
717 0 : uint32_t Rate() const
718 : {
719 0 : return mRate;
720 : }
721 0 : SampleFormat Format() const
722 : {
723 0 : return mFormat;
724 : }
725 0 : bool Interleaved() const
726 : {
727 0 : return mInterleaved;
728 : }
729 0 : bool operator==(const AudioConfig& aOther) const
730 : {
731 0 : return mChannelLayout == aOther.mChannelLayout
732 0 : && mRate == aOther.mRate
733 0 : && mFormat == aOther.mFormat
734 0 : && mInterleaved == aOther.mInterleaved;
735 : }
736 0 : bool operator!=(const AudioConfig& aOther) const
737 : {
738 0 : return !(*this == aOther);
739 : }
740 :
741 0 : bool IsValid() const
742 : {
743 0 : return mChannelLayout.IsValid() && Format() != FORMAT_NONE && Rate() > 0;
744 : }
745 :
746 : static const char* FormatToString(SampleFormat aFormat);
747 : static uint32_t SampleSize(SampleFormat aFormat);
748 : static uint32_t FormatToBits(SampleFormat aFormat);
749 :
750 : private:
751 : // Channels configuration.
752 : ChannelLayout mChannelLayout;
753 :
754 : // Channel count.
755 : uint32_t mChannels;
756 :
757 : // Sample rate.
758 : uint32_t mRate;
759 :
760 : // Sample format.
761 : SampleFormat mFormat;
762 :
763 : bool mInterleaved;
764 : };
765 :
766 : } // namespace mozilla
767 :
768 : #endif // MediaInfo_h
|