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(MediaData_h)
9 # include "AudioConfig.h"
10 # include "AudioSampleFormat.h"
11 # include "ImageTypes.h"
12 # include "SharedBuffer.h"
13 # include "TimeUnits.h"
14 # include "mozilla/CheckedInt.h"
15 # include "mozilla/Maybe.h"
16 # include "mozilla/PodOperations.h"
17 # include "mozilla/RefPtr.h"
18 # include "mozilla/Span.h"
19 # include "mozilla/UniquePtr.h"
20 # include "mozilla/UniquePtrExtensions.h"
21 # include "mozilla/gfx/Rect.h"
22 # include "nsString.h"
23 # include "nsTArray.h"
30 class KnowsCompositor
;
33 class MediaByteBuffer
;
34 class TrackInfoSharedPtr
;
37 // Memory allocations are fallibles. Methods return a boolean indicating if
38 // memory allocations were successful. Return values should always be checked.
39 // AlignedBuffer::mData will be nullptr if no memory has been allocated or if
40 // an error occurred during construction.
41 // Existing data is only ever modified if new memory allocation has succeeded
42 // and preserved if not.
44 // The memory referenced by mData will always be Alignment bytes aligned and the
45 // underlying buffer will always have a size such that Alignment bytes blocks
46 // can be used to read the content, regardless of the mSize value. Buffer is
47 // zeroed on creation, elements are not individually constructed.
48 // An Alignment value of 0 means that the data isn't aligned.
50 // Type must be trivially copyable.
52 // AlignedBuffer can typically be used in place of UniquePtr<Type[]> however
53 // care must be taken as all memory allocations are fallible.
55 // auto buffer = MakeUniqueFallible<float[]>(samples)
56 // becomes: AlignedFloatBuffer buffer(samples)
58 // auto buffer = MakeUnique<float[]>(samples)
60 // AlignedFloatBuffer buffer(samples);
61 // if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; }
62 class InflatableShortBuffer
;
63 template <typename Type
, int Alignment
= 32>
66 friend InflatableShortBuffer
;
68 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {}
70 explicit AlignedBuffer(size_t aLength
)
71 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {
72 if (EnsureCapacity(aLength
)) {
77 AlignedBuffer(const Type
* aData
, size_t aLength
) : AlignedBuffer(aLength
) {
81 PodCopy(mData
, aData
, aLength
);
84 AlignedBuffer(const AlignedBuffer
& aOther
)
85 : AlignedBuffer(aOther
.Data(), aOther
.Length()) {}
87 AlignedBuffer(AlignedBuffer
&& aOther
) noexcept
88 : mData(aOther
.mData
),
89 mLength(aOther
.mLength
),
90 mBuffer(std::move(aOther
.mBuffer
)),
91 mCapacity(aOther
.mCapacity
) {
92 aOther
.mData
= nullptr;
97 AlignedBuffer
& operator=(AlignedBuffer
&& aOther
) noexcept
{
98 this->~AlignedBuffer();
99 new (this) AlignedBuffer(std::move(aOther
));
103 Type
* Data() const { return mData
; }
104 size_t Length() const { return mLength
; }
105 size_t Size() const { return mLength
* sizeof(Type
); }
106 Type
& operator[](size_t aIndex
) {
107 MOZ_ASSERT(aIndex
< mLength
);
108 return mData
[aIndex
];
110 const Type
& operator[](size_t aIndex
) const {
111 MOZ_ASSERT(aIndex
< mLength
);
112 return mData
[aIndex
];
114 // Set length of buffer, allocating memory as required.
115 // If length is increased, new buffer area is filled with 0.
116 bool SetLength(size_t aLength
) {
117 if (aLength
> mLength
&& !EnsureCapacity(aLength
)) {
123 // Add aData at the beginning of buffer.
124 bool Prepend(const Type
* aData
, size_t aLength
) {
125 if (!EnsureCapacity(aLength
+ mLength
)) {
129 // Shift the data to the right by aLength to leave room for the new data.
130 PodMove(mData
+ aLength
, mData
, mLength
);
131 PodCopy(mData
, aData
, aLength
);
136 // Add aData at the end of buffer.
137 bool Append(const Type
* aData
, size_t aLength
) {
138 if (!EnsureCapacity(aLength
+ mLength
)) {
142 PodCopy(mData
+ mLength
, aData
, aLength
);
147 // Replace current content with aData.
148 bool Replace(const Type
* aData
, size_t aLength
) {
149 // If aLength is smaller than our current length, we leave the buffer as is,
150 // only adjusting the reported length.
151 if (!EnsureCapacity(aLength
)) {
155 PodCopy(mData
, aData
, aLength
);
159 // Clear the memory buffer. Will set target mData and mLength to 0.
165 // Methods for reporting memory.
166 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
167 size_t size
= aMallocSizeOf(this);
168 size
+= aMallocSizeOf(mBuffer
.get());
171 // AlignedBuffer is typically allocated on the stack. As such, you likely
172 // want to use SizeOfExcludingThis
173 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
174 return aMallocSizeOf(mBuffer
.get());
176 size_t ComputedSizeOfExcludingThis() const { return mCapacity
; }
178 // For backward compatibility with UniquePtr<Type[]>
179 Type
* get() const { return mData
; }
180 explicit operator bool() const { return mData
!= nullptr; }
182 // Size in bytes of extra space allocated for padding.
183 static size_t AlignmentPaddingSize() { return AlignmentOffset() * 2; }
185 void PopFront(size_t aCount
) {
186 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
187 PodMove(mData
, mData
+ aCount
, mLength
- aCount
);
191 void PopBack(size_t aCount
) {
192 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
197 static size_t AlignmentOffset() { return Alignment
? Alignment
- 1 : 0; }
199 // Ensure that the backend buffer can hold aLength data. Will update mData.
200 // Will enforce that the start of allocated data is always Alignment bytes
201 // aligned and that it has sufficient end padding to allow for Alignment bytes
202 // block read as required by some data decoders.
203 // Returns false if memory couldn't be allocated.
204 bool EnsureCapacity(size_t aLength
) {
206 // No need to allocate a buffer yet.
209 const CheckedInt
<size_t> sizeNeeded
=
210 CheckedInt
<size_t>(aLength
) * sizeof(Type
) + AlignmentPaddingSize();
212 if (!sizeNeeded
.isValid() || sizeNeeded
.value() >= INT32_MAX
) {
213 // overflow or over an acceptable size.
216 if (mData
&& mCapacity
>= sizeNeeded
.value()) {
219 auto newBuffer
= MakeUniqueFallible
<uint8_t[]>(sizeNeeded
.value());
224 // Find alignment address.
225 const uintptr_t alignmask
= AlignmentOffset();
226 Type
* newData
= reinterpret_cast<Type
*>(
227 (reinterpret_cast<uintptr_t>(newBuffer
.get()) + alignmask
) &
229 MOZ_ASSERT(uintptr_t(newData
) % (AlignmentOffset() + 1) == 0);
231 MOZ_ASSERT(!mLength
|| mData
);
233 PodZero(newData
+ mLength
, aLength
- mLength
);
235 PodCopy(newData
, mData
, mLength
);
238 mBuffer
= std::move(newBuffer
);
239 mCapacity
= sizeNeeded
.value();
245 size_t mLength
{}; // number of elements
246 UniquePtr
<uint8_t[]> mBuffer
;
247 size_t mCapacity
{}; // in bytes
250 using AlignedByteBuffer
= AlignedBuffer
<uint8_t>;
251 using AlignedFloatBuffer
= AlignedBuffer
<float>;
252 using AlignedShortBuffer
= AlignedBuffer
<int16_t>;
253 using AlignedAudioBuffer
= AlignedBuffer
<AudioDataValue
>;
255 // A buffer in which int16_t audio can be written to, and then converted to
256 // float32 audio without reallocating.
257 // This class is useful when an API hands out int16_t audio but the samples
258 // need to be immediately converted to f32.
259 class InflatableShortBuffer
{
261 explicit InflatableShortBuffer(size_t aElementCount
)
262 : mBuffer(aElementCount
* 2) {}
263 AlignedFloatBuffer
Inflate() {
264 // Convert the data from int16_t to f32 in place, in the same buffer.
265 // The reason this works is because the buffer has in fact twice the
266 // capacity, and the loop goes backward.
267 float* output
= reinterpret_cast<float*>(mBuffer
.mData
);
268 for (size_t i
= Length(); i
--;) {
269 output
[i
] = AudioSampleToFloat(mBuffer
.mData
[i
]);
271 AlignedFloatBuffer rv
;
272 rv
.mBuffer
= std::move(mBuffer
.mBuffer
);
273 rv
.mCapacity
= mBuffer
.mCapacity
;
274 rv
.mLength
= Length();
278 size_t Length() const { return mBuffer
.mLength
/ 2; }
279 int16_t* get() const { return mBuffer
.get(); }
280 explicit operator bool() const { return mBuffer
.mData
!= nullptr; }
283 AlignedShortBuffer mBuffer
;
286 // Container that holds media samples.
289 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaData
)
291 enum class Type
: uint8_t { AUDIO_DATA
= 0, VIDEO_DATA
, RAW_DATA
, NULL_DATA
};
292 static const char* TypeToStr(Type aType
) {
294 case Type::AUDIO_DATA
:
296 case Type::VIDEO_DATA
:
300 case Type::NULL_DATA
:
303 MOZ_CRASH("bad value");
307 MediaData(Type aType
, int64_t aOffset
, const media::TimeUnit
& aTimestamp
,
308 const media::TimeUnit
& aDuration
)
312 mTimecode(aTimestamp
),
313 mDuration(aDuration
),
316 // Type of contained data.
319 // Approximate byte offset where this data was demuxed from its media.
322 // Start time of sample.
323 media::TimeUnit mTime
;
325 // Codec specific internal time code. For Ogg based codecs this is the
327 media::TimeUnit mTimecode
;
329 // Duration of sample, in microseconds.
330 media::TimeUnit mDuration
;
334 media::TimeUnit
GetEndTime() const { return mTime
+ mDuration
; }
336 media::TimeUnit
GetEndTimecode() const { return mTimecode
+ mDuration
; }
338 bool HasValidTime() const {
339 return mTime
.IsValid() && mTimecode
.IsValid() && mDuration
.IsValid() &&
340 GetEndTime().IsValid() && GetEndTimecode().IsValid();
343 template <typename ReturnType
>
344 const ReturnType
* As() const {
345 MOZ_ASSERT(this->mType
== ReturnType::sType
);
346 return static_cast<const ReturnType
*>(this);
349 template <typename ReturnType
>
351 MOZ_ASSERT(this->mType
== ReturnType::sType
);
352 return static_cast<ReturnType
*>(this);
356 explicit MediaData(Type aType
) : mType(aType
), mOffset(0), mKeyframe(false) {}
358 virtual ~MediaData() = default;
361 // NullData is for decoder generating a sample which doesn't need to be
363 class NullData
: public MediaData
{
365 NullData(int64_t aOffset
, const media::TimeUnit
& aTime
,
366 const media::TimeUnit
& aDuration
)
367 : MediaData(Type::NULL_DATA
, aOffset
, aTime
, aDuration
) {}
369 static const Type sType
= Type::NULL_DATA
;
372 // Holds chunk a decoded audio frames.
373 class AudioData
: public MediaData
{
375 AudioData(int64_t aOffset
, const media::TimeUnit
& aTime
,
376 AlignedAudioBuffer
&& aData
, uint32_t aChannels
, uint32_t aRate
,
377 uint32_t aChannelMap
= AudioConfig::ChannelLayout::UNKNOWN_MAP
);
379 static const Type sType
= Type::AUDIO_DATA
;
380 static const char* sTypeName
;
382 // Access the buffer as a Span.
383 Span
<AudioDataValue
> Data() const;
385 // Amount of frames for contained data.
386 uint32_t Frames() const { return mFrames
; }
388 // Trim the audio buffer such that its apparent content fits within the aTrim
389 // interval. The actual data isn't removed from the buffer and a followup call
390 // to SetTrimWindow could restore the content. mDuration, mTime and mFrames
391 // will be adjusted accordingly.
392 // Warning: rounding may occurs, in which case the new start time of the audio
393 // sample may still be lesser than aTrim.mStart.
394 bool SetTrimWindow(const media::TimeInterval
& aTrim
);
396 // Get the internal audio buffer to be moved. After this call the original
397 // AudioData will be emptied and can't be used again.
398 AlignedAudioBuffer
MoveableData();
400 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
402 // If mAudioBuffer is null, creates it from mAudioData.
403 void EnsureAudioBuffer();
405 // Return true if the adjusted time is valid. Caller should handle error when
406 // the result is invalid.
407 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
409 // This method is used to adjust the original start time, which would change
410 // `mTime` and `mOriginalTime` together, and should only be used for data
411 // which hasn't been trimmed before.
412 void SetOriginalStartTime(const media::TimeUnit
& aStartTime
);
414 const uint32_t mChannels
;
415 // The AudioConfig::ChannelLayout map. Channels are ordered as per SMPTE
416 // definition. A value of UNKNOWN_MAP indicates unknown layout.
417 // ChannelMap is an unsigned bitmap compatible with Windows' WAVE and FFmpeg
419 const AudioConfig::ChannelLayout::ChannelMap mChannelMap
;
420 const uint32_t mRate
;
422 // At least one of mAudioBuffer/mAudioData must be non-null.
423 // mChannels channels, each with mFrames frames
424 RefPtr
<SharedBuffer
> mAudioBuffer
;
427 ~AudioData() = default;
430 friend class ArrayOfRemoteAudioData
;
431 AudioDataValue
* GetAdjustedData() const;
432 media::TimeUnit mOriginalTime
;
433 // mFrames frames, each with mChannels values
434 AlignedAudioBuffer mAudioData
;
435 Maybe
<media::TimeInterval
> mTrimWindow
;
436 // Amount of frames for contained data.
438 size_t mDataOffset
= 0;
443 class PlanarYCbCrImage
;
444 } // namespace layers
448 // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
449 class VideoData
: public MediaData
{
451 using IntRect
= gfx::IntRect
;
452 using IntSize
= gfx::IntSize
;
453 using ColorDepth
= gfx::ColorDepth
;
454 using ColorRange
= gfx::ColorRange
;
455 using YUVColorSpace
= gfx::YUVColorSpace
;
456 using ColorSpace2
= gfx::ColorSpace2
;
457 using ChromaSubsampling
= gfx::ChromaSubsampling
;
458 using ImageContainer
= layers::ImageContainer
;
459 using Image
= layers::Image
;
460 using PlanarYCbCrImage
= layers::PlanarYCbCrImage
;
462 static const Type sType
= Type::VIDEO_DATA
;
463 static const char* sTypeName
;
465 // YCbCr data obtained from decoding the video. The index's are:
479 YUVColorSpace mYUVColorSpace
= YUVColorSpace::Identity
;
480 ColorSpace2 mColorPrimaries
= ColorSpace2::UNKNOWN
;
481 ColorDepth mColorDepth
= ColorDepth::COLOR_8
;
482 ColorRange mColorRange
= ColorRange::LIMITED
;
483 ChromaSubsampling mChromaSubsampling
= ChromaSubsampling::FULL
;
486 // Constructs a VideoData object. If aImage is nullptr, creates a new Image
487 // holding a copy of the YCbCr data passed in aBuffer. If aImage is not
488 // nullptr, it's stored as the underlying video image and aBuffer is assumed
489 // to point to memory within aImage so no copy is made. aTimecode is a codec
490 // specific number representing the timestamp of the frame of video data.
491 // Returns nsnull if an error occurs. This may indicate that memory couldn't
492 // be allocated to create the VideoData object, or it may indicate some
493 // problem with the input data (e.g. negative stride).
495 static bool UseUseNV12ForSoftwareDecodedVideoIfPossible(
496 layers::KnowsCompositor
* aAllocator
);
498 // Creates a new VideoData containing a deep copy of aBuffer. May use
499 // aContainer to allocate an Image to hold the copied data.
500 static already_AddRefed
<VideoData
> CreateAndCopyData(
501 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
502 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
503 const YCbCrBuffer
& aBuffer
, bool aKeyframe
,
504 const media::TimeUnit
& aTimecode
, const IntRect
& aPicture
,
505 layers::KnowsCompositor
* aAllocator
);
507 static already_AddRefed
<VideoData
> CreateAndCopyData(
508 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
509 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
510 const YCbCrBuffer
& aBuffer
, const YCbCrBuffer::Plane
& aAlphaPlane
,
511 bool aKeyframe
, const media::TimeUnit
& aTimecode
,
512 const IntRect
& aPicture
);
514 static already_AddRefed
<VideoData
> CreateFromImage(
515 const IntSize
& aDisplay
, int64_t aOffset
, const media::TimeUnit
& aTime
,
516 const media::TimeUnit
& aDuration
, const RefPtr
<Image
>& aImage
,
517 bool aKeyframe
, const media::TimeUnit
& aTimecode
);
519 // Initialize PlanarYCbCrImage. Only When aCopyData is true,
520 // video data is copied to PlanarYCbCrImage.
521 static bool SetVideoDataToImage(PlanarYCbCrImage
* aVideoImage
,
522 const VideoInfo
& aInfo
,
523 const YCbCrBuffer
& aBuffer
,
524 const IntRect
& aPicture
, bool aCopyData
);
526 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
528 // Dimensions at which to display the video frame. The picture region
529 // will be scaled to this size. This is should be the picture region's
530 // dimensions scaled with respect to its aspect ratio.
531 const IntSize mDisplay
;
533 // This frame's image.
534 RefPtr
<Image
> mImage
;
536 ColorDepth
GetColorDepth() const;
540 VideoData(int64_t aOffset
, const media::TimeUnit
& aTime
,
541 const media::TimeUnit
& aDuration
, bool aKeyframe
,
542 const media::TimeUnit
& aTimecode
, IntSize aDisplay
,
545 void MarkSentToCompositor() { mSentToCompositor
= true; }
546 bool IsSentToCompositor() { return mSentToCompositor
; }
548 void UpdateDuration(const media::TimeUnit
& aDuration
);
549 void UpdateTimestamp(const media::TimeUnit
& aTimestamp
);
551 // Return true if the adjusted time is valid. Caller should handle error when
552 // the result is invalid.
553 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
555 void SetNextKeyFrameTime(const media::TimeUnit
& aTime
) {
556 mNextKeyFrameTime
= aTime
;
559 const media::TimeUnit
& NextKeyFrameTime() const { return mNextKeyFrameTime
; }
564 bool mSentToCompositor
;
565 media::TimeUnit mNextKeyFrameTime
;
568 enum class CryptoScheme
: uint8_t {
577 : mCryptoScheme(CryptoScheme::None
),
581 CryptoScheme mCryptoScheme
;
583 CopyableTArray
<uint8_t> mKeyId
;
584 uint8_t mCryptByteBlock
;
585 uint8_t mSkipByteBlock
;
586 CopyableTArray
<uint8_t> mConstantIV
;
588 bool IsEncrypted() const { return mCryptoScheme
!= CryptoScheme::None
; }
591 class CryptoSample
: public CryptoTrack
{
593 // The num clear bytes in each subsample. The nth element in the array is the
594 // number of clear bytes at the start of the nth subsample.
595 // Clear sizes are stored as uint16_t in containers per ISO/IEC
596 // 23001-7, but we store them as uint32_t for 2 reasons
597 // - The Widevine CDM accepts clear sizes as uint32_t.
598 // - When converting samples to Annex B we modify the clear sizes and
599 // clear sizes near UINT16_MAX can overflow if stored in a uint16_t.
600 CopyableTArray
<uint32_t> mPlainSizes
;
601 // The num encrypted bytes in each subsample. The nth element in the array is
602 // the number of encrypted bytes at the start of the nth subsample.
603 CopyableTArray
<uint32_t> mEncryptedSizes
;
604 CopyableTArray
<uint8_t> mIV
;
605 CopyableTArray
<CopyableTArray
<uint8_t>> mInitDatas
;
606 nsString mInitDataType
;
609 // MediaRawData is a MediaData container used to store demuxed, still compressed
611 // Use MediaRawData::CreateWriter() to obtain a MediaRawDataWriter object that
612 // provides methods to modify and manipulate the data.
613 // Memory allocations are fallible. Methods return a boolean indicating if
614 // memory allocations were successful. Return values should always be checked.
615 // MediaRawData::mData will be nullptr if no memory has been allocated or if
616 // an error occurred during construction.
617 // Existing data is only ever modified if new memory allocation has succeeded
618 // and preserved if not.
620 // The memory referenced by mData will always be 32 bytes aligned and the
621 // underlying buffer will always have a size such that 32 bytes blocks can be
622 // used to read the content, regardless of the mSize value. Buffer is zeroed
625 // Typical usage: create new MediaRawData; create the associated
626 // MediaRawDataWriter, call SetSize() to allocate memory, write to mData,
627 // up to mSize bytes.
631 class MediaRawDataWriter
{
633 // Pointer to data or null if not-yet allocated
635 // Writeable size of buffer.
637 // Writeable reference to MediaRawData::mCryptoInternal
638 CryptoSample
& mCrypto
;
640 // Data manipulation methods. mData and mSize may be updated accordingly.
642 // Set size of buffer, allocating memory as required.
643 // If size is increased, new buffer area is filled with 0.
644 [[nodiscard
]] bool SetSize(size_t aSize
);
645 // Add aData at the beginning of buffer.
646 [[nodiscard
]] bool Prepend(const uint8_t* aData
, size_t aSize
);
647 [[nodiscard
]] bool Append(const uint8_t* aData
, size_t aSize
);
648 // Replace current content with aData.
649 [[nodiscard
]] bool Replace(const uint8_t* aData
, size_t aSize
);
650 // Clear the memory buffer. Will set target mData and mSize to 0.
652 // Remove aSize bytes from the front of the sample.
653 void PopFront(size_t aSize
);
656 friend class MediaRawData
;
657 explicit MediaRawDataWriter(MediaRawData
* aMediaRawData
);
658 [[nodiscard
]] bool EnsureSize(size_t aSize
);
659 MediaRawData
* mTarget
;
662 class MediaRawData final
: public MediaData
{
665 MediaRawData(const uint8_t* aData
, size_t aSize
);
666 MediaRawData(const uint8_t* aData
, size_t aSize
, const uint8_t* aAlphaData
,
668 explicit MediaRawData(AlignedByteBuffer
&& aData
);
669 MediaRawData(AlignedByteBuffer
&& aData
, AlignedByteBuffer
&& aAlphaData
);
671 // Pointer to data or null if not-yet allocated
672 const uint8_t* Data() const { return mBuffer
.Data(); }
673 // Pointer to alpha data or null if not-yet allocated
674 const uint8_t* AlphaData() const { return mAlphaBuffer
.Data(); }
676 size_t Size() const { return mBuffer
.Length(); }
677 size_t AlphaSize() const { return mAlphaBuffer
.Length(); }
678 size_t ComputedSizeOfIncludingThis() const {
679 return sizeof(*this) + mBuffer
.ComputedSizeOfExcludingThis() +
680 mAlphaBuffer
.ComputedSizeOfExcludingThis();
682 // Access the buffer as a Span.
683 operator Span
<const uint8_t>() { return Span
{Data(), Size()}; }
685 const CryptoSample
& mCrypto
;
686 RefPtr
<MediaByteBuffer
> mExtraData
;
688 // Used by the Vorbis decoder and Ogg demuxer.
689 // Indicates that this is the last packet of the stream.
692 RefPtr
<TrackInfoSharedPtr
> mTrackInfo
;
694 // May contain the original start time and duration of the frames.
695 // mOriginalPresentationWindow.mStart would always be less or equal to mTime
696 // and mOriginalPresentationWindow.mEnd equal or greater to mTime + mDuration.
697 // This is used when the sample should get cropped so that its content will
698 // actually start on mTime and go for mDuration. If this interval is set, then
699 // the decoder should crop the content accordingly.
700 Maybe
<media::TimeInterval
> mOriginalPresentationWindow
;
702 // If it's true, the `mCrypto` should be copied into the remote data as well.
703 // Currently this is only used for the media engine DRM playback.
704 bool mShouldCopyCryptoToRemoteRawData
= false;
706 // It's only used when the remote decoder reconstructs the media raw data.
707 CryptoSample
& GetWritableCrypto() { return mCryptoInternal
; }
709 // Return a deep copy or nullptr if out of memory.
710 already_AddRefed
<MediaRawData
> Clone() const;
711 // Create a MediaRawDataWriter for this MediaRawData. The writer is not
713 UniquePtr
<MediaRawDataWriter
> CreateWriter();
714 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
720 friend class MediaRawDataWriter
;
721 friend class ArrayOfRemoteMediaRawData
;
722 AlignedByteBuffer mBuffer
;
723 AlignedByteBuffer mAlphaBuffer
;
724 CryptoSample mCryptoInternal
;
725 MediaRawData(const MediaRawData
&); // Not implemented
728 // MediaByteBuffer is a ref counted infallible TArray.
729 class MediaByteBuffer
: public nsTArray
<uint8_t> {
730 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer
);
731 MediaByteBuffer() = default;
732 explicit MediaByteBuffer(size_t aCapacity
) : nsTArray
<uint8_t>(aCapacity
) {}
735 ~MediaByteBuffer() = default;
738 // MediaAlignedByteBuffer is a ref counted AlignedByteBuffer whose memory
739 // allocations are fallible.
740 class MediaAlignedByteBuffer final
: public AlignedByteBuffer
{
741 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaAlignedByteBuffer
);
742 MediaAlignedByteBuffer() = default;
743 MediaAlignedByteBuffer(const uint8_t* aData
, size_t aLength
)
744 : AlignedByteBuffer(aData
, aLength
) {}
747 ~MediaAlignedByteBuffer() = default;
750 } // namespace mozilla
752 #endif // MediaData_h