Loading include/media/stagefright/CameraSource.h +13 −13 Original line number Diff line number Diff line Loading @@ -26,12 +26,11 @@ namespace android { class ICamera; class ICameraClient; class IMemory; class ISurface; class Camera; class CameraSource : public MediaSource, public MediaBufferObserver { class CameraSource : public MediaSource { public: static CameraSource *Create(); Loading @@ -45,24 +44,25 @@ public: virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2); virtual void dataCallback(int32_t msgType, const sp<IMemory>& data); virtual void signalBufferReturned(MediaBuffer *buffer); private: CameraSource(const sp<ICamera> &camera, const sp<ICameraClient> &client); friend class CameraSourceListener; sp<ICamera> mCamera; sp<ICameraClient> mCameraClient; sp<Camera> mCamera; Mutex mLock; Condition mFrameAvailableCondition; List<sp<IMemory> > mFrames; List<int64_t> mFrameTimes; int mNumFrames; int mWidth, mHeight; int64_t mFirstFrameTimeUs; int32_t mNumFrames; bool mStarted; CameraSource(const sp<Camera> &camera); void dataCallback(int32_t msgType, const sp<IMemory> &data); CameraSource(const CameraSource &); CameraSource &operator=(const CameraSource &); }; Loading media/libstagefright/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true) LOCAL_SRC_FILES += \ AMRExtractor.cpp \ CachingDataSource.cpp \ CameraSource.cpp \ DataSource.cpp \ FileSource.cpp \ HTTPDataSource.cpp \ Loading media/libstagefright/CameraSource.cpp +107 −92 Original line number Diff line number Diff line Loading @@ -21,120 +21,142 @@ #include <binder/IServiceManager.h> #include <media/stagefright/CameraSource.h> #include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <ui/ICameraClient.h> #include <ui/ICameraService.h> #include <ui/Camera.h> #include <ui/CameraParameters.h> #include <ui/GraphicBuffer.h> #include <ui/ISurface.h> #include <ui/Overlay.h> #include <utils/String16.h> #include <utils/String8.h> namespace android { class CameraBuffer : public MediaBuffer { public: CameraBuffer(const sp<IMemory> &frame) : MediaBuffer(frame->pointer(), frame->size()), mFrame(frame) { } static int64_t getNowUs() { struct timeval tv; gettimeofday(&tv, NULL); sp<IMemory> releaseFrame() { sp<IMemory> frame = mFrame; mFrame.clear(); return frame; return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; } private: sp<IMemory> mFrame; }; struct DummySurface : public BnSurface { DummySurface() {} class CameraSourceClient : public BnCameraClient { public: CameraSourceClient() : mSource(NULL) { virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) { return NULL; } virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { CHECK(mSource != NULL); mSource->notifyCallback(msgType, ext1, ext2); virtual status_t registerBuffers(const BufferHeap &buffers) { return OK; } virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) { CHECK(mSource != NULL); mSource->dataCallback(msgType, data); } virtual void postBuffer(ssize_t offset) {} virtual void unregisterBuffers() {} void setCameraSource(CameraSource *source) { mSource = source; virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format) { return NULL; } protected: virtual ~DummySurface() {} DummySurface(const DummySurface &); DummySurface &operator=(const DummySurface &); }; struct CameraSourceListener : public CameraListener { CameraSourceListener(const sp<CameraSource> &source); virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr); virtual void postDataTimestamp( nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); protected: virtual ~CameraSourceListener(); private: CameraSource *mSource; wp<CameraSource> mSource; CameraSourceListener(const CameraSourceListener &); CameraSourceListener &operator=(const CameraSourceListener &); }; class DummySurface : public BnSurface { public: DummySurface() {} CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) : mSource(source) { } virtual status_t registerBuffers(const BufferHeap &buffers) { return OK; CameraSourceListener::~CameraSourceListener() { } virtual void postBuffer(ssize_t offset) { void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { LOGV("notify(%d, %d, %d)", msgType, ext1, ext2); } virtual void unregisterBuffers() { 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); } } virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format) { return NULL; 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()); } }; // static CameraSource *CameraSource::Create() { sp<IServiceManager> sm = defaultServiceManager(); sp<ICameraService> service = interface_cast<ICameraService>( sm->getService(String16("media.camera"))); sp<CameraSourceClient> client = new CameraSourceClient; sp<ICamera> camera = service->connect(client); sp<Camera> camera = Camera::connect(); CameraSource *source = new CameraSource(camera, client); client->setCameraSource(source); if (camera.get() == NULL) { return NULL; } return source; return new CameraSource(camera); } CameraSource::CameraSource( const sp<ICamera> &camera, const sp<ICameraClient> &client) CameraSource::CameraSource(const sp<Camera> &camera) : mCamera(camera), mCameraClient(client), mWidth(0), mHeight(0), mFirstFrameTimeUs(0), mNumFrames(0), mStarted(false) { printf("params: \"%s\"\n", mCamera->getParameters().string()); String8 s = mCamera->getParameters(); printf("params: \"%s\"\n", s.string()); CameraParameters params(s); params.getPreviewSize(&mWidth, &mHeight); } CameraSource::~CameraSource() { if (mStarted) { stop(); } mCamera->disconnect(); } status_t CameraSource::start(MetaData *) { CHECK(!mStarted); status_t err = mCamera->lock(); CHECK_EQ(err, OK); mCamera->setListener(new CameraSourceListener(this)); err = mCamera->setPreviewDisplay(new DummySurface); sp<ISurface> dummy = new DummySurface; status_t err = mCamera->setPreviewDisplay(dummy); CHECK_EQ(err, OK); mCamera->setPreviewCallbackFlag(1); mCamera->startPreview(); mCamera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK); err = mCamera->startPreview(); CHECK_EQ(err, OK); mStarted = true; Loading @@ -146,7 +168,6 @@ status_t CameraSource::stop() { CHECK(mStarted); mCamera->stopPreview(); mCamera->unlock(); mStarted = false; Loading @@ -157,8 +178,8 @@ sp<MetaData> CameraSource::getFormat() { sp<MetaData> meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar); meta->setInt32(kKeyWidth, 480); meta->setInt32(kKeyHeight, 320); meta->setInt32(kKeyWidth, mWidth); meta->setInt32(kKeyHeight, mHeight); return meta; } Loading @@ -175,6 +196,7 @@ status_t CameraSource::read( } sp<IMemory> frame; int64_t frameTime; { Mutex::Autolock autoLock(mLock); Loading @@ -184,40 +206,33 @@ status_t CameraSource::read( frame = *mFrames.begin(); mFrames.erase(mFrames.begin()); } int count = mNumFrames++; frameTime = *mFrameTimes.begin(); mFrameTimes.erase(mFrameTimes.begin()); } *buffer = new CameraBuffer(frame); *buffer = new MediaBuffer(frame->size()); memcpy((*buffer)->data(), frame->pointer(), frame->size()); (*buffer)->set_range(0, frame->size()); (*buffer)->meta_data()->clear(); (*buffer)->meta_data()->setInt64(kKeyTime, (count * 1000000) / 15); (*buffer)->add_ref(); (*buffer)->setObserver(this); (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); return OK; } void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2); } void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) { Mutex::Autolock autoLock(mLock); mFrames.push_back(data); mFrameAvailableCondition.signal(); int64_t nowUs = getNowUs(); if (mNumFrames == 0) { mFirstFrameTimeUs = nowUs; } ++mNumFrames; void CameraSource::signalBufferReturned(MediaBuffer *_buffer) { CameraBuffer *buffer = static_cast<CameraBuffer *>(_buffer); mCamera->releaseRecordingFrame(buffer->releaseFrame()); buffer->setObserver(NULL); buffer->release(); buffer = NULL; mFrames.push_back(data); mFrameTimes.push_back(nowUs - mFirstFrameTimeUs); mFrameAvailableCondition.signal(); } } // namespace android Loading
include/media/stagefright/CameraSource.h +13 −13 Original line number Diff line number Diff line Loading @@ -26,12 +26,11 @@ namespace android { class ICamera; class ICameraClient; class IMemory; class ISurface; class Camera; class CameraSource : public MediaSource, public MediaBufferObserver { class CameraSource : public MediaSource { public: static CameraSource *Create(); Loading @@ -45,24 +44,25 @@ public: virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2); virtual void dataCallback(int32_t msgType, const sp<IMemory>& data); virtual void signalBufferReturned(MediaBuffer *buffer); private: CameraSource(const sp<ICamera> &camera, const sp<ICameraClient> &client); friend class CameraSourceListener; sp<ICamera> mCamera; sp<ICameraClient> mCameraClient; sp<Camera> mCamera; Mutex mLock; Condition mFrameAvailableCondition; List<sp<IMemory> > mFrames; List<int64_t> mFrameTimes; int mNumFrames; int mWidth, mHeight; int64_t mFirstFrameTimeUs; int32_t mNumFrames; bool mStarted; CameraSource(const sp<Camera> &camera); void dataCallback(int32_t msgType, const sp<IMemory> &data); CameraSource(const CameraSource &); CameraSource &operator=(const CameraSource &); }; Loading
media/libstagefright/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true) LOCAL_SRC_FILES += \ AMRExtractor.cpp \ CachingDataSource.cpp \ CameraSource.cpp \ DataSource.cpp \ FileSource.cpp \ HTTPDataSource.cpp \ Loading
media/libstagefright/CameraSource.cpp +107 −92 Original line number Diff line number Diff line Loading @@ -21,120 +21,142 @@ #include <binder/IServiceManager.h> #include <media/stagefright/CameraSource.h> #include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <ui/ICameraClient.h> #include <ui/ICameraService.h> #include <ui/Camera.h> #include <ui/CameraParameters.h> #include <ui/GraphicBuffer.h> #include <ui/ISurface.h> #include <ui/Overlay.h> #include <utils/String16.h> #include <utils/String8.h> namespace android { class CameraBuffer : public MediaBuffer { public: CameraBuffer(const sp<IMemory> &frame) : MediaBuffer(frame->pointer(), frame->size()), mFrame(frame) { } static int64_t getNowUs() { struct timeval tv; gettimeofday(&tv, NULL); sp<IMemory> releaseFrame() { sp<IMemory> frame = mFrame; mFrame.clear(); return frame; return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; } private: sp<IMemory> mFrame; }; struct DummySurface : public BnSurface { DummySurface() {} class CameraSourceClient : public BnCameraClient { public: CameraSourceClient() : mSource(NULL) { virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) { return NULL; } virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { CHECK(mSource != NULL); mSource->notifyCallback(msgType, ext1, ext2); virtual status_t registerBuffers(const BufferHeap &buffers) { return OK; } virtual void dataCallback(int32_t msgType, const sp<IMemory> &data) { CHECK(mSource != NULL); mSource->dataCallback(msgType, data); } virtual void postBuffer(ssize_t offset) {} virtual void unregisterBuffers() {} void setCameraSource(CameraSource *source) { mSource = source; virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format) { return NULL; } protected: virtual ~DummySurface() {} DummySurface(const DummySurface &); DummySurface &operator=(const DummySurface &); }; struct CameraSourceListener : public CameraListener { CameraSourceListener(const sp<CameraSource> &source); virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr); virtual void postDataTimestamp( nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); protected: virtual ~CameraSourceListener(); private: CameraSource *mSource; wp<CameraSource> mSource; CameraSourceListener(const CameraSourceListener &); CameraSourceListener &operator=(const CameraSourceListener &); }; class DummySurface : public BnSurface { public: DummySurface() {} CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) : mSource(source) { } virtual status_t registerBuffers(const BufferHeap &buffers) { return OK; CameraSourceListener::~CameraSourceListener() { } virtual void postBuffer(ssize_t offset) { void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { LOGV("notify(%d, %d, %d)", msgType, ext1, ext2); } virtual void unregisterBuffers() { 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); } } virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format) { return NULL; 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()); } }; // static CameraSource *CameraSource::Create() { sp<IServiceManager> sm = defaultServiceManager(); sp<ICameraService> service = interface_cast<ICameraService>( sm->getService(String16("media.camera"))); sp<CameraSourceClient> client = new CameraSourceClient; sp<ICamera> camera = service->connect(client); sp<Camera> camera = Camera::connect(); CameraSource *source = new CameraSource(camera, client); client->setCameraSource(source); if (camera.get() == NULL) { return NULL; } return source; return new CameraSource(camera); } CameraSource::CameraSource( const sp<ICamera> &camera, const sp<ICameraClient> &client) CameraSource::CameraSource(const sp<Camera> &camera) : mCamera(camera), mCameraClient(client), mWidth(0), mHeight(0), mFirstFrameTimeUs(0), mNumFrames(0), mStarted(false) { printf("params: \"%s\"\n", mCamera->getParameters().string()); String8 s = mCamera->getParameters(); printf("params: \"%s\"\n", s.string()); CameraParameters params(s); params.getPreviewSize(&mWidth, &mHeight); } CameraSource::~CameraSource() { if (mStarted) { stop(); } mCamera->disconnect(); } status_t CameraSource::start(MetaData *) { CHECK(!mStarted); status_t err = mCamera->lock(); CHECK_EQ(err, OK); mCamera->setListener(new CameraSourceListener(this)); err = mCamera->setPreviewDisplay(new DummySurface); sp<ISurface> dummy = new DummySurface; status_t err = mCamera->setPreviewDisplay(dummy); CHECK_EQ(err, OK); mCamera->setPreviewCallbackFlag(1); mCamera->startPreview(); mCamera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK); err = mCamera->startPreview(); CHECK_EQ(err, OK); mStarted = true; Loading @@ -146,7 +168,6 @@ status_t CameraSource::stop() { CHECK(mStarted); mCamera->stopPreview(); mCamera->unlock(); mStarted = false; Loading @@ -157,8 +178,8 @@ sp<MetaData> CameraSource::getFormat() { sp<MetaData> meta = new MetaData; meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar); meta->setInt32(kKeyWidth, 480); meta->setInt32(kKeyHeight, 320); meta->setInt32(kKeyWidth, mWidth); meta->setInt32(kKeyHeight, mHeight); return meta; } Loading @@ -175,6 +196,7 @@ status_t CameraSource::read( } sp<IMemory> frame; int64_t frameTime; { Mutex::Autolock autoLock(mLock); Loading @@ -184,40 +206,33 @@ status_t CameraSource::read( frame = *mFrames.begin(); mFrames.erase(mFrames.begin()); } int count = mNumFrames++; frameTime = *mFrameTimes.begin(); mFrameTimes.erase(mFrameTimes.begin()); } *buffer = new CameraBuffer(frame); *buffer = new MediaBuffer(frame->size()); memcpy((*buffer)->data(), frame->pointer(), frame->size()); (*buffer)->set_range(0, frame->size()); (*buffer)->meta_data()->clear(); (*buffer)->meta_data()->setInt64(kKeyTime, (count * 1000000) / 15); (*buffer)->add_ref(); (*buffer)->setObserver(this); (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); return OK; } void CameraSource::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { printf("notifyCallback %d, %d, %d\n", msgType, ext1, ext2); } void CameraSource::dataCallback(int32_t msgType, const sp<IMemory> &data) { Mutex::Autolock autoLock(mLock); mFrames.push_back(data); mFrameAvailableCondition.signal(); int64_t nowUs = getNowUs(); if (mNumFrames == 0) { mFirstFrameTimeUs = nowUs; } ++mNumFrames; void CameraSource::signalBufferReturned(MediaBuffer *_buffer) { CameraBuffer *buffer = static_cast<CameraBuffer *>(_buffer); mCamera->releaseRecordingFrame(buffer->releaseFrame()); buffer->setObserver(NULL); buffer->release(); buffer = NULL; mFrames.push_back(data); mFrameTimes.push_back(nowUs - mFirstFrameTimeUs); mFrameAvailableCondition.signal(); } } // namespace android