Coverage Report

Created: 2018-09-25 14:53

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