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__ */