Loading camera/Camera.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -136,6 +136,15 @@ status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProduc return c->setPreviewTarget(bufferProducer); } status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setVideoTarget(%p)", bufferProducer.get()); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; ALOGD_IF(bufferProducer == 0, "app passed NULL video surface"); return c->setVideoTarget(bufferProducer); } // start preview mode status_t Camera::startPreview() { Loading @@ -145,13 +154,12 @@ status_t Camera::startPreview() return c->startPreview(); } status_t Camera::storeMetaDataInBuffers(bool enabled) status_t Camera::setVideoBufferMode(int32_t videoBufferMode) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); ALOGV("setVideoBufferMode: %d", videoBufferMode); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; return c->storeMetaDataInBuffers(enabled); return c->setVideoBufferMode(videoBufferMode); } // start recording mode, must call setPreviewTarget first Loading camera/ICamera.cpp +29 −9 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ enum { STOP_RECORDING, RECORDING_ENABLED, RELEASE_RECORDING_FRAME, STORE_META_DATA_IN_BUFFERS, SET_VIDEO_BUFFER_MODE, SET_VIDEO_BUFFER_TARGET, }; class BpCamera: public BpInterface<ICamera> Loading Loading @@ -151,13 +152,13 @@ public: remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } status_t storeMetaDataInBuffers(bool enabled) status_t setVideoBufferMode(int32_t videoBufferMode) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); ALOGV("setVideoBufferMode: %d", videoBufferMode); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(enabled); remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); data.writeInt32(videoBufferMode); remote()->transact(SET_VIDEO_BUFFER_MODE, data, &reply); return reply.readInt32(); } Loading Loading @@ -268,6 +269,17 @@ public: remote()->transact(UNLOCK, data, &reply); return reply.readInt32(); } status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setVideoTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(SET_VIDEO_BUFFER_TARGET, data, &reply); return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera"); Loading Loading @@ -339,11 +351,11 @@ status_t BnCamera::onTransact( releaseRecordingFrame(mem); return NO_ERROR; } break; case STORE_META_DATA_IN_BUFFERS: { ALOGV("STORE_META_DATA_IN_BUFFERS"); case SET_VIDEO_BUFFER_MODE: { ALOGV("SET_VIDEO_BUFFER_MODE"); CHECK_INTERFACE(ICamera, data, reply); bool enabled = data.readInt32(); reply->writeInt32(storeMetaDataInBuffers(enabled)); int32_t mode = data.readInt32(); reply->writeInt32(setVideoBufferMode(mode)); return NO_ERROR; } break; case PREVIEW_ENABLED: { Loading Loading @@ -415,6 +427,14 @@ status_t BnCamera::onTransact( reply->writeInt32(unlock()); return NO_ERROR; } break; case SET_VIDEO_BUFFER_TARGET: { ALOGV("SET_VIDEO_BUFFER_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> st = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setVideoTarget(st)); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } Loading include/camera/Camera.h +9 −2 Original line number Diff line number Diff line Loading @@ -126,8 +126,15 @@ public: // send command to camera driver status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); // tell camera hal to store meta data or real YUV in video buffers. status_t storeMetaDataInBuffers(bool enabled); // Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*. // Returns OK if the specified video buffer mode is supported. If videoBufferMode is // VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting // video recording. status_t setVideoBufferMode(int32_t videoBufferMode); // Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE // mode. status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer); void setListener(const sp<CameraListener>& listener); void setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener); Loading include/camera/ICamera.h +19 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,15 @@ class ICamera: public IInterface * Keep up-to-date with ICamera.aidl in frameworks/base */ public: enum { // Pass real YUV data in video buffers through ICameraClient.dataCallbackTimestamp(). VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV = 0, // Pass metadata in video buffers through ICameraClient.dataCallbackTimestamp(). VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA = 1, // Pass video buffers through IGraphicBufferProducer set with setVideoTarget(). VIDEO_BUFFER_MODE_BUFFER_QUEUE = 2, }; DECLARE_META_INTERFACE(Camera); virtual void disconnect() = 0; Loading Loading @@ -109,8 +118,16 @@ public: // send command to camera driver virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; // tell the camera hal to store meta data or real YUV data in video buffers. virtual status_t storeMetaDataInBuffers(bool enabled) = 0; // Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*. // Returns OK if the specified video buffer mode is supported. If videoBufferMode is // VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting video // recording. virtual status_t setVideoBufferMode(int32_t videoBufferMode) = 0; // Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. virtual status_t setVideoTarget( const sp<IGraphicBufferProducer>& bufferProducer) = 0; }; // ---------------------------------------------------------------------------- Loading include/media/stagefright/CameraSource.h +57 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <camera/ICamera.h> #include <camera/ICameraRecordingProxyListener.h> #include <camera/CameraParameters.h> #include <gui/BufferItemConsumer.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/String16.h> Loading Loading @@ -122,6 +123,12 @@ public: virtual void signalBufferReturned(MediaBuffer* buffer); protected: /** * The class for listening to BnCameraRecordingProxyListener. This is used to receive video * buffers in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA * mode. When a frame is available, CameraSource::dataCallbackTimestamp() will be called. */ class ProxyListener: public BnCameraRecordingProxyListener { public: ProxyListener(const sp<CameraSource>& source); Loading @@ -132,6 +139,28 @@ protected: sp<CameraSource> mSource; }; /** * The class for listening to BufferQueue's onFrameAvailable. This is used to receive video * buffers in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. When a frame is available, * CameraSource::processBufferQueueFrame() will be called. */ class BufferQueueListener : public Thread, public BufferItemConsumer::FrameAvailableListener { public: BufferQueueListener(const sp<BufferItemConsumer> &consumer, const sp<CameraSource> &cameraSource); virtual void onFrameAvailable(const BufferItem& item); virtual bool threadLoop(); private: static const nsecs_t kFrameAvailableTimeout = 50000000; // 50ms sp<BufferItemConsumer> mConsumer; sp<CameraSource> mCameraSource; Mutex mLock; Condition mFrameAvailableSignal; bool mFrameAvailable; }; // isBinderAlive needs linkToDeath to work. class DeathNotifier: public IBinder::DeathRecipient { public: Loading Loading @@ -204,11 +233,29 @@ private: int32_t mNumGlitches; int64_t mGlitchDurationThresholdUs; bool mCollectStats; bool mIsMetaDataStoredInVideoBuffers; // The mode video buffers are received from camera. One of VIDEO_BUFFER_MODE_*. int32_t mVideoBufferMode; /** * The following variables are used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. */ static const size_t kConsumerBufferCount = 8; // Consumer and producer of the buffer queue between this class and camera. sp<BufferItemConsumer> mVideoBufferConsumer; sp<IGraphicBufferProducer> mVideoBufferProducer; // Memory used to send the buffers to encoder, where sp<IMemory> stores VideoNativeMetadata. sp<IMemoryHeap> mMemoryHeapBase; List<sp<IMemory>> mMemoryBases; // A mapping from ANativeWindowBuffer sent to encoder to BufferItem received from camera. // This is protected by mLock. KeyedVector<ANativeWindowBuffer*, BufferItem> mReceivedBufferItemMap; sp<BufferQueueListener> mBufferQueueListener; void releaseQueuedFrames(); void releaseOneRecordingFrame(const sp<IMemory>& frame); // Process a buffer item received in BufferQueueListener. void processBufferQueueFrame(const BufferItem& buffer); status_t init(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, int32_t cameraId, const String16& clientName, uid_t clientUid, Loading @@ -219,6 +266,10 @@ private: int32_t cameraId, const String16& clientName, uid_t clientUid, Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers); // Initialize the buffer queue used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. status_t initBufferQueue(uint32_t width, uint32_t height, uint32_t format, android_dataspace dataSpace, uint32_t bufferCount); status_t isCameraAvailable(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, int32_t cameraId, Loading @@ -236,6 +287,10 @@ private: status_t checkFrameRate(const CameraParameters& params, int32_t frameRate); // Check if this frame should be skipped based on the frame's timestamp in microsecond. // mLock must be locked before calling this function. bool shouldSkipFrameLocked(int64_t timestampUs); void stopCameraRecording(); status_t reset(); Loading Loading
camera/Camera.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -136,6 +136,15 @@ status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProduc return c->setPreviewTarget(bufferProducer); } status_t Camera::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setVideoTarget(%p)", bufferProducer.get()); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; ALOGD_IF(bufferProducer == 0, "app passed NULL video surface"); return c->setVideoTarget(bufferProducer); } // start preview mode status_t Camera::startPreview() { Loading @@ -145,13 +154,12 @@ status_t Camera::startPreview() return c->startPreview(); } status_t Camera::storeMetaDataInBuffers(bool enabled) status_t Camera::setVideoBufferMode(int32_t videoBufferMode) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); ALOGV("setVideoBufferMode: %d", videoBufferMode); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; return c->storeMetaDataInBuffers(enabled); return c->setVideoBufferMode(videoBufferMode); } // start recording mode, must call setPreviewTarget first Loading
camera/ICamera.cpp +29 −9 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ enum { STOP_RECORDING, RECORDING_ENABLED, RELEASE_RECORDING_FRAME, STORE_META_DATA_IN_BUFFERS, SET_VIDEO_BUFFER_MODE, SET_VIDEO_BUFFER_TARGET, }; class BpCamera: public BpInterface<ICamera> Loading Loading @@ -151,13 +152,13 @@ public: remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } status_t storeMetaDataInBuffers(bool enabled) status_t setVideoBufferMode(int32_t videoBufferMode) { ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false"); ALOGV("setVideoBufferMode: %d", videoBufferMode); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); data.writeInt32(enabled); remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); data.writeInt32(videoBufferMode); remote()->transact(SET_VIDEO_BUFFER_MODE, data, &reply); return reply.readInt32(); } Loading Loading @@ -268,6 +269,17 @@ public: remote()->transact(UNLOCK, data, &reply); return reply.readInt32(); } status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) { ALOGV("setVideoTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(SET_VIDEO_BUFFER_TARGET, data, &reply); return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera"); Loading Loading @@ -339,11 +351,11 @@ status_t BnCamera::onTransact( releaseRecordingFrame(mem); return NO_ERROR; } break; case STORE_META_DATA_IN_BUFFERS: { ALOGV("STORE_META_DATA_IN_BUFFERS"); case SET_VIDEO_BUFFER_MODE: { ALOGV("SET_VIDEO_BUFFER_MODE"); CHECK_INTERFACE(ICamera, data, reply); bool enabled = data.readInt32(); reply->writeInt32(storeMetaDataInBuffers(enabled)); int32_t mode = data.readInt32(); reply->writeInt32(setVideoBufferMode(mode)); return NO_ERROR; } break; case PREVIEW_ENABLED: { Loading Loading @@ -415,6 +427,14 @@ status_t BnCamera::onTransact( reply->writeInt32(unlock()); return NO_ERROR; } break; case SET_VIDEO_BUFFER_TARGET: { ALOGV("SET_VIDEO_BUFFER_TARGET"); CHECK_INTERFACE(ICamera, data, reply); sp<IGraphicBufferProducer> st = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); reply->writeInt32(setVideoTarget(st)); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } Loading
include/camera/Camera.h +9 −2 Original line number Diff line number Diff line Loading @@ -126,8 +126,15 @@ public: // send command to camera driver status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); // tell camera hal to store meta data or real YUV in video buffers. status_t storeMetaDataInBuffers(bool enabled); // Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*. // Returns OK if the specified video buffer mode is supported. If videoBufferMode is // VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting // video recording. status_t setVideoBufferMode(int32_t videoBufferMode); // Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE // mode. status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer); void setListener(const sp<CameraListener>& listener); void setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener); Loading
include/camera/ICamera.h +19 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,15 @@ class ICamera: public IInterface * Keep up-to-date with ICamera.aidl in frameworks/base */ public: enum { // Pass real YUV data in video buffers through ICameraClient.dataCallbackTimestamp(). VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV = 0, // Pass metadata in video buffers through ICameraClient.dataCallbackTimestamp(). VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA = 1, // Pass video buffers through IGraphicBufferProducer set with setVideoTarget(). VIDEO_BUFFER_MODE_BUFFER_QUEUE = 2, }; DECLARE_META_INTERFACE(Camera); virtual void disconnect() = 0; Loading Loading @@ -109,8 +118,16 @@ public: // send command to camera driver virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; // tell the camera hal to store meta data or real YUV data in video buffers. virtual status_t storeMetaDataInBuffers(bool enabled) = 0; // Tell camera how to pass video buffers. videoBufferMode is one of VIDEO_BUFFER_MODE_*. // Returns OK if the specified video buffer mode is supported. If videoBufferMode is // VIDEO_BUFFER_MODE_BUFFER_QUEUE, setVideoTarget() must be called before starting video // recording. virtual status_t setVideoBufferMode(int32_t videoBufferMode) = 0; // Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. virtual status_t setVideoTarget( const sp<IGraphicBufferProducer>& bufferProducer) = 0; }; // ---------------------------------------------------------------------------- Loading
include/media/stagefright/CameraSource.h +57 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <camera/ICamera.h> #include <camera/ICameraRecordingProxyListener.h> #include <camera/CameraParameters.h> #include <gui/BufferItemConsumer.h> #include <utils/List.h> #include <utils/RefBase.h> #include <utils/String16.h> Loading Loading @@ -122,6 +123,12 @@ public: virtual void signalBufferReturned(MediaBuffer* buffer); protected: /** * The class for listening to BnCameraRecordingProxyListener. This is used to receive video * buffers in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA * mode. When a frame is available, CameraSource::dataCallbackTimestamp() will be called. */ class ProxyListener: public BnCameraRecordingProxyListener { public: ProxyListener(const sp<CameraSource>& source); Loading @@ -132,6 +139,28 @@ protected: sp<CameraSource> mSource; }; /** * The class for listening to BufferQueue's onFrameAvailable. This is used to receive video * buffers in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. When a frame is available, * CameraSource::processBufferQueueFrame() will be called. */ class BufferQueueListener : public Thread, public BufferItemConsumer::FrameAvailableListener { public: BufferQueueListener(const sp<BufferItemConsumer> &consumer, const sp<CameraSource> &cameraSource); virtual void onFrameAvailable(const BufferItem& item); virtual bool threadLoop(); private: static const nsecs_t kFrameAvailableTimeout = 50000000; // 50ms sp<BufferItemConsumer> mConsumer; sp<CameraSource> mCameraSource; Mutex mLock; Condition mFrameAvailableSignal; bool mFrameAvailable; }; // isBinderAlive needs linkToDeath to work. class DeathNotifier: public IBinder::DeathRecipient { public: Loading Loading @@ -204,11 +233,29 @@ private: int32_t mNumGlitches; int64_t mGlitchDurationThresholdUs; bool mCollectStats; bool mIsMetaDataStoredInVideoBuffers; // The mode video buffers are received from camera. One of VIDEO_BUFFER_MODE_*. int32_t mVideoBufferMode; /** * The following variables are used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. */ static const size_t kConsumerBufferCount = 8; // Consumer and producer of the buffer queue between this class and camera. sp<BufferItemConsumer> mVideoBufferConsumer; sp<IGraphicBufferProducer> mVideoBufferProducer; // Memory used to send the buffers to encoder, where sp<IMemory> stores VideoNativeMetadata. sp<IMemoryHeap> mMemoryHeapBase; List<sp<IMemory>> mMemoryBases; // A mapping from ANativeWindowBuffer sent to encoder to BufferItem received from camera. // This is protected by mLock. KeyedVector<ANativeWindowBuffer*, BufferItem> mReceivedBufferItemMap; sp<BufferQueueListener> mBufferQueueListener; void releaseQueuedFrames(); void releaseOneRecordingFrame(const sp<IMemory>& frame); // Process a buffer item received in BufferQueueListener. void processBufferQueueFrame(const BufferItem& buffer); status_t init(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, int32_t cameraId, const String16& clientName, uid_t clientUid, Loading @@ -219,6 +266,10 @@ private: int32_t cameraId, const String16& clientName, uid_t clientUid, Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers); // Initialize the buffer queue used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. status_t initBufferQueue(uint32_t width, uint32_t height, uint32_t format, android_dataspace dataSpace, uint32_t bufferCount); status_t isCameraAvailable(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, int32_t cameraId, Loading @@ -236,6 +287,10 @@ private: status_t checkFrameRate(const CameraParameters& params, int32_t frameRate); // Check if this frame should be skipped based on the frame's timestamp in microsecond. // mLock must be locked before calling this function. bool shouldSkipFrameLocked(int64_t timestampUs); void stopCameraRecording(); status_t reset(); Loading