From 43c94189c0db1ec59c39479339b0a1704177e2e0 Mon Sep 17 00:00:00 2001 From: Guosong Zhou Date: Fri, 01 Jul 2016 06:42:28 +0000 Subject: PD#124344: camera: add flush interface for v3 camera Change-Id: If0843aabe3122e27e3aa66e487d2faadefb86718 --- diff --git a/v3/EmulatedFakeCamera3.cpp b/v3/EmulatedFakeCamera3.cpp index 2967de3..79aafa1 100644 --- a/v3/EmulatedFakeCamera3.cpp +++ b/v3/EmulatedFakeCamera3.cpp @@ -21,7 +21,7 @@ #include -//#define LOG_NDEBUG 0 +#define LOG_NDEBUG 0 //#define LOG_NNDEBUG 0 #define LOG_TAG "EmulatedCamera_FakeCamera3" #include @@ -179,6 +179,7 @@ EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, struct hw_module_t* modul mSupportCap = 0; mSupportRotate = 0; mFullMode = 0; + mFlushTag = false; gLoadXml.parseXMLFile(); } @@ -241,9 +242,10 @@ status_t EmulatedFakeCamera3::Initialize() { status_t EmulatedFakeCamera3::connectCamera(hw_device_t** device) { ALOGV("%s: E", __FUNCTION__); - DBG_LOGA("ddd"); + DBG_LOGB("%s, ddd", __FUNCTION__); Mutex::Autolock l(mLock); status_t res; + DBG_LOGB("%s , mStatus = %d" , __FUNCTION__, mStatus); if ((mStatus != STATUS_CLOSED) || !mPlugged) { ALOGE("%s: Can't connect in state %d, mPlugged=%d", @@ -341,12 +343,14 @@ bool EmulatedFakeCamera3::getCameraStatus() status_t EmulatedFakeCamera3::closeCamera() { DBG_LOGB("%s, %d\n", __FUNCTION__, __LINE__); - status_t res; { Mutex::Autolock l(mLock); if (mStatus == STATUS_CLOSED) return OK; } + + CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); + mReadoutThread->sendFlushSingnal(); mSensor->sendExitSingalToSensor(); res = mSensor->shutDown(); if (res != NO_ERROR) { @@ -354,6 +358,7 @@ status_t EmulatedFakeCamera3::closeCamera() { return res; } mSensor.clear(); + CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); { Mutex::Autolock l(mLock); @@ -365,6 +370,8 @@ status_t EmulatedFakeCamera3::closeCamera() { mReadoutThread->sendExitReadoutThreadSignal(); mReadoutThread->requestExit(); } + CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); + mReadoutThread->join(); DBG_LOGA("Sucess exit ReadOutThread"); { @@ -379,7 +386,7 @@ status_t EmulatedFakeCamera3::closeCamera() { mStreams.clear(); mReadoutThread.clear(); } - + CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); return EmulatedCamera3::closeCamera(); } @@ -465,6 +472,7 @@ status_t EmulatedFakeCamera3::configureStreams( Mutex::Autolock l(mLock); uint32_t width, height, pixelfmt; bool isRestart = false; + mFlushTag = false; DBG_LOGB("%s: %d streams", __FUNCTION__, streamList->num_streams); if (mStatus != STATUS_OPEN && mStatus != STATUS_READY) { @@ -1067,6 +1075,11 @@ status_t EmulatedFakeCamera3::processCaptureRequest( CameraMetadata settings; Buffers *sensorBuffers = NULL; HalBufferVector *buffers = NULL; + + if (mFlushTag) { + DBG_LOGA("already flush, but still send Capture Request .\n"); + } + { Mutex::Autolock l(mLock); @@ -1233,7 +1246,7 @@ status_t EmulatedFakeCamera3::processCaptureRequest( res = process3A(settings); if (res != OK) { - CAMHAL_LOGDB("%s: process3A failed!", __FUNCTION__); + ALOGVV("%s: process3A failed!", __FUNCTION__); //return res; } @@ -1478,7 +1491,7 @@ status_t EmulatedFakeCamera3::processCaptureRequest( // Cache the settings for next time mPrevSettings.acquire(settings); } - CAMHAL_LOGDB("%s , X" , __FUNCTION__); + CAMHAL_LOGVB("%s , X" , __FUNCTION__); return OK; } @@ -1515,6 +1528,10 @@ void EmulatedFakeCamera3::dump(int fd) { //CAMERA3_BUFFER_STATUS_ERROR flag. int EmulatedFakeCamera3::flush_all_requests() { DBG_LOGA("flush all request"); + mFlushTag = true; + mReadoutThread->flushAllRequest(true); + mReadoutThread->setFlushFlag(false); + mSensor->setFlushFlag(false); return 0; } /** Tag query methods */ @@ -1721,9 +1738,9 @@ status_t EmulatedFakeCamera3::constructStaticInfo() { // android.sensor - static const int32_t testAvailablePattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; + static const int32_t testAvailablePattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; info.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &testAvailablePattern, 1); - static const int32_t testPattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; + static const int32_t testPattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; info.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPattern, 1); info.update(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, Sensor::kExposureTimeRange, 2); @@ -2222,9 +2239,9 @@ status_t EmulatedFakeCamera3::doFakeAE(CameraMetadata &settings) { } if (precaptureTrigger) { - ALOGV("%s: Pre capture trigger = %d", __FUNCTION__, precaptureTrigger); + ALOGVV("%s: Pre capture trigger = %d", __FUNCTION__, precaptureTrigger); } else if (e.count > 0) { - ALOGV("%s: Pre capture trigger was present? %zu", + ALOGVV("%s: Pre capture trigger was present? %zu", __FUNCTION__, e.count); } @@ -2330,9 +2347,9 @@ status_t EmulatedFakeCamera3::doFakeAF(CameraMetadata &settings) { mAfTriggerId = e.data.i32[0]; - ALOGV("%s: AF trigger set to 0x%x", __FUNCTION__, afTrigger); - ALOGV("%s: AF trigger ID set to 0x%x", __FUNCTION__, mAfTriggerId); - ALOGV("%s: AF mode is 0x%x", __FUNCTION__, afMode); + ALOGVV("%s: AF trigger set to 0x%x", __FUNCTION__, afTrigger); + ALOGVV("%s: AF trigger ID set to 0x%x", __FUNCTION__, mAfTriggerId); + ALOGVV("%s: AF mode is 0x%x", __FUNCTION__, afMode); } else { afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; } @@ -2601,14 +2618,14 @@ void EmulatedFakeCamera3::update3A(CameraMetadata &settings) { void EmulatedFakeCamera3::signalReadoutIdle() { Mutex::Autolock l(mLock); - CAMHAL_LOGDB("%s , E" , __FUNCTION__); + CAMHAL_LOGVB("%s , E" , __FUNCTION__); // Need to chek isIdle again because waiting on mLock may have allowed // something to be placed in the in-flight queue. if (mStatus == STATUS_ACTIVE && mReadoutThread->isIdle()) { ALOGV("Now idle"); mStatus = STATUS_READY; } - CAMHAL_LOGDB("%s , X , mStatus = %d " , __FUNCTION__, mStatus); + CAMHAL_LOGVB("%s , X , mStatus = %d " , __FUNCTION__, mStatus); } void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e, @@ -2644,6 +2661,7 @@ void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e, EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent) : mParent(parent), mJpegWaiting(false) { mExitReadoutThread = false; + mFlushFlag = false; } EmulatedFakeCamera3::ReadoutThread::~ReadoutThread() { @@ -2654,6 +2672,33 @@ EmulatedFakeCamera3::ReadoutThread::~ReadoutThread() { } } +status_t EmulatedFakeCamera3::ReadoutThread::flushAllRequest(bool flag) { + status_t res; + mFlushFlag = flag; + Mutex::Autolock l(mLock); + CAMHAL_LOGDB("count = %d" , mInFlightQueue.size()); + if (mInFlightQueue.size() > 0) { + mParent->mSensor->setFlushFlag(true); + res = mFlush.waitRelative(mLock, kSyncWaitTimeout * 15); + if (res != OK && res != TIMED_OUT) { + ALOGE("%s: Error waiting for mFlush singnal : %d", + __FUNCTION__, res); + return INVALID_OPERATION; + } + DBG_LOGA("finish flush all request"); + } + return 0; +} + +void EmulatedFakeCamera3::ReadoutThread::sendFlushSingnal(void) { + Mutex::Autolock l(mLock); + mFlush.signal(); +} + +void EmulatedFakeCamera3::ReadoutThread::setFlushFlag(bool flag) { + mFlushFlag = flag; +} + void EmulatedFakeCamera3::ReadoutThread::queueCaptureRequest(const Request &r) { Mutex::Autolock l(mLock); @@ -2669,7 +2714,7 @@ bool EmulatedFakeCamera3::ReadoutThread::isIdle() { status_t EmulatedFakeCamera3::ReadoutThread::waitForReadout() { status_t res; Mutex::Autolock l(mLock); - CAMHAL_LOGDB("%s , E" , __FUNCTION__); + CAMHAL_LOGVB("%s , E" , __FUNCTION__); int loopCount = 0; while (mInFlightQueue.size() >= kMaxQueueSize) { res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop); @@ -2729,6 +2774,14 @@ bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { return false; } + { + Mutex::Autolock l(mLock); + if ((mInFlightQueue.size() == 0) && (mFlushFlag) && + (mCurrentRequest.settings.isEmpty())) { + mFlush.signal(); + } + } + if (mCurrentRequest.settings.isEmpty()) { Mutex::Autolock l(mLock); if (mInFlightQueue.empty()) { @@ -2854,7 +2907,7 @@ bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { mCurrentRequest.sensorBuffers = NULL; } mCurrentRequest.settings.clear(); - CAMHAL_LOGDB("%s , X " , __FUNCTION__); + CAMHAL_LOGVB("%s , X " , __FUNCTION__); return true; } diff --git a/v3/EmulatedFakeCamera3.h b/v3/EmulatedFakeCamera3.h index e984cc3..8428a93 100644 --- a/v3/EmulatedFakeCamera3.h +++ b/v3/EmulatedFakeCamera3.h @@ -123,8 +123,8 @@ private: void getStreamConfigurationDurations(CameraMetadata *info); void getStreamConfigurationp(CameraMetadata *info); - void getValidJpegSize(uint32_t picSizes[], uint32_t availablejpegsize[], int count); - status_t checkValidJpegSize(uint32_t width, uint32_t height); + void getValidJpegSize(uint32_t picSizes[], uint32_t availablejpegsize[], int count); + status_t checkValidJpegSize(uint32_t width, uint32_t height); //HW levels worst<->best, 0 = worst, 2 = best */ //compareHardwareLevel @@ -155,9 +155,9 @@ private: static const struct KeyInfo_s sKeyInfoReq[]; static const struct KeyInfo_s sKeyInfoResult[]; static const struct KeyInfo_s sKeyBackwardCompat[]; - jpegsize maxJpegResolution; - jpegsize getMaxJpegResolution(uint32_t picSizes[],int count); - ssize_t getJpegBufferSize(int width, int height); + jpegsize maxJpegResolution; + jpegsize getMaxJpegResolution(uint32_t picSizes[],int count); + ssize_t getJpegBufferSize(int width, int height); /** * Run the fake 3A algorithms as needed. May override/modify settings * values. @@ -254,9 +254,10 @@ private: sp mSensor; sp mJpegCompressor; friend class JpegCompressor; - unsigned int mSupportCap; - unsigned int mSupportRotate; + unsigned int mSupportCap; + unsigned int mSupportRotate; camera_status_t mCameraStatus; + bool mFlushTag; /** Processing thread for sending out results */ class ReadoutThread : public Thread, private JpegCompressor::JpegListener { @@ -288,7 +289,9 @@ private: status_t startJpegCompressor(EmulatedFakeCamera3 *parent); status_t shutdownJpegCompressor(EmulatedFakeCamera3 * parent); void sendExitReadoutThreadSignal(void); - + status_t flushAllRequest(bool flag); + void setFlushFlag(bool flag); + void sendFlushSingnal(void); private: static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms static const nsecs_t kMaxWaitLoops = 1000; @@ -313,6 +316,8 @@ private: bool mJpegWaiting; camera3_stream_buffer mJpegHalBuffer; uint32_t mJpegFrameNumber; + bool mFlushFlag; + Condition mFlush; virtual void onJpegDone(const StreamBuffer &jpegBuffer, bool success, CaptureRequest &r); virtual void onJpegInputDone(const StreamBuffer &inputBuffer); }; diff --git a/v3/fake-pipeline2/Sensor.cpp b/v3/fake-pipeline2/Sensor.cpp index 8554c01..2c5048b 100644 --- a/v3/fake-pipeline2/Sensor.cpp +++ b/v3/fake-pipeline2/Sensor.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -//#define LOG_NDEBUG 0 +#define LOG_NDEBUG 0 //#define LOG_NNDEBUG 0 #define LOG_TAG "EmulatedCamera3_Sensor" @@ -202,6 +202,7 @@ Sensor::Sensor(): mWait(false), mPre_width(0), mPre_height(0), + mFlushFlag(false), mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond) { @@ -985,10 +986,14 @@ void Sensor::setFrameNumber(uint32_t frameNumber) { mFrameNumber = frameNumber; } +void Sensor::setFlushFlag(bool flushFlag) { + mFlushFlag = flushFlag; +} + status_t Sensor::waitForVSync(nsecs_t reltime) { int res; Mutex::Autolock lock(mControlMutex); - CAMHAL_LOGDB("%s , E mControlMutex" , __FUNCTION__); + CAMHAL_LOGVB("%s , E mControlMutex" , __FUNCTION__); if (mExitSensorThread) { return -1; } @@ -999,7 +1004,7 @@ status_t Sensor::waitForVSync(nsecs_t reltime) { ALOGE("%s: Error waiting for VSync signal: %d", __FUNCTION__, res); return false; } - CAMHAL_LOGDB("%s , X mControlMutex , mGotVSync = %d " , __FUNCTION__ , mGotVSync); + CAMHAL_LOGVB("%s , X mControlMutex , mGotVSync = %d " , __FUNCTION__ , mGotVSync); return mGotVSync; } @@ -1012,13 +1017,27 @@ status_t Sensor::waitForNewFrame(nsecs_t reltime, if (mCapturedBuffers == NULL) { int res; - CAMHAL_LOGDB("%s , E mReadoutMutex , reltime = %d" , __FUNCTION__, reltime); + CAMHAL_LOGVB("%s , E mReadoutMutex , reltime = %d" , __FUNCTION__, reltime); res = mReadoutAvailable.waitRelative(mReadoutMutex, reltime); if (res == TIMED_OUT) { return false; } else if (res != OK || mCapturedBuffers == NULL) { - ALOGE("Error waiting for sensor readout signal: %d", res); - return false; + if (mFlushFlag) { + ALOGE("%s , return immediately , mWait = %d", __FUNCTION__, mWait); + if (mWait) { + mWait = false; + *captureTime = mCaptureTime; + mCapturedBuffers = NULL; + mReadoutComplete.signal(); + } else { + *captureTime = mCaptureTime; + mCapturedBuffers = NULL; + } + return -2; + } else { + ALOGE("Error waiting for sensor readout signal: %d", res); + return false; + } } } if (mWait) { @@ -1030,7 +1049,7 @@ status_t Sensor::waitForNewFrame(nsecs_t reltime, *captureTime = mCaptureTime; mCapturedBuffers = NULL; } - CAMHAL_LOGDB("%s , X" , __FUNCTION__); + CAMHAL_LOGVB("%s , X" , __FUNCTION__); return true; } @@ -1065,6 +1084,7 @@ bool Sensor::threadLoop() { if (mExitSensorThread) { return false; } + /** * Stage 1: Read in latest control parameters */ @@ -1076,7 +1096,7 @@ bool Sensor::threadLoop() { SensorListener *listener = NULL; { Mutex::Autolock lock(mControlMutex); - CAMHAL_LOGDB("%s , E mControlMutex" , __FUNCTION__); + CAMHAL_LOGVB("%s , E mControlMutex" , __FUNCTION__); exposureDuration = mExposureTime; frameDuration = mFrameDuration; gain = mGainFactor; @@ -1120,7 +1140,7 @@ bool Sensor::threadLoop() { if (capturedBuffers != NULL) { ALOGVV("Sensor readout complete"); Mutex::Autolock lock(mReadoutMutex); - CAMHAL_LOGDB("%s , E mReadoutMutex" , __FUNCTION__); + CAMHAL_LOGVB("%s , E mReadoutMutex" , __FUNCTION__); if (mCapturedBuffers != NULL) { ALOGE("Waiting for readout thread to catch up!"); mWait = true; @@ -1132,7 +1152,7 @@ bool Sensor::threadLoop() { mReadoutAvailable.signal(); capturedBuffers = NULL; } - CAMHAL_LOGDB("%s , X mReadoutMutex" , __FUNCTION__); + CAMHAL_LOGVB("%s , X mReadoutMutex" , __FUNCTION__); if (mExitSensorThread) { return false; @@ -1196,7 +1216,7 @@ bool Sensor::threadLoop() { ALOGVV("Frame cycle took %d ms, target %d ms", (int)((endRealTime - startRealTime)/1000000), (int)(frameDuration / 1000000)); - CAMHAL_LOGDB("%s , X" , __FUNCTION__); + CAMHAL_LOGVB("%s , X" , __FUNCTION__); return true; }; @@ -1318,7 +1338,7 @@ int Sensor::captureNewImage() { break; } } - if (!isjpeg) { //jpeg buffer that is rgb888 has been save in the different buffer struct; + if ((!isjpeg)&&(mKernelBuffer)) { //jpeg buffer that is rgb888 has been save in the different buffer struct; // whose buffer putback separately. putback_frame(vinfo); } @@ -2154,6 +2174,10 @@ void Sensor::captureNV21(StreamBuffer b, uint32_t gain) { return ; } while(1){ + if (mFlushFlag) { + break; + } + if (mExitSensorThread) { break; } @@ -2292,7 +2316,7 @@ void Sensor::captureYV12(StreamBuffer b, uint32_t gain) { uint8_t *src; if (mKernelBuffer) { src = mKernelBuffer; - if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) { + if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) { //memcpy(b.img, src, 200 * 100 * 3 / 2 /*vinfo->preview.buf.length*/); ALOGI("Sclale YV12 frame down \n"); @@ -2344,8 +2368,8 @@ void Sensor::captureYV12(StreamBuffer b, uint32_t gain) { } if (ConvertToI420(src, vinfo->preview.buf.bytesused, tmp_buffer, width, tmp_buffer + width * height + width * height / 4, (width + 1) / 2, - tmp_buffer + width * height, (width + 1) / 2, 0, 0, width, height, - width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) { + tmp_buffer + width * height, (width + 1) / 2, 0, 0, width, height, + width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) { DBG_LOGA("Decode MJPEG frame failed\n"); } @@ -2368,6 +2392,9 @@ void Sensor::captureYV12(StreamBuffer b, uint32_t gain) { return ; } while(1){ + if (mFlushFlag) { + break; + } if (mExitSensorThread) { break; } @@ -2486,7 +2513,7 @@ void Sensor::captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride) { uint8_t *src; if (mKernelBuffer) { src = mKernelBuffer; - if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { + if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { //TODO YUYV scale //memcpy(img, src, vinfo->preview.buf.length); @@ -2497,6 +2524,9 @@ void Sensor::captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride) { } while(1) { + if (mFlushFlag) { + break; + } if (mExitSensorThread) { break; } diff --git a/v3/fake-pipeline2/Sensor.h b/v3/fake-pipeline2/Sensor.h index d84d951..5670f24 100644 --- a/v3/fake-pipeline2/Sensor.h +++ b/v3/fake-pipeline2/Sensor.h @@ -216,14 +216,14 @@ class Sensor: private Thread, public virtual RefBase { int setZoom(int zoomValue); int getExposure(int *mamExp, int *minExp, int *def, camera_metadata_rational *step); status_t setExposure(int expCmp); - status_t setEffect(uint8_t effect); - int getAntiBanding(uint8_t *antiBanding, uint8_t maxCont); - status_t setAntiBanding(uint8_t antiBanding); - status_t setFocuasArea(int32_t x0, int32_t y0, int32_t x1, int32_t y1); - int getAWB(uint8_t *awbMode, uint8_t maxCount); - status_t setAWB(uint8_t awbMode); - status_t setAutoFocuas(uint8_t afMode); - int getAutoFocus(uint8_t *afMode, uint8_t maxCount); + status_t setEffect(uint8_t effect); + int getAntiBanding(uint8_t *antiBanding, uint8_t maxCont); + status_t setAntiBanding(uint8_t antiBanding); + status_t setFocuasArea(int32_t x0, int32_t y0, int32_t x1, int32_t y1); + int getAWB(uint8_t *awbMode, uint8_t maxCount); + status_t setAWB(uint8_t awbMode); + status_t setAutoFocuas(uint8_t afMode); + int getAutoFocus(uint8_t *afMode, uint8_t maxCount); void setExposureTime(uint64_t ns); void setFrameDuration(uint64_t ns); void setSensitivity(uint32_t gain); @@ -231,7 +231,7 @@ class Sensor: private Thread, public virtual RefBase { void setDestinationBuffers(Buffers *buffers); // To simplify tracking sensor's current frame void setFrameNumber(uint32_t frameNumber); - + void setFlushFlag(bool flushFlag); status_t force_reset_sensor(); /* * Controls that cause reconfiguration delay @@ -361,7 +361,7 @@ class Sensor: private Thread, public virtual RefBase { bool mWait; uint32_t mPre_width; uint32_t mPre_height; - + bool mFlushFlag; /** * Inherited Thread virtual overrides, and members only used by the * processing thread @@ -382,10 +382,10 @@ class Sensor: private Thread, public virtual RefBase { void captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride); void captureRGB(uint8_t *img, uint32_t gain, uint32_t stride); void captureNV21(StreamBuffer b, uint32_t gain); - void captureYV12(StreamBuffer b, uint32_t gain); - void captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride); + void captureYV12(StreamBuffer b, uint32_t gain); + void captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride); void YUYVToNV21(uint8_t *src, uint8_t *dst, int width, int height); - void YUYVToYV12(uint8_t *src, uint8_t *dst, int width, int height); + void YUYVToYV12(uint8_t *src, uint8_t *dst, int width, int height); }; } -- cgit