Backed out changeset f594e6f00208 (bug 1940883) for causing crashes in bug 1941164.
[gecko.git] / dom / media / MediaData.h
blob488f68d49d7114782580ee5ff7e446efbbb40f2b
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)
7 # define 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"
30 namespace mozilla {
32 namespace layers {
33 class Image;
34 class ImageContainer;
35 class KnowsCompositor;
36 } // namespace layers
38 class MediaByteBuffer;
39 class TrackInfoSharedPtr;
41 // AlignedBuffer:
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.
59 // Example:
60 // auto buffer = MakeUniqueFallible<float[]>(samples)
61 // becomes: AlignedFloatBuffer buffer(samples)
63 // auto buffer = MakeUnique<float[]>(samples)
64 // becomes:
65 // AlignedFloatBuffer buffer(samples);
66 // if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; }
67 class InflatableShortBuffer;
68 template <typename Type, int Alignment = 32>
69 class AlignedBuffer {
70 public:
71 friend InflatableShortBuffer;
72 AlignedBuffer()
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)) {
78 mLength = aLength;
82 AlignedBuffer(const Type* aData, size_t aLength) : AlignedBuffer(aLength) {
83 if (!mData) {
84 return;
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;
98 aOther.mLength = 0;
99 aOther.mCapacity = 0;
102 AlignedBuffer& operator=(AlignedBuffer&& aOther) noexcept {
103 if (&aOther == this) {
104 return *this;
106 mData = aOther.mData;
107 mLength = aOther.mLength;
108 mBuffer = std::move(aOther.mBuffer);
109 mCapacity = aOther.mCapacity;
110 aOther.mData = nullptr;
111 aOther.mLength = 0;
112 aOther.mCapacity = 0;
113 return *this;
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)) {
131 return false;
133 mLength = aLength;
134 return true;
136 // Add aData at the beginning of buffer.
137 bool Prepend(const Type* aData, size_t aLength) {
138 if (!EnsureCapacity(aLength + mLength)) {
139 return false;
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);
146 mLength += aLength;
147 return true;
149 // Add aData at the end of buffer.
150 bool Append(const Type* aData, size_t aLength) {
151 if (!EnsureCapacity(aLength + mLength)) {
152 return false;
155 PodCopy(mData + mLength, aData, aLength);
157 mLength += aLength;
158 return true;
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)) {
165 return false;
168 PodCopy(mData, aData, aLength);
169 mLength = aLength;
170 return true;
172 // Clear the memory buffer. Will set target mData and mLength to 0.
173 void Clear() {
174 mLength = 0;
175 mData = nullptr;
178 // Methods for reporting memory.
179 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
180 size_t size = aMallocSizeOf(this);
181 size += aMallocSizeOf(mBuffer.get());
182 return size;
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);
201 mLength -= aCount;
204 void PopBack(size_t aCount) {
205 MOZ_DIAGNOSTIC_ASSERT(mLength >= aCount, "Popping too many elements.");
206 mLength -= aCount;
209 private:
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) {
218 if (!aLength) {
219 // No need to allocate a buffer yet.
220 return true;
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.
227 return false;
229 if (mData && mCapacity >= sizeNeeded.value()) {
230 return true;
232 auto newBuffer = MakeUniqueFallible<uint8_t[]>(sizeNeeded.value());
233 if (!newBuffer) {
234 return false;
237 // Find alignment address.
238 const uintptr_t alignmask = AlignmentOffset();
239 Type* newData = reinterpret_cast<Type*>(
240 (reinterpret_cast<uintptr_t>(newBuffer.get()) + alignmask) &
241 ~alignmask);
242 MOZ_ASSERT(uintptr_t(newData) % (AlignmentOffset() + 1) == 0);
244 MOZ_ASSERT(!mLength || mData);
246 PodZero(newData + mLength, aLength - mLength);
247 if (mLength) {
248 PodCopy(newData, mData, mLength);
251 mBuffer = std::move(newBuffer);
252 mCapacity = sizeNeeded.value();
253 mData = newData;
255 return true;
257 Type* mData;
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 {
273 public:
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();
288 rv.mData = output;
289 return rv;
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; }
295 protected:
296 AlignedShortBuffer mBuffer;
299 // Container that holds media samples.
300 class MediaData {
301 public:
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)
309 : mType(aType),
310 mOffset(aOffset),
311 mTime(aTimestamp),
312 mTimecode(aTimestamp),
313 mDuration(aDuration),
314 mKeyframe(false) {}
316 // Type of contained data.
317 const Type mType;
319 // Approximate byte offset where this data was demuxed from its media.
320 int64_t mOffset;
322 // Start time of sample.
323 media::TimeUnit mTime;
325 // Codec specific internal time code. For Ogg based codecs this is the
326 // granulepos.
327 media::TimeUnit mTimecode;
329 // Duration of sample, in microseconds.
330 media::TimeUnit mDuration;
332 bool mKeyframe;
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>
350 ReturnType* As() {
351 MOZ_ASSERT(this->mType == ReturnType::sType);
352 return static_cast<ReturnType*>(this);
355 protected:
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
362 // rendered.
363 class NullData : public MediaData {
364 public:
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 {
374 public:
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
420 // channel map.
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;
428 protected:
429 ~AudioData() = default;
431 private:
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.
439 uint32_t mFrames;
440 size_t mDataOffset = 0;
443 namespace layers {
444 class TextureClient;
445 class PlanarYCbCrImage;
446 } // namespace layers
448 class VideoInfo;
450 // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
451 class VideoData : public MediaData {
452 public:
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:
468 // 0 = Y
469 // 1 = Cb
470 // 2 = Cr
471 struct YCbCrBuffer {
472 struct Plane {
473 uint8_t* mData;
474 uint32_t mWidth;
475 uint32_t mHeight;
476 uint32_t mStride;
477 uint32_t mSkip;
480 Plane mPlanes[3]{};
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,
527 bool aCopyData);
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;
541 uint32_t mFrameID;
543 VideoData(int64_t aOffset, const media::TimeUnit& aTime,
544 const media::TimeUnit& aDuration, bool aKeyframe,
545 const media::TimeUnit& aTimecode, IntSize aDisplay,
546 uint32_t aFrameID);
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; }
566 protected:
567 ~VideoData();
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);
581 class CryptoTrack {
582 public:
583 CryptoTrack()
584 : mCryptoScheme(CryptoScheme::None),
585 mIVSize(0),
586 mCryptByteBlock(0),
587 mSkipByteBlock(0) {}
588 CryptoScheme mCryptoScheme;
589 int32_t mIVSize;
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 {
599 public:
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
617 // samples.
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
630 // on creation.
632 // Typical usage: create new MediaRawData; create the associated
633 // MediaRawDataWriter, call SetSize() to allocate memory, write to mData,
634 // up to mSize bytes.
636 class MediaRawData;
638 class MediaRawDataWriter {
639 public:
640 // Pointer to data or null if not-yet allocated
641 uint8_t* Data();
642 // Writeable size of buffer.
643 size_t Size();
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.
658 void Clear();
659 // Remove aSize bytes from the front of the sample.
660 void PopFront(size_t aSize);
662 private:
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 {
670 public:
671 MediaRawData();
672 MediaRawData(const uint8_t* aData, size_t aSize);
673 MediaRawData(const uint8_t* aData, size_t aSize, const uint8_t* aAlphaData,
674 size_t aAlphaSize);
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(); }
682 // Size of buffer.
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.
697 bool mEOS = false;
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
725 // thread-safe.
726 UniquePtr<MediaRawDataWriter> CreateWriter();
727 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
729 protected:
730 ~MediaRawData();
732 private:
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) {}
747 private:
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) {}
759 private:
760 ~MediaAlignedByteBuffer() = default;
763 } // namespace mozilla
765 #endif // MediaData_h