From 8c533254831f51de0944c54314d8a2a236717cb4 Mon Sep 17 00:00:00 2001 From: brian.zhu Date: Fri, 18 Jul 2014 20:15:50 +0000 Subject: PD#89978, use kernel time stamp, fix block issue when stop. skip late frame --- 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(module); - dev->common.close = aml_screen_device_close; + dev->common.tag = HARDWARE_DEVICE_TAG; + dev->common.version = 0; + dev->common.module = const_cast(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(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(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 mBufs; - int mBufferCount; - int mFrameWidth; - int mFrameHeight; - int mBufferSize; - volatile int mState; - olStateCB mSetStateCB; - int mPixelFormat; - int mNativeWindowPixelFormat; - sp mANativeWindow; - sp mWorkThread; - mutable Mutex mLock; - int mCameraHandle; - struct VideoInfo *mVideoInfo; - int mFrameType; - app_data_callback mDataCB; - bool mOpen; - void *mUser; + int mCurrentIndex; + KeyedVector mBufs; + int mBufferCount; + int mFrameWidth; + int mFrameHeight; + int mBufferSize; + volatile int mState; + olStateCB mSetStateCB; + int mPixelFormat; + int mNativeWindowPixelFormat; + sp mANativeWindow; + sp 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 -- cgit