Loading include/media/stagefright/CameraSourceTimeLapse.h +14 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ namespace android { class ICamera; class IMemory; class ISurface; class Camera; class CameraSourceTimeLapse : public CameraSource { Loading Loading @@ -65,6 +64,9 @@ private: // to know if current frame needs to be skipped. bool mSkipCurrentFrame; // True if camera is in preview mode and ready for takePicture(). bool mCameraIdle; CameraSourceTimeLapse(const sp<Camera> &camera, bool useStillCameraForTimeLapse, int64_t timeBetweenTimeLapseFrameCaptureUs, Loading Loading @@ -117,6 +119,17 @@ private: // Used only in the case mUseStillCameraForTimeLapse = true. void threadTimeLapseEntry(); // Wrapper to enter threadStartPreview() static void *ThreadStartPreviewWrapper(void *me); // Starts the camera's preview. void threadStartPreview(); // Starts thread ThreadStartPreviewWrapper() for restarting preview. // Needs to be done in a thread so that dataCallback() which calls this function // can return, and the camera can know that takePicture() is done. void restartPreview(); // Creates a copy of source_data into a new memory of final type MemoryBase. sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data); Loading media/libstagefright/CameraSourceTimeLapse.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -92,9 +92,15 @@ void *CameraSourceTimeLapse::ThreadTimeLapseWrapper(void *me) { void CameraSourceTimeLapse::threadTimeLapseEntry() { while(mStarted) { LOGV("threadTimeLapseEntry loop"); sleep(mTimeBetweenTimeLapseFrameCaptureUs/1E6); if(mCameraIdle) { LOGV("threadTimeLapseEntry: taking picture"); CHECK_EQ(OK, mCamera->takePicture()); mCameraIdle = false; sleep(mTimeBetweenTimeLapseFrameCaptureUs/1E6); } else { LOGV("threadTimeLapseEntry: camera busy with old takePicture. Sleeping a little."); sleep(.01); } } } Loading @@ -112,11 +118,9 @@ void CameraSourceTimeLapse::startCameraRecording() { IPCThreadState::self()->restoreCallingIdentity(token); CameraParameters params(s); params.setPictureSize(width, height); mCamera->setParameters(params.flatten()); CHECK_EQ(OK, mCamera->takePicture()); mCameraIdle = true; // create a thread which takes pictures in a loop pthread_attr_t attr; Loading Loading @@ -156,7 +160,35 @@ sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(const sp<IMemory> &source_d return newMemory; } // static void *CameraSourceTimeLapse::ThreadStartPreviewWrapper(void *me) { CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me); source->threadStartPreview(); return NULL; } void CameraSourceTimeLapse::threadStartPreview() { CHECK_EQ(OK, mCamera->startPreview()); mCameraIdle = true; } void CameraSourceTimeLapse::restartPreview() { // Start this in a different thread, so that the dataCallback can return LOGV("restartPreview"); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t threadPreview; pthread_create(&threadPreview, &attr, ThreadStartPreviewWrapper, this); pthread_attr_destroy(&attr); } void CameraSourceTimeLapse::dataCallback(int32_t msgType, const sp<IMemory> &data) { if(msgType == CAMERA_MSG_COMPRESSED_IMAGE) { // takePicture will complete after this callback, so restart preview. restartPreview(); } if(msgType != CAMERA_MSG_RAW_IMAGE) { return; } Loading Loading
include/media/stagefright/CameraSourceTimeLapse.h +14 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ namespace android { class ICamera; class IMemory; class ISurface; class Camera; class CameraSourceTimeLapse : public CameraSource { Loading Loading @@ -65,6 +64,9 @@ private: // to know if current frame needs to be skipped. bool mSkipCurrentFrame; // True if camera is in preview mode and ready for takePicture(). bool mCameraIdle; CameraSourceTimeLapse(const sp<Camera> &camera, bool useStillCameraForTimeLapse, int64_t timeBetweenTimeLapseFrameCaptureUs, Loading Loading @@ -117,6 +119,17 @@ private: // Used only in the case mUseStillCameraForTimeLapse = true. void threadTimeLapseEntry(); // Wrapper to enter threadStartPreview() static void *ThreadStartPreviewWrapper(void *me); // Starts the camera's preview. void threadStartPreview(); // Starts thread ThreadStartPreviewWrapper() for restarting preview. // Needs to be done in a thread so that dataCallback() which calls this function // can return, and the camera can know that takePicture() is done. void restartPreview(); // Creates a copy of source_data into a new memory of final type MemoryBase. sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data); Loading
media/libstagefright/CameraSourceTimeLapse.cpp +38 −6 Original line number Diff line number Diff line Loading @@ -92,9 +92,15 @@ void *CameraSourceTimeLapse::ThreadTimeLapseWrapper(void *me) { void CameraSourceTimeLapse::threadTimeLapseEntry() { while(mStarted) { LOGV("threadTimeLapseEntry loop"); sleep(mTimeBetweenTimeLapseFrameCaptureUs/1E6); if(mCameraIdle) { LOGV("threadTimeLapseEntry: taking picture"); CHECK_EQ(OK, mCamera->takePicture()); mCameraIdle = false; sleep(mTimeBetweenTimeLapseFrameCaptureUs/1E6); } else { LOGV("threadTimeLapseEntry: camera busy with old takePicture. Sleeping a little."); sleep(.01); } } } Loading @@ -112,11 +118,9 @@ void CameraSourceTimeLapse::startCameraRecording() { IPCThreadState::self()->restoreCallingIdentity(token); CameraParameters params(s); params.setPictureSize(width, height); mCamera->setParameters(params.flatten()); CHECK_EQ(OK, mCamera->takePicture()); mCameraIdle = true; // create a thread which takes pictures in a loop pthread_attr_t attr; Loading Loading @@ -156,7 +160,35 @@ sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(const sp<IMemory> &source_d return newMemory; } // static void *CameraSourceTimeLapse::ThreadStartPreviewWrapper(void *me) { CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me); source->threadStartPreview(); return NULL; } void CameraSourceTimeLapse::threadStartPreview() { CHECK_EQ(OK, mCamera->startPreview()); mCameraIdle = true; } void CameraSourceTimeLapse::restartPreview() { // Start this in a different thread, so that the dataCallback can return LOGV("restartPreview"); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t threadPreview; pthread_create(&threadPreview, &attr, ThreadStartPreviewWrapper, this); pthread_attr_destroy(&attr); } void CameraSourceTimeLapse::dataCallback(int32_t msgType, const sp<IMemory> &data) { if(msgType == CAMERA_MSG_COMPRESSED_IMAGE) { // takePicture will complete after this callback, so restart preview. restartPreview(); } if(msgType != CAMERA_MSG_RAW_IMAGE) { return; } Loading