/*
* Copyright 2016, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXBuffer"
#include <media/stagefright/foundation/ADebug.h>
#include <media/MediaCodecBuffer.h>
#include <media/OMXBuffer.h>
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <ui/GraphicBuffer.h>
#include <utils/NativeHandle.h>
namespace android {
//static
OMXBuffer OMXBuffer::sPreset(static_cast<sp<MediaCodecBuffer> >(NULL));
OMXBuffer::OMXBuffer()
: mBufferType(kBufferTypeInvalid) {
}
OMXBuffer::OMXBuffer(const sp<MediaCodecBuffer>& codecBuffer)
: mBufferType(kBufferTypePreset),
mRangeOffset(codecBuffer != NULL ? codecBuffer->offset() : 0),
mRangeLength(codecBuffer != NULL ? codecBuffer->size() : 0) {
}
OMXBuffer::OMXBuffer(OMX_U32 rangeOffset, OMX_U32 rangeLength)
: mBufferType(kBufferTypePreset),
mRangeOffset(rangeOffset),
mRangeLength(rangeLength) {
}
OMXBuffer::OMXBuffer(const sp<IMemory> &mem)
: mBufferType(kBufferTypeSharedMem),
mMem(mem) {
}
OMXBuffer::OMXBuffer(const sp<GraphicBuffer> &gbuf)
: mBufferType(kBufferTypeANWBuffer),
mGraphicBuffer(gbuf) {
}
OMXBuffer::OMXBuffer(const sp<NativeHandle> &handle)
: mBufferType(kBufferTypeNativeHandle),
mNativeHandle(handle) {
}
OMXBuffer::OMXBuffer(const hidl_memory &hidlMemory)
: mBufferType(kBufferTypeHidlMemory),
mHidlMemory(hidlMemory) {
}
OMXBuffer::~OMXBuffer() {
}
status_t OMXBuffer::writeToParcel(Parcel *parcel) const {
CHECK(mBufferType != kBufferTypeHidlMemory);
parcel->writeInt32(mBufferType);
switch(mBufferType) {
case kBufferTypePreset:
{
status_t err = parcel->writeUint32(mRangeOffset);
if (err != OK) {
return err;
}
return parcel->writeUint32(mRangeLength);
}
case kBufferTypeSharedMem:
{
return parcel->writeStrongBinder(IInterface::asBinder(mMem));
}
case kBufferTypeANWBuffer:
{
if (mGraphicBuffer == NULL) {
return parcel->writeBool(false);
}
status_t err = parcel->writeBool(true);
if (err != OK) {
return err;
}
return parcel->write(*mGraphicBuffer);
}
case kBufferTypeNativeHandle:
{
return parcel->writeNativeHandle(mNativeHandle->handle());
}
default:
return BAD_VALUE;
}
return BAD_VALUE;
}
status_t OMXBuffer::readFromParcel(const Parcel *parcel) {
BufferType bufferType = (BufferType) parcel->readInt32();
CHECK(bufferType != kBufferTypeHidlMemory);
switch(bufferType) {
case kBufferTypePreset:
{
status_t err = parcel->readUint32(&mRangeOffset);
if (err != OK) {
return err;
}
err = parcel->readUint32(&mRangeLength);
if (err != OK) {
return err;
}
break;
}
case kBufferTypeSharedMem:
{
mMem = interface_cast<IMemory>(parcel->readStrongBinder());
break;
}
case kBufferTypeANWBuffer:
{
bool notNull;
status_t err = parcel->readBool(¬Null);
if (err != OK) {
return err;
}
if (notNull) {
sp<GraphicBuffer> buffer = new GraphicBuffer();
status_t err = parcel->read(*buffer);
if (err != OK) {
return err;
}
mGraphicBuffer = buffer;
} else {
mGraphicBuffer = nullptr;
}
break;
}
case kBufferTypeNativeHandle:
{
sp<NativeHandle> handle = NativeHandle::create(
parcel->readNativeHandle(), true /* ownsHandle */);
mNativeHandle = handle;
break;
}
default:
return BAD_VALUE;
}
mBufferType = bufferType;
return OK;
}
OMXBuffer& OMXBuffer::operator=(OMXBuffer&& source) noexcept {
mBufferType = std::move(source.mBufferType);
mRangeOffset = std::move(source.mRangeOffset);
mRangeLength = std::move(source.mRangeLength);
mMem = std::move(source.mMem);
mGraphicBuffer = std::move(source.mGraphicBuffer);
mNativeHandle = std::move(source.mNativeHandle);
mHidlMemory = std::move(source.mHidlMemory);
return *this;
}
} // namespace android