зеркало из https://github.com/mozilla/gecko-dev.git
325 строки
6.9 KiB
C++
325 строки
6.9 KiB
C++
/* -*- 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"
|
|
#include "GMPEncryptedBufferDataImpl.h"
|
|
|
|
namespace mozilla {
|
|
namespace 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);
|
|
if (aFrameData.mDecryptionData().mKeyId().Length() > 0) {
|
|
mCrypto = new GMPEncryptedBufferDataImpl(aFrameData.mDecryptionData());
|
|
}
|
|
aHost->EncodedFrameCreated(this);
|
|
}
|
|
|
|
GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl()
|
|
{
|
|
DestroyBuffer();
|
|
if (mHost) {
|
|
mHost->EncodedFrameDestroyed(this);
|
|
}
|
|
}
|
|
|
|
void
|
|
GMPVideoEncodedFrameImpl::InitCrypto(const mp4_demuxer::CryptoSample& aCrypto)
|
|
{
|
|
mCrypto = new GMPEncryptedBufferDataImpl(aCrypto);
|
|
}
|
|
|
|
const GMPEncryptedBufferMetadata*
|
|
GMPVideoEncodedFrameImpl::GetDecryptionData() const
|
|
{
|
|
return mCrypto;
|
|
}
|
|
|
|
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;
|
|
if (mCrypto) {
|
|
mCrypto->RelinquishData(aFrameData.mDecryptionData());
|
|
}
|
|
|
|
// 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,
|
|
ipc::SharedMemory::TYPE_BASIC, &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;
|
|
mCrypto = new GMPEncryptedBufferDataImpl(*(f.mCrypto));
|
|
// 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,
|
|
ipc::SharedMemory::TYPE_BASIC, &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 gmp
|
|
} // namespace mozilla
|