From 83805f317038b0c46e239f29dc72782eb6d60b37 Mon Sep 17 00:00:00 2001 From: Guosong Zhou Date: Fri, 14 Aug 2015 13:17:25 +0000 Subject: PD#111061:fix usb camera plug problem Change-Id: I373b270fa07cbb48247094e821d03bf030f6248a --- diff --git a/v3/EmulatedBaseCamera.cpp b/v3/EmulatedBaseCamera.cpp index 28b4063..70af1b5 100644 --- a/v3/EmulatedBaseCamera.cpp +++ b/v3/EmulatedBaseCamera.cpp @@ -55,15 +55,10 @@ EmulatedBaseCamera::~EmulatedBaseCamera() { } -void EmulatedBaseCamera::setCameraStatus(camera_status_t status) +bool EmulatedBaseCamera::getCameraStatus() { ALOGE("%s: do nothing", __FUNCTION__); -} - -camera_status_t EmulatedBaseCamera::getCameraStatus() -{ - ALOGE("%s: do nothing", __FUNCTION__); - return CAMERA_READY_REMOVE; + return false; } status_t EmulatedBaseCamera::getCameraInfo(struct camera_info* info) diff --git a/v3/EmulatedBaseCamera.h b/v3/EmulatedBaseCamera.h index 53cf329..0bf8948 100644 --- a/v3/EmulatedBaseCamera.h +++ b/v3/EmulatedBaseCamera.h @@ -57,8 +57,7 @@ class EmulatedBaseCamera { * NO_ERROR on success, or an appropriate error status on failure. */ virtual status_t Initialize() = 0; - virtual void setCameraStatus(camera_status_t status) = 0; - virtual camera_status_t getCameraStatus() = 0; + virtual bool getCameraStatus() = 0; /**************************************************************************** * Camera API implementation ***************************************************************************/ diff --git a/v3/EmulatedCamera3.cpp b/v3/EmulatedCamera3.cpp index 30d6364..0cd6a3e 100644 --- a/v3/EmulatedCamera3.cpp +++ b/v3/EmulatedCamera3.cpp @@ -80,15 +80,10 @@ status_t EmulatedCamera3::Initialize() { return NO_ERROR; } -void EmulatedCamera3::setCameraStatus(camera_status_t status) +bool EmulatedCamera3::getCameraStatus() { DBG_LOGB("%s : do nothing", __FUNCTION__); -} - -camera_status_t EmulatedCamera3::getCameraStatus() -{ - DBG_LOGB("%s : do nothing", __FUNCTION__); - return CAMERA_READY_REMOVE; + return false; } /**************************************************************************** diff --git a/v3/EmulatedCamera3.h b/v3/EmulatedCamera3.h index b7be30e..3e43af8 100644 --- a/v3/EmulatedCamera3.h +++ b/v3/EmulatedCamera3.h @@ -67,8 +67,7 @@ public: public: virtual status_t Initialize(); - virtual void setCameraStatus(camera_status_t status); - virtual camera_status_t getCameraStatus(); + virtual bool getCameraStatus(); /**************************************************************************** * Camera module API and generic hardware device API implementation diff --git a/v3/EmulatedCameraFactory.cpp b/v3/EmulatedCameraFactory.cpp index ea25c91..0f6a6fa 100755..100644 --- a/v3/EmulatedCameraFactory.cpp +++ b/v3/EmulatedCameraFactory.cpp @@ -127,6 +127,17 @@ EmulatedCameraFactory::~EmulatedCameraFactory() } } +int EmulatedCameraFactory::getValidCameraId() { + int iValidId = 0; + for (int i = 0; i < MAX_CAMERA_NUM; i++ ) { + if (0 == access(SENSOR_PATH[i], F_OK | R_OK | W_OK)) { + iValidId = i; + break; + } + } + return iValidId; +} + /**************************************************************************** * Camera HAL API handlers. * @@ -138,7 +149,7 @@ EmulatedCameraFactory::~EmulatedCameraFactory() int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device) { ALOGV("%s: id = %d", __FUNCTION__, camera_id); - + int valid_id; *device = NULL; if (!isConstructedOK()) { @@ -151,14 +162,15 @@ int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device) __FUNCTION__, camera_id, getEmulatedCameraNum()); return -ENODEV; } - - return mEmulatedCameras[camera_id]->connectCamera(device); + valid_id = getValidCameraId(); + //return mEmulatedCameras[camera_id]->connectCamera(device); + return mEmulatedCameras[valid_id]->connectCamera(device); } int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info) { ALOGV("%s: id = %d", __FUNCTION__, camera_id); - + int valid_id; if (!isConstructedOK()) { ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__); return -EINVAL; @@ -169,8 +181,9 @@ int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info __FUNCTION__, camera_id, getEmulatedCameraNum()); return -ENODEV; } - - return mEmulatedCameras[camera_id]->getCameraInfo(info); + valid_id = getValidCameraId(); + //return mEmulatedCameras[camera_id]->getCameraInfo(info); + return mEmulatedCameras[valid_id]->getCameraInfo(info); } int EmulatedCameraFactory::setCallbacks( @@ -216,6 +229,30 @@ void EmulatedCameraFactory::getvendortagops(vendor_tag_ops_t* ops) * Camera HAL API callbacks. ***************************************************************************/ +EmulatedBaseCamera* EmulatedCameraFactory::getValidCameraOject() +{ + EmulatedBaseCamera* cam = NULL; + for (int i = 0; i < MAX_CAMERA_NUM; i++) { + if (mEmulatedCameras[i] != NULL) { + cam = mEmulatedCameras[i]; + break; + } + } + return cam; +} + +int EmulatedCameraFactory::getValidCameraOjectId() +{ + int j =0; + for (int i = 0; i < MAX_CAMERA_NUM; i++) { + if (mEmulatedCameras[i] != NULL) { + j = i; + break; + } + } + return j; +} + int EmulatedCameraFactory::device_open(const hw_module_t* module, const char* name, hw_device_t** device) @@ -240,6 +277,21 @@ int EmulatedCameraFactory::device_open(const hw_module_t* module, int EmulatedCameraFactory::get_number_of_cameras(void) { + int i = 0; + EmulatedBaseCamera* cam = gEmulatedCameraFactory.getValidCameraOject(); + while (i < 6) { + if (cam != NULL) { + if (!cam->getHotplugStatus()) { + DBG_LOGA("here we wait usb camera plug"); + usleep(50000); + i++; + } else { + break; + } + } else { + break; + } + } return gEmulatedCameraFactory.getEmulatedCameraNum(); } @@ -415,7 +467,8 @@ void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) { status_t res; char dev_name[128]; - int i = 0; + int i = 0 , j = 0; + int m = 0, n = 0; //EmulatedBaseCamera *cam = mEmulatedCameras[cameraId]; const camera_module_callbacks_t* cb = mCallbacks; sprintf(dev_name, "%s%d", "/dev/video", cameraId); @@ -427,34 +480,30 @@ void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) return; CAMHAL_LOGDB("mEmulatedCameraNum =%d\n", mEmulatedCameraNum); - - /*we release mEmulatedCameras[i] object for the last time construct*/ - for (int i = 0; i < MAX_CAMERA_NUM; i++) { - if ((mEmulatedCameras[i] != NULL) && (mEmulatedCameras[i]->getCameraStatus() == CAMERA_READY_REMOVE)) { - mEmulatedCameras[i]->setCameraStatus(CAMERA_INIT); - delete mEmulatedCameras[i]; - mEmulatedCameras[i] = NULL; - } + n = getValidCameraOjectId(); + if ((n != cameraId) && (mEmulatedCameras[n] != NULL)) { + mEmulatedCameras[n]->unplugCamera(); + delete mEmulatedCameras[n]; + mEmulatedCameras[n] = NULL; } EmulatedBaseCamera *cam = mEmulatedCameras[cameraId]; - if (!cam) { + if ((!cam) && (newStatus == CAMERA_DEVICE_STATUS_PRESENT)) { /*suppose only usb camera produce uevent, and it is facing back*/ cam = new EmulatedFakeCamera3(cameraId, &HAL_MODULE_INFO_SYM.common); if (cam != NULL) { - cam->setCameraStatus(CAMERA_INIT); CAMHAL_LOGDB("%s: new camera device version is %d", __FUNCTION__, getFakeCameraHalVersion(cameraId)); //sleep 10ms for /dev/video* create - usleep(200000); - while (i < 4) { + usleep(50000); + while (i < 20) { if (0 == access(dev_name, F_OK | R_OK | W_OK)) { DBG_LOGB("access %s success\n", dev_name); break; } else { - DBG_LOGB("access %s fail , i = %d .\n", dev_name,i); - usleep(200000); + CAMHAL_LOGDB("access %s fail , i = %d .\n", dev_name,i); + usleep(50000); i++; } } @@ -499,15 +548,24 @@ void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) CAMHAL_LOGDB("mEmulatedCameraNum =%d\n", mEmulatedCameraNum); -/*don't delete mEmulatedCameras[i], or will generate crash*/ if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) { - //cam->unplugCamera(); -//// - //delete mEmulatedCameras[cameraId]; - //mEmulatedCameras[cameraId] = NULL; - mEmulatedCameras[cameraId]->setCameraStatus(CAMERA_READY_REMOVE); + j = getValidCameraOjectId(); + while (m < 2000) { + if (mEmulatedCameras[j] != NULL) { + if (mEmulatedCameras[j]->getCameraStatus()) { + DBG_LOGA("start to delete EmulatedFakeCamera3 object"); + cam->unplugCamera(); + delete mEmulatedCameras[j]; + mEmulatedCameras[j] = NULL; + } else { + usleep(5000); + m++; + } + } else { + break; + } + } mEmulatedCameraNum --; -//// } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) { CAMHAL_LOGDA("camera plugged again?\n"); cam->plugCamera(); diff --git a/v3/EmulatedCameraFactory.h b/v3/EmulatedCameraFactory.h index 504f842..c844c56 100755..100644 --- a/v3/EmulatedCameraFactory.h +++ b/v3/EmulatedCameraFactory.h @@ -78,6 +78,9 @@ public: ***************************************************************************/ public: + EmulatedBaseCamera* getValidCameraOject(void); + + int getValidCameraOjectId(void); /* Opens (connects to) a camera device. * This method is called in response to hw_module_methods_t::open callback. */ @@ -151,6 +154,8 @@ public: void onStatusChanged(int cameraId, int newStatus); + int getValidCameraId(void); + /**************************************************************************** * Private API ***************************************************************************/ diff --git a/v3/EmulatedFakeCamera3.cpp b/v3/EmulatedFakeCamera3.cpp index 12f5eda..c9ca6c1 100644 --- a/v3/EmulatedFakeCamera3.cpp +++ b/v3/EmulatedFakeCamera3.cpp @@ -317,8 +317,7 @@ status_t EmulatedFakeCamera3::unplugCamera() { mPlugged = false; } } - - return closeCamera(); + return true; } camera_device_status_t EmulatedFakeCamera3::getHotplugStatus() { @@ -328,15 +327,16 @@ camera_device_status_t EmulatedFakeCamera3::getHotplugStatus() { CAMERA_DEVICE_STATUS_NOT_PRESENT; } -void EmulatedFakeCamera3::setCameraStatus(camera_status_t status) -{ - mCameraStatus = status; -} - -camera_status_t EmulatedFakeCamera3::getCameraStatus() +bool EmulatedFakeCamera3::getCameraStatus() { CAMHAL_LOGVB("%s, mCameraStatus = %d",__FUNCTION__,mCameraStatus); - return mCameraStatus; + bool ret = false; + if (mStatus == STATUS_CLOSED) { + ret = true; + } else { + ret = false; + } + return ret; } status_t EmulatedFakeCamera3::closeCamera() { @@ -2615,6 +2615,15 @@ void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e, sendNotify(&msg); break; } + case Sensor::SensorListener::ERROR_CAMERA_DEVICE: { + camera3_notify_msg_t msg; + msg.type = CAMERA3_MSG_ERROR; + msg.message.error.frame_number = frameNumber; + msg.message.error.error_stream = NULL; + msg.message.error.error_code = 1; + sendNotify(&msg); + break; + } default: ALOGW("%s: Unexpected sensor event %d at %" PRId64, __FUNCTION__, e, timestamp); diff --git a/v3/EmulatedFakeCamera3.h b/v3/EmulatedFakeCamera3.h index 4968f28..4a23f26 100644 --- a/v3/EmulatedFakeCamera3.h +++ b/v3/EmulatedFakeCamera3.h @@ -79,8 +79,7 @@ public: virtual status_t closeCamera(); virtual status_t getCameraInfo(struct camera_info *info); - virtual void setCameraStatus(camera_status_t status); - virtual camera_status_t getCameraStatus(); + virtual bool getCameraStatus(); /**************************************************************************** * EmulatedCamera3 abstract API implementation diff --git a/v3/fake-pipeline2/Sensor.cpp b/v3/fake-pipeline2/Sensor.cpp index aea3ab0..b0b5fbe 100755..100644 --- a/v3/fake-pipeline2/Sensor.cpp +++ b/v3/fake-pipeline2/Sensor.cpp @@ -191,7 +191,7 @@ status_t Sensor::startUp(int idx) { int res; mCapturedBuffers = NULL; - res = run("EmulatedFakeCamera2::Sensor", + res = run("EmulatedFakeCamera3::Sensor", ANDROID_PRIORITY_URGENT_DISPLAY); if (res != OK) { @@ -405,7 +405,13 @@ int Sensor::halFormatToSensorFormat(uint32_t pixelfmt) fmt.index++; } - ALOGE("Unable to find a supported sensor format!"); + fmt.index = 0; + while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0) { + if (fmt.pixelformat == V4L2_PIX_FMT_YUYV) + return V4L2_PIX_FMT_YUYV; + fmt.index++; + } + ALOGE("%s, Unable to find a supported sensor format!", __FUNCTION__); return BAD_VALUE; } @@ -1037,6 +1043,11 @@ bool Sensor::threadLoop() { if (mNextCapturedBuffers != NULL) { if (listener != NULL) { +#if 0 + if (get_device_status(vinfo)) { + listener->onSensorEvent(frameNumber, SensorListener::ERROR_CAMERA_DEVICE, mNextCaptureTime); + } +#endif listener->onSensorEvent(frameNumber, SensorListener::EXPOSURE_START, mNextCaptureTime); } @@ -1109,7 +1120,7 @@ int Sensor::captureNewImage() { mKernelBuffer = NULL; // Might be adding more buffers, so size isn't constant - DBG_LOGB("size=%d\n", mNextCapturedBuffers->size()); + CAMHAL_LOGDB("size=%d\n", mNextCapturedBuffers->size()); for (size_t i = 0; i < mNextCapturedBuffers->size(); i++) { const StreamBuffer &b = (*mNextCapturedBuffers)[i]; ALOGVV("Sensor capturing buffer %d: stream %d," @@ -2015,14 +2026,23 @@ void Sensor::captureNV21(StreamBuffer b, uint32_t gain) { return ; } while(1){ - if (get_device_status(vinfo)) { - break; - } src = (uint8_t *)get_frame(vinfo); if (NULL == src) { - CAMHAL_LOGDA("get frame NULL, sleep 5ms"); - usleep(5000); - continue; + if (get_device_status(vinfo)) { + break; + } else { + CAMHAL_LOGDA("get frame NULL, sleep 5ms"); + usleep(5000); + continue; + } + } + + if (vinfo->preview.format.fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) { + if (vinfo->preview.buf.length != vinfo->preview.buf.bytesused) { + DBG_LOGB("length=%d, bytesused=%d \n", vinfo->preview.buf.length, vinfo->preview.buf.bytesused); + putback_frame(vinfo); + continue; + } } if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_NV21) { if (vinfo->preview.buf.length == b.width * b.height * 3/2) { @@ -2192,9 +2212,20 @@ void Sensor::captureYV12(StreamBuffer b, uint32_t gain) { src = (uint8_t *)get_frame(vinfo); if (NULL == src) { - CAMHAL_LOGDA("get frame NULL, sleep 5ms"); - usleep(5000); - continue; + if (get_device_status(vinfo)) { + break; + } else { + CAMHAL_LOGDA("get frame NULL, sleep 5ms"); + usleep(5000); + continue; + } + } + if (vinfo->preview.format.fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) { + if (vinfo->preview.buf.length != vinfo->preview.buf.bytesused) { + CAMHAL_LOGDB("length=%d, bytesused=%d \n", vinfo->preview.buf.length, vinfo->preview.buf.bytesused); + putback_frame(vinfo); + continue; + } } if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) { if (vinfo->preview.buf.length == b.width * b.height * 3/2) { @@ -2297,9 +2328,20 @@ void Sensor::captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride) { while(1) { src = (uint8_t *)get_frame(vinfo); if (NULL == src) { - CAMHAL_LOGDA("get frame NULL, sleep 5ms"); - usleep(5000); - continue; + if (get_device_status(vinfo)) { + break; + } else { + CAMHAL_LOGDA("get frame NULL, sleep 5ms"); + usleep(5000); + continue; + } + } + if (vinfo->preview.format.fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) { + if (vinfo->preview.buf.length != vinfo->preview.buf.bytesused) { + CAMHAL_LOGDB("length=%d, bytesused=%d \n", vinfo->preview.buf.length, vinfo->preview.buf.bytesused); + putback_frame(vinfo); + continue; + } } if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { memcpy(img, src, vinfo->preview.buf.length); diff --git a/v3/fake-pipeline2/Sensor.h b/v3/fake-pipeline2/Sensor.h index 5b47a48..4d8d308 100755..100644 --- a/v3/fake-pipeline2/Sensor.h +++ b/v3/fake-pipeline2/Sensor.h @@ -255,6 +255,7 @@ class Sensor: private Thread, public virtual RefBase { struct SensorListener { enum Event { EXPOSURE_START, // Start of exposure + ERROR_CAMERA_DEVICE, }; virtual void onSensorEvent(uint32_t frameNumber, Event e, diff --git a/v3/fake-pipeline2/camera_hw.cpp b/v3/fake-pipeline2/camera_hw.cpp index 67c5ece..ec74667 100755..100644 --- a/v3/fake-pipeline2/camera_hw.cpp +++ b/v3/fake-pipeline2/camera_hw.cpp @@ -276,14 +276,13 @@ void *get_frame(struct VideoInfo *vinfo) /* fall through */ default: - DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno); + CAMHAL_LOGDB("VIDIOC_DQBUF failed, errno=%d\n", errno); //CAMHAL_LOGDB //exit(1); /*here will generate crash, so delete. when ocour error, should break while() loop*/ set_device_status(vinfo); + return NULL; } - DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno); } //DBG_LOGA("get frame\n"); - return vinfo->mem[vinfo->preview.buf.index]; } diff --git a/v3/inc/DebugUtils.h b/v3/inc/DebugUtils.h index 4b0e184..09900f8 100755..100644 --- a/v3/inc/DebugUtils.h +++ b/v3/inc/DebugUtils.h @@ -71,9 +71,8 @@ extern volatile int32_t gCamHal_LogLevel; #define LOG_FUNCTION_NAME CAMHAL_LOGVA("ENTER"); #define LOG_FUNCTION_NAME_EXIT CAMHAL_LOGVA("EXIT"); -#define DBG_LOGA(str) ALOGI_IF(gCamHal_LogLevel >=4,"%10s-%5d %s - " str, CAMHAL_BUILD_NAME, __LINE__,__FUNCTION__) -#define DBG_LOGB(str, ...) ALOGI_IF(gCamHal_LogLevel >=4,"%10s-%5d %s - " str, CAMHAL_BUILD_NAME, __LINE__,__FUNCTION__, __VA_ARGS__) - +#define DBG_LOGA(str) ALOGI_IF(gCamHal_LogLevel >=4,"%5d %s - " str, __LINE__, __FUNCTION__) +#define DBG_LOGB(str, ...) ALOGI_IF(gCamHal_LogLevel >=4,"%5d %s - " str, __LINE__, __FUNCTION__, __VA_ARGS__) #endif #endif //DEBUG_UTILS_H -- cgit