Enable cross process buffer sharing

BZ: 140092

Change-Id: Ia53b3a2306d2cc045a55e38b8c26336aa0f9de10
Signed-off-by: Zhao Liang <leo.zhao@intel.com>
Reviewed-on: http://android.intel.com:8080/125820
Reviewed-by: Yuan, Shengquan <shengquan.yuan@intel.com>
Reviewed-by: Hu, Gang A <gang.a.hu@intel.com>
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: cactus <cactus@intel.com>
diff --git a/test/Android.mk b/test/Android.mk
index f443a06..dbd0d06 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -22,6 +22,55 @@
 
 include $(BUILD_EXECUTABLE)
 
+# For intelmetadatabuffer cross-process buffersharing test
+# =====================================================
+
+include $(CLEAR_VARS)
+
+#VIDEO_ENC_LOG_ENABLE := true
+
+LOCAL_SRC_FILES :=              \
+    BSServer.cpp
+
+LOCAL_C_INCLUDES :=             \
+    $(LOCAL_PATH)               \
+    $(TARGET_OUT_HEADERS)/libmix_videoencoder \
+
+LOCAL_SHARED_LIBRARIES :=       \
+        libintelmetadatabuffer libutils libbinder
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := bserver
+
+include $(BUILD_EXECUTABLE)
+
+# For intelmetadatabuffer cross-process buffersharing test
+# =====================================================
+
+include $(CLEAR_VARS)
+
+#VIDEO_ENC_LOG_ENABLE := true
+
+LOCAL_SRC_FILES :=              \
+    BSClient.cpp
+
+LOCAL_C_INCLUDES :=             \
+    $(LOCAL_PATH)               \
+    $(TARGET_OUT_HEADERS)/libmix_videoencoder \
+
+LOCAL_SHARED_LIBRARIES :=       \
+        libintelmetadatabuffer libutils libbinder \
+        libgui                  \
+        libui                   \
+        libutils                \
+        libcutils               \
+        libhardware             \
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := bclient
+
+include $(BUILD_EXECUTABLE)
+
 # For mix_encoder
 # =====================================================
 
diff --git a/test/BSClient.cpp b/test/BSClient.cpp
new file mode 100755
index 0000000..b368642
--- /dev/null
+++ b/test/BSClient.cpp
@@ -0,0 +1,198 @@
+#include "IntelMetadataBuffer.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/MemoryDealer.h>
+#include <binder/IMemory.h>
+#include <binder/MemoryBase.h>
+#include <private/gui/ComposerService.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <getopt.h>
+
+using namespace android;
+
+int main(int argc, char* argv[])
+{
+    uint32_t tokenP =  0x80000000;
+    uint32_t tokenC =  0x40000000;
+    uint32_t tokenPC = 0xC0000000;
+    uint32_t token;
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    token = IntelMetadataBuffer::MakeSessionFlag(IntelMetadataBuffer::WEBRTC_BASE, true, false);
+#endif
+    int memmode = 0;
+    int clearcontext = 1;
+    int waittime = 0;
+    int storefile = 0;
+    int isProvider = 1;
+    int service = 0;
+
+    char c;
+    const char *short_opts = "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:q:u:v:w:x:y:z:?";
+
+    ProcessState::self()->startThreadPool();
+
+    while ((c = getopt_long(argc, argv, short_opts, NULL, NULL) ) != EOF) {
+        switch (c) {
+            case 't':
+                token = atoi(optarg);
+                break;
+            case 'm':
+                memmode = atoi(optarg);
+                break;
+            case 'c':
+                clearcontext = atoi(optarg); 
+                break;
+            case 'w':
+                waittime = atoi(optarg); 
+                break;
+            case 'f':
+                storefile = atoi(optarg); 
+                break;
+            case 'p':
+                isProvider = atoi(optarg); 
+                break;
+            case 's':
+                service = atoi(optarg); 
+                break;
+        }
+    }
+
+    if (service > 0) {
+        printf("Setup Service ....\n");
+#ifdef INTEL_VIDEO_XPROC_SHARING
+        IntelBufferSharingService::instantiate();
+#endif
+    }
+
+    if (isProvider) {	
+
+        printf("Working as Provider ...\n");
+
+        IntelMetadataBuffer *mb1;
+        IMB_Result ret;
+        int32_t value;
+        uint8_t* bytes;
+        uint32_t size;
+        ValueInfo vi;
+
+        if (memmode == 0) {
+            sp<MemoryHeapBase> Heap = new MemoryHeapBase(10000);
+            sp<MemoryBase> Buffer1 = new MemoryBase(Heap, 0, 1000);
+//            sp<MemoryBase> Buffer2 = new MemoryBase(Heap, 1000, 1000);
+            memset(Buffer1->pointer(), 0xAA, 1000);
+
+            mb1 = new IntelMetadataBuffer();
+            ret = mb1->SetType(MetadataBufferTypeCameraSource);
+#ifdef INTEL_VIDEO_XPROC_SHARING
+            mb1->SetSessionFlag(token);
+            if ((ret = mb1->ShareValue(Buffer1)) != IMB_SUCCESS) {
+                printf("IntelMetadataBuffer shareValue MemBase ret = %d failed\n", ret);
+                return 1;
+            }
+#else
+            mb1->SetValue((int32_t)Buffer1->pointer());
+#endif
+            ret = mb1->SetValueInfo(&vi);
+            ret = mb1->Serialize(bytes, size);
+ //                mb1->GetValue(value);
+            printf("original MemBase1 pointer is %x\n", Buffer1->pointer());
+
+        } else {
+            sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+            sp<IGraphicBufferAlloc> GraphicBufferAlloc = composer->createGraphicBufferAlloc();
+
+            uint32_t usage = GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE;
+            int format = 0x3231564E; // = HAL_PIXEL_FORMAT_NV12
+     //        int format = 0x7FA00E00; // = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar
+            int32_t error;
+            void* usrptr[3];
+
+            sp<GraphicBuffer> graphicBuffer(GraphicBufferAlloc->createGraphicBuffer(
+                                    1280, 720, format, usage, &error));
+            if (graphicBuffer.get() == NULL)
+                printf("create graphicbuffer failed\n");
+
+            status_t ret1=graphicBuffer->lock(usage, &usrptr[0]);
+            memset(usrptr[0], 0xAA, 4);
+            graphicBuffer->unlock();
+
+            mb1 = new IntelMetadataBuffer();
+            ret = mb1->SetType(MetadataBufferTypeCameraSource);
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+            mb1->SetSessionFlag(token);
+            if ((ret = mb1->ShareValue(graphicBuffer)) != IMB_SUCCESS) {
+                printf("IntelMetadataBuffer shareValue graphicbuffer ret = %d failed\n", ret);
+                return 1;
+            }
+#else
+            mb1->SetValue((int32_t)graphicBuffer->handle);
+#endif
+            ret = mb1->SetValueInfo(&vi);
+            ret = mb1->Serialize(bytes, size);
+
+      //       mb1->GetValue(value);
+            printf("original graphicbuffer handle is %x\n", graphicBuffer->handle);
+        }
+
+        if (storefile > 0) {
+            FILE* fp = fopen("/data/mdb.data", "wb+");
+            if (fp != NULL) {
+                fwrite(bytes, 1, size, fp);
+                fclose(fp);
+            }
+        }
+
+        delete mb1;
+	
+    }else {
+
+        printf("Working as Consumer ...\n");
+
+        uint8_t bytes[128];
+        uint32_t size;
+		
+        FILE* fp = fopen("/data/mdb.data", "rb");
+        if (fp != NULL)
+        {
+            size = fread(bytes, 1, 128, fp);
+            fclose(fp);
+        }
+
+        IntelMetadataBuffer mb1;
+	    int32_t value;
+        IMB_Result res;
+        res = mb1.UnSerialize(bytes,size);
+	
+        if (IMB_SUCCESS == res) {
+	        res = mb1.GetValue(value);
+            if (res != IMB_SUCCESS)
+                printf("Consumer GetValue failed, result=%x\n", res);
+            else
+                printf("Consumer get value =%x\n", value);
+        } else
+            printf("unserialize failed, result=%x\n", res);
+
+    }
+
+    if (waittime > 0) {
+        printf("waiting %d seconds .... \n", waittime);
+		sleep(waittime);
+    }
+
+    if (clearcontext > 0) {
+        printf("Clearing %s Context ... \n", (isProvider > 0) ? "Provider":"Consumer");
+#ifdef INTEL_VIDEO_XPROC_SHARING
+        IntelMetadataBuffer::ClearContext(token, isProvider > 0);
+#endif
+    }
+
+    printf("Exit\n");
+    return 1;
+}
+
diff --git a/test/BSServer.cpp b/test/BSServer.cpp
new file mode 100755
index 0000000..f3b822f
--- /dev/null
+++ b/test/BSServer.cpp
@@ -0,0 +1,21 @@
+#include "IntelMetadataBuffer.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+
+using namespace android;
+
+int main(int argc, char* argv[])
+{
+    //start service
+    ProcessState::self()->startThreadPool();
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    IntelBufferSharingService::instantiate();
+#endif
+    IPCThreadState::self()->joinThreadPool();
+    return 1;
+}
+
+
diff --git a/test/mix_encoder2.cpp b/test/mix_encoder2.cpp
index 3bdd07f..0fa9096 100755
--- a/test/mix_encoder2.cpp
+++ b/test/mix_encoder2.cpp
@@ -22,7 +22,7 @@
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
 #include <gui/IGraphicBufferAlloc.h>
-#include <gui/SurfaceTextureClient.h>
+#include <gui/Surface.h>
 
 #include <ui/PixelFormat.h>
 #include <hardware/gralloc.h>
@@ -88,7 +88,6 @@
                 Y_row[jj] = 0xeb;
             if ((xpos == 1) && (ypos == 1))
                 Y_row[jj] = 0xeb;
-
             if ((xpos == 1) && (ypos == 0))
                 Y_row[jj] = 0x10;
             if ((xpos == 0) && (ypos == 1))
@@ -109,7 +108,6 @@
             memset (V_row,0x80,width/2);
         }
     }
-
     row_shift += 8;
 //        if (row_shift==BOX_WIDTH) row_shift = 0;
 
@@ -126,25 +124,47 @@
 class DummySource : public MediaSource {
 
 public:
-    DummySource(int width, int height, int stride, int nFrames, int fps,
-						bool metadata, const char* yuv)
-        : mWidth(width),
-          mHeight(height),
-          mStride(stride),
-          mMaxNumFrames(nFrames),
-          mFrameRate(fps),
-          mMetadata(metadata),
-          mYuvfile(yuv),
-          mYuvhandle(NULL){
+    DummySource(const sp<MetaData> &meta, uint32_t flag) {
+
+        bool success;
+
+        success = meta->findInt32(kKeyWidth, &mWidth);
+        CHECK(success);
+
+        success = meta->findInt32(kKeyHeight, &mHeight);
+        CHECK(success);
+
+        success = meta->findInt32(kKeyStride, &mStride);
+        CHECK(success);
+
+        success = meta->findInt32(kKeyFrameRate, &mFrameRate);
+        CHECK(success);
+
+        success = meta->findInt32(kKeyColorFormat, &mColorFormat);
+        CHECK(success);
+
+        success = meta->findCString('yuvf', &mYuvfile);
+        CHECK(success);
+
+        success = meta->findInt32('fnum', &mMaxNumFrames);
+        CHECK(success);
+
+        success = meta->findInt32('sflg', (int32_t*)&mSessionFlag);
+        CHECK(success);
+
+        mYuvhandle = NULL;
+
+        mMetadata = flag & OMXCodec::kStoreMetaDataInVideoBuffers;
 
         if (mMetadata)
             mSize = 128;
         else
-            mSize = mStride * mHeight * 3 /2;
+            mSize = mStride * mHeight * 3 / 2 ;
 
         for(int i=0; i<PRELOAD_FRAME_NUM; i++)
-            mGroup.add_buffer(new MediaBuffer(mSize));
+            mGroup.add_buffer(new MediaBuffer(mSize + 0x0FFF));
 
+        mTAG = "Dummy";
     }
 
     virtual sp<MetaData> getFormat() {
@@ -163,12 +183,37 @@
         gNumFramesOutput = 0;
         createResource ();
 
-        if (mYuvfile == NULL) {
+#if 1
+        {
+            int size= mStride * mHeight * 1.5;
+            void* tmp = malloc(size);
+
+            int64_t start = systemTime();
+
+            for(int j=0; j<100; j++) {
+                for(int i=0; i<PRELOAD_FRAME_NUM; i++)
+                    memcpy(tmp, mUsrptr[i], size);
+            }
+            int64_t end = systemTime();
+            printf("read from %s mem, write to cached malloc mem, per memcpy cost = %lld us\n", mTAG, (end-start) / (100000*PRELOAD_FRAME_NUM));
+
+            for(int j=0; j<100; j++) {
+                for(int i=0; i<PRELOAD_FRAME_NUM; i++)
+                    memcpy(mUsrptr[i], tmp, size);
+            }
+            start = systemTime();
+
+            printf("read from cached malloc mem, write to %s mem, per memcpy cost = %lld us\n", mTAG, (start - end)/ (100000*PRELOAD_FRAME_NUM));
+
+        }
+#endif
+        if (mYuvfile == NULL || strlen(mYuvfile) == 0) {
             //upload src data
-            LOG("Fill src picture width=%d, Height=%d\n", mStride, mHeight);
+            LOG("Fill src pictures width=%d, Height=%d\n", mStride, mHeight);
             for(int i=0; i<PRELOAD_FRAME_NUM; i++) {
                 YUV_generator_planar(mStride, mHeight, mUsrptr[i], mStride, mUsrptr[i] + mStride*mHeight, mStride, 0, 0, 1);
             }
+            LOG("Fill src pictures end\n");
         }else{
             mYuvhandle = fopen(mYuvfile, "rb");
             if (mYuvhandle == NULL)
@@ -179,7 +224,7 @@
     }
 
     virtual status_t stop() {
-        gNumFramesOutput = 0;
+//        gNumFramesOutput = 0;
         return OK;
     }
 
@@ -226,8 +271,14 @@
             size = mSize;
         }
 
-        memcpy ((*buffer)->data(), data, size);
-        (*buffer)->set_range(0, size);
+        size_t offset = 0;
+        if (mMetadata)
+            memcpy ((*buffer)->data(), data, size);
+        else {
+            offset = ((int)((*buffer)->data() + 0x0FFF) & ~0x0FFF) - (int)(*buffer)->data();
+            memcpy ((*buffer)->data() + offset, data, size);
+        }
+        (*buffer)->set_range(offset, size);
         (*buffer)->meta_data()->clear();
         (*buffer)->meta_data()->setInt64(
                 kKeyTime, (gNumFramesOutput * 1000000) / mFrameRate);
@@ -246,6 +297,10 @@
     virtual ~DummySource() {
         for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
             delete mIMB[i];
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+        IntelMetadataBuffer::ClearContext(mSessionFlag, true);
+#endif
     }
 
 public:
@@ -259,6 +314,9 @@
     int mFrameRate;
     int mColorFormat;
     size_t mSize;
+    unsigned int mSessionFlag;
+    const char* mTAG;
+
 //    int64_t mNumFramesOutput;
 
     DummySource(const DummySource &);
@@ -275,8 +333,10 @@
 class MallocSource : public DummySource {
 public:
 
-    MallocSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
-			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
+    MallocSource(const sp<MetaData> &meta, uint32_t flag) :
+			DummySource (meta, flag) {
+
+        mTAG = "Malloc";
     }
 
     ~MallocSource() {
@@ -306,7 +366,6 @@
 
             //keep address 4K aligned
             mUsrptr[i] = (uint8_t*)((((uint32_t )mMallocPtr[i] + 4095) / 4096 ) * 4096);
-
             mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeCameraSource, (int32_t) mUsrptr[i]);
             mIMB[i]->SetValueInfo(&vinfo);
 //            LOG("Malloc address=%x\n", mUsrptr[i]);
@@ -324,8 +383,9 @@
 class MemHeapSource : public DummySource {
 public:
 
-    MemHeapSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
-			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
+    MemHeapSource(const sp<MetaData> &meta, uint32_t flag) :
+			DummySource (meta, flag) {
+        mTAG = "MemHeap";
     }
 
     ~MemHeapSource() {
@@ -358,9 +418,16 @@
 
             mUsrptr[i] = (uint8_t*) ((int) (mBuffers[i]->pointer() + 0x0FFF) & ~0x0FFF);
 
-            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeCameraSource, (int32_t) mUsrptr[i]);
+            mIMB[i] = new IntelMetadataBuffer();
+            mIMB[i]->SetType(MetadataBufferTypeCameraSource);
+#ifdef INTEL_VIDEO_XPROC_SHARING
+            mIMB[i]->SetSessionFlag(mSessionFlag);
+            mIMB[i]->ShareValue(mBuffers[i]);
+#else
+            mIMB[i]->SetValue((int32_t)mUsrptr[i]);
+#endif
             mIMB[i]->SetValueInfo(&vinfo);
-            LOG("MemHeap address=%x\n", mUsrptr[i]);
+            LOG("MemHeap local address=%x\n", mUsrptr[i]);
         }
 
         return OK;
@@ -393,9 +460,10 @@
 
 class VASurfaceSource : public DummySource {
 public:
-    VASurfaceSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv, int mode) :
-			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
+    VASurfaceSource(const sp<MetaData> &meta, uint32_t flag, int mode) :
+			DummySource (meta, flag) {
         mMode = mode;
+        mTAG = "VASurface";
     }
 
     virtual ~VASurfaceSource() {
@@ -529,12 +597,13 @@
 class GfxSource : public DummySource {
 
 public:
-    GfxSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
-			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
-        mColor = 0;
+    GfxSource(const sp<MetaData> &meta, uint32_t flag) :
+			DummySource (meta, flag) {
+
         mWidth = ((mWidth + 15 ) / 16 ) * 16;
         mHeight = ((mHeight + 15 ) / 16 ) * 16;
         mStride = mWidth;
+        mTAG = "Gfx";
     }
 
     virtual ~GfxSource() {
@@ -548,17 +617,24 @@
         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
 
         uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_OFTEN;// | GraphicBuffer::USAGE_HW_COMPOSER;
-        int format = HAL_PIXEL_FORMAT_NV12;
-        if (mColor == 1)
-            format = 0x7FA00E00; // = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar in OMX_IVCommon.h
-
         int32_t error;
 
+        ValueInfo vinfo;
+        memset(&vinfo, 0, sizeof(ValueInfo));
+        vinfo.mode = MEM_MODE_GFXHANDLE;
+        vinfo.size = 0;
+        vinfo.width = mWidth;
+        vinfo.height = mHeight;
+        vinfo.lumaStride = mStride;
+        vinfo.chromStride = mStride;
+        vinfo.format = mColorFormat;
+        vinfo.s3dformat = 0xFFFFFFFF;
+
         for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
         {
             sp<GraphicBuffer> graphicBuffer(
                     mGraphicBufferAlloc->createGraphicBuffer(
-                                    mWidth, mHeight, format, usage, &error));
+                                    mWidth, mHeight, mColorFormat, usage, &error));
 
             if (graphicBuffer.get() == NULL) {
                 printf("GFX createGraphicBuffer failed\n");
@@ -570,7 +646,16 @@
             if (graphicBuffer->lock(usage, &vaddr[0]) != OK)
                 return UNKNOWN_ERROR;
 
-            mIMB[i] = new IntelMetadataBuffer(MetadataBufferTypeGrallocSource, (int32_t)mGraphicBuffer[i]->handle);
+            mUsrptr[i] = (uint8_t*)vaddr[0];
+            mIMB[i] = new IntelMetadataBuffer();
+            mIMB[i]->SetType(MetadataBufferTypeCameraSource);
+#ifdef INTEL_VIDEO_XPROC_SHARING
+            mIMB[i]->SetSessionFlag(mSessionFlag);
+            mIMB[i]->ShareValue(mGraphicBuffer[i]);
+#else
+            mIMB[i]->SetValue((int32_t)mGraphicBuffer[i]->handle);
+#endif
+            mIMB[i]->SetValueInfo(&vinfo);
             graphicBuffer->unlock();
 
             mUsrptr[i] = (uint8_t*)vaddr[0];
@@ -589,16 +674,14 @@
     //for gfxhandle
     sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
     sp<GraphicBuffer> mGraphicBuffer[PRELOAD_FRAME_NUM];
-
-    int mColor;
 };
 
 class GrallocSource : public DummySource {
 
 public:
-    GrallocSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv) :
-			DummySource (width, height, stride, nFrames, fps, mdata, yuv) {
-        mColor = 0;
+    GrallocSource(const sp<MetaData> &meta, uint32_t flag) :
+			DummySource (meta, flag) {
+        mTAG = "Gralloc";
     }
 
     virtual ~GrallocSource () {
@@ -609,15 +692,12 @@
     status_t createResource()
     {
         int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_WRITE_OFTEN;
-        int format = HAL_PIXEL_FORMAT_NV12;
-        if (mColor == 1)
-            format = 0x7FA00E00; // = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar in OMX_IVCommon.h
 
         gfx_init();
 
         for(int i = 0; i < PRELOAD_FRAME_NUM; i ++)
         {
-            if (gfx_alloc(mWidth, mHeight, format, usage, &mHandle[i], (int32_t*)&mStride) != 0)
+            if (gfx_alloc(mWidth, mHeight, mColorFormat, usage, &mHandle[i], (int32_t*)&mStride) != 0)
                 return UNKNOWN_ERROR;
             void* vaddr[3];
 
@@ -630,7 +710,6 @@
             mStride = h->iWidth;
             mHeight = h->iHeight;
         }
-
         return OK;
     }
 
@@ -713,13 +792,12 @@
     alloc_device_t  *mAllocDev; /* get by gralloc_open */
 
     buffer_handle_t mHandle[PRELOAD_FRAME_NUM];
-    int mColor;
 };
 
 class MixSurfaceMediaSource : public SurfaceMediaSource {
 
 public:
-    MixSurfaceMediaSource(int width, int height, int stride, int nFrames, int fps, bool mdata, const char* yuv)
+    MixSurfaceMediaSource(int width, int height, int nFrames, int fps)
                                  :SurfaceMediaSource(width, height){
         mMaxNumFrames = nFrames;
         mFPS = fps;
@@ -729,7 +807,7 @@
     }
 
     status_t start(MetaData *params) {
-		mSTC = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(getBufferQueue()));
+		mSTC = new Surface(getBufferQueue());
 		mANW = mSTC;
         mRunning = true;
 
@@ -759,7 +837,7 @@
     int mFPS;
 
 private:
-    sp<SurfaceTextureClient> mSTC;
+    sp<Surface> mSTC;
     sp<ANativeWindow> mANW;
     pthread_t mThread;
     bool mRunning;
@@ -812,6 +890,7 @@
         mEncodeFrameCount = 0;
         mSource = source;
 
+        mMeta = meta;
         const char *mime;
         bool success = meta->findCString(kKeyMIMEType, &mime);
         CHECK(success);
@@ -869,16 +948,18 @@
         mRCMode = RC_MODES[rcmode];
     }
 
-    virtual sp<MetaData> getFormat() {
-        sp<MetaData> meta = new MetaData;
-        meta->setInt32(kKeyWidth, mWidth);
-        meta->setInt32(kKeyHeight, mHeight);
+    sp<MetaData> getFormat() {
+#if 0
+        mMeta = new MetaData;
+        mMeta->setInt32(kKeyWidth, mWidth);
+        mMeta->setInt32(kKeyHeight, mHeight);
 //        meta->setInt32(kKeyColorFormat, mColorFormat);
-        meta->setCString(kKeyMIMEType, mCodec);
-        return meta;
+        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+#endif
+        return mMeta;
     }
 
-    virtual status_t start(MetaData *params) {
+    status_t start(MetaData *params) {
         Encode_Status ret;
         status_t err;
 
@@ -906,7 +987,7 @@
         return mSource->start();
     }
 
-    virtual status_t stop() {
+    status_t stop() {
         Encode_Status ret;
 
         ret = mVideoEncoder->stop();
@@ -1144,7 +1225,7 @@
 
     sp<MediaSource> mSource;
     MediaBufferGroup mGroup;
-
+    sp<MetaData> mMeta;
 };
 
 class IVFWriter : public MediaWriter {
@@ -1394,9 +1475,11 @@
     printf(" -p/--fps <Bitrate>				set frame rate, default 30\n");
     printf(" -q/--minQP <qp>					set minQP, default 0\n");
     printf(" -r/--rcMode <Mode>				set rc mode, like VBR(default), CBR, VCM, NO_RC\n");
-    printf(" -s/--src <source>				select source, like MALLOC(default), VASURFACE, KBUFHANDLE, GFX, GRALLOC, MEMHEAP (CAMERASOURCE, not support yet) \n");
+    printf(" -s/--src <source>				select source, like MALLOC(default), VASURFACE, KBUFHANDLE, GFX, GRALLOC, MEMHEAP, SURFACEMEDIASOURCE (CAMERASOURCE, not support yet) \n");
+    printf(" -t/--sessionFlag	<sessionflag>	            set sessionflag, default is 0\n");
+    printf(" -u/--disableFrameSkip				disable frame skip, default is false\n");
     printf(" -w <Width> -h <Height>				set source width /height, default 1280*720\n");
-    printf(" -t/--disableFrameSkip				disable frame skip, default is false\n");
+
     printf("\n");
 
 }
@@ -1426,7 +1509,8 @@
     int OutFormat = 0;
     int SyncMode = 0;
     char* OutFileName = "out.264";
-    const char* Yuvfile = NULL;
+    const char* Yuvfile = "";
+    unsigned int SessionFlag = 0;
 
     android::ProcessState::self()->startThreadPool();
 
@@ -1453,7 +1537,8 @@
 						{"intraPeriod", required_argument, NULL, 'd'},
 						{"winSize", required_argument, NULL, 'j'},
 						{"idrInt", required_argument, NULL, 'l'},
-						{"disableFrameSkip", no_argument, NULL, 't'},
+						{"disableFrameSkip", no_argument, NULL, 'u'},
+						{"sessionFlag", required_argument, NULL, 't'},
 						{0, 0, 0, 0}
     };
 
@@ -1584,6 +1669,10 @@
                     break;
 
                 case 't':
+                    SessionFlag = atoi(optarg);
+                    break;
+
+                case 'u':
                     DisableFrameSkip = 1;
                     break;
 
@@ -1604,7 +1693,7 @@
     printf("=========================================\n");
     printf("Source:\n");
     printf("Type: %s, Width: %d, Height: %d, Stride: %d\n", SRCTYPE[SrcType], SrcWidth, SrcHeight, SrcStride);
-    printf("FPS: %d, YUV: %s, Metadata: %d\n", SrcFps, Yuvfile, MetadataMode);
+    printf("FPS: %d, YUV: %s, Metadata: %d, SessionFlag: 0x%08x\n", SrcFps, Yuvfile, MetadataMode, SessionFlag);
 
     printf("\nEncoder:\n");
     printf("Type: %s, Codec: %s, Width: %d, Height: %d\n", ENCTYPE[EncType], CODEC[EncCodec], EncWidth, EncHeight);
@@ -1621,29 +1710,37 @@
     sp<MediaWriter> writer;
 
     //setup source
+    sp<MetaData> src_meta = new MetaData;
+    src_meta->setInt32(kKeyWidth, SrcWidth);
+    src_meta->setInt32(kKeyHeight, SrcHeight);
+    src_meta->setInt32(kKeyStride, SrcStride);
+    src_meta->setInt32(kKeyFrameRate, SrcFps);
+    src_meta->setInt32(kKeyColorFormat, OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar); //HAL_PIXEL_FORMAT_NV12     OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar =  0x7FA00E00,
+
+    src_meta->setCString('yuvf', Yuvfile);
+    src_meta->setInt32('fnum', SrcFrameNum);
+    src_meta->setInt32('sflg', SessionFlag);
+
+    uint32_t src_flags = 0;
+    if (MetadataMode)
+        src_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
+
     if (SrcType == 0) {
-        source = new MallocSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile);
+        source = new MallocSource(src_meta, src_flags);
     } else if (SrcType == 1) {
-        source = new VASurfaceSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile, 0);
+        source = new VASurfaceSource(src_meta, src_flags, 0);
     } else if (SrcType == 2) {
-        source = new VASurfaceSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile, 1);
+        source = new VASurfaceSource(src_meta, src_flags, 1);
     } else if (SrcType == 3) {
-        source = new GfxSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile);
+        source = new GfxSource(src_meta, src_flags);
     } else if (SrcType == 4) {
-        source = new GrallocSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile);
+        source = new GrallocSource(src_meta, src_flags);
     } else if (SrcType == 5) {
-        source = new MemHeapSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile);
+        source = new MemHeapSource(src_meta, src_flags);
     } else if (SrcType == 7) {
-        source = new MixSurfaceMediaSource(SrcWidth, SrcHeight, SrcStride, SrcFrameNum,
-			SrcFps, MetadataMode, Yuvfile);
+        source = new MixSurfaceMediaSource(SrcWidth, SrcHeight, SrcFrameNum, SrcFps);
         SyncMode = 1;
-	}else{
+    }else{
         printf("Source Type is not supported\n");
         return 0;
     }
@@ -1712,16 +1809,28 @@
 	else 
 		writer = new IVFWriter(OutFileName);
 
-    writer->addSource(encoder);
+    status_t err;
+    err = writer->addSource(encoder);
+    if (err != OK) {
+        printf("Writer addSource failed %d\n", err);
+        return 0;
+    }
+
+    err = writer->start(enc_meta.get());
+    if (err != OK) {
+        printf("Writer start failed %d\n", err);
+        return 0;
+    }
 
     printf("Start encoding\n");
 
     int64_t start = systemTime();
-    CHECK_EQ((status_t)OK, writer->start(enc_meta.get()));
+
     while (!writer->reachedEOS()) {
         usleep(100000);
     }
-    status_t err = writer->stop();
+
+    err = writer->stop();
     int64_t end = systemTime();
 
     if (EncType == 1) {
@@ -1735,6 +1844,7 @@
         return 1;
     }
 
+    src_meta.clear();
     enc_meta.clear();
 
     printf("encoding %d frames in %lld us\n", gNumFramesOutput, (end-start)/1000);
diff --git a/videoencoder/Android.mk b/videoencoder/Android.mk
index 5821c5c..3ec61de 100644
--- a/videoencoder/Android.mk
+++ b/videoencoder/Android.mk
@@ -101,6 +101,11 @@
 LOCAL_COPY_HEADERS := \
     IntelMetadataBuffer.h
 
+ifeq ($(INTEL_VIDEO_XPROC_SHARING),true)
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libgui \
+                          libui libcutils libhardware
+endif
+
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libintelmetadatabuffer
 
diff --git a/videoencoder/IntelMetadataBuffer.cpp b/videoencoder/IntelMetadataBuffer.cpp
index 4a2b42f..b7dcfc0 100644
--- a/videoencoder/IntelMetadataBuffer.cpp
+++ b/videoencoder/IntelMetadataBuffer.cpp
@@ -22,10 +22,315 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IntelMetadataBuffer"
+#include <utils/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;
+    int32_t value;
+    int32_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, uint32_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 = (int32_t) ((int) ( mem->pointer() + 0x0FFF) & ~0x0FFF);
+        map->membase = mem;
+
+#ifdef TEST
+        ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \
+           heap->getHeapID(), mem->pointer(), *((int *)(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 = (uint32_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:%x data:%x", (int32_t)buffer->handle, *((int *)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, int32_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, int32_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)
+        LOGE("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) {
+
+    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
+            {
+                LOGE("onTransact in same process, wrong sessionflag?");
+                return UNKNOWN_ERROR;
+            }
+
+            int32_t value = data.readInt32();
+
+//            LOGI("onTransact SHARE_MEM value=%x", value);
+
+            //different process
+            ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value);
+            if (map == NULL)
+                return UNKNOWN_ERROR;
+
+            reply->writeInt32(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
+                LOGE("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
+            {
+                LOGE("onTransact GET_MEM in same process, wrong sessionflag?");
+                return UNKNOWN_ERROR;
+            }
+
+            int32_t value = data.readInt32();
+
+//            LOGI("onTransact GET_MEM value=%x", value);
+
+            ShareMemMap* smem = FindShareMem(sessionflag, value, false);
+            if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem)))
+                return NO_ERROR;
+            else
+                LOGE("onTransact GET_MEM: Not find mem");
+
+            return UNKNOWN_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+
+    }
+    return NO_ERROR;
+}
+#endif
+
 IntelMetadataBuffer::IntelMetadataBuffer()
 {
     mType = MetadataBufferTypeCameraSource;
@@ -35,6 +340,9 @@
     mExtraValues_Count = 0;
     mBytes = NULL;
     mSize = 0;
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    mSessionFlag = 0;
+#endif
 }
 
 IntelMetadataBuffer::IntelMetadataBuffer(MetadataBufferType type, int32_t value)
@@ -46,8 +354,11 @@
     mExtraValues_Count = 0;
     mBytes = NULL;
     mSize = 0;
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    mSessionFlag = 0;
+#endif
 }
- 
+
 IntelMetadataBuffer::~IntelMetadataBuffer()
 {
     if (mInfo)
@@ -64,6 +375,9 @@
 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);
@@ -90,6 +404,9 @@
     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);
@@ -130,7 +447,47 @@
 {
     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();
+    data.writeInt32(pid);
+    data.writeInt32(mSessionFlag);
+    data.writeInt32(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(int32_t value)
@@ -157,7 +514,7 @@
         memcpy(mInfo, info, sizeof(ValueInfo));
     }
     else
-        return IMB_INVAL_PARAM;    
+        return IMB_INVAL_PARAM;
 
     return IMB_SUCCESS;
 }
@@ -166,7 +523,7 @@
 {
     values = mExtraValues;
     num = mExtraValues_Count;
- 
+
     return IMB_SUCCESS;
 }
 
@@ -182,7 +539,7 @@
 
         if (mExtraValues == NULL)
             mExtraValues = new int32_t[num];
-        
+
         memcpy(mExtraValues, values, sizeof(int32_t) * num);
         mExtraValues_Count = num;
     }
@@ -208,7 +565,7 @@
     data += 4;
     memcpy(&value, data, 4);
     data += 4;
-    
+
     switch (type)
     {
         case MetadataBufferTypeCameraSource:
@@ -216,16 +573,16 @@
         case MetadataBufferTypeUser:
         {
             if (extrasize >0 && extrasize < sizeof(ValueInfo))
-                return IMB_INVAL_BUFFER;    
-            
-            if (extrasize > sizeof(ValueInfo)) //has extravalues 
+                return IMB_INVAL_BUFFER;
+
+            if (extrasize > sizeof(ValueInfo)) //has extravalues
             {
                 if ( (extrasize - sizeof(ValueInfo)) % 4 != 0 )
                     return IMB_INVAL_BUFFER;
                 ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / 4;
             }
-                
-            if (extrasize > 0) 
+
+            if (extrasize > 0)
             {
                 info = new ValueInfo;
                 memcpy(info, data, sizeof(ValueInfo));
@@ -259,7 +616,10 @@
         delete[] mExtraValues;
     mExtraValues = ExtraValues;
     mExtraValues_Count = ExtraValues_Count;
-
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    if (mInfo != NULL)
+        mSessionFlag = mInfo->sessionFlag;
+#endif
     return IMB_SUCCESS;
 }
 
@@ -285,9 +645,12 @@
         ptr += 4;
         memcpy(ptr, &mValue, 4);
         ptr += 4;
-        
+
         if (mInfo)
         {
+        #ifdef INTEL_VIDEO_XPROC_SHARING
+            mInfo->sessionFlag = mSessionFlag;
+        #endif
             memcpy(ptr, mInfo, sizeof(ValueInfo));
             ptr += sizeof(ValueInfo);
 
@@ -298,7 +661,7 @@
 
     data = mBytes;
     size = mSize;
-    
+
     return IMB_SUCCESS;
 }
 
@@ -306,3 +669,167 @@
 {
     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 = (int32_t)((int) ( mem->pointer() + 0x0FFF) & ~0x0FFF);
+
+    if (mSessionFlag == 0) //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();
+        data.writeInt32(pid);
+        data.writeInt32(mSessionFlag);
+        data.writeInt32(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.readInt32();
+//        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 = (int32_t)gbuffer->handle;
+
+    if (mSessionFlag == 0) //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();
+        data.writeInt32(pid);
+        data.writeInt32(mSessionFlag);
+        data.writeInt32(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.readInt32();
+//        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 == 0) //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();
+        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(uint16_t sindex, bool romoteProvider, bool remoteConsumer)
+{
+    uint32_t sessionflag = 0;
+
+    if (romoteProvider)
+        sessionflag |= REMOTE_PROVIDER;
+
+    if (remoteConsumer)
+        sessionflag |= REMOTE_PROVIDER;
+
+    return sessionflag + sindex;
+}
+#endif
diff --git a/videoencoder/IntelMetadataBuffer.h b/videoencoder/IntelMetadataBuffer.h
index 6d8f978..00b6649 100644
--- a/videoencoder/IntelMetadataBuffer.h
+++ b/videoencoder/IntelMetadataBuffer.h
@@ -27,12 +27,25 @@
 
 #include <stdint.h>
 
+//#define INTEL_VIDEO_XPROC_SHARING
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+#include <binder/MemoryBase.h>
+#include <ui/GraphicBuffer.h>
+
+using namespace android;
+#endif
+
 #define STRING_TO_FOURCC(format) ((uint32_t)(((format)[0])|((format)[1]<<8)|((format)[2]<<16)|((format)[3]<<24)))
 
 typedef enum {
     IMB_SUCCESS = 0,
     IMB_INVAL_PARAM = 1,
     IMB_INVAL_BUFFER = 2,
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    IMB_NO_SERVICE = 3,
+    IMB_SERVICE_FAIL = 4,
+#endif
 }IMB_Result;
 
 typedef enum {
@@ -57,6 +70,9 @@
         uint32_t chromStride;		//picture chrom stride
         uint32_t format;		//color format
         uint32_t s3dformat;		//S3D format
+#ifdef INTEL_VIDEO_XPROC_SHARING
+        uint32_t sessionFlag;     //for buffer sharing session
+#endif
 }ValueInfo;
 
 typedef enum {
@@ -102,7 +118,52 @@
 
     uint8_t* mBytes;
     uint32_t mSize;
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+public:
+    IMB_Result ShareValue(sp<MemoryBase> mem);
+    IMB_Result ShareValue(sp<GraphicBuffer> gbuffer);
+
+    IMB_Result GetSessionFlag(uint32_t &sessionflag);
+    IMB_Result SetSessionFlag(uint32_t sessionflag);
+
+    //Static, for clear context
+    static IMB_Result ClearContext(uint32_t sessionflag, bool isProvider = true);
+
+    static const uint16_t CAMERA_BASE =    0x0000;
+    static const uint16_t WIDI_BASE =      0x1000;
+    static const uint16_t WEBRTC_BASE =    0x2000;
+    static const uint16_t VIDEOEDIT_BASE = 0x3000;
+
+    static uint32_t MakeSessionFlag(uint16_t sindex, bool romoteProvider, bool remoteConsumer);
+
+private:
+    uint32_t mSessionFlag;
+#endif
+
 };
 
+#ifdef INTEL_VIDEO_XPROC_SHARING
+
+class IntelBufferSharingService : public BBinder
+{
+private:
+    static IntelBufferSharingService *gBufferService;
+
+public:
+    static status_t instantiate();
+
+    IntelBufferSharingService(){
+        LOGI("IntelBufferSharingService instance is created");
+    }
+
+    ~IntelBufferSharingService(){
+        LOGI("IntelBufferSharingService instance is destroyed");
+    }
+
+    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+};
+#endif
+
 #endif
 
diff --git a/videoencoder/VideoEncoderBase.cpp b/videoencoder/VideoEncoderBase.cpp
index af16152..8e90e9f 100644
--- a/videoencoder/VideoEncoderBase.cpp
+++ b/videoencoder/VideoEncoderBase.cpp
@@ -68,7 +68,11 @@
     ,mTotalSize(0)
     ,mTotalSizeCopied(0)
     ,mFrameSkipped(false)
-    ,mSupportedSurfaceMemType(0){
+    ,mSupportedSurfaceMemType(0)
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    ,mSessionFlag(0)
+#endif
+    {
 
     VAStatus vaStatus = VA_STATUS_SUCCESS;
     // here the display can be any value, use following one
@@ -106,6 +110,10 @@
     } else {
         mVADisplay = NULL;
     }
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    IntelMetadataBuffer::ClearContext(mSessionFlag, false);
+#endif
 }
 
 Encode_Status VideoEncoderBase::start() {
@@ -1806,6 +1814,9 @@
         value = (int32_t)inBuffer->data;
     }
 
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    imb.GetSessionFlag(mSessionFlag);
+#endif
 
     //find if mapped
     map = (SurfaceMap*) findSurfaceMapByValue(value);
diff --git a/videoencoder/VideoEncoderBase.h b/videoencoder/VideoEncoderBase.h
index d43878b..75c3874 100644
--- a/videoencoder/VideoEncoderBase.h
+++ b/videoencoder/VideoEncoderBase.h
@@ -163,5 +163,9 @@
 
     //supported surface memory types
     int mSupportedSurfaceMemType;
+
+#ifdef INTEL_VIDEO_XPROC_SHARING
+    uint32_t mSessionFlag;
+#endif
 };
 #endif /* __VIDEO_ENCODER_BASE_H__ */