diff options
Diffstat (limited to '')
-rw-r--r-- | dom/media/gmp/GMPVideoEncodedFrameImpl.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/dom/media/gmp/GMPVideoEncodedFrameImpl.cpp b/dom/media/gmp/GMPVideoEncodedFrameImpl.cpp new file mode 100644 index 0000000000..c0ed87df4d --- /dev/null +++ b/dom/media/gmp/GMPVideoEncodedFrameImpl.cpp @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GMPVideoEncodedFrameImpl.h" +#include "GMPVideoHost.h" +#include "mozilla/gmp/GMPTypes.h" +#include "GMPSharedMemManager.h" + +namespace mozilla::gmp { + +GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(GMPVideoHostImpl* aHost) + : mEncodedWidth(0), + mEncodedHeight(0), + mTimeStamp(0ll), + mDuration(0ll), + mFrameType(kGMPDeltaFrame), + mSize(0), + mCompleteFrame(false), + mHost(aHost), + mBufferType(GMP_BufferSingle) { + MOZ_ASSERT(aHost); + aHost->EncodedFrameCreated(this); +} + +GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl( + const GMPVideoEncodedFrameData& aFrameData, GMPVideoHostImpl* aHost) + : mEncodedWidth(aFrameData.mEncodedWidth()), + mEncodedHeight(aFrameData.mEncodedHeight()), + mTimeStamp(aFrameData.mTimestamp()), + mDuration(aFrameData.mDuration()), + mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())), + mSize(aFrameData.mSize()), + mCompleteFrame(aFrameData.mCompleteFrame()), + mHost(aHost), + mBuffer(aFrameData.mBuffer()), + mBufferType(aFrameData.mBufferType()) { + MOZ_ASSERT(aHost); + aHost->EncodedFrameCreated(this); +} + +GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl() { + DestroyBuffer(); + if (mHost) { + mHost->EncodedFrameDestroyed(this); + } +} + +GMPVideoFrameFormat GMPVideoEncodedFrameImpl::GetFrameFormat() { + return kGMPEncodedVideoFrame; +} + +void GMPVideoEncodedFrameImpl::DoneWithAPI() { + DestroyBuffer(); + + // Do this after destroying the buffer because destruction + // involves deallocation, which requires a host. + mHost = nullptr; +} + +void GMPVideoEncodedFrameImpl::ActorDestroyed() { + // Simply clear out Shmem reference, do not attempt to + // properly free it. It has already been freed. + mBuffer = ipc::Shmem(); + // No more host. + mHost = nullptr; +} + +bool GMPVideoEncodedFrameImpl::RelinquishFrameData( + GMPVideoEncodedFrameData& aFrameData) { + aFrameData.mEncodedWidth() = mEncodedWidth; + aFrameData.mEncodedHeight() = mEncodedHeight; + aFrameData.mTimestamp() = mTimeStamp; + aFrameData.mDuration() = mDuration; + aFrameData.mFrameType() = mFrameType; + aFrameData.mSize() = mSize; + aFrameData.mCompleteFrame() = mCompleteFrame; + aFrameData.mBuffer() = mBuffer; + aFrameData.mBufferType() = mBufferType; + + // This method is called right before Shmem is sent to another process. + // We need to effectively zero out our member copy so that we don't + // try to delete Shmem we don't own later. + mBuffer = ipc::Shmem(); + + return true; +} + +void GMPVideoEncodedFrameImpl::DestroyBuffer() { + if (mHost && mBuffer.IsWritable()) { + mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData, + mBuffer); + } + mBuffer = ipc::Shmem(); +} + +GMPErr GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize) { + if (aSize == 0) { + DestroyBuffer(); + } else if (aSize > AllocatedSize()) { + DestroyBuffer(); + if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, + aSize, &mBuffer) || + !Buffer()) { + return GMPAllocErr; + } + } + mSize = aSize; + + return GMPNoErr; +} + +GMPErr GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame) { + auto& f = static_cast<const GMPVideoEncodedFrameImpl&>(aFrame); + + if (f.mSize != 0) { + GMPErr err = CreateEmptyFrame(f.mSize); + if (err != GMPNoErr) { + return err; + } + memcpy(Buffer(), f.Buffer(), f.mSize); + } + mEncodedWidth = f.mEncodedWidth; + mEncodedHeight = f.mEncodedHeight; + mTimeStamp = f.mTimeStamp; + mDuration = f.mDuration; + mFrameType = f.mFrameType; + mSize = f.mSize; // already set... + mCompleteFrame = f.mCompleteFrame; + mBufferType = f.mBufferType; + // Don't copy host, that should have been set properly on object creation via + // host. + + return GMPNoErr; +} + +void GMPVideoEncodedFrameImpl::SetEncodedWidth(uint32_t aEncodedWidth) { + mEncodedWidth = aEncodedWidth; +} + +uint32_t GMPVideoEncodedFrameImpl::EncodedWidth() { return mEncodedWidth; } + +void GMPVideoEncodedFrameImpl::SetEncodedHeight(uint32_t aEncodedHeight) { + mEncodedHeight = aEncodedHeight; +} + +uint32_t GMPVideoEncodedFrameImpl::EncodedHeight() { return mEncodedHeight; } + +void GMPVideoEncodedFrameImpl::SetTimeStamp(uint64_t aTimeStamp) { + mTimeStamp = aTimeStamp; +} + +uint64_t GMPVideoEncodedFrameImpl::TimeStamp() { return mTimeStamp; } + +void GMPVideoEncodedFrameImpl::SetDuration(uint64_t aDuration) { + mDuration = aDuration; +} + +uint64_t GMPVideoEncodedFrameImpl::Duration() const { return mDuration; } + +void GMPVideoEncodedFrameImpl::SetFrameType(GMPVideoFrameType aFrameType) { + mFrameType = aFrameType; +} + +GMPVideoFrameType GMPVideoEncodedFrameImpl::FrameType() { return mFrameType; } + +void GMPVideoEncodedFrameImpl::SetAllocatedSize(uint32_t aNewSize) { + if (aNewSize <= AllocatedSize()) { + return; + } + + if (!mHost) { + return; + } + + ipc::Shmem new_mem; + if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, + aNewSize, &new_mem) || + !new_mem.get<uint8_t>()) { + return; + } + + if (mBuffer.IsReadable()) { + memcpy(new_mem.get<uint8_t>(), Buffer(), mSize); + } + + DestroyBuffer(); + + mBuffer = new_mem; +} + +uint32_t GMPVideoEncodedFrameImpl::AllocatedSize() { + if (mBuffer.IsWritable()) { + return mBuffer.Size<uint8_t>(); + } + return 0; +} + +void GMPVideoEncodedFrameImpl::SetSize(uint32_t aSize) { mSize = aSize; } + +uint32_t GMPVideoEncodedFrameImpl::Size() { return mSize; } + +void GMPVideoEncodedFrameImpl::SetCompleteFrame(bool aCompleteFrame) { + mCompleteFrame = aCompleteFrame; +} + +bool GMPVideoEncodedFrameImpl::CompleteFrame() { return mCompleteFrame; } + +const uint8_t* GMPVideoEncodedFrameImpl::Buffer() const { + return mBuffer.get<uint8_t>(); +} + +uint8_t* GMPVideoEncodedFrameImpl::Buffer() { return mBuffer.get<uint8_t>(); } + +void GMPVideoEncodedFrameImpl::Destroy() { delete this; } + +GMPBufferType GMPVideoEncodedFrameImpl::BufferType() const { + return mBufferType; +} + +void GMPVideoEncodedFrameImpl::SetBufferType(GMPBufferType aBufferType) { + mBufferType = aBufferType; +} + +} // namespace mozilla::gmp |