Loading camera/IProCameraUser.cpp +145 −33 Original line number Diff line number Diff line Loading @@ -42,8 +42,78 @@ enum { CANCEL_REQUEST, REQUEST_STREAM, CANCEL_STREAM, CREATE_STREAM, CREATE_DEFAULT_REQUEST, }; /** * Caller becomes the owner of the new metadata * 'const Parcel' doesnt prevent us from calling the read functions. * which is interesting since it changes the internal state */ void readMetadata(const Parcel& data, camera_metadata_t** out) { camera_metadata_t* metadata; // arg0 = metadataSize (int32) size_t metadataSize = static_cast<size_t>(data.readInt32()); if (metadataSize == 0) { if (out) { *out = NULL; } return; } // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) { data.readBlob(metadataSize, &blob); const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); size_t entry_capacity = get_camera_metadata_entry_capacity(tmp); size_t data_capacity = get_camera_metadata_data_capacity(tmp); metadata = allocate_camera_metadata(entry_capacity, data_capacity); copy_camera_metadata(metadata, metadataSize, tmp); } blob.release(); if (out) { *out = metadata; } else { free_camera_metadata(metadata); } } /** * Caller retains ownership of metadata * - Write 2 (int32 + blob) args in the current position */ void writeMetadata(Parcel& data, camera_metadata_t* metadata) { // arg0 = metadataSize (int32) size_t metadataSize; if (metadata == NULL) { data.writeInt32(0); return; } metadataSize = get_camera_metadata_compact_size(metadata); data.writeInt32(static_cast<int32_t>(metadataSize)); // arg1 = metadata (blob) WritableBlob blob; { data.writeBlob(metadataSize, &blob); copy_camera_metadata(blob.data(), metadataSize, metadata); } blob.release(); } class BpProCameraUser: public BpInterface<IProCameraUser> { public: Loading Loading @@ -109,17 +179,8 @@ public: Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); // arg0 = metadataSize (int32) size_t metadataSize = get_camera_metadata_compact_size(metadata); data.writeInt32(static_cast<int32_t>(metadataSize)); // arg1 = metadata (blob) WritableBlob blob; { data.writeBlob(metadataSize, &blob); copy_camera_metadata(blob.data(), metadataSize, metadata); } blob.release(); // arg0+arg1 writeMetadata(data, metadata); // arg2 = streaming (bool) data.writeInt32(streaming); Loading Loading @@ -157,6 +218,44 @@ public: return reply.readInt32(); } virtual status_t createStream(int width, int height, int format, const sp<Surface>& surface, /*out*/ int* streamId) { Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); data.writeInt32(width); data.writeInt32(height); data.writeInt32(format); Surface::writeToParcel(surface, &data); remote()->transact(CREATE_STREAM, data, &reply); int sId = reply.readInt32(); if (streamId) { *streamId = sId; } return reply.readInt32(); } // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ camera_metadata** request) { Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); data.writeInt32(templateId); remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); readMetadata(reply, /*out*/request); return reply.readInt32(); } private: }; IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser"); Loading Loading @@ -205,28 +304,7 @@ status_t BnProCameraUser::onTransact( case SUBMIT_REQUEST: { CHECK_INTERFACE(IProCameraUser, data, reply); camera_metadata_t* metadata; // arg0 = metadataSize (int32) size_t metadataSize = static_cast<size_t>(data.readInt32()); // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) { data.readBlob(metadataSize, &blob); const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); size_t entry_capacity = get_camera_metadata_entry_capacity(tmp); size_t data_capacity = get_camera_metadata_data_capacity(tmp); metadata = allocate_camera_metadata(entry_capacity, data_capacity); copy_camera_metadata(metadata, metadataSize, tmp); } blob.release(); readMetadata(data, /*out*/&metadata); // arg2 = streaming (bool) bool streaming = data.readInt32(); Loading Loading @@ -254,6 +332,40 @@ status_t BnProCameraUser::onTransact( reply->writeInt32(cancelStream(streamId)); return NO_ERROR; } break; case CREATE_STREAM: { CHECK_INTERFACE(IProCameraUser, data, reply); int width, height, format; width = data.readInt32(); height = data.readInt32(); format = data.readInt32(); sp<Surface> surface = Surface::readFromParcel(data); int streamId = -1; status_t ret; ret = createStream(width, height, format, surface, &streamId); reply->writeInt32(streamId); reply->writeInt32(ret); return NO_ERROR; } break; case CREATE_DEFAULT_REQUEST: { CHECK_INTERFACE(IProCameraUser, data, reply); int templateId = data.readInt32(); camera_metadata_t* request = NULL; status_t ret; ret = createDefaultRequest(templateId, &request); writeMetadata(*reply, request); reply->writeInt32(ret); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } Loading camera/ProCamera.cpp +12 −13 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ status_t ProCamera::cancelStream(int streamId) } status_t ProCamera::createStream(int width, int height, int format, const sp<ANativeWindow>& window, const sp<Surface>& surface, /*out*/ int* streamId) { Loading @@ -271,12 +271,14 @@ status_t ProCamera::createStream(int width, int height, int format, ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height, format); if (window == 0) { if (surface == 0) { return BAD_VALUE; } // TODO: actually implement this in IProCamera return INVALID_OPERATION; sp <IProCameraUser> c = mCamera; if (c == 0) return NO_INIT; return c->createStream(width, height, format, surface, streamId); } status_t ProCamera::createStream(int width, int height, int format, Loading @@ -288,13 +290,10 @@ status_t ProCamera::createStream(int width, int height, int format, format); sp<IBinder> binder; sp<ANativeWindow> window; status_t stat = INVALID_OPERATION; if (bufferProducer != 0) { binder = bufferProducer->asBinder(); window = new Surface(bufferProducer); status_t stat = createStream(width, height, format, window, streamId); ALOGV("%s: createStreamT END (%d), StreamID = %d", __FUNCTION__, stat, *streamId); Loading @@ -304,7 +303,7 @@ status_t ProCamera::createStream(int width, int height, int format, return BAD_VALUE; } return BAD_VALUE; return stat; } int ProCamera::getNumberOfCameras() { Loading @@ -321,12 +320,12 @@ camera_metadata* ProCamera::getCameraInfo(int cameraId) { status_t ProCamera::createDefaultRequest(int templateId, camera_metadata** request) const { ALOGE("%s: not implemented yet", __FUNCTION__); ALOGV("%s: templateId = %d", __FUNCTION__, templateId); *request = NULL; return INVALID_OPERATION; sp <IProCameraUser> c = mCamera; if (c == 0) return NO_INIT; return c->createDefaultRequest(templateId, request); } }; // namespace android camera/tests/ProCameraTests.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -317,14 +317,12 @@ TEST_F(ProCameraTest, StreamingImage) { } sp<Surface> surface; sp<ANativeWindow> window; if (mDisplaySecs > 0) { createOnScreenSurface(/*out*/surface); window = surface; } int streamId = -1; EXPECT_OK(mCamera->createStream(/*width*/640, /*height*/480, TEST_FORMAT, window, &streamId)); surface, &streamId)); EXPECT_NE(-1, streamId); EXPECT_OK(mCamera->exclusiveTryLock()); Loading @@ -351,8 +349,16 @@ TEST_F(ProCameraTest, StreamingImage) { uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); int find = find_camera_metadata_entry(request, tag, &entry); if (find == -ENOENT) { if (add_camera_metadata_entry(request, tag, &streamId, /*data_count*/1) != OK) { camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); ASSERT_OK(append_camera_metadata(tmp, request)); free_camera_metadata(request); request = tmp; ASSERT_OK(add_camera_metadata_entry(request, tag, &streamId, /*data_count*/1)); } } else { ASSERT_OK(update_camera_metadata_entry(request, entry.index, &streamId, /*data_count*/1, &entry)); Loading @@ -360,10 +366,8 @@ TEST_F(ProCameraTest, StreamingImage) { EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); dout << "will sleep now for " << mDisplaySecs << std::endl; sleep(mDisplaySecs); //should the window be empty until the buffer is flipped? // that would certainly make sense free_camera_metadata(request); EXPECT_OK(mCamera->cancelStream(streamId)); Loading include/camera/IProCameraUser.h +10 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,16 @@ public: virtual status_t requestStream(int streamId) = 0; virtual status_t cancelStream(int streamId) = 0; virtual status_t createStream(int width, int height, int format, const sp<Surface>& surface, /*out*/ int* streamId) = 0; // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ camera_metadata** request) = 0; }; Loading include/camera/ProCamera.h +1 −1 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public: * Errors: -EBUSY if too many streams created */ status_t createStream(int width, int height, int format, const sp<ANativeWindow>& window, const sp<Surface>& surface, /*out*/ int* streamId); Loading Loading
camera/IProCameraUser.cpp +145 −33 Original line number Diff line number Diff line Loading @@ -42,8 +42,78 @@ enum { CANCEL_REQUEST, REQUEST_STREAM, CANCEL_STREAM, CREATE_STREAM, CREATE_DEFAULT_REQUEST, }; /** * Caller becomes the owner of the new metadata * 'const Parcel' doesnt prevent us from calling the read functions. * which is interesting since it changes the internal state */ void readMetadata(const Parcel& data, camera_metadata_t** out) { camera_metadata_t* metadata; // arg0 = metadataSize (int32) size_t metadataSize = static_cast<size_t>(data.readInt32()); if (metadataSize == 0) { if (out) { *out = NULL; } return; } // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) { data.readBlob(metadataSize, &blob); const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); size_t entry_capacity = get_camera_metadata_entry_capacity(tmp); size_t data_capacity = get_camera_metadata_data_capacity(tmp); metadata = allocate_camera_metadata(entry_capacity, data_capacity); copy_camera_metadata(metadata, metadataSize, tmp); } blob.release(); if (out) { *out = metadata; } else { free_camera_metadata(metadata); } } /** * Caller retains ownership of metadata * - Write 2 (int32 + blob) args in the current position */ void writeMetadata(Parcel& data, camera_metadata_t* metadata) { // arg0 = metadataSize (int32) size_t metadataSize; if (metadata == NULL) { data.writeInt32(0); return; } metadataSize = get_camera_metadata_compact_size(metadata); data.writeInt32(static_cast<int32_t>(metadataSize)); // arg1 = metadata (blob) WritableBlob blob; { data.writeBlob(metadataSize, &blob); copy_camera_metadata(blob.data(), metadataSize, metadata); } blob.release(); } class BpProCameraUser: public BpInterface<IProCameraUser> { public: Loading Loading @@ -109,17 +179,8 @@ public: Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); // arg0 = metadataSize (int32) size_t metadataSize = get_camera_metadata_compact_size(metadata); data.writeInt32(static_cast<int32_t>(metadataSize)); // arg1 = metadata (blob) WritableBlob blob; { data.writeBlob(metadataSize, &blob); copy_camera_metadata(blob.data(), metadataSize, metadata); } blob.release(); // arg0+arg1 writeMetadata(data, metadata); // arg2 = streaming (bool) data.writeInt32(streaming); Loading Loading @@ -157,6 +218,44 @@ public: return reply.readInt32(); } virtual status_t createStream(int width, int height, int format, const sp<Surface>& surface, /*out*/ int* streamId) { Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); data.writeInt32(width); data.writeInt32(height); data.writeInt32(format); Surface::writeToParcel(surface, &data); remote()->transact(CREATE_STREAM, data, &reply); int sId = reply.readInt32(); if (streamId) { *streamId = sId; } return reply.readInt32(); } // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ camera_metadata** request) { Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); data.writeInt32(templateId); remote()->transact(CREATE_DEFAULT_REQUEST, data, &reply); readMetadata(reply, /*out*/request); return reply.readInt32(); } private: }; IMPLEMENT_META_INTERFACE(ProCameraUser, "android.hardware.IProCameraUser"); Loading Loading @@ -205,28 +304,7 @@ status_t BnProCameraUser::onTransact( case SUBMIT_REQUEST: { CHECK_INTERFACE(IProCameraUser, data, reply); camera_metadata_t* metadata; // arg0 = metadataSize (int32) size_t metadataSize = static_cast<size_t>(data.readInt32()); // NOTE: this doesn't make sense to me. shouldnt the blob // know how big it is? why do we have to specify the size // to Parcel::readBlob ? ReadableBlob blob; // arg1 = metadata (blob) { data.readBlob(metadataSize, &blob); const camera_metadata_t* tmp = reinterpret_cast<const camera_metadata_t*>(blob.data()); size_t entry_capacity = get_camera_metadata_entry_capacity(tmp); size_t data_capacity = get_camera_metadata_data_capacity(tmp); metadata = allocate_camera_metadata(entry_capacity, data_capacity); copy_camera_metadata(metadata, metadataSize, tmp); } blob.release(); readMetadata(data, /*out*/&metadata); // arg2 = streaming (bool) bool streaming = data.readInt32(); Loading Loading @@ -254,6 +332,40 @@ status_t BnProCameraUser::onTransact( reply->writeInt32(cancelStream(streamId)); return NO_ERROR; } break; case CREATE_STREAM: { CHECK_INTERFACE(IProCameraUser, data, reply); int width, height, format; width = data.readInt32(); height = data.readInt32(); format = data.readInt32(); sp<Surface> surface = Surface::readFromParcel(data); int streamId = -1; status_t ret; ret = createStream(width, height, format, surface, &streamId); reply->writeInt32(streamId); reply->writeInt32(ret); return NO_ERROR; } break; case CREATE_DEFAULT_REQUEST: { CHECK_INTERFACE(IProCameraUser, data, reply); int templateId = data.readInt32(); camera_metadata_t* request = NULL; status_t ret; ret = createDefaultRequest(templateId, &request); writeMetadata(*reply, request); reply->writeInt32(ret); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } Loading
camera/ProCamera.cpp +12 −13 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ status_t ProCamera::cancelStream(int streamId) } status_t ProCamera::createStream(int width, int height, int format, const sp<ANativeWindow>& window, const sp<Surface>& surface, /*out*/ int* streamId) { Loading @@ -271,12 +271,14 @@ status_t ProCamera::createStream(int width, int height, int format, ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height, format); if (window == 0) { if (surface == 0) { return BAD_VALUE; } // TODO: actually implement this in IProCamera return INVALID_OPERATION; sp <IProCameraUser> c = mCamera; if (c == 0) return NO_INIT; return c->createStream(width, height, format, surface, streamId); } status_t ProCamera::createStream(int width, int height, int format, Loading @@ -288,13 +290,10 @@ status_t ProCamera::createStream(int width, int height, int format, format); sp<IBinder> binder; sp<ANativeWindow> window; status_t stat = INVALID_OPERATION; if (bufferProducer != 0) { binder = bufferProducer->asBinder(); window = new Surface(bufferProducer); status_t stat = createStream(width, height, format, window, streamId); ALOGV("%s: createStreamT END (%d), StreamID = %d", __FUNCTION__, stat, *streamId); Loading @@ -304,7 +303,7 @@ status_t ProCamera::createStream(int width, int height, int format, return BAD_VALUE; } return BAD_VALUE; return stat; } int ProCamera::getNumberOfCameras() { Loading @@ -321,12 +320,12 @@ camera_metadata* ProCamera::getCameraInfo(int cameraId) { status_t ProCamera::createDefaultRequest(int templateId, camera_metadata** request) const { ALOGE("%s: not implemented yet", __FUNCTION__); ALOGV("%s: templateId = %d", __FUNCTION__, templateId); *request = NULL; return INVALID_OPERATION; sp <IProCameraUser> c = mCamera; if (c == 0) return NO_INIT; return c->createDefaultRequest(templateId, request); } }; // namespace android
camera/tests/ProCameraTests.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -317,14 +317,12 @@ TEST_F(ProCameraTest, StreamingImage) { } sp<Surface> surface; sp<ANativeWindow> window; if (mDisplaySecs > 0) { createOnScreenSurface(/*out*/surface); window = surface; } int streamId = -1; EXPECT_OK(mCamera->createStream(/*width*/640, /*height*/480, TEST_FORMAT, window, &streamId)); surface, &streamId)); EXPECT_NE(-1, streamId); EXPECT_OK(mCamera->exclusiveTryLock()); Loading @@ -351,8 +349,16 @@ TEST_F(ProCameraTest, StreamingImage) { uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); int find = find_camera_metadata_entry(request, tag, &entry); if (find == -ENOENT) { if (add_camera_metadata_entry(request, tag, &streamId, /*data_count*/1) != OK) { camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); ASSERT_OK(append_camera_metadata(tmp, request)); free_camera_metadata(request); request = tmp; ASSERT_OK(add_camera_metadata_entry(request, tag, &streamId, /*data_count*/1)); } } else { ASSERT_OK(update_camera_metadata_entry(request, entry.index, &streamId, /*data_count*/1, &entry)); Loading @@ -360,10 +366,8 @@ TEST_F(ProCameraTest, StreamingImage) { EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); dout << "will sleep now for " << mDisplaySecs << std::endl; sleep(mDisplaySecs); //should the window be empty until the buffer is flipped? // that would certainly make sense free_camera_metadata(request); EXPECT_OK(mCamera->cancelStream(streamId)); Loading
include/camera/IProCameraUser.h +10 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,16 @@ public: virtual status_t requestStream(int streamId) = 0; virtual status_t cancelStream(int streamId) = 0; virtual status_t createStream(int width, int height, int format, const sp<Surface>& surface, /*out*/ int* streamId) = 0; // Create a request object from a template. virtual status_t createDefaultRequest(int templateId, /*out*/ camera_metadata** request) = 0; }; Loading
include/camera/ProCamera.h +1 −1 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public: * Errors: -EBUSY if too many streams created */ status_t createStream(int width, int height, int format, const sp<ANativeWindow>& window, const sp<Surface>& surface, /*out*/ int* streamId); Loading