Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 : #if !defined(MediaData_h)
7 : #define MediaData_h
8 :
9 : #include "AudioSampleFormat.h"
10 : #include "ImageTypes.h"
11 : #include "SharedBuffer.h"
12 : #include "TimeUnits.h"
13 : #include "mozilla/CheckedInt.h"
14 : #include "mozilla/PodOperations.h"
15 : #include "mozilla/RefPtr.h"
16 : #include "mozilla/Span.h"
17 : #include "mozilla/UniquePtr.h"
18 : #include "mozilla/UniquePtrExtensions.h"
19 : #include "mozilla/gfx/Rect.h"
20 : #include "nsIMemoryReporter.h"
21 : #include "nsRect.h"
22 : #include "nsSize.h"
23 : #include "nsTArray.h"
24 :
25 : namespace mozilla {
26 :
27 : namespace layers {
28 : class Image;
29 : class ImageContainer;
30 : class KnowsCompositor;
31 : } // namespace layers
32 :
33 : class MediaByteBuffer;
34 : class TrackInfoSharedPtr;
35 :
36 : // AlignedBuffer:
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.
43 : //
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.
49 : //
50 : // Type must be trivially copyable.
51 : //
52 : // AlignedBuffer can typically be used in place of UniquePtr<Type[]> however
53 : // care must be taken as all memory allocations are fallible.
54 : // Example:
55 : // auto buffer = MakeUniqueFallible<float[]>(samples)
56 : // becomes: AlignedFloatBuffer buffer(samples)
57 : //
58 : // auto buffer = MakeUnique<float[]>(samples)
59 : // becomes:
60 : // AlignedFloatBuffer buffer(samples);
61 : // if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; }
62 :
63 : template <typename Type, int Alignment = 32>
64 0 : class AlignedBuffer
65 : {
66 : public:
67 0 : AlignedBuffer()
68 : : mData(nullptr)
69 : , mLength(0)
70 : , mBuffer(nullptr)
71 0 : , mCapacity(0)
72 : {
73 0 : }
74 :
75 0 : explicit AlignedBuffer(size_t aLength)
76 : : mData(nullptr)
77 : , mLength(0)
78 : , mBuffer(nullptr)
79 0 : , mCapacity(0)
80 : {
81 0 : if (EnsureCapacity(aLength)) {
82 0 : mLength = aLength;
83 : }
84 0 : }
85 :
86 0 : AlignedBuffer(const Type* aData, size_t aLength)
87 0 : : AlignedBuffer(aLength)
88 : {
89 0 : if (!mData) {
90 0 : return;
91 : }
92 0 : PodCopy(mData, aData, aLength);
93 : }
94 :
95 : AlignedBuffer(const AlignedBuffer& aOther)
96 : : AlignedBuffer(aOther.Data(), aOther.Length())
97 : {
98 : }
99 :
100 0 : AlignedBuffer(AlignedBuffer&& aOther)
101 0 : : mData(aOther.mData)
102 0 : , mLength(aOther.mLength)
103 0 : , mBuffer(Move(aOther.mBuffer))
104 0 : , mCapacity(aOther.mCapacity)
105 : {
106 0 : aOther.mData = nullptr;
107 0 : aOther.mLength = 0;
108 0 : aOther.mCapacity = 0;
109 0 : }
110 :
111 0 : AlignedBuffer& operator=(AlignedBuffer&& aOther)
112 : {
113 0 : this->~AlignedBuffer();
114 0 : new (this) AlignedBuffer(Move(aOther));
115 0 : return *this;
116 : }
117 :
118 0 : Type* Data() const { return mData; }
119 0 : size_t Length() const { return mLength; }
120 : size_t Size() const { return mLength * sizeof(Type); }
121 0 : Type& operator[](size_t aIndex)
122 : {
123 0 : MOZ_ASSERT(aIndex < mLength);
124 0 : return mData[aIndex];
125 : }
126 0 : const Type& operator[](size_t aIndex) const
127 : {
128 0 : MOZ_ASSERT(aIndex < mLength);
129 0 : return mData[aIndex];
130 : }
131 : // Set length of buffer, allocating memory as required.
132 : // If length is increased, new buffer area is filled with 0.
133 0 : bool SetLength(size_t aLength)
134 : {
135 0 : if (aLength > mLength && !EnsureCapacity(aLength)) {
136 0 : return false;
137 : }
138 0 : mLength = aLength;
139 0 : return true;
140 : }
141 : // Add aData at the beginning of buffer.
142 0 : bool Prepend(const Type* aData, size_t aLength)
143 : {
144 0 : if (!EnsureCapacity(aLength + mLength)) {
145 0 : return false;
146 : }
147 :
148 : // Shift the data to the right by aLength to leave room for the new data.
149 0 : PodMove(mData + aLength, mData, mLength);
150 0 : PodCopy(mData, aData, aLength);
151 :
152 0 : mLength += aLength;
153 0 : return true;
154 : }
155 : // Add aData at the end of buffer.
156 0 : bool Append(const Type* aData, size_t aLength)
157 : {
158 0 : if (!EnsureCapacity(aLength + mLength)) {
159 0 : return false;
160 : }
161 :
162 0 : PodCopy(mData + mLength, aData, aLength);
163 :
164 0 : mLength += aLength;
165 0 : return true;
166 : }
167 : // Replace current content with aData.
168 0 : bool Replace(const Type* aData, size_t aLength)
169 : {
170 : // If aLength is smaller than our current length, we leave the buffer as is,
171 : // only adjusting the reported length.
172 0 : if (!EnsureCapacity(aLength)) {
173 0 : return false;
174 : }
175 :
176 0 : PodCopy(mData, aData, aLength);
177 0 : mLength = aLength;
178 0 : return true;
179 : }
180 : // Clear the memory buffer. Will set target mData and mLength to 0.
181 0 : void Clear()
182 : {
183 0 : mLength = 0;
184 0 : mData = nullptr;
185 0 : }
186 :
187 : // Methods for reporting memory.
188 : size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
189 : {
190 : size_t size = aMallocSizeOf(this);
191 : size += aMallocSizeOf(mBuffer.get());
192 : return size;
193 : }
194 : // AlignedBuffer is typically allocated on the stack. As such, you likely
195 : // want to use SizeOfExcludingThis
196 0 : size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
197 : {
198 0 : return aMallocSizeOf(mBuffer.get());
199 : }
200 0 : size_t ComputedSizeOfExcludingThis() const
201 : {
202 0 : return mCapacity;
203 : }
204 :
205 : // For backward compatibility with UniquePtr<Type[]>
206 0 : Type* get() const { return mData; }
207 0 : explicit operator bool() const { return mData != nullptr; }
208 :
209 : // Size in bytes of extra space allocated for padding.
210 0 : static size_t AlignmentPaddingSize()
211 : {
212 0 : return AlignmentOffset() * 2;
213 : }
214 :
215 : private:
216 0 : static size_t AlignmentOffset()
217 : {
218 0 : return Alignment ? Alignment - 1 : 0;
219 : }
220 :
221 : // Ensure that the backend buffer can hold aLength data. Will update mData.
222 : // Will enforce that the start of allocated data is always Alignment bytes
223 : // aligned and that it has sufficient end padding to allow for Alignment bytes
224 : // block read as required by some data decoders.
225 : // Returns false if memory couldn't be allocated.
226 0 : bool EnsureCapacity(size_t aLength)
227 : {
228 0 : if (!aLength) {
229 : // No need to allocate a buffer yet.
230 0 : return true;
231 : }
232 : const CheckedInt<size_t> sizeNeeded =
233 0 : CheckedInt<size_t>(aLength) * sizeof(Type) + AlignmentPaddingSize();
234 :
235 0 : if (!sizeNeeded.isValid() || sizeNeeded.value() >= INT32_MAX) {
236 : // overflow or over an acceptable size.
237 0 : return false;
238 : }
239 0 : if (mData && mCapacity >= sizeNeeded.value()) {
240 0 : return true;
241 : }
242 0 : auto newBuffer = MakeUniqueFallible<uint8_t[]>(sizeNeeded.value());
243 0 : if (!newBuffer) {
244 0 : return false;
245 : }
246 :
247 : // Find alignment address.
248 0 : const uintptr_t alignmask = AlignmentOffset();
249 : Type* newData = reinterpret_cast<Type*>(
250 0 : (reinterpret_cast<uintptr_t>(newBuffer.get()) + alignmask) & ~alignmask);
251 0 : MOZ_ASSERT(uintptr_t(newData) % (AlignmentOffset()+1) == 0);
252 :
253 0 : MOZ_ASSERT(!mLength || mData);
254 :
255 0 : PodZero(newData + mLength, aLength - mLength);
256 0 : if (mLength) {
257 0 : PodCopy(newData, mData, mLength);
258 : }
259 :
260 0 : mBuffer = Move(newBuffer);
261 0 : mCapacity = sizeNeeded.value();
262 0 : mData = newData;
263 :
264 0 : return true;
265 : }
266 : Type* mData;
267 : size_t mLength;
268 : UniquePtr<uint8_t[]> mBuffer;
269 : size_t mCapacity;
270 : };
271 :
272 : typedef AlignedBuffer<uint8_t> AlignedByteBuffer;
273 : typedef AlignedBuffer<float> AlignedFloatBuffer;
274 : typedef AlignedBuffer<int16_t> AlignedShortBuffer;
275 : typedef AlignedBuffer<AudioDataValue> AlignedAudioBuffer;
276 :
277 : // Container that holds media samples.
278 : class MediaData
279 : {
280 : public:
281 :
282 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaData)
283 :
284 : enum Type
285 : {
286 : AUDIO_DATA = 0,
287 : VIDEO_DATA,
288 : RAW_DATA,
289 : NULL_DATA
290 : };
291 :
292 0 : MediaData(Type aType,
293 : int64_t aOffset,
294 : const media::TimeUnit& aTimestamp,
295 : const media::TimeUnit& aDuration,
296 : uint32_t aFrames)
297 0 : : mType(aType)
298 : , mOffset(aOffset)
299 : , mTime(aTimestamp)
300 : , mTimecode(aTimestamp)
301 : , mDuration(aDuration)
302 : , mFrames(aFrames)
303 0 : , mKeyframe(false)
304 : {
305 0 : }
306 :
307 : // Type of contained data.
308 : const Type mType;
309 :
310 : // Approximate byte offset where this data was demuxed from its media.
311 : int64_t mOffset;
312 :
313 : // Start time of sample.
314 : media::TimeUnit mTime;
315 :
316 : // Codec specific internal time code. For Ogg based codecs this is the
317 : // granulepos.
318 : media::TimeUnit mTimecode;
319 :
320 : // Duration of sample, in microseconds.
321 : media::TimeUnit mDuration;
322 :
323 : // Amount of frames for contained data.
324 : const uint32_t mFrames;
325 :
326 : bool mKeyframe;
327 :
328 0 : media::TimeUnit GetEndTime() const
329 : {
330 0 : return mTime + mDuration;
331 : }
332 :
333 0 : bool AdjustForStartTime(int64_t aStartTime)
334 : {
335 0 : mTime = mTime - media::TimeUnit::FromMicroseconds(aStartTime);
336 0 : return !mTime.IsNegative();
337 : }
338 :
339 : template <typename ReturnType>
340 : const ReturnType* As() const
341 : {
342 : MOZ_ASSERT(this->mType == ReturnType::sType);
343 : return static_cast<const ReturnType*>(this);
344 : }
345 :
346 : template <typename ReturnType>
347 0 : ReturnType* As()
348 : {
349 0 : MOZ_ASSERT(this->mType == ReturnType::sType);
350 0 : return static_cast<ReturnType*>(this);
351 : }
352 :
353 : protected:
354 0 : MediaData(Type aType, uint32_t aFrames)
355 0 : : mType(aType)
356 : , mOffset(0)
357 : , mFrames(aFrames)
358 0 : , mKeyframe(false)
359 : {
360 0 : }
361 :
362 0 : virtual ~MediaData() { }
363 :
364 : };
365 :
366 : // NullData is for decoder generating a sample which doesn't need to be
367 : // rendered.
368 : class NullData : public MediaData
369 : {
370 : public:
371 : NullData(int64_t aOffset,
372 : const media::TimeUnit& aTime,
373 : const media::TimeUnit& aDuration)
374 : : MediaData(NULL_DATA, aOffset, aTime, aDuration, 0)
375 : {
376 : }
377 :
378 : static const Type sType = NULL_DATA;
379 : };
380 :
381 : // Holds chunk a decoded audio frames.
382 : class AudioData : public MediaData
383 : {
384 : public:
385 :
386 0 : AudioData(int64_t aOffset,
387 : const media::TimeUnit& aTime,
388 : const media::TimeUnit& aDuration,
389 : uint32_t aFrames,
390 : AlignedAudioBuffer&& aData,
391 : uint32_t aChannels,
392 : uint32_t aRate)
393 0 : : MediaData(sType, aOffset, aTime, aDuration, aFrames)
394 : , mChannels(aChannels)
395 : , mRate(aRate)
396 0 : , mAudioData(Move(aData))
397 : {
398 0 : }
399 :
400 : static const Type sType = AUDIO_DATA;
401 : static const char* sTypeName;
402 :
403 : // Creates a new AudioData identical to aOther, but with a different
404 : // specified timestamp and duration. All data from aOther is copied
405 : // into the new AudioData but the audio data which is transferred.
406 : // After such call, the original aOther is unusable.
407 : static already_AddRefed<AudioData>
408 : TransferAndUpdateTimestampAndDuration(AudioData* aOther,
409 : const media::TimeUnit& aTimestamp,
410 : const media::TimeUnit& aDuration);
411 :
412 : size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
413 :
414 : // If mAudioBuffer is null, creates it from mAudioData.
415 : void EnsureAudioBuffer();
416 :
417 : // To check whether mAudioData has audible signal, it's used to distinguish
418 : // the audiable data and silent data.
419 : bool IsAudible() const;
420 :
421 : const uint32_t mChannels;
422 : const uint32_t mRate;
423 : // At least one of mAudioBuffer/mAudioData must be non-null.
424 : // mChannels channels, each with mFrames frames
425 : RefPtr<SharedBuffer> mAudioBuffer;
426 : // mFrames frames, each with mChannels values
427 : AlignedAudioBuffer mAudioData;
428 :
429 : protected:
430 0 : ~AudioData() { }
431 : };
432 :
433 : namespace layers {
434 : class TextureClient;
435 : class PlanarYCbCrImage;
436 : } // namespace layers
437 :
438 : class VideoInfo;
439 :
440 : // Holds a decoded video frame, in YCbCr format. These are queued in the reader.
441 : class VideoData : public MediaData
442 : {
443 : public:
444 : typedef gfx::IntRect IntRect;
445 : typedef gfx::IntSize IntSize;
446 : typedef layers::ImageContainer ImageContainer;
447 : typedef layers::Image Image;
448 : typedef layers::PlanarYCbCrImage PlanarYCbCrImage;
449 :
450 : static const Type sType = VIDEO_DATA;
451 : static const char* sTypeName;
452 :
453 : // YCbCr data obtained from decoding the video. The index's are:
454 : // 0 = Y
455 : // 1 = Cb
456 : // 2 = Cr
457 0 : struct YCbCrBuffer
458 : {
459 : struct Plane
460 : {
461 : uint8_t* mData;
462 : uint32_t mWidth;
463 : uint32_t mHeight;
464 : uint32_t mStride;
465 : uint32_t mOffset;
466 : uint32_t mSkip;
467 : };
468 :
469 : Plane mPlanes[3];
470 : YUVColorSpace mYUVColorSpace = YUVColorSpace::BT601;
471 : };
472 :
473 : class Listener
474 : {
475 : public:
476 : virtual void OnSentToCompositor() = 0;
477 : virtual ~Listener() { }
478 : };
479 :
480 : // Constructs a VideoData object. If aImage is nullptr, creates a new Image
481 : // holding a copy of the YCbCr data passed in aBuffer. If aImage is not
482 : // nullptr, it's stored as the underlying video image and aBuffer is assumed
483 : // to point to memory within aImage so no copy is made. aTimecode is a codec
484 : // specific number representing the timestamp of the frame of video data.
485 : // Returns nsnull if an error occurs. This may indicate that memory couldn't
486 : // be allocated to create the VideoData object, or it may indicate some
487 : // problem with the input data (e.g. negative stride).
488 :
489 :
490 : // Creates a new VideoData containing a deep copy of aBuffer. May use
491 : // aContainer to allocate an Image to hold the copied data.
492 : static already_AddRefed<VideoData> CreateAndCopyData(
493 : const VideoInfo& aInfo,
494 : ImageContainer* aContainer,
495 : int64_t aOffset,
496 : const media::TimeUnit& aTime,
497 : const media::TimeUnit& aDuration,
498 : const YCbCrBuffer& aBuffer,
499 : bool aKeyframe,
500 : const media::TimeUnit& aTimecode,
501 : const IntRect& aPicture,
502 : layers::KnowsCompositor* aAllocator = nullptr);
503 :
504 : static already_AddRefed<VideoData> CreateAndCopyData(
505 : const VideoInfo& aInfo,
506 : ImageContainer* aContainer,
507 : int64_t aOffset,
508 : const media::TimeUnit& aTime,
509 : const media::TimeUnit& aDuration,
510 : const YCbCrBuffer& aBuffer,
511 : const YCbCrBuffer::Plane& aAlphaPlane,
512 : bool aKeyframe,
513 : const media::TimeUnit& aTimecode,
514 : const IntRect& aPicture);
515 :
516 : static already_AddRefed<VideoData> CreateAndCopyIntoTextureClient(
517 : const VideoInfo& aInfo,
518 : int64_t aOffset,
519 : const media::TimeUnit& aTime,
520 : const media::TimeUnit& aDuration,
521 : layers::TextureClient* aBuffer,
522 : bool aKeyframe,
523 : const media::TimeUnit& aTimecode,
524 : const IntRect& aPicture);
525 :
526 : static already_AddRefed<VideoData> CreateFromImage(
527 : const IntSize& aDisplay,
528 : int64_t aOffset,
529 : const media::TimeUnit& aTime,
530 : const media::TimeUnit& aDuration,
531 : const RefPtr<Image>& aImage,
532 : bool aKeyframe,
533 : const media::TimeUnit& aTimecode);
534 :
535 : // Initialize PlanarYCbCrImage. Only When aCopyData is true,
536 : // video data is copied to PlanarYCbCrImage.
537 : static bool SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
538 : const VideoInfo& aInfo,
539 : const YCbCrBuffer& aBuffer,
540 : const IntRect& aPicture,
541 : bool aCopyData);
542 :
543 : size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
544 :
545 : // Dimensions at which to display the video frame. The picture region
546 : // will be scaled to this size. This is should be the picture region's
547 : // dimensions scaled with respect to its aspect ratio.
548 : const IntSize mDisplay;
549 :
550 : // This frame's image.
551 : RefPtr<Image> mImage;
552 :
553 : int32_t mFrameID;
554 :
555 : VideoData(int64_t aOffset,
556 : const media::TimeUnit& aTime,
557 : const media::TimeUnit& aDuration,
558 : bool aKeyframe,
559 : const media::TimeUnit& aTimecode,
560 : IntSize aDisplay,
561 : uint32_t aFrameID);
562 :
563 : void SetListener(UniquePtr<Listener> aListener);
564 : void MarkSentToCompositor();
565 0 : bool IsSentToCompositor() { return mSentToCompositor; }
566 :
567 : void UpdateDuration(const media::TimeUnit& aDuration);
568 : void UpdateTimestamp(const media::TimeUnit& aTimestamp);
569 :
570 : protected:
571 : ~VideoData();
572 :
573 : bool mSentToCompositor;
574 : UniquePtr<Listener> mListener;
575 : };
576 :
577 0 : class CryptoTrack
578 : {
579 : public:
580 2 : CryptoTrack() : mValid(false), mMode(0), mIVSize(0) { }
581 : bool mValid;
582 : int32_t mMode;
583 : int32_t mIVSize;
584 : nsTArray<uint8_t> mKeyId;
585 : };
586 :
587 0 : class CryptoSample : public CryptoTrack
588 : {
589 : public:
590 : nsTArray<uint16_t> mPlainSizes;
591 : nsTArray<uint32_t> mEncryptedSizes;
592 : nsTArray<uint8_t> mIV;
593 : nsTArray<nsCString> mSessionIds;
594 : };
595 :
596 : // MediaRawData is a MediaData container used to store demuxed, still compressed
597 : // samples.
598 : // Use MediaRawData::CreateWriter() to obtain a MediaRawDataWriter object that
599 : // provides methods to modify and manipulate the data.
600 : // Memory allocations are fallible. Methods return a boolean indicating if
601 : // memory allocations were successful. Return values should always be checked.
602 : // MediaRawData::mData will be nullptr if no memory has been allocated or if
603 : // an error occurred during construction.
604 : // Existing data is only ever modified if new memory allocation has succeeded
605 : // and preserved if not.
606 : //
607 : // The memory referenced by mData will always be 32 bytes aligned and the
608 : // underlying buffer will always have a size such that 32 bytes blocks can be
609 : // used to read the content, regardless of the mSize value. Buffer is zeroed
610 : // on creation.
611 : //
612 : // Typical usage: create new MediaRawData; create the associated
613 : // MediaRawDataWriter, call SetSize() to allocate memory, write to mData,
614 : // up to mSize bytes.
615 :
616 : class MediaRawData;
617 :
618 : class MediaRawDataWriter
619 : {
620 : public:
621 : // Pointer to data or null if not-yet allocated
622 : uint8_t* Data();
623 : // Writeable size of buffer.
624 : size_t Size();
625 : // Writeable reference to MediaRawData::mCryptoInternal
626 : CryptoSample& mCrypto;
627 :
628 : // Data manipulation methods. mData and mSize may be updated accordingly.
629 :
630 : // Set size of buffer, allocating memory as required.
631 : // If size is increased, new buffer area is filled with 0.
632 : bool SetSize(size_t aSize);
633 : // Add aData at the beginning of buffer.
634 : bool Prepend(const uint8_t* aData, size_t aSize);
635 : // Replace current content with aData.
636 : bool Replace(const uint8_t* aData, size_t aSize);
637 : // Clear the memory buffer. Will set target mData and mSize to 0.
638 : void Clear();
639 :
640 : private:
641 : friend class MediaRawData;
642 : explicit MediaRawDataWriter(MediaRawData* aMediaRawData);
643 : bool EnsureSize(size_t aSize);
644 : MediaRawData* mTarget;
645 : };
646 :
647 : class MediaRawData : public MediaData
648 : {
649 : public:
650 : MediaRawData();
651 : MediaRawData(const uint8_t* aData, size_t aSize);
652 : MediaRawData(const uint8_t* aData, size_t aSize,
653 : const uint8_t* aAlphaData, size_t aAlphaSize);
654 :
655 : // Pointer to data or null if not-yet allocated
656 0 : const uint8_t* Data() const { return mBuffer.Data(); }
657 : // Pointer to alpha data or null if not-yet allocated
658 0 : const uint8_t* AlphaData() const { return mAlphaBuffer.Data(); }
659 : // Size of buffer.
660 0 : size_t Size() const { return mBuffer.Length(); }
661 0 : size_t AlphaSize() const { return mAlphaBuffer.Length(); }
662 0 : size_t ComputedSizeOfIncludingThis() const
663 : {
664 : return sizeof(*this)
665 0 : + mBuffer.ComputedSizeOfExcludingThis()
666 0 : + mAlphaBuffer.ComputedSizeOfExcludingThis();
667 : }
668 : // Access the buffer as a Span.
669 0 : operator Span<const uint8_t>() { return MakeSpan(Data(), Size()); }
670 :
671 : const CryptoSample& mCrypto;
672 : RefPtr<MediaByteBuffer> mExtraData;
673 :
674 : // Used by the Vorbis decoder and Ogg demuxer.
675 : // Indicates that this is the last packet of the stream.
676 : bool mEOS = false;
677 :
678 : // Indicate to the audio decoder that mDiscardPadding frames should be
679 : // trimmed.
680 : uint32_t mDiscardPadding = 0;
681 :
682 : RefPtr<TrackInfoSharedPtr> mTrackInfo;
683 :
684 : // Return a deep copy or nullptr if out of memory.
685 : virtual already_AddRefed<MediaRawData> Clone() const;
686 : // Create a MediaRawDataWriter for this MediaRawData. The caller must
687 : // delete the writer once done. The writer is not thread-safe.
688 : virtual MediaRawDataWriter* CreateWriter();
689 : virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
690 :
691 : protected:
692 : ~MediaRawData();
693 :
694 : private:
695 : friend class MediaRawDataWriter;
696 : AlignedByteBuffer mBuffer;
697 : AlignedByteBuffer mAlphaBuffer;
698 : CryptoSample mCryptoInternal;
699 : MediaRawData(const MediaRawData&); // Not implemented
700 : };
701 :
702 : // MediaByteBuffer is a ref counted infallible TArray.
703 : class MediaByteBuffer : public nsTArray<uint8_t>
704 : {
705 4 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer);
706 4 : MediaByteBuffer() = default;
707 0 : explicit MediaByteBuffer(size_t aCapacity) : nsTArray<uint8_t>(aCapacity) { }
708 :
709 : private:
710 0 : ~MediaByteBuffer() { }
711 : };
712 :
713 : } // namespace mozilla
714 :
715 : #endif // MediaData_h
|