838 lines
21 KiB
C++
838 lines
21 KiB
C++
/*
|
|
* Copyright (c) 2009-2011 Intel Corporation. All rights reserved.
|
|
*
|
|
* 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 "IntelMetadataBuffer"
|
|
#include <wrs_omxil_core/log.h>
|
|
|
|
#include "IntelMetadataBuffer.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
#include <binder/IServiceManager.h>
|
|
#include <binder/MemoryBase.h>
|
|
#include <binder/Parcel.h>
|
|
#include <utils/List.h>
|
|
#include <utils/threads.h>
|
|
#include <ui/GraphicBuffer.h>
|
|
|
|
//#define TEST
|
|
|
|
struct ShareMemMap {
|
|
uint32_t sessionflag;
|
|
intptr_t value;
|
|
intptr_t value_backup;
|
|
uint32_t type;
|
|
sp<MemoryBase> membase;
|
|
sp<GraphicBuffer> gbuffer;
|
|
};
|
|
|
|
List <ShareMemMap *> gShareMemMapList;
|
|
Mutex gShareMemMapListLock;
|
|
|
|
enum {
|
|
SHARE_MEM = IBinder::FIRST_CALL_TRANSACTION,
|
|
GET_MEM,
|
|
CLEAR_MEM,
|
|
};
|
|
|
|
enum {
|
|
ST_MEMBASE = 0,
|
|
ST_GFX,
|
|
ST_MAX,
|
|
};
|
|
|
|
#define REMOTE_PROVIDER 0x80000000
|
|
#define REMOTE_CONSUMER 0x40000000
|
|
|
|
static ShareMemMap* ReadMemObjFromBinder(const Parcel& data, uint32_t sessionflag, intptr_t value) {
|
|
|
|
uint32_t type = data.readInt32();
|
|
if (type >= ST_MAX)
|
|
return NULL;
|
|
|
|
ShareMemMap* map = new ShareMemMap;
|
|
map->sessionflag = sessionflag;
|
|
map->type = type;
|
|
map->value_backup = value;
|
|
map->membase = NULL;
|
|
map->gbuffer= NULL;
|
|
|
|
// LOGI("ReadMemObjFromBinder");
|
|
|
|
if (type == ST_MEMBASE) /*offset, size, heap*/
|
|
{
|
|
ssize_t offset = data.readInt32();
|
|
size_t size = data.readInt32();
|
|
|
|
sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
|
|
|
|
sp<MemoryBase> mem = new MemoryBase(heap, offset, size);
|
|
if (mem == NULL)
|
|
{
|
|
delete map;
|
|
return NULL;
|
|
}
|
|
|
|
map->value = (intptr_t)( ((char *) mem->pointer()) + 0x0FFF) & ~0x0FFF;
|
|
map->membase = mem;
|
|
|
|
#ifdef TEST
|
|
ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \
|
|
heap->getHeapID(), mem->pointer(), *((intptr_t *)(mem->pointer())), map->value);
|
|
#endif
|
|
|
|
}
|
|
else if (type == ST_GFX) /*graphicbuffer*/
|
|
{
|
|
sp<GraphicBuffer> buffer = new GraphicBuffer();
|
|
if (buffer == NULL)
|
|
{
|
|
delete map;
|
|
return NULL;
|
|
}
|
|
data.read(*buffer);
|
|
|
|
map->value = (intptr_t)buffer->handle;
|
|
map->gbuffer = buffer;
|
|
|
|
#ifdef TEST
|
|
void* usrptr[3];
|
|
buffer->lock(GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, &usrptr[0]);
|
|
buffer->unlock();
|
|
ALOGI("gfx handle:%p data:%x", (intptr_t)buffer->handle, *((intptr_t *)usrptr[0]));
|
|
#endif
|
|
}
|
|
|
|
gShareMemMapListLock.lock();
|
|
gShareMemMapList.push_back(map);
|
|
gShareMemMapListLock.unlock();
|
|
return map;
|
|
}
|
|
|
|
static status_t WriteMemObjToBinder(Parcel& data, ShareMemMap* smem) {
|
|
|
|
if (smem->type >= ST_MAX)
|
|
return BAD_VALUE;
|
|
|
|
// LOGI("WriteMemObjToBinder");
|
|
|
|
data.writeInt32(smem->type);
|
|
|
|
if (smem->type == ST_MEMBASE) /*offset, size, heap*/
|
|
{
|
|
ssize_t offset;
|
|
size_t size;
|
|
sp<IMemoryHeap> heap = smem->membase->getMemory(&offset, &size);
|
|
data.writeInt32(offset);
|
|
data.writeInt32(size);
|
|
data.writeStrongBinder(IInterface::asBinder(heap));
|
|
#ifdef TEST
|
|
ALOGI("membase heapID:%d pointer:%x data:%x", \
|
|
heap->getHeapID(), smem->membase->pointer(), *((int *)(smem->membase->pointer())));
|
|
#endif
|
|
}
|
|
else if (smem->type == ST_GFX) /*graphicbuffer*/
|
|
data.write(*(smem->gbuffer));
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
static void ClearLocalMem(uint32_t sessionflag)
|
|
{
|
|
List<ShareMemMap *>::iterator node;
|
|
|
|
gShareMemMapListLock.lock();
|
|
|
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); )
|
|
{
|
|
if ((*node)->sessionflag == sessionflag) //remove all buffers belong to this session
|
|
{
|
|
(*node)->membase = NULL;
|
|
(*node)->gbuffer = NULL;
|
|
delete (*node);
|
|
node = gShareMemMapList.erase(node);
|
|
}
|
|
else
|
|
node ++;
|
|
}
|
|
|
|
gShareMemMapListLock.unlock();
|
|
}
|
|
|
|
static ShareMemMap* FindShareMem(uint32_t sessionflag, intptr_t value, bool isBackup)
|
|
{
|
|
List<ShareMemMap *>::iterator node;
|
|
|
|
gShareMemMapListLock.lock();
|
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++)
|
|
{
|
|
if (isBackup)
|
|
{
|
|
if ((*node)->sessionflag == sessionflag && (*node)->value_backup == value)
|
|
{
|
|
gShareMemMapListLock.unlock();
|
|
return (*node);
|
|
}
|
|
}
|
|
else if ((*node)->sessionflag == sessionflag && (*node)->value == value)
|
|
{
|
|
gShareMemMapListLock.unlock();
|
|
return (*node);
|
|
}
|
|
}
|
|
gShareMemMapListLock.unlock();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static ShareMemMap* PopShareMem(uint32_t sessionflag, intptr_t value)
|
|
{
|
|
List<ShareMemMap *>::iterator node;
|
|
|
|
gShareMemMapListLock.lock();
|
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++)
|
|
{
|
|
if ((*node)->sessionflag == sessionflag && (*node)->value == value)
|
|
{
|
|
gShareMemMapList.erase(node);
|
|
gShareMemMapListLock.unlock();
|
|
return (*node);
|
|
}
|
|
}
|
|
gShareMemMapListLock.unlock();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void PushShareMem(ShareMemMap* &smem)
|
|
{
|
|
gShareMemMapListLock.lock();
|
|
gShareMemMapList.push_back(smem);
|
|
gShareMemMapListLock.unlock();
|
|
}
|
|
|
|
static sp<IBinder> GetIntelBufferSharingService() {
|
|
|
|
sp<IServiceManager> sm = defaultServiceManager();
|
|
sp<IBinder> binder = sm->checkService(String16("media.IntelBufferSharing"));
|
|
|
|
if (binder == 0)
|
|
ALOGE("media.IntelBufferSharing service is not published");
|
|
|
|
return binder;
|
|
}
|
|
|
|
IntelBufferSharingService* IntelBufferSharingService::gBufferService = NULL;
|
|
|
|
status_t IntelBufferSharingService::instantiate(){
|
|
status_t ret = NO_ERROR;
|
|
|
|
if (gBufferService == NULL) {
|
|
gBufferService = new IntelBufferSharingService();
|
|
ret = defaultServiceManager()->addService(String16("media.IntelBufferSharing"), gBufferService);
|
|
LOGI("IntelBufferSharingService::instantiate() ret = %d\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void writeIntPtr(Parcel &data, intptr_t ptr)
|
|
{
|
|
data.writeInt32((int32_t) ptr);
|
|
}
|
|
|
|
status_t IntelBufferSharingService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
|
|
|
|
//TODO: if pid is int32?
|
|
pid_t pid = data.readInt32();
|
|
uint32_t sessionflag = data.readInt32();
|
|
|
|
switch(code)
|
|
{
|
|
case SHARE_MEM:
|
|
{
|
|
|
|
if (pid == getpid()) //in same process, should not use binder
|
|
{
|
|
ALOGE("onTransact in same process, wrong sessionflag?");
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
|
|
intptr_t value = data.readIntPtr();
|
|
|
|
// LOGI("onTransact SHARE_MEM value=%x", value);
|
|
|
|
//different process
|
|
ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value);
|
|
if (map == NULL)
|
|
return UNKNOWN_ERROR;
|
|
|
|
writeIntPtr(*reply, map->value);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
case CLEAR_MEM:
|
|
{
|
|
// LOGI("onTransact CLEAR_MEM sessionflag=%x", sessionflag);
|
|
|
|
if (pid == getpid()) //in same process, should not use binder
|
|
{
|
|
//same process, return same pointer in data
|
|
ALOGE("onTransact CLEAR_MEM in same process, wrong sessionflag?");
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
|
|
ClearLocalMem(sessionflag);
|
|
return NO_ERROR;
|
|
}
|
|
case GET_MEM:
|
|
{
|
|
|
|
if (pid == getpid()) //in same process, should not use binder
|
|
{
|
|
ALOGE("onTransact GET_MEM in same process, wrong sessionflag?");
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
|
|
intptr_t value = data.readIntPtr();
|
|
|
|
// LOGI("onTransact GET_MEM value=%x", value);
|
|
|
|
ShareMemMap* smem = FindShareMem(sessionflag, value, false);
|
|
if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem)))
|
|
return NO_ERROR;
|
|
else
|
|
ALOGE("onTransact GET_MEM: Not find mem");
|
|
|
|
return UNKNOWN_ERROR;
|
|
}
|
|
default:
|
|
return BBinder::onTransact(code, data, reply, flags);
|
|
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
#endif
|
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer()
|
|
{
|
|
mType = IntelMetadataBufferTypeCameraSource;
|
|
mValue = 0;
|
|
mInfo = NULL;
|
|
mExtraValues = NULL;
|
|
mExtraValues_Count = 0;
|
|
mBytes = NULL;
|
|
mSize = 0;
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
mSessionFlag = 0;
|
|
#endif
|
|
}
|
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer(IntelMetadataBufferType type, intptr_t value)
|
|
{
|
|
mType = type;
|
|
mValue = value;
|
|
mInfo = NULL;
|
|
mExtraValues = NULL;
|
|
mExtraValues_Count = 0;
|
|
mBytes = NULL;
|
|
mSize = 0;
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
mSessionFlag = 0;
|
|
#endif
|
|
}
|
|
|
|
IntelMetadataBuffer::~IntelMetadataBuffer()
|
|
{
|
|
if (mInfo)
|
|
delete mInfo;
|
|
|
|
if (mExtraValues)
|
|
delete[] mExtraValues;
|
|
|
|
if (mBytes)
|
|
delete[] mBytes;
|
|
}
|
|
|
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer(const IntelMetadataBuffer& imb)
|
|
:mType(imb.mType), mValue(imb.mValue), mInfo(NULL), mExtraValues(NULL),
|
|
mExtraValues_Count(imb.mExtraValues_Count), mBytes(NULL), mSize(imb.mSize)
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
,mSessionFlag(imb.mSessionFlag)
|
|
#endif
|
|
{
|
|
if (imb.mInfo)
|
|
mInfo = new ValueInfo(*imb.mInfo);
|
|
|
|
if (imb.mExtraValues)
|
|
{
|
|
mExtraValues = new intptr_t[mExtraValues_Count];
|
|
memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
|
|
}
|
|
|
|
if (imb.mBytes)
|
|
{
|
|
mBytes = new uint8_t[mSize];
|
|
memcpy(mBytes, imb.mBytes, mSize);
|
|
}
|
|
}
|
|
|
|
const IntelMetadataBuffer& IntelMetadataBuffer::operator=(const IntelMetadataBuffer& imb)
|
|
{
|
|
mType = imb.mType;
|
|
mValue = imb.mValue;
|
|
mInfo = NULL;
|
|
mExtraValues = NULL;
|
|
mExtraValues_Count = imb.mExtraValues_Count;
|
|
mBytes = NULL;
|
|
mSize = imb.mSize;
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
mSessionFlag = imb.mSessionFlag;
|
|
#endif
|
|
|
|
if (imb.mInfo)
|
|
mInfo = new ValueInfo(*imb.mInfo);
|
|
|
|
if (imb.mExtraValues)
|
|
{
|
|
mExtraValues = new intptr_t[mExtraValues_Count];
|
|
memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
|
|
}
|
|
|
|
if (imb.mBytes)
|
|
{
|
|
mBytes = new uint8_t[mSize];
|
|
memcpy(mBytes, imb.mBytes, mSize);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::GetType(IntelMetadataBufferType& type)
|
|
{
|
|
type = mType;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::SetType(IntelMetadataBufferType type)
|
|
{
|
|
if (type < IntelMetadataBufferTypeLast)
|
|
mType = type;
|
|
else
|
|
return IMB_INVAL_PARAM;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::GetValue(intptr_t& value)
|
|
{
|
|
value = mValue;
|
|
|
|
#ifndef INTEL_VIDEO_XPROC_SHARING
|
|
return IMB_SUCCESS;
|
|
#else
|
|
if ((mSessionFlag & REMOTE_CONSUMER) == 0) //no sharing or is local consumer
|
|
return IMB_SUCCESS;
|
|
|
|
//try to find if it is already cached.
|
|
ShareMemMap* smem = FindShareMem(mSessionFlag, mValue, true);
|
|
if(smem)
|
|
{
|
|
value = smem->value;
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
//is remote provider and not find from cache, then pull from service
|
|
sp<IBinder> binder = GetIntelBufferSharingService();
|
|
if (binder == 0)
|
|
return IMB_NO_SERVICE;
|
|
|
|
//Detect IntelBufferSharingService, share mem to service
|
|
Parcel data, reply;
|
|
|
|
//send pid, sessionflag, and memtype
|
|
pid_t pid = getpid();
|
|
//TODO: if pid is int32?
|
|
data.writeInt32(pid);
|
|
data.writeInt32(mSessionFlag);
|
|
writeIntPtr(data, mValue);
|
|
|
|
//do transcation
|
|
if (binder->transact(GET_MEM, data, &reply) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
//get type/Mem OBJ
|
|
smem = ReadMemObjFromBinder(reply, mSessionFlag, mValue);
|
|
if (smem)
|
|
value = smem->value;
|
|
else
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
return IMB_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::SetValue(intptr_t value)
|
|
{
|
|
mValue = value;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info)
|
|
{
|
|
info = mInfo;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::SetValueInfo(ValueInfo* info)
|
|
{
|
|
if (info)
|
|
{
|
|
if (mInfo == NULL)
|
|
mInfo = new ValueInfo;
|
|
|
|
memcpy(mInfo, info, sizeof(ValueInfo));
|
|
}
|
|
else
|
|
return IMB_INVAL_PARAM;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::GetExtraValues(intptr_t* &values, uint32_t& num)
|
|
{
|
|
values = mExtraValues;
|
|
num = mExtraValues_Count;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::SetExtraValues(intptr_t* values, uint32_t num)
|
|
{
|
|
if (values && num > 0)
|
|
{
|
|
if (mExtraValues && mExtraValues_Count != num)
|
|
{
|
|
delete[] mExtraValues;
|
|
mExtraValues = NULL;
|
|
}
|
|
|
|
if (mExtraValues == NULL)
|
|
mExtraValues = new intptr_t[num];
|
|
|
|
memcpy(mExtraValues, values, sizeof(intptr_t) * num);
|
|
mExtraValues_Count = num;
|
|
}
|
|
else
|
|
return IMB_INVAL_PARAM;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::UnSerialize(uint8_t* data, uint32_t size)
|
|
{
|
|
if (!data || size == 0)
|
|
return IMB_INVAL_PARAM;
|
|
|
|
IntelMetadataBufferType type;
|
|
intptr_t value;
|
|
uint32_t extrasize = size - sizeof(type) - sizeof(value);
|
|
ValueInfo* info = NULL;
|
|
intptr_t* ExtraValues = NULL;
|
|
uint32_t ExtraValues_Count = 0;
|
|
|
|
memcpy(&type, data, sizeof(type));
|
|
data += sizeof(type);
|
|
memcpy(&value, data, sizeof(value));
|
|
data += sizeof(value);
|
|
|
|
switch (type)
|
|
{
|
|
case IntelMetadataBufferTypeCameraSource:
|
|
case IntelMetadataBufferTypeEncoder:
|
|
case IntelMetadataBufferTypeUser:
|
|
{
|
|
if (extrasize >0 && extrasize < sizeof(ValueInfo))
|
|
return IMB_INVAL_BUFFER;
|
|
|
|
if (extrasize > sizeof(ValueInfo)) //has extravalues
|
|
{
|
|
if ( (extrasize - sizeof(ValueInfo)) % sizeof(mValue) != 0 )
|
|
return IMB_INVAL_BUFFER;
|
|
ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / sizeof(mValue);
|
|
}
|
|
|
|
if (extrasize > 0)
|
|
{
|
|
info = new ValueInfo;
|
|
memcpy(info, data, sizeof(ValueInfo));
|
|
data += sizeof(ValueInfo);
|
|
}
|
|
|
|
if (ExtraValues_Count > 0)
|
|
{
|
|
ExtraValues = new intptr_t[ExtraValues_Count];
|
|
memcpy(ExtraValues, data, ExtraValues_Count * sizeof(mValue));
|
|
}
|
|
|
|
break;
|
|
}
|
|
case IntelMetadataBufferTypeGrallocSource:
|
|
if (extrasize > 0)
|
|
return IMB_INVAL_BUFFER;
|
|
|
|
break;
|
|
default:
|
|
return IMB_INVAL_BUFFER;
|
|
}
|
|
|
|
//store data
|
|
mType = type;
|
|
mValue = value;
|
|
if (mInfo)
|
|
delete mInfo;
|
|
mInfo = info;
|
|
if (mExtraValues)
|
|
delete[] mExtraValues;
|
|
mExtraValues = ExtraValues;
|
|
mExtraValues_Count = ExtraValues_Count;
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
if (mInfo != NULL)
|
|
mSessionFlag = mInfo->sessionFlag;
|
|
#endif
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::Serialize(uint8_t* &data, uint32_t& size)
|
|
{
|
|
if (mBytes == NULL)
|
|
{
|
|
if (mType == IntelMetadataBufferTypeGrallocSource && mInfo)
|
|
return IMB_INVAL_PARAM;
|
|
|
|
//assemble bytes according members
|
|
mSize = sizeof(mType) + sizeof(mValue);
|
|
if (mInfo)
|
|
{
|
|
mSize += sizeof(ValueInfo);
|
|
if (mExtraValues)
|
|
mSize += sizeof(mValue) * mExtraValues_Count;
|
|
}
|
|
|
|
mBytes = new uint8_t[mSize];
|
|
uint8_t *ptr = mBytes;
|
|
memcpy(ptr, &mType, sizeof(mType));
|
|
ptr += sizeof(mType);
|
|
memcpy(ptr, &mValue, sizeof(mValue));
|
|
ptr += sizeof(mValue);
|
|
|
|
if (mInfo)
|
|
{
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
mInfo->sessionFlag = mSessionFlag;
|
|
#endif
|
|
memcpy(ptr, mInfo, sizeof(ValueInfo));
|
|
ptr += sizeof(ValueInfo);
|
|
|
|
if (mExtraValues)
|
|
memcpy(ptr, mExtraValues, mExtraValues_Count * sizeof(mValue));
|
|
}
|
|
}
|
|
|
|
data = mBytes;
|
|
size = mSize;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
uint32_t IntelMetadataBuffer::GetMaxBufferSize()
|
|
{
|
|
return 256;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
|
|
{
|
|
sessionflag = mSessionFlag;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
|
|
{
|
|
mSessionFlag = sessionflag;
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING
|
|
|
|
IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem)
|
|
{
|
|
mValue = (intptr_t)((intptr_t) ( ((char *) mem->pointer()) + 0x0FFF) & ~0x0FFF);
|
|
|
|
if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing
|
|
return IMB_SUCCESS;
|
|
|
|
if (mSessionFlag & REMOTE_PROVIDER) //is remote provider
|
|
{
|
|
sp<IBinder> binder = GetIntelBufferSharingService();
|
|
if (binder == 0)
|
|
return IMB_NO_SERVICE;
|
|
|
|
//Detect IntelBufferSharingService, share mem to service
|
|
Parcel data, reply;
|
|
|
|
//send pid, sessionflag, and value
|
|
pid_t pid = getpid();
|
|
//TODO: if pid is int32?
|
|
data.writeInt32(pid);
|
|
data.writeInt32(mSessionFlag);
|
|
writeIntPtr(data, mValue);
|
|
|
|
//send type/obj (offset/size/MemHeap)
|
|
ShareMemMap smem;
|
|
smem.membase = mem;
|
|
smem.type = ST_MEMBASE;
|
|
if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
//do transcation
|
|
if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
//set new value gotten from peer
|
|
mValue = reply.readIntPtr();
|
|
// LOGI("ShareValue(membase) Get reply from sevice, new value:%x\n", mValue);
|
|
}
|
|
else //is local provider , direct access list
|
|
{
|
|
ShareMemMap* smem = new ShareMemMap;
|
|
smem->sessionflag = mSessionFlag;
|
|
smem->value = mValue;
|
|
smem->value_backup = mValue;
|
|
smem->type = ST_MEMBASE;
|
|
smem->membase = mem;
|
|
smem->gbuffer = NULL;
|
|
PushShareMem(smem);
|
|
}
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::ShareValue(sp<GraphicBuffer> gbuffer)
|
|
{
|
|
mValue = (intptr_t)gbuffer->handle;
|
|
|
|
if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing
|
|
return IMB_SUCCESS;
|
|
|
|
if ((mSessionFlag & REMOTE_PROVIDER) == 0) //is remote provider
|
|
{
|
|
sp<IBinder> binder = GetIntelBufferSharingService();
|
|
if (binder == 0)
|
|
return IMB_NO_SERVICE;
|
|
|
|
Parcel data, reply;
|
|
|
|
//send pid, sessionflag, and memtype
|
|
pid_t pid = getpid();
|
|
//TODO: if pid is int32 ?
|
|
data.writeInt32(pid);
|
|
data.writeInt32(mSessionFlag);
|
|
writeIntPtr(data, mValue);
|
|
|
|
//send value/graphicbuffer obj
|
|
ShareMemMap smem;
|
|
smem.gbuffer = gbuffer;
|
|
smem.type = ST_GFX;
|
|
if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
//do transcation
|
|
if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
|
|
//set new value gotten from peer
|
|
mValue = reply.readIntPtr();
|
|
// LOGI("ShareValue(gfx) Get reply from sevice, new value:%x\n", mValue);
|
|
}
|
|
else //is local provider, direct access list
|
|
{
|
|
ShareMemMap* smem = new ShareMemMap;
|
|
smem->sessionflag = mSessionFlag;
|
|
smem->value = mValue;
|
|
smem->value_backup = mValue;
|
|
smem->type = ST_GFX;
|
|
smem->membase = NULL;
|
|
smem->gbuffer = gbuffer;
|
|
PushShareMem(smem);
|
|
}
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
IMB_Result IntelMetadataBuffer::ClearContext(uint32_t sessionflag, bool isProvider)
|
|
{
|
|
if ( !(sessionflag & REMOTE_PROVIDER) && !(sessionflag & REMOTE_CONSUMER)) //no sharing
|
|
return IMB_SUCCESS;
|
|
|
|
//clear local firstly
|
|
ClearLocalMem(sessionflag);
|
|
|
|
//clear mem on service if it is remote user
|
|
if ((isProvider && (sessionflag & REMOTE_PROVIDER)) || (!isProvider && (sessionflag & REMOTE_CONSUMER)))
|
|
{
|
|
// LOGI("CLEAR_MEM sessionflag=%x", sessionflag);
|
|
|
|
sp<IBinder> binder = GetIntelBufferSharingService();
|
|
if (binder == 0)
|
|
return IMB_NO_SERVICE;
|
|
|
|
//Detect IntelBufferSharingService, unshare mem from service
|
|
Parcel data, reply;
|
|
|
|
//send pid and sessionflag
|
|
pid_t pid = getpid();
|
|
//TODO: if pid is int32?
|
|
data.writeInt32(pid);
|
|
data.writeInt32(sessionflag);
|
|
|
|
if (binder->transact(CLEAR_MEM, data, &reply) != NO_ERROR)
|
|
return IMB_SERVICE_FAIL;
|
|
}
|
|
|
|
return IMB_SUCCESS;
|
|
}
|
|
|
|
uint32_t IntelMetadataBuffer::MakeSessionFlag(bool romoteProvider, bool remoteConsumer, uint16_t sindex)
|
|
{
|
|
uint32_t sessionflag = 0;
|
|
|
|
if (romoteProvider)
|
|
sessionflag |= REMOTE_PROVIDER;
|
|
|
|
if (remoteConsumer)
|
|
sessionflag |= REMOTE_CONSUMER;
|
|
|
|
return sessionflag + sindex;
|
|
}
|
|
#endif
|