summaryrefslogtreecommitdiff
authorbrian.zhu <brian.zhu@amlogic.com>2014-07-18 20:15:50 (GMT)
committer Sandy lUo <sandy.luo@amlogic.com>2014-07-29 14:10:50 (GMT)
commit8c533254831f51de0944c54314d8a2a236717cb4 (patch)
tree172774027a7f5628c268eca104e5b749f60a8184
parent53f97cd29db7ae23bd43b3e54d36f3ce176f0d50 (diff)
downloadscreen_source-8c533254831f51de0944c54314d8a2a236717cb4.zip
screen_source-8c533254831f51de0944c54314d8a2a236717cb4.tar.gz
screen_source-8c533254831f51de0944c54314d8a2a236717cb4.tar.bz2
PD#89978, use kernel time stamp, fix block issue when stop. skip late frame
Diffstat
-rwxr-xr-xaml_screen.cpp47
-rwxr-xr-xv4l2_vdin.cpp566
-rwxr-xr-xv4l2_vdin.h96
3 files changed, 354 insertions, 355 deletions
diff --git a/aml_screen.cpp b/aml_screen.cpp
index 33923c9..8e0921b 100755
--- a/aml_screen.cpp
+++ b/aml_screen.cpp
@@ -86,7 +86,7 @@ static int aml_screen_device_close(struct hw_device_t *dev)
android::vdin_screen_source* source = NULL;
aml_screen_device_t* ctx = (aml_screen_device_t*)dev;
- android::Mutex::Autolock lock(gAmlScreenLock);
+ android::Mutex::Autolock lock(gAmlScreenLock);
if (ctx) {
if (ctx->priv){
source = (android::vdin_screen_source*)ctx->priv;
@@ -95,14 +95,14 @@ static int aml_screen_device_close(struct hw_device_t *dev)
}
free(ctx);
}
- gAmlScreenOpen--;
+ gAmlScreenOpen--;
return 0;
}
int screen_source_start(struct aml_screen_device* dev)
{
android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
- LOGV("screen_source_start");
+ LOGV("screen_source_start");
return source->start();
}
int screen_source_stop(struct aml_screen_device* dev)
@@ -211,32 +211,28 @@ static int aml_screen_device_open(const struct hw_module_t* module, const char*
{
int status = -EINVAL;
android::vdin_screen_source* source = NULL;
-
- android::Mutex::Autolock lock(gAmlScreenLock);
+ android::Mutex::Autolock lock(gAmlScreenLock);
LOGV("aml_screen_device_open");
if (!strcmp(name, AML_SCREEN_SOURCE)) {
-
- if(gAmlScreenOpen > 1){
- ALOGD("aml screen device already open");
- *device = NULL;
- return -EINVAL;
- }
+ if(gAmlScreenOpen > 1){
+ ALOGD("aml screen device already open");
+ *device = NULL;
+ return -EINVAL;
+ }
aml_screen_device_t *dev = (aml_screen_device_t*)malloc(sizeof(aml_screen_device_t));
- if (!dev)
- {
- LOGE("no memory for the screen source device");
+ if (!dev){
+ LOGE("no memory for the screen source device");
return -ENOMEM;
}
/* initialize handle here */
memset(dev, 0, sizeof(*dev));
source = new android::vdin_screen_source;
- if (!source)
- {
+ if (!source){
LOGE("no memory for class of vdin_screen_source");
free (dev);
return -ENOMEM;
@@ -244,14 +240,14 @@ static int aml_screen_device_open(const struct hw_module_t* module, const char*
dev->priv = (void*)source;
/* initialize the procs */
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
- dev->common.module = const_cast<hw_module_t*>(module);
- dev->common.close = aml_screen_device_close;
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = const_cast<hw_module_t*>(module);
+ dev->common.close = aml_screen_device_close;
dev->ops.start = screen_source_start;
dev->ops.stop = screen_source_stop;
- dev->ops.pause = screen_source_pause;
+ dev->ops.pause = screen_source_pause;
dev->ops.get_format = screen_source_get_format;
dev->ops.set_format = screen_source_set_format;
dev->ops.set_rotation = screen_source_set_rotation;
@@ -259,16 +255,15 @@ static int aml_screen_device_open(const struct hw_module_t* module, const char*
dev->ops.aquire_buffer = screen_source_aquire_buffer;
dev->ops.release_buffer = screen_source_release_buffer;
dev->ops.setStateCallBack = screen_source_set_state_callback;
- dev->ops.setPreviewWindow = screen_source_set_preview_window;
- dev->ops.setDataCallBack = screen_source_set_data_callback;
+ dev->ops.setPreviewWindow = screen_source_set_preview_window;
+ dev->ops.setDataCallBack = screen_source_set_data_callback;
dev->ops.set_frame_rate = screen_source_set_frame_rate;
dev->ops.set_source_type = screen_source_set_source_type;
dev->ops.get_source_type = screen_source_get_source_type;
- // dev->ops.inc_buffer_refcount = screen_source_inc_buffer_refcount;
+ // dev->ops.inc_buffer_refcount = screen_source_inc_buffer_refcount;
*device = &dev->common;
-
status = 0;
- gAmlScreenOpen++;
+ gAmlScreenOpen++;
}
return status;
}
diff --git a/v4l2_vdin.cpp b/v4l2_vdin.cpp
index face0d5..393e123 100755
--- a/v4l2_vdin.cpp
+++ b/v4l2_vdin.cpp
@@ -57,31 +57,29 @@ namespace android {
#define ALIGN(x) (x + (BOUNDRY) - 1)& ~((BOUNDRY) - 1)
-
-
static size_t getBufSize(int format, int width, int height)
{
size_t buf_size = 0;
- switch(format){
- case V4L2_PIX_FMT_YVU420:
- case V4L2_PIX_FMT_NV21:
- buf_size = width * height * 3 / 2;
- break;
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_RGB565:
- buf_size = width * height * 2;
- break;
- case V4L2_PIX_FMT_RGB24:
- buf_size = width * height * 3;
- break;
- case V4L2_PIX_FMT_RGB32:
- buf_size = width * height * 4;
- break;
- default:
- ALOGE("Invalid format");
- buf_size = 0;
- }
+ switch(format){
+ case V4L2_PIX_FMT_YVU420:
+ case V4L2_PIX_FMT_NV21:
+ buf_size = width * height * 3 / 2;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_RGB565:
+ buf_size = width * height * 2;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ buf_size = width * height * 3;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ buf_size = width * height * 4;
+ break;
+ default:
+ ALOGE("Invalid format");
+ buf_size = 0;
+ }
return buf_size;
}
@@ -89,34 +87,35 @@ static int getNativeWindowFormat(int format)
{
int nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
- switch(format){
- case V4L2_PIX_FMT_YVU420:
- nativeFormat = HAL_PIXEL_FORMAT_YV12;
- break;
- case V4L2_PIX_FMT_NV21:
- nativeFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
- break;
- case V4L2_PIX_FMT_YUYV:
- nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
- break;
- case V4L2_PIX_FMT_RGB565:
- nativeFormat = HAL_PIXEL_FORMAT_RGB_565;
- break;
- case V4L2_PIX_FMT_RGB24:
- nativeFormat = HAL_PIXEL_FORMAT_RGB_888;
- break;
- case V4L2_PIX_FMT_RGB32:
- nativeFormat = HAL_PIXEL_FORMAT_RGBA_8888;
- break;
- default:
- ALOGE("Invalid format,Use default format");
- }
+ switch(format){
+ case V4L2_PIX_FMT_YVU420:
+ nativeFormat = HAL_PIXEL_FORMAT_YV12;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ nativeFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ nativeFormat = HAL_PIXEL_FORMAT_RGB_565;
+ break;
+ case V4L2_PIX_FMT_RGB24:
+ nativeFormat = HAL_PIXEL_FORMAT_RGB_888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ nativeFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ break;
+ default:
+ ALOGE("Invalid format,Use default format");
+ }
return nativeFormat;
}
-static ANativeWindowBuffer* handle_to_buffer(buffer_handle_t *handle){
- return container_of(handle, ANativeWindowBuffer, handle);
+static ANativeWindowBuffer* handle_to_buffer(buffer_handle_t *handle)
+{
+ return container_of(handle, ANativeWindowBuffer, handle);
}
vdin_screen_source::vdin_screen_source()
@@ -124,41 +123,34 @@ vdin_screen_source::vdin_screen_source()
mVideoInfo(NULL)
{
mCameraHandle = open("/dev/video11", O_RDWR| O_NONBLOCK);
- if (mCameraHandle < 0)
- {
+ if (mCameraHandle < 0){
ALOGE("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
}
mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
- if (mVideoInfo == NULL)
- {
+ if (mVideoInfo == NULL){
ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__);
}
- mBufferCount = 4;
- mPixelFormat = V4L2_PIX_FMT_NV21;
- mNativeWindowPixelFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
- mFrameWidth = 1280;
- mFrameHeight = 720;
- mBufferSize = mFrameWidth * mFrameHeight * 3/2;
- mSetStateCB = NULL;
- mState = STOP;
- mANativeWindow = NULL;
- mFrameType = 0;
- mWorkThread = NULL;
- mDataCB = NULL;
- mOpen = false;
-
+ mBufferCount = 4;
+ mPixelFormat = V4L2_PIX_FMT_NV21;
+ mNativeWindowPixelFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ mFrameWidth = 1280;
+ mFrameHeight = 720;
+ mBufferSize = mFrameWidth * mFrameHeight * 3/2;
+ mSetStateCB = NULL;
+ mState = STOP;
+ mANativeWindow = NULL;
+ mFrameType = 0;
+ mWorkThread = NULL;
+ mDataCB = NULL;
+ mOpen = false;
}
vdin_screen_source::~vdin_screen_source()
{
if (mVideoInfo)
- {
free (mVideoInfo);
- }
- if (mCameraHandle >= 0)
- {
+ if (mCameraHandle >= 0)
close(mCameraHandle);
- }
}
int vdin_screen_source::start_v4l2_device()
@@ -176,7 +168,7 @@ int vdin_screen_source::start_v4l2_device()
ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
if (ret < 0) {
- ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
+ ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
return ret;
}
@@ -200,7 +192,7 @@ int vdin_screen_source::start_v4l2_device()
ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__);
return -1;
}
- mVideoInfo->refcount[i] = 0;
+ mVideoInfo->refcount[i] = 0;
mBufs.add((int)mVideoInfo->mem[i],i);
}
ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__);
@@ -224,54 +216,57 @@ int vdin_screen_source::start_v4l2_device()
return ret;
}
-int vdin_screen_source::start(){
- ALOGV("%s %d", __FUNCTION__, __LINE__);
- int ret;
- if(mOpen == true){
- ALOGI("already open");
- return NO_ERROR;
- }
+int vdin_screen_source::start()
+{
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
+ int ret;
+ if(mOpen == true){
+ ALOGI("already open");
+ return NO_ERROR;
+ }
- ret = start_v4l2_device();
- if(ret != NO_ERROR){
- ALOGE("Start v4l2 device failed:%d",ret);
- return ret;
- }
- if(mFrameType & NATIVE_WINDOW_DATA){
- ret = init_native_window();
- if(ret != NO_ERROR){
- ALOGE("Init Native Window Failed:%d",ret);
- return ret;
- }
- }
- if(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA){
- ALOGD("Create Work Thread");
- mWorkThread = new WorkThread(this);
- }
- if(mSetStateCB != NULL)
- mSetStateCB(START);
- mState = START;
- mOpen = true;
- ALOGV("%s %d ret:%d", __FUNCTION__, __LINE__, ret);
- return NO_ERROR;
+ ret = start_v4l2_device();
+ if(ret != NO_ERROR){
+ ALOGE("Start v4l2 device failed:%d",ret);
+ return ret;
+ }
+ if(mFrameType & NATIVE_WINDOW_DATA){
+ ret = init_native_window();
+ if(ret != NO_ERROR){
+ ALOGE("Init Native Window Failed:%d",ret);
+ return ret;
+ }
+ }
+ if(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA){
+ ALOGD("Create Work Thread");
+ mWorkThread = new WorkThread(this);
+ }
+ if(mSetStateCB != NULL)
+ mSetStateCB(START);
+ mState = START;
+ mOpen = true;
+ ALOGV("%s %d ret:%d", __FUNCTION__, __LINE__, ret);
+ return NO_ERROR;
}
-int vdin_screen_source::pause(){
- ALOGV("%s %d", __FUNCTION__, __LINE__);
- mState = PAUSE;
- if(mSetStateCB != NULL)
- mSetStateCB(PAUSE);
- return NO_ERROR;
+int vdin_screen_source::pause()
+{
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
+ mState = PAUSE;
+ if(mSetStateCB != NULL)
+ mSetStateCB(PAUSE);
+ return NO_ERROR;
}
int vdin_screen_source::stop()
{
- ALOGV("%s %d", __FUNCTION__, __LINE__);
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
int ret;
+ mState = STOPING;
- if(mWorkThread != NULL){
- mWorkThread->requestExitAndWait();
- mWorkThread.clear();
- }
+ if(mWorkThread != NULL){
+ mWorkThread->requestExitAndWait();
+ mWorkThread.clear();
+ }
enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -279,63 +274,62 @@ int vdin_screen_source::stop()
if (ret < 0) {
ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
}
- for (int i = 0; i < mBufferCount; i++)
- {
+ for (int i = 0; i < mBufferCount; i++){
if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0)
ALOGE("Unmap failed");
}
- mBufferCount = 0;
- mState = STOP;
- if(mSetStateCB != NULL)
- mSetStateCB(STOP);
- mOpen = false;
+ mBufferCount = 0;
+ mState = STOP;
+ if(mSetStateCB != NULL)
+ mSetStateCB(STOP);
+ mOpen = false;
return ret;
}
-int vdin_screen_source::set_state_callback(olStateCB callback){
- if (!callback){
- ALOGE("NULL state callback pointer");
- return BAD_VALUE;
- }
- mSetStateCB = callback;
- return NO_ERROR;
+int vdin_screen_source::set_state_callback(olStateCB callback)
+{
+ if (!callback){
+ ALOGE("NULL state callback pointer");
+ return BAD_VALUE;
+ }
+ mSetStateCB = callback;
+ return NO_ERROR;
}
int vdin_screen_source::set_preview_window(ANativeWindow* window)
{
- ALOGV("%s %d", __FUNCTION__, __LINE__);
- if(mOpen == true)
- return NO_ERROR;
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
+ if(mOpen == true)
+ return NO_ERROR;
//can work without a valid window object ?
- if (window == NULL)
- {
+ if (window == NULL){
ALOGD("NULL window object passed to ScreenSource");
- if(mWorkThread != NULL){
- mWorkThread->requestExitAndWait();
- mWorkThread.clear();
- }
- mFrameType &= ~NATIVE_WINDOW_DATA;
+ if(mWorkThread != NULL){
+ mWorkThread->requestExitAndWait();
+ mWorkThread.clear();
+ }
+ mFrameType &= ~NATIVE_WINDOW_DATA;
return NO_ERROR;
}
- mFrameType |= NATIVE_WINDOW_DATA;
+ mFrameType |= NATIVE_WINDOW_DATA;
mANativeWindow = window;
return NO_ERROR;
}
-int vdin_screen_source::set_data_callback(app_data_callback callback, void* user){
- ALOGV("%s %d", __FUNCTION__, __LINE__);
- if (callback == NULL){
- ALOGE("NULL data callback pointer");
- return BAD_VALUE;
- }
- mDataCB = callback;
- mUser = user;
- mFrameType |= CALL_BACK_DATA;
- return NO_ERROR;
+int vdin_screen_source::set_data_callback(app_data_callback callback, void* user)
+{
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
+ if (callback == NULL){
+ ALOGE("NULL data callback pointer");
+ return BAD_VALUE;
+ }
+ mDataCB = callback;
+ mUser = user;
+ mFrameType |= CALL_BACK_DATA;
+ return NO_ERROR;
}
-
int vdin_screen_source::get_format()
{
return mPixelFormat;
@@ -344,8 +338,8 @@ int vdin_screen_source::get_format()
int vdin_screen_source::set_format(int width, int height, int color_format)
{
ALOGV("[%s %d]", __FUNCTION__, __LINE__);
- if(mOpen == true)
- return NO_ERROR;
+ if(mOpen == true)
+ return NO_ERROR;
int ret;
mVideoInfo->width = ALIGN(width);
mVideoInfo->height = height;
@@ -356,19 +350,18 @@ int vdin_screen_source::set_format(int width, int height, int color_format)
mVideoInfo->format.fmt.pix.width = ALIGN(width);
mVideoInfo->format.fmt.pix.height = height;
mVideoInfo->format.fmt.pix.pixelformat = color_format;
- mPixelFormat = color_format;
- mNativeWindowPixelFormat = getNativeWindowFormat(color_format);
- mFrameWidth = ALIGN(width);
- mFrameHeight = height;
- mBufferSize = getBufSize(color_format, mFrameWidth, mFrameHeight);
- ALOGD("mFrameWidth:%d,mFrameHeight:%d",mFrameWidth,mFrameHeight);
- ALOGD("mPixelFormat:%x,mNativeWindowPixelFormat:%x,mBufferSize:%d",mPixelFormat,mNativeWindowPixelFormat,mBufferSize);
+ mPixelFormat = color_format;
+ mNativeWindowPixelFormat = getNativeWindowFormat(color_format);
+ mFrameWidth = ALIGN(width);
+ mFrameHeight = height;
+ mBufferSize = getBufSize(color_format, mFrameWidth, mFrameHeight);
+ ALOGD("mFrameWidth:%d,mFrameHeight:%d",mFrameWidth,mFrameHeight);
+ ALOGD("mPixelFormat:%x,mNativeWindowPixelFormat:%x,mBufferSize:%d",mPixelFormat,mNativeWindowPixelFormat,mBufferSize);
ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
if (ret < 0) {
ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret);
return ret;
}
-
return ret;
}
@@ -395,9 +388,7 @@ int vdin_screen_source::set_rotation(int degree)
if(ret<0){
ALOGE("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
}
-
return ret ;
-
}
int vdin_screen_source::set_crop(int x, int y, int width, int height)
@@ -413,7 +404,6 @@ int vdin_screen_source::set_crop(int x, int y, int width, int height)
ALOGW("Failed to set crop!");
return err;
}
-
return NO_ERROR;
}
@@ -436,9 +426,7 @@ int vdin_screen_source::set_frame_rate(int frameRate)
if(ret < 0){
ALOGE("Set frame rate fail: %s. ret=%d", strerror(errno),ret);
}
-
return ret ;
-
}
int vdin_screen_source::set_source_type(int sourceType)
@@ -451,7 +439,6 @@ int vdin_screen_source::set_source_type(int sourceType)
ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
}
return ret;
-
}
int vdin_screen_source::get_source_type()
@@ -466,7 +453,6 @@ int vdin_screen_source::get_source_type()
return ret;
}
return sourceType;
-
}
int vdin_screen_source::aquire_buffer(int *buff_info)
@@ -489,6 +475,8 @@ int vdin_screen_source::aquire_buffer(int *buff_info)
}
buff_info[0] = (unsigned)mVideoInfo->mem[mVideoInfo->buf.index];
buff_info[1] = (unsigned)mVideoInfo->canvas[mVideoInfo->buf.index];
+ buff_info[2] = mVideoInfo->buf.timestamp.tv_sec;
+ buff_info[3] = mVideoInfo->buf.timestamp.tv_usec;
return ret;
}
@@ -505,142 +493,158 @@ int vdin_screen_source::release_buffer(int* ptr)
{
ALOGV("%s %d", __FUNCTION__, __LINE__);
int ret = -1;
- int currentIndex;
+ int currentIndex;
v4l2_buffer hbuf_query;
- currentIndex = mBufs.valueFor((unsigned int)ptr);
- if(mVideoInfo->refcount[currentIndex] > 0)
- mVideoInfo->refcount[currentIndex] -= 1;
- else {
- ALOGE("return buffer when refcount already zero");
- return 0;
- }
- if(mVideoInfo->refcount[currentIndex] == 0){
- memset(&hbuf_query,0,sizeof(v4l2_buffer));
- hbuf_query.index = currentIndex;
- hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- hbuf_query.memory = V4L2_MEMORY_MMAP;
+ Mutex::Autolock autoLock(mLock);
+
+ currentIndex = mBufs.valueFor((unsigned int)ptr);
+ if(mVideoInfo->refcount[currentIndex] > 0){
+ mVideoInfo->refcount[currentIndex] -= 1;
+ }else{
+ ALOGE("return buffer when refcount already zero");
+ return 0;
+ }
+ if(mVideoInfo->refcount[currentIndex] == 0){
+ memset(&hbuf_query,0,sizeof(v4l2_buffer));
+ hbuf_query.index = currentIndex;
+ hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ hbuf_query.memory = V4L2_MEMORY_MMAP;
ALOGV("return buffer :%d",currentIndex);
- ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
+ ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
if(ret != 0){
ALOGE("Return Buffer :%d failed", currentIndex);
}
- }
+ }
return 0;
}
-int vdin_screen_source::init_native_window(){
- ALOGV("%s %d", __FUNCTION__, __LINE__);
- int err = NO_ERROR;
+int vdin_screen_source::init_native_window()
+{
+ ALOGV("%s %d", __FUNCTION__, __LINE__);
+ int err = NO_ERROR;
- if ( NULL == mANativeWindow.get() ) {
- return BAD_VALUE;
- }
-
- // Set gralloc usage bits for window.
- err = native_window_set_usage(mANativeWindow.get(), SCREENSOURCE_GRALLOC_USAGE);
- if (err != 0) {
- ALOGE("native_window_set_usage failed: %s\n", strerror(-err));
-
- if ( ENODEV == err ) {
- ALOGE("Preview surface abandoned!");
- mANativeWindow = NULL;
- }
-
- return err;
- }
-
- ALOGD("Number of buffers set to ANativeWindow %d", mBufferCount);
- ///Set the number of buffers needed for camera preview
- err = native_window_set_buffer_count(mANativeWindow.get(), mBufferCount);
- if (err != 0) {
- ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
-
- if ( ENODEV == err ) {
- ALOGE("Preview surface abandoned!");
- mANativeWindow = NULL;
- }
-
- return err;
- }
+ if(NULL == mANativeWindow.get())
+ return BAD_VALUE;
+
+ // Set gralloc usage bits for window.
+ err = native_window_set_usage(mANativeWindow.get(), SCREENSOURCE_GRALLOC_USAGE);
+ if (err != 0) {
+ ALOGE("native_window_set_usage failed: %s\n", strerror(-err));
+ if(ENODEV == err ){
+ ALOGE("Preview surface abandoned!");
+ mANativeWindow = NULL;
+ }
+ return err;
+ }
+
+ ALOGD("Number of buffers set to ANativeWindow %d", mBufferCount);
+ ///Set the number of buffers needed for camera preview
+ err = native_window_set_buffer_count(mANativeWindow.get(), mBufferCount);
+ if (err != 0) {
+ ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
+ if(ENODEV == err){
+ ALOGE("Preview surface abandoned!");
+ mANativeWindow = NULL;
+ }
+ return err;
+ }
- ALOGD("native_window_set_buffers_geometry format:0x%x",mNativeWindowPixelFormat);
- // Set window geometry
- err = native_window_set_buffers_geometry(
- mANativeWindow.get(),
- mFrameWidth,
- mFrameHeight,
- mNativeWindowPixelFormat);
-
- if (err != 0) {
- ALOGE("native_window_set_buffers_geometry failed: %s", strerror(-err));
-
- if ( ENODEV == err ) {
- ALOGE("Surface abandoned!");
- mANativeWindow = NULL;
- }
-
- return err;
- }
- err = native_window_set_scaling_mode(
- mANativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+ ALOGD("native_window_set_buffers_geometry format:0x%x",mNativeWindowPixelFormat);
+ // Set window geometry
+ err = native_window_set_buffers_geometry(
+ mANativeWindow.get(),
+ mFrameWidth,
+ mFrameHeight,
+ mNativeWindowPixelFormat);
+
+ if (err != 0) {
+ ALOGE("native_window_set_buffers_geometry failed: %s", strerror(-err));
+ if ( ENODEV == err ) {
+ ALOGE("Surface abandoned!");
+ mANativeWindow = NULL;
+ }
+ return err;
+ }
+ err = native_window_set_scaling_mode(mANativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
if (err != 0) {
ALOGW("Failed to set scaling mode: %d", err);
- return err;
+ return err;
}
-
- return NO_ERROR;
+ return NO_ERROR;
}
-
-int vdin_screen_source::workThread(){
- int index;
- int buff_info[2];
- int ret;
- unsigned char *src = NULL;
- unsigned char *dest = NULL;
- uint8_t *handle = NULL;
- ANativeWindowBuffer* buf;
- if(mState == START){
- usleep(5000);
- ret = aquire_buffer(buff_info);
- if(ret != 0 || (buff_info[0] == 0)){
+int vdin_screen_source::workThread()
+{
+ bool buff_keep = false;
+ int index;
+ int buff_info[4], buff_info_latest[4];
+ int ret;
+ unsigned char *src = NULL;
+ unsigned char *dest = NULL;
+ uint8_t *handle = NULL;
+ ANativeWindowBuffer* buf;
+ if(mState == START){
+ usleep(5000);
+#if 0
+ ret = aquire_buffer(buff_info);
+#else
+ while(mState == START){
+ ret = aquire_buffer(buff_info);
+ if(ret != 0){
+ if(true == buff_keep){//use the latest buffer
+ memcpy(buff_info, buff_info_latest, 16);
+ ret = 0;
+ }
+ break;
+ }else{
+ if(true == buff_keep){
+ //release
+ ALOGD("v4l2 vdin drop frame");
+ release_buffer((int *)(buff_info_latest[0]));
+ }
+ buff_keep = true;
+ memcpy(buff_info_latest, buff_info, 16);
+ }
+ }
+#endif
+ if(ret != 0 || (buff_info[0] == 0)){
ALOGV("Get V4l2 buffer failed");
- return ret;
- }
- src = (unsigned char *)buff_info[0];
- index = mBufs.valueFor((unsigned int)src);
- if(mFrameType & NATIVE_WINDOW_DATA){
- mVideoInfo->refcount[index] += 1;
- if(mANativeWindow.get() == NULL){
- ALOGE("Null window");
- return BAD_VALUE;
- }
- ret = mANativeWindow->dequeueBuffer_DEPRECATED(mANativeWindow.get(), &buf);
- if(ret != 0){
- ALOGE("dequeue buffer failed :%s (%d)",strerror(-ret), -ret);
- return BAD_VALUE;
- }
- mANativeWindow->lockBuffer_DEPRECATED(mANativeWindow.get(), buf);
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest);
- if(dest == NULL){
- ALOGE("Invalid Gralloc Handle");
- return BAD_VALUE;
- }
- memcpy(dest, src, mBufferSize);
- graphicBuffer->unlock();
- mANativeWindow->queueBuffer_DEPRECATED(mANativeWindow.get(), buf);
- graphicBuffer.clear();
+ return ret;
+ }
+ src = (unsigned char *)buff_info[0];
+ index = mBufs.valueFor((unsigned int)src);
+ if(mFrameType & NATIVE_WINDOW_DATA){
+ mVideoInfo->refcount[index] += 1;
+ if(mANativeWindow.get() == NULL){
+ ALOGE("Null window");
+ return BAD_VALUE;
+ }
+ ret = mANativeWindow->dequeueBuffer_DEPRECATED(mANativeWindow.get(), &buf);
+ if(ret != 0){
+ ALOGE("dequeue buffer failed :%s (%d)",strerror(-ret), -ret);
+ return BAD_VALUE;
+ }
+ mANativeWindow->lockBuffer_DEPRECATED(mANativeWindow.get(), buf);
+ sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
+ graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest);
+ if(dest == NULL){
+ ALOGE("Invalid Gralloc Handle");
+ return BAD_VALUE;
+ }
+ memcpy(dest, src, mBufferSize);
+ graphicBuffer->unlock();
+ mANativeWindow->queueBuffer_DEPRECATED(mANativeWindow.get(), buf);
+ graphicBuffer.clear();
ALOGV("queue one buffer to native window");
- release_buffer((int*)src);
- }
- if(mFrameType & CALL_BACK_DATA && mDataCB != NULL){
- mVideoInfo->refcount[index] += 1;
- mDataCB(mUser, buff_info);
- }
- }
- return NO_ERROR;
+ release_buffer((int*)src);
+ }
+ if(mFrameType & CALL_BACK_DATA && mDataCB != NULL&& mState == START){
+ mVideoInfo->refcount[index] += 1;
+ mDataCB(mUser, buff_info);
+ }
+ }
+ return NO_ERROR;
}
}
diff --git a/v4l2_vdin.h b/v4l2_vdin.h
index 0183464..19f2ea0 100755
--- a/v4l2_vdin.h
+++ b/v4l2_vdin.h
@@ -45,7 +45,7 @@ struct VideoInfo {
struct v4l2_requestbuffers rb;
void *mem[NB_BUFFER];
unsigned canvas[NB_BUFFER];
- unsigned refcount[NB_BUFFER];
+ unsigned refcount[NB_BUFFER];
bool isStreaming;
int width;
int height;
@@ -53,20 +53,20 @@ struct VideoInfo {
int framesizeIn;
};
enum State{
- START,
- PAUSE,
- STOP,
+ START,
+ PAUSE,
+ STOPING,
+ STOP,
};
enum FrameType{
- NATIVE_WINDOW_DATA = 0x1,
- CALL_BACK_DATA = 0x2,
+ NATIVE_WINDOW_DATA = 0x1,
+ CALL_BACK_DATA = 0x2,
};
typedef void (*olStateCB)(int state);
-typedef void (*app_data_callback)(void *user,
- int *buffer);
+typedef void (*app_data_callback)(void *user,int *buffer);
#define SCREENSOURCE_GRALLOC_USAGE GRALLOC_USAGE_HW_TEXTURE | \
GRALLOC_USAGE_HW_RENDER | \
@@ -80,59 +80,59 @@ class vdin_screen_source {
int start();
int stop();
- int pause();
+ int pause();
int get_format();
int set_format(int width = 640, int height = 480, int color_format = V4L2_PIX_FMT_NV21);
int set_rotation(int degree);
int set_crop(int x, int y, int width, int height);
int aquire_buffer(int* buff_info);
- // int inc_buffer_refcount(int* ptr);
+ // int inc_buffer_refcount(int* ptr);
int release_buffer(int* ptr);
- int set_state_callback(olStateCB callback);
- int set_data_callback(app_data_callback callback, void* user);
- int set_preview_window(ANativeWindow* window);
+ int set_state_callback(olStateCB callback);
+ int set_data_callback(app_data_callback callback, void* user);
+ int set_preview_window(ANativeWindow* window);
int set_frame_rate(int frameRate);
int set_source_type(int sourceType);
int get_source_type();
- private:
- int init_native_window();
- int start_v4l2_device();
- int workThread();
- private:
- class WorkThread : public Thread {
+ private:
+ int init_native_window();
+ int start_v4l2_device();
+ int workThread();
+ private:
+ class WorkThread : public Thread {
vdin_screen_source* mSource;
- public:
- WorkThread(vdin_screen_source* source) :
+ public:
+ WorkThread(vdin_screen_source* source) :
Thread(false), mSource(source) { }
- virtual void onFirstRef() {
- run("vdin screen source work thread", PRIORITY_URGENT_DISPLAY);
- }
- virtual bool threadLoop() {
- mSource->workThread();
- // loop until we need to quit
- return true;
- }
+ virtual void onFirstRef() {
+ run("vdin screen source work thread", PRIORITY_URGENT_DISPLAY);
+ }
+ virtual bool threadLoop() {
+ mSource->workThread();
+ // loop until we need to quit
+ return true;
+ }
};
private:
- int mCurrentIndex;
- KeyedVector<int, int> mBufs;
- int mBufferCount;
- int mFrameWidth;
- int mFrameHeight;
- int mBufferSize;
- volatile int mState;
- olStateCB mSetStateCB;
- int mPixelFormat;
- int mNativeWindowPixelFormat;
- sp<ANativeWindow> mANativeWindow;
- sp<WorkThread> mWorkThread;
- mutable Mutex mLock;
- int mCameraHandle;
- struct VideoInfo *mVideoInfo;
- int mFrameType;
- app_data_callback mDataCB;
- bool mOpen;
- void *mUser;
+ int mCurrentIndex;
+ KeyedVector<int, int> mBufs;
+ int mBufferCount;
+ int mFrameWidth;
+ int mFrameHeight;
+ int mBufferSize;
+ volatile int mState;
+ olStateCB mSetStateCB;
+ int mPixelFormat;
+ int mNativeWindowPixelFormat;
+ sp<ANativeWindow> mANativeWindow;
+ sp<WorkThread> mWorkThread;
+ mutable Mutex mLock;
+ int mCameraHandle;
+ struct VideoInfo *mVideoInfo;
+ int mFrameType;
+ app_data_callback mDataCB;
+ bool mOpen;
+ void *mUser;
};
} \ No newline at end of file