Initial libmix commit
Change-Id: I7a0b9afdc83a3274189cef0788c7296a871a3d98
Signed-off-by: Guilhem IMBERTON <guilhem.imberton@intel.com>
diff --git a/videoencoder/IntelMetadataBuffer.cpp b/videoencoder/IntelMetadataBuffer.cpp
new file mode 100644
index 0000000..28f8e63
--- /dev/null
+++ b/videoencoder/IntelMetadataBuffer.cpp
@@ -0,0 +1,832 @@
+/*
+* 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)( 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(heap->asBinder());
+#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;
+}
+
+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;
+
+ reply->writeIntPtr(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);
+ data.writeIntPtr(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;
+}
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
+{
+ sessionflag = mSessionFlag;
+
+ return IMB_SUCCESS;
+}
+
+IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
+{
+ mSessionFlag = sessionflag;
+
+ return IMB_SUCCESS;
+}
+
+IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem)
+{
+ mValue = (intptr_t)((intptr_t) ( 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);
+ data.writeIntPtr(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);
+ data.writeIntPtr(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