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 "MediaResult.h"
13 # include "SharedBuffer.h"
14 # include "TimeUnits.h"
15 # include "mozilla/CheckedInt.h"
16 # include "mozilla/Maybe.h"
17 # include "mozilla/PodOperations.h"
18 # include "mozilla/RefPtr.h"
19 # include "mozilla/Result.h"
20 # include "mozilla/Span.h"
21 # include "mozilla/UniquePtr.h"
22 # include "mozilla/UniquePtrExtensions.h"
23 # include "mozilla/gfx/Rect.h"
24 # include "nsString.h"
25 # include "nsTArray.h"
26 # include "EncoderConfig.h"
33 class KnowsCompositor
;
36 class MediaByteBuffer
;
37 class TrackInfoSharedPtr
;
40 // Memory allocations are fallibles. Methods return a boolean indicating if
41 // memory allocations were successful. Return values should always be checked.
42 // AlignedBuffer::mData will be nullptr if no memory has been allocated or if
43 // an error occurred during construction.
44 // Existing data is only ever modified if new memory allocation has succeeded
45 // and preserved if not.
47 // The memory referenced by mData will always be Alignment bytes aligned and the
48 // underlying buffer will always have a size such that Alignment bytes blocks
49 // can be used to read the content, regardless of the mSize value. Buffer is
50 // zeroed on creation, elements are not individually constructed.
51 // An Alignment value of 0 means that the data isn't aligned.
53 // Type must be trivially copyable.
55 // AlignedBuffer can typically be used in place of UniquePtr<Type[]> however
56 // care must be taken as all memory allocations are fallible.
58 // auto buffer = MakeUniqueFallible<float[]>(samples)
59 // becomes: AlignedFloatBuffer buffer(samples)
61 // auto buffer = MakeUnique<float[]>(samples)
63 // AlignedFloatBuffer buffer(samples);
64 // if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; }
65 class InflatableShortBuffer
;
66 template <typename Type
, int Alignment
= 32>
69 friend InflatableShortBuffer
;
71 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {}
73 explicit AlignedBuffer(size_t aLength
)
74 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {
75 if (EnsureCapacity(aLength
)) {
80 AlignedBuffer(const Type
* aData
, size_t aLength
) : AlignedBuffer(aLength
) {
84 PodCopy(mData
, aData
, aLength
);
87 AlignedBuffer(const AlignedBuffer
& aOther
)
88 : AlignedBuffer(aOther
.Data(), aOther
.Length()) {}
90 AlignedBuffer(AlignedBuffer
&& aOther
) noexcept
91 : mData(aOther
.mData
),
92 mLength(aOther
.mLength
),
93 mBuffer(std::move(aOther
.mBuffer
)),
94 mCapacity(aOther
.mCapacity
) {
95 aOther
.mData
= nullptr;
100 AlignedBuffer
& operator=(AlignedBuffer
&& aOther
) noexcept
{
101 if (&aOther
== this) {
104 mData
= aOther
.mData
;
105 mLength
= aOther
.mLength
;
106 mBuffer
= std::move(aOther
.mBuffer
);
107 mCapacity
= aOther
.mCapacity
;
108 aOther
.mData
= nullptr;
110 aOther
.mCapacity
= 0;
114 Type
* Data() const { return mData
; }
115 size_t Length() const { return mLength
; }
116 size_t Size() const { return mLength
* sizeof(Type
); }
117 Type
& operator[](size_t aIndex
) {
118 MOZ_ASSERT(aIndex
< mLength
);
119 return mData
[aIndex
];
121 const Type
& operator[](size_t aIndex
) const {
122 MOZ_ASSERT(aIndex
< mLength
);
123 return mData
[aIndex
];
125 // Set length of buffer, allocating memory as required.
126 // If memory is allocated, additional buffer area is filled with 0.
127 bool SetLength(size_t aLength
) {
128 if (aLength
> mLength
&& !EnsureCapacity(aLength
)) {
134 // Add aData at the beginning of buffer.
135 bool Prepend(const Type
* aData
, size_t aLength
) {
136 if (!EnsureCapacity(aLength
+ mLength
)) {
140 // Shift the data to the right by aLength to leave room for the new data.
141 PodMove(mData
+ aLength
, mData
, mLength
);
142 PodCopy(mData
, aData
, aLength
);
147 // Add aData at the end of buffer.
148 bool Append(const Type
* aData
, size_t aLength
) {
149 if (!EnsureCapacity(aLength
+ mLength
)) {
153 PodCopy(mData
+ mLength
, aData
, aLength
);
158 // Replace current content with aData.
159 bool Replace(const Type
* aData
, size_t aLength
) {
160 // If aLength is smaller than our current length, we leave the buffer as is,
161 // only adjusting the reported length.
162 if (!EnsureCapacity(aLength
)) {
166 PodCopy(mData
, aData
, aLength
);
170 // Clear the memory buffer. Will set target mData and mLength to 0.
176 // Methods for reporting memory.
177 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
178 size_t size
= aMallocSizeOf(this);
179 size
+= aMallocSizeOf(mBuffer
.get());
182 // AlignedBuffer is typically allocated on the stack. As such, you likely
183 // want to use SizeOfExcludingThis
184 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
185 return aMallocSizeOf(mBuffer
.get());
187 size_t ComputedSizeOfExcludingThis() const { return mCapacity
; }
189 // For backward compatibility with UniquePtr<Type[]>
190 Type
* get() const { return mData
; }
191 explicit operator bool() const { return mData
!= nullptr; }
193 // Size in bytes of extra space allocated for padding.
194 static size_t AlignmentPaddingSize() { return AlignmentOffset() * 2; }
196 void PopFront(size_t aCount
) {
197 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
198 PodMove(mData
, mData
+ aCount
, mLength
- aCount
);
202 void PopBack(size_t aCount
) {
203 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
208 static size_t AlignmentOffset() { return Alignment
? Alignment
- 1 : 0; }
210 // Ensure that the backend buffer can hold aLength data. Will update mData.
211 // Will enforce that the start of allocated data is always Alignment bytes
212 // aligned and that it has sufficient end padding to allow for Alignment bytes
213 // block read as required by some data decoders.
214 // Returns false if memory couldn't be allocated.
215 bool EnsureCapacity(size_t aLength
) {
217 // No need to allocate a buffer yet.
220 const CheckedInt
<size_t> sizeNeeded
=
221 CheckedInt
<size_t>(aLength
) * sizeof(Type
) + AlignmentPaddingSize();
223 if (!sizeNeeded
.isValid() || sizeNeeded
.value() >= INT32_MAX
) {
224 // overflow or over an acceptable size.
227 if (mData
&& mCapacity
>= sizeNeeded
.value()) {
230 auto newBuffer
= MakeUniqueFallible
<uint8_t[]>(sizeNeeded
.value());
235 // Find alignment address.
236 const uintptr_t alignmask
= AlignmentOffset();
237 Type
* newData
= reinterpret_cast<Type
*>(
238 (reinterpret_cast<uintptr_t>(newBuffer
.get()) + alignmask
) &
240 MOZ_ASSERT(uintptr_t(newData
) % (AlignmentOffset() + 1) == 0);
242 MOZ_ASSERT(!mLength
|| mData
);
244 PodZero(newData
+ mLength
, aLength
- mLength
);
246 PodCopy(newData
, mData
, mLength
);
249 mBuffer
= std::move(newBuffer
);
250 mCapacity
= sizeNeeded
.value();
256 size_t mLength
{}; // number of elements
257 UniquePtr
<uint8_t[]> mBuffer
;
258 size_t mCapacity
{}; // in bytes
261 using AlignedByteBuffer
= AlignedBuffer
<uint8_t>;
262 using AlignedFloatBuffer
= AlignedBuffer
<float>;
263 using AlignedShortBuffer
= AlignedBuffer
<int16_t>;
264 using AlignedAudioBuffer
= AlignedBuffer
<AudioDataValue
>;
266 // A buffer in which int16_t audio can be written to, and then converted to
267 // float32 audio without reallocating.
268 // This class is useful when an API hands out int16_t audio but the samples
269 // need to be immediately converted to f32.
270 class InflatableShortBuffer
{
272 explicit InflatableShortBuffer(size_t aElementCount
)
273 : mBuffer(aElementCount
* 2) {}
274 AlignedFloatBuffer
Inflate() {
275 // Convert the data from int16_t to f32 in place, in the same buffer.
276 // The reason this works is because the buffer has in fact twice the
277 // capacity, and the loop goes backward.
278 float* output
= reinterpret_cast<float*>(mBuffer
.mData
);
279 for (size_t i
= Length(); i
--;) {
280 output
[i
] = ConvertAudioSample
<float>(mBuffer
.mData
[i
]);
282 AlignedFloatBuffer rv
;
283 rv
.mBuffer
= std::move(mBuffer
.mBuffer
);
284 rv
.mCapacity
= mBuffer
.mCapacity
;
285 rv
.mLength
= Length();
289 size_t Length() const { return mBuffer
.mLength
/ 2; }
290 int16_t* get() const { return mBuffer
.get(); }
291 explicit operator bool() const { return mBuffer
.mData
!= nullptr; }
294 AlignedShortBuffer mBuffer
;
297 // Container that holds media samples.
300 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaData
)
302 enum class Type
: uint8_t { AUDIO_DATA
= 0, VIDEO_DATA
, RAW_DATA
, NULL_DATA
};
303 static const char* TypeToStr(Type aType
) {
305 case Type::AUDIO_DATA
:
307 case Type::VIDEO_DATA
:
311 case Type::NULL_DATA
:
314 MOZ_CRASH("bad value");
318 MediaData(Type aType
, int64_t aOffset
, const media::TimeUnit
& aTimestamp
,
319 const media::TimeUnit
& aDuration
)
323 mTimecode(aTimestamp
),
324 mDuration(aDuration
),
327 // Type of contained data.
330 // Approximate byte offset where this data was demuxed from its media.
333 // Start time of sample.
334 media::TimeUnit mTime
;
336 // Codec specific internal time code. For Ogg based codecs this is the
338 media::TimeUnit mTimecode
;
340 // Duration of sample, in microseconds.
341 media::TimeUnit mDuration
;
345 media::TimeUnit
GetEndTime() const { return mTime
+ mDuration
; }
347 media::TimeUnit
GetEndTimecode() const { return mTimecode
+ mDuration
; }
349 bool HasValidTime() const {
350 return mTime
.IsValid() && mTimecode
.IsValid() && mDuration
.IsValid() &&
351 GetEndTime().IsValid() && GetEndTimecode().IsValid();
354 template <typename ReturnType
>
355 const ReturnType
* As() const {
356 MOZ_ASSERT(this->mType
== ReturnType::sType
);
357 return static_cast<const ReturnType
*>(this);
360 template <typename ReturnType
>
362 MOZ_ASSERT(this->mType
== ReturnType::sType
);
363 return static_cast<ReturnType
*>(this);
367 explicit MediaData(Type aType
) : mType(aType
), mOffset(0), mKeyframe(false) {}
369 virtual ~MediaData() = default;
372 // NullData is for decoder generating a sample which doesn't need to be
374 class NullData
: public MediaData
{
376 NullData(int64_t aOffset
, const media::TimeUnit
& aTime
,
377 const media::TimeUnit
& aDuration
)
378 : MediaData(Type::NULL_DATA
, aOffset
, aTime
, aDuration
) {}
380 static const Type sType
= Type::NULL_DATA
;
383 // Holds chunk a decoded interleaved audio frames.
384 class AudioData
: public MediaData
{
386 AudioData(int64_t aOffset
, const media::TimeUnit
& aTime
,
387 AlignedAudioBuffer
&& aData
, uint32_t aChannels
, uint32_t aRate
,
388 uint32_t aChannelMap
= AudioConfig::ChannelLayout::UNKNOWN_MAP
);
390 static const Type sType
= Type::AUDIO_DATA
;
391 static const char* sTypeName
;
393 nsCString
ToString() const;
395 // Access the buffer as a Span.
396 Span
<AudioDataValue
> Data() const;
398 // Amount of frames for contained data.
399 uint32_t Frames() const { return mFrames
; }
401 // Trim the audio buffer such that its apparent content fits within the aTrim
402 // interval. The actual data isn't removed from the buffer and a followup call
403 // to SetTrimWindow could restore the content. mDuration, mTime and mFrames
404 // will be adjusted accordingly.
405 // Warning: rounding may occurs, in which case the new start time of the audio
406 // sample may still be lesser than aTrim.mStart.
407 bool SetTrimWindow(const media::TimeInterval
& aTrim
);
409 // Get the internal audio buffer to be moved. After this call the original
410 // AudioData will be emptied and can't be used again.
411 AlignedAudioBuffer
MoveableData();
413 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
415 // If mAudioBuffer is null, creates it from mAudioData.
416 void EnsureAudioBuffer();
418 // Return true if the adjusted time is valid. Caller should handle error when
419 // the result is invalid.
420 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
422 // This method is used to adjust the original start time, which would change
423 // `mTime` and `mOriginalTime` together, and should only be used for data
424 // which hasn't been trimmed before.
425 void SetOriginalStartTime(const media::TimeUnit
& aStartTime
);
427 const uint32_t mChannels
;
428 // The AudioConfig::ChannelLayout map. Channels are ordered as per SMPTE
429 // definition. A value of UNKNOWN_MAP indicates unknown layout.
430 // ChannelMap is an unsigned bitmap compatible with Windows' WAVE and FFmpeg
432 const AudioConfig::ChannelLayout::ChannelMap mChannelMap
;
433 const uint32_t mRate
;
435 // At least one of mAudioBuffer/mAudioData must be non-null.
436 // mChannels channels, each with mFrames frames
437 RefPtr
<SharedBuffer
> mAudioBuffer
;
440 ~AudioData() = default;
443 friend class ArrayOfRemoteAudioData
;
444 AudioDataValue
* GetAdjustedData() const;
445 media::TimeUnit mOriginalTime
;
446 // mFrames frames, each with mChannels values
447 AlignedAudioBuffer mAudioData
;
448 Maybe
<media::TimeInterval
> mTrimWindow
;
449 // Amount of frames for contained data.
451 size_t mDataOffset
= 0;
456 class PlanarYCbCrImage
;
457 } // namespace layers
461 // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
462 class VideoData
: public MediaData
{
464 using IntRect
= gfx::IntRect
;
465 using IntSize
= gfx::IntSize
;
466 using ColorDepth
= gfx::ColorDepth
;
467 using ColorRange
= gfx::ColorRange
;
468 using YUVColorSpace
= gfx::YUVColorSpace
;
469 using ColorSpace2
= gfx::ColorSpace2
;
470 using ChromaSubsampling
= gfx::ChromaSubsampling
;
471 using ImageContainer
= layers::ImageContainer
;
472 using Image
= layers::Image
;
473 using PlanarYCbCrImage
= layers::PlanarYCbCrImage
;
475 static const Type sType
= Type::VIDEO_DATA
;
476 static const char* sTypeName
;
478 // YCbCr data obtained from decoding the video. The index's are:
492 YUVColorSpace mYUVColorSpace
= YUVColorSpace::Identity
;
493 ColorSpace2 mColorPrimaries
= ColorSpace2::UNKNOWN
;
494 ColorDepth mColorDepth
= ColorDepth::COLOR_8
;
495 ColorRange mColorRange
= ColorRange::LIMITED
;
496 ChromaSubsampling mChromaSubsampling
= ChromaSubsampling::FULL
;
499 // Constructs a VideoData object. If aImage is nullptr, creates a new Image
500 // holding a copy of the YCbCr data passed in aBuffer. If aImage is not
501 // nullptr, it's stored as the underlying video image and aBuffer is assumed
502 // to point to memory within aImage so no copy is made. aTimecode is a codec
503 // specific number representing the timestamp of the frame of video data.
504 // Returns nsnull if an error occurs. This may indicate that memory couldn't
505 // be allocated to create the VideoData object, or it may indicate some
506 // problem with the input data (e.g. negative stride).
508 static bool UseUseNV12ForSoftwareDecodedVideoIfPossible(
509 layers::KnowsCompositor
* aAllocator
);
511 // Creates a new VideoData containing a deep copy of aBuffer. May use
512 // aContainer to allocate an Image to hold the copied data.
513 static Result
<already_AddRefed
<VideoData
>, MediaResult
> CreateAndCopyData(
514 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
515 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
516 const YCbCrBuffer
& aBuffer
, bool aKeyframe
,
517 const media::TimeUnit
& aTimecode
, const IntRect
& aPicture
,
518 layers::KnowsCompositor
* aAllocator
);
520 static already_AddRefed
<VideoData
> CreateAndCopyData(
521 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
522 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
523 const YCbCrBuffer
& aBuffer
, const YCbCrBuffer::Plane
& aAlphaPlane
,
524 bool aKeyframe
, const media::TimeUnit
& aTimecode
,
525 const IntRect
& aPicture
);
527 static already_AddRefed
<VideoData
> CreateFromImage(
528 const IntSize
& aDisplay
, int64_t aOffset
, const media::TimeUnit
& aTime
,
529 const media::TimeUnit
& aDuration
, const RefPtr
<Image
>& aImage
,
530 bool aKeyframe
, const media::TimeUnit
& aTimecode
);
532 // Initialize PlanarYCbCrImage. Only When aCopyData is true,
533 // video data is copied to PlanarYCbCrImage.
534 static MediaResult
SetVideoDataToImage(PlanarYCbCrImage
* aVideoImage
,
535 const VideoInfo
& aInfo
,
536 const YCbCrBuffer
& aBuffer
,
537 const IntRect
& aPicture
,
540 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
542 // Dimensions at which to display the video frame. The picture region
543 // will be scaled to this size. This is should be the picture region's
544 // dimensions scaled with respect to its aspect ratio.
545 const IntSize mDisplay
;
547 // This frame's image.
548 RefPtr
<Image
> mImage
;
550 ColorDepth
GetColorDepth() const;
554 VideoData(int64_t aOffset
, const media::TimeUnit
& aTime
,
555 const media::TimeUnit
& aDuration
, bool aKeyframe
,
556 const media::TimeUnit
& aTimecode
, IntSize aDisplay
,
559 nsCString
ToString() const;
561 void MarkSentToCompositor() { mSentToCompositor
= true; }
562 bool IsSentToCompositor() { return mSentToCompositor
; }
564 void UpdateDuration(const media::TimeUnit
& aDuration
);
565 void UpdateTimestamp(const media::TimeUnit
& aTimestamp
);
567 // Return true if the adjusted time is valid. Caller should handle error when
568 // the result is invalid.
569 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
571 void SetNextKeyFrameTime(const media::TimeUnit
& aTime
) {
572 mNextKeyFrameTime
= aTime
;
575 const media::TimeUnit
& NextKeyFrameTime() const { return mNextKeyFrameTime
; }
580 bool mSentToCompositor
;
581 media::TimeUnit mNextKeyFrameTime
;
584 enum class CryptoScheme
: uint8_t {
590 const char* CryptoSchemeToString(const CryptoScheme
& aScheme
);
595 : mCryptoScheme(CryptoScheme::None
),
599 CryptoScheme mCryptoScheme
;
601 CopyableTArray
<uint8_t> mKeyId
;
602 uint8_t mCryptByteBlock
;
603 uint8_t mSkipByteBlock
;
604 CopyableTArray
<uint8_t> mConstantIV
;
606 bool IsEncrypted() const { return mCryptoScheme
!= CryptoScheme::None
; }
609 class CryptoSample
: public CryptoTrack
{
611 // The num clear bytes in each subsample. The nth element in the array is the
612 // number of clear bytes at the start of the nth subsample.
613 // Clear sizes are stored as uint16_t in containers per ISO/IEC
614 // 23001-7, but we store them as uint32_t for 2 reasons
615 // - The Widevine CDM accepts clear sizes as uint32_t.
616 // - When converting samples to Annex B we modify the clear sizes and
617 // clear sizes near UINT16_MAX can overflow if stored in a uint16_t.
618 CopyableTArray
<uint32_t> mPlainSizes
;
619 // The num encrypted bytes in each subsample. The nth element in the array is
620 // the number of encrypted bytes at the start of the nth subsample.
621 CopyableTArray
<uint32_t> mEncryptedSizes
;
622 CopyableTArray
<uint8_t> mIV
;
623 CopyableTArray
<CopyableTArray
<uint8_t>> mInitDatas
;
624 nsString mInitDataType
;
627 // MediaRawData is a MediaData container used to store demuxed, still compressed
629 // Use MediaRawData::CreateWriter() to obtain a MediaRawDataWriter object that
630 // provides methods to modify and manipulate the data.
631 // Memory allocations are fallible. Methods return a boolean indicating if
632 // memory allocations were successful. Return values should always be checked.
633 // MediaRawData::mData will be nullptr if no memory has been allocated or if
634 // an error occurred during construction.
635 // Existing data is only ever modified if new memory allocation has succeeded
636 // and preserved if not.
638 // The memory referenced by mData will always be 32 bytes aligned and the
639 // underlying buffer will always have a size such that 32 bytes blocks can be
640 // used to read the content, regardless of the mSize value. Buffer is zeroed
643 // Typical usage: create new MediaRawData; create the associated
644 // MediaRawDataWriter, call SetSize() to allocate memory, write to mData,
645 // up to mSize bytes.
649 class MediaRawDataWriter
{
651 // Pointer to data or null if not-yet allocated
653 // Writeable size of buffer.
655 // Writeable reference to MediaRawData::mCryptoInternal
656 CryptoSample
& mCrypto
;
658 // Data manipulation methods. mData and mSize may be updated accordingly.
660 // Set size of buffer, allocating memory as required.
661 // If memory is allocated, additional buffer area is filled with 0.
662 [[nodiscard
]] bool SetSize(size_t aSize
);
663 // Add aData at the beginning of buffer.
664 [[nodiscard
]] bool Prepend(const uint8_t* aData
, size_t aSize
);
665 [[nodiscard
]] bool Append(const uint8_t* aData
, size_t aSize
);
666 // Replace current content with aData.
667 [[nodiscard
]] bool Replace(const uint8_t* aData
, size_t aSize
);
668 // Clear the memory buffer. Will set target mData and mSize to 0.
670 // Remove aSize bytes from the front of the sample.
671 void PopFront(size_t aSize
);
674 friend class MediaRawData
;
675 explicit MediaRawDataWriter(MediaRawData
* aMediaRawData
);
676 [[nodiscard
]] bool EnsureSize(size_t aSize
);
677 MediaRawData
* mTarget
;
680 class MediaRawData final
: public MediaData
{
683 MediaRawData(const uint8_t* aData
, size_t aSize
);
684 MediaRawData(const uint8_t* aData
, size_t aSize
, const uint8_t* aAlphaData
,
686 explicit MediaRawData(AlignedByteBuffer
&& aData
);
687 MediaRawData(AlignedByteBuffer
&& aData
, AlignedByteBuffer
&& aAlphaData
);
689 // Pointer to data or null if not-yet allocated
690 const uint8_t* Data() const { return mBuffer
.Data(); }
691 // Pointer to alpha data or null if not-yet allocated
692 const uint8_t* AlphaData() const { return mAlphaBuffer
.Data(); }
694 size_t Size() const { return mBuffer
.Length(); }
695 size_t AlphaSize() const { return mAlphaBuffer
.Length(); }
696 size_t ComputedSizeOfIncludingThis() const {
697 return sizeof(*this) + mBuffer
.ComputedSizeOfExcludingThis() +
698 mAlphaBuffer
.ComputedSizeOfExcludingThis();
700 // Access the buffer as a Span.
701 operator Span
<const uint8_t>() { return Span
{Data(), Size()}; }
703 const CryptoSample
& mCrypto
;
704 RefPtr
<MediaByteBuffer
> mExtraData
;
706 // Used by the Vorbis decoder and Ogg demuxer.
707 // Indicates that this is the last packet of the stream.
710 RefPtr
<TrackInfoSharedPtr
> mTrackInfo
;
712 // Used to indicate the id of the temporal scalability layer.
713 Maybe
<uint8_t> mTemporalLayerId
;
715 // May contain the original start time and duration of the frames.
716 // mOriginalPresentationWindow.mStart would always be less or equal to mTime
717 // and mOriginalPresentationWindow.mEnd equal or greater to mTime + mDuration.
718 // This is used when the sample should get cropped so that its content will
719 // actually start on mTime and go for mDuration. If this interval is set, then
720 // the decoder should crop the content accordingly.
721 Maybe
<media::TimeInterval
> mOriginalPresentationWindow
;
723 // If it's true, the `mCrypto` should be copied into the remote data as well.
724 // Currently this is only used for the media engine DRM playback.
725 bool mShouldCopyCryptoToRemoteRawData
= false;
727 // Config used to encode this packet.
728 UniquePtr
<const EncoderConfig
> mConfig
;
730 // It's only used when the remote decoder reconstructs the media raw data.
731 CryptoSample
& GetWritableCrypto() { return mCryptoInternal
; }
733 // Return a deep copy or nullptr if out of memory.
734 already_AddRefed
<MediaRawData
> Clone() const;
735 // Create a MediaRawDataWriter for this MediaRawData. The writer is not
737 UniquePtr
<MediaRawDataWriter
> CreateWriter();
738 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
744 friend class MediaRawDataWriter
;
745 friend class ArrayOfRemoteMediaRawData
;
746 AlignedByteBuffer mBuffer
;
747 AlignedByteBuffer mAlphaBuffer
;
748 CryptoSample mCryptoInternal
;
749 MediaRawData(const MediaRawData
&); // Not implemented
752 // MediaByteBuffer is a ref counted infallible TArray.
753 class MediaByteBuffer
: public nsTArray
<uint8_t> {
754 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer
);
755 MediaByteBuffer() = default;
756 explicit MediaByteBuffer(size_t aCapacity
) : nsTArray
<uint8_t>(aCapacity
) {}
759 ~MediaByteBuffer() = default;
762 // MediaAlignedByteBuffer is a ref counted AlignedByteBuffer whose memory
763 // allocations are fallible.
764 class MediaAlignedByteBuffer final
: public AlignedByteBuffer
{
765 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaAlignedByteBuffer
);
766 MediaAlignedByteBuffer() = default;
767 MediaAlignedByteBuffer(const uint8_t* aData
, size_t aLength
)
768 : AlignedByteBuffer(aData
, aLength
) {}
771 ~MediaAlignedByteBuffer() = default;
774 } // namespace mozilla
776 #endif // MediaData_h