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 "EncoderConfig.h"
12 # include "ImageTypes.h"
13 # include "MediaResult.h"
14 # include "SharedBuffer.h"
15 # include "TimeUnits.h"
16 # include "mozilla/CheckedInt.h"
17 # include "mozilla/DefineEnum.h"
18 # include "mozilla/EnumSet.h"
19 # include "mozilla/Maybe.h"
20 # include "mozilla/PodOperations.h"
21 # include "mozilla/RefPtr.h"
22 # include "mozilla/Result.h"
23 # include "mozilla/Span.h"
24 # include "mozilla/UniquePtr.h"
25 # include "mozilla/UniquePtrExtensions.h"
26 # include "mozilla/gfx/Rect.h"
27 # include "nsString.h"
28 # include "nsTArray.h"
35 class KnowsCompositor
;
38 class MediaByteBuffer
;
39 class TrackInfoSharedPtr
;
42 // Memory allocations are fallibles. Methods return a boolean indicating if
43 // memory allocations were successful. Return values should always be checked.
44 // AlignedBuffer::mData will be nullptr if no memory has been allocated or if
45 // an error occurred during construction.
46 // Existing data is only ever modified if new memory allocation has succeeded
47 // and preserved if not.
49 // The memory referenced by mData will always be Alignment bytes aligned and the
50 // underlying buffer will always have a size such that Alignment bytes blocks
51 // can be used to read the content, regardless of the mSize value. Buffer is
52 // zeroed on creation, elements are not individually constructed.
53 // An Alignment value of 0 means that the data isn't aligned.
55 // Type must be trivially copyable.
57 // AlignedBuffer can typically be used in place of UniquePtr<Type[]> however
58 // care must be taken as all memory allocations are fallible.
60 // auto buffer = MakeUniqueFallible<float[]>(samples)
61 // becomes: AlignedFloatBuffer buffer(samples)
63 // auto buffer = MakeUnique<float[]>(samples)
65 // AlignedFloatBuffer buffer(samples);
66 // if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; }
67 class InflatableShortBuffer
;
68 template <typename Type
, int Alignment
= 32>
71 friend InflatableShortBuffer
;
73 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {}
75 explicit AlignedBuffer(size_t aLength
)
76 : mData(nullptr), mLength(0), mBuffer(nullptr), mCapacity(0) {
77 if (EnsureCapacity(aLength
)) {
82 AlignedBuffer(const Type
* aData
, size_t aLength
) : AlignedBuffer(aLength
) {
86 PodCopy(mData
, aData
, aLength
);
89 AlignedBuffer(const AlignedBuffer
& aOther
)
90 : AlignedBuffer(aOther
.Data(), aOther
.Length()) {}
92 AlignedBuffer(AlignedBuffer
&& aOther
) noexcept
93 : mData(aOther
.mData
),
94 mLength(aOther
.mLength
),
95 mBuffer(std::move(aOther
.mBuffer
)),
96 mCapacity(aOther
.mCapacity
) {
97 aOther
.mData
= nullptr;
102 AlignedBuffer
& operator=(AlignedBuffer
&& aOther
) noexcept
{
103 if (&aOther
== this) {
106 mData
= aOther
.mData
;
107 mLength
= aOther
.mLength
;
108 mBuffer
= std::move(aOther
.mBuffer
);
109 mCapacity
= aOther
.mCapacity
;
110 aOther
.mData
= nullptr;
112 aOther
.mCapacity
= 0;
116 Type
* Data() const { return mData
; }
117 size_t Length() const { return mLength
; }
118 size_t Size() const { return mLength
* sizeof(Type
); }
119 Type
& operator[](size_t aIndex
) {
120 MOZ_ASSERT(aIndex
< mLength
);
121 return mData
[aIndex
];
123 const Type
& operator[](size_t aIndex
) const {
124 MOZ_ASSERT(aIndex
< mLength
);
125 return mData
[aIndex
];
127 // Set length of buffer, allocating memory as required.
128 // If memory is allocated, additional buffer area is filled with 0.
129 bool SetLength(size_t aLength
) {
130 if (aLength
> mLength
&& !EnsureCapacity(aLength
)) {
136 // Add aData at the beginning of buffer.
137 bool Prepend(const Type
* aData
, size_t aLength
) {
138 if (!EnsureCapacity(aLength
+ mLength
)) {
142 // Shift the data to the right by aLength to leave room for the new data.
143 PodMove(mData
+ aLength
, mData
, mLength
);
144 PodCopy(mData
, aData
, aLength
);
149 // Add aData at the end of buffer.
150 bool Append(const Type
* aData
, size_t aLength
) {
151 if (!EnsureCapacity(aLength
+ mLength
)) {
155 PodCopy(mData
+ mLength
, aData
, aLength
);
160 // Replace current content with aData.
161 bool Replace(const Type
* aData
, size_t aLength
) {
162 // If aLength is smaller than our current length, we leave the buffer as is,
163 // only adjusting the reported length.
164 if (!EnsureCapacity(aLength
)) {
168 PodCopy(mData
, aData
, aLength
);
172 // Clear the memory buffer. Will set target mData and mLength to 0.
178 // Methods for reporting memory.
179 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const {
180 size_t size
= aMallocSizeOf(this);
181 size
+= aMallocSizeOf(mBuffer
.get());
184 // AlignedBuffer is typically allocated on the stack. As such, you likely
185 // want to use SizeOfExcludingThis
186 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
187 return aMallocSizeOf(mBuffer
.get());
189 size_t ComputedSizeOfExcludingThis() const { return mCapacity
; }
191 // For backward compatibility with UniquePtr<Type[]>
192 Type
* get() const { return mData
; }
193 explicit operator bool() const { return mData
!= nullptr; }
195 // Size in bytes of extra space allocated for padding.
196 static size_t AlignmentPaddingSize() { return AlignmentOffset() * 2; }
198 void PopFront(size_t aCount
) {
199 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
200 PodMove(mData
, mData
+ aCount
, mLength
- aCount
);
204 void PopBack(size_t aCount
) {
205 MOZ_DIAGNOSTIC_ASSERT(mLength
>= aCount
, "Popping too many elements.");
210 static size_t AlignmentOffset() { return Alignment
? Alignment
- 1 : 0; }
212 // Ensure that the backend buffer can hold aLength data. Will update mData.
213 // Will enforce that the start of allocated data is always Alignment bytes
214 // aligned and that it has sufficient end padding to allow for Alignment bytes
215 // block read as required by some data decoders.
216 // Returns false if memory couldn't be allocated.
217 bool EnsureCapacity(size_t aLength
) {
219 // No need to allocate a buffer yet.
222 const CheckedInt
<size_t> sizeNeeded
=
223 CheckedInt
<size_t>(aLength
) * sizeof(Type
) + AlignmentPaddingSize();
225 if (!sizeNeeded
.isValid() || sizeNeeded
.value() >= INT32_MAX
) {
226 // overflow or over an acceptable size.
229 if (mData
&& mCapacity
>= sizeNeeded
.value()) {
232 auto newBuffer
= MakeUniqueFallible
<uint8_t[]>(sizeNeeded
.value());
237 // Find alignment address.
238 const uintptr_t alignmask
= AlignmentOffset();
239 Type
* newData
= reinterpret_cast<Type
*>(
240 (reinterpret_cast<uintptr_t>(newBuffer
.get()) + alignmask
) &
242 MOZ_ASSERT(uintptr_t(newData
) % (AlignmentOffset() + 1) == 0);
244 MOZ_ASSERT(!mLength
|| mData
);
246 PodZero(newData
+ mLength
, aLength
- mLength
);
248 PodCopy(newData
, mData
, mLength
);
251 mBuffer
= std::move(newBuffer
);
252 mCapacity
= sizeNeeded
.value();
258 size_t mLength
{}; // number of elements
259 UniquePtr
<uint8_t[]> mBuffer
;
260 size_t mCapacity
{}; // in bytes
263 using AlignedByteBuffer
= AlignedBuffer
<uint8_t>;
264 using AlignedFloatBuffer
= AlignedBuffer
<float>;
265 using AlignedShortBuffer
= AlignedBuffer
<int16_t>;
266 using AlignedAudioBuffer
= AlignedBuffer
<AudioDataValue
>;
268 // A buffer in which int16_t audio can be written to, and then converted to
269 // float32 audio without reallocating.
270 // This class is useful when an API hands out int16_t audio but the samples
271 // need to be immediately converted to f32.
272 class InflatableShortBuffer
{
274 explicit InflatableShortBuffer(size_t aElementCount
)
275 : mBuffer(aElementCount
* 2) {}
276 AlignedFloatBuffer
Inflate() {
277 // Convert the data from int16_t to f32 in place, in the same buffer.
278 // The reason this works is because the buffer has in fact twice the
279 // capacity, and the loop goes backward.
280 float* output
= reinterpret_cast<float*>(mBuffer
.mData
);
281 for (size_t i
= Length(); i
--;) {
282 output
[i
] = ConvertAudioSample
<float>(mBuffer
.mData
[i
]);
284 AlignedFloatBuffer rv
;
285 rv
.mBuffer
= std::move(mBuffer
.mBuffer
);
286 rv
.mCapacity
= mBuffer
.mCapacity
;
287 rv
.mLength
= Length();
291 size_t Length() const { return mBuffer
.mLength
/ 2; }
292 int16_t* get() const { return mBuffer
.get(); }
293 explicit operator bool() const { return mBuffer
.mData
!= nullptr; }
296 AlignedShortBuffer mBuffer
;
299 // Container that holds media samples.
302 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaData
)
304 MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING_AT_CLASS_SCOPE(
305 Type
, uint8_t, (AUDIO_DATA
, VIDEO_DATA
, RAW_DATA
, NULL_DATA
));
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 interleaved 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 nsCString
ToString() const;
384 // Access the buffer as a Span.
385 Span
<AudioDataValue
> Data() const;
387 // Amount of frames for contained data.
388 uint32_t Frames() const { return mFrames
; }
390 // Trim the audio buffer such that its apparent content fits within the aTrim
391 // interval. The actual data isn't removed from the buffer and a followup call
392 // to SetTrimWindow could restore the content. mDuration, mTime and mFrames
393 // will be adjusted accordingly.
394 // Warning: rounding may occurs, in which case the new start time of the audio
395 // sample may still be lesser than aTrim.mStart.
396 bool SetTrimWindow(const media::TimeInterval
& aTrim
);
398 // Get the internal audio buffer to be moved. After this call the original
399 // AudioData will be emptied and can't be used again.
400 AlignedAudioBuffer
MoveableData();
402 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
404 // If mAudioBuffer is null, creates it from mAudioData.
405 void EnsureAudioBuffer();
407 // Return true if the adjusted time is valid. Caller should handle error when
408 // the result is invalid.
409 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
411 // This method is used to adjust the original start time, which would change
412 // `mTime` and `mOriginalTime` together, and should only be used for data
413 // which hasn't been trimmed before.
414 void SetOriginalStartTime(const media::TimeUnit
& aStartTime
);
416 const uint32_t mChannels
;
417 // The AudioConfig::ChannelLayout map. Channels are ordered as per SMPTE
418 // definition. A value of UNKNOWN_MAP indicates unknown layout.
419 // ChannelMap is an unsigned bitmap compatible with Windows' WAVE and FFmpeg
421 const AudioConfig::ChannelLayout::ChannelMap mChannelMap
;
422 const uint32_t mRate
;
424 // At least one of mAudioBuffer/mAudioData must be non-null.
425 // mChannels channels, each with mFrames frames
426 RefPtr
<SharedBuffer
> mAudioBuffer
;
429 ~AudioData() = default;
432 friend class ArrayOfRemoteAudioData
;
433 AudioDataValue
* GetAdjustedData() const;
434 media::TimeUnit mOriginalTime
;
435 // mFrames frames, each with mChannels values
436 AlignedAudioBuffer mAudioData
;
437 Maybe
<media::TimeInterval
> mTrimWindow
;
438 // Amount of frames for contained data.
440 size_t mDataOffset
= 0;
445 class PlanarYCbCrImage
;
446 } // namespace layers
450 // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
451 class VideoData
: public MediaData
{
453 using IntRect
= gfx::IntRect
;
454 using IntSize
= gfx::IntSize
;
455 using ColorDepth
= gfx::ColorDepth
;
456 using ColorRange
= gfx::ColorRange
;
457 using YUVColorSpace
= gfx::YUVColorSpace
;
458 using ColorSpace2
= gfx::ColorSpace2
;
459 using ChromaSubsampling
= gfx::ChromaSubsampling
;
460 using ImageContainer
= layers::ImageContainer
;
461 using Image
= layers::Image
;
462 using PlanarYCbCrImage
= layers::PlanarYCbCrImage
;
464 static const Type sType
= Type::VIDEO_DATA
;
465 static const char* sTypeName
;
467 // YCbCr data obtained from decoding the video. The index's are:
481 YUVColorSpace mYUVColorSpace
= YUVColorSpace::Identity
;
482 ColorSpace2 mColorPrimaries
= ColorSpace2::UNKNOWN
;
483 ColorDepth mColorDepth
= ColorDepth::COLOR_8
;
484 ColorRange mColorRange
= ColorRange::LIMITED
;
485 ChromaSubsampling mChromaSubsampling
= ChromaSubsampling::FULL
;
488 // Constructs a VideoData object. If aImage is nullptr, creates a new Image
489 // holding a copy of the YCbCr data passed in aBuffer. If aImage is not
490 // nullptr, it's stored as the underlying video image and aBuffer is assumed
491 // to point to memory within aImage so no copy is made. aTimecode is a codec
492 // specific number representing the timestamp of the frame of video data.
493 // Returns nsnull if an error occurs. This may indicate that memory couldn't
494 // be allocated to create the VideoData object, or it may indicate some
495 // problem with the input data (e.g. negative stride).
497 static bool UseUseNV12ForSoftwareDecodedVideoIfPossible(
498 layers::KnowsCompositor
* aAllocator
);
500 // Creates a new VideoData containing a deep copy of aBuffer. May use
501 // aContainer to allocate an Image to hold the copied data.
502 static Result
<already_AddRefed
<VideoData
>, MediaResult
> CreateAndCopyData(
503 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
504 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
505 const YCbCrBuffer
& aBuffer
, bool aKeyframe
,
506 const media::TimeUnit
& aTimecode
, const IntRect
& aPicture
,
507 layers::KnowsCompositor
* aAllocator
);
509 static already_AddRefed
<VideoData
> CreateAndCopyData(
510 const VideoInfo
& aInfo
, ImageContainer
* aContainer
, int64_t aOffset
,
511 const media::TimeUnit
& aTime
, const media::TimeUnit
& aDuration
,
512 const YCbCrBuffer
& aBuffer
, const YCbCrBuffer::Plane
& aAlphaPlane
,
513 bool aKeyframe
, const media::TimeUnit
& aTimecode
,
514 const IntRect
& aPicture
);
516 static already_AddRefed
<VideoData
> CreateFromImage(
517 const IntSize
& aDisplay
, int64_t aOffset
, const media::TimeUnit
& aTime
,
518 const media::TimeUnit
& aDuration
, const RefPtr
<Image
>& aImage
,
519 bool aKeyframe
, const media::TimeUnit
& aTimecode
);
521 // Initialize PlanarYCbCrImage. Only When aCopyData is true,
522 // video data is copied to PlanarYCbCrImage.
523 static MediaResult
SetVideoDataToImage(PlanarYCbCrImage
* aVideoImage
,
524 const VideoInfo
& aInfo
,
525 const YCbCrBuffer
& aBuffer
,
526 const IntRect
& aPicture
,
529 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
531 // Dimensions at which to display the video frame. The picture region
532 // will be scaled to this size. This is should be the picture region's
533 // dimensions scaled with respect to its aspect ratio.
534 const IntSize mDisplay
;
536 // This frame's image.
537 RefPtr
<Image
> mImage
;
539 ColorDepth
GetColorDepth() const;
543 VideoData(int64_t aOffset
, const media::TimeUnit
& aTime
,
544 const media::TimeUnit
& aDuration
, bool aKeyframe
,
545 const media::TimeUnit
& aTimecode
, IntSize aDisplay
,
548 nsCString
ToString() const;
550 void MarkSentToCompositor() { mSentToCompositor
= true; }
551 bool IsSentToCompositor() { return mSentToCompositor
; }
553 void UpdateDuration(const media::TimeUnit
& aDuration
);
554 void UpdateTimestamp(const media::TimeUnit
& aTimestamp
);
556 // Return true if the adjusted time is valid. Caller should handle error when
557 // the result is invalid.
558 bool AdjustForStartTime(const media::TimeUnit
& aStartTime
);
560 void SetNextKeyFrameTime(const media::TimeUnit
& aTime
) {
561 mNextKeyFrameTime
= aTime
;
564 const media::TimeUnit
& NextKeyFrameTime() const { return mNextKeyFrameTime
; }
569 bool mSentToCompositor
;
570 media::TimeUnit mNextKeyFrameTime
;
573 // See https://w3c.github.io/encrypted-media/#scheme-cenc
574 MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AND_TOSTRING(CryptoScheme
, uint8_t,
575 (None
, Cenc
, Cbcs
, Cbcs_1_9
));
576 using CryptoSchemeSet
= EnumSet
<CryptoScheme
, uint8_t>;
578 nsCString
CryptoSchemeSetToString(const CryptoSchemeSet
& aSchemes
);
579 CryptoScheme
StringToCryptoScheme(const nsAString
& aString
);
584 : mCryptoScheme(CryptoScheme::None
),
588 CryptoScheme mCryptoScheme
;
590 CopyableTArray
<uint8_t> mKeyId
;
591 uint8_t mCryptByteBlock
;
592 uint8_t mSkipByteBlock
;
593 CopyableTArray
<uint8_t> mConstantIV
;
595 bool IsEncrypted() const { return mCryptoScheme
!= CryptoScheme::None
; }
598 class CryptoSample
: public CryptoTrack
{
600 // The num clear bytes in each subsample. The nth element in the array is the
601 // number of clear bytes at the start of the nth subsample.
602 // Clear sizes are stored as uint16_t in containers per ISO/IEC
603 // 23001-7, but we store them as uint32_t for 2 reasons
604 // - The Widevine CDM accepts clear sizes as uint32_t.
605 // - When converting samples to Annex B we modify the clear sizes and
606 // clear sizes near UINT16_MAX can overflow if stored in a uint16_t.
607 CopyableTArray
<uint32_t> mPlainSizes
;
608 // The num encrypted bytes in each subsample. The nth element in the array is
609 // the number of encrypted bytes at the start of the nth subsample.
610 CopyableTArray
<uint32_t> mEncryptedSizes
;
611 CopyableTArray
<uint8_t> mIV
;
612 CopyableTArray
<CopyableTArray
<uint8_t>> mInitDatas
;
613 nsString mInitDataType
;
616 // MediaRawData is a MediaData container used to store demuxed, still compressed
618 // Use MediaRawData::CreateWriter() to obtain a MediaRawDataWriter object that
619 // provides methods to modify and manipulate the data.
620 // Memory allocations are fallible. Methods return a boolean indicating if
621 // memory allocations were successful. Return values should always be checked.
622 // MediaRawData::mData will be nullptr if no memory has been allocated or if
623 // an error occurred during construction.
624 // Existing data is only ever modified if new memory allocation has succeeded
625 // and preserved if not.
627 // The memory referenced by mData will always be 32 bytes aligned and the
628 // underlying buffer will always have a size such that 32 bytes blocks can be
629 // used to read the content, regardless of the mSize value. Buffer is zeroed
632 // Typical usage: create new MediaRawData; create the associated
633 // MediaRawDataWriter, call SetSize() to allocate memory, write to mData,
634 // up to mSize bytes.
638 class MediaRawDataWriter
{
640 // Pointer to data or null if not-yet allocated
642 // Writeable size of buffer.
644 // Writeable reference to MediaRawData::mCryptoInternal
645 CryptoSample
& mCrypto
;
647 // Data manipulation methods. mData and mSize may be updated accordingly.
649 // Set size of buffer, allocating memory as required.
650 // If memory is allocated, additional buffer area is filled with 0.
651 [[nodiscard
]] bool SetSize(size_t aSize
);
652 // Add aData at the beginning of buffer.
653 [[nodiscard
]] bool Prepend(const uint8_t* aData
, size_t aSize
);
654 [[nodiscard
]] bool Append(const uint8_t* aData
, size_t aSize
);
655 // Replace current content with aData.
656 [[nodiscard
]] bool Replace(const uint8_t* aData
, size_t aSize
);
657 // Clear the memory buffer. Will set target mData and mSize to 0.
659 // Remove aSize bytes from the front of the sample.
660 void PopFront(size_t aSize
);
663 friend class MediaRawData
;
664 explicit MediaRawDataWriter(MediaRawData
* aMediaRawData
);
665 [[nodiscard
]] bool EnsureSize(size_t aSize
);
666 MediaRawData
* mTarget
;
669 class MediaRawData final
: public MediaData
{
672 MediaRawData(const uint8_t* aData
, size_t aSize
);
673 MediaRawData(const uint8_t* aData
, size_t aSize
, const uint8_t* aAlphaData
,
675 explicit MediaRawData(AlignedByteBuffer
&& aData
);
676 MediaRawData(AlignedByteBuffer
&& aData
, AlignedByteBuffer
&& aAlphaData
);
678 // Pointer to data or null if not-yet allocated
679 const uint8_t* Data() const { return mBuffer
.Data(); }
680 // Pointer to alpha data or null if not-yet allocated
681 const uint8_t* AlphaData() const { return mAlphaBuffer
.Data(); }
683 size_t Size() const { return mBuffer
.Length(); }
684 size_t AlphaSize() const { return mAlphaBuffer
.Length(); }
685 size_t ComputedSizeOfIncludingThis() const {
686 return sizeof(*this) + mBuffer
.ComputedSizeOfExcludingThis() +
687 mAlphaBuffer
.ComputedSizeOfExcludingThis();
689 // Access the buffer as a Span.
690 operator Span
<const uint8_t>() { return Span
{Data(), Size()}; }
692 const CryptoSample
& mCrypto
;
693 RefPtr
<MediaByteBuffer
> mExtraData
;
695 // Used by the Vorbis decoder and Ogg demuxer.
696 // Indicates that this is the last packet of the stream.
699 RefPtr
<TrackInfoSharedPtr
> mTrackInfo
;
701 // Used to indicate the id of the temporal scalability layer.
702 Maybe
<uint8_t> mTemporalLayerId
;
704 // May contain the original start time and duration of the frames.
705 // mOriginalPresentationWindow.mStart would always be less or equal to mTime
706 // and mOriginalPresentationWindow.mEnd equal or greater to mTime + mDuration.
707 // This is used when the sample should get cropped so that its content will
708 // actually start on mTime and go for mDuration. If this interval is set, then
709 // the decoder should crop the content accordingly.
710 Maybe
<media::TimeInterval
> mOriginalPresentationWindow
;
712 // If it's true, the `mCrypto` should be copied into the remote data as well.
713 // Currently this is only used for the media engine DRM playback.
714 bool mShouldCopyCryptoToRemoteRawData
= false;
716 // Config used to encode this packet.
717 UniquePtr
<const EncoderConfig
> mConfig
;
719 // It's only used when the remote decoder reconstructs the media raw data.
720 CryptoSample
& GetWritableCrypto() { return mCryptoInternal
; }
722 // Return a deep copy or nullptr if out of memory.
723 already_AddRefed
<MediaRawData
> Clone() const;
724 // Create a MediaRawDataWriter for this MediaRawData. The writer is not
726 UniquePtr
<MediaRawDataWriter
> CreateWriter();
727 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const;
733 friend class MediaRawDataWriter
;
734 friend class ArrayOfRemoteMediaRawData
;
735 AlignedByteBuffer mBuffer
;
736 AlignedByteBuffer mAlphaBuffer
;
737 CryptoSample mCryptoInternal
;
738 MediaRawData(const MediaRawData
&); // Not implemented
741 // MediaByteBuffer is a ref counted infallible TArray.
742 class MediaByteBuffer
: public nsTArray
<uint8_t> {
743 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer
);
744 MediaByteBuffer() = default;
745 explicit MediaByteBuffer(size_t aCapacity
) : nsTArray
<uint8_t>(aCapacity
) {}
748 ~MediaByteBuffer() = default;
751 // MediaAlignedByteBuffer is a ref counted AlignedByteBuffer whose memory
752 // allocations are fallible.
753 class MediaAlignedByteBuffer final
: public AlignedByteBuffer
{
754 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaAlignedByteBuffer
);
755 MediaAlignedByteBuffer() = default;
756 MediaAlignedByteBuffer(const uint8_t* aData
, size_t aLength
)
757 : AlignedByteBuffer(aData
, aLength
) {}
760 ~MediaAlignedByteBuffer() = default;
763 } // namespace mozilla
765 #endif // MediaData_h