summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-04-26 17:48:26 -0700
committerJames Dong <jdong@google.com>2010-04-28 11:55:47 -0700
commitc32cd79d9ad4aba7d959b5b3be7361b4715e6f18 (patch)
tree8a3b2842c196b748fd50d633b038ce33c9d6ee1a /media
parent261741e728f2137f12b28df25c25e96acd942de9 (diff)
downloadframeworks_av-c32cd79d9ad4aba7d959b5b3be7361b4715e6f18.zip
frameworks_av-c32cd79d9ad4aba7d959b5b3be7361b4715e6f18.tar.gz
frameworks_av-c32cd79d9ad4aba7d959b5b3be7361b4715e6f18.tar.bz2
Use timestamp from camera driver for CameraSource
Change-Id: I09ddec69997c43b8f17fdd21304c76cb4c5ab8cf
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/Android.mk1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp38
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h9
-rw-r--r--media/libstagefright/CameraSource.cpp87
-rw-r--r--media/libstagefright/OMXCodec.cpp51
5 files changed, 118 insertions, 68 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index cf97b23..3b678cb 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -37,6 +37,7 @@ LOCAL_SHARED_LIBRARIES := \
libvorbisidec \
libsonivox \
libmedia \
+ libcamera_client \
libandroid_runtime \
libstagefright \
libstagefright_omx \
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 531fd11..a63d94b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -20,6 +20,7 @@
#include "StagefrightRecorder.h"
+#include <binder/IPCThreadState.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/CameraSource.h>
@@ -30,8 +31,11 @@
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
#include <camera/ICamera.h>
+#include <camera/Camera.h>
#include <surfaceflinger/ISurface.h>
#include <utils/Errors.h>
+#include <sys/types.h>
+#include <unistd.h>
namespace android {
@@ -96,7 +100,25 @@ status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) {
}
status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) {
- mCamera = camera;
+ LOGV("setCamera: pid %d pid %d", IPCThreadState::self()->getCallingPid(), getpid());
+ if (camera == 0) {
+ LOGE("camera is NULL");
+ return UNKNOWN_ERROR;
+ }
+
+ mFlags &= ~ FLAGS_SET_CAMERA | FLAGS_HOT_CAMERA;
+ mCamera = Camera::create(camera);
+ if (mCamera == 0) {
+ LOGE("Unable to connect to camera");
+ return UNKNOWN_ERROR;
+ }
+
+ LOGV("Connected to camera");
+ mFlags |= FLAGS_SET_CAMERA;
+ if (mCamera->previewEnabled()) {
+ LOGV("camera is hot");
+ mFlags |= FLAGS_HOT_CAMERA;
+ }
return OK;
}
@@ -240,7 +262,7 @@ status_t StagefrightRecorder::startMPEG4Recording() {
CHECK(mCamera != NULL);
sp<CameraSource> cameraSource =
- CameraSource::CreateFromICamera(mCamera);
+ CameraSource::CreateFromCamera(mCamera);
CHECK(cameraSource != NULL);
@@ -314,6 +336,17 @@ status_t StagefrightRecorder::stop() {
status_t StagefrightRecorder::close() {
stop();
+ if (mCamera != 0) {
+ if ((mFlags & FLAGS_HOT_CAMERA) == 0) {
+ LOGV("Camera was cold when we started, stopping preview");
+ mCamera->stopPreview();
+ }
+ if (mFlags & FLAGS_SET_CAMERA) {
+ LOGV("Unlocking camera");
+ mCamera->unlock();
+ }
+ mFlags = 0;
+ }
return OK;
}
@@ -329,6 +362,7 @@ status_t StagefrightRecorder::reset() {
mVideoHeight = -1;
mFrameRate = -1;
mOutputFd = -1;
+ mFlags = 0;
return OK;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 7ec412d..2f2f748 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -23,6 +23,7 @@
namespace android {
+class Camera;
struct MediaSource;
struct MediaWriter;
@@ -52,7 +53,12 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t getMaxAmplitude(int *max);
private:
- sp<ICamera> mCamera;
+ enum CameraFlags {
+ FLAGS_SET_CAMERA = 1L << 0,
+ FLAGS_HOT_CAMERA = 1L << 1,
+ };
+
+ sp<Camera> mCamera;
sp<ISurface> mPreviewSurface;
sp<IMediaPlayerClient> mListener;
sp<MediaWriter> mWriter;
@@ -66,6 +72,7 @@ private:
int mFrameRate;
String8 mParams;
int mOutputFd;
+ int32_t mFlags;
status_t startMPEG4Recording();
status_t startAMRRecording();
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index f57ddc1..b07bd0e 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include <sys/time.h>
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CameraSource"
+#include <utils/Log.h>
#include <OMX_Component.h>
-#include <binder/IServiceManager.h>
-#include <cutils/properties.h> // for property_get
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
@@ -34,13 +34,6 @@
namespace android {
-static int64_t getNowUs() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
-}
-
struct DummySurface : public BnSurface {
DummySurface() {}
@@ -100,17 +93,15 @@ void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
LOGV("postData(%d, ptr:%p, size:%d)",
msgType, dataPtr->pointer(), dataPtr->size());
-
- sp<CameraSource> source = mSource.promote();
- if (source.get() != NULL) {
- source->dataCallback(msgType, dataPtr);
- }
}
void CameraSourceListener::postDataTimestamp(
nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
- LOGV("postDataTimestamp(%lld, %d, ptr:%p, size:%d)",
- timestamp, msgType, dataPtr->pointer(), dataPtr->size());
+
+ sp<CameraSource> source = mSource.promote();
+ if (source.get() != NULL) {
+ source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
+ }
}
// static
@@ -125,9 +116,7 @@ CameraSource *CameraSource::Create() {
}
// static
-CameraSource *CameraSource::CreateFromICamera(const sp<ICamera> &icamera) {
- sp<Camera> camera = Camera::create(icamera);
-
+CameraSource *CameraSource::CreateFromCamera(const sp<Camera> &camera) {
if (camera.get() == NULL) {
return NULL;
}
@@ -140,7 +129,9 @@ CameraSource::CameraSource(const sp<Camera> &camera)
mWidth(0),
mHeight(0),
mFirstFrameTimeUs(0),
+ mLastFrameTimestampUs(0),
mNumFrames(0),
+ mNumFramesReleased(0),
mStarted(false) {
String8 s = mCamera->getParameters();
printf("params: \"%s\"\n", s.string());
@@ -160,6 +151,7 @@ void CameraSource::setPreviewSurface(const sp<ISurface> &surface) {
}
status_t CameraSource::start(MetaData *) {
+ LOGV("start");
CHECK(!mStarted);
mCamera->setListener(new CameraSourceListener(this));
@@ -169,11 +161,7 @@ status_t CameraSource::start(MetaData *) {
mPreviewSurface != NULL ? mPreviewSurface : new DummySurface);
CHECK_EQ(err, OK);
- mCamera->setPreviewCallbackFlags(
- FRAME_CALLBACK_FLAG_ENABLE_MASK
- | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);
-
- err = mCamera->startPreview();
+ err = mCamera->startRecording();
CHECK_EQ(err, OK);
mStarted = true;
@@ -182,15 +170,30 @@ status_t CameraSource::start(MetaData *) {
}
status_t CameraSource::stop() {
- CHECK(mStarted);
-
- mCamera->stopPreview();
-
+ LOGV("stop");
+ Mutex::Autolock autoLock(mLock);
mStarted = false;
+ mFrameAvailableCondition.signal();
+ mCamera->setListener(NULL);
+ mCamera->stopRecording();
+ releaseQueuedFrames();
+ LOGI("Frames received/released: %d/%d, timestamp (us) last/first: %lld/%lld",
+ mNumFrames, mNumFramesReleased,
+ mLastFrameTimestampUs, mFirstFrameTimeUs);
return OK;
}
+void CameraSource::releaseQueuedFrames() {
+ List<sp<IMemory> >::iterator it;
+ while (!mFrames.empty()) {
+ it = mFrames.begin();
+ mCamera->releaseRecordingFrame(*it);
+ mFrames.erase(it);
+ ++mNumFramesReleased;
+ }
+}
+
sp<MetaData> CameraSource::getFormat() {
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
@@ -203,7 +206,7 @@ sp<MetaData> CameraSource::getFormat() {
status_t CameraSource::read(
MediaBuffer **buffer, const ReadOptions *options) {
- CHECK(mStarted);
+ LOGV("read");
*buffer = NULL;
@@ -217,20 +220,24 @@ status_t CameraSource::read(
{
Mutex::Autolock autoLock(mLock);
- while (mFrames.empty()) {
+ while (mStarted && mFrames.empty()) {
mFrameAvailableCondition.wait(mLock);
}
-
+ if (!mStarted) {
+ return OK;
+ }
frame = *mFrames.begin();
mFrames.erase(mFrames.begin());
frameTime = *mFrameTimes.begin();
mFrameTimes.erase(mFrameTimes.begin());
+ ++mNumFramesReleased;
}
*buffer = new MediaBuffer(frame->size());
memcpy((*buffer)->data(), frame->pointer(), frame->size());
(*buffer)->set_range(0, frame->size());
+ mCamera->releaseRecordingFrame(frame);
(*buffer)->meta_data()->clear();
(*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
@@ -238,17 +245,25 @@ status_t CameraSource::read(
return OK;
}
-void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) {
+void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
+ int32_t msgType, const sp<IMemory> &data) {
+ LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
+ mLastFrameTimestampUs = timestampUs;
Mutex::Autolock autoLock(mLock);
+ if (!mStarted) {
+ mCamera->releaseRecordingFrame(data);
+ ++mNumFrames;
+ ++mNumFramesReleased;
+ return;
+ }
- int64_t nowUs = getNowUs();
if (mNumFrames == 0) {
- mFirstFrameTimeUs = nowUs;
+ mFirstFrameTimeUs = timestampUs;
}
++mNumFrames;
mFrames.push_back(data);
- mFrameTimes.push_back(nowUs - mFirstFrameTimeUs);
+ mFrameTimes.push_back(timestampUs - mFirstFrameTimeUs);
mFrameAvailableCondition.signal();
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 9cdf96e..41be9ac 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -711,38 +711,16 @@ void OMXCodec::setVideoInputFormat(
colorFormat = OMX_COLOR_FormatYUV420Planar;
}
- CHECK_EQ(setVideoPortFormatType(
- kPortIndexInput, OMX_VIDEO_CodingUnused,
- colorFormat), OK);
- CHECK_EQ(setVideoPortFormatType(
- kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
- OK);
+ status_t err;
OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexOutput;
-
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- CHECK_EQ(err, OK);
- CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
-
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
-
- video_def->eCompressionFormat = compressionFormat;
- video_def->eColorFormat = OMX_COLOR_FormatUnused;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- CHECK_EQ(err, OK);
-
- ////////////////////////////////////////////////////////////////////////////
-
+ //////////////////////// Input port /////////////////////////
+ CHECK_EQ(setVideoPortFormatType(
+ kPortIndexInput, OMX_VIDEO_CodingUnused,
+ colorFormat), OK);
InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
@@ -751,7 +729,6 @@ void OMXCodec::setVideoInputFormat(
CHECK_EQ(err, OK);
def.nBufferSize = getFrameSize(colorFormat, width, height);
- CODEC_LOGV("Setting nBufferSize = %ld", def.nBufferSize);
CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
@@ -760,20 +737,36 @@ void OMXCodec::setVideoInputFormat(
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat;
- video_def->xFramerate = 24 << 16; // XXX crucial!
+ video_def->xFramerate = (24 << 16); // Q16 format
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
+ //////////////////////// Output port /////////////////////////
+ CHECK_EQ(setVideoPortFormatType(
+ kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused),
+ OK);
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexOutput;
+
err = mOMX->getParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
CHECK_EQ(err, OK);
+ CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
+
+ video_def->nFrameWidth = width;
+ video_def->nFrameHeight = height;
+
+ video_def->eCompressionFormat = compressionFormat;
+ video_def->eColorFormat = OMX_COLOR_FormatUnused;
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
+ /////////////////// Codec-specific ////////////////////////
switch (compressionFormat) {
case OMX_VIDEO_CodingMPEG4:
{