diff options
-rw-r--r-- | include/media/stagefright/CameraSource.h | 12 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 6 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.h | 2 | ||||
-rw-r--r-- | media/libstagefright/CameraSource.cpp | 47 |
4 files changed, 65 insertions, 2 deletions
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index 3192d03..fd30ba5 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -35,6 +35,10 @@ public: static CameraSource *Create(); static CameraSource *CreateFromCamera(const sp<Camera> &camera); + void enableTimeLapseMode( + int64_t timeBetweenTimeLapseFrameCaptureUs, int32_t videoFrameRate); + void disableTimeLapseMode(); + virtual ~CameraSource(); virtual status_t start(MetaData *params = NULL); @@ -71,6 +75,14 @@ private: bool mCollectStats; bool mStarted; + // Time between capture of two frames during time lapse recording + // Negative value indicates that timelapse is disabled. + int64_t mTimeBetweenTimeLapseFrameCaptureUs; + // Time between two frames in final video (1/frameRate) + int64_t mTimeBetweenTimeLapseVideoFramesUs; + // Real timestamp of the last encoded time lapse frame + int64_t mLastTimeLapseFrameRealTimestampUs; + CameraSource(const sp<Camera> &camera); void dataCallbackTimestamp( diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 91c5b92..3619013 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -815,6 +815,9 @@ status_t StagefrightRecorder::setupVideoEncoder(const sp<MediaWriter>& writer) { sp<CameraSource> cameraSource = CameraSource::CreateFromCamera(mCamera); CHECK(cameraSource != NULL); + if(mCaptureTimeLapse) { + cameraSource->enableTimeLapseMode(1E6, mFrameRate); + } sp<MetaData> enc_meta = new MetaData; enc_meta->setInt32(kKeyBitRate, mVideoBitRate); @@ -892,7 +895,7 @@ status_t StagefrightRecorder::startMPEG4Recording() { sp<MediaWriter> writer = new MPEG4Writer(dup(mOutputFd)); // Add audio source first if it exists - if (mAudioSource != AUDIO_SOURCE_LIST_END) { + if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) { err = setupAudioEncoder(writer); if (err != OK) return err; totalBitRate += mAudioBitRate; @@ -994,6 +997,7 @@ status_t StagefrightRecorder::reset() { mCameraId = 0; mTrackEveryNumberOfFrames = 0; mTrackEveryTimeDurationUs = 0; + mCaptureTimeLapse = false; mEncoderProfiles = MediaProfiles::getInstance(); mOutputFd = -1; diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index cb05571..dcb4747 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -87,6 +87,8 @@ private: int32_t mTrackEveryNumberOfFrames; int64_t mTrackEveryTimeDurationUs; + bool mCaptureTimeLapse; + String8 mParams; int mOutputFd; int32_t mFlags; diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 6f4c980..bb53d97 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -116,6 +116,19 @@ CameraSource *CameraSource::CreateFromCamera(const sp<Camera> &camera) { return new CameraSource(camera); } +void CameraSource::enableTimeLapseMode( + int64_t timeBetweenTimeLapseFrameCaptureUs, int32_t videoFrameRate) { + LOGV("starting time lapse mode"); + mTimeBetweenTimeLapseFrameCaptureUs = timeBetweenTimeLapseFrameCaptureUs; + mTimeBetweenTimeLapseVideoFramesUs = (1E6/videoFrameRate); +} + +void CameraSource::disableTimeLapseMode() { + LOGV("stopping time lapse mode"); + mTimeBetweenTimeLapseFrameCaptureUs = -1; + mTimeBetweenTimeLapseVideoFramesUs = 0; +} + CameraSource::CameraSource(const sp<Camera> &camera) : mCamera(camera), mFirstFrameTimeUs(0), @@ -126,7 +139,10 @@ CameraSource::CameraSource(const sp<Camera> &camera) mNumGlitches(0), mGlitchDurationThresholdUs(200000), mCollectStats(false), - mStarted(false) { + mStarted(false), + mTimeBetweenTimeLapseFrameCaptureUs(-1), + mTimeBetweenTimeLapseVideoFramesUs(0), + mLastTimeLapseFrameRealTimestampUs(0) { int64_t token = IPCThreadState::self()->clearCallingIdentity(); String8 s = mCamera->getParameters(); @@ -316,6 +332,35 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs, ++mNumGlitches; } + // time lapse + if(mTimeBetweenTimeLapseFrameCaptureUs >= 0) { + if(mLastTimeLapseFrameRealTimestampUs == 0) { + // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs + // to current time (timestampUs) and save frame data. + LOGV("dataCallbackTimestamp timelapse: initial frame"); + + mLastTimeLapseFrameRealTimestampUs = timestampUs; + } else if (timestampUs < + (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) { + // Skip all frames from last encoded frame until + // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed. + // Tell the camera to release its recording frame and return. + LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame"); + + releaseOneRecordingFrame(data); + return; + } else { + // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time: + // - Reset mLastTimeLapseFrameRealTimestampUs to current time. + // - Artificially modify timestampUs to be one frame time (1/framerate) ahead + // of the last encoded frame's time stamp. + LOGV("dataCallbackTimestamp timelapse: got timelapse frame"); + + mLastTimeLapseFrameRealTimestampUs = timestampUs; + timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs; + } + } + mLastFrameTimestampUs = timestampUs; if (mNumFramesReceived == 0) { mFirstFrameTimeUs = timestampUs; |