diff options
author | hoony.yu <hoony.yu@samsung.com> | 2010-09-07 23:56:11 -0700 |
---|---|---|
committer | Maarten Hooft <mthooft@google.com> | 2010-09-14 22:09:54 -0700 |
commit | f5bc9d8908c7612b8240a46fba560a1ecf05f2ae (patch) | |
tree | 9bf3ba9d55c0398b6014703874024d34806b50d5 | |
parent | 17fee1bcd52aac003ef69816ba61992680bd3035 (diff) | |
download | device_samsung_crespo-f5bc9d8908c7612b8240a46fba560a1ecf05f2ae.zip device_samsung_crespo-f5bc9d8908c7612b8240a46fba560a1ecf05f2ae.tar.gz device_samsung_crespo-f5bc9d8908c7612b8240a46fba560a1ecf05f2ae.tar.bz2 |
S5PC11X: OVERLAY: Added overlay feature.
- add liboverlay source.
- add overlay option in BoardConfig.mk
- add overlay renderer on libcamera
- change the mode of video0,2
Change-Id: Icd392a80c0baa7b6e608a9b0cf57abfd74ae9f01
-rw-r--r-- | BoardConfig.mk | 3 | ||||
-rw-r--r-- | device.mk | 3 | ||||
-rwxr-xr-x | include/s5p_fimc.h | 2 | ||||
-rw-r--r-- | libcamera/Android.mk | 4 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.cpp | 408 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.h | 8 | ||||
-rw-r--r-- | liboverlay/Android.mk | 37 | ||||
-rw-r--r-- | liboverlay/overlay.cpp | 1350 | ||||
-rw-r--r-- | liboverlay/v4l2_utils.c | 738 | ||||
-rw-r--r-- | liboverlay/v4l2_utils.h | 72 | ||||
-rw-r--r-- | ueventd.smdkc110.rc | 2 |
11 files changed, 2482 insertions, 145 deletions
diff --git a/BoardConfig.mk b/BoardConfig.mk index 4b1fdf9..fdd59ea 100644 --- a/BoardConfig.mk +++ b/BoardConfig.mk @@ -55,8 +55,9 @@ endif BOARD_USES_HGL := true BOARD_USES_COPYBIT := false +BOARD_USES_OVERLAY := true -DEFAULT_FB_NUM := 0 +DEFAULT_FB_NUM := 2 BOARD_NAND_PAGE_SIZE := 4096 -s 128 @@ -66,7 +66,8 @@ PRODUCT_PACKAGES := \ # Misc other modules PRODUCT_PACKAGES += \ - lights.s5pc110 + lights.s5pc110 \ + overlay.s5pc110 # Input device calibration files PRODUCT_COPY_FILES += \ diff --git a/include/s5p_fimc.h b/include/s5p_fimc.h index af42cf1..d2c760c 100755 --- a/include/s5p_fimc.h +++ b/include/s5p_fimc.h @@ -17,6 +17,8 @@ #ifndef _S5P_FIMC_H_ #define _S5P_FIMC_H_ +#include <linux/videodev2.h> + /* * G E N E R A L S * diff --git a/libcamera/Android.mk b/libcamera/Android.mk index 393ee4c..1048730 100644 --- a/libcamera/Android.mk +++ b/libcamera/Android.mk @@ -34,6 +34,10 @@ LOCAL_SHARED_LIBRARIES+= libcamera_client #LOCAL_SHARED_LIBRARIES+= libhdmi #endif +ifeq ($(BOARD_USES_OVERLAY),true) +LOCAL_CFLAGS += -DBOARD_USES_OVERLAY +endif + ifeq ($(DLOPEN_LIBSECCAMERA),1) LOCAL_SHARED_LIBRARIES+= libdl endif diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp index 5c2dc76..3c32506 100644 --- a/libcamera/SecCameraHWInterface.cpp +++ b/libcamera/SecCameraHWInterface.cpp @@ -25,6 +25,14 @@ #include <fcntl.h> #include <sys/mman.h> +#if defined(BOARD_USES_OVERLAY) +#include <hardware/overlay.h> +#include <ui/Overlay.h> +#define CACHEABLE_BUFFERS 0x1 +#define ALL_BUFFERS_FLUSHED -66 +int buf_idx = 0; +#endif + #ifdef SEND_YUV_RECORD_DATA #define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) #define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) @@ -38,6 +46,8 @@ struct ADDRS { unsigned int addr_y; unsigned int addr_cbcr; + unsigned int buf_index; + unsigned int reserved; }; struct ADDRS_CAP @@ -48,56 +58,59 @@ struct ADDRS_CAP }; CameraHardwareSec::CameraHardwareSec() - : mParameters(), - mPreviewHeap(0), - mRawHeap(0), - mRecordHeap(0), - mJpegHeap(0), - mSecCamera(NULL), - mPreviewRunning(false), - mPreviewFrameSize(0), - mRawFrameSize(0), - mPreviewFrameRateMicrosec(33000), - mNotifyCb(0), - mDataCb(0), - mDataCbTimestamp(0), - mCallbackCookie(0), - mMsgEnabled(0), - mCurrentPreviewFrame(0), - mRecordRunning(false) + : mParameters(), + mPreviewHeap(0), + mRawHeap(0), + mRecordHeap(0), + mJpegHeap(0), + mSecCamera(NULL), + mPreviewRunning(false), + mPreviewFrameSize(0), + mRawFrameSize(0), + mPreviewFrameRateMicrosec(33000), + mNotifyCb(0), + mDataCb(0), + mDataCbTimestamp(0), + mCallbackCookie(0), + mMsgEnabled(0), + mCurrentPreviewFrame(0), +#if defined(BOARD_USES_OVERLAY) + mUseOverlay(false), +#endif + mRecordRunning(false) #ifdef JPEG_FROM_SENSOR - , - mPostViewWidth(0), - mPostViewHeight(0), - mPostViewSize(0) + , + mPostViewWidth(0), + mPostViewHeight(0), + mPostViewSize(0) #endif - #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION - , - mObjectTrackingStatus(0), - mSmartautosceneRunning(false), - mSmartautoscene_current_status(0), - mSmartautoscene_previous_status(0) - #endif +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + , + mObjectTrackingStatus(0), + mSmartautosceneRunning(false), + mSmartautoscene_current_status(0), + mSmartautoscene_previous_status(0) +#endif { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); int ret = 0; mNoHwHandle = 0; mSecCamera = SecCamera::createInstance(); if(mSecCamera == NULL) { - LOGE("ERR(%s):Fail on mSecCamera object creation", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera object creation", __func__); } ret = mSecCamera->initCamera(); if(ret < 0) { - LOGE("ERR(%s):Fail on mSecCamera init", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera init", __func__); } if(mSecCamera->flagCreate() == 0) { - LOGE("ERR(%s):Fail on mSecCamera->flagCreate()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->flagCreate()", __func__); } #ifndef PREVIEW_USING_MMAP @@ -149,7 +162,7 @@ void CameraHardwareSec::initDefaultParameters() { if(mSecCamera == NULL) { - LOGE("ERR(%s):mSecCamera object is NULL", __FUNCTION__); + LOGE("ERR(%s):mSecCamera object is NULL", __func__); return; } @@ -272,13 +285,13 @@ void CameraHardwareSec::initDefaultParameters() p.set("AppShutterSound", 0); if (setParameters(p) != NO_ERROR) { - LOGE("ERR(%s):Fail on setParameters(p)", __FUNCTION__); + LOGE("ERR(%s):Fail on setParameters(p)", __func__); } } CameraHardwareSec::~CameraHardwareSec() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); mSecCamera->DeinitCamera(); @@ -349,7 +362,7 @@ int CameraHardwareSec::previewThread() index = mSecCamera->getPreview(); if(index < 0) { - LOGE("ERR(%s):Fail on SecCamera->getPreview()", __FUNCTION__); + LOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__); return UNKNOWN_ERROR; } @@ -359,24 +372,57 @@ int CameraHardwareSec::previewThread() int width, height, frame_size, offset; mSecCamera->getPreviewSize(&width, &height, &frame_size); - offset = (frame_size+8)*index; + offset = (frame_size+16)*index; sp<MemoryBase> buffer = new MemoryBase(mPreviewHeap, offset, frame_size); unsigned int phyYAddr = mSecCamera->getPhyAddrY(index); unsigned int phyCAddr = mSecCamera->getPhyAddrC(index); if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) { - LOGE("ERR(%s):Fail on SecCamera. Invalid PhyAddr, Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + LOGE("ERR(%s):Fail on SecCamera. Invalid PhyAddr, Y addr = %0x C addr = %0x", __func__, phyYAddr, phyCAddr); return UNKNOWN_ERROR; } memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset+frame_size ), &phyYAddr, 4); memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset+frame_size+4), &phyCAddr, 4); + +#if defined(BOARD_USES_OVERLAY) + if(mUseOverlay) { + int ret; + + if ( buf_idx == 0 ) + buf_idx = 1; + else + buf_idx = 0; + + memcpy(static_cast<unsigned char*>(mPreviewHeap->base()) + (offset+frame_size) + sizeof(phyYAddr) + sizeof(phyCAddr), &buf_idx, sizeof(buf_idx)); + + ret = mOverlay->queueBuffer((void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset+frame_size))); + + if (ret == ALL_BUFFERS_FLUSHED) { + goto OverlayEnd; + } else if (ret == -1) { + LOGE("ERR(%s):overlay queueBuffer fail", __func__); + goto OverlayEnd; + } + + overlay_buffer_t overlay_buffer; + ret = mOverlay->dequeueBuffer(&overlay_buffer); + if (ret == -1) { + LOGE("ERR(%s):overlay dequeueBuffer fail", __func__); + goto OverlayEnd; + } + + } + +OverlayEnd: +#endif + #else unsigned int phyYAddr = mSecCamera->getPhyAddrY(index); unsigned int phyCAddr = mSecCamera->getPhyAddrC(index); if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) { - LOGE("ERR(%s):Fail on SecCamera getPhyAddr Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + LOGE("ERR(%s):Fail on SecCamera getPhyAddr Y addr = %0x C addr = %0x", __func__, phyYAddr, phyCAddr); return UNKNOWN_ERROR; } struct ADDRS *addrs = (struct ADDRS *)mPreviewHeap->base(); @@ -411,14 +457,14 @@ int CameraHardwareSec::previewThread() int index = mSecCamera->getRecord(); if(index < 0) { - LOGE("ERR(%s):Fail on SecCamera->getRecord()", __FUNCTION__); + LOGE("ERR(%s):Fail on SecCamera->getRecord()", __func__); return UNKNOWN_ERROR; } unsigned int phyYAddr = mSecCamera->getRecPhyAddrY(index); unsigned int phyCAddr = mSecCamera->getRecPhyAddrC(index); if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) { - LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __func__, phyYAddr, phyCAddr); return UNKNOWN_ERROR; } #endif//DUAL_PORT_RECORDING @@ -440,7 +486,7 @@ int CameraHardwareSec::previewThread() { if(mSecCamera->stopRecord() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __func__); return UNKNOWN_ERROR; } } @@ -470,7 +516,7 @@ status_t CameraHardwareSec::startPreview() { int ret = 0; //s1 [Apply factory standard] - LOGE("%s()", __FUNCTION__); + LOGE("%s()", __func__); Mutex::Autolock lock(mLock); if (mPreviewThread != 0) { @@ -485,14 +531,14 @@ status_t CameraHardwareSec::startPreview() #if 1 //s1 [Apply factory standard] ret = mSecCamera->startPreview(); - LOGE("%s : return startPreview %d", __FUNCTION__, ret); + LOGE("%s : return startPreview %d", __func__, ret); if(ret < 0) #else if(mSecCamera->startPreview() < 0) #endif { - LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__); if (mMsgEnabled & CAMERA_MSG_ERROR) { mNotifyCb(CAMERA_MSG_ERROR, -2, 0, mCallbackCookie); @@ -505,9 +551,9 @@ status_t CameraHardwareSec::startPreview() mPreviewHeap.clear(); int width, height, frame_size; mSecCamera->getPreviewSize(&width, &height, &frame_size); - int previewHeapSize = (frame_size+8) * kBufferCount; + int previewHeapSize = (frame_size+16) * kBufferCount; LOGD("MemoryHeapBase(fd(%d), size(%d), width(%d), height(%d))", (int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), width, height); - mPreviewHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), (uint32_t)0); + mPreviewHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), (uint32_t)0); #endif #ifdef JPEG_FROM_SENSOR @@ -544,9 +590,68 @@ status_t CameraHardwareSec::startPreview() return NO_ERROR; } +#if defined(BOARD_USES_OVERLAY) +bool CameraHardwareSec::useOverlay() +{ + return true; +} + +status_t CameraHardwareSec::setOverlay(const sp<Overlay> &overlay) +{ + LOGV("%s() : ", __func__); + + int overlayWidth = 0; + int overlayHeight = 0; + int overlayFrameSize = 0; + + if(overlay == NULL) { + goto setOverlayFail; + } + + if(overlay->getHandleRef()== NULL && mUseOverlay == true) { + if(mOverlay != 0) + mOverlay->destroy(); + mOverlay = NULL; + mUseOverlay = false; + + return NO_ERROR; + } + + if(overlay->getStatus() != NO_ERROR) + { + LOGE("ERR(%s):overlay->getStatus() fail", __func__); + goto setOverlayFail; + } + + mSecCamera->getPreviewSize(&overlayWidth, &overlayHeight, &overlayFrameSize); + + if(overlay->setCrop(0, 0, overlayWidth, overlayHeight) != NO_ERROR) + { + LOGE("ERR(%s)::(mOverlay->setCrop(0, 0, %d, %d) fail", __func__, overlayWidth, overlayHeight); + goto setOverlayFail; + } + + mOverlay = overlay; + mUseOverlay = true; + + return NO_ERROR; + +setOverlayFail : + + if(mOverlay != 0) + mOverlay->destroy(); + mOverlay = 0; + + mUseOverlay = false; + + return UNKNOWN_ERROR; + +} +#endif + void CameraHardwareSec::stopPreview() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); sp<PreviewThread> previewThread; @@ -566,14 +671,23 @@ void CameraHardwareSec::stopPreview() if(!mNoHwHandle) if(mSecCamera->stopPreview() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->stopPreview()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->stopPreview()", __func__); } mPreviewRunning = false; + +#if defined(BOARD_USES_OVERLAY) + if(mUseOverlay) { + mOverlay->destroy(); + mUseOverlay = false; + mOverlay = NULL; + } +#endif + } bool CameraHardwareSec::previewEnabled() { - LOGV("%s() : %d", __FUNCTION__, mPreviewThread != 0); + LOGV("%s() : %d", __func__, mPreviewThread != 0); return mPreviewThread != 0; } @@ -581,12 +695,12 @@ bool CameraHardwareSec::previewEnabled() { status_t CameraHardwareSec::startRecording() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); #ifdef DUAL_PORT_RECORDING if(mSecCamera->startRecord() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__); return UNKNOWN_ERROR; } #endif @@ -597,21 +711,21 @@ status_t CameraHardwareSec::startRecording() void CameraHardwareSec::stopRecording() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); mRecordRunning = false; } bool CameraHardwareSec::recordingEnabled() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); return mRecordRunning; } void CameraHardwareSec::releaseRecordingFrame(const sp<IMemory>& mem) { - LOG_CAMERA_PREVIEW("%s()", __FUNCTION__); + LOG_CAMERA_PREVIEW("%s()", __func__); // ssize_t offset; size_t size; // sp<MemoryBase> mem1 = mem; @@ -632,7 +746,7 @@ int CameraHardwareSec::smartautosceneThread() if(mSmartautoscene_current_status < 0) { - LOGE("ERR(%s):Fail on mSecCamera->getAutosceneStatus()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->getAutosceneStatus()", __func__); return UNKNOWN_ERROR; } @@ -640,12 +754,12 @@ int CameraHardwareSec::smartautosceneThread() { //if (mMsgEnabled & CAMERA_MSG_SMARTAUTO_SCENE_STATUS) //mNotifyCb(CAMERA_MSG_SMARTAUTO_SCENE_STATUS, mSmartautoscene_current_status, 0, mCallbackCookie); - LOGE("%s CAMERA_MSG_SMARTAUTO_SCENE_STATUS(%d) Callback!!!!!!!! ", __FUNCTION__,mSmartautoscene_current_status); + LOGE("%s CAMERA_MSG_SMARTAUTO_SCENE_STATUS(%d) Callback!!!!!!!! ", __func__,mSmartautoscene_current_status); mSmartautoscene_previous_status = mSmartautoscene_current_status; } else { - LOGE("%s current_status(%d) is same with previous_status(%d)", __FUNCTION__,mSmartautoscene_current_status,mSmartautoscene_previous_status); + LOGE("%s current_status(%d) is same with previous_status(%d)", __func__,mSmartautoscene_current_status,mSmartautoscene_previous_status); } usleep(2000*1000); //2000ms delay LOGE("DELAY(2000ms)!!!!!!!"); @@ -654,7 +768,7 @@ int CameraHardwareSec::smartautosceneThread() status_t CameraHardwareSec::startSmartautoscene() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); // Mutex::Autolock lock(mLock); @@ -670,7 +784,7 @@ status_t CameraHardwareSec::startSmartautoscene() void CameraHardwareSec::stopSmartautoscene() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); sp<SmartautosceneThread> smartautosceneThread; @@ -691,7 +805,7 @@ void CameraHardwareSec::stopSmartautoscene() } bool CameraHardwareSec::smartautosceneEnabled() { - LOGV("%s() : %d", __FUNCTION__, mSmartautosceneThread != 0); + LOGV("%s() : %d", __func__, mSmartautosceneThread != 0); return mSmartautosceneThread != 0; } @@ -700,7 +814,7 @@ bool CameraHardwareSec::smartautosceneEnabled() { int CameraHardwareSec::beginAutoFocusThread(void *cookie) { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); CameraHardwareSec *c = (CameraHardwareSec *)cookie; return c->autoFocusThread(); } @@ -712,11 +826,11 @@ int CameraHardwareSec::autoFocusThread() int af_status =0 ; #endif - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); // usleep(50000); // 1frame delay 50ms if(mSecCamera->setAutofocus() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__); return UNKNOWN_ERROR; } @@ -726,19 +840,19 @@ int CameraHardwareSec::autoFocusThread() if (af_status == 0x01) { - LOGV("%s() AF Success!!", __FUNCTION__); + LOGV("%s() AF Success!!", __func__); if (mMsgEnabled & CAMERA_MSG_FOCUS) mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); } else if (af_status == 0x02) { - LOGV("%s() AF Cancelled !!", __FUNCTION__); + LOGV("%s() AF Cancelled !!", __func__); if (mMsgEnabled & CAMERA_MSG_FOCUS) mNotifyCb(CAMERA_MSG_FOCUS, 0x02, 0, mCallbackCookie); } else { - LOGV("%s() AF Fail !!", __FUNCTION__); + LOGV("%s() AF Fail !!", __func__); if (mMsgEnabled & CAMERA_MSG_FOCUS) mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); } @@ -751,7 +865,7 @@ int CameraHardwareSec::autoFocusThread() status_t CameraHardwareSec::autoFocus() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); Mutex::Autolock lock(mLock); if (createThread(beginAutoFocusThread, this) == false) return UNKNOWN_ERROR; @@ -762,11 +876,11 @@ status_t CameraHardwareSec::autoFocus() status_t CameraHardwareSec::cancelAutoFocus() { #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); if(mSecCamera->cancelAutofocus() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __func__); return UNKNOWN_ERROR; } #endif @@ -776,7 +890,7 @@ status_t CameraHardwareSec::cancelAutoFocus() #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION status_t CameraHardwareSec::objectTracking(int onoff) { - LOGV("%s() onoff = %d", __FUNCTION__, onoff); + LOGV("%s() onoff = %d", __func__, onoff); Mutex::Autolock lock(mLock); if(onoff) @@ -854,7 +968,7 @@ int CameraHardwareSec::objectTrackingThread() #endif /*static*/ int CameraHardwareSec::beginPictureThread(void *cookie) { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); CameraHardwareSec *c = (CameraHardwareSec *)cookie; return c->pictureThread(); } @@ -889,7 +1003,7 @@ void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t int CameraHardwareSec::pictureThread() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); int jpeg_size = 0; int ret = NO_ERROR; @@ -905,7 +1019,7 @@ int CameraHardwareSec::pictureThread() mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); int postviewHeapSize = mPostViewWidth*mPostViewHeight*2; //*size = (BACK_CAMERA_POSTVIEW_WIDTH * BACK_CAMERA_POSTVIEW_HEIGHT * BACK_CAMERA_POSTVIEW_BPP)/8; mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); - LOGE("[kidggang]:func(%s):line(%d)&cap_width(%d), &cap_height(%d), &cap_frame_size(%d)\n",__FUNCTION__,__LINE__,cap_width, cap_height, cap_frame_size); + LOGE("[kidggang]:func(%s):line(%d)&cap_width(%d), &cap_height(%d), &cap_frame_size(%d)\n",__func__,__LINE__,cap_width, cap_height, cap_frame_size); // sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, postviewHeapSize); @@ -962,7 +1076,7 @@ int CameraHardwareSec::pictureThread() jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr); if(jpeg_data == NULL) { - LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __FUNCTION__); + LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __func__); ret = UNKNOWN_ERROR; } }//[zzangdol] CAMERA_ID_BACK @@ -1052,7 +1166,7 @@ int CameraHardwareSec::pictureThread() status_t CameraHardwareSec::takePicture() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); stopPreview(); mNoHwHandle = 0; @@ -1180,7 +1294,7 @@ status_t CameraHardwareSec::dump(int fd, const Vector<String16>& args) const status_t CameraHardwareSec::setParameters(const CameraParameters& params) { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); Mutex::Autolock lock(mLock); @@ -1194,7 +1308,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setCameraId(new_camera_id) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setCameraId(camera_id(%d))", __FUNCTION__, new_camera_id); + LOGE("ERR(%s):Fail on mSecCamera->setCameraId(camera_id(%d))", __func__, new_camera_id); ret = UNKNOWN_ERROR; } } @@ -1225,9 +1339,17 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) if(mSecCamera->setPreviewSize(new_preview_width, new_preview_height, new_preview_format) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))", __FUNCTION__, new_preview_width, new_preview_height, new_preview_format); + LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))", __func__, new_preview_width, new_preview_height, new_preview_format); ret = UNKNOWN_ERROR; } +#if defined(BOARD_USES_OVERLAY) + if(mUseOverlay == true && mOverlay != 0) + { + if(mOverlay->setCrop(0, 0, new_preview_width, new_preview_height) != NO_ERROR) { + LOGE("ERR(%s)::(mOverlay->setCrop(0, 0, %d, %d) fail", __func__, new_preview_width, new_preview_height); + } + } +#endif } int new_picture_width = 0; @@ -1237,7 +1359,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))", __FUNCTION__, new_picture_width, new_picture_height); + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))", __func__, new_picture_width, new_picture_height); ret = UNKNOWN_ERROR; } } @@ -1275,7 +1397,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) if(mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __FUNCTION__, new_picture_format); + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __func__, new_picture_format); ret = UNKNOWN_ERROR; } } @@ -1285,7 +1407,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) int new_jpeg_quality = params.getInt("jpeg-quality"); if (new_jpeg_quality < 1 || new_jpeg_quality > 100) { - LOGE("ERR(%s): Invalid quality(%d))", __FUNCTION__, new_jpeg_quality); + LOGE("ERR(%s): Invalid quality(%d))", __func__, new_jpeg_quality); new_jpeg_quality = 100; @@ -1313,7 +1435,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __FUNCTION__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height); + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __func__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height); ret = UNKNOWN_ERROR; } } @@ -1339,7 +1461,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setVTmode(new_vtmode) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setVTMode(%d)", __FUNCTION__, new_vtmode); + LOGE("ERR(%s):Fail on mSecCamera->setVTMode(%d)", __func__, new_vtmode); ret = UNKNOWN_ERROR; } } @@ -1351,11 +1473,11 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(new_vtmode == SecCamera::VT_MODE_ON ) // vt preview rotation { - LOGE("ERR(%s):VT mode is on. Rotate(%d))", __FUNCTION__, new_rotation); + LOGE("ERR(%s):VT mode is on. Rotate(%d))", __func__, new_rotation); if(mSecCamera->SetRotate(new_rotation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __FUNCTION__, new_rotation); + LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __func__, new_rotation); ret = UNKNOWN_ERROR; } } @@ -1363,7 +1485,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->SetRotate(0) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __FUNCTION__, new_rotation); + LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __func__, new_rotation); ret = UNKNOWN_ERROR; } @@ -1391,7 +1513,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setBrightness(new_exposure_compensation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __FUNCTION__, new_exposure_compensation); + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_exposure_compensation); ret = UNKNOWN_ERROR; } @@ -1419,7 +1541,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_white = SecCamera::WHITE_BALANCE_SUNNY; else { - LOGE("ERR(%s):Invalid white balance(%s)", __FUNCTION__, new_white_str); + LOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); ret = UNKNOWN_ERROR; } @@ -1428,7 +1550,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) // white_balance if(mSecCamera->setWhiteBalance(new_white) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __FUNCTION__, new_white); + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white); ret = UNKNOWN_ERROR; } } @@ -1454,7 +1576,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_image_effect = SecCamera::IMAGE_EFFECT_SILHOUETTE; else { - LOGE("ERR(%s):Invalid effect(%s)", __FUNCTION__, new_image_effect_str); + LOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str); ret = UNKNOWN_ERROR; } @@ -1463,7 +1585,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) // white_balance if(mSecCamera->setImageEffect(new_image_effect) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __FUNCTION__, new_image_effect); + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect); ret = UNKNOWN_ERROR; } } @@ -1473,7 +1595,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) // scene mode const char * new_scene_mode_str = params.get("scene-mode"); - LOGV("%s() new_scene_mode_str %s", __FUNCTION__,new_scene_mode_str); + LOGV("%s() new_scene_mode_str %s", __func__,new_scene_mode_str); if(new_scene_mode_str != NULL) { @@ -1675,7 +1797,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) } else { - LOGE("%s::unmatched scene_mode(%s)", __FUNCTION__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto + LOGE("%s::unmatched scene_mode(%s)", __func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto ret = UNKNOWN_ERROR; } @@ -1715,14 +1837,14 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_iso = SecCamera::ISO_MOVIE; else { - LOGE("%s::unmatched iso(%d)", __FUNCTION__, new_iso); + LOGE("%s::unmatched iso(%d)", __func__, new_iso); ret = UNKNOWN_ERROR; } if(0 <= new_iso) { if(mSecCamera->setISO(new_iso) < 0) { - LOGE("%s::mSecCamera->setISO(%d) fail", __FUNCTION__, new_iso); + LOGE("%s::mSecCamera->setISO(%d) fail", __func__, new_iso); ret = UNKNOWN_ERROR; } } @@ -1740,14 +1862,14 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_metering = SecCamera::METERING_SPOT; else { - LOGE("%s::unmatched metering(%s)", __FUNCTION__, new_metering_str); + LOGE("%s::unmatched metering(%s)", __func__, new_metering_str); ret = UNKNOWN_ERROR; } if(0 <= new_metering) { if(mSecCamera->setMetering(new_metering) < 0) { - LOGE("%s::mSecCamera->setMetering(%d) fail", __FUNCTION__, new_metering); + LOGE("%s::mSecCamera->setMetering(%d) fail", __func__, new_metering); ret = UNKNOWN_ERROR; } } @@ -1762,7 +1884,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setBrightness(new_exposure_compensation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __FUNCTION__, new_exposure_compensation); + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_exposure_compensation); ret = UNKNOWN_ERROR; } @@ -1785,7 +1907,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_white = SecCamera::WHITE_BALANCE_INCANDESCENT; else { - LOGE("ERR(%s):Invalid white balance(%s)", __FUNCTION__, new_white_str); //twilight, shade, warm_flourescent + LOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); //twilight, shade, warm_flourescent ret = UNKNOWN_ERROR; } @@ -1794,7 +1916,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) // white_balance if(mSecCamera->setWhiteBalance(new_white) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __FUNCTION__, new_white); + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white); ret = UNKNOWN_ERROR; } } @@ -1805,7 +1927,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSharpness(new_sharpness) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSharpness(%d)", __FUNCTION__,new_sharpness); + LOGE("ERR(%s):Fail on mSecCamera->setSharpness(%d)", __func__,new_sharpness); ret = UNKNOWN_ERROR; } } @@ -1815,7 +1937,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSaturation(new_saturation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSaturation(%d)", __FUNCTION__, new_saturation); + LOGE("ERR(%s):Fail on mSecCamera->setSaturation(%d)", __func__, new_saturation); ret = UNKNOWN_ERROR; } } @@ -1833,7 +1955,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_focus_mode = SecCamera::FOCUS_MODE_FACEDETECT; else { - LOGE("%s::unmatched focus_mode(%s)", __FUNCTION__, new_focus_mode_str); //infinity + LOGE("%s::unmatched focus_mode(%s)", __func__, new_focus_mode_str); //infinity ret = UNKNOWN_ERROR; } @@ -1841,7 +1963,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setFocusMode(new_focus_mode) < 0) { - LOGE("%s::mSecCamera->setFocusMode(%d) fail", __FUNCTION__, new_focus_mode); + LOGE("%s::mSecCamera->setFocusMode(%d) fail", __func__, new_focus_mode); ret = UNKNOWN_ERROR; } } @@ -1861,14 +1983,14 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_flash_mode = SecCamera::FLASH_MODE_TORCH; else { - LOGE("%s::unmatched flash_mode(%s)", __FUNCTION__, new_flash_mode_str); //red-eye + LOGE("%s::unmatched flash_mode(%s)", __func__, new_flash_mode_str); //red-eye ret = UNKNOWN_ERROR; } if(0 <= new_flash_mode) { if(mSecCamera->setFlashMode(new_flash_mode) < 0) { - LOGE("%s::mSecCamera->setFlashMode(%d) fail", __FUNCTION__, new_flash_mode); + LOGE("%s::mSecCamera->setFlashMode(%d) fail", __func__, new_flash_mode); ret = UNKNOWN_ERROR; } } @@ -1879,7 +2001,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSceneMode(new_scene_mode) < 0) { - LOGE("%s::mSecCamera->setSceneMode(%d) fail", __FUNCTION__, new_scene_mode); + LOGE("%s::mSecCamera->setSceneMode(%d) fail", __func__, new_scene_mode); ret = UNKNOWN_ERROR; } } @@ -1909,7 +2031,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_image_effect = SecCamera::IMAGE_EFFECT_SHARPEN; else { - LOGE("ERR(%s):Invalid effect(%s)", __FUNCTION__, new_image_effect_str); //posterize, whiteboard, blackboard, solarize + LOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str); //posterize, whiteboard, blackboard, solarize ret = UNKNOWN_ERROR; } @@ -1917,7 +2039,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setImageEffect(new_image_effect) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __FUNCTION__, new_image_effect); + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect); ret = UNKNOWN_ERROR; } } @@ -1939,7 +2061,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_antibanding = SecCamera::ANTI_BANDING_OFF; else { - LOGE("%s::unmatched antibanding(%s)", __FUNCTION__, new_antibanding_str); + LOGE("%s::unmatched antibanding(%s)", __func__, new_antibanding_str); ret = UNKNOWN_ERROR; } @@ -1947,7 +2069,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setAntiBanding(new_antibanding) < 0) { - LOGE("%s::mSecCamera->setAntiBanding(%d) fail", __FUNCTION__, new_antibanding); + LOGE("%s::mSecCamera->setAntiBanding(%d) fail", __func__, new_antibanding); ret = UNKNOWN_ERROR; } } @@ -1960,7 +2082,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setContrast(new_contrast) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setContrast(%d)", __FUNCTION__, new_contrast); + LOGE("ERR(%s):Fail on mSecCamera->setContrast(%d)", __func__, new_contrast); ret = UNKNOWN_ERROR; } } @@ -1971,7 +2093,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setWDR(new_wdr) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __FUNCTION__, new_wdr); + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_wdr); ret = UNKNOWN_ERROR; } } @@ -1982,7 +2104,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setAntiShake(new_anti_shake) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __FUNCTION__, new_anti_shake); + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_anti_shake); ret = UNKNOWN_ERROR; } } @@ -1993,7 +2115,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setZoom(new_zoom_level) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setZoom(%d)", __FUNCTION__, new_zoom_level); + LOGE("ERR(%s):Fail on mSecCamera->setZoom(%d)", __func__, new_zoom_level); ret = UNKNOWN_ERROR; } } @@ -2004,7 +2126,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setObjectTracking(new_obj_tracking) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setObjectTracking(%d)", __FUNCTION__, new_obj_tracking); + LOGE("ERR(%s):Fail on mSecCamera->setObjectTracking(%d)", __func__, new_obj_tracking); ret = UNKNOWN_ERROR; } } @@ -2015,7 +2137,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSmartAuto(new_smart_auto) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSmartAuto(%d)", __FUNCTION__, new_smart_auto); + LOGE("ERR(%s):Fail on mSecCamera->setSmartAuto(%d)", __func__, new_smart_auto); ret = UNKNOWN_ERROR; } @@ -2048,7 +2170,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setBeautyShot(new_beauty_shot) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setBeautyShot(%d)", __FUNCTION__, new_beauty_shot); + LOGE("ERR(%s):Fail on mSecCamera->setBeautyShot(%d)", __func__, new_beauty_shot); ret = UNKNOWN_ERROR; } } @@ -2071,7 +2193,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_vintage_mode = SecCamera::VINTAGE_MODE_BNW; else { - LOGE("%s::unmatched vintage_mode(%d)", __FUNCTION__, new_vintage_mode); + LOGE("%s::unmatched vintage_mode(%d)", __func__, new_vintage_mode); ret = UNKNOWN_ERROR; } @@ -2079,7 +2201,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setVintageMode(new_vintage_mode) < 0) { - LOGE("%s::mSecCamera->setVintageMode(%d) fail", __FUNCTION__, new_vintage_mode); + LOGE("%s::mSecCamera->setVintageMode(%d) fail", __func__, new_vintage_mode); ret = UNKNOWN_ERROR; } } @@ -2089,7 +2211,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) const char * new_gps_latitude_str = params.get("gps-latitude"); if(mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) { - LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __FUNCTION__, new_gps_latitude_str); + LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __func__, new_gps_latitude_str); ret = UNKNOWN_ERROR; } @@ -2097,7 +2219,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) const char * new_gps_longitute_str = params.get("gps-longitude"); if(mSecCamera->setGPSLongitude(new_gps_longitute_str) < 0) { - LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __FUNCTION__, new_gps_longitute_str); + LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __func__, new_gps_longitute_str); ret = UNKNOWN_ERROR; } @@ -2105,7 +2227,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) const char * new_gps_altitude_str = params.get("gps-altitude"); if(mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) { - LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __FUNCTION__, new_gps_altitude_str); + LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __func__, new_gps_altitude_str); ret = UNKNOWN_ERROR; } @@ -2113,7 +2235,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) const char * new_gps_timestamp_str = params.get("gps-timestamp"); if(mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) { - LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __FUNCTION__, new_gps_timestamp_str); + LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __func__, new_gps_timestamp_str); ret = UNKNOWN_ERROR; } @@ -2123,14 +2245,14 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) if(0 < new_recording_width && 0 < new_recording_height) { if(mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __FUNCTION__, new_recording_width, new_recording_height); + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __func__, new_recording_width, new_recording_height); ret = UNKNOWN_ERROR; } } else { if(mSecCamera->setRecordingSize(new_preview_width, new_preview_height) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __FUNCTION__, new_preview_width, new_preview_height); + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __func__, new_preview_width, new_preview_height); ret = UNKNOWN_ERROR; } } @@ -2147,7 +2269,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_gamma = SecCamera::GAMMA_ON; else { - LOGE("%s::unmatched gamma(%s)", __FUNCTION__, new_gamma_str); + LOGE("%s::unmatched gamma(%s)", __func__, new_gamma_str); ret = UNKNOWN_ERROR; } @@ -2155,7 +2277,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setGamma(new_gamma) < 0) { - LOGE("%s::mSecCamera->setGamma(%d) fail", __FUNCTION__, new_gamma); + LOGE("%s::mSecCamera->setGamma(%d) fail", __func__, new_gamma); ret = UNKNOWN_ERROR; } } @@ -2173,7 +2295,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_slow_ae = SecCamera::SLOW_AE_ON; else { - LOGE("%s::unmatched slow_ae(%s)", __FUNCTION__, new_slow_ae_str); + LOGE("%s::unmatched slow_ae(%s)", __func__, new_slow_ae_str); ret = UNKNOWN_ERROR; } @@ -2181,7 +2303,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSlowAE(new_slow_ae) < 0) { - LOGE("%s::mSecCamera->setSlowAE(%d) fail", __FUNCTION__, new_slow_ae); + LOGE("%s::mSecCamera->setSlowAE(%d) fail", __func__, new_slow_ae); ret = UNKNOWN_ERROR; } } @@ -2193,7 +2315,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setExifOrientationInfo(new_exif_orientation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __FUNCTION__, new_exif_orientation); + LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_exif_orientation); ret = UNKNOWN_ERROR; } } @@ -2204,7 +2326,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setSensorMode(new_sensor_mode) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __FUNCTION__, new_sensor_mode); + LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __func__, new_sensor_mode); ret = UNKNOWN_ERROR; } } @@ -2219,7 +2341,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setShotMode(new_shot_mode) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __FUNCTION__, new_shot_mode); + LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __func__, new_shot_mode); ret = UNKNOWN_ERROR; } } @@ -2234,7 +2356,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setBlur(new_blur_level) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setBlur(%d)", __FUNCTION__, new_blur_level); + LOGE("ERR(%s):Fail on mSecCamera->setBlur(%d)", __func__, new_blur_level); ret = UNKNOWN_ERROR; } } @@ -2246,7 +2368,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setDataLineCheck(new_dataline) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __FUNCTION__, new_dataline); + LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __func__, new_dataline); ret = UNKNOWN_ERROR; } } @@ -2256,7 +2378,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) { if(mSecCamera->setBatchReflection() < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setBatchCmd", __FUNCTION__); + LOGE("ERR(%s):Fail on mSecCamera->setBatchCmd", __func__); ret = UNKNOWN_ERROR; } } @@ -2267,7 +2389,7 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) CameraParameters CameraHardwareSec::getParameters() const { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); Mutex::Autolock lock(mLock); return mParameters; } @@ -2275,7 +2397,7 @@ CameraParameters CameraHardwareSec::getParameters() const status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2) { #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION - LOGV("%s() : command = %d, arg1 =%d, arg2= %d", __FUNCTION__,command, arg1, arg2); + LOGV("%s() : command = %d, arg1 =%d, arg2= %d", __func__,command, arg1, arg2); switch(command) { case COMMAND_AE_AWB_LOCK_UNLOCK: @@ -2307,7 +2429,7 @@ status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t a mSecCamera->setDefultIMEI(arg1); break; defualt: - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); break; } @@ -2319,14 +2441,14 @@ status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t a void CameraHardwareSec::release() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); } wp<CameraHardwareInterface> CameraHardwareSec::singleton; sp<CameraHardwareInterface> CameraHardwareSec::createInstance() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); if (singleton != 0) { sp<CameraHardwareInterface> hardware = singleton.promote(); if (hardware != 0) { @@ -2340,7 +2462,7 @@ sp<CameraHardwareInterface> CameraHardwareSec::createInstance() #if 0 extern "C" sp<CameraHardwareInterface> openCameraHardware() { - LOGV("%s()", __FUNCTION__); + LOGV("%s()", __func__); return CameraHardwareSec::createInstance(); } #endif diff --git a/libcamera/SecCameraHWInterface.h b/libcamera/SecCameraHWInterface.h index 9e4fb79..4cf446c 100644 --- a/libcamera/SecCameraHWInterface.h +++ b/libcamera/SecCameraHWInterface.h @@ -42,6 +42,10 @@ public: virtual bool msgTypeEnabled(int32_t msgType); virtual status_t startPreview(); +#if defined(BOARD_USES_OVERLAY) + virtual bool useOverlay(); + virtual status_t setOverlay(const sp<Overlay> &overlay); +#endif virtual void stopPreview(); virtual bool previewEnabled(); @@ -175,6 +179,10 @@ private: int mRawFrameSize; int mPreviewFrameRateMicrosec; +#if defined(BOARD_USES_OVERLAY) + sp<Overlay> mOverlay; + bool mUseOverlay; +#endif // protected by mLock sp<PreviewThread> mPreviewThread; diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk new file mode 100644 index 0000000..694eaa8 --- /dev/null +++ b/liboverlay/Android.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(BOARD_USES_OVERLAY),true) + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation, not prelinked and stored in +# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils + +LOCAL_CFLAGS += -DSLSI_S5PC110 + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := v4l2_utils.c overlay.cpp + +LOCAL_MODULE := overlay.$(TARGET_BOARD_PLATFORM) +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) + +endif diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp new file mode 100644 index 0000000..1278bd4 --- /dev/null +++ b/liboverlay/overlay.cpp @@ -0,0 +1,1350 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*#define LOG_NDEBUG 0*/ +#define LOG_TAG "SEC_Overlay" + +#include <hardware/hardware.h> +#include <hardware/overlay.h> + +extern "C" { +#include "v4l2_utils.h" +} + +#include <pthread.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> +#include <linux/videodev.h> + +#include <cutils/log.h> +#include <cutils/ashmem.h> +#include <cutils/atomic.h> + +#include "linux/fb.h" + +/*****************************************************************************/ + +#define LOG_FUNCTION_NAME LOGV(" %s %s", __FILE__, __func__) + +#define NUM_OVERLAY_BUFFERS_REQUESTED (2) +/* OVRLYSHM on phone keypad*/ +#define SHARED_DATA_MARKER (0x68759746) + +/* These values should come from Surface Flinger */ +unsigned int g_lcd_width = 480; +unsigned int g_lcd_height = 800; + +#define CACHEABLE_BUFFERS 0x1 + +/* shared with Camera/Video Playback HAL */ +#define ALL_BUFFERS_FLUSHED -66 + +uint32_t phyAddr; +s5p_fimc_t g_s5p_fimc; + +typedef struct +{ + uint32_t posX; + uint32_t posY; + uint32_t posW; + uint32_t posH; + uint32_t rotation; + + uint32_t posX_org; + uint32_t posY_org; + uint32_t posW_org; + uint32_t posH_org; + +} overlay_ctrl_t; + +typedef struct +{ + uint32_t cropX; + uint32_t cropY; + uint32_t cropW; + uint32_t cropH; +} overlay_data_t; + +typedef struct +{ + uint32_t marker; + uint32_t size; + + volatile int32_t refCnt; + + uint32_t controlReady; /* Only updated by the control side */ + uint32_t dataReady; /* Only updated by the data side */ + + pthread_mutex_t lock; + + uint32_t streamEn; + uint32_t streamingReset; + + uint32_t dispW; + uint32_t dispH; + +} overlay_shared_t; + +/* Only one instance is created per platform */ +struct overlay_control_context_t { + struct overlay_control_device_t device; + /* our private state goes below here */ + struct overlay_t* overlay_video1; + struct overlay_t* overlay_video2; +}; + +/* A separate instance is created per overlay data side user*/ +struct overlay_data_context_t { + struct overlay_data_device_t device; + /* our private state goes below here */ + int ctl_fd; + int shared_fd; + int shared_size; + int width; + int height; + int format; + int num_buffers; + size_t *buffers_len; + void **buffers; + + overlay_data_t data; + overlay_shared_t *shared; + struct mapping_data *mapping_data; + /* Need to count Qd buffers + to be sure we don't block DQ'ing when exiting */ + int qd_buf_count; + int cacheable_buffers; + + bool zerocopy; +}; + +static int create_shared_data(overlay_shared_t **shared); +static void destroy_shared_data(int shared_fd, overlay_shared_t *shared, + bool closefd); +static int open_shared_data(overlay_data_context_t *ctx); +static void close_shared_data(overlay_data_context_t *ctx); +enum { LOCK_REQUIRED = 1, NO_LOCK_NEEDED = 0 }; +static int enable_streaming(overlay_shared_t *shared, int ovly_fd, + int lock_required ); + +static int overlay_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device); + +static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc, + unsigned int rotation); +static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc); + +static struct hw_module_methods_t overlay_module_methods = { +open: overlay_device_open +}; + +struct overlay_module_t HAL_MODULE_INFO_SYM = { +common: { +tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: OVERLAY_HARDWARE_MODULE_ID, + name: "SEC Overlay module", + author: "The Android Open Source Project", + methods: &overlay_module_methods, + } +}; + +/*****************************************************************************/ + +/* + * This is the overlay_t object, it is returned to the user and represents + * an overlay. here we use a subclass, where we can store our own state. + * This handles will be passed across processes and possibly given to other + * HAL modules (for instance video decode modules). + */ +struct handle_t : public native_handle { + /* add the data fields we need here, for instance: */ + int ctl_fd; + int shared_fd; + int width; + int height; + int format; + int num_buffers; + int shared_size; +}; + +static int handle_format(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->format; +} + +static int handle_ctl_fd(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->ctl_fd; +} + +static int handle_shared_fd(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->shared_fd; +} + +static int handle_num_buffers(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->num_buffers; +} + +static int handle_width(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->width; +} + +static int handle_height(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->height; +} + +static int handle_shared_size(const overlay_handle_t overlay) { + return static_cast<const struct handle_t *>(overlay)->shared_size; +} + +/* A separate instance of this class is created per overlay */ +class overlay_object : public overlay_t +{ + handle_t mHandle; + + overlay_ctrl_t mCtl; + overlay_ctrl_t mCtlStage; + overlay_shared_t *mShared; + + static overlay_handle_t getHandleRef(struct overlay_t* overlay) { + /* returns a reference to the handle, caller doesn't take ownership */ + return &(static_cast<overlay_object *>(overlay)->mHandle); + } + + public: + overlay_object(int ctl_fd, int shared_fd, int shared_size, int w, int h, + int format, int num_buffers) { + this->overlay_t::getHandleRef = getHandleRef; + mHandle.version = sizeof(native_handle); + mHandle.numFds = 2; + mHandle.numInts = 5; /* extra ints we have in our handle */ + mHandle.ctl_fd = ctl_fd; + mHandle.shared_fd = shared_fd; + mHandle.width = w; + mHandle.height = h; + mHandle.format = format; + mHandle.num_buffers = num_buffers; + mHandle.shared_size = shared_size; + this->w = w; + this->h = h; + this->format = format; + + memset( &mCtl, 0, sizeof( mCtl ) ); + memset( &mCtlStage, 0, sizeof( mCtlStage ) ); + } + + int ctl_fd() { return mHandle.ctl_fd; } + int shared_fd() { return mHandle.shared_fd; } + overlay_ctrl_t* data() { return &mCtl; } + overlay_ctrl_t* staging() { return &mCtlStage; } + overlay_shared_t* getShared() { return mShared; } + void setShared( overlay_shared_t *p ) { mShared = p; } +}; + +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +static int create_shared_data(overlay_shared_t **shared) +{ + int fd; + /* assuming sizeof(overlay_shared_t) < a single page */ + int size = getpagesize(); + overlay_shared_t *p; + + if ((fd = ashmem_create_region("overlay_data", size)) < 0) { + LOGE("Failed to Create Overlay Shared Data!\n"); + return fd; + } + + p = (overlay_shared_t*)mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) { + LOGE("Failed to Map Overlay Shared Data!\n"); + close(fd); + return -1; + } + + memset(p, 0, size); + p->marker = SHARED_DATA_MARKER; + p->size = size; + p->refCnt = 1; + + if (pthread_mutex_init(&p->lock, NULL) != 0) { + LOGE("Failed to Open Overlay Lock!\n"); + munmap(p, size); + close(fd); + return -1; + } + + *shared = p; + return fd; +} + +static void destroy_shared_data(int shared_fd, overlay_shared_t *shared, + bool closefd ) +{ + if (shared == NULL) + return; + + /* Last side deallocated releases the mutex, otherwise the remaining */ + /* side will deadlock trying to use an already released mutex */ + if (android_atomic_dec(&shared->refCnt) == 1) { + if (pthread_mutex_destroy(&shared->lock)) { + LOGE("Failed to Close Overlay Semaphore!\n"); + } + + shared->marker = 0; + } + + if (munmap(shared, shared->size)) { + LOGE("Failed to Unmap Overlay Shared Data!\n"); + } + + if (closefd && close(shared_fd)) { + LOGE("Failed to Close Overlay Shared Data!\n"); + } +} + +static int open_shared_data( overlay_data_context_t *ctx ) +{ + int rc = -1; + int mode = PROT_READ | PROT_WRITE; + int fd = ctx->shared_fd; + int size = ctx->shared_size; + + if (ctx->shared != NULL) { + /* Already open, return success */ + LOGI("Overlay Shared Data Already Open\n"); + return 0; + } + ctx->shared = (overlay_shared_t*)mmap(0, size, mode, MAP_SHARED, fd, 0); + + if (ctx->shared == MAP_FAILED) { + LOGE("Failed to Map Overlay Shared Data!\n"); + } else if ( ctx->shared->marker != SHARED_DATA_MARKER ) { + LOGE("Invalid Overlay Shared Marker!\n"); + munmap( ctx->shared, size); + } else if ( (int)ctx->shared->size != size ) { + LOGE("Invalid Overlay Shared Size!\n"); + munmap(ctx->shared, size); + } else { + android_atomic_inc(&ctx->shared->refCnt); + rc = 0; + } + + return rc; +} + +static void close_shared_data(overlay_data_context_t *ctx) +{ + destroy_shared_data(ctx->shared_fd, ctx->shared, false); + ctx->shared = NULL; +} + +static int enable_streaming_locked(overlay_shared_t *shared, int ovly_fd) +{ + int rc = 0; + + if (!shared->controlReady || !shared->dataReady) { + LOGI("Postponing Stream Enable/%d/%d\n", shared->controlReady, + shared->dataReady); + } else { + shared->streamEn = 1; + rc = v4l2_overlay_stream_on(ovly_fd); + if (rc) { + LOGE("Stream Enable Failed!/%d\n", rc); + shared->streamEn = 0; + } + } + + return rc; +} + +static int enable_streaming(overlay_shared_t *shared, int ovly_fd) +{ + int ret; + + pthread_mutex_lock(&shared->lock); + ret = enable_streaming_locked(shared, ovly_fd); + pthread_mutex_unlock(&shared->lock); + return ret; +} + +static int disable_streaming_locked(overlay_shared_t *shared, int ovly_fd) +{ + int ret = 0; + + if (shared->streamEn) { + ret = v4l2_overlay_stream_off( ovly_fd ); + if (ret) { + LOGE("Stream Off Failed!/%d\n", ret); + } else { + shared->streamingReset = 1; + shared->streamEn = 0; + } + } + + return ret; +} + +/**************************************************************************** + * Control module + *****************************************************************************/ + +static int overlay_get(struct overlay_control_device_t *dev, int name) +{ + int result = -1; + + switch (name) { + /* 0 = no limit */ + case OVERLAY_MINIFICATION_LIMIT: result = 0; break; + /* 0 = no limit */ + case OVERLAY_MAGNIFICATION_LIMIT: result = 0; break; + /* 0 = infinite */ + case OVERLAY_SCALING_FRAC_BITS: result = 0; break; + /* 90 rotation steps (for instance) */ + case OVERLAY_ROTATION_STEP_DEG: result = 90; break; + /* 1-pixel alignment */ + case OVERLAY_HORIZONTAL_ALIGNMENT: result = 1; break; + /* 1-pixel alignment */ + case OVERLAY_VERTICAL_ALIGNMENT: result = 1; break; + /* 1-pixel alignment */ + case OVERLAY_WIDTH_ALIGNMENT: result = 1; break; + case OVERLAY_HEIGHT_ALIGNMENT: break; + } + + return result; +} + +static int get_fb_var_screeninfo( struct fb_var_screeninfo *info ) +{ + int fd = -1; + int i=0; + char name[64]; + int ret = 0; + + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + 0 }; + + while ((fd==-1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + + if (fd < 0) + ret = -EINVAL; + + if (ioctl(fd, FBIOGET_VSCREENINFO, info) == -1) + ret = -EINVAL; + + if (fd > 0) + close(fd); + + return 0; +} +static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev, + uint32_t w, uint32_t h, int32_t format) +{ + LOGD("overlay_createOverlay:IN w=%d h=%d format=%d\n", w, h, format); + LOG_FUNCTION_NAME; + + overlay_object *overlay; + overlay_control_context_t *ctx = (overlay_control_context_t *)dev; + overlay_shared_t *shared; + + int ret; + uint32_t num = NUM_OVERLAY_BUFFERS_REQUESTED; + int fd; + int shared_fd; + struct fb_var_screeninfo info; + + phyAddr = 0; + + if (format == OVERLAY_FORMAT_DEFAULT) { + LOGV("format == OVERLAY_FORMAT_DEFAULT\n"); + LOGV("set to HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP\n"); + format = HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP; + } + + if (ctx->overlay_video1) { + LOGE("Error - overlays already in use\n"); + return NULL; + } + + shared_fd = create_shared_data(&shared); + if (shared_fd < 0) { + LOGE("Failed to create shared data"); + return NULL; + } + + fd = v4l2_overlay_open(V4L2_OVERLAY_PLANE_VIDEO1); + if (fd < 0) { + LOGE("Failed to open overlay device : %s\n", strerror(errno)); + goto error; + } + + g_s5p_fimc.params.src.full_width = w; + g_s5p_fimc.params.src.full_height = h; + g_s5p_fimc.params.src.width = w; + g_s5p_fimc.params.src.height = h; + if(format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP) + g_s5p_fimc.params.src.color_space = V4L2_PIX_FMT_NV12T; + else + g_s5p_fimc.params.src.color_space = V4L2_PIX_FMT_YUV420; + ret = check_fimc_src_constraints(&g_s5p_fimc); + if(ret != 0) { + if(ret < 0) { + LOGE("Not supported source image size"); + goto error1; + } else { + LOGD("src width, height are changed [w= %d, h= %d]->[w=%d, h= %d]" + , w, h, g_s5p_fimc.params.src.width + , g_s5p_fimc.params.src.height); + w = g_s5p_fimc.params.src.width; + h = g_s5p_fimc.params.src.height; + } + } + + if (v4l2_overlay_init(fd, w, h, format, phyAddr)) { + LOGE("Failed initializing overlays\n"); + goto error1; + } + + if (v4l2_overlay_set_crop(fd, 0, 0, w, h)) { + LOGE("Failed defaulting crop window\n"); + goto error1; + } + + if (v4l2_overlay_set_rotation(fd, 0, 0)) { + LOGE("Failed defaulting rotation\n"); + goto error1; + } + + if (v4l2_overlay_req_buf(fd, &num, 0)) { + LOGE("Failed requesting buffers\n"); + goto error1; + } + + overlay = new overlay_object(fd, shared_fd, shared->size, + w, h, format, num); + if (overlay == NULL) { + LOGE("Failed to create overlay object\n"); + goto error1; + } + ctx->overlay_video1 = overlay; + + overlay->setShared(shared); + + shared->controlReady = 0; + shared->streamEn = 0; + shared->streamingReset = 0; + + /* get lcd size from kernel framebuffer */ + if(get_fb_var_screeninfo(&info) == 0) { + shared->dispW = info.xres; + shared->dispH = info.yres; + g_lcd_width = info.xres; + g_lcd_height = info.yres; + } else { + shared->dispW = g_lcd_width; /* Need to determine this properly */ + shared->dispH = g_lcd_height; /* Need to determine this properly */ + } + + LOGI("Opened video1/fd=%d/obj=%08lx/shm=%d/size=%d", fd, + (unsigned long)overlay, shared_fd, shared->size); + + return overlay; + +error1: + close(fd); +error: + destroy_shared_data(shared_fd, shared, true); + return NULL; +} + +static void overlay_destroyOverlay(struct overlay_control_device_t *dev, + overlay_t* overlay) +{ + LOGD("overlay_destroyOverlay:IN dev (%p) and overlay (%p)", dev, overlay); + LOG_FUNCTION_NAME; + + overlay_control_context_t *ctx = (overlay_control_context_t *)dev; + overlay_object *obj = static_cast<overlay_object *>(overlay); + + int rc; + int fd = obj->ctl_fd(); + uint32_t num = 0; + + overlay_shared_t *shared = obj->getShared(); + + if (shared == NULL) { + LOGE("Overlay was already destroyed - nothing needs to be done\n"); + return; + } + + pthread_mutex_lock(&shared->lock); + + disable_streaming_locked(shared, fd); + + pthread_mutex_unlock(&shared->lock); + + destroy_shared_data(obj->shared_fd(), shared, true); + obj->setShared(NULL); + + if (v4l2_overlay_req_buf(fd, &num, 0)) { + LOGE("Failed requesting buffers\n"); + } + + LOGI("Destroying overlay/fd=%d/obj=%08lx", fd, (unsigned long)overlay); + + if (close(fd)) { + LOGE( "Error closing overly fd/%d\n", errno); + } + + if (overlay) { + if (ctx->overlay_video1 == overlay) + ctx->overlay_video1 = NULL; + delete overlay; + overlay = NULL; + } + LOGD("overlay_destroyOverlay:OUT"); +} + +static int overlay_setPosition(struct overlay_control_device_t *dev, + overlay_t* overlay, int x, int y, uint32_t w, + uint32_t h) +{ + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast<overlay_object *>(overlay); + + overlay_ctrl_t *stage = obj->staging(); + overlay_shared_t *shared = obj->getShared(); + + int rc = 0; + int temp_x = x, temp_y = y, temp_w = w, temp_h = h; + + /* + * This logic here is to return an error if the rectangle is not fully + * within the display, unless we have not received a valid position yet, + * in which case we will do our best to adjust the rectangle to be within + * the display. + */ + + /*quire a minimum size */ + if (temp_w < 16 || temp_h < 16) { + /* Return an error */ + rc = -1; + } else if (!shared->controlReady) { + if ( temp_x < 0 ) temp_x = 0; + if ( temp_y < 0 ) temp_y = 0; + if ( temp_w > shared->dispW ) temp_w = shared->dispW; + if ( temp_h > shared->dispH ) temp_h = shared->dispH; + if ( (temp_x + temp_w) > shared->dispW ) temp_w = shared->dispW - temp_x; + if ( (temp_y + temp_h) > shared->dispH ) temp_h = shared->dispH - temp_y; + } else if (temp_x < 0 || temp_y < 0 || (temp_x + temp_w) > shared->dispW || + (temp_y + temp_h) > shared->dispH) { + /* Return an error */ + rc = -1; + } + + if (rc == 0) { + stage->posX = temp_x; + stage->posY = temp_y; + stage->posW = temp_w; + stage->posH = temp_h; + + stage->posX_org = x; + stage->posY_org = y; + stage->posW_org = w; + stage->posH_org = h; + } + + return rc; +} + +static int overlay_getPosition(struct overlay_control_device_t *dev, + overlay_t* overlay, int* x, int* y, uint32_t* w, + uint32_t* h) +{ + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast<overlay_object *>(overlay); + overlay_ctrl_t *stage = obj->staging(); + + *x = stage->posX_org; + *y = stage->posY_org; + *w = stage->posW_org; + *h = stage->posH_org; + + return 0; +} + +static int overlay_setParameter(struct overlay_control_device_t *dev, + overlay_t* overlay, int param, int value) +{ + LOG_FUNCTION_NAME; + + overlay_ctrl_t *stage = static_cast<overlay_object *>(overlay)->staging(); + int rc = 0; + + switch (param) { + case OVERLAY_DITHER: + break; + + case OVERLAY_TRANSFORM: + switch ( value ) + { + case 0: + stage->rotation = 0; + break; + case OVERLAY_TRANSFORM_ROT_90: + stage->rotation = 90; + break; + case OVERLAY_TRANSFORM_ROT_180: + stage->rotation = 180; + break; + case OVERLAY_TRANSFORM_ROT_270: + stage->rotation = 270; + break; + default: + rc = -EINVAL; + break; + } + break; + } + + return rc; +} + +static int overlay_stage(struct overlay_control_device_t *dev, + overlay_t* overlay) { + return 0; +} + +static int overlay_commit(struct overlay_control_device_t *dev, + overlay_t* overlay) { + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast<overlay_object *>(overlay); + + overlay_ctrl_t *data = obj->data(); + overlay_ctrl_t *stage = obj->staging(); + overlay_shared_t *shared = obj->getShared(); + + int ret = 0; + int fd = obj->ctl_fd(); + + if (shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + pthread_mutex_lock(&shared->lock); + + if (!shared->controlReady) { + shared->controlReady = 1; + } + + if (data->posX == stage->posX && data->posY == stage->posY && + data->posW == stage->posW && data->posH == stage->posH && + data->rotation == stage->rotation) { + LOGI("Nothing to do!\n"); + goto end; + } + + LOGV("Position/X%d/Y%d/W%d/H%d\n", data->posX, data->posY, data->posW, + data->posH); + LOGV("Adjusted Position/X%d/Y%d/W%d/H%d\n", stage->posX, stage->posY, + stage->posW, stage->posH); + LOGV("Rotation/%d\n", stage->rotation ); + + if ((ret = disable_streaming_locked(shared, fd))) + goto end; + + if (stage->rotation != data->rotation) { + ret = v4l2_overlay_set_rotation(fd, stage->rotation, 0); + if (ret) { + LOGE("Set Rotation Failed!/%d\n", ret); + goto end; + } + data->rotation = stage->rotation; + v4l2_overlay_s_fbuf(fd, stage->rotation); + } + + if (!(stage->posX == data->posX && stage->posY == data->posY && + stage->posW == data->posW && stage->posH == data->posH)) { + g_s5p_fimc.params.dst.full_width = g_lcd_width; + g_s5p_fimc.params.dst.full_height = g_lcd_height; + g_s5p_fimc.params.dst.width = stage->posW; + g_s5p_fimc.params.dst.height = stage->posH; + g_s5p_fimc.params.dst.color_space = V4L2_PIX_FMT_NV12T; + ret = check_fimc_dst_constraints(&g_s5p_fimc, stage->rotation); + if(ret != 0) { + if(ret < 0) { + LOGE("Not supported destination image size"); + goto end; + } else { + LOGD("dst width, height are changed [w= %d, h= %d] -> [w=%d, h= %d]", + stage->posW, stage->posH, g_s5p_fimc.params.dst.width, + g_s5p_fimc.params.dst.height); + stage->posW = g_s5p_fimc.params.dst.width; + stage->posH = g_s5p_fimc.params.dst.height; + } + } + ret = v4l2_overlay_set_position(fd, stage->posX, stage->posY, + stage->posW, stage->posH, stage->rotation); + if (ret) { + LOGE("Set Position Failed!/%d\n", ret); + goto end; + } + data->posX = stage->posX; + data->posY = stage->posY; + data->posW = stage->posW; + data->posH = stage->posH; + } + + ret = enable_streaming_locked(shared, fd); + +end: + pthread_mutex_unlock(&shared->lock); + + return ret; +} + +static int overlay_control_close(struct hw_device_t *dev) +{ + LOG_FUNCTION_NAME; + + struct overlay_control_context_t* ctx = + (struct overlay_control_context_t*)dev; + overlay_object *overlay_v1; + + if (ctx) { + overlay_v1 = static_cast<overlay_object *>(ctx->overlay_video1); + + overlay_destroyOverlay((struct overlay_control_device_t *)ctx, + overlay_v1); + + free(ctx); + } + return 0; +} + +/* check the constraints of destination image size */ +static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc, + unsigned int rotation) +{ + int ret = 0; + int tmp = 0; + if((s5p_fimc->params.dst.height > 0) && (s5p_fimc->params.dst.height < 8)) { + s5p_fimc->params.dst.height = 8; + ret = 1; + } + if(s5p_fimc->params.dst.width %8 != 0) { + tmp = s5p_fimc->params.dst.width - (s5p_fimc->params.dst.width%8); + if(tmp <= 0) { + ret = -1; + } else { + s5p_fimc->params.dst.width = tmp; + ret = 1; + } + } + return ret; +} +/* check the constraints of source image size */ +static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc) +{ + int ret = 0; + + if(s5p_fimc->params.src.full_width < 16 || + s5p_fimc->params.src.full_height < 8 ) + ret = -1; + + if(s5p_fimc->hw_ver == 0x50) { + if(s5p_fimc->params.src.color_space == V4L2_PIX_FMT_YUV422P) { + if((s5p_fimc->params.src.full_width%2 != 0) || + (s5p_fimc->params.src.full_height%2 != 0)) + ret = -1; + } + } else { + if(s5p_fimc->params.src.full_width%16 != 0) + ret = -1; + + if(s5p_fimc->params.src.height < 8) { + s5p_fimc->params.src.height = 8; + ret = 1; + } + if(s5p_fimc->params.src.width%16 != 0) { + s5p_fimc->params.src.height = s5p_fimc->params.src.height + - (s5p_fimc->params.src.height)%16; + ret = 1; + } + } + return ret; +} + +/**************************************************************************** + * Data module + *****************************************************************************/ + +int overlay_initialize(struct overlay_data_device_t *dev, + overlay_handle_t handle) +{ + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + struct stat stat; + + int i; + int rc = -1; + + ctx->num_buffers = handle_num_buffers(handle); + ctx->width = handle_width(handle); + ctx->height = handle_height(handle); + ctx->format = handle_format(handle); + ctx->ctl_fd = handle_ctl_fd(handle); + ctx->shared_fd = handle_shared_fd(handle); + ctx->shared_size = handle_shared_size(handle); + ctx->shared = NULL; + ctx->qd_buf_count = 0; + ctx->cacheable_buffers = 0; + + if(ctx->format >= HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP) + ctx->zerocopy = true; + else + ctx->zerocopy = false; + + if (fstat(ctx->ctl_fd, &stat)) { + LOGE("Error = %s from %s\n", strerror(errno), "overlay initialize"); + return -1; + } + + if (open_shared_data(ctx)) { + return -1; + } + + ctx->shared->dataReady = 0; + + ctx->mapping_data = new struct mapping_data; + ctx->buffers = new void* [ctx->num_buffers]; + ctx->buffers_len = new size_t[ctx->num_buffers]; + + if (!ctx->buffers || !ctx->buffers_len || !ctx->mapping_data) { + LOGE("Failed alloc'ing buffer arrays\n"); + goto error; + } else { + + /* + * in the zero copy case, + * don't need to mmap buffer for source + */ + if (ctx->zerocopy) + rc = 0; + else { + for (i = 0; i < ctx->num_buffers; i++) { + rc = v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i], + &ctx->buffers_len[i]); + if (rc) { + LOGE("Failed mapping buffers\n"); + goto error; + } + } + } + } + + v4l2_overlay_init_fimc(ctx->ctl_fd, &g_s5p_fimc); + + return ( rc ); + +error: + + if(ctx->mapping_data) + delete (ctx->mapping_data); + if(ctx->buffers) + delete [] ctx->buffers; + if(ctx->buffers_len) + delete [] ctx->buffers_len; + + close_shared_data( ctx ); + + return -1; +} + +static int overlay_resizeInput(struct overlay_data_device_t *dev, uint32_t w, + uint32_t h) +{ + int rc = -1; + int ret = 0; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if ((ctx->width == (int)w) && (ctx->width == (int)h)) { + LOGV("same as current width and height. so do nothing"); + return 0; + } + + if (!ctx->shared) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + if (ctx->shared->dataReady) { + LOGV("Either setCrop() or queueBuffer() was called prior to this!" + "Therefore failing this call.\n"); + return -1; + } + + pthread_mutex_lock(&ctx->shared->lock); + + if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd))) + goto end; + + if (!ctx->zerocopy) { + for (int i = 0; i < ctx->num_buffers; i++) { + v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]); + } + } + + g_s5p_fimc.params.src.full_width = w; + g_s5p_fimc.params.src.full_height = h; + g_s5p_fimc.params.src.width = w; + g_s5p_fimc.params.src.height = h; + if(ctx->zerocopy) + g_s5p_fimc.params.src.color_space = V4L2_PIX_FMT_NV12T; + else + g_s5p_fimc.params.src.color_space = V4L2_PIX_FMT_YUV420; + ret = check_fimc_src_constraints(&g_s5p_fimc); + + if(ret != 0) { + if(ret < 0) { + LOGE("Not supported source image size"); + goto end; + } else { + LOGD("src width, height are changed [w= %d, h= %d] -> [w=%d, h= %d]" + , w, h, g_s5p_fimc.params.src.width + , g_s5p_fimc.params.src.height); + w = g_s5p_fimc.params.src.width; + h = g_s5p_fimc.params.src.height; + } + } + + rc = v4l2_overlay_init(ctx->ctl_fd, w, h, ctx->format, phyAddr); + if (rc) { + LOGE("Error initializing overlay"); + goto end; + } + rc = v4l2_overlay_set_crop(ctx->ctl_fd, 0, 0, w, h); + if (rc) { + LOGE("Error setting crop window\n"); + goto end; + } + rc = v4l2_overlay_req_buf(ctx->ctl_fd, (uint32_t *)(&ctx->num_buffers), + ctx->cacheable_buffers); + if (rc) { + LOGE("Error creating buffers"); + goto end; + } + + if (!ctx->zerocopy) { + for (int i = 0; i < ctx->num_buffers; i++) + v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i], + &ctx->buffers_len[i]); + } + + rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd); + +end: + pthread_mutex_unlock(&ctx->shared->lock); + + return rc; +} + + +static int overlay_data_setParameter(struct overlay_data_device_t *dev, + int param, int value) +{ + int ret = 0; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if (ctx->shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + if (ctx->shared->dataReady) { + LOGI("Too late. Cant set it now!\n"); + return -1; + } + + if (param == CACHEABLE_BUFFERS) + ctx->cacheable_buffers = value; + + return ( ret ); +} + + +static int overlay_setCrop(struct overlay_data_device_t *dev, uint32_t x, + uint32_t y, uint32_t w, uint32_t h) { + LOG_FUNCTION_NAME; + + int rc = 0; + int cnt = 0; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if (ctx->shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + pthread_mutex_lock(&ctx->shared->lock); + + ctx->shared->dataReady = 1; + + if (ctx->data.cropX == x && ctx->data.cropY == y && ctx->data.cropW == w + && ctx->data.cropH == h) { + goto end; + } + + ctx->data.cropX = x; + ctx->data.cropY = y; + ctx->data.cropW = w; + ctx->data.cropH = h; + + LOGV("Crop Win/X%d/Y%d/W%d/H%d\n", x, y, w, h ); + + if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd))) + goto end; + + rc = v4l2_overlay_set_crop(ctx->ctl_fd, x, y, w, h); + if (rc) { + LOGE("Set Crop Window Failed!/%d\n", rc); + } + + rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd); + +end: + pthread_mutex_unlock(&ctx->shared->lock); + return rc; +} + +static int overlay_getCrop(struct overlay_data_device_t *dev , uint32_t* x, + uint32_t* y, uint32_t* w, uint32_t* h) { + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + return v4l2_overlay_get_crop(ctx->ctl_fd, x, y, w, h); +} + +int overlay_dequeueBuffer(struct overlay_data_device_t *dev, + overlay_buffer_t *buffer) { + /* blocks until a buffer is available and return an opaque structure + * representing this buffer. + */ + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + int rc=0; + int i = -1; + uint32_t num = 0; + int cnt = 0; + + pthread_mutex_lock(&ctx->shared->lock); + if ( ctx->shared->streamingReset ) { + ctx->shared->streamingReset = 0; + pthread_mutex_unlock(&ctx->shared->lock); + return ALL_BUFFERS_FLUSHED; + } + pthread_mutex_unlock(&ctx->shared->lock); + + /* If we are not streaming dequeue will fail, + skip to prevent error printouts */ + if (ctx->shared->streamEn && ctx->qd_buf_count) { + if ((rc = v4l2_overlay_dq_buf( ctx->ctl_fd, &i ,ctx->zerocopy)) != 0) { + LOGE("Failed to DQ/%d\n", rc); + } + else if (i < 0 || i > ctx->num_buffers) { + rc = -EINVAL; + } else { + *((int *)buffer) = i; + ctx->qd_buf_count --; + } + } else { + rc = -1; + } + + return rc; +} + +int overlay_queueBuffer(struct overlay_data_device_t *dev, + overlay_buffer_t buffer) { + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + int cnt = 0; + + pthread_mutex_lock(&ctx->shared->lock); + if ( ctx->shared->streamingReset ) { + ctx->shared->streamingReset = 0; + pthread_mutex_unlock(&ctx->shared->lock); + return ALL_BUFFERS_FLUSHED; + } + pthread_mutex_unlock(&ctx->shared->lock); + + /* Catch the case where the data side had no need to set the crop window */ + if (!ctx->shared->dataReady) { + ctx->shared->dataReady = 1; + enable_streaming(ctx->shared, ctx->ctl_fd); + } + + int rc = v4l2_overlay_q_buf( ctx->ctl_fd, (int)buffer, (int) ctx->zerocopy ); + if (rc == 0 && ctx->qd_buf_count < ctx->num_buffers) { + ctx->qd_buf_count ++; + } + + return rc; +} + +void *overlay_getBufferAddress(struct overlay_data_device_t *dev, + overlay_buffer_t buffer) +{ + LOG_FUNCTION_NAME; + + /* this may fail (NULL) if this feature is not supported. In that case, + * presumably, there is some other HAL module that can fill the buffer, + * using a DSP for instance + */ + int ret; + struct v4l2_buffer buf; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + return (void*) ctx->buffers[(int)buffer]; +} + +int overlay_getBufferCount(struct overlay_data_device_t *dev) +{ + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + return (ctx->num_buffers); +} + +static int overlay_data_close(struct hw_device_t *dev) { + + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + int rc; + + if (ctx) { + overlay_data_device_t *overlay_dev = &ctx->device; + int buf; + int i; + + pthread_mutex_lock(&ctx->shared->lock); + + if (!ctx->zerocopy) + for (i = 0; i < ctx->num_buffers; i++) { + LOGV("Unmap Buffer/%d/%08lx/%d", i, (unsigned long)ctx->buffers[i], + ctx->buffers_len[i] ); + rc = v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]); + if (rc != 0) { + LOGE("Error unmapping the buffer/%d/%d", i, rc); + } + } + + delete (ctx->mapping_data); + delete [] ctx->buffers; + delete [] ctx->buffers_len; + + pthread_mutex_unlock(&ctx->shared->lock); + + ctx->shared->dataReady = 0; + close_shared_data( ctx ); + + free(ctx); + } + + return 0; +} + +/*****************************************************************************/ + +static int overlay_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device) +{ + LOG_FUNCTION_NAME; + int status = -EINVAL; + + if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) { + struct overlay_control_context_t *dev; + dev = (overlay_control_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = overlay_control_close; + + dev->device.get = overlay_get; + dev->device.createOverlay = overlay_createOverlay; + dev->device.destroyOverlay = overlay_destroyOverlay; + dev->device.setPosition = overlay_setPosition; + dev->device.getPosition = overlay_getPosition; + dev->device.setParameter = overlay_setParameter; + dev->device.stage = overlay_stage; + dev->device.commit = overlay_commit; + + *device = &dev->device.common; + status = 0; + } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) { + struct overlay_data_context_t *dev; + dev = (overlay_data_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = overlay_data_close; + + dev->device.initialize = overlay_initialize; + dev->device.resizeInput = overlay_resizeInput; + dev->device.setCrop = overlay_setCrop; + dev->device.getCrop = overlay_getCrop; + dev->device.setParameter = overlay_data_setParameter; + dev->device.dequeueBuffer = overlay_dequeueBuffer; + dev->device.queueBuffer = overlay_queueBuffer; + dev->device.getBufferAddress = overlay_getBufferAddress; + dev->device.getBufferCount = overlay_getBufferCount; + + *device = &dev->device.common; + status = 0; + } + return status; +} diff --git a/liboverlay/v4l2_utils.c b/liboverlay/v4l2_utils.c new file mode 100644 index 0000000..5d83393 --- /dev/null +++ b/liboverlay/v4l2_utils.c @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* #define OVERLAY_DEBUG 1 */ +#define LOG_TAG "v4l2_utils" + +#include <fcntl.h> +#include <errno.h> +#include <cutils/log.h> +#include <hardware/overlay.h> +#include <linux/videodev.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include "v4l2_utils.h" + + +#define LOG_FUNCTION_NAME LOGV("%s: %s", __FILE__, __func__); + +#define V4L2_CID_PRIV_OFFSET 0x0 +#define V4L2_CID_PRIV_ROTATION (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 0) +#define V4L2_CID_PRIV_COLORKEY (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 1) +#define V4L2_CID_PRIV_COLORKEY_EN (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 2) + +extern unsigned int g_lcd_width; +extern unsigned int g_lcd_height; + +int v4l2_overlay_get(int name) +{ + int result = -1; + switch (name) { + case OVERLAY_MINIFICATION_LIMIT: + result = 4; /* 0 = no limit */ + break; + case OVERLAY_MAGNIFICATION_LIMIT: + result = 2; /* 0 = no limit */ + break; + case OVERLAY_SCALING_FRAC_BITS: + result = 0; /* 0 = infinite */ + break; + case OVERLAY_ROTATION_STEP_DEG: + result = 90; /* 90 rotation steps (for instance) */ + break; + case OVERLAY_HORIZONTAL_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_VERTICAL_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_WIDTH_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_HEIGHT_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + } + return result; +} + +int v4l2_overlay_open(int id) +{ + LOG_FUNCTION_NAME + return open("/dev/video1", O_RDWR); +} + +int v4l2_overlay_init_fimc(int fd, s5p_fimc_t *s5p_fimc) +{ + int ret; + struct v4l2_control vc; + + if (fd < 0) + return -1; + + vc.id = V4L2_CID_FIMC_VERSION; + vc.value = 0; + + s5p_fimc->dev_fd = fd; + + ret = ioctl(s5p_fimc->dev_fd, VIDIOC_G_CTRL, &vc); + if (ret < 0) { + LOGE("Error in video VIDIOC_G_CTRL - V4L2_CID_FIMC_VERSION (%d)", ret); + LOGE("FIMC version is set with default"); + vc.value = 0x43; + } + s5p_fimc->hw_ver = vc.value; + return 0; +} + +void dump_pixfmt(struct v4l2_pix_format *pix) +{ + LOGV("w: %d\n", pix->width); + LOGV("h: %d\n", pix->height); + LOGV("color: %x\n", pix->colorspace); + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + LOGV("YUYV\n"); + break; + case V4L2_PIX_FMT_UYVY: + LOGV("UYVY\n"); + break; + case V4L2_PIX_FMT_RGB565: + LOGV("RGB565\n"); + break; + case V4L2_PIX_FMT_RGB565X: + LOGV("RGB565X\n"); + break; + default: + LOGV("not supported\n"); + } +} + +void dump_crop(struct v4l2_crop *crop) +{ + LOGV("crop l: %d ", crop->c.left); + LOGV("crop t: %d ", crop->c.top); + LOGV("crop w: %d ", crop->c.width); + LOGV("crop h: %d\n", crop->c.height); +} + +void dump_window(struct v4l2_window *win) +{ + LOGV("window l: %d ", win->w.left); + LOGV("window t: %d ", win->w.top); + LOGV("window w: %d ", win->w.width); + LOGV("window h: %d\n", win->w.height); +} + +void v4l2_overlay_dump_state(int fd) +{ + struct v4l2_format format; + struct v4l2_crop crop; + int ret; + + LOGV("dumping driver state:"); + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(fd, VIDIOC_G_FMT, &format); + if (ret < 0) + return; + LOGV("output pixfmt:\n"); + dump_pixfmt(&format.fmt.pix); + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = ioctl(fd, VIDIOC_G_FMT, &format); + if (ret < 0) + return; + LOGV("v4l2_overlay window:\n"); + dump_window(&format.fmt.win); + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(fd, VIDIOC_G_CROP, &crop); + if (ret < 0) + return; + LOGV("output crop:\n"); + dump_crop(&crop); +} + +static void error(int fd, const char *msg) +{ + LOGE("Error = %s from %s", strerror(errno), msg); +#ifdef OVERLAY_DEBUG + v4l2_overlay_dump_state(fd); +#endif +} + +static int v4l2_overlay_ioctl(int fd, int req, void *arg, const char* msg) +{ + int ret; + ret = ioctl(fd, req, arg); + if (ret < 0) { + error(fd, msg); + return -1; + } + return 0; +} + +#define v4l2_fourcc(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \ + ((__u32)(c) << 16) | ((__u32)(d) << 24)) +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') + +int configure_pixfmt(struct v4l2_pix_format *pix, int32_t fmt, + uint32_t w, uint32_t h) +{ + LOG_FUNCTION_NAME + int fd; + + switch (fmt) { + case OVERLAY_FORMAT_RGBA_8888: + return -1; + case OVERLAY_FORMAT_RGB_565: + pix->pixelformat = V4L2_PIX_FMT_RGB565; + break; + case OVERLAY_FORMAT_BGRA_8888: + return -1; + case OVERLAY_FORMAT_YCbCr_420_SP: + pix->pixelformat = V4L2_PIX_FMT_NV21; + break; + case OVERLAY_FORMAT_YCbYCr_422_I: + pix->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case OVERLAY_FORMAT_CbYCrY_422_I: + pix->pixelformat = V4L2_PIX_FMT_UYVY; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + pix->pixelformat = V4L2_PIX_FMT_YUV420; + break; + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + pix->pixelformat = V4L2_PIX_FMT_NV21; + break; + default: + return -1; + } + pix->width = w; + pix->height = h; + return 0; +} + +static void configure_window(struct v4l2_window *win, int32_t w, + int32_t h, int32_t x, int32_t y) +{ + LOG_FUNCTION_NAME + + win->w.left = x; + win->w.top = y; + win->w.width = w; + win->w.height = h; +} + +void get_window(struct v4l2_format *format, int32_t *x, + int32_t *y, int32_t *w, int32_t *h) +{ + LOG_FUNCTION_NAME + + *x = format->fmt.win.w.left; + *y = format->fmt.win.w.top; + *w = format->fmt.win.w.width; + *h = format->fmt.win.w.height; +} + +int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt, + uint32_t addr) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + struct v4l2_framebuffer fbuf; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); + if (ret) + return ret; + LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, + format.fmt.pix.height); + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + configure_pixfmt(&format.fmt.pix, fmt, w, h); + LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, + format.fmt.pix.height); + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format"); + if (ret) + return ret; + + ret = v4l2_overlay_s_fbuf(fd, 0); + if (ret) + return ret; + + return ret; +} + +int v4l2_overlay_s_fbuf(int fd, int rotation) +{ + struct v4l2_framebuffer fbuf; + int ret; + + /* configure the v4l2_overlay framebuffer */ + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get fbuf"); + if (ret) + return ret; + + /* if fbuf.base value is set by 0, using local DMA. */ + fbuf.base = (void *)0; + if (rotation == 0 || rotation == 180) { + fbuf.fmt.width = g_lcd_width; + fbuf.fmt.height = g_lcd_height; + } else { + fbuf.fmt.width = g_lcd_height; + fbuf.fmt.height = g_lcd_width; + } + fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB32; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "set fbuf"); + if (ret) + return ret; + + return ret; +} + +int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h + , uint32_t *fmt) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); + *w = format.fmt.pix.width; + *h = format.fmt.pix.height; + if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) + *fmt = OVERLAY_FORMAT_CbYCrY_422_I; + else + return -EINVAL; + return ret; +} + +int v4l2_overlay_set_position(int fd, int32_t x, int32_t y + , int32_t w, int32_t h, int rotation) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + int ret; + int rot_x = 0, rot_y = 0 , rot_w = 0, rot_h = 0; + + /* configure the src format pix */ + /* configure the dst v4l2_overlay window */ + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, + "get v4l2_overlay format"); + if (ret) + return ret; + LOGV("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width + , format.fmt.win.w.height); + + if (rotation == 0) { + rot_x = x; + rot_y = y; + rot_w = w; + rot_h = h; + } else if (rotation == 90) { + rot_x = y; + rot_y = g_lcd_width - (x + w); + rot_w = h; + rot_h = w; + } else if (rotation == 180) { + rot_x = g_lcd_width - (x + w); + rot_y = g_lcd_height - (y + h); + rot_w = w; + rot_h = h; + } else if (rotation == 270) { + rot_x = g_lcd_height - (y + h); + rot_y = x; + rot_w = h; + rot_h = w; + } + + configure_window(&format.fmt.win, rot_w, rot_h, rot_x, rot_y); + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, + "set v4l2_overlay format"); + + LOGV("v4l2_overlay_set_position:: w=%d h=%d rotation=%d" + , format.fmt.win.w.width, format.fmt.win.w.height, rotation); + + if (ret) + return ret; + v4l2_overlay_dump_state(fd); + + return 0; +} + +int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, + int32_t *h) +{ + struct v4l2_format format; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, + "get v4l2_overlay format"); + + if (ret) + return ret; + + get_window(&format, x, y, w, h); + + return 0; +} + +int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, + uint32_t h) +{ + LOG_FUNCTION_NAME + + struct v4l2_crop crop; + int ret; + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); + crop.c.left = x; + crop.c.top = y; + crop.c.width = w; + crop.c.height = h; + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + LOGV("%s:crop.c.left = %d\n", __func__, crop.c.left); + LOGV("%s:crop.c.top = %d\n", __func__, crop.c.top); + LOGV("%s:crop.c.width = %d\n", __func__, crop.c.width); + LOGV("%s:crop.c.height = %d\n", __func__, crop.c.height); + LOGV("%s:crop.type = 0x%x\n", __func__, crop.type); + + return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop"); +} + +int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, + uint32_t *h) +{ + LOG_FUNCTION_NAME + + struct v4l2_crop crop; + int ret; + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); + *x = crop.c.left; + *y = crop.c.top; + *w = crop.c.width; + *h = crop.c.height; + return ret; +} + +int v4l2_overlay_set_rotation(int fd, int degree, int step) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_PRIV_ROTATION; + ctrl.value = degree; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation"); + + return ret; +} + +int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + memset(&fbuf, 0, sizeof(fbuf)); + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, + "get transparency enables"); + + if (ret) + return ret; + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey"); + + if (ret) + return ret; + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey"); + + if (ret) + return ret; + + fmt.fmt.win.chromakey = colorkey & 0xFFFFFF; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey"); + } + + return ret; +} + +int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + memset(&fbuf, 0, sizeof(fbuf)); + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, + "get transparency enables"); + + if (ret) + return ret; + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha"); + + if (ret) + return ret; + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha"); + + if (ret) + return ret; + + fmt.fmt.win.global_alpha = alpha & 0xFF; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha"); + } + + return ret; +} + +int v4l2_overlay_set_local_alpha(int fd, int enable) +{ + int ret; + struct v4l2_framebuffer fbuf; + + ret = 0; + + return ret; +} + +int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers) +{ + struct v4l2_requestbuffers reqbuf; + int ret, i; + + reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + reqbuf.memory = V4L2_MEMORY_MMAP; + reqbuf.count = *num_bufs; + + ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf); + if (ret < 0) { + error(fd, "reqbuf ioctl"); + return ret; + } + + if (reqbuf.count > *num_bufs) { + error(fd, "Not enough buffer structs passed to get_buffers"); + return -ENOMEM; + } + *num_bufs = reqbuf.count; + + return 0; +} + +static int is_mmaped(struct v4l2_buffer *buf) +{ + return buf->flags == V4L2_BUF_FLAG_MAPPED; +} + +static int is_queued(struct v4l2_buffer *buf) +{ + /* is either on the input or output queue in the kernel */ + return (buf->flags & V4L2_BUF_FLAG_QUEUED) || + (buf->flags & V4L2_BUF_FLAG_DONE); +} + +static int is_dequeued(struct v4l2_buffer *buf) +{ + /* is on neither input or output queue in kernel */ + return !(buf->flags & V4L2_BUF_FLAG_QUEUED) && + !(buf->flags & V4L2_BUF_FLAG_DONE); +} + +int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf) +{ + LOG_FUNCTION_NAME + + memset(buf, 0, sizeof(struct v4l2_buffer)); + + buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf->memory = V4L2_MEMORY_MMAP; + buf->index = index; + LOGV("query buffer, mem=%u type=%u index=%u\n", + buf->memory, buf->type, buf->index); + return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl"); +} + +int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len) +{ + LOG_FUNCTION_NAME + + struct v4l2_buffer buf; + int ret; + + ret = v4l2_overlay_query_buffer(fd, index, &buf); + if (ret) + return ret; + + if (is_mmaped(&buf)) { + LOGE("Trying to mmap buffers that are already mapped!\n"); + return -EINVAL; + } + + *len = buf.length; + *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, buf.m.offset); + if (*start == MAP_FAILED) { + LOGE("map failed, length=%u offset=%u\n", buf.length, buf.m.offset); + return -EINVAL; + } + return 0; +} + +int v4l2_overlay_unmap_buf(void *start, size_t len) +{ + LOG_FUNCTION_NAME + return munmap(start, len); +} + + +int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps) +{ + return v4l2_overlay_ioctl(fd, VIDIOC_QUERYCAP, caps, "query cap"); +} + +int v4l2_overlay_stream_on(int fd) +{ + int ret; + uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + ret = v4l2_overlay_set_local_alpha(fd, 1); + if (ret) + return ret; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on"); + + return ret; +} + +int v4l2_overlay_stream_off(int fd) +{ + int ret; + uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + ret = v4l2_overlay_set_local_alpha(fd, 0); + if (ret) + return ret; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMOFF, &type, "stream off"); + + return ret; +} + +int v4l2_overlay_q_buf(int fd, int buffer, int zerocopy) +{ + struct v4l2_buffer buf; + int ret; + + if (zerocopy) { + uint8_t *pPhyYAddr; + uint8_t *pPhyCAddr; + struct fimc_buf fimc_src_buf; + uint8_t index; + + memcpy(&pPhyYAddr, (void *) buffer, sizeof(pPhyYAddr)); + memcpy(&pPhyCAddr, (void *) (buffer + sizeof(pPhyYAddr)), + sizeof(pPhyCAddr)); + memcpy(&index, + (void *) (buffer + sizeof(pPhyYAddr) + sizeof(pPhyCAddr)), + sizeof(index)); + + fimc_src_buf.base[0] = (dma_addr_t) pPhyYAddr; + fimc_src_buf.base[1] = (dma_addr_t) pPhyCAddr; + fimc_src_buf.base[2] = + (dma_addr_t) (pPhyCAddr + (pPhyCAddr - pPhyYAddr)/4); + + buf.index = index; + buf.memory = V4L2_MEMORY_USERPTR; + buf.m.userptr = (unsigned long)&fimc_src_buf; + buf.length = 0; + } else { + buf.index = buffer; + buf.memory = V4L2_MEMORY_MMAP; + } + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf.field = V4L2_FIELD_NONE; + buf.timestamp.tv_sec = 0; + buf.timestamp.tv_usec = 0; + buf.flags = 0; + + return v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf"); +} + +int v4l2_overlay_dq_buf(int fd, int *index, int zerocopy) +{ + struct v4l2_buffer buf; + int ret; + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + if (zerocopy) + buf.memory = V4L2_MEMORY_USERPTR; + else + buf.memory = V4L2_MEMORY_MMAP; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_DQBUF, &buf, "dqbuf"); + if (ret) + return ret; + *index = buf.index; + return 0; +} diff --git a/liboverlay/v4l2_utils.h b/liboverlay/v4l2_utils.h new file mode 100644 index 0000000..e85b65a --- /dev/null +++ b/liboverlay/v4l2_utils.h @@ -0,0 +1,72 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * Author: rschultz@google.com (Rebecca Schultz Zavin) + */ + +#ifndef ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_ +#define ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_ + +#include "s5p_fimc.h" + +int v4l2_overlay_open(int id); +int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps); +int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers); +int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf); +int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len); +int v4l2_overlay_unmap_buf(void *start, size_t len); +int v4l2_overlay_stream_on(int fd); +int v4l2_overlay_stream_off(int fd); +int v4l2_overlay_q_buf(int fd, int index, int zerocopy); +int v4l2_overlay_dq_buf(int fd, int *index, int zerocopy); +int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt, + uint32_t addr); +int v4l2_overlay_get_input_size(int fd, uint32_t *w, uint32_t *h, + uint32_t *fmt); +int v4l2_overlay_set_position(int fd, int32_t x, int32_t y, int32_t w, + int32_t h, int rotation); +int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, + int32_t *h); +int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, + uint32_t h); +int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, + uint32_t *h); +int v4l2_overlay_set_rotation(int fd, int degree, int step); +int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey); +int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha); +int v4l2_overlay_set_local_alpha(int fd, int enable); +int v4l2_overlay_init_fimc(int fd, s5p_fimc_t *s5p_fimc); +int v4l2_overlay_s_fbuf(int fd, int rotation); + +enum { + V4L2_OVERLAY_PLANE_GRAPHICS, + V4L2_OVERLAY_PLANE_VIDEO1, + V4L2_OVERLAY_PLANE_VIDEO2, +}; + + +enum { + OVERLAY_FORMAT_YCbCr_420_SP = 0x21, +}; + +enum { + /* support customed format for zero copy */ + HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x21, + HAL_PIXEL_FORMAT_YCbCr_420_P = 0x13, + + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x100, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I = 0x101, + HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I = 0x102, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x103, + +}; + +struct mapping_data { + int fd; + size_t length; + uint32_t offset; + void *ptr; +}; + +#define ALL_BUFFERS_FLUSHED -66 + +#endif /* ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_*/ diff --git a/ueventd.smdkc110.rc b/ueventd.smdkc110.rc index 78a0efc..60544df 100644 --- a/ueventd.smdkc110.rc +++ b/ueventd.smdkc110.rc @@ -1,6 +1,8 @@ # dev files for 3D /dev/pvrsrvkm 0666 system system +/dev/video0 0664 system camera /dev/video1 0664 system camera +/dev/video2 0664 system camera /dev/pmem_gpu1 0664 system graphics /dev/s3c-mem 0664 system system /dev/s3c_bc 0664 system system |