tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GMPVideoEncodedFrameImpl.cpp (8696B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "GMPVideoEncodedFrameImpl.h"
      7 
      8 #include "GMPSharedMemManager.h"
      9 #include "GMPVideoHost.h"
     10 #include "mozilla/gmp/GMPTypes.h"
     11 
     12 namespace mozilla::gmp {
     13 
     14 GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(GMPVideoHostImpl* aHost)
     15    : mEncodedWidth(0),
     16      mEncodedHeight(0),
     17      mTimeStamp(0ll),
     18      mDuration(0ll),
     19      mFrameType(kGMPDeltaFrame),
     20      mSize(0),
     21      mTemporalLayerId(-1),
     22      mCompleteFrame(false),
     23      mHost(aHost),
     24      mBufferType(GMP_BufferSingle) {
     25  MOZ_ASSERT(aHost);
     26  aHost->EncodedFrameCreated(this);
     27 }
     28 
     29 GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(
     30    const GMPVideoEncodedFrameData& aFrameData, ipc::Shmem&& aShmemBuffer,
     31    GMPVideoHostImpl* aHost)
     32    : mEncodedWidth(aFrameData.mEncodedWidth()),
     33      mEncodedHeight(aFrameData.mEncodedHeight()),
     34      mTimeStamp(aFrameData.mTimestamp()),
     35      mDuration(aFrameData.mDuration()),
     36      mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())),
     37      mSize(aFrameData.mSize()),
     38      mTemporalLayerId(aFrameData.mTemporalLayerId()),
     39      mCompleteFrame(aFrameData.mCompleteFrame()),
     40      mHost(aHost),
     41      mShmemBuffer(std::move(aShmemBuffer)),
     42      mBufferType(aFrameData.mBufferType()) {
     43  MOZ_ASSERT(aHost);
     44  aHost->EncodedFrameCreated(this);
     45 }
     46 
     47 GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(
     48    const GMPVideoEncodedFrameData& aFrameData,
     49    nsTArray<uint8_t>&& aArrayBuffer, GMPVideoHostImpl* aHost)
     50    : mEncodedWidth(aFrameData.mEncodedWidth()),
     51      mEncodedHeight(aFrameData.mEncodedHeight()),
     52      mTimeStamp(aFrameData.mTimestamp()),
     53      mDuration(aFrameData.mDuration()),
     54      mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())),
     55      mSize(aFrameData.mSize()),
     56      mTemporalLayerId(aFrameData.mTemporalLayerId()),
     57      mCompleteFrame(aFrameData.mCompleteFrame()),
     58      mHost(aHost),
     59      mArrayBuffer(std::move(aArrayBuffer)),
     60      mBufferType(aFrameData.mBufferType()) {
     61  MOZ_ASSERT(aHost);
     62  aHost->EncodedFrameCreated(this);
     63 }
     64 
     65 GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl() {
     66  DestroyBuffer();
     67  if (mHost) {
     68    mHost->EncodedFrameDestroyed(this);
     69  }
     70 }
     71 
     72 GMPVideoFrameFormat GMPVideoEncodedFrameImpl::GetFrameFormat() {
     73  return kGMPEncodedVideoFrame;
     74 }
     75 
     76 void GMPVideoEncodedFrameImpl::DoneWithAPI() {
     77  DestroyBuffer();
     78 
     79  // Do this after destroying the buffer because destruction
     80  // involves deallocation, which requires a host.
     81  mHost = nullptr;
     82 }
     83 
     84 /* static */
     85 bool GMPVideoEncodedFrameImpl::CheckFrameData(
     86    const GMPVideoEncodedFrameData& aFrameData, size_t aBufferSize) {
     87  return aFrameData.mSize() <= aBufferSize;
     88 }
     89 
     90 void GMPVideoEncodedFrameImpl::RelinquishFrameData(
     91    GMPVideoEncodedFrameData& aFrameData) {
     92  aFrameData.mEncodedWidth() = mEncodedWidth;
     93  aFrameData.mEncodedHeight() = mEncodedHeight;
     94  aFrameData.mTimestamp() = mTimeStamp;
     95  aFrameData.mDuration() = mDuration;
     96  aFrameData.mFrameType() = mFrameType;
     97  aFrameData.mSize() = mSize;
     98  aFrameData.mTemporalLayerId() = mTemporalLayerId;
     99  aFrameData.mCompleteFrame() = mCompleteFrame;
    100  aFrameData.mBufferType() = mBufferType;
    101 }
    102 
    103 bool GMPVideoEncodedFrameImpl::RelinquishFrameData(
    104    GMPVideoEncodedFrameData& aFrameData, ipc::Shmem& aShmemBuffer) {
    105  if (!mShmemBuffer.IsReadable()) {
    106    return false;
    107  }
    108 
    109  aShmemBuffer = mShmemBuffer;
    110 
    111  // This method is called right before Shmem is sent to another process.
    112  // We need to effectively zero out our member copy so that we don't
    113  // try to delete Shmem we don't own later.
    114  mShmemBuffer = ipc::Shmem();
    115 
    116  RelinquishFrameData(aFrameData);
    117  return true;
    118 }
    119 
    120 bool GMPVideoEncodedFrameImpl::RelinquishFrameData(
    121    GMPVideoEncodedFrameData& aFrameData, nsTArray<uint8_t>& aArrayBuffer) {
    122  if (mShmemBuffer.IsReadable()) {
    123    return false;
    124  }
    125 
    126  aArrayBuffer = std::move(mArrayBuffer);
    127  RelinquishFrameData(aFrameData);
    128  return true;
    129 }
    130 
    131 void GMPVideoEncodedFrameImpl::DestroyBuffer() {
    132  if (mHost && mShmemBuffer.IsWritable()) {
    133    mHost->SharedMemMgr()->MgrGiveShmem(GMPSharedMemClass::Encoded,
    134                                        std::move(mShmemBuffer));
    135  }
    136  mShmemBuffer = ipc::Shmem();
    137  mArrayBuffer.Clear();
    138 }
    139 
    140 GMPErr GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize) {
    141  if (aSize == 0) {
    142    DestroyBuffer();
    143  } else if (aSize > AllocatedSize()) {
    144    DestroyBuffer();
    145    if (!mHost->SharedMemMgr()->MgrTakeShmem(GMPSharedMemClass::Encoded, aSize,
    146                                             &mShmemBuffer) &&
    147        !mArrayBuffer.SetLength(aSize, fallible)) {
    148      return GMPAllocErr;
    149    }
    150  }
    151  mSize = aSize;
    152 
    153  return GMPNoErr;
    154 }
    155 
    156 GMPErr GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame) {
    157  auto& f = static_cast<const GMPVideoEncodedFrameImpl&>(aFrame);
    158 
    159  if (f.mSize != 0) {
    160    GMPErr err = CreateEmptyFrame(f.mSize);
    161    if (err != GMPNoErr) {
    162      return err;
    163    }
    164    memcpy(Buffer(), f.Buffer(), f.mSize);
    165  }
    166  mEncodedWidth = f.mEncodedWidth;
    167  mEncodedHeight = f.mEncodedHeight;
    168  mTimeStamp = f.mTimeStamp;
    169  mDuration = f.mDuration;
    170  mFrameType = f.mFrameType;
    171  mSize = f.mSize;  // already set...
    172  mCompleteFrame = f.mCompleteFrame;
    173  mBufferType = f.mBufferType;
    174  // Don't copy host, that should have been set properly on object creation via
    175  // host.
    176 
    177  return GMPNoErr;
    178 }
    179 
    180 void GMPVideoEncodedFrameImpl::SetEncodedWidth(uint32_t aEncodedWidth) {
    181  mEncodedWidth = aEncodedWidth;
    182 }
    183 
    184 uint32_t GMPVideoEncodedFrameImpl::EncodedWidth() { return mEncodedWidth; }
    185 
    186 void GMPVideoEncodedFrameImpl::SetEncodedHeight(uint32_t aEncodedHeight) {
    187  mEncodedHeight = aEncodedHeight;
    188 }
    189 
    190 uint32_t GMPVideoEncodedFrameImpl::EncodedHeight() { return mEncodedHeight; }
    191 
    192 void GMPVideoEncodedFrameImpl::SetTimeStamp(uint64_t aTimeStamp) {
    193  mTimeStamp = aTimeStamp;
    194 }
    195 
    196 uint64_t GMPVideoEncodedFrameImpl::TimeStamp() { return mTimeStamp; }
    197 
    198 void GMPVideoEncodedFrameImpl::SetDuration(uint64_t aDuration) {
    199  mDuration = aDuration;
    200 }
    201 
    202 uint64_t GMPVideoEncodedFrameImpl::Duration() const { return mDuration; }
    203 
    204 void GMPVideoEncodedFrameImpl::SetFrameType(GMPVideoFrameType aFrameType) {
    205  mFrameType = aFrameType;
    206 }
    207 
    208 GMPVideoFrameType GMPVideoEncodedFrameImpl::FrameType() { return mFrameType; }
    209 
    210 void GMPVideoEncodedFrameImpl::SetAllocatedSize(uint32_t aNewSize) {
    211  if (aNewSize <= AllocatedSize()) {
    212    return;
    213  }
    214 
    215  if (!mHost) {
    216    return;
    217  }
    218 
    219  if (!mArrayBuffer.IsEmpty()) {
    220    (void)mArrayBuffer.SetLength(aNewSize, fallible);
    221    return;
    222  }
    223 
    224  ipc::Shmem new_mem;
    225  if (!mHost->SharedMemMgr()->MgrTakeShmem(GMPSharedMemClass::Encoded, aNewSize,
    226                                           &new_mem) &&
    227      !mArrayBuffer.SetLength(aNewSize, fallible)) {
    228    return;
    229  }
    230 
    231  if (mShmemBuffer.IsReadable()) {
    232    if (new_mem.IsWritable()) {
    233      memcpy(new_mem.get<uint8_t>(), mShmemBuffer.get<uint8_t>(), mSize);
    234    }
    235    mHost->SharedMemMgr()->MgrGiveShmem(GMPSharedMemClass::Encoded,
    236                                        std::move(mShmemBuffer));
    237  }
    238 
    239  mShmemBuffer = new_mem;
    240 }
    241 
    242 uint32_t GMPVideoEncodedFrameImpl::AllocatedSize() {
    243  if (mShmemBuffer.IsWritable()) {
    244    return mShmemBuffer.Size<uint8_t>();
    245  }
    246  return mArrayBuffer.Length();
    247 }
    248 
    249 void GMPVideoEncodedFrameImpl::SetSize(uint32_t aSize) { mSize = aSize; }
    250 
    251 uint32_t GMPVideoEncodedFrameImpl::Size() { return mSize; }
    252 
    253 void GMPVideoEncodedFrameImpl::SetCompleteFrame(bool aCompleteFrame) {
    254  mCompleteFrame = aCompleteFrame;
    255 }
    256 
    257 bool GMPVideoEncodedFrameImpl::CompleteFrame() { return mCompleteFrame; }
    258 
    259 const uint8_t* GMPVideoEncodedFrameImpl::Buffer() const {
    260  if (mShmemBuffer.IsReadable()) {
    261    return mShmemBuffer.get<uint8_t>();
    262  }
    263  if (!mArrayBuffer.IsEmpty()) {
    264    return mArrayBuffer.Elements();
    265  }
    266  return nullptr;
    267 }
    268 
    269 uint8_t* GMPVideoEncodedFrameImpl::Buffer() {
    270  if (mShmemBuffer.IsWritable()) {
    271    return mShmemBuffer.get<uint8_t>();
    272  }
    273  if (!mArrayBuffer.IsEmpty()) {
    274    return mArrayBuffer.Elements();
    275  }
    276  return nullptr;
    277 }
    278 
    279 void GMPVideoEncodedFrameImpl::Destroy() { delete this; }
    280 
    281 GMPBufferType GMPVideoEncodedFrameImpl::BufferType() const {
    282  return mBufferType;
    283 }
    284 
    285 void GMPVideoEncodedFrameImpl::SetBufferType(GMPBufferType aBufferType) {
    286  mBufferType = aBufferType;
    287 }
    288 
    289 void GMPVideoEncodedFrameImpl::SetTemporalLayerId(int32_t aLayerId) {
    290  mTemporalLayerId = aLayerId;
    291 }
    292 
    293 int32_t GMPVideoEncodedFrameImpl::GetTemporalLayerId() {
    294  return mTemporalLayerId;
    295 }
    296 
    297 }  // namespace mozilla::gmp