Merge "Transcoder: Fix video track transcoding crash."
diff --git a/camera/Android.bp b/camera/Android.bp
index fa36bb3..b777d74 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -38,7 +38,6 @@
"ICamera.cpp",
"ICameraClient.cpp",
"ICameraRecordingProxy.cpp",
- "ICameraRecordingProxyListener.cpp",
"camera2/CaptureRequest.cpp",
"camera2/ConcurrentCamera.cpp",
"camera2/OutputConfiguration.cpp",
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 84d1d93..f7d194e 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -25,7 +25,6 @@
#include <binder/IMemory.h>
#include <Camera.h>
-#include <ICameraRecordingProxyListener.h>
#include <android/hardware/ICameraService.h>
#include <android/hardware/ICamera.h>
@@ -77,63 +76,6 @@
return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
-status_t Camera::connectLegacy(int cameraId, int halVersion,
- const String16& clientPackageName,
- int clientUid,
- sp<Camera>& camera)
-{
- ALOGV("%s: connect legacy camera device", __FUNCTION__);
- sp<Camera> c = new Camera(cameraId);
- sp<::android::hardware::ICameraClient> cl = c;
- status_t status = NO_ERROR;
- const sp<::android::hardware::ICameraService>& cs = CameraBaseT::getCameraService();
-
- binder::Status ret;
- if (cs != nullptr) {
- ret = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
- clientUid, /*out*/&(c->mCamera));
- }
- if (ret.isOk() && c->mCamera != nullptr) {
- IInterface::asBinder(c->mCamera)->linkToDeath(c);
- c->mStatus = NO_ERROR;
- camera = c;
- } else {
- switch(ret.serviceSpecificErrorCode()) {
- case hardware::ICameraService::ERROR_DISCONNECTED:
- status = -ENODEV;
- break;
- case hardware::ICameraService::ERROR_CAMERA_IN_USE:
- status = -EBUSY;
- break;
- case hardware::ICameraService::ERROR_INVALID_OPERATION:
- status = -EINVAL;
- break;
- case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
- status = -EUSERS;
- break;
- case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
- status = BAD_VALUE;
- break;
- case hardware::ICameraService::ERROR_DEPRECATED_HAL:
- status = -EOPNOTSUPP;
- break;
- case hardware::ICameraService::ERROR_DISABLED:
- status = -EACCES;
- break;
- case hardware::ICameraService::ERROR_PERMISSION_DENIED:
- status = PERMISSION_DENIED;
- break;
- default:
- status = -EINVAL;
- ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
- (cs != nullptr) ? "Service not available" : ret.toString8().string());
- break;
- }
- c.clear();
- }
- return status;
-}
-
status_t Camera::reconnect()
{
ALOGV("reconnect");
@@ -214,10 +156,6 @@
void Camera::stopRecording()
{
ALOGV("stopRecording");
- {
- Mutex::Autolock _l(mLock);
- mRecordingProxyListener.clear();
- }
sp <::android::hardware::ICamera> c = mCamera;
if (c == 0) return;
c->stopRecording();
@@ -325,12 +263,6 @@
mListener = listener;
}
-void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
-{
- Mutex::Autolock _l(mLock);
- mRecordingProxyListener = listener;
-}
-
void Camera::setPreviewCallbackFlags(int flag)
{
ALOGV("setPreviewCallbackFlags");
@@ -384,19 +316,6 @@
// callback from camera service when timestamped frame is ready
void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
- // If recording proxy listener is registered, forward the frame and return.
- // The other listener (mListener) is ignored because the receiver needs to
- // call releaseRecordingFrame.
- sp<ICameraRecordingProxyListener> proxylistener;
- {
- Mutex::Autolock _l(mLock);
- proxylistener = mRecordingProxyListener;
- }
- if (proxylistener != NULL) {
- proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
- return;
- }
-
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
@@ -413,19 +332,6 @@
void Camera::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle)
{
- // If recording proxy listener is registered, forward the frame and return.
- // The other listener (mListener) is ignored because the receiver needs to
- // call releaseRecordingFrameHandle.
- sp<ICameraRecordingProxyListener> proxylistener;
- {
- Mutex::Autolock _l(mLock);
- proxylistener = mRecordingProxyListener;
- }
- if (proxylistener != NULL) {
- proxylistener->recordingFrameHandleCallbackTimestamp(timestamp, handle);
- return;
- }
-
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
@@ -444,19 +350,6 @@
const std::vector<nsecs_t>& timestamps,
const std::vector<native_handle_t*>& handles)
{
- // If recording proxy listener is registered, forward the frame and return.
- // The other listener (mListener) is ignored because the receiver needs to
- // call releaseRecordingFrameHandle.
- sp<ICameraRecordingProxyListener> proxylistener;
- {
- Mutex::Autolock _l(mLock);
- proxylistener = mRecordingProxyListener;
- }
- if (proxylistener != NULL) {
- proxylistener->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
- return;
- }
-
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
@@ -476,10 +369,9 @@
return new RecordingProxy(this);
}
-status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
+status_t Camera::RecordingProxy::startRecording()
{
ALOGV("RecordingProxy::startRecording");
- mCamera->setRecordingProxyListener(listener);
mCamera->reconnect();
return mCamera->startRecording();
}
@@ -490,23 +382,6 @@
mCamera->stopRecording();
}
-void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
-{
- ALOGV("RecordingProxy::releaseRecordingFrame");
- mCamera->releaseRecordingFrame(mem);
-}
-
-void Camera::RecordingProxy::releaseRecordingFrameHandle(native_handle_t* handle) {
- ALOGV("RecordingProxy::releaseRecordingFrameHandle");
- mCamera->releaseRecordingFrameHandle(handle);
-}
-
-void Camera::RecordingProxy::releaseRecordingFrameHandleBatch(
- const std::vector<native_handle_t*>& handles) {
- ALOGV("RecordingProxy::releaseRecordingFrameHandleBatch");
- mCamera->releaseRecordingFrameHandleBatch(handles);
-}
-
Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
{
mCamera = camera;
diff --git a/camera/ICameraRecordingProxy.cpp b/camera/ICameraRecordingProxy.cpp
index bd6af75..97523a5 100644
--- a/camera/ICameraRecordingProxy.cpp
+++ b/camera/ICameraRecordingProxy.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "ICameraRecordingProxy"
#include <camera/CameraUtils.h>
#include <camera/ICameraRecordingProxy.h>
-#include <camera/ICameraRecordingProxyListener.h>
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/hardware/HardwareAPI.h>
@@ -29,10 +28,7 @@
enum {
START_RECORDING = IBinder::FIRST_CALL_TRANSACTION,
- STOP_RECORDING,
- RELEASE_RECORDING_FRAME,
- RELEASE_RECORDING_FRAME_HANDLE,
- RELEASE_RECORDING_FRAME_HANDLE_BATCH,
+ STOP_RECORDING
};
@@ -44,12 +40,11 @@
{
}
- status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
+ status_t startRecording()
{
ALOGV("startRecording");
Parcel data, reply;
data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(listener));
remote()->transact(START_RECORDING, data, &reply);
return reply.readInt32();
}
@@ -61,46 +56,6 @@
data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
remote()->transact(STOP_RECORDING, data, &reply);
}
-
- void releaseRecordingFrame(const sp<IMemory>& mem)
- {
- ALOGV("releaseRecordingFrame");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(mem));
- remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
- }
-
- void releaseRecordingFrameHandle(native_handle_t *handle) {
- ALOGV("releaseRecordingFrameHandle");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
- data.writeNativeHandle(handle);
-
- remote()->transact(RELEASE_RECORDING_FRAME_HANDLE, data, &reply);
-
- // Close the native handle because camera received a dup copy.
- native_handle_close(handle);
- native_handle_delete(handle);
- }
-
- void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
- ALOGV("releaseRecordingFrameHandleBatch");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
- uint32_t n = handles.size();
- data.writeUint32(n);
- for (auto& handle : handles) {
- data.writeNativeHandle(handle);
- }
- remote()->transact(RELEASE_RECORDING_FRAME_HANDLE_BATCH, data, &reply);
-
- // Close the native handle because camera received a dup copy.
- for (auto& handle : handles) {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
- }
};
IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
@@ -114,9 +69,7 @@
case START_RECORDING: {
ALOGV("START_RECORDING");
CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
- sp<ICameraRecordingProxyListener> listener =
- interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
- reply->writeInt32(startRecording(listener));
+ reply->writeInt32(startRecording());
return NO_ERROR;
} break;
case STOP_RECORDING: {
@@ -125,46 +78,6 @@
stopRecording();
return NO_ERROR;
} break;
- case RELEASE_RECORDING_FRAME: {
- ALOGV("RELEASE_RECORDING_FRAME");
- CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
- sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
- releaseRecordingFrame(mem);
- return NO_ERROR;
- } break;
- case RELEASE_RECORDING_FRAME_HANDLE: {
- ALOGV("RELEASE_RECORDING_FRAME_HANDLE");
- CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
-
- // releaseRecordingFrameHandle will be responsble to close the native handle.
- releaseRecordingFrameHandle(data.readNativeHandle());
- return NO_ERROR;
- } break;
- case RELEASE_RECORDING_FRAME_HANDLE_BATCH: {
- ALOGV("RELEASE_RECORDING_FRAME_HANDLE_BATCH");
- CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
- uint32_t n = 0;
- status_t res = data.readUint32(&n);
- if (res != OK) {
- ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
- return BAD_VALUE;
- }
- std::vector<native_handle_t*> handles;
- handles.reserve(n);
- for (uint32_t i = 0; i < n; i++) {
- native_handle_t* handle = data.readNativeHandle();
- if (handle == nullptr) {
- ALOGE("%s: Received a null native handle at handles[%d]",
- __FUNCTION__, i);
- return BAD_VALUE;
- }
- handles.push_back(handle);
- }
-
- // releaseRecordingFrameHandleBatch will be responsble to close the native handle.
- releaseRecordingFrameHandleBatch(handles);
- return NO_ERROR;
- } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
@@ -173,4 +86,3 @@
// ----------------------------------------------------------------------------
}; // namespace android
-
diff --git a/camera/ICameraRecordingProxyListener.cpp b/camera/ICameraRecordingProxyListener.cpp
deleted file mode 100644
index 66faf8f..0000000
--- a/camera/ICameraRecordingProxyListener.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "ICameraRecordingProxyListener"
-#include <camera/CameraUtils.h>
-#include <camera/ICameraRecordingProxyListener.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <media/hardware/HardwareAPI.h>
-#include <utils/Log.h>
-
-namespace android {
-
-enum {
- DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION,
- RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP,
- RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH
-};
-
-class BpCameraRecordingProxyListener: public BpInterface<ICameraRecordingProxyListener>
-{
-public:
- explicit BpCameraRecordingProxyListener(const sp<IBinder>& impl)
- : BpInterface<ICameraRecordingProxyListener>(impl)
- {
- }
-
- void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
- {
- ALOGV("dataCallback");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
- data.writeInt64(timestamp);
- data.writeInt32(msgType);
- data.writeStrongBinder(IInterface::asBinder(imageData));
- remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
- }
-
- void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, native_handle_t* handle) {
- ALOGV("recordingFrameHandleCallbackTimestamp");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
- data.writeInt64(timestamp);
- data.writeNativeHandle(handle);
- remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP, data, &reply,
- IBinder::FLAG_ONEWAY);
-
- // The native handle is dupped in ICameraClient so we need to free it here.
- native_handle_close(handle);
- native_handle_delete(handle);
- }
-
- void recordingFrameHandleCallbackTimestampBatch(
- const std::vector<nsecs_t>& timestamps,
- const std::vector<native_handle_t*>& handles) {
- ALOGV("recordingFrameHandleCallbackTimestampBatch");
- Parcel data, reply;
- data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
-
- uint32_t n = timestamps.size();
- if (n != handles.size()) {
- ALOGE("%s: size of timestamps(%zu) and handles(%zu) mismatch!",
- __FUNCTION__, timestamps.size(), handles.size());
- return;
- }
- data.writeUint32(n);
- for (auto ts : timestamps) {
- data.writeInt64(ts);
- }
- for (auto& handle : handles) {
- data.writeNativeHandle(handle);
- }
- remote()->transact(RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH, data, &reply,
- IBinder::FLAG_ONEWAY);
-
- // The native handle is dupped in ICameraClient so we need to free it here.
- for (auto& handle : handles) {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
- }
-};
-
-IMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener");
-
-// ----------------------------------------------------------------------
-
-status_t BnCameraRecordingProxyListener::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case DATA_CALLBACK_TIMESTAMP: {
- ALOGV("DATA_CALLBACK_TIMESTAMP");
- CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
- nsecs_t timestamp = data.readInt64();
- int32_t msgType = data.readInt32();
- sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
- dataCallbackTimestamp(timestamp, msgType, imageData);
- return NO_ERROR;
- } break;
- case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP: {
- ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP");
- CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
- nsecs_t timestamp;
- status_t res = data.readInt64(×tamp);
- if (res != OK) {
- ALOGE("%s: Failed to read timestamp: %s (%d)", __FUNCTION__, strerror(-res), res);
- return BAD_VALUE;
- }
-
- native_handle_t* handle = data.readNativeHandle();
- if (handle == nullptr) {
- ALOGE("%s: Received a null native handle", __FUNCTION__);
- return BAD_VALUE;
- }
- // The native handle will be freed in
- // BpCameraRecordingProxy::releaseRecordingFrameHandle.
- recordingFrameHandleCallbackTimestamp(timestamp, handle);
- return NO_ERROR;
- } break;
- case RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH: {
- ALOGV("RECORDING_FRAME_HANDLE_CALLBACK_TIMESTAMP_BATCH");
- CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
- uint32_t n = 0;
- status_t res = data.readUint32(&n);
- if (res != OK) {
- ALOGE("%s: Failed to read batch size: %s (%d)", __FUNCTION__, strerror(-res), res);
- return BAD_VALUE;
- }
- std::vector<nsecs_t> timestamps;
- std::vector<native_handle_t*> handles;
- timestamps.reserve(n);
- handles.reserve(n);
- for (uint32_t i = 0; i < n; i++) {
- nsecs_t t;
- res = data.readInt64(&t);
- if (res != OK) {
- ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
- __FUNCTION__, i, strerror(-res), res);
- return BAD_VALUE;
- }
- timestamps.push_back(t);
- }
- for (uint32_t i = 0; i < n; i++) {
- native_handle_t* handle = data.readNativeHandle();
- if (handle == nullptr) {
- ALOGE("%s: Received a null native handle at handles[%d]",
- __FUNCTION__, i);
- return BAD_VALUE;
- }
- handles.push_back(handle);
- }
- // The native handle will be freed in
- // BpCameraRecordingProxy::releaseRecordingFrameHandleBatch.
- recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index ac7a35b..8af704d 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -69,7 +69,7 @@
/**
* Default UID/PID values for non-privileged callers of
- * connect(), connectDevice(), and connectLegacy()
+ * connect() and connectDevice()
*/
const int USE_CALLING_UID = -1;
const int USE_CALLING_PID = -1;
@@ -93,20 +93,6 @@
int clientUid);
/**
- * halVersion constant for connectLegacy
- */
- const int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;
-
- /**
- * Open a camera device in legacy mode, if supported by the camera module HAL.
- */
- ICamera connectLegacy(ICameraClient client,
- int cameraId,
- int halVersion,
- String opPackageName,
- int clientUid);
-
- /**
* Add listener for changes to camera device and flashlight state.
*
* Also returns the set of currently-known camera IDs and state of each device.
diff --git a/camera/include/camera/Camera.h b/camera/include/camera/Camera.h
index 2cdb617..5579183 100644
--- a/camera/include/camera/Camera.h
+++ b/camera/include/camera/Camera.h
@@ -24,7 +24,6 @@
#include <gui/IGraphicBufferProducer.h>
#include <system/camera.h>
#include <camera/ICameraRecordingProxy.h>
-#include <camera/ICameraRecordingProxyListener.h>
#include <camera/android/hardware/ICamera.h>
#include <camera/android/hardware/ICameraClient.h>
#include <camera/CameraBase.h>
@@ -84,10 +83,6 @@
const String16& clientPackageName,
int clientUid, int clientPid);
- static status_t connectLegacy(int cameraId, int halVersion,
- const String16& clientPackageName,
- int clientUid, sp<Camera>& camera);
-
virtual ~Camera();
status_t reconnect();
@@ -154,7 +149,6 @@
status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);
void setListener(const sp<CameraListener>& listener);
- void setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener);
// Configure preview callbacks to app. Only one of the older
// callbacks or the callback surface can be active at the same time;
@@ -187,12 +181,8 @@
explicit RecordingProxy(const sp<Camera>& camera);
// ICameraRecordingProxy interface
- virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener);
+ virtual status_t startRecording();
virtual void stopRecording();
- virtual void releaseRecordingFrame(const sp<IMemory>& mem);
- virtual void releaseRecordingFrameHandle(native_handle_t* handle);
- virtual void releaseRecordingFrameHandleBatch(
- const std::vector<native_handle_t*>& handles);
private:
sp<Camera> mCamera;
@@ -203,8 +193,6 @@
Camera(const Camera&);
Camera& operator=(const Camera);
- sp<ICameraRecordingProxyListener> mRecordingProxyListener;
-
friend class CameraBase;
};
diff --git a/camera/include/camera/ICameraRecordingProxy.h b/camera/include/camera/ICameraRecordingProxy.h
index 02af2f3..4306dc1 100644
--- a/camera/include/camera/ICameraRecordingProxy.h
+++ b/camera/include/camera/ICameraRecordingProxy.h
@@ -24,13 +24,11 @@
namespace android {
-class ICameraRecordingProxyListener;
-class IMemory;
class Parcel;
/*
- * The purpose of ICameraRecordingProxy and ICameraRecordingProxyListener is to
- * allow applications using the camera during recording.
+ * The purpose of ICameraRecordingProxy is to
+ * allow applications to use the camera during recording with the old camera API.
*
* Camera service allows only one client at a time. Since camcorder application
* needs to own the camera to do things like zoom, the media recorder cannot
@@ -42,35 +40,29 @@
* ICameraRecordingProxy
* startRecording()
* stopRecording()
- * releaseRecordingFrame()
*
- * ICameraRecordingProxyListener
- * dataCallbackTimestamp()
-
* The camcorder app opens the camera and starts the preview. The app passes
* ICamera and ICameraRecordingProxy to the media recorder by
* MediaRecorder::setCamera(). The recorder uses ICamera to setup the camera in
* MediaRecorder::start(). After setup, the recorder disconnects from camera
- * service. The recorder calls ICameraRecordingProxy::startRecording() and
- * passes a ICameraRecordingProxyListener to the app. The app connects back to
- * camera service and starts the recording. The app owns the camera and can do
- * things like zoom. The media recorder receives the video frames from the
- * listener and releases them by ICameraRecordingProxy::releaseRecordingFrame.
- * The recorder calls ICameraRecordingProxy::stopRecording() to stop the
- * recording.
+ * service. The recorder calls ICameraRecordingProxy::startRecording() and The
+ * app owns the camera and can do things like zoom. The media recorder receives
+ * the video frames via a buffer queue. The recorder calls
+ * ICameraRecordingProxy::stopRecording() to stop the recording.
*
* The call sequences are as follows:
* 1. The app: Camera.unlock().
* 2. The app: MediaRecorder.setCamera().
* 3. Start recording
* (1) The app: MediaRecorder.start().
- * (2) The recorder: ICamera.unlock() and ICamera.disconnect().
- * (3) The recorder: ICameraRecordingProxy.startRecording().
- * (4) The app: ICamera.reconnect().
- * (5) The app: ICamera.startRecording().
+ * (2) The recorder: ICamera.setVideoTarget(buffer queue).
+ * (3) The recorder: ICamera.unlock() and ICamera.disconnect().
+ * (4) The recorder: ICameraRecordingProxy.startRecording().
+ * (5) The app: ICamera.reconnect().
+ * (6) The app: ICamera.startRecording().
* 4. During recording
- * (1) The recorder: receive frames from ICameraRecordingProxyListener.dataCallbackTimestamp()
- * (2) The recorder: release frames by ICameraRecordingProxy.releaseRecordingFrame().
+ * (1) The recorder: receive frames via a buffer queue
+ * (2) The recorder: release frames via a buffer queue
* 5. Stop recording
* (1) The app: MediaRecorder.stop()
* (2) The recorder: ICameraRecordingProxy.stopRecording().
@@ -82,12 +74,8 @@
public:
DECLARE_META_INTERFACE(CameraRecordingProxy);
- virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener) = 0;
+ virtual status_t startRecording() = 0;
virtual void stopRecording() = 0;
- virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
- virtual void releaseRecordingFrameHandle(native_handle_t *handle) = 0;
- virtual void releaseRecordingFrameHandleBatch(
- const std::vector<native_handle_t*>& handles) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/camera/include/camera/ICameraRecordingProxyListener.h b/camera/include/camera/ICameraRecordingProxyListener.h
deleted file mode 100644
index da03c56..0000000
--- a/camera/include/camera/ICameraRecordingProxyListener.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H
-#define ANDROID_HARDWARE_ICAMERA_RECORDING_PROXY_LISTENER_H
-
-#include <vector>
-#include <binder/IInterface.h>
-#include <cutils/native_handle.h>
-#include <stdint.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-class Parcel;
-class IMemory;
-
-class ICameraRecordingProxyListener: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(CameraRecordingProxyListener);
-
- virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
- const sp<IMemory>& data) = 0;
-
- virtual void recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,
- native_handle_t* handle) = 0;
-
- virtual void recordingFrameHandleCallbackTimestampBatch(
- const std::vector<nsecs_t>& timestamps,
- const std::vector<native_handle_t*>& handles) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnCameraRecordingProxyListener: public BnInterface<ICameraRecordingProxyListener>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-}; // namespace android
-
-#endif
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 37091c4..098c278 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -259,31 +259,6 @@
printf("$\n");
#endif
-#if 0
- CameraSource *source = CameraSource::Create(
- String16(argv[0], strlen(argv[0])));
- source->start();
-
- printf("source = %p\n", source);
-
- for (int i = 0; i < 100; ++i) {
- MediaBuffer *buffer;
- status_t err = source->read(&buffer);
- CHECK_EQ(err, (status_t)OK);
-
- printf("got a frame, data=%p, size=%d\n",
- buffer->data(), buffer->range_length());
-
- buffer->release();
- buffer = NULL;
- }
-
- err = source->stop();
-
- delete source;
- source = NULL;
-#endif
-
if (err != OK && err != ERROR_END_OF_STREAM) {
fprintf(stderr, "record failed: %d\n", err);
return 1;
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index f05c2d2..f75e4c7 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -6,8 +6,11 @@
capabilities BLOCK_SUSPEND
ioprio rt 4
task_profiles ProcessCapacityHigh HighPerformance
-
- onrestart setprop sys.audio.restart.hal 1
+ onrestart restart vendor.audio-hal
+ onrestart restart vendor.audio-hal-4-0-msd
+ # Keep the original service names for backward compatibility
+ onrestart restart vendor.audio-hal-2-0
+ onrestart restart audio-hal-2-0
on property:vts.native_server.on=1
stop audioserver
@@ -37,11 +40,16 @@
start audio-hal-2-0
on property:sys.audio.restart.hal=1
- restart vendor.audio-hal
- restart vendor.audio-hal-4-0-msd
+ # See b/159966243. Avoid restart loop between audioserver and HAL.
# Keep the original service names for backward compatibility
- restart vendor.audio-hal-2-0
- restart audio-hal-2-0
+ stop vendor.audio-hal
+ stop vendor.audio-hal-4-0-msd
+ stop vendor.audio-hal-2-0
+ stop audio-hal-2-0
+ start vendor.audio-hal
+ start vendor.audio-hal-4-0-msd
+ start vendor.audio-hal-2-0
+ start audio-hal-2-0
# reset the property
setprop sys.audio.restart.hal 0
diff --git a/media/bufferpool/1.0/vts/multi.cpp b/media/bufferpool/1.0/vts/multi.cpp
index 1796819..d8cc285 100644
--- a/media/bufferpool/1.0/vts/multi.cpp
+++ b/media/bufferpool/1.0/vts/multi.cpp
@@ -215,7 +215,7 @@
} // anonymous namespace
int main(int argc, char** argv) {
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+ android::hardware::details::setTrebleTestingOverride(true);
::testing::InitGoogleTest(&argc, argv);
int status = RUN_ALL_TESTS();
LOG(INFO) << "Test result = " << status;
diff --git a/media/bufferpool/2.0/tests/multi.cpp b/media/bufferpool/2.0/tests/multi.cpp
index 68b6992..b40838e 100644
--- a/media/bufferpool/2.0/tests/multi.cpp
+++ b/media/bufferpool/2.0/tests/multi.cpp
@@ -215,7 +215,7 @@
} // anonymous namespace
int main(int argc, char** argv) {
- setenv("TREBLE_TESTING_OVERRIDE", "true", true);
+ android::hardware::details::setTrebleTestingOverride(true);
::testing::InitGoogleTest(&argc, argv);
int status = RUN_ALL_TESTS();
LOG(INFO) << "Test result = " << status;
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index a16b106..3780a5a 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -52,6 +52,9 @@
// directly in the main device manifest.xml file or via vintf_fragments.
// (Remove the line below if the entry is already in the main manifest.)
vintf_fragments: ["manifest_media_c2_V1_1_default.xml"],
+
+ // Remove this line to enable this module.
+ enabled: false,
}
// seccomp policy file.
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
index a9fc7e4..594ee7b 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/extractors/fuzzers/Android.bp
@@ -308,3 +308,25 @@
dictionary: "flac_extractor_fuzzer.dict",
}
+
+cc_fuzz {
+ name: "midi_extractor_fuzzer",
+ defaults: ["extractor-fuzzer-defaults"],
+
+ srcs: [
+ "midi_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/midi",
+ ],
+
+ static_libs: [
+ "libsonivox",
+ "libmedia_midiiowrapper",
+ "libmidiextractor",
+ "libwatchdog",
+ ],
+
+ dictionary: "midi_extractor_fuzzer.dict",
+}
diff --git a/media/extractors/fuzzers/README.md b/media/extractors/fuzzers/README.md
index 4223b5e..fb1d52f 100644
--- a/media/extractors/fuzzers/README.md
+++ b/media/extractors/fuzzers/README.md
@@ -11,6 +11,7 @@
+ [libmp3extractor](#mp3ExtractorFuzzer)
+ [libaacextractor](#aacExtractorFuzzer)
+ [libflacextractor](#flacExtractor)
++ [libmidiextractor](#midiExtractorFuzzer)
# <a name="ExtractorFuzzerBase"></a> Fuzzer for libextractorfuzzerbase
All the extractors have a common API - creating a data source, extraction
@@ -321,6 +322,41 @@
$ adb shell /data/fuzz/arm64/flac_extractor_fuzzer/flac_extractor_fuzzer CORPUS_DIR
```
+# <a name="midiExtractorFuzzer"></a> Fuzzer for libmidiextractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MIDI extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MIDI extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MIDI to ensure that the required MIDI
+headers are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered as a range of MIDI headers will be
+present in the input data.
+
+
+## Build
+
+This describes steps to build midi_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) midi_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MIDI files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/midi_extractor_fuzzer/midi_extractor_fuzzer CORPUS_DIR
+```
+
## References:
* http://llvm.org/docs/LibFuzzer.html
* https://github.com/google/oss-fuzz
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.cpp b/media/extractors/fuzzers/midi_extractor_fuzzer.cpp
new file mode 100644
index 0000000..e02a12b
--- /dev/null
+++ b/media/extractors/fuzzers/midi_extractor_fuzzer.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MidiExtractor.h"
+
+using namespace android;
+
+class MIDIExtractor : public ExtractorFuzzerBase {
+ public:
+ MIDIExtractor() = default;
+ ~MIDIExtractor() = default;
+
+ bool createExtractor();
+};
+
+bool MIDIExtractor::createExtractor() {
+ mExtractor = new MidiExtractor(mDataSource->wrap());
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ MIDIExtractor* extractor = new MIDIExtractor();
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
+ }
+ return 0;
+}
diff --git a/media/extractors/fuzzers/midi_extractor_fuzzer.dict b/media/extractors/fuzzers/midi_extractor_fuzzer.dict
new file mode 100644
index 0000000..5b6bb8b
--- /dev/null
+++ b/media/extractors/fuzzers/midi_extractor_fuzzer.dict
@@ -0,0 +1,3 @@
+# MIDI Chunks
+kw1="MThd"
+kw2="MTrk"
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 7d16fb4..019a99a 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -3836,43 +3836,44 @@
switch ((int32_t)mPath[4]) {
case FOURCC("\251alb"):
{
- metadataKey = "album";
+ metadataKey = AMEDIAFORMAT_KEY_ALBUM;
break;
}
case FOURCC("\251ART"):
{
- metadataKey = "artist";
+ metadataKey = AMEDIAFORMAT_KEY_ARTIST;
break;
}
case FOURCC("aART"):
{
- metadataKey = "albumartist";
+ metadataKey = AMEDIAFORMAT_KEY_ALBUMARTIST;
break;
}
case FOURCC("\251day"):
{
- metadataKey = "year";
+ metadataKey = AMEDIAFORMAT_KEY_YEAR;
break;
}
case FOURCC("\251nam"):
{
- metadataKey = "title";
+ metadataKey = AMEDIAFORMAT_KEY_TITLE;
break;
}
case FOURCC("\251wrt"):
{
- metadataKey = "writer";
+ // various open source taggers agree that the "©wrt" tag is for composer, not writer
+ metadataKey = AMEDIAFORMAT_KEY_COMPOSER;
break;
}
case FOURCC("covr"):
{
- metadataKey = "albumart";
+ metadataKey = AMEDIAFORMAT_KEY_ALBUMART;
break;
}
case FOURCC("gnre"):
case FOURCC("\251gen"):
{
- metadataKey = "genre";
+ metadataKey = AMEDIAFORMAT_KEY_GENRE;
break;
}
case FOURCC("cpil"):
@@ -3977,7 +3978,7 @@
if (!strcmp(metadataKey, "albumart")) {
AMediaFormat_setBuffer(mFileMetaData, metadataKey,
buffer + 8, size - 8);
- } else if (!strcmp(metadataKey, "genre")) {
+ } else if (!strcmp(metadataKey, AMEDIAFORMAT_KEY_GENRE)) {
if (flags == 0) {
// uint8_t genre code, iTunes genre codes are
// the standard id3 codes, except they start
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 0eee254..4c25314 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -1,6 +1,16 @@
cc_library {
name: "libmpeg2extractor",
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ android: {
+ shared_libs: ["libvndksupport#29"],
+ },
+ },
+
defaults: ["extractor-defaults"],
srcs: [
@@ -12,7 +22,6 @@
shared_libs: [
"libbase",
"libcgrouprc#29",
- "libvndksupport#29",
],
header_libs: [
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 4520823..ac7ad9a 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -353,6 +353,8 @@
// Clear any stale timestamps from the previous run.
drainTimestampsFromService();
+ prepareBuffersForStart(); // tell subclasses to get ready
+
aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle);
if (result == AAUDIO_ERROR_INVALID_HANDLE) {
ALOGD("%s() INVALID_HANDLE, stream was probably stolen", __func__);
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 61591b3..63be978 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -123,7 +123,9 @@
aaudio_result_t stopCallback();
- virtual void advanceClientToMatchServerPosition() = 0;
+ virtual void prepareBuffersForStart() {}
+
+ virtual void advanceClientToMatchServerPosition(int32_t serverMargin = 0) = 0;
virtual void onFlushFromServer() {}
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 9fa2e40..d014608 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -41,9 +41,9 @@
AudioStreamInternalCapture::~AudioStreamInternalCapture() {}
-void AudioStreamInternalCapture::advanceClientToMatchServerPosition() {
+void AudioStreamInternalCapture::advanceClientToMatchServerPosition(int32_t serverMargin) {
int64_t readCounter = mAudioEndpoint->getDataReadCounter();
- int64_t writeCounter = mAudioEndpoint->getDataWriteCounter();
+ int64_t writeCounter = mAudioEndpoint->getDataWriteCounter() + serverMargin;
// Bump offset so caller does not see the retrograde motion in getFramesRead().
int64_t offset = readCounter - writeCounter;
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.h b/media/libaaudio/src/client/AudioStreamInternalCapture.h
index 6436a53..1d65d87 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.h
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.h
@@ -46,7 +46,7 @@
}
protected:
- void advanceClientToMatchServerPosition() override;
+ void advanceClientToMatchServerPosition(int32_t serverOffset = 0) override;
/**
* Low level data processing that will not block. It will just read or write as much as it can.
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 1303daf..6337b53 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -86,8 +86,13 @@
return mServiceInterface.flushStream(mServiceStreamHandle);
}
-void AudioStreamInternalPlay::advanceClientToMatchServerPosition() {
- int64_t readCounter = mAudioEndpoint->getDataReadCounter();
+void AudioStreamInternalPlay::prepareBuffersForStart() {
+ // Prevent stale data from being played.
+ mAudioEndpoint->eraseDataMemory();
+}
+
+void AudioStreamInternalPlay::advanceClientToMatchServerPosition(int32_t serverMargin) {
+ int64_t readCounter = mAudioEndpoint->getDataReadCounter() + serverMargin;
int64_t writeCounter = mAudioEndpoint->getDataWriteCounter();
// Bump offset so caller does not see the retrograde motion in getFramesRead().
@@ -145,7 +150,9 @@
if (mNeedCatchUp.isRequested()) {
// Catch an MMAP pointer that is already advancing.
// This will avoid initial underruns caused by a slow cold start.
- advanceClientToMatchServerPosition();
+ // We add a one burst margin in case the DSP advances before we can write the data.
+ // This can help prevent the beginning of the stream from being skipped.
+ advanceClientToMatchServerPosition(getFramesPerBurst());
mNeedCatchUp.acknowledge();
}
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.h b/media/libaaudio/src/client/AudioStreamInternalPlay.h
index 2e93157..be95da6 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.h
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.h
@@ -65,7 +65,9 @@
protected:
- void advanceClientToMatchServerPosition() override;
+ void prepareBuffersForStart() override;
+
+ void advanceClientToMatchServerPosition(int32_t serverMargin = 0) override;
void onFlushFromServer() override;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 4ad780c..1caee04 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -219,7 +219,7 @@
],
header_libs: [
- "libmedia_headers",
+ "libmedia_datasource_headers",
"media_ndk_headers",
],
@@ -236,6 +236,14 @@
],
cfi: true,
},
+
+ host_supported: true,
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library_shared {
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index aaa15c4..bd03671 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -103,6 +103,8 @@
return "Finish";
case Event::Error:
return "Error";
+ case Event::Progress:
+ return "Progress";
default:
break;
}
@@ -132,8 +134,10 @@
virtual void onProgressUpdate(const MediaTranscoder* transcoder __unused,
int32_t progress) override {
- ALOGV("%s: job {%lld, %d}, progress %d", __FUNCTION__, (long long)mClientId, mJobId,
- progress);
+ auto owner = mOwner.lock();
+ if (owner != nullptr) {
+ owner->onProgress(mClientId, mJobId, progress);
+ }
}
virtual void onCodecResourceLost(const MediaTranscoder* transcoder __unused,
@@ -261,6 +265,15 @@
});
}
+void TranscoderWrapper::onProgress(ClientIdType clientId, JobIdType jobId, int32_t progress) {
+ queueEvent(Event::Progress, clientId, jobId, [=] {
+ auto callback = mCallback.lock();
+ if (callback != nullptr) {
+ callback->onProgressUpdate(clientId, jobId, progress);
+ }
+ });
+}
+
TranscodingErrorCode TranscoderWrapper::setupTranscoder(
ClientIdType clientId, JobIdType jobId, const TranscodingRequestParcel& request,
const std::shared_ptr<ITranscodingClientCallback>& clientCb,
diff --git a/media/libmediatranscoding/include/media/TranscoderWrapper.h b/media/libmediatranscoding/include/media/TranscoderWrapper.h
index 804119f..a4c92c5 100644
--- a/media/libmediatranscoding/include/media/TranscoderWrapper.h
+++ b/media/libmediatranscoding/include/media/TranscoderWrapper.h
@@ -51,7 +51,7 @@
private:
class CallbackImpl;
struct Event {
- enum Type { NoEvent, Start, Pause, Resume, Stop, Finish, Error } type;
+ enum Type { NoEvent, Start, Pause, Resume, Stop, Finish, Error, Progress } type;
ClientIdType clientId;
JobIdType jobId;
std::function<void()> runnable;
@@ -71,6 +71,7 @@
static const char* toString(Event::Type type);
void onFinish(ClientIdType clientId, JobIdType jobId);
void onError(ClientIdType clientId, JobIdType jobId, TranscodingErrorCode error);
+ void onProgress(ClientIdType clientId, JobIdType jobId, int32_t progress);
TranscodingErrorCode handleStart(ClientIdType clientId, JobIdType jobId,
const TranscodingRequestParcel& request,
diff --git a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
index 91dbf78..3676d73 100644
--- a/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
+++ b/media/libmediatranscoding/transcoder/MediaSampleWriter.cpp
@@ -78,14 +78,14 @@
}
}
-bool MediaSampleWriter::init(int fd, const OnWritingFinishedCallback& callback) {
- return init(DefaultMuxer::create(fd), callback);
+bool MediaSampleWriter::init(int fd, const std::weak_ptr<CallbackInterface>& callbacks) {
+ return init(DefaultMuxer::create(fd), callbacks);
}
bool MediaSampleWriter::init(const std::shared_ptr<MediaSampleWriterMuxerInterface>& muxer,
- const OnWritingFinishedCallback& callback) {
- if (callback == nullptr) {
- LOG(ERROR) << "Callback cannot be null";
+ const std::weak_ptr<CallbackInterface>& callbacks) {
+ if (callbacks.lock() == nullptr) {
+ LOG(ERROR) << "Callback object cannot be null";
return false;
} else if (muxer == nullptr) {
LOG(ERROR) << "Muxer cannot be null";
@@ -100,7 +100,7 @@
mState = INITIALIZED;
mMuxer = muxer;
- mWritingFinishedCallback = callback;
+ mCallbacks = callbacks;
return true;
}
@@ -127,7 +127,11 @@
durationUs = 0;
}
- mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex), durationUs);
+ const char* mime = nullptr;
+ const bool isVideo = AMediaFormat_getString(trackFormat.get(), AMEDIAFORMAT_KEY_MIME, &mime) &&
+ (strncmp(mime, "video/", 6) == 0);
+
+ mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex), durationUs, isVideo);
return true;
}
@@ -144,7 +148,9 @@
mThread = std::thread([this] {
media_status_t status = writeSamples();
- mWritingFinishedCallback(status);
+ if (auto callbacks = mCallbacks.lock()) {
+ callbacks->onFinished(this, status);
+ }
});
mState = STARTED;
return true;
@@ -191,6 +197,18 @@
AMediaCodecBufferInfo bufferInfo;
uint32_t segmentEndTimeUs = mTrackSegmentLengthUs;
bool samplesLeft = true;
+ int32_t lastProgressUpdate = 0;
+
+ // Set the "primary" track that will be used to determine progress to the track with longest
+ // duration.
+ int primaryTrackIndex = -1;
+ int64_t longestDurationUs = 0;
+ for (int trackIndex = 0; trackIndex < mTracks.size(); ++trackIndex) {
+ if (mTracks[trackIndex].mDurationUs > longestDurationUs) {
+ primaryTrackIndex = trackIndex;
+ longestDurationUs = mTracks[trackIndex].mDurationUs;
+ }
+ }
while (samplesLeft) {
samplesLeft = false;
@@ -216,9 +234,10 @@
samplesLeft = true;
}
- // Record the first sample's timestamp in order to translate duration to EOS time
- // for tracks that does not start at 0.
+ track.mPrevSampleTimeUs = sample->info.presentationTimeUs;
if (!track.mFirstSampleTimeSet) {
+ // Record the first sample's timestamp in order to translate duration to EOS
+ // time for tracks that does not start at 0.
track.mFirstSampleTimeUs = sample->info.presentationTimeUs;
track.mFirstSampleTimeSet = true;
}
@@ -238,6 +257,22 @@
} while (sample->info.presentationTimeUs < segmentEndTimeUs && !track.mReachedEos);
}
+ // TODO(lnilsson): Add option to toggle progress reporting on/off.
+ if (primaryTrackIndex >= 0) {
+ const TrackRecord& track = mTracks[primaryTrackIndex];
+
+ const int64_t elapsed = track.mPrevSampleTimeUs - track.mFirstSampleTimeUs;
+ int32_t progress = (elapsed * 100) / track.mDurationUs;
+ progress = std::clamp(progress, 0, 100);
+
+ if (progress > lastProgressUpdate) {
+ if (auto callbacks = mCallbacks.lock()) {
+ callbacks->onProgressUpdate(this, progress);
+ }
+ lastProgressUpdate = progress;
+ }
+ }
+
segmentEndTimeUs += mTrackSegmentLengthUs;
}
diff --git a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
index 999e226..ed702db 100644
--- a/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/MediaTranscoder.cpp
@@ -151,11 +151,16 @@
sendCallback(status);
}
-void MediaTranscoder::onSampleWriterFinished(media_status_t status) {
+void MediaTranscoder::onFinished(const MediaSampleWriter* writer __unused, media_status_t status) {
LOG((status != AMEDIA_OK) ? ERROR : DEBUG) << "Sample writer finished with status " << status;
sendCallback(status);
}
+void MediaTranscoder::onProgressUpdate(const MediaSampleWriter* writer __unused, int32_t progress) {
+ // Dispatch progress updated to the client.
+ mCallbacks->onProgressUpdate(this, progress);
+}
+
MediaTranscoder::MediaTranscoder(const std::shared_ptr<CallbackInterface>& callbacks)
: mCallbacks(callbacks) {}
@@ -288,8 +293,7 @@
}
mSampleWriter = std::make_unique<MediaSampleWriter>();
- const bool initOk = mSampleWriter->init(
- fd, std::bind(&MediaTranscoder::onSampleWriterFinished, this, std::placeholders::_1));
+ const bool initOk = mSampleWriter->init(fd, shared_from_this());
if (!initOk) {
LOG(ERROR) << "Unable to initialize sample writer with destination fd: " << fd;
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h b/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
index d971f3e..92ddc2f 100644
--- a/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
+++ b/media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h
@@ -71,18 +71,27 @@
/** The default segment length. */
static constexpr uint32_t kDefaultTrackSegmentLengthUs = 1 * 1000 * 1000; // 1 sec.
- /** Client callback for when the writer is finished. */
- using OnWritingFinishedCallback = std::function<void(media_status_t)>;
+ /** Callback interface. */
+ class CallbackInterface {
+ public:
+ /**
+ * Sample writer finished. The finished callback is only called after the sample writer has
+ * been successfully started.
+ */
+ virtual void onFinished(const MediaSampleWriter* writer, media_status_t status) = 0;
+
+ /** Sample writer progress update in percent. */
+ virtual void onProgressUpdate(const MediaSampleWriter* writer, int32_t progress) = 0;
+
+ virtual ~CallbackInterface() = default;
+ };
/**
* Constructor with custom segment length.
* @param trackSegmentLengthUs The segment length to use for this MediaSampleWriter.
*/
MediaSampleWriter(uint32_t trackSegmentLengthUs)
- : mTrackSegmentLengthUs(trackSegmentLengthUs),
- mWritingFinishedCallback(nullptr),
- mMuxer(nullptr),
- mState(UNINITIALIZED){};
+ : mTrackSegmentLengthUs(trackSegmentLengthUs), mMuxer(nullptr), mState(UNINITIALIZED){};
/** Constructor using the default segment length. */
MediaSampleWriter() : MediaSampleWriter(kDefaultTrackSegmentLengthUs){};
@@ -95,21 +104,19 @@
* to be initialized before tracks are added and can only be initialized once.
* @param fd An open file descriptor to write to. The caller is responsible for closing this
* file descriptor and it is safe to do so once this method returns.
- * @param callback Client callback that gets called when the sample writer has finished, after
- * it was successfully started.
+ * @param callbacks Client callback object that gets called by the sample writer.
* @return True if the writer was successfully initialized.
*/
- bool init(int fd, const OnWritingFinishedCallback& callback /* nonnull */);
+ bool init(int fd, const std::weak_ptr<CallbackInterface>& callbacks /* nonnull */);
/**
* Initializes the sample writer with a custom muxer interface implementation.
* @param muxer The custom muxer interface implementation.
- * @param callback Client callback that gets called when the sample writer has finished, after
- * it was successfully started.
+ * @param @param callbacks Client callback object that gets called by the sample writer.
* @return True if the writer was successfully initialized.
*/
bool init(const std::shared_ptr<MediaSampleWriterMuxerInterface>& muxer /* nonnull */,
- const OnWritingFinishedCallback& callback /* nonnull */);
+ const std::weak_ptr<CallbackInterface>& callbacks /* nonnull */);
/**
* Adds a new track to the sample writer. Tracks must be added after the sample writer has been
@@ -145,24 +152,28 @@
struct TrackRecord {
TrackRecord(const std::shared_ptr<MediaSampleQueue>& sampleQueue, size_t trackIndex,
- int64_t durationUs)
+ int64_t durationUs, bool isVideo)
: mSampleQueue(sampleQueue),
mTrackIndex(trackIndex),
mDurationUs(durationUs),
mFirstSampleTimeUs(0),
+ mPrevSampleTimeUs(0),
mFirstSampleTimeSet(false),
- mReachedEos(false) {}
+ mReachedEos(false),
+ mIsVideo(isVideo) {}
std::shared_ptr<MediaSampleQueue> mSampleQueue;
const size_t mTrackIndex;
int64_t mDurationUs;
int64_t mFirstSampleTimeUs;
+ int64_t mPrevSampleTimeUs;
bool mFirstSampleTimeSet;
bool mReachedEos;
+ bool mIsVideo;
};
const uint32_t mTrackSegmentLengthUs;
- OnWritingFinishedCallback mWritingFinishedCallback;
+ std::weak_ptr<CallbackInterface> mCallbacks;
std::shared_ptr<MediaSampleWriterMuxerInterface> mMuxer;
std::vector<TrackRecord> mTracks;
std::thread mThread;
diff --git a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
index 33fa558..031d01e 100644
--- a/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/MediaTranscoder.h
@@ -17,6 +17,9 @@
#ifndef ANDROID_MEDIA_TRANSCODER_H
#define ANDROID_MEDIA_TRANSCODER_H
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <media/MediaSampleWriter.h>
#include <media/MediaTrackTranscoderCallback.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaFormat.h>
@@ -30,11 +33,11 @@
namespace android {
class MediaSampleReader;
-class MediaSampleWriter;
class Parcel;
class MediaTranscoder : public std::enable_shared_from_this<MediaTranscoder>,
- public MediaTrackTranscoderCallback {
+ public MediaTrackTranscoderCallback,
+ public MediaSampleWriter::CallbackInterface {
public:
/** Callbacks from transcoder to client. */
class CallbackInterface {
@@ -126,6 +129,12 @@
virtual void onTrackError(const MediaTrackTranscoder* transcoder,
media_status_t status) override;
// ~MediaTrackTranscoderCallback
+
+ // MediaSampleWriter::CallbackInterface
+ virtual void onFinished(const MediaSampleWriter* writer, media_status_t status) override;
+ virtual void onProgressUpdate(const MediaSampleWriter* writer, int32_t progress) override;
+ // ~MediaSampleWriter::CallbackInterface
+
void onSampleWriterFinished(media_status_t status);
void sendCallback(media_status_t status);
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
index e3cb192..c82ec28 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp
@@ -32,28 +32,6 @@
namespace android {
-/** Minimal one-shot semaphore */
-class SimpleSemaphore {
-public:
- void signal() {
- std::unique_lock<std::mutex> lock(mMutex);
- mSignaled = true;
- mCondition.notify_all();
- }
-
- void wait() {
- std::unique_lock<std::mutex> lock(mMutex);
- while (!mSignaled) {
- mCondition.wait(lock);
- }
- }
-
-private:
- std::mutex mMutex;
- std::condition_variable mCondition;
- bool mSignaled = false;
-};
-
/** Muxer interface to enable MediaSampleWriter testing. */
class TestMuxer : public MediaSampleWriterMuxerInterface {
public:
@@ -151,11 +129,22 @@
for (size_t trackIndex = 0; trackIndex < mTrackCount; trackIndex++) {
AMediaFormat* trackFormat = AMediaExtractor_getTrackFormat(mExtractor, trackIndex);
ASSERT_NE(trackFormat, nullptr);
+
+ const char* mime = nullptr;
+ AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+ if (strncmp(mime, "video/", 6) == 0) {
+ mVideoTrackIndex = trackIndex;
+ } else if (strncmp(mime, "audio/", 6) == 0) {
+ mAudioTrackIndex = trackIndex;
+ }
+
mTrackFormats.push_back(
std::shared_ptr<AMediaFormat>(trackFormat, &AMediaFormat_delete));
AMediaExtractor_selectTrack(mExtractor, trackIndex);
}
+ EXPECT_GE(mVideoTrackIndex, 0);
+ EXPECT_GE(mAudioTrackIndex, 0);
}
void reset() const {
@@ -167,6 +156,60 @@
AMediaExtractor* mExtractor = nullptr;
size_t mTrackCount = 0;
std::vector<std::shared_ptr<AMediaFormat>> mTrackFormats;
+ int mVideoTrackIndex = -1;
+ int mAudioTrackIndex = -1;
+};
+
+class TestCallbacks : public MediaSampleWriter::CallbackInterface {
+public:
+ TestCallbacks(bool expectSuccess = true) : mExpectSuccess(expectSuccess) {}
+
+ bool hasFinished() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ return mFinished;
+ }
+
+ // MediaSampleWriter::CallbackInterface
+ virtual void onFinished(const MediaSampleWriter* writer __unused,
+ media_status_t status) override {
+ std::unique_lock<std::mutex> lock(mMutex);
+ EXPECT_FALSE(mFinished);
+ if (mExpectSuccess) {
+ EXPECT_EQ(status, AMEDIA_OK);
+ } else {
+ EXPECT_NE(status, AMEDIA_OK);
+ }
+ mFinished = true;
+ mCondition.notify_all();
+ }
+
+ virtual void onProgressUpdate(const MediaSampleWriter* writer __unused,
+ int32_t progress) override {
+ EXPECT_GT(progress, mLastProgress);
+ EXPECT_GE(progress, 0);
+ EXPECT_LE(progress, 100);
+
+ mLastProgress = progress;
+ mProgressUpdateCount++;
+ }
+ // ~MediaSampleWriter::CallbackInterface
+
+ void waitForWritingFinished() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ while (!mFinished) {
+ mCondition.wait(lock);
+ }
+ }
+
+ uint32_t getProgressUpdateCount() const { return mProgressUpdateCount; }
+
+private:
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ bool mFinished = false;
+ bool mExpectSuccess;
+ int32_t mLastProgress = -1;
+ uint32_t mProgressUpdateCount = 0;
};
class MediaSampleWriterTests : public ::testing::Test {
@@ -222,7 +265,7 @@
protected:
std::shared_ptr<TestMuxer> mTestMuxer;
std::shared_ptr<MediaSampleQueue> mSampleQueue;
- const MediaSampleWriter::OnWritingFinishedCallback mEmptyCallback = [](media_status_t) {};
+ std::shared_ptr<TestCallbacks> mTestCallbacks = std::make_shared<TestCallbacks>();
};
TEST_F(MediaSampleWriterTests, TestAddTrackWithoutInit) {
@@ -239,14 +282,14 @@
TEST_F(MediaSampleWriterTests, TestStartWithoutTracks) {
MediaSampleWriter writer{};
- EXPECT_TRUE(writer.init(mTestMuxer, mEmptyCallback));
+ EXPECT_TRUE(writer.init(mTestMuxer, mTestCallbacks));
EXPECT_FALSE(writer.start());
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::NoEvent);
}
TEST_F(MediaSampleWriterTests, TestAddInvalidTrack) {
MediaSampleWriter writer{};
- EXPECT_TRUE(writer.init(mTestMuxer, mEmptyCallback));
+ EXPECT_TRUE(writer.init(mTestMuxer, mTestCallbacks));
EXPECT_FALSE(writer.addTrack(mSampleQueue, nullptr));
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::NoEvent);
@@ -259,31 +302,25 @@
TEST_F(MediaSampleWriterTests, TestDoubleStartStop) {
MediaSampleWriter writer{};
- bool callbackFired = false;
- MediaSampleWriter::OnWritingFinishedCallback stoppedCallback =
- [&callbackFired](media_status_t status) {
- EXPECT_NE(status, AMEDIA_OK);
- EXPECT_FALSE(callbackFired);
- callbackFired = true;
- };
-
- EXPECT_TRUE(writer.init(mTestMuxer, stoppedCallback));
+ std::shared_ptr<TestCallbacks> callbacks =
+ std::make_shared<TestCallbacks>(false /* expectSuccess */);
+ EXPECT_TRUE(writer.init(mTestMuxer, callbacks));
const TestMediaSource& mediaSource = getMediaSource();
EXPECT_TRUE(writer.addTrack(mSampleQueue, mediaSource.mTrackFormats[0]));
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::AddTrack(mediaSource.mTrackFormats[0].get()));
- EXPECT_TRUE(writer.start());
+ ASSERT_TRUE(writer.start());
EXPECT_FALSE(writer.start());
EXPECT_TRUE(writer.stop());
- EXPECT_TRUE(callbackFired);
+ EXPECT_TRUE(callbacks->hasFinished());
EXPECT_FALSE(writer.stop());
}
TEST_F(MediaSampleWriterTests, TestStopWithoutStart) {
MediaSampleWriter writer{};
- EXPECT_TRUE(writer.init(mTestMuxer, mEmptyCallback));
+ EXPECT_TRUE(writer.init(mTestMuxer, mTestCallbacks));
const TestMediaSource& mediaSource = getMediaSource();
EXPECT_TRUE(writer.addTrack(mSampleQueue, mediaSource.mTrackFormats[0]));
@@ -295,22 +332,48 @@
TEST_F(MediaSampleWriterTests, TestStartWithoutCallback) {
MediaSampleWriter writer{};
- EXPECT_FALSE(writer.init(mTestMuxer, nullptr));
+
+ std::weak_ptr<MediaSampleWriter::CallbackInterface> unassignedWp;
+ EXPECT_FALSE(writer.init(mTestMuxer, unassignedWp));
+
+ std::shared_ptr<MediaSampleWriter::CallbackInterface> unassignedSp;
+ EXPECT_FALSE(writer.init(mTestMuxer, unassignedSp));
const TestMediaSource& mediaSource = getMediaSource();
EXPECT_FALSE(writer.addTrack(mSampleQueue, mediaSource.mTrackFormats[0]));
ASSERT_FALSE(writer.start());
}
+TEST_F(MediaSampleWriterTests, TestProgressUpdate) {
+ static constexpr uint32_t kSegmentLengthUs = 1;
+ const TestMediaSource& mediaSource = getMediaSource();
+
+ MediaSampleWriter writer{kSegmentLengthUs};
+ EXPECT_TRUE(writer.init(mTestMuxer, mTestCallbacks));
+
+ std::shared_ptr<AMediaFormat> videoFormat =
+ std::shared_ptr<AMediaFormat>(AMediaFormat_new(), &AMediaFormat_delete);
+ AMediaFormat_copy(videoFormat.get(),
+ mediaSource.mTrackFormats[mediaSource.mVideoTrackIndex].get());
+
+ AMediaFormat_setInt64(videoFormat.get(), AMEDIAFORMAT_KEY_DURATION, 100);
+ EXPECT_TRUE(writer.addTrack(mSampleQueue, videoFormat));
+ ASSERT_TRUE(writer.start());
+
+ for (int64_t pts = 0; pts < 100; ++pts) {
+ mSampleQueue->enqueue(newSampleWithPts(pts));
+ }
+ mSampleQueue->enqueue(newSampleEos());
+ mTestCallbacks->waitForWritingFinished();
+
+ EXPECT_EQ(mTestCallbacks->getProgressUpdateCount(), 100);
+}
+
TEST_F(MediaSampleWriterTests, TestInterleaving) {
static constexpr uint32_t kSegmentLength = MediaSampleWriter::kDefaultTrackSegmentLengthUs;
- SimpleSemaphore semaphore;
MediaSampleWriter writer{kSegmentLength};
- EXPECT_TRUE(writer.init(mTestMuxer, [&semaphore](media_status_t status) {
- EXPECT_EQ(status, AMEDIA_OK);
- semaphore.signal();
- }));
+ EXPECT_TRUE(writer.init(mTestMuxer, mTestCallbacks));
// Use two tracks for this test.
static constexpr int kNumTracks = 2;
@@ -356,7 +419,7 @@
ASSERT_TRUE(writer.start());
// Wait for writer to complete.
- semaphore.wait();
+ mTestCallbacks->waitForWritingFinished();
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Start());
// Verify sample order.
@@ -386,16 +449,14 @@
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Stop());
EXPECT_TRUE(writer.stop());
+ EXPECT_TRUE(mTestCallbacks->hasFinished());
}
TEST_F(MediaSampleWriterTests, TestAbortInputQueue) {
- SimpleSemaphore semaphore;
-
MediaSampleWriter writer{};
- EXPECT_TRUE(writer.init(mTestMuxer, [&semaphore](media_status_t status) {
- EXPECT_NE(status, AMEDIA_OK);
- semaphore.signal();
- }));
+ std::shared_ptr<TestCallbacks> callbacks =
+ std::make_shared<TestCallbacks>(false /* expectSuccess */);
+ EXPECT_TRUE(writer.init(mTestMuxer, callbacks));
// Use two tracks for this test.
static constexpr int kNumTracks = 2;
@@ -417,7 +478,8 @@
for (int trackIdx = 0; trackIdx < kNumTracks; ++trackIdx) {
sampleQueues[trackIdx]->abort();
}
- semaphore.wait();
+
+ callbacks->waitForWritingFinished();
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Start());
EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Stop());
@@ -465,12 +527,8 @@
ASSERT_GT(destinationFd, 0);
// Initialize writer.
- SimpleSemaphore semaphore;
MediaSampleWriter writer{};
- EXPECT_TRUE(writer.init(destinationFd, [&semaphore](media_status_t status) {
- EXPECT_EQ(status, AMEDIA_OK);
- semaphore.signal();
- }));
+ EXPECT_TRUE(writer.init(destinationFd, mTestCallbacks));
close(destinationFd);
// Add tracks.
@@ -497,7 +555,7 @@
}
// Wait for writer.
- semaphore.wait();
+ mTestCallbacks->waitForWritingFinished();
EXPECT_TRUE(writer.stop());
// Compare output file with source.
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 9b3f420..bcf418a 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -46,88 +46,6 @@
static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
-struct CameraSourceListener : public CameraListener {
- explicit 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,
- camera_frame_metadata_t *metadata);
-
- virtual void postDataTimestamp(
- nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
-
- virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
-
- virtual void postRecordingFrameHandleTimestampBatch(
- const std::vector<nsecs_t>& timestamps,
- const std::vector<native_handle_t*>& handles);
-
-protected:
- virtual ~CameraSourceListener();
-
-private:
- wp<CameraSource> mSource;
-
- CameraSourceListener(const CameraSourceListener &);
- CameraSourceListener &operator=(const CameraSourceListener &);
-};
-
-CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source)
- : mSource(source) {
-}
-
-CameraSourceListener::~CameraSourceListener() {
-}
-
-void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
- UNUSED_UNLESS_VERBOSE(msgType);
- UNUSED_UNLESS_VERBOSE(ext1);
- UNUSED_UNLESS_VERBOSE(ext2);
- ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
-}
-
-void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
- camera_frame_metadata_t * /* metadata */) {
- ALOGV("postData(%d, ptr:%p, size:%zu)",
- msgType, dataPtr->unsecurePointer(), 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) {
-
- sp<CameraSource> source = mSource.promote();
- if (source.get() != NULL) {
- source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
- }
-}
-
-void CameraSourceListener::postRecordingFrameHandleTimestamp(nsecs_t timestamp,
- native_handle_t* handle) {
- sp<CameraSource> source = mSource.promote();
- if (source.get() != nullptr) {
- source->recordingFrameHandleCallbackTimestamp(timestamp/1000, handle);
- }
-}
-
-void CameraSourceListener::postRecordingFrameHandleTimestampBatch(
- const std::vector<nsecs_t>& timestamps,
- const std::vector<native_handle_t*>& handles) {
- sp<CameraSource> source = mSource.promote();
- if (source.get() != nullptr) {
- int n = timestamps.size();
- std::vector<nsecs_t> modifiedTimestamps(n);
- for (int i = 0; i < n; i++) {
- modifiedTimestamps[i] = timestamps[i] / 1000;
- }
- source->recordingFrameHandleCallbackTimestampBatch(modifiedTimestamps, handles);
- }
-}
-
static int32_t getColorFormat(const char* colorFormat) {
if (!colorFormat) {
ALOGE("Invalid color format");
@@ -169,16 +87,6 @@
return -1;
}
-CameraSource *CameraSource::Create(const String16 &clientName) {
- Size size;
- size.width = -1;
- size.height = -1;
-
- sp<hardware::ICamera> camera;
- return new CameraSource(camera, NULL, 0, clientName, Camera::USE_CALLING_UID,
- Camera::USE_CALLING_PID, size, -1, NULL, false);
-}
-
// static
CameraSource *CameraSource::CreateFromCamera(
const sp<hardware::ICamera>& camera,
@@ -189,12 +97,10 @@
pid_t clientPid,
Size videoSize,
int32_t frameRate,
- const sp<IGraphicBufferProducer>& surface,
- bool storeMetaDataInVideoBuffers) {
+ const sp<IGraphicBufferProducer>& surface) {
CameraSource *source = new CameraSource(camera, proxy, cameraId,
- clientName, clientUid, clientPid, videoSize, frameRate, surface,
- storeMetaDataInVideoBuffers);
+ clientName, clientUid, clientPid, videoSize, frameRate, surface);
return source;
}
@@ -207,8 +113,7 @@
pid_t clientPid,
Size videoSize,
int32_t frameRate,
- const sp<IGraphicBufferProducer>& surface,
- bool storeMetaDataInVideoBuffers)
+ const sp<IGraphicBufferProducer>& surface)
: mCameraFlags(0),
mNumInputBuffers(0),
mVideoFrameRate(-1),
@@ -231,8 +136,7 @@
mInitCheck = init(camera, proxy, cameraId,
clientName, clientUid, clientPid,
- videoSize, frameRate,
- storeMetaDataInVideoBuffers);
+ videoSize, frameRate);
if (mInitCheck != OK) releaseCamera();
}
@@ -531,15 +435,13 @@
uid_t clientUid,
pid_t clientPid,
Size videoSize,
- int32_t frameRate,
- bool storeMetaDataInVideoBuffers) {
+ int32_t frameRate) {
ALOGV("init");
status_t err = OK;
int64_t token = IPCThreadState::self()->clearCallingIdentity();
err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, clientPid,
- videoSize, frameRate,
- storeMetaDataInVideoBuffers);
+ videoSize, frameRate);
IPCThreadState::self()->restoreCallingIdentity(token);
return err;
}
@@ -626,8 +528,7 @@
uid_t clientUid,
pid_t clientPid,
Size videoSize,
- int32_t frameRate,
- bool storeMetaDataInVideoBuffers) {
+ int32_t frameRate) {
ALOGV("initWithCameraAccess");
status_t err = OK;
@@ -667,24 +568,12 @@
CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface));
}
- // By default, store real data in video buffers.
- mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV;
- if (storeMetaDataInVideoBuffers) {
- if (OK == mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE)) {
- mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE;
- } else if (OK == mCamera->setVideoBufferMode(
- hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA)) {
- mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA;
- }
- }
-
- if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) {
- err = mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV);
- if (err != OK) {
- ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV failed: "
- "%s (err=%d)", __FUNCTION__, strerror(-err), err);
- return err;
- }
+ // Use buffer queue to receive video buffers from camera
+ err = mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE);
+ if (err != OK) {
+ ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_BUFFER_QUEUE failed: "
+ "%s (err=%d)", __FUNCTION__, strerror(-err), err);
+ return err;
}
int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
@@ -724,54 +613,26 @@
int64_t token = IPCThreadState::self()->clearCallingIdentity();
status_t err;
- if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) {
- // Initialize buffer queue.
- err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat,
- (android_dataspace_t)mEncoderDataSpace,
- mNumInputBuffers > 0 ? mNumInputBuffers : 1);
- if (err != OK) {
- ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__,
- strerror(-err), err);
- return err;
- }
- } else {
- if (mNumInputBuffers > 0) {
- err = mCamera->sendCommand(
- CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);
-
- // This could happen for CameraHAL1 clients; thus the failure is
- // not a fatal error
- if (err != OK) {
- ALOGW("Failed to set video buffer count to %d due to %d",
- mNumInputBuffers, err);
- }
- }
-
- err = mCamera->sendCommand(
- CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace);
-
- // This could happen for CameraHAL1 clients; thus the failure is
- // not a fatal error
- if (err != OK) {
- ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d",
- mEncoderFormat, mEncoderDataSpace, err);
- }
-
- // Create memory heap to store buffers as VideoNativeMetadata.
- createVideoBufferMemoryHeap(sizeof(VideoNativeHandleMetadata), kDefaultVideoBufferCount);
+ // Initialize buffer queue.
+ err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat,
+ (android_dataspace_t)mEncoderDataSpace,
+ mNumInputBuffers > 0 ? mNumInputBuffers : 1);
+ if (err != OK) {
+ ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__,
+ strerror(-err), err);
+ return err;
}
+ // Start data flow
err = OK;
if (mCameraFlags & FLAGS_HOT_CAMERA) {
mCamera->unlock();
mCamera.clear();
- if ((err = mCameraRecordingProxy->startRecording(
- new ProxyListener(this))) != OK) {
+ if ((err = mCameraRecordingProxy->startRecording()) != OK) {
ALOGE("Failed to start recording, received error: %s (%d)",
strerror(-err), err);
}
} else {
- mCamera->setListener(new CameraSourceListener(this));
mCamera->startRecording();
if (!mCamera->recordingEnabled()) {
err = -EINVAL;
@@ -836,7 +697,6 @@
}
} else {
if (mCamera != 0) {
- mCamera->setListener(NULL);
mCamera->stopRecording();
}
}
@@ -935,97 +795,31 @@
void CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
ALOGV("releaseRecordingFrame");
- if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) {
- // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = frame->getMemory(&offset, &size);
- if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) {
- ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__,
- heap->getHeapID(), mMemoryHeapBase->getHeapID());
- return;
- }
-
- VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
- (uint8_t*)heap->getBase() + offset);
-
- // Find the corresponding buffer item for the native window buffer.
- ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer);
- if (index == NAME_NOT_FOUND) {
- ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer);
- return;
- }
-
- BufferItem buffer = mReceivedBufferItemMap.valueAt(index);
- mReceivedBufferItemMap.removeItemsAt(index);
- mVideoBufferConsumer->releaseBuffer(buffer);
- mMemoryBases.push_back(frame);
- mMemoryBaseAvailableCond.signal();
- } else {
- native_handle_t* handle = nullptr;
-
- // Check if frame contains a VideoNativeHandleMetadata.
- if (frame->size() == sizeof(VideoNativeHandleMetadata)) {
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata *metadata =
- (VideoNativeHandleMetadata*)(frame->unsecurePointer());
- if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
- handle = metadata->pHandle;
- }
- }
-
- if (handle != nullptr) {
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = frame->getMemory(&offset, &size);
- if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) {
- ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)",
- __FUNCTION__, heap->getHeapID(), mMemoryHeapBase->getHeapID());
- return;
- }
- uint32_t batchSize = 0;
- {
- Mutex::Autolock autoLock(mBatchLock);
- if (mInflightBatchSizes.size() > 0) {
- batchSize = mInflightBatchSizes[0];
- }
- }
- if (batchSize == 0) { // return buffers one by one
- // Frame contains a VideoNativeHandleMetadata. Send the handle back to camera.
- releaseRecordingFrameHandle(handle);
- mMemoryBases.push_back(frame);
- mMemoryBaseAvailableCond.signal();
- } else { // Group buffers in batch then return
- Mutex::Autolock autoLock(mBatchLock);
- mInflightReturnedHandles.push_back(handle);
- mInflightReturnedMemorys.push_back(frame);
- if (mInflightReturnedHandles.size() == batchSize) {
- releaseRecordingFrameHandleBatch(mInflightReturnedHandles);
-
- mInflightBatchSizes.pop_front();
- mInflightReturnedHandles.clear();
- for (const auto& mem : mInflightReturnedMemorys) {
- mMemoryBases.push_back(mem);
- mMemoryBaseAvailableCond.signal();
- }
- mInflightReturnedMemorys.clear();
- }
- }
-
- } else if (mCameraRecordingProxy != nullptr) {
- // mCamera is created by application. Return the frame back to camera via camera
- // recording proxy.
- mCameraRecordingProxy->releaseRecordingFrame(frame);
- } else if (mCamera != nullptr) {
- // mCamera is created by CameraSource. Return the frame directly back to camera.
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- mCamera->releaseRecordingFrame(frame);
- IPCThreadState::self()->restoreCallingIdentity(token);
- }
+ // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
+ ssize_t offset;
+ size_t size;
+ sp<IMemoryHeap> heap = frame->getMemory(&offset, &size);
+ if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) {
+ ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__,
+ heap->getHeapID(), mMemoryHeapBase->getHeapID());
+ return;
}
+
+ VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
+ (uint8_t*)heap->getBase() + offset);
+
+ // Find the corresponding buffer item for the native window buffer.
+ ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer);
+ if (index == NAME_NOT_FOUND) {
+ ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer);
+ return;
+ }
+
+ BufferItem buffer = mReceivedBufferItemMap.valueAt(index);
+ mReceivedBufferItemMap.removeItemsAt(index);
+ mVideoBufferConsumer->releaseBuffer(buffer);
+ mMemoryBases.push_back(frame);
+ mMemoryBaseAvailableCond.signal();
}
void CameraSource::releaseQueuedFrames() {
@@ -1181,152 +975,6 @@
return false;
}
-void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
- int32_t msgType __unused, const sp<IMemory> &data) {
- ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs);
- Mutex::Autolock autoLock(mLock);
-
- if (shouldSkipFrameLocked(timestampUs)) {
- releaseOneRecordingFrame(data);
- return;
- }
-
- ++mNumFramesReceived;
-
- CHECK(data != NULL && data->size() > 0);
- mFramesReceived.push_back(data);
- int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
- mFrameTimes.push_back(timeUs);
- ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64,
- mStartTimeUs, timeUs);
- mFrameAvailableCondition.signal();
-}
-
-void CameraSource::releaseRecordingFrameHandle(native_handle_t* handle) {
- if (mCameraRecordingProxy != nullptr) {
- mCameraRecordingProxy->releaseRecordingFrameHandle(handle);
- } else if (mCamera != nullptr) {
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- mCamera->releaseRecordingFrameHandle(handle);
- IPCThreadState::self()->restoreCallingIdentity(token);
- } else {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
-}
-
-void CameraSource::releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
- if (mCameraRecordingProxy != nullptr) {
- mCameraRecordingProxy->releaseRecordingFrameHandleBatch(handles);
- } else if (mCamera != nullptr) {
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
- mCamera->releaseRecordingFrameHandleBatch(handles);
- IPCThreadState::self()->restoreCallingIdentity(token);
- } else {
- for (auto& handle : handles) {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
- }
-}
-
-void CameraSource::recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
- native_handle_t* handle) {
- ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs);
- Mutex::Autolock autoLock(mLock);
- if (handle == nullptr) return;
-
- if (shouldSkipFrameLocked(timestampUs)) {
- releaseRecordingFrameHandle(handle);
- return;
- }
-
- while (mMemoryBases.empty()) {
- if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) ==
- TIMED_OUT) {
- ALOGW("Waiting on an available memory base timed out. Dropping a recording frame.");
- releaseRecordingFrameHandle(handle);
- return;
- }
- }
-
- ++mNumFramesReceived;
-
- sp<IMemory> data = *mMemoryBases.begin();
- mMemoryBases.erase(mMemoryBases.begin());
-
- // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived.
- VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->unsecurePointer());
- metadata->eType = kMetadataBufferTypeNativeHandleSource;
- metadata->pHandle = handle;
-
- mFramesReceived.push_back(data);
- int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
- mFrameTimes.push_back(timeUs);
- ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs);
- mFrameAvailableCondition.signal();
-}
-
-void CameraSource::recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles) {
- size_t n = timestampsUs.size();
- if (n != handles.size()) {
- ALOGE("%s: timestampsUs(%zu) and handles(%zu) size mismatch!",
- __FUNCTION__, timestampsUs.size(), handles.size());
- }
-
- Mutex::Autolock autoLock(mLock);
- int batchSize = 0;
- for (size_t i = 0; i < n; i++) {
- int64_t timestampUs = timestampsUs[i];
- native_handle_t* handle = handles[i];
-
- ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs);
- if (handle == nullptr) continue;
-
- if (shouldSkipFrameLocked(timestampUs)) {
- releaseRecordingFrameHandle(handle);
- continue;
- }
-
- while (mMemoryBases.empty()) {
- if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) ==
- TIMED_OUT) {
- ALOGW("Waiting on an available memory base timed out. Dropping a recording frame.");
- releaseRecordingFrameHandle(handle);
- continue;
- }
- }
- ++batchSize;
- ++mNumFramesReceived;
- sp<IMemory> data = *mMemoryBases.begin();
- mMemoryBases.erase(mMemoryBases.begin());
-
- // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived.
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->unsecurePointer());
- metadata->eType = kMetadataBufferTypeNativeHandleSource;
- metadata->pHandle = handle;
-
- mFramesReceived.push_back(data);
- int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
- mFrameTimes.push_back(timeUs);
- ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs);
-
- }
- if (batchSize > 0) {
- Mutex::Autolock autoLock(mBatchLock);
- mInflightBatchSizes.push_back(batchSize);
- }
- for (int i = 0; i < batchSize; i++) {
- mFrameAvailableCondition.signal();
- }
-}
-
CameraSource::BufferQueueListener::BufferQueueListener(const sp<BufferItemConsumer>& consumer,
const sp<CameraSource>& cameraSource) {
mConsumer = consumer;
@@ -1417,41 +1065,7 @@
MetadataBufferType CameraSource::metaDataStoredInVideoBuffers() const {
ALOGV("metaDataStoredInVideoBuffers");
- // Output buffers will contain metadata if camera sends us buffer in metadata mode or via
- // buffer queue.
- switch (mVideoBufferMode) {
- case hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA:
- return kMetadataBufferTypeNativeHandleSource;
- case hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE:
- return kMetadataBufferTypeANWBuffer;
- default:
- return kMetadataBufferTypeInvalid;
- }
-}
-
-CameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
- mSource = source;
-}
-
-void CameraSource::ProxyListener::dataCallbackTimestamp(
- nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
- mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
-}
-
-void CameraSource::ProxyListener::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,
- native_handle_t* handle) {
- mSource->recordingFrameHandleCallbackTimestamp(timestamp / 1000, handle);
-}
-
-void CameraSource::ProxyListener::recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles) {
- int n = timestampsUs.size();
- std::vector<nsecs_t> modifiedTimestamps(n);
- for (int i = 0; i < n; i++) {
- modifiedTimestamps[i] = timestampsUs[i] / 1000;
- }
- mSource->recordingFrameHandleCallbackTimestampBatch(modifiedTimestamps, handles);
+ return kMetadataBufferTypeANWBuffer;
}
void CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index e0a6eb3..50a512f 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -45,15 +45,13 @@
Size videoSize,
int32_t videoFrameRate,
const sp<IGraphicBufferProducer>& surface,
- int64_t timeBetweenFrameCaptureUs,
- bool storeMetaDataInVideoBuffers) {
+ int64_t timeBetweenFrameCaptureUs) {
CameraSourceTimeLapse *source = new
CameraSourceTimeLapse(camera, proxy, cameraId,
clientName, clientUid, clientPid,
videoSize, videoFrameRate, surface,
- timeBetweenFrameCaptureUs,
- storeMetaDataInVideoBuffers);
+ timeBetweenFrameCaptureUs);
if (source != NULL) {
if (source->initCheck() != OK) {
@@ -74,11 +72,9 @@
Size videoSize,
int32_t videoFrameRate,
const sp<IGraphicBufferProducer>& surface,
- int64_t timeBetweenFrameCaptureUs,
- bool storeMetaDataInVideoBuffers)
+ int64_t timeBetweenFrameCaptureUs)
: CameraSource(camera, proxy, cameraId, clientName, clientUid, clientPid,
- videoSize, videoFrameRate, surface,
- storeMetaDataInVideoBuffers),
+ videoSize, videoFrameRate, surface),
mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
mLastTimeLapseFrameRealTimestampUs(0),
mSkipCurrentFrame(false) {
@@ -173,12 +169,6 @@
ALOGV("signalBufferReturned");
Mutex::Autolock autoLock(mQuickStopLock);
if (mQuickStop && (buffer == mLastReadBufferCopy)) {
- if (metaDataStoredInVideoBuffers() == kMetadataBufferTypeNativeHandleSource) {
- native_handle_t* handle = (
- (VideoNativeHandleMetadata*)(mLastReadBufferCopy->data()))->pHandle;
- native_handle_close(handle);
- native_handle_delete(handle);
- }
buffer->setObserver(NULL);
buffer->release();
mLastReadBufferCopy = NULL;
@@ -191,8 +181,7 @@
void createMediaBufferCopy(
const MediaBufferBase& sourceBuffer,
int64_t frameTime,
- MediaBufferBase **newBuffer,
- int32_t videoBufferMode) {
+ MediaBufferBase **newBuffer) {
ALOGV("createMediaBufferCopy");
size_t sourceSize = sourceBuffer.size();
@@ -203,19 +192,13 @@
(*newBuffer)->meta_data().setInt64(kKeyTime, frameTime);
- if (videoBufferMode == kMetadataBufferTypeNativeHandleSource) {
- ((VideoNativeHandleMetadata*)((*newBuffer)->data()))->pHandle =
- native_handle_clone(
- ((VideoNativeHandleMetadata*)(sourceBuffer.data()))->pHandle);
- }
}
void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBufferBase& sourceBuffer) {
ALOGV("fillLastReadBufferCopy");
int64_t frameTime;
CHECK(sourceBuffer.meta_data().findInt64(kKeyTime, &frameTime));
- createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy,
- metaDataStoredInVideoBuffers());
+ createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
mLastReadBufferCopy->add_ref();
mLastReadBufferCopy->setObserver(this);
}
@@ -240,19 +223,6 @@
}
}
-sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
- const sp<IMemory> &source_data) {
-
- ALOGV("createIMemoryCopy");
- size_t source_size = source_data->size();
- void* source_pointer = source_data->unsecurePointer();
-
- sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size);
- sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size);
- memcpy(newMemory->unsecurePointer(), source_pointer, source_size);
- return newMemory;
-}
-
bool CameraSourceTimeLapse::skipCurrentFrame(int64_t /* timestampUs */) {
ALOGV("skipCurrentFrame");
if (mSkipCurrentFrame) {
@@ -318,31 +288,6 @@
return false;
}
-void CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
- const sp<IMemory> &data) {
- ALOGV("dataCallbackTimestamp");
- mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs);
- CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
-}
-
-void CameraSourceTimeLapse::recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
- native_handle_t* handle) {
- ALOGV("recordingFrameHandleCallbackTimestamp");
- mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs);
- CameraSource::recordingFrameHandleCallbackTimestamp(timestampUs, handle);
-}
-
-void CameraSourceTimeLapse::recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles) {
- ALOGV("recordingFrameHandleCallbackTimestampBatch");
- int n = timestampsUs.size();
- for (int i = 0; i < n; i++) {
- // Don't do batching for CameraSourceTimeLapse for now
- recordingFrameHandleCallbackTimestamp(timestampsUs[i], handles[i]);
- }
-}
-
void CameraSourceTimeLapse::processBufferQueueFrame(BufferItem& buffer) {
ALOGV("processBufferQueueFrame");
int64_t timestampUs = buffer.mTimestamp / 1000;
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index 3add006..078c8e3 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -399,29 +399,31 @@
mEncoderWriteData = true;
mEncoderReturnedEncodedData = false;
mEncoderReturnedNbBytes = 0;
- mCurrentInputTimeStamp = inHeader->nTimeStamp;
+ if (inHeader->nFilledLen) {
+ mCurrentInputTimeStamp = inHeader->nTimeStamp;
- const unsigned nbInputFrames = inHeader->nFilledLen / frameSize;
- const unsigned nbInputSamples = inHeader->nFilledLen / sampleSize;
+ const unsigned nbInputFrames = inHeader->nFilledLen / frameSize;
+ const unsigned nbInputSamples = inHeader->nFilledLen / sampleSize;
- if (inputFloat) {
- CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels);
- const float * const pcmFloat = reinterpret_cast<float *>(inHeader->pBuffer);
- memcpy_to_q8_23_from_float_with_clamp(
- mInputBufferPcm32, pcmFloat, nbInputSamples);
- } else {
- // note nbInputSamples may be 2x as large for pcm16 data.
- CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels * 2);
- const int16_t * const pcm16 = reinterpret_cast<int16_t *>(inHeader->pBuffer);
- for (unsigned i = 0; i < nbInputSamples; ++i) {
- mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+ if (inputFloat) {
+ CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels);
+ const float * const pcmFloat = reinterpret_cast<float *>(inHeader->pBuffer);
+ memcpy_to_q8_23_from_float_with_clamp(
+ mInputBufferPcm32, pcmFloat, nbInputSamples);
+ } else {
+ // note nbInputSamples may be 2x as large for pcm16 data.
+ CHECK_LE(nbInputSamples, kNumSamplesPerFrame * kMaxChannels * 2);
+ const int16_t * const pcm16 = reinterpret_cast<int16_t *>(inHeader->pBuffer);
+ for (unsigned i = 0; i < nbInputSamples; ++i) {
+ mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+ }
}
+ ALOGV(" about to encode %u samples per channel", nbInputFrames);
+ ok = FLAC__stream_encoder_process_interleaved(
+ mFlacStreamEncoder,
+ mInputBufferPcm32,
+ nbInputFrames /*samples per channel*/ );
}
- ALOGV(" about to encode %u samples per channel", nbInputFrames);
- ok = FLAC__stream_encoder_process_interleaved(
- mFlacStreamEncoder,
- mInputBufferPcm32,
- nbInputFrames /*samples per channel*/ );
inInfo->mOwnedByUs = false;
inQueue.erase(inQueue.begin());
@@ -434,7 +436,15 @@
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
if (ok) {
- if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) {
+ ALOGV("encoded %d, bytes %lld, eos %d", mEncoderReturnedEncodedData,
+ (long long )mEncoderReturnedNbBytes, mSawInputEOS);
+ if (mSawInputEOS && !mEncoderReturnedEncodedData) {
+ ALOGV("finishing encoder");
+ mSentOutputEOS = true;
+ FLAC__stream_encoder_finish(mFlacStreamEncoder);
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ }
+ if (mSawInputEOS || mEncoderReturnedEncodedData) {
ALOGV(" dequeueing buffer on output port after writing data");
outInfo->mOwnedByUs = false;
outQueue.erase(outQueue.begin());
@@ -442,23 +452,6 @@
notifyFillBufferDone(outHeader);
outHeader = NULL;
mEncoderReturnedEncodedData = false;
- } else {
- ALOGV(" encoder process_interleaved returned without data to write");
- if (mSawInputEOS) {
- ALOGV("finishing encoder");
- mSentOutputEOS = true;
- FLAC__stream_encoder_finish(mFlacStreamEncoder);
- if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) {
- ALOGV(" dequeueing residual buffer on output port after writing data");
- outInfo->mOwnedByUs = false;
- outQueue.erase(outQueue.begin());
- outInfo = NULL;
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
- notifyFillBufferDone(outHeader);
- outHeader = NULL;
- mEncoderReturnedEncodedData = false;
- }
- }
}
} else {
ALOGE(" error encountered during encoding");
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 80083f7..b5d32ed 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -307,6 +307,20 @@
if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
mSawInputEos = true;
+ if (mIsFirst && !inHeader->nFilledLen) {
+ ALOGV("empty first EOS");
+ outHeader->nFilledLen = 0;
+ outHeader->nTimeStamp = inHeader->nTimeStamp;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ notifyFillBufferDone(outHeader);
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ notifyEmptyBufferDone(inHeader);
+ return;
+ }
}
mConfig->pInputBuffer =
diff --git a/media/libstagefright/include/media/stagefright/CameraSource.h b/media/libstagefright/include/media/stagefright/CameraSource.h
index 6f0d3b5..16e7d89 100644
--- a/media/libstagefright/include/media/stagefright/CameraSource.h
+++ b/media/libstagefright/include/media/stagefright/CameraSource.h
@@ -23,7 +23,6 @@
#include <media/stagefright/MediaBuffer.h>
#include <camera/android/hardware/ICamera.h>
#include <camera/ICameraRecordingProxy.h>
-#include <camera/ICameraRecordingProxyListener.h>
#include <camera/CameraParameters.h>
#include <gui/BufferItemConsumer.h>
#include <utils/List.h>
@@ -40,17 +39,6 @@
class CameraSource : public MediaSource, public MediaBufferObserver {
public:
/**
- * Factory method to create a new CameraSource using the current
- * settings (such as video size, frame rate, color format, etc)
- * from the default camera.
- *
- * @param clientName The package/process name of the client application.
- * This is used for permissions checking.
- * @return NULL on error.
- */
- static CameraSource *Create(const String16 &clientName);
-
- /**
* Factory method to create a new CameraSource.
*
* @param camera the video input frame data source. If it is NULL,
@@ -89,8 +77,7 @@
pid_t clientPid,
Size videoSize,
int32_t frameRate,
- const sp<IGraphicBufferProducer>& surface,
- bool storeMetaDataInVideoBuffers = true);
+ const sp<IGraphicBufferProducer>& surface);
virtual ~CameraSource();
@@ -132,26 +119,6 @@
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);
- virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
- const sp<IMemory> &data);
- virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
- native_handle_t* handle);
- virtual void recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles);
-
- private:
- 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.
@@ -213,32 +180,15 @@
CameraSource(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
Size videoSize, int32_t frameRate,
- const sp<IGraphicBufferProducer>& surface,
- bool storeMetaDataInVideoBuffers);
+ const sp<IGraphicBufferProducer>& surface);
virtual status_t startCameraRecording();
virtual void releaseRecordingFrame(const sp<IMemory>& frame);
- virtual void releaseRecordingFrameHandle(native_handle_t* handle);
- // stagefright recorder not using this for now
- virtual void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles);
// Returns true if need to skip the current frame.
// Called from dataCallbackTimestamp.
virtual bool skipCurrentFrame(int64_t /*timestampUs*/) {return false;}
- // Callback called when still camera raw data is available.
- virtual void dataCallback(int32_t /*msgType*/, const sp<IMemory>& /*data*/) {}
-
- virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
- const sp<IMemory> &data);
-
- virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
- native_handle_t* handle);
-
- virtual void recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles);
-
// Process a buffer item received in BufferQueueListener.
virtual void processBufferQueueFrame(BufferItem& buffer);
@@ -261,9 +211,6 @@
int64_t mGlitchDurationThresholdUs;
bool mCollectStats;
- // The mode video buffers are received from camera. One of VIDEO_BUFFER_MODE_*.
- int32_t mVideoBufferMode;
-
static const uint32_t kDefaultVideoBufferCount = 32;
/**
@@ -297,12 +244,12 @@
status_t init(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
- Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
+ Size videoSize, int32_t frameRate);
status_t initWithCameraAccess(
const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
- Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
+ Size videoSize, int32_t frameRate);
// Initialize the buffer queue used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
status_t initBufferQueue(uint32_t width, uint32_t height, uint32_t format,
diff --git a/media/libstagefright/include/media/stagefright/CameraSourceTimeLapse.h b/media/libstagefright/include/media/stagefright/CameraSourceTimeLapse.h
index 533e33b..3c311cf 100644
--- a/media/libstagefright/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/media/libstagefright/include/media/stagefright/CameraSourceTimeLapse.h
@@ -45,8 +45,7 @@
Size videoSize,
int32_t videoFrameRate,
const sp<IGraphicBufferProducer>& surface,
- int64_t timeBetweenTimeLapseFrameCaptureUs,
- bool storeMetaDataInVideoBuffers = true);
+ int64_t timeBetweenTimeLapseFrameCaptureUs);
virtual ~CameraSourceTimeLapse();
@@ -122,8 +121,7 @@
Size videoSize,
int32_t videoFrameRate,
const sp<IGraphicBufferProducer>& surface,
- int64_t timeBetweenTimeLapseFrameCaptureUs,
- bool storeMetaDataInVideoBuffers = true);
+ int64_t timeBetweenTimeLapseFrameCaptureUs);
// Wrapper over CameraSource::signalBufferReturned() to implement quick stop.
// It only handles the case when mLastReadBufferCopy is signalled. Otherwise
@@ -137,33 +135,6 @@
// frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
virtual bool skipCurrentFrame(int64_t timestampUs);
- // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
- // timestamp and set mSkipCurrentFrame.
- // Then it calls the base CameraSource::dataCallbackTimestamp()
- // This will be called in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and
- // VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA mode.
- virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
- const sp<IMemory> &data);
-
- // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
- // timestamp and set mSkipCurrentFrame.
- // Then it calls the base CameraSource::recordingFrameHandleCallbackTimestamp() or
- // CameraSource::recordingFrameHandleCallbackTimestampBatch()
- // This will be called in VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA mode when
- // the metadata is VideoNativeHandleMetadata.
- virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
- native_handle_t* handle);
-
- // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
- // timestamp and set mSkipCurrentFrame.
- // Then it calls the base CameraSource::recordingFrameHandleCallbackTimestamp() or
- // CameraSource::recordingFrameHandleCallbackTimestampBatch()
- // This will be called in VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA mode when
- // the metadata is VideoNativeHandleMetadata.
- virtual void recordingFrameHandleCallbackTimestampBatch(
- const std::vector<int64_t>& timestampsUs,
- const std::vector<native_handle_t*>& handles);
-
// Process a buffer item received in CameraSource::BufferQueueListener.
// This will be called in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
virtual void processBufferQueueFrame(BufferItem& buffer);
@@ -187,9 +158,6 @@
// Wrapper to enter threadTimeLapseEntry()
static void *ThreadTimeLapseWrapper(void *me);
- // Creates a copy of source_data into a new memory of final type MemoryBase.
- sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);
-
CameraSourceTimeLapse(const CameraSourceTimeLapse &);
CameraSourceTimeLapse &operator=(const CameraSourceTimeLapse &);
};
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index 1b71a2b..5d697f7 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -47,6 +47,14 @@
],
min_sdk_version: "29",
+
+ host_supported: true,
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 501d922..bdbcdb0 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -30,7 +30,6 @@
"common/CameraProviderManager.cpp",
"common/DepthPhotoProcessor.cpp",
"common/FrameProcessorBase.cpp",
- "api1/CameraClient.cpp",
"api1/Camera2Client.cpp",
"api1/client2/Parameters.cpp",
"api1/client2/FrameProcessor.cpp",
@@ -46,7 +45,6 @@
"api2/DepthCompositeStream.cpp",
"api2/HeicEncoderInfoManager.cpp",
"api2/HeicCompositeStream.cpp",
- "device1/CameraHardwareInterface.cpp",
"device3/BufferUtils.cpp",
"device3/Camera3Device.cpp",
"device3/Camera3OfflineSession.cpp",
@@ -122,7 +120,6 @@
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
- "android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.3",
"android.hardware.camera.device@3.4",
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index e629cdd..ccdd9e5 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -59,9 +59,8 @@
if (mProviderManager->supportSetTorchMode(cameraId.string())) {
mFlashControl = new ProviderFlashControl(mProviderManager);
} else {
- // Only HAL1 devices do not support setTorchMode
- mFlashControl =
- new CameraHardwareInterfaceFlashControl(mProviderManager, mCallbacks);
+ ALOGE("Flashlight control not supported by this device!");
+ return NO_INIT;
}
return OK;
@@ -309,271 +308,4 @@
}
// ProviderFlashControl implementation ends
-/////////////////////////////////////////////////////////////////////
-// CameraHardwareInterfaceFlashControl implementation begins
-// Flash control for camera module <= v2.3 and camera HAL v1
-/////////////////////////////////////////////////////////////////////
-
-CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
- sp<CameraProviderManager> manager,
- CameraProviderManager::StatusListener* callbacks) :
- mProviderManager(manager),
- mCallbacks(callbacks),
- mTorchEnabled(false) {
-}
-
-CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
- disconnectCameraDevice();
-
- mSurface.clear();
- mSurfaceTexture.clear();
- mProducer.clear();
- mConsumer.clear();
-
- if (mTorchEnabled) {
- if (mCallbacks) {
- ALOGV("%s: notify the framework that torch was turned off",
- __FUNCTION__);
- mCallbacks->onTorchStatusChanged(mCameraId, TorchModeStatus::AVAILABLE_OFF);
- }
- }
-}
-
-status_t CameraHardwareInterfaceFlashControl::setTorchMode(
- const String8& cameraId, bool enabled) {
- Mutex::Autolock l(mLock);
-
- // pre-check
- status_t res;
- if (enabled) {
- bool hasFlash = false;
- // Check if it has a flash unit and leave camera device open.
- res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
- // invalid camera?
- if (res) {
- // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
- // another camera device.
- return res == BAD_INDEX ? BAD_INDEX : -EINVAL;
- }
- // no flash unit?
- if (!hasFlash) {
- // Disconnect camera device if it has no flash.
- disconnectCameraDevice();
- return -ENOSYS;
- }
- } else if (mDevice == NULL || cameraId != mCameraId) {
- // disabling the torch mode of an un-opened or different device.
- return OK;
- } else {
- // disabling the torch mode of currently opened device
- disconnectCameraDevice();
- mTorchEnabled = false;
- mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_OFF);
- return OK;
- }
-
- res = startPreviewAndTorch();
- if (res) {
- return res;
- }
-
- mTorchEnabled = true;
- mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_ON);
- return OK;
-}
-
-status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
- const String8& cameraId, bool *hasFlash) {
- Mutex::Autolock l(mLock);
- // Close device after checking if it has a flash unit.
- return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
-}
-
-status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
- const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
- bool closeCameraDevice = false;
-
- if (!hasFlash) {
- return BAD_VALUE;
- }
-
- status_t res;
- if (mDevice == NULL) {
- // Connect to camera device to query if it has a flash unit.
- res = connectCameraDevice(cameraId);
- if (res) {
- return res;
- }
- // Close camera device only when it is just opened and the caller doesn't want to keep
- // the camera device open.
- closeCameraDevice = !keepDeviceOpen;
- }
-
- if (cameraId != mCameraId) {
- return BAD_INDEX;
- }
-
- const char *flashMode =
- mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
- if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
- *hasFlash = true;
- } else {
- *hasFlash = false;
- }
-
- if (closeCameraDevice) {
- res = disconnectCameraDevice();
- if (res != OK) {
- ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
- strerror(-res), res);
- return res;
- }
- }
-
- return OK;
-}
-
-status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() {
- status_t res = OK;
- res = mDevice->startPreview();
- if (res) {
- ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__,
- strerror(-res), res);
- return res;
- }
-
- mParameters.set(CameraParameters::KEY_FLASH_MODE,
- CameraParameters::FLASH_MODE_TORCH);
-
- return mDevice->setParameters(mParameters);
-}
-
-status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize(
- int32_t *width, int32_t *height) {
- if (!width || !height) {
- return BAD_VALUE;
- }
-
- int32_t w = INT32_MAX;
- int32_t h = 1;
- Vector<Size> sizes;
-
- mParameters.getSupportedPreviewSizes(sizes);
- for (size_t i = 0; i < sizes.size(); i++) {
- Size s = sizes[i];
- if (w * h > s.width * s.height) {
- w = s.width;
- h = s.height;
- }
- }
-
- if (w == INT32_MAX) {
- return NAME_NOT_FOUND;
- }
-
- *width = w;
- *height = h;
-
- return OK;
-}
-
-status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
- const sp<CameraHardwareInterface>& device, int32_t width, int32_t height) {
- status_t res;
- BufferQueue::createBufferQueue(&mProducer, &mConsumer);
-
- mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL,
- true, true);
- if (mSurfaceTexture == NULL) {
- return NO_MEMORY;
- }
-
- int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
- res = mSurfaceTexture->setDefaultBufferSize(width, height);
- if (res) {
- return res;
- }
- res = mSurfaceTexture->setDefaultBufferFormat(format);
- if (res) {
- return res;
- }
-
- mSurface = new Surface(mProducer, /*useAsync*/ true);
- if (mSurface == NULL) {
- return NO_MEMORY;
- }
-
- res = native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_CAMERA);
- if (res) {
- ALOGE("%s: Unable to connect to native window", __FUNCTION__);
- return res;
- }
-
- return device->setPreviewWindow(mSurface);
-}
-
-status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
- const String8& cameraId) {
- sp<CameraHardwareInterface> device =
- new CameraHardwareInterface(cameraId.string());
-
- status_t res = device->initialize(mProviderManager);
- if (res) {
- ALOGE("%s: initializing camera %s failed", __FUNCTION__,
- cameraId.string());
- return res;
- }
-
- // need to set __get_memory in set_callbacks().
- device->setCallbacks(NULL, NULL, NULL, NULL, NULL);
-
- mParameters = device->getParameters();
-
- int32_t width, height;
- res = getSmallestSurfaceSize(&width, &height);
- if (res) {
- ALOGE("%s: failed to get smallest surface size for camera %s",
- __FUNCTION__, cameraId.string());
- return res;
- }
-
- res = initializePreviewWindow(device, width, height);
- if (res) {
- ALOGE("%s: failed to initialize preview window for camera %s",
- __FUNCTION__, cameraId.string());
- return res;
- }
-
- mCameraId = cameraId;
- mDevice = device;
- return OK;
-}
-
-status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() {
- if (mDevice == NULL) {
- return OK;
- }
-
- if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
- // There is a flash, turn if off.
- // (If there isn't one, leave the parameter null)
- mParameters.set(CameraParameters::KEY_FLASH_MODE,
- CameraParameters::FLASH_MODE_OFF);
- mDevice->setParameters(mParameters);
- }
- mDevice->stopPreview();
- status_t res = native_window_api_disconnect(mSurface.get(),
- NATIVE_WINDOW_API_CAMERA);
- if (res) {
- ALOGW("%s: native_window_api_disconnect failed: %s (%d)",
- __FUNCTION__, strerror(-res), res);
- }
- mDevice->setPreviewWindow(NULL);
- mDevice->release();
- mDevice = NULL;
-
- return OK;
-}
-// CameraHardwareInterfaceFlashControl implementation ends
-
}
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 1baaba2..b97fa5f 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -23,8 +23,6 @@
#include <utils/SortedVector.h>
#include "common/CameraProviderManager.h"
#include "common/CameraDeviceBase.h"
-#include "device1/CameraHardwareInterface.h"
-
namespace android {
@@ -124,59 +122,6 @@
Mutex mLock;
};
-/**
- * Flash control for camera module <= v2.3 and camera HAL v1
- */
-class CameraHardwareInterfaceFlashControl : public FlashControlBase {
- public:
- CameraHardwareInterfaceFlashControl(
- sp<CameraProviderManager> manager,
- CameraProviderManager::StatusListener* callbacks);
- virtual ~CameraHardwareInterfaceFlashControl();
-
- // FlashControlBase
- status_t setTorchMode(const String8& cameraId, bool enabled);
- status_t hasFlashUnit(const String8& cameraId, bool *hasFlash);
-
- private:
- // connect to a camera device
- status_t connectCameraDevice(const String8& cameraId);
-
- // disconnect and free mDevice
- status_t disconnectCameraDevice();
-
- // initialize the preview window
- status_t initializePreviewWindow(const sp<CameraHardwareInterface>& device,
- int32_t width, int32_t height);
-
- // start preview and enable torch
- status_t startPreviewAndTorch();
-
- // get the smallest surface
- status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
-
- // protected by mLock
- // If this function opens camera device in order to check if it has a flash unit, the
- // camera device will remain open if keepDeviceOpen is true and the camera device will be
- // closed if keepDeviceOpen is false. If camera device is already open when calling this
- // function, keepDeviceOpen is ignored.
- status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
-
- sp<CameraProviderManager> mProviderManager;
- CameraProviderManager::StatusListener* mCallbacks;
- sp<CameraHardwareInterface> mDevice;
- String8 mCameraId;
- CameraParameters mParameters;
- bool mTorchEnabled;
-
- sp<IGraphicBufferProducer> mProducer;
- sp<IGraphicBufferConsumer> mConsumer;
- sp<GLConsumer> mSurfaceTexture;
- sp<Surface> mSurface;
-
- Mutex mLock;
-};
-
} // namespace android
#endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b5de1b7..adafbda 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -70,7 +70,6 @@
#include <system/camera.h>
#include "CameraService.h"
-#include "api1/CameraClient.h"
#include "api1/Camera2Client.h"
#include "api2/CameraDeviceClient.h"
#include "utils/CameraTraces.h"
@@ -679,9 +678,15 @@
status_t res = mCameraProviderManager->getCameraCharacteristics(
String8(cameraId).string(), cameraInfo);
if (res != OK) {
- return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
- "characteristics for device %s: %s (%d)", String8(cameraId).string(),
- strerror(-res), res);
+ if (res == NAME_NOT_FOUND) {
+ return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to retrieve camera "
+ "characteristics for unknown device %s: %s (%d)", String8(cameraId).string(),
+ strerror(-res), res);
+ } else {
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
+ "characteristics for device %s: %s (%d)", String8(cameraId).string(),
+ strerror(-res), res);
+ }
}
SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(String8(cameraId), &deviceKind) != OK) {
@@ -802,35 +807,26 @@
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName,
- const std::optional<String16>& featureId, const String8& cameraId, int api1CameraId,
- int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
+ const std::optional<String16>& featureId, const String8& cameraId,
+ int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
- if (halVersion < 0 || halVersion == deviceVersion) {
- // Default path: HAL version is unspecified by caller, create CameraClient
- // based on device version reported by the HAL.
- switch(deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- if (effectiveApiLevel == API_1) { // Camera1 API route
- sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName, featureId,
- api1CameraId, facing, clientPid, clientUid,
- getpid());
- } else { // Camera2 API route
- ALOGW("Camera using old HAL version: %d", deviceVersion);
- return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
- "Camera device \"%s\" HAL version %d does not support camera2 API",
- cameraId.string(), deviceVersion);
- }
+ // Create CameraClient based on device version reported by the HAL.
+ switch(deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_1_0:
+ ALOGE("Camera using old HAL version: %d", deviceVersion);
+ return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
+ "Camera device \"%s\" HAL version %d no longer supported",
+ cameraId.string(), deviceVersion);
break;
- case CAMERA_DEVICE_API_VERSION_3_0:
- case CAMERA_DEVICE_API_VERSION_3_1:
- case CAMERA_DEVICE_API_VERSION_3_2:
- case CAMERA_DEVICE_API_VERSION_3_3:
- case CAMERA_DEVICE_API_VERSION_3_4:
- case CAMERA_DEVICE_API_VERSION_3_5:
- case CAMERA_DEVICE_API_VERSION_3_6:
+ case CAMERA_DEVICE_API_VERSION_3_0:
+ case CAMERA_DEVICE_API_VERSION_3_1:
+ case CAMERA_DEVICE_API_VERSION_3_2:
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_4:
+ case CAMERA_DEVICE_API_VERSION_3_5:
+ case CAMERA_DEVICE_API_VERSION_3_6:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName, featureId,
@@ -844,32 +840,12 @@
cameraId, facing, clientPid, clientUid, servicePid);
}
break;
- default:
+ default:
// Should not be reachable
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Camera device \"%s\" has unknown HAL version %d",
cameraId.string(), deviceVersion);
- }
- } else {
- // A particular HAL version is requested by caller. Create CameraClient
- // based on the requested HAL version.
- if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
- halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
- // Only support higher HAL version device opened as HAL1.0 device.
- sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new CameraClient(cameraService, tmp, packageName, featureId,
- api1CameraId, facing, clientPid, clientUid,
- servicePid);
- } else {
- // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
- ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
- " opened as HAL %x device", halVersion, deviceVersion,
- CAMERA_DEVICE_API_VERSION_1_0);
- return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
- "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
- cameraId.string(), deviceVersion, halVersion);
- }
}
return Status::ok();
}
@@ -957,7 +933,6 @@
sp<Client> tmp = nullptr;
if (!(ret = connectHelper<ICameraClient,Client>(
sp<ICameraClient>{nullptr}, id, cameraId,
- static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
internalPackageName, {}, uid, USE_CALLING_PID,
API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
).isOk()) {
@@ -1476,34 +1451,7 @@
String8 id = cameraIdIntToStr(api1CameraId);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
- CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, {},
- clientUid, clientPid, API_1, /*shimUpdateOnly*/ false, /*out*/client);
-
- if(!ret.isOk()) {
- logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
- ret.toString8());
- return ret;
- }
-
- *device = client;
- return ret;
-}
-
-Status CameraService::connectLegacy(
- const sp<ICameraClient>& cameraClient,
- int api1CameraId, int halVersion,
- const String16& clientPackageName,
- int clientUid,
- /*out*/
- sp<ICamera>* device) {
-
- ATRACE_CALL();
- String8 id = cameraIdIntToStr(api1CameraId);
-
- Status ret = Status::ok();
- sp<Client> client = nullptr;
- ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
- clientPackageName, {}, clientUid, USE_CALLING_PID, API_1,
+ clientPackageName, {}, clientUid, clientPid, API_1,
/*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
@@ -1545,8 +1493,9 @@
int cUid = CameraThreadState::getCallingUid();
SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
if (getSystemCameraKind(cameraId, &systemCameraKind) != OK) {
- ALOGE("%s: Invalid camera id %s, ", __FUNCTION__, cameraId.c_str());
- return true;
+ // This isn't a known camera ID, so it's not a system camera
+ ALOGV("%s: Unknown camera id %s, ", __FUNCTION__, cameraId.c_str());
+ return false;
}
// (1) Cameraserver trying to connect, accept.
@@ -1595,8 +1544,7 @@
clientPackageNameAdj = String16(vendorClient.c_str());
}
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
- /*api1CameraId*/-1,
- CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
+ /*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
if(!ret.isOk()) {
@@ -1611,7 +1559,7 @@
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, int halVersion, const String16& clientPackageName,
+ int api1CameraId, const String16& clientPackageName,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
@@ -1621,9 +1569,8 @@
int originalClientPid = 0;
- ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
+ ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
"Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
- (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
static_cast<int>(effectiveApiLevel));
sp<CLIENT> client = nullptr;
@@ -1703,7 +1650,7 @@
if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
cameraId, api1CameraId, facing,
clientPid, clientUid, getpid(),
- halVersion, deviceVersion, effectiveApiLevel,
+ deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 35e13e7..3d3b7dd 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -70,7 +70,6 @@
public virtual CameraProviderManager::StatusListener
{
friend class BinderService<CameraService>;
- friend class CameraClient;
friend class CameraOfflineSessionClient;
public:
class Client;
@@ -134,12 +133,6 @@
/*out*/
sp<hardware::ICamera>* device);
- virtual binder::Status connectLegacy(const sp<hardware::ICameraClient>& cameraClient,
- int32_t cameraId, int32_t halVersion,
- const String16& clientPackageName, int32_t clientUid,
- /*out*/
- sp<hardware::ICamera>* device);
-
virtual binder::Status connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
@@ -728,7 +721,7 @@
// Single implementation shared between the various connect calls
template<class CALLBACK, class CLIENT>
binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
- int api1CameraId, int halVersion, const String16& clientPackageName,
+ int api1CameraId, const String16& clientPackageName,
const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
@@ -1059,7 +1052,7 @@
static binder::Status makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName,
const std::optional<String16>& featureId, const String8& cameraId, int api1CameraId,
- int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
+ int facing, int clientPid, uid_t clientUid, int servicePid,
int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client);
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
deleted file mode 100644
index b860ceb..0000000
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ /dev/null
@@ -1,1208 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "CameraClient"
-//#define LOG_NDEBUG 0
-
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <gui/Surface.h>
-#include <media/hardware/HardwareAPI.h>
-
-#include "api1/CameraClient.h"
-#include "device1/CameraHardwareInterface.h"
-#include "CameraService.h"
-#include "utils/CameraThreadState.h"
-
-namespace android {
-
-#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
-#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
-
-CameraClient::CameraClient(const sp<CameraService>& cameraService,
- const sp<hardware::ICameraClient>& cameraClient,
- const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
- int cameraId, int cameraFacing,
- int clientPid, int clientUid,
- int servicePid):
- Client(cameraService, cameraClient, clientPackageName, clientFeatureId,
- String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
- clientUid, servicePid)
-{
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId);
-
- mHardware = NULL;
- mMsgEnabled = 0;
- mSurface = 0;
- mPreviewWindow = 0;
- mDestructionStarted = false;
-
- // Callback is disabled by default
- mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
- mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
- mPlayShutterSound = true;
- LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId);
-}
-
-status_t CameraClient::initialize(sp<CameraProviderManager> manager,
- const String8& /*monitorTags*/) {
- int callingPid = CameraThreadState::getCallingPid();
- status_t res;
-
- LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);
-
- // Verify ops permissions
- res = startCameraOps();
- if (res != OK) {
- return res;
- }
-
- char camera_device_name[10];
- snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
-
- mHardware = new CameraHardwareInterface(camera_device_name);
- res = mHardware->initialize(manager);
- if (res != OK) {
- ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
- __FUNCTION__, mCameraId, strerror(-res), res);
- mHardware.clear();
- return res;
- }
-
- mHardware->setCallbacks(notifyCallback,
- dataCallback,
- dataCallbackTimestamp,
- handleCallbackTimestampBatch,
- (void *)(uintptr_t)mCameraId);
-
- // Enable zoom, error, focus, and metadata messages by default
- enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
- CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
-
- LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
- return OK;
-}
-
-
-// tear down the client
-CameraClient::~CameraClient() {
- mDestructionStarted = true;
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
-
- disconnect();
- LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
-}
-
-status_t CameraClient::dump(int fd, const Vector<String16>& args) {
- return BasicClient::dump(fd, args);
-}
-
-status_t CameraClient::dumpClient(int fd, const Vector<String16>& args) {
- const size_t SIZE = 256;
- char buffer[SIZE];
-
- size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) with UID %d\n",
- mCameraId,
- (getRemoteCallback() != NULL ?
- IInterface::asBinder(getRemoteCallback()).get() : NULL),
- mClientUid);
- len = (len > SIZE - 1) ? SIZE - 1 : len;
- write(fd, buffer, len);
-
- len = snprintf(buffer, SIZE, "Latest set parameters:\n");
- len = (len > SIZE - 1) ? SIZE - 1 : len;
- write(fd, buffer, len);
-
- mLatestSetParameters.dump(fd, args);
-
- const char *enddump = "\n\n";
- write(fd, enddump, strlen(enddump));
-
- sp<CameraHardwareInterface> hardware = mHardware;
- if (hardware != nullptr) {
- return hardware->dump(fd, args);
- }
- ALOGI("%s: camera device closed already, skip dumping", __FUNCTION__);
- return OK;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t CameraClient::checkPid() const {
- int callingPid = CameraThreadState::getCallingPid();
- if (callingPid == mClientPid) return NO_ERROR;
-
- ALOGW("attempt to use a locked camera from a different process"
- " (old pid %d, new pid %d)", mClientPid, callingPid);
- return EBUSY;
-}
-
-status_t CameraClient::checkPidAndHardware() const {
- if (mHardware == 0) {
- ALOGE("attempt to use a camera after disconnect() (pid %d)",
- CameraThreadState::getCallingPid());
- return INVALID_OPERATION;
- }
- status_t result = checkPid();
- if (result != NO_ERROR) return result;
- return NO_ERROR;
-}
-
-status_t CameraClient::lock() {
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("lock (pid %d)", callingPid);
- Mutex::Autolock lock(mLock);
-
- // lock camera to this client if the the camera is unlocked
- if (mClientPid == 0) {
- mClientPid = callingPid;
- return NO_ERROR;
- }
-
- // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
- return checkPid();
-}
-
-status_t CameraClient::unlock() {
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("unlock (pid %d)", callingPid);
- Mutex::Autolock lock(mLock);
-
- // allow anyone to use camera (after they lock the camera)
- status_t result = checkPid();
- if (result == NO_ERROR) {
- if (mHardware->recordingEnabled()) {
- ALOGE("Not allowed to unlock camera during recording.");
- return INVALID_OPERATION;
- }
- mClientPid = 0;
- LOG1("clear mRemoteCallback (pid %d)", callingPid);
- // we need to remove the reference to ICameraClient so that when the app
- // goes away, the reference count goes to 0.
- mRemoteCallback.clear();
- }
- return result;
-}
-
-// connect a new client to the camera
-status_t CameraClient::connect(const sp<hardware::ICameraClient>& client) {
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("connect E (pid %d)", callingPid);
- Mutex::Autolock lock(mLock);
-
- if (mClientPid != 0 && checkPid() != NO_ERROR) {
- ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
- mClientPid, callingPid);
- return EBUSY;
- }
-
- if (mRemoteCallback != 0 &&
- (IInterface::asBinder(client) == IInterface::asBinder(mRemoteCallback))) {
- LOG1("Connect to the same client");
- return NO_ERROR;
- }
-
- mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
- mClientPid = callingPid;
- mRemoteCallback = client;
-
- LOG1("connect X (pid %d)", callingPid);
- return NO_ERROR;
-}
-
-static void disconnectWindow(const sp<ANativeWindow>& window) {
- if (window != 0) {
- status_t result = native_window_api_disconnect(window.get(),
- NATIVE_WINDOW_API_CAMERA);
- if (result != NO_ERROR) {
- ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
- result);
- }
- }
-}
-
-binder::Status CameraClient::disconnect() {
- int callingPid = CameraThreadState::getCallingPid();
- LOG1("disconnect E (pid %d)", callingPid);
- Mutex::Autolock lock(mLock);
-
- binder::Status res = binder::Status::ok();
- // Allow both client and the cameraserver to disconnect at all times
- if (callingPid != mClientPid && callingPid != mServicePid) {
- ALOGW("different client - don't disconnect");
- return res;
- }
-
- // Make sure disconnect() is done once and once only, whether it is called
- // from the user directly, or called by the destructor.
- if (mHardware == 0) return res;
-
- LOG1("hardware teardown");
- // Before destroying mHardware, we must make sure it's in the
- // idle state.
- // Turn off all messages.
- disableMsgType(CAMERA_MSG_ALL_MSGS);
- mHardware->stopPreview();
- sCameraService->updateProxyDeviceState(
- hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName,
- hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
- mHardware->cancelPicture();
- // Release the hardware resources.
- mHardware->release();
-
- // Release the held ANativeWindow resources.
- if (mPreviewWindow != 0) {
- disconnectWindow(mPreviewWindow);
- mPreviewWindow = 0;
- mHardware->setPreviewWindow(mPreviewWindow);
- }
- mHardware.clear();
-
- CameraService::Client::disconnect();
-
- LOG1("disconnect X (pid %d)", callingPid);
-
- return res;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder,
- const sp<ANativeWindow>& window) {
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- // return if no change in surface.
- if (binder == mSurface) {
- return NO_ERROR;
- }
-
- if (window != 0) {
- result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
- if (result != NO_ERROR) {
- ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
- result);
- return result;
- }
- }
-
- // If preview has been already started, register preview buffers now.
- if (mHardware->previewEnabled()) {
- if (window != 0) {
- mHardware->setPreviewScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- mHardware->setPreviewTransform(mOrientation);
- result = mHardware->setPreviewWindow(window);
- }
- }
-
- if (result == NO_ERROR) {
- // Everything has succeeded. Disconnect the old window and remember the
- // new window.
- disconnectWindow(mPreviewWindow);
- mSurface = binder;
- mPreviewWindow = window;
- } else {
- // Something went wrong after we connected to the new window, so
- // disconnect here.
- disconnectWindow(window);
- }
-
- return result;
-}
-
-// set the buffer consumer that the preview will use
-status_t CameraClient::setPreviewTarget(
- const sp<IGraphicBufferProducer>& bufferProducer) {
- LOG1("setPreviewTarget(%p) (pid %d)", bufferProducer.get(),
- CameraThreadState::getCallingPid());
-
- sp<IBinder> binder;
- sp<ANativeWindow> window;
- if (bufferProducer != 0) {
- binder = IInterface::asBinder(bufferProducer);
- // Using controlledByApp flag to ensure that the buffer queue remains in
- // async mode for the old camera API, where many applications depend
- // on that behavior.
- window = new Surface(bufferProducer, /*controlledByApp*/ true);
- }
- return setPreviewWindow(binder, window);
-}
-
-// set the preview callback flag to affect how the received frames from
-// preview are handled.
-void CameraClient::setPreviewCallbackFlag(int callback_flag) {
- LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, CameraThreadState::getCallingPid());
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return;
-
- mPreviewCallbackFlag = callback_flag;
- if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
- enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- } else {
- disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- }
-}
-
-status_t CameraClient::setPreviewCallbackTarget(
- const sp<IGraphicBufferProducer>& callbackProducer) {
- (void)callbackProducer;
- ALOGE("%s: Unimplemented!", __FUNCTION__);
- return INVALID_OPERATION;
-}
-
-// start preview mode
-status_t CameraClient::startPreview() {
- LOG1("startPreview (pid %d)", CameraThreadState::getCallingPid());
- return startCameraMode(CAMERA_PREVIEW_MODE);
-}
-
-// start recording mode
-status_t CameraClient::startRecording() {
- LOG1("startRecording (pid %d)", CameraThreadState::getCallingPid());
- return startCameraMode(CAMERA_RECORDING_MODE);
-}
-
-// start preview or recording
-status_t CameraClient::startCameraMode(camera_mode mode) {
- LOG1("startCameraMode(%d)", mode);
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- switch(mode) {
- case CAMERA_PREVIEW_MODE:
- if (mSurface == 0 && mPreviewWindow == 0) {
- LOG1("mSurface is not set yet.");
- // still able to start preview in this case.
- }
- return startPreviewMode();
- case CAMERA_RECORDING_MODE:
- if (mSurface == 0 && mPreviewWindow == 0) {
- ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
- return INVALID_OPERATION;
- }
- return startRecordingMode();
- default:
- return UNKNOWN_ERROR;
- }
-}
-
-status_t CameraClient::startPreviewMode() {
- LOG1("startPreviewMode");
- status_t result = NO_ERROR;
-
- // if preview has been enabled, nothing needs to be done
- if (mHardware->previewEnabled()) {
- return NO_ERROR;
- }
-
- if (mPreviewWindow != 0) {
- mHardware->setPreviewScalingMode(
- NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- mHardware->setPreviewTransform(mOrientation);
- }
- mHardware->setPreviewWindow(mPreviewWindow);
- result = mHardware->startPreview();
- if (result == NO_ERROR) {
- sCameraService->updateProxyDeviceState(
- hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
- mCameraIdStr, mCameraFacing, mClientPackageName,
- hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
- }
- return result;
-}
-
-status_t CameraClient::startRecordingMode() {
- LOG1("startRecordingMode");
- status_t result = NO_ERROR;
-
- // if recording has been enabled, nothing needs to be done
- if (mHardware->recordingEnabled()) {
- return NO_ERROR;
- }
-
- // if preview has not been started, start preview first
- if (!mHardware->previewEnabled()) {
- result = startPreviewMode();
- if (result != NO_ERROR) {
- return result;
- }
- }
-
- // start recording mode
- enableMsgType(CAMERA_MSG_VIDEO_FRAME);
- sCameraService->playSound(CameraService::SOUND_RECORDING_START);
- result = mHardware->startRecording();
- if (result != NO_ERROR) {
- ALOGE("mHardware->startRecording() failed with status %d", result);
- }
- return result;
-}
-
-// stop preview mode
-void CameraClient::stopPreview() {
- LOG1("stopPreview (pid %d)", CameraThreadState::getCallingPid());
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return;
-
-
- disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- mHardware->stopPreview();
- sCameraService->updateProxyDeviceState(
- hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName,
- hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
- mPreviewBuffer.clear();
-}
-
-// stop recording mode
-void CameraClient::stopRecording() {
- LOG1("stopRecording (pid %d)", CameraThreadState::getCallingPid());
- {
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return;
-
- disableMsgType(CAMERA_MSG_VIDEO_FRAME);
- mHardware->stopRecording();
- sCameraService->playSound(CameraService::SOUND_RECORDING_STOP);
-
- mPreviewBuffer.clear();
- }
-
- {
- Mutex::Autolock l(mAvailableCallbackBuffersLock);
- if (!mAvailableCallbackBuffers.empty()) {
- mAvailableCallbackBuffers.clear();
- }
- }
-}
-
-// release a recording frame
-void CameraClient::releaseRecordingFrame(const sp<IMemory>& mem) {
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return;
- if (mem == nullptr) {
- android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26164272",
- CameraThreadState::getCallingUid(), nullptr, 0);
- return;
- }
-
- mHardware->releaseRecordingFrame(mem);
-}
-
-void CameraClient::releaseRecordingFrameHandle(native_handle_t *handle) {
- if (handle == nullptr) return;
- Mutex::Autolock lock(mLock);
- sp<IMemory> dataPtr;
- {
- Mutex::Autolock l(mAvailableCallbackBuffersLock);
- if (!mAvailableCallbackBuffers.empty()) {
- dataPtr = mAvailableCallbackBuffers.back();
- mAvailableCallbackBuffers.pop_back();
- }
- }
-
- if (dataPtr == nullptr) {
- ALOGE("%s: %d: No callback buffer available. Dropping a native handle.", __FUNCTION__,
- __LINE__);
- native_handle_close(handle);
- native_handle_delete(handle);
- return;
- } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
- ALOGE("%s: %d: Callback buffer size doesn't match VideoNativeHandleMetadata", __FUNCTION__,
- __LINE__);
- native_handle_close(handle);
- native_handle_delete(handle);
- return;
- }
-
- if (mHardware != nullptr) {
- VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
- metadata->eType = kMetadataBufferTypeNativeHandleSource;
- metadata->pHandle = handle;
- mHardware->releaseRecordingFrame(dataPtr);
- }
-}
-
-void CameraClient::releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) {
- Mutex::Autolock lock(mLock);
- bool disconnected = (mHardware == nullptr);
- size_t n = handles.size();
- std::vector<sp<IMemory>> frames;
- if (!disconnected) {
- frames.reserve(n);
- }
- bool error = false;
- for (auto& handle : handles) {
- sp<IMemory> dataPtr;
- {
- Mutex::Autolock l(mAvailableCallbackBuffersLock);
- if (!mAvailableCallbackBuffers.empty()) {
- dataPtr = mAvailableCallbackBuffers.back();
- mAvailableCallbackBuffers.pop_back();
- }
- }
-
- if (dataPtr == nullptr) {
- ALOGE("%s: %d: No callback buffer available. Dropping frames.", __FUNCTION__,
- __LINE__);
- error = true;
- break;
- } else if (dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
- ALOGE("%s: %d: Callback buffer must be VideoNativeHandleMetadata", __FUNCTION__,
- __LINE__);
- error = true;
- break;
- }
-
- if (!disconnected) {
- VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
- metadata->eType = kMetadataBufferTypeNativeHandleSource;
- metadata->pHandle = handle;
- frames.push_back(dataPtr);
- }
- }
-
- if (error) {
- for (auto& handle : handles) {
- native_handle_close(handle);
- native_handle_delete(handle);
- }
- } else if (!disconnected) {
- mHardware->releaseRecordingFrameBatch(frames);
- }
- return;
-}
-
-status_t CameraClient::setVideoBufferMode(int32_t videoBufferMode) {
- LOG1("setVideoBufferMode: %d", videoBufferMode);
- bool enableMetadataInBuffers = false;
-
- if (videoBufferMode == VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA) {
- enableMetadataInBuffers = true;
- } else if (videoBufferMode != VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) {
- ALOGE("%s: %d: videoBufferMode %d is not supported.", __FUNCTION__, __LINE__,
- videoBufferMode);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) {
- return UNKNOWN_ERROR;
- }
-
- return mHardware->storeMetaDataInBuffers(enableMetadataInBuffers);
-}
-
-bool CameraClient::previewEnabled() {
- LOG1("previewEnabled (pid %d)", CameraThreadState::getCallingPid());
-
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return false;
- return mHardware->previewEnabled();
-}
-
-bool CameraClient::recordingEnabled() {
- LOG1("recordingEnabled (pid %d)", CameraThreadState::getCallingPid());
-
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) return false;
- return mHardware->recordingEnabled();
-}
-
-status_t CameraClient::autoFocus() {
- LOG1("autoFocus (pid %d)", CameraThreadState::getCallingPid());
-
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- return mHardware->autoFocus();
-}
-
-status_t CameraClient::cancelAutoFocus() {
- LOG1("cancelAutoFocus (pid %d)", CameraThreadState::getCallingPid());
-
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- return mHardware->cancelAutoFocus();
-}
-
-// take a picture - image is returned in callback
-status_t CameraClient::takePicture(int msgType) {
- LOG1("takePicture (pid %d): 0x%x", CameraThreadState::getCallingPid(), msgType);
-
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
- (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
- ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
- " cannot be both enabled");
- return BAD_VALUE;
- }
-
- // We only accept picture related message types
- // and ignore other types of messages for takePicture().
- int picMsgType = msgType
- & (CAMERA_MSG_SHUTTER |
- CAMERA_MSG_POSTVIEW_FRAME |
- CAMERA_MSG_RAW_IMAGE |
- CAMERA_MSG_RAW_IMAGE_NOTIFY |
- CAMERA_MSG_COMPRESSED_IMAGE);
-
- enableMsgType(picMsgType);
-
- return mHardware->takePicture();
-}
-
-// set preview/capture parameters - key/value pairs
-status_t CameraClient::setParameters(const String8& params) {
- LOG1("setParameters (pid %d) (%s)", CameraThreadState::getCallingPid(), params.string());
-
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- mLatestSetParameters = CameraParameters(params);
- CameraParameters p(params);
- return mHardware->setParameters(p);
-}
-
-// get preview/capture parameters - key/value pairs
-String8 CameraClient::getParameters() const {
- Mutex::Autolock lock(mLock);
- // The camera service can unconditionally get the parameters at all times
- if (CameraThreadState::getCallingPid() != mServicePid && checkPidAndHardware() != NO_ERROR) {
- return String8();
- }
-
- String8 params(mHardware->getParameters().flatten());
- LOG1("getParameters (pid %d) (%s)", CameraThreadState::getCallingPid(), params.string());
- return params;
-}
-
-// enable shutter sound
-status_t CameraClient::enableShutterSound(bool enable) {
- LOG1("enableShutterSound (pid %d)", CameraThreadState::getCallingPid());
-
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- if (enable) {
- mPlayShutterSound = true;
- return OK;
- }
-
- mPlayShutterSound = false;
- return OK;
-}
-
-status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
- LOG1("sendCommand (pid %d)", CameraThreadState::getCallingPid());
- int orientation;
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
- // Mirror the preview if the camera is front-facing.
- orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
- if (orientation == -1) return BAD_VALUE;
-
- if (mOrientation != orientation) {
- mOrientation = orientation;
- if (mPreviewWindow != 0) {
- mHardware->setPreviewTransform(mOrientation);
- }
- }
- return OK;
- } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
- switch (arg1) {
- case 0:
- return enableShutterSound(false);
- case 1:
- return enableShutterSound(true);
- default:
- return BAD_VALUE;
- }
- return OK;
- } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
- sCameraService->playSound(CameraService::SOUND_RECORDING_START);
- } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
- // Silently ignore this command
- return INVALID_OPERATION;
- } else if (cmd == CAMERA_CMD_PING) {
- // If mHardware is 0, checkPidAndHardware will return error.
- return OK;
- }
-
- return mHardware->sendCommand(cmd, arg1, arg2);
-}
-
-// ----------------------------------------------------------------------------
-
-void CameraClient::enableMsgType(int32_t msgType) {
- android_atomic_or(msgType, &mMsgEnabled);
- mHardware->enableMsgType(msgType);
-}
-
-void CameraClient::disableMsgType(int32_t msgType) {
- android_atomic_and(~msgType, &mMsgEnabled);
- mHardware->disableMsgType(msgType);
-}
-
-#define CHECK_MESSAGE_INTERVAL 10 // 10ms
-bool CameraClient::lockIfMessageWanted(int32_t msgType) {
- int sleepCount = 0;
- while (mMsgEnabled & msgType) {
- if (mLock.tryLock() == NO_ERROR) {
- if (sleepCount > 0) {
- LOG1("lockIfMessageWanted(%d): waited for %d ms",
- msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
- }
-
- // If messages are no longer enabled after acquiring lock, release and drop message
- if ((mMsgEnabled & msgType) == 0) {
- mLock.unlock();
- break;
- }
-
- return true;
- }
- if (sleepCount++ == 0) {
- LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
- }
- usleep(CHECK_MESSAGE_INTERVAL * 1000);
- }
- ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
- return false;
-}
-
-sp<CameraClient> CameraClient::getClientFromCookie(void* user) {
- String8 cameraId = String8::format("%d", (int)(intptr_t) user);
- auto clientDescriptor = sCameraService->mActiveClientManager.get(cameraId);
- if (clientDescriptor != nullptr) {
- return sp<CameraClient>{
- static_cast<CameraClient*>(clientDescriptor->getValue().get())};
- }
- return sp<CameraClient>{nullptr};
-}
-
-// Callback messages can be dispatched to internal handlers or pass to our
-// client's callback functions, depending on the message type.
-//
-// notifyCallback:
-// CAMERA_MSG_SHUTTER handleShutter
-// (others) c->notifyCallback
-// dataCallback:
-// CAMERA_MSG_PREVIEW_FRAME handlePreviewData
-// CAMERA_MSG_POSTVIEW_FRAME handlePostview
-// CAMERA_MSG_RAW_IMAGE handleRawPicture
-// CAMERA_MSG_COMPRESSED_IMAGE handleCompressedPicture
-// (others) c->dataCallback
-// dataCallbackTimestamp
-// (others) c->dataCallbackTimestamp
-
-void CameraClient::notifyCallback(int32_t msgType, int32_t ext1,
- int32_t ext2, void* user) {
- LOG2("notifyCallback(%d)", msgType);
-
- sp<CameraClient> client = getClientFromCookie(user);
- if (client.get() == nullptr) return;
-
- if (!client->lockIfMessageWanted(msgType)) return;
-
- switch (msgType) {
- case CAMERA_MSG_SHUTTER:
- // ext1 is the dimension of the yuv picture.
- client->handleShutter();
- break;
- default:
- client->handleGenericNotify(msgType, ext1, ext2);
- break;
- }
-}
-
-void CameraClient::dataCallback(int32_t msgType,
- const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
- LOG2("dataCallback(%d)", msgType);
-
- sp<CameraClient> client = getClientFromCookie(user);
- if (client.get() == nullptr) return;
-
- if (!client->lockIfMessageWanted(msgType)) return;
- if (dataPtr == 0 && metadata == NULL) {
- ALOGE("Null data returned in data callback");
- client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
- return;
- }
-
- switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
- case CAMERA_MSG_PREVIEW_FRAME:
- client->handlePreviewData(msgType, dataPtr, metadata);
- break;
- case CAMERA_MSG_POSTVIEW_FRAME:
- client->handlePostview(dataPtr);
- break;
- case CAMERA_MSG_RAW_IMAGE:
- client->handleRawPicture(dataPtr);
- break;
- case CAMERA_MSG_COMPRESSED_IMAGE:
- client->handleCompressedPicture(dataPtr);
- break;
- default:
- client->handleGenericData(msgType, dataPtr, metadata);
- break;
- }
-}
-
-void CameraClient::dataCallbackTimestamp(nsecs_t timestamp,
- int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
- LOG2("dataCallbackTimestamp(%d)", msgType);
-
- sp<CameraClient> client = getClientFromCookie(user);
- if (client.get() == nullptr) return;
-
- if (!client->lockIfMessageWanted(msgType)) return;
-
- if (dataPtr == 0) {
- ALOGE("Null data returned in data with timestamp callback");
- client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
- return;
- }
-
- client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
-}
-
-void CameraClient::handleCallbackTimestampBatch(
- int32_t msgType, const std::vector<HandleTimestampMessage>& msgs, void* user) {
- LOG2("dataCallbackTimestampBatch");
- sp<CameraClient> client = getClientFromCookie(user);
- if (client.get() == nullptr) return;
- if (!client->lockIfMessageWanted(msgType)) return;
-
- sp<hardware::ICameraClient> c = client->mRemoteCallback;
- client->mLock.unlock();
- if (c != 0 && msgs.size() > 0) {
- size_t n = msgs.size();
- std::vector<nsecs_t> timestamps;
- std::vector<native_handle_t*> handles;
- timestamps.reserve(n);
- handles.reserve(n);
- for (auto& msg : msgs) {
- native_handle_t* handle = nullptr;
- if (msg.dataPtr->size() != sizeof(VideoNativeHandleMetadata)) {
- ALOGE("%s: dataPtr does not contain VideoNativeHandleMetadata!", __FUNCTION__);
- return;
- }
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata *metadata =
- (VideoNativeHandleMetadata*)(msg.dataPtr->unsecurePointer());
- if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
- handle = metadata->pHandle;
- }
-
- if (handle == nullptr) {
- ALOGE("%s: VideoNativeHandleMetadata type mismatch or null handle passed!",
- __FUNCTION__);
- return;
- }
- {
- Mutex::Autolock l(client->mAvailableCallbackBuffersLock);
- client->mAvailableCallbackBuffers.push_back(msg.dataPtr);
- }
- timestamps.push_back(msg.timestamp);
- handles.push_back(handle);
- }
- c->recordingFrameHandleCallbackTimestampBatch(timestamps, handles);
- }
-}
-
-// snapshot taken callback
-void CameraClient::handleShutter(void) {
- if (mPlayShutterSound) {
- sCameraService->playSound(CameraService::SOUND_SHUTTER);
- }
-
- sp<hardware::ICameraClient> c = mRemoteCallback;
- if (c != 0) {
- mLock.unlock();
- c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
- if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
- }
- disableMsgType(CAMERA_MSG_SHUTTER);
-
- // Shutters only happen in response to takePicture, so mark device as
- // idle now, until preview is restarted
- sCameraService->updateProxyDeviceState(
- hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
- mCameraIdStr, mCameraFacing, mClientPackageName,
- hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
-
- mLock.unlock();
-}
-
-// preview callback - frame buffer update
-void CameraClient::handlePreviewData(int32_t msgType,
- const sp<IMemory>& mem,
- camera_frame_metadata_t *metadata) {
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-
- // local copy of the callback flags
- int flags = mPreviewCallbackFlag;
-
- // is callback enabled?
- if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
- // If the enable bit is off, the copy-out and one-shot bits are ignored
- LOG2("frame callback is disabled");
- mLock.unlock();
- return;
- }
-
- // hold a strong pointer to the client
- sp<hardware::ICameraClient> c = mRemoteCallback;
-
- // clear callback flags if no client or one-shot mode
- if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
- LOG2("Disable preview callback");
- mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
- CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
- CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
- disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- }
-
- if (c != 0) {
- // Is the received frame copied out or not?
- if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
- LOG2("frame is copied");
- copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
- } else {
- LOG2("frame is forwarded");
- mLock.unlock();
- c->dataCallback(msgType, mem, metadata);
- }
- } else {
- mLock.unlock();
- }
-}
-
-// picture callback - postview image ready
-void CameraClient::handlePostview(const sp<IMemory>& mem) {
- disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
-
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0) {
- c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
- }
-}
-
-// picture callback - raw image ready
-void CameraClient::handleRawPicture(const sp<IMemory>& mem) {
- disableMsgType(CAMERA_MSG_RAW_IMAGE);
-
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0) {
- c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
- }
-}
-
-// picture callback - compressed picture ready
-void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
- disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
-
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0) {
- c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
- }
-}
-
-
-void CameraClient::handleGenericNotify(int32_t msgType,
- int32_t ext1, int32_t ext2) {
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0) {
- c->notifyCallback(msgType, ext1, ext2);
- }
-}
-
-void CameraClient::handleGenericData(int32_t msgType,
- const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0) {
- c->dataCallback(msgType, dataPtr, metadata);
- }
-}
-
-void CameraClient::handleGenericDataTimestamp(nsecs_t timestamp,
- int32_t msgType, const sp<IMemory>& dataPtr) {
- sp<hardware::ICameraClient> c = mRemoteCallback;
- mLock.unlock();
- if (c != 0 && dataPtr != nullptr) {
- native_handle_t* handle = nullptr;
-
- // Check if dataPtr contains a VideoNativeHandleMetadata.
- if (dataPtr->size() == sizeof(VideoNativeHandleMetadata)) {
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata *metadata =
- (VideoNativeHandleMetadata*)(dataPtr->unsecurePointer());
- if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
- handle = metadata->pHandle;
- }
- }
-
- // If dataPtr contains a native handle, send it via recordingFrameHandleCallbackTimestamp.
- if (handle != nullptr) {
- {
- Mutex::Autolock l(mAvailableCallbackBuffersLock);
- mAvailableCallbackBuffers.push_back(dataPtr);
- }
- c->recordingFrameHandleCallbackTimestamp(timestamp, handle);
- } else {
- c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
- }
- }
-}
-
-void CameraClient::copyFrameAndPostCopiedFrame(
- int32_t msgType, const sp<hardware::ICameraClient>& client,
- const sp<IMemoryHeap>& heap, size_t offset, size_t size,
- camera_frame_metadata_t *metadata) {
- LOG2("copyFrameAndPostCopiedFrame");
- // It is necessary to copy out of pmem before sending this to
- // the callback. For efficiency, reuse the same MemoryHeapBase
- // provided it's big enough. Don't allocate the memory or
- // perform the copy if there's no callback.
- // hold the preview lock while we grab a reference to the preview buffer
- sp<MemoryHeapBase> previewBuffer;
-
- if (mPreviewBuffer == 0) {
- mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
- } else if (size > mPreviewBuffer->virtualSize()) {
- mPreviewBuffer.clear();
- mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
- }
- if (mPreviewBuffer == 0) {
- ALOGE("failed to allocate space for preview buffer");
- mLock.unlock();
- return;
- }
- previewBuffer = mPreviewBuffer;
-
- void* previewBufferBase = previewBuffer->base();
- void* heapBase = heap->base();
-
- if (heapBase == MAP_FAILED) {
- ALOGE("%s: Failed to mmap heap for preview frame.", __FUNCTION__);
- mLock.unlock();
- return;
- } else if (previewBufferBase == MAP_FAILED) {
- ALOGE("%s: Failed to mmap preview buffer for preview frame.", __FUNCTION__);
- mLock.unlock();
- return;
- }
-
- memcpy(previewBufferBase, (uint8_t *) heapBase + offset, size);
-
- sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
- if (frame == 0) {
- ALOGE("failed to allocate space for frame callback");
- mLock.unlock();
- return;
- }
-
- mLock.unlock();
- client->dataCallback(msgType, frame, metadata);
-}
-
-int CameraClient::getOrientation(int degrees, bool mirror) {
- if (!mirror) {
- if (degrees == 0) return 0;
- else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
- else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
- else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
- } else { // Do mirror (horizontal flip)
- if (degrees == 0) { // FLIP_H and ROT_0
- return HAL_TRANSFORM_FLIP_H;
- } else if (degrees == 90) { // FLIP_H and ROT_90
- return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
- } else if (degrees == 180) { // FLIP_H and ROT_180
- return HAL_TRANSFORM_FLIP_V;
- } else if (degrees == 270) { // FLIP_H and ROT_270
- return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
- }
- }
- ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
- return -1;
-}
-
-status_t CameraClient::setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer) {
- (void)bufferProducer;
- ALOGE("%s: %d: CameraClient doesn't support setting a video target.", __FUNCTION__, __LINE__);
- return INVALID_OPERATION;
-}
-
-status_t CameraClient::setAudioRestriction(int mode) {
- if (!isValidAudioRestriction(mode)) {
- ALOGE("%s: invalid audio restriction mode %d", __FUNCTION__, mode);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) {
- return INVALID_OPERATION;
- }
- return BasicClient::setAudioRestriction(mode);
-}
-
-int32_t CameraClient::getGlobalAudioRestriction() {
- Mutex::Autolock lock(mLock);
- if (checkPidAndHardware() != NO_ERROR) {
- return INVALID_OPERATION;
- }
- return BasicClient::getServiceAudioRestriction();
-}
-
-// API1->Device1 does not support this feature
-status_t CameraClient::setRotateAndCropOverride(uint8_t /*rotateAndCrop*/) {
- return OK;
-}
-
-}; // namespace android
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
deleted file mode 100644
index aacb00e..0000000
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_SERVERS_CAMERA_CAMERACLIENT_H
-#define ANDROID_SERVERS_CAMERA_CAMERACLIENT_H
-
-#include "CameraService.h"
-
-namespace android {
-
-class MemoryHeapBase;
-class CameraHardwareInterface;
-
-/**
- * Interface between android.hardware.Camera API and Camera HAL device for version
- * CAMERA_DEVICE_API_VERSION_1_0.
- */
-
-class CameraClient : public CameraService::Client
-{
-public:
- // ICamera interface (see ICamera for details)
- virtual binder::Status disconnect();
- virtual status_t connect(const sp<hardware::ICameraClient>& client);
- virtual status_t lock();
- virtual status_t unlock();
- virtual status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer);
- virtual void setPreviewCallbackFlag(int flag);
- virtual status_t setPreviewCallbackTarget(
- const sp<IGraphicBufferProducer>& callbackProducer);
- virtual status_t startPreview();
- virtual void stopPreview();
- virtual bool previewEnabled();
- virtual status_t setVideoBufferMode(int32_t videoBufferMode);
- virtual status_t startRecording();
- virtual void stopRecording();
- virtual bool recordingEnabled();
- virtual void releaseRecordingFrame(const sp<IMemory>& mem);
- virtual void releaseRecordingFrameHandle(native_handle_t *handle);
- virtual void releaseRecordingFrameHandleBatch(
- const std::vector<native_handle_t*>& handles);
- virtual status_t autoFocus();
- virtual status_t cancelAutoFocus();
- virtual status_t takePicture(int msgType);
- virtual status_t setParameters(const String8& params);
- virtual String8 getParameters() const;
- virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
- virtual status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);
- virtual status_t setAudioRestriction(int mode);
- virtual int32_t getGlobalAudioRestriction();
-
- virtual status_t setRotateAndCropOverride(uint8_t override);
-
- // Interface used by CameraService
- CameraClient(const sp<CameraService>& cameraService,
- const sp<hardware::ICameraClient>& cameraClient,
- const String16& clientPackageName,
- const std::optional<String16>& clientFeatureId,
- int cameraId,
- int cameraFacing,
- int clientPid,
- int clientUid,
- int servicePid);
- ~CameraClient();
-
- virtual status_t initialize(sp<CameraProviderManager> manager,
- const String8& monitorTags) override;
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- virtual status_t dumpClient(int fd, const Vector<String16>& args);
-
-private:
-
- // check whether the calling process matches mClientPid.
- status_t checkPid() const;
- status_t checkPidAndHardware() const; // also check mHardware != 0
-
- // these are internal functions used to set up preview buffers
- status_t registerPreviewBuffers();
-
- // camera operation mode
- enum camera_mode {
- CAMERA_PREVIEW_MODE = 0, // frame automatically released
- CAMERA_RECORDING_MODE = 1, // frame has to be explicitly released by releaseRecordingFrame()
- };
- // these are internal functions used for preview/recording
- status_t startCameraMode(camera_mode mode);
- status_t startPreviewMode();
- status_t startRecordingMode();
-
- // internal function used by sendCommand to enable/disable shutter sound.
- status_t enableShutterSound(bool enable);
-
- static sp<CameraClient> getClientFromCookie(void* user);
-
- // these are static callback functions
- static void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
- static void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
- camera_frame_metadata_t *metadata, void* user);
- static void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
- static void handleCallbackTimestampBatch(
- int32_t msgType, const std::vector<HandleTimestampMessage>&, void* user);
- // handlers for messages
- void handleShutter(void);
- void handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
- camera_frame_metadata_t *metadata);
- void handlePostview(const sp<IMemory>& mem);
- void handleRawPicture(const sp<IMemory>& mem);
- void handleCompressedPicture(const sp<IMemory>& mem);
- void handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
- void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
- camera_frame_metadata_t *metadata);
- void handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
-
- void copyFrameAndPostCopiedFrame(
- int32_t msgType,
- const sp<hardware::ICameraClient>& client,
- const sp<IMemoryHeap>& heap,
- size_t offset, size_t size,
- camera_frame_metadata_t *metadata);
-
- int getOrientation(int orientation, bool mirror);
-
- status_t setPreviewWindow(
- const sp<IBinder>& binder,
- const sp<ANativeWindow>& window);
-
-
- // these are initialized in the constructor.
- sp<CameraHardwareInterface> mHardware; // cleared after disconnect()
- int mPreviewCallbackFlag;
- int mOrientation; // Current display orientation
- bool mPlayShutterSound;
- bool mLegacyMode; // camera2 api legacy mode?
-
- // Ensures atomicity among the public methods
- mutable Mutex mLock;
- // This is a binder of Surface or Surface.
- sp<IBinder> mSurface;
- sp<ANativeWindow> mPreviewWindow;
-
- // If the user want us to return a copy of the preview frame (instead
- // of the original one), we allocate mPreviewBuffer and reuse it if possible.
- sp<MemoryHeapBase> mPreviewBuffer;
-
- // Debugging information
- CameraParameters mLatestSetParameters;
-
- // mAvailableCallbackBuffers stores sp<IMemory> that HAL uses to send VideoNativeHandleMetadata.
- // It will be used to send VideoNativeHandleMetadata back to HAL when camera receives the
- // native handle from releaseRecordingFrameHandle.
- Mutex mAvailableCallbackBuffersLock;
- std::vector<sp<IMemory>> mAvailableCallbackBuffers;
-
- // We need to avoid the deadlock when the incoming command thread and
- // the CameraHardwareInterface callback thread both want to grab mLock.
- // An extra flag is used to tell the callback thread that it should stop
- // trying to deliver the callback messages if the client is not
- // interested in it anymore. For example, if the client is calling
- // stopPreview(), the preview frame messages do not need to be delivered
- // anymore.
-
- // This function takes the same parameter as the enableMsgType() and
- // disableMsgType() functions in CameraHardwareInterface.
- void enableMsgType(int32_t msgType);
- void disableMsgType(int32_t msgType);
- volatile int32_t mMsgEnabled;
-
- // This function keeps trying to grab mLock, or give up if the message
- // is found to be disabled. It returns true if mLock is grabbed.
- bool lockIfMessageWanted(int32_t msgType);
-};
-
-}
-
-#endif
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 32d118d..b17d3d8 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -417,46 +417,6 @@
return mapToStatusT(status);
}
-status_t CameraProviderManager::openSession(const std::string &id,
- const sp<device::V1_0::ICameraDeviceCallback>& callback,
- /*out*/
- sp<device::V1_0::ICameraDevice> *session) {
-
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
-
- auto deviceInfo = findDeviceInfoLocked(id,
- /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
- if (deviceInfo == nullptr) return NAME_NOT_FOUND;
-
- auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
- sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
- if (parentProvider == nullptr) {
- return DEAD_OBJECT;
- }
- const sp<provider::V2_4::ICameraProvider> provider = parentProvider->startProviderInterface();
- if (provider == nullptr) {
- return DEAD_OBJECT;
- }
- saveRef(DeviceMode::CAMERA, id, provider);
-
- auto interface = deviceInfo1->startDeviceInterface<
- CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT>();
- if (interface == nullptr) {
- return DEAD_OBJECT;
- }
- hardware::Return<Status> status = interface->open(callback);
- if (!status.isOk()) {
- removeRef(DeviceMode::CAMERA, id);
- ALOGE("%s: Transaction error opening a session for camera device %s: %s",
- __FUNCTION__, id.c_str(), status.description().c_str());
- return DEAD_OBJECT;
- }
- if (status == Status::OK) {
- *session = interface;
- }
- return mapToStatusT(status);
-}
-
void CameraProviderManager::saveRef(DeviceMode usageType, const std::string &cameraId,
sp<provider::V2_4::ICameraProvider> provider) {
if (!kEnableLazyHal) {
@@ -1537,9 +1497,9 @@
std::unique_ptr<DeviceInfo> deviceInfo;
switch (major) {
case 1:
- deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
- id, minor);
- break;
+ ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:", __FUNCTION__,
+ name.c_str(), major);
+ return BAD_VALUE;
case 3:
deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
id, minor);
@@ -2034,35 +1994,6 @@
}
template<>
-sp<device::V1_0::ICameraDevice>
-CameraProviderManager::ProviderInfo::startDeviceInterface
- <device::V1_0::ICameraDevice>(const std::string &name) {
- Status status;
- sp<device::V1_0::ICameraDevice> cameraInterface;
- hardware::Return<void> ret;
- const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
- if (interface == nullptr) {
- return nullptr;
- }
- ret = interface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
- Status s, sp<device::V1_0::ICameraDevice> interface) {
- status = s;
- cameraInterface = interface;
- });
- if (!ret.isOk()) {
- ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
- __FUNCTION__, name.c_str(), ret.description().c_str());
- return nullptr;
- }
- if (status != Status::OK) {
- ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
- name.c_str(), statusToString(status));
- return nullptr;
- }
- return cameraInterface;
-}
-
-template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::startDeviceInterface
<device::V3_2::ICameraDevice>(const std::string &name) {
@@ -2115,126 +2046,6 @@
return mapToStatusT(s);
}
-CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
- const metadata_vendor_id_t tagId, const std::string &id,
- uint16_t minorVersion,
- const CameraResourceCost& resourceCost,
- sp<ProviderInfo> parentProvider,
- const std::vector<std::string>& publicCameraIds,
- sp<InterfaceT> interface) :
- DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
- publicCameraIds, resourceCost, parentProvider) {
- // Get default parameters and initialize flash unit availability
- // Requires powering on the camera device
- hardware::Return<Status> status = interface->open(nullptr);
- if (!status.isOk()) {
- ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
- __FUNCTION__, id.c_str(), status.description().c_str());
- return;
- }
- if (status != Status::OK) {
- ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
- id.c_str(), CameraProviderManager::statusToString(status));
- return;
- }
- hardware::Return<void> ret;
- ret = interface->getParameters([this](const hardware::hidl_string& parms) {
- mDefaultParameters.unflatten(String8(parms.c_str()));
- });
- if (!ret.isOk()) {
- ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
- __FUNCTION__, id.c_str(), status.description().c_str());
- return;
- }
- const char *flashMode =
- mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
- if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
- mHasFlashUnit = true;
- }
-
- status_t res = cacheCameraInfo(interface);
- if (res != OK) {
- ALOGE("%s: Could not cache CameraInfo", __FUNCTION__);
- return;
- }
-
- ret = interface->close();
- if (!ret.isOk()) {
- ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
- __FUNCTION__, id.c_str(), status.description().c_str());
- }
-
- if (!kEnableLazyHal) {
- // Save HAL reference indefinitely
- mSavedInterface = interface;
- }
-}
-
-CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
-
-status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
- return setTorchModeForDevice<InterfaceT>(enabled);
-}
-
-status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
- hardware::CameraInfo *info) const {
- if (info == nullptr) return BAD_VALUE;
- *info = mInfo;
- return OK;
-}
-
-status_t CameraProviderManager::ProviderInfo::DeviceInfo1::cacheCameraInfo(
- sp<CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT> interface) {
- Status status;
- device::V1_0::CameraInfo cInfo;
- hardware::Return<void> ret;
- ret = interface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
- status = s;
- cInfo = camInfo;
- });
- if (!ret.isOk()) {
- ALOGE("%s: Transaction error reading camera info from device %s: %s",
- __FUNCTION__, mId.c_str(), ret.description().c_str());
- return DEAD_OBJECT;
- }
- if (status != Status::OK) {
- return mapToStatusT(status);
- }
-
- switch(cInfo.facing) {
- case device::V1_0::CameraFacing::BACK:
- mInfo.facing = hardware::CAMERA_FACING_BACK;
- break;
- case device::V1_0::CameraFacing::EXTERNAL:
- // Map external to front for legacy API
- case device::V1_0::CameraFacing::FRONT:
- mInfo.facing = hardware::CAMERA_FACING_FRONT;
- break;
- default:
- ALOGW("%s: Device %s: Unknown camera facing: %d",
- __FUNCTION__, mId.c_str(), cInfo.facing);
- mInfo.facing = hardware::CAMERA_FACING_BACK;
- }
- mInfo.orientation = cInfo.orientation;
-
- return OK;
-}
-
-status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) {
- native_handle_t* handle = native_handle_create(1,0);
- handle->data[0] = fd;
- const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
- if (interface == nullptr) {
- return DEAD_OBJECT;
- }
- hardware::Return<Status> s = interface->dumpState(handle);
- native_handle_delete(handle);
- if (!s.isOk()) {
- return INVALID_OPERATION;
- }
- return mapToStatusT(s);
-}
-
CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
const metadata_vendor_id_t tagId, const std::string &id,
uint16_t minorVersion,
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 25d3639..20ca319 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -269,11 +269,6 @@
/*out*/
sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session);
- status_t openSession(const std::string &id,
- const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
- /*out*/
- sp<hardware::camera::device::V1_0::ICameraDevice> *session);
-
/**
* Save the ICameraProvider while it is being used by a camera or torch client
*/
@@ -513,27 +508,6 @@
// physical camera IDs.
std::vector<std::string> mProviderPublicCameraIds;
- // HALv1-specific camera fields, including the actual device interface
- struct DeviceInfo1 : public DeviceInfo {
- typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT;
-
- virtual status_t setTorchMode(bool enabled) override;
- virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
- //In case of Device1Info assume that we are always API1 compatible
- virtual bool isAPI1Compatible() const override { return true; }
- virtual status_t dumpState(int fd) override;
- DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId,
- const std::string &id, uint16_t minorVersion,
- const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
- sp<ProviderInfo> parentProvider,
- const std::vector<std::string>& publicCameraIds,
- sp<InterfaceT> interface);
- virtual ~DeviceInfo1();
- private:
- CameraParameters2 mDefaultParameters;
- status_t cacheCameraInfo(sp<InterfaceT> interface);
- };
-
// HALv3-specific camera fields, including the actual device interface
struct DeviceInfo3 : public DeviceInfo {
typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
deleted file mode 100644
index 62ef681..0000000
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "CameraHardwareInterface"
-//#define LOG_NDEBUG 0
-
-#include <inttypes.h>
-#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
-#include "CameraHardwareInterface.h"
-
-namespace android {
-
-using namespace hardware::camera::device::V1_0;
-using namespace hardware::camera::common::V1_0;
-using hardware::hidl_handle;
-
-CameraHardwareInterface::~CameraHardwareInterface()
-{
- ALOGI("Destroying camera %s", mName.string());
- if (mHidlDevice != nullptr) {
- mHidlDevice->close();
- mHidlDevice.clear();
- cleanupCirculatingBuffers();
- }
-}
-
-status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
- ALOGI("Opening camera %s", mName.string());
-
- status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
- if (ret != OK) {
- ALOGE("%s: openSession failed! %s (%d)", __FUNCTION__, strerror(-ret), ret);
- }
- return ret;
-}
-
-status_t CameraHardwareInterface::setPreviewScalingMode(int scalingMode)
-{
- int rc = OK;
- mPreviewScalingMode = scalingMode;
- if (mPreviewWindow != nullptr) {
- rc = native_window_set_scaling_mode(mPreviewWindow.get(),
- scalingMode);
- }
- return rc;
-}
-
-status_t CameraHardwareInterface::setPreviewTransform(int transform) {
- int rc = OK;
- mPreviewTransform = transform;
- if (mPreviewWindow != nullptr) {
- rc = native_window_set_buffers_transform(mPreviewWindow.get(),
- mPreviewTransform);
- }
- return rc;
-}
-
-/**
- * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
- */
-hardware::Return<void> CameraHardwareInterface::notifyCallback(
- NotifyCallbackMsg msgType, int32_t ext1, int32_t ext2) {
- sNotifyCb((int32_t) msgType, ext1, ext2, (void*) this);
- return hardware::Void();
-}
-
-hardware::Return<uint32_t> CameraHardwareInterface::registerMemory(
- const hardware::hidl_handle& descriptor,
- uint32_t bufferSize, uint32_t bufferCount) {
- if (descriptor->numFds != 1) {
- ALOGE("%s: camera memory descriptor has numFds %d (expect 1)",
- __FUNCTION__, descriptor->numFds);
- return 0;
- }
- if (descriptor->data[0] < 0) {
- ALOGE("%s: camera memory descriptor has FD %d (expect >= 0)",
- __FUNCTION__, descriptor->data[0]);
- return 0;
- }
-
- camera_memory_t* mem = sGetMemory(descriptor->data[0], bufferSize, bufferCount, this);
- sp<CameraHeapMemory> camMem(static_cast<CameraHeapMemory *>(mem->handle));
- int memPoolId = camMem->mHeap->getHeapID();
- if (memPoolId < 0) {
- ALOGE("%s: CameraHeapMemory has FD %d (expect >= 0)", __FUNCTION__, memPoolId);
- return 0;
- }
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
- return memPoolId;
-}
-
-hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
- camera_memory_t* mem = nullptr;
- {
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- if (mHidlMemPoolMap.count(memId) == 0) {
- ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
- return hardware::Void();
- }
- mem = mHidlMemPoolMap.at(memId);
- mHidlMemPoolMap.erase(memId);
- }
- sPutMemory(mem);
- return hardware::Void();
-}
-
-hardware::Return<void> CameraHardwareInterface::dataCallback(
- DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
- const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
- camera_memory_t* mem = nullptr;
- {
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- if (mHidlMemPoolMap.count(data) == 0) {
- ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
- return hardware::Void();
- }
- mem = mHidlMemPoolMap.at(data);
- }
- camera_frame_metadata_t md;
- md.number_of_faces = metadata.faces.size();
- md.faces = (camera_face_t*) metadata.faces.data();
- sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
- return hardware::Void();
-}
-
-hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
- DataCallbackMsg msgType, uint32_t data,
- uint32_t bufferIndex, int64_t timestamp) {
- camera_memory_t* mem = nullptr;
- {
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- if (mHidlMemPoolMap.count(data) == 0) {
- ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
- return hardware::Void();
- }
- mem = mHidlMemPoolMap.at(data);
- }
- sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
- return hardware::Void();
-}
-
-hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
- DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
- uint32_t bufferIndex, int64_t timestamp) {
- camera_memory_t* mem = nullptr;
- {
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- if (mHidlMemPoolMap.count(data) == 0) {
- ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
- return hardware::Void();
- }
- mem = mHidlMemPoolMap.at(data);
- }
- sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle));
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
- heapMem->mBuffers[bufferIndex]->unsecurePointer();
- md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
- sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
- return hardware::Void();
-}
-
-hardware::Return<void> CameraHardwareInterface::handleCallbackTimestampBatch(
- DataCallbackMsg msgType,
- const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
- std::vector<android::HandleTimestampMessage> msgs;
- msgs.reserve(messages.size());
- {
- std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
- for (const auto& hidl_msg : messages) {
- if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
- ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
- return hardware::Void();
- }
- sp<CameraHeapMemory> mem(
- static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
-
- if (hidl_msg.bufferIndex >= mem->mNumBufs) {
- ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
- hidl_msg.bufferIndex, mem->mNumBufs);
- return hardware::Void();
- }
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
- mem->mBuffers[hidl_msg.bufferIndex]->unsecurePointer();
- md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
-
- msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
- }
- }
- mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
- return hardware::Void();
-}
-
-std::pair<bool, uint64_t> CameraHardwareInterface::getBufferId(
- ANativeWindowBuffer* anb) {
- std::lock_guard<std::mutex> lock(mBufferIdMapLock);
-
- buffer_handle_t& buf = anb->handle;
- auto it = mBufferIdMap.find(buf);
- if (it == mBufferIdMap.end()) {
- uint64_t bufId = mNextBufferId++;
- mBufferIdMap[buf] = bufId;
- mReversedBufMap[bufId] = anb;
- return std::make_pair(true, bufId);
- } else {
- return std::make_pair(false, it->second);
- }
-}
-
-void CameraHardwareInterface::cleanupCirculatingBuffers() {
- std::lock_guard<std::mutex> lock(mBufferIdMapLock);
- mBufferIdMap.clear();
- mReversedBufMap.clear();
-}
-
-hardware::Return<void>
-CameraHardwareInterface::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return hardware::Void();
- }
- ANativeWindowBuffer* anb;
- int rc = native_window_dequeue_buffer_and_wait(a, &anb);
- Status s = Status::INTERNAL_ERROR;
- uint64_t bufferId = 0;
- uint32_t stride = 0;
- hidl_handle buf = nullptr;
- if (rc == OK) {
- s = Status::OK;
- auto pair = getBufferId(anb);
- buf = (pair.first) ? anb->handle : nullptr;
- bufferId = pair.second;
- stride = anb->stride;
- }
-
- _hidl_cb(s, bufferId, buf, stride);
- return hardware::Void();
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::enqueueBuffer(uint64_t bufferId) {
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return Status::INTERNAL_ERROR;
- }
- if (mReversedBufMap.count(bufferId) == 0) {
- ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
- return Status::ILLEGAL_ARGUMENT;
- }
- int rc = a->queueBuffer(a, mReversedBufMap.at(bufferId), -1);
- if (rc == 0) {
- return Status::OK;
- }
- return Status::INTERNAL_ERROR;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::cancelBuffer(uint64_t bufferId) {
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return Status::INTERNAL_ERROR;
- }
- if (mReversedBufMap.count(bufferId) == 0) {
- ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
- return Status::ILLEGAL_ARGUMENT;
- }
- int rc = a->cancelBuffer(a, mReversedBufMap.at(bufferId), -1);
- if (rc == 0) {
- return Status::OK;
- }
- return Status::INTERNAL_ERROR;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setBufferCount(uint32_t count) {
- ANativeWindow *a = mPreviewWindow.get();
- if (a != nullptr) {
- // Workaround for b/27039775
- // Previously, setting the buffer count would reset the buffer
- // queue's flag that allows for all buffers to be dequeued on the
- // producer side, instead of just the producer's declared max count,
- // if no filled buffers have yet been queued by the producer. This
- // reset no longer happens, but some HALs depend on this behavior,
- // so it needs to be maintained for HAL backwards compatibility.
- // Simulate the prior behavior by disconnecting/reconnecting to the
- // window and setting the values again. This has the drawback of
- // actually causing memory reallocation, which may not have happened
- // in the past.
- native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
- native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
- if (mPreviewScalingMode != NOT_SET) {
- native_window_set_scaling_mode(a, mPreviewScalingMode);
- }
- if (mPreviewTransform != NOT_SET) {
- native_window_set_buffers_transform(a, mPreviewTransform);
- }
- if (mPreviewWidth != NOT_SET) {
- native_window_set_buffers_dimensions(a,
- mPreviewWidth, mPreviewHeight);
- native_window_set_buffers_format(a, mPreviewFormat);
- }
- if (mPreviewUsage != 0) {
- native_window_set_usage(a, mPreviewUsage);
- }
- if (mPreviewSwapInterval != NOT_SET) {
- a->setSwapInterval(a, mPreviewSwapInterval);
- }
- if (mPreviewCrop.left != NOT_SET) {
- native_window_set_crop(a, &(mPreviewCrop));
- }
- }
- int rc = native_window_set_buffer_count(a, count);
- if (rc == OK) {
- cleanupCirculatingBuffers();
- return Status::OK;
- }
- return Status::INTERNAL_ERROR;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setBuffersGeometry(
- uint32_t w, uint32_t h, hardware::graphics::common::V1_0::PixelFormat format) {
- Status s = Status::INTERNAL_ERROR;
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return s;
- }
- mPreviewWidth = w;
- mPreviewHeight = h;
- mPreviewFormat = (int) format;
- int rc = native_window_set_buffers_dimensions(a, w, h);
- if (rc == OK) {
- rc = native_window_set_buffers_format(a, mPreviewFormat);
- }
- if (rc == OK) {
- cleanupCirculatingBuffers();
- s = Status::OK;
- }
- return s;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) {
- Status s = Status::INTERNAL_ERROR;
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return s;
- }
- mPreviewCrop.left = left;
- mPreviewCrop.top = top;
- mPreviewCrop.right = right;
- mPreviewCrop.bottom = bottom;
- int rc = native_window_set_crop(a, &mPreviewCrop);
- if (rc == OK) {
- s = Status::OK;
- }
- return s;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setUsage(hardware::graphics::common::V1_0::BufferUsage usage) {
- Status s = Status::INTERNAL_ERROR;
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return s;
- }
- mPreviewUsage = static_cast<uint64_t> (usage);
- int rc = native_window_set_usage(a, mPreviewUsage);
- if (rc == OK) {
- cleanupCirculatingBuffers();
- s = Status::OK;
- }
- return s;
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setSwapInterval(int32_t interval) {
- Status s = Status::INTERNAL_ERROR;
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return s;
- }
- mPreviewSwapInterval = interval;
- int rc = a->setSwapInterval(a, interval);
- if (rc == OK) {
- s = Status::OK;
- }
- return s;
-}
-
-hardware::Return<void>
-CameraHardwareInterface::getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb) {
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return hardware::Void();
- }
- int count = 0;
- int rc = a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
- Status s = Status::INTERNAL_ERROR;
- if (rc == OK) {
- s = Status::OK;
- }
- _hidl_cb(s, count);
- return hardware::Void();
-}
-
-hardware::Return<Status>
-CameraHardwareInterface::setTimestamp(int64_t timestamp) {
- Status s = Status::INTERNAL_ERROR;
- ANativeWindow *a = mPreviewWindow.get();
- if (a == nullptr) {
- ALOGE("%s: preview window is null", __FUNCTION__);
- return s;
- }
- int rc = native_window_set_buffers_timestamp(a, timestamp);
- if (rc == OK) {
- s = Status::OK;
- }
- return s;
-}
-
-status_t CameraHardwareInterface::setPreviewWindow(const sp<ANativeWindow>& buf)
-{
- ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mPreviewWindow = buf;
- if (buf != nullptr) {
- if (mPreviewScalingMode != NOT_SET) {
- setPreviewScalingMode(mPreviewScalingMode);
- }
- if (mPreviewTransform != NOT_SET) {
- setPreviewTransform(mPreviewTransform);
- }
- }
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->setPreviewWindow(buf.get() ? this : nullptr));
- }
- return INVALID_OPERATION;
-}
-
-void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
- data_callback_timestamp_batch data_cb_timestamp_batch,
- void* user)
-{
- mNotifyCb = notify_cb;
- mDataCb = data_cb;
- mDataCbTimestamp = data_cb_timestamp;
- mDataCbTimestampBatch = data_cb_timestamp_batch;
- mCbUser = user;
-
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
-}
-
-void CameraHardwareInterface::enableMsgType(int32_t msgType)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mHidlDevice->enableMsgType(msgType);
- }
-}
-
-void CameraHardwareInterface::disableMsgType(int32_t msgType)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mHidlDevice->disableMsgType(msgType);
- }
-}
-
-int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return mHidlDevice->msgTypeEnabled(msgType);
- }
- return false;
-}
-
-status_t CameraHardwareInterface::startPreview()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->startPreview());
- }
- return INVALID_OPERATION;
-}
-
-void CameraHardwareInterface::stopPreview()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mHidlDevice->stopPreview();
- }
-}
-
-int CameraHardwareInterface::previewEnabled()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return mHidlDevice->previewEnabled();
- }
- return false;
-}
-
-status_t CameraHardwareInterface::storeMetaDataInBuffers(int enable)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->storeMetaDataInBuffers(enable));
- }
- return enable ? INVALID_OPERATION: OK;
-}
-
-status_t CameraHardwareInterface::startRecording()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->startRecording());
- }
- return INVALID_OPERATION;
-}
-
-/**
- * Stop a previously started recording.
- */
-void CameraHardwareInterface::stopRecording()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mHidlDevice->stopRecording();
- }
-}
-
-/**
- * Returns true if recording is enabled.
- */
-int CameraHardwareInterface::recordingEnabled()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return mHidlDevice->recordingEnabled();
- }
- return false;
-}
-
-void CameraHardwareInterface::releaseRecordingFrame(const sp<IMemory>& mem)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
- int heapId = heap->getHeapID();
- int bufferIndex = offset / size;
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- if (size == sizeof(VideoNativeHandleMetadata)) {
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
- // Caching the handle here because md->pHandle will be subject to HAL's edit
- native_handle_t* nh = md->pHandle;
- hidl_handle frame = nh;
- mHidlDevice->releaseRecordingFrameHandle(heapId, bufferIndex, frame);
- native_handle_close(nh);
- native_handle_delete(nh);
- } else {
- mHidlDevice->releaseRecordingFrame(heapId, bufferIndex);
- }
- }
-}
-
-void CameraHardwareInterface::releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- size_t n = frames.size();
- std::vector<VideoFrameMessage> msgs;
- msgs.reserve(n);
- for (auto& mem : frames) {
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
- if (size == sizeof(VideoNativeHandleMetadata)) {
- uint32_t heapId = heap->getHeapID();
- uint32_t bufferIndex = offset / size;
- // TODO: Using unsecurePointer() has some associated security pitfalls
- // (see declaration for details).
- // Either document why it is safe in this case or address the
- // issue (e.g. by copying).
- VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->unsecurePointer();
- // Caching the handle here because md->pHandle will be subject to HAL's edit
- native_handle_t* nh = md->pHandle;
- VideoFrameMessage msg;
- msgs.push_back({nh, heapId, bufferIndex});
- } else {
- ALOGE("%s only supports VideoNativeHandleMetadata mode", __FUNCTION__);
- return;
- }
- }
- }
-
- mHidlDevice->releaseRecordingFrameHandleBatch(msgs);
-
- for (auto& msg : msgs) {
- native_handle_t* nh = const_cast<native_handle_t*>(msg.frameData.getNativeHandle());
- native_handle_close(nh);
- native_handle_delete(nh);
- }
-}
-
-status_t CameraHardwareInterface::autoFocus()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->autoFocus());
- }
- return INVALID_OPERATION;
-}
-
-status_t CameraHardwareInterface::cancelAutoFocus()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->cancelAutoFocus());
- }
- return INVALID_OPERATION;
-}
-
-status_t CameraHardwareInterface::takePicture()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->takePicture());
- }
- return INVALID_OPERATION;
-}
-
-status_t CameraHardwareInterface::cancelPicture()
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->cancelPicture());
- }
- return INVALID_OPERATION;
-}
-
-status_t CameraHardwareInterface::setParameters(const CameraParameters ¶ms)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->setParameters(params.flatten().string()));
- }
- return INVALID_OPERATION;
-}
-
-CameraParameters CameraHardwareInterface::getParameters() const
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- CameraParameters parms;
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- hardware::hidl_string outParam;
- mHidlDevice->getParameters(
- [&outParam](const auto& outStr) {
- outParam = outStr;
- });
- String8 tmp(outParam.c_str());
- parms.unflatten(tmp);
- }
- return parms;
-}
-
-status_t CameraHardwareInterface::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- return CameraProviderManager::mapToStatusT(
- mHidlDevice->sendCommand((CommandType) cmd, arg1, arg2));
- }
- return INVALID_OPERATION;
-}
-
-/**
- * Release the hardware resources owned by this object. Note that this is
- * *not* done in the destructor.
- */
-void CameraHardwareInterface::release() {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- mHidlDevice->close();
- mHidlDevice.clear();
- }
-}
-
-/**
- * Dump state of the camera hardware
- */
-status_t CameraHardwareInterface::dump(int fd, const Vector<String16>& /*args*/) const
-{
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (CC_LIKELY(mHidlDevice != nullptr)) {
- native_handle_t* handle = native_handle_create(1,0);
- handle->data[0] = fd;
- Status s = mHidlDevice->dumpState(handle);
- native_handle_delete(handle);
- return CameraProviderManager::mapToStatusT(s);
- }
- return OK; // It's fine if the HAL doesn't implement dump()
-}
-
-void CameraHardwareInterface::sNotifyCb(int32_t msg_type, int32_t ext1,
- int32_t ext2, void *user)
-{
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *object =
- static_cast<CameraHardwareInterface *>(user);
- object->mNotifyCb(msg_type, ext1, ext2, object->mCbUser);
-}
-
-void CameraHardwareInterface::sDataCb(int32_t msg_type,
- const camera_memory_t *data, unsigned int index,
- camera_frame_metadata_t *metadata,
- void *user)
-{
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *object =
- static_cast<CameraHardwareInterface *>(user);
- sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
- if (index >= mem->mNumBufs) {
- ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
- index, mem->mNumBufs);
- return;
- }
- object->mDataCb(msg_type, mem->mBuffers[index], metadata, object->mCbUser);
-}
-
-void CameraHardwareInterface::sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
- const camera_memory_t *data, unsigned index,
- void *user)
-{
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *object =
- static_cast<CameraHardwareInterface *>(user);
- // Start refcounting the heap object from here on. When the clients
- // drop all references, it will be destroyed (as well as the enclosed
- // MemoryHeapBase.
- sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
- if (index >= mem->mNumBufs) {
- ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
- index, mem->mNumBufs);
- return;
- }
- object->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], object->mCbUser);
-}
-
-camera_memory_t* CameraHardwareInterface::sGetMemory(
- int fd, size_t buf_size, uint_t num_bufs,
- void *user __attribute__((unused)))
-{
- CameraHeapMemory *mem;
- if (fd < 0) {
- mem = new CameraHeapMemory(buf_size, num_bufs);
- } else {
- mem = new CameraHeapMemory(fd, buf_size, num_bufs);
- }
- mem->incStrong(mem);
- return &mem->handle;
-}
-
-void CameraHardwareInterface::sPutMemory(camera_memory_t *data)
-{
- if (!data) {
- return;
- }
-
- CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
- mem->decStrong(mem);
-}
-
-}; // namespace android
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
deleted file mode 100644
index e519b04..0000000
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-
-#include <unordered_map>
-#include <binder/IMemory.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <utils/RefBase.h>
-#include <ui/GraphicBuffer.h>
-#include <camera/Camera.h>
-#include <camera/CameraParameters.h>
-#include <system/window.h>
-#include <hardware/camera.h>
-
-#include <common/CameraProviderManager.h>
-
-namespace android {
-
-typedef void (*notify_callback)(int32_t msgType,
- int32_t ext1,
- int32_t ext2,
- void* user);
-
-typedef void (*data_callback)(int32_t msgType,
- const sp<IMemory> &dataPtr,
- camera_frame_metadata_t *metadata,
- void* user);
-
-typedef void (*data_callback_timestamp)(nsecs_t timestamp,
- int32_t msgType,
- const sp<IMemory> &dataPtr,
- void *user);
-
-struct HandleTimestampMessage {
- nsecs_t timestamp;
- const sp<IMemory> dataPtr;
-};
-
-typedef void (*data_callback_timestamp_batch)(
- int32_t msgType,
- const std::vector<HandleTimestampMessage>&, void* user);
-
-/**
- * CameraHardwareInterface.h defines the interface to the
- * camera hardware abstraction layer, used for setting and getting
- * parameters, live previewing, and taking pictures. It is used for
- * HAL devices with version CAMERA_DEVICE_API_VERSION_1_0 only.
- *
- * It is a referenced counted interface with RefBase as its base class.
- * CameraService calls openCameraHardware() to retrieve a strong pointer to the
- * instance of this interface and may be called multiple times. The
- * following steps describe a typical sequence:
- *
- * -# After CameraService calls openCameraHardware(), getParameters() and
- * setParameters() are used to initialize the camera instance.
- * -# startPreview() is called.
- *
- * Prior to taking a picture, CameraService often calls autofocus(). When auto
- * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
- * which informs the application whether focusing was successful. The camera instance
- * only sends this message once and it is up to the application to call autoFocus()
- * again if refocusing is desired.
- *
- * CameraService calls takePicture() to request the camera instance take a
- * picture. At this point, if a shutter, postview, raw, and/or compressed
- * callback is desired, the corresponding message must be enabled. Any memory
- * provided in a data callback must be copied if it's needed after returning.
- */
-
-class CameraHardwareInterface :
- public virtual RefBase,
- public virtual hardware::camera::device::V1_0::ICameraDeviceCallback,
- public virtual hardware::camera::device::V1_0::ICameraDevicePreviewCallback {
-
-public:
- explicit CameraHardwareInterface(const char *name):
- mHidlDevice(nullptr),
- mName(name),
- mPreviewScalingMode(NOT_SET),
- mPreviewTransform(NOT_SET),
- mPreviewWidth(NOT_SET),
- mPreviewHeight(NOT_SET),
- mPreviewFormat(NOT_SET),
- mPreviewUsage(0),
- mPreviewSwapInterval(NOT_SET),
- mPreviewCrop{NOT_SET,NOT_SET,NOT_SET,NOT_SET}
- {
- }
-
- ~CameraHardwareInterface();
-
- status_t initialize(sp<CameraProviderManager> manager);
-
- /** Set the ANativeWindow to which preview frames are sent */
- status_t setPreviewWindow(const sp<ANativeWindow>& buf);
-
- status_t setPreviewScalingMode(int scalingMode);
-
- status_t setPreviewTransform(int transform);
-
- /** Set the notification and data callbacks */
- void setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
- data_callback_timestamp_batch data_cb_timestamp_batch,
- void* user);
-
- /**
- * The following three functions all take a msgtype,
- * which is a bitmask of the messages defined in
- * include/ui/Camera.h
- */
-
- /**
- * Enable a message, or set of messages.
- */
- void enableMsgType(int32_t msgType);
-
- /**
- * Disable a message, or a set of messages.
- *
- * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
- * should not rely on its client to call releaseRecordingFrame() to release
- * video recording frames sent out by the cameral hal before and after the
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
- * modify/access any video recording frame after calling
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
- */
- void disableMsgType(int32_t msgType);
-
- /**
- * Query whether a message, or a set of messages, is enabled.
- * Note that this is operates as an AND, if any of the messages
- * queried are off, this will return false.
- */
- int msgTypeEnabled(int32_t msgType);
-
- /**
- * Start preview mode.
- */
- status_t startPreview();
-
- /**
- * Stop a previously started preview.
- */
- void stopPreview();
-
- /**
- * Returns true if preview is enabled.
- */
- int previewEnabled();
-
- /**
- * Request the camera hal to store meta data or real YUV data in
- * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
- * recording session. If it is not called, the default camera
- * hal behavior is to store real YUV data in the video buffers.
- *
- * This method should be called before startRecording() in order
- * to be effective.
- *
- * If meta data is stored in the video buffers, it is up to the
- * receiver of the video buffers to interpret the contents and
- * to find the actual frame data with the help of the meta data
- * in the buffer. How this is done is outside of the scope of
- * this method.
- *
- * Some camera hal may not support storing meta data in the video
- * buffers, but all camera hal should support storing real YUV data
- * in the video buffers. If the camera hal does not support storing
- * the meta data in the video buffers when it is requested to do
- * do, INVALID_OPERATION must be returned. It is very useful for
- * the camera hal to pass meta data rather than the actual frame
- * data directly to the video encoder, since the amount of the
- * uncompressed frame data can be very large if video size is large.
- *
- * @param enable if true to instruct the camera hal to store
- * meta data in the video buffers; false to instruct
- * the camera hal to store real YUV data in the video
- * buffers.
- *
- * @return OK on success.
- */
-
- status_t storeMetaDataInBuffers(int enable);
-
- /**
- * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
- * message is sent with the corresponding frame. Every record frame must be released
- * by a cameral hal client via releaseRecordingFrame() before the client calls
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
- * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
- * to manage the life-cycle of the video recording frames, and the client must
- * not modify/access any video recording frames.
- */
- status_t startRecording();
-
- /**
- * Stop a previously started recording.
- */
- void stopRecording();
-
- /**
- * Returns true if recording is enabled.
- */
- int recordingEnabled();
-
- /**
- * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
- *
- * It is camera hal client's responsibility to release video recording
- * frames sent out by the camera hal before the camera hal receives
- * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
- * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
- * responsibility of managing the life-cycle of the video recording
- * frames.
- */
- void releaseRecordingFrame(const sp<IMemory>& mem);
-
- /**
- * Release a batch of recording frames previously returned by
- * CAMERA_MSG_VIDEO_FRAME. This method only supports frames that are
- * stored as VideoNativeHandleMetadata.
- *
- * It is camera hal client's responsibility to release video recording
- * frames sent out by the camera hal before the camera hal receives
- * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
- * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
- * responsibility of managing the life-cycle of the video recording
- * frames.
- */
- void releaseRecordingFrameBatch(const std::vector<sp<IMemory>>& frames);
-
- /**
- * Start auto focus, the notification callback routine is called
- * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
- * will be called again if another auto focus is needed.
- */
- status_t autoFocus();
-
- /**
- * Cancels auto-focus function. If the auto-focus is still in progress,
- * this function will cancel it. Whether the auto-focus is in progress
- * or not, this function will return the focus position to the default.
- * If the camera does not support auto-focus, this is a no-op.
- */
- status_t cancelAutoFocus();
-
- /**
- * Take a picture.
- */
- status_t takePicture();
-
- /**
- * Cancel a picture that was started with takePicture. Calling this
- * method when no picture is being taken is a no-op.
- */
- status_t cancelPicture();
-
- /**
- * Set the camera parameters. This returns BAD_VALUE if any parameter is
- * invalid or not supported. */
- status_t setParameters(const CameraParameters ¶ms);
-
- /** Return the camera parameters. */
- CameraParameters getParameters() const;
-
- /**
- * Send command to camera driver.
- */
- status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
-
- /**
- * Release the hardware resources owned by this object. Note that this is
- * *not* done in the destructor.
- */
- void release();
-
- /**
- * Dump state of the camera hardware
- */
- status_t dump(int fd, const Vector<String16>& /*args*/) const;
-
-private:
- sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;
- String8 mName;
-
- static void sNotifyCb(int32_t msg_type, int32_t ext1,
- int32_t ext2, void *user);
-
- static void sDataCb(int32_t msg_type,
- const camera_memory_t *data, unsigned int index,
- camera_frame_metadata_t *metadata,
- void *user);
-
- static void sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
- const camera_memory_t *data, unsigned index,
- void *user);
-
- // This is a utility class that combines a MemoryHeapBase and a MemoryBase
- // in one. Since we tend to use them in a one-to-one relationship, this is
- // handy.
- class CameraHeapMemory : public RefBase {
- public:
- CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) :
- mBufSize(buf_size),
- mNumBufs(num_buffers)
- {
- mHeap = new MemoryHeapBase(fd, buf_size * num_buffers);
- commonInitialization();
- }
-
- explicit CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1) :
- mBufSize(buf_size),
- mNumBufs(num_buffers)
- {
- mHeap = new MemoryHeapBase(buf_size * num_buffers);
- commonInitialization();
- }
-
- void commonInitialization()
- {
- handle.data = mHeap->base();
- handle.size = mBufSize * mNumBufs;
- handle.handle = this;
-
- mBuffers = new sp<MemoryBase>[mNumBufs];
- for (uint_t i = 0; i < mNumBufs; i++)
- mBuffers[i] = new MemoryBase(mHeap,
- i * mBufSize,
- mBufSize);
-
- handle.release = sPutMemory;
- }
-
- virtual ~CameraHeapMemory()
- {
- delete [] mBuffers;
- }
-
- size_t mBufSize;
- uint_t mNumBufs;
- sp<MemoryHeapBase> mHeap;
- sp<MemoryBase> *mBuffers;
-
- camera_memory_t handle;
- };
-
- static camera_memory_t* sGetMemory(int fd, size_t buf_size, uint_t num_bufs,
- void *user __attribute__((unused)));
-
- static void sPutMemory(camera_memory_t *data);
-
- std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
- void cleanupCirculatingBuffers();
-
- /**
- * Implementation of android::hardware::camera::device::V1_0::ICameraDeviceCallback
- */
- hardware::Return<void> notifyCallback(
- hardware::camera::device::V1_0::NotifyCallbackMsg msgType,
- int32_t ext1, int32_t ext2) override;
- hardware::Return<uint32_t> registerMemory(
- const hardware::hidl_handle& descriptor,
- uint32_t bufferSize, uint32_t bufferCount) override;
- hardware::Return<void> unregisterMemory(uint32_t memId) override;
- hardware::Return<void> dataCallback(
- hardware::camera::device::V1_0::DataCallbackMsg msgType,
- uint32_t data, uint32_t bufferIndex,
- const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) override;
- hardware::Return<void> dataCallbackTimestamp(
- hardware::camera::device::V1_0::DataCallbackMsg msgType,
- uint32_t data, uint32_t bufferIndex, int64_t timestamp) override;
- hardware::Return<void> handleCallbackTimestamp(
- hardware::camera::device::V1_0::DataCallbackMsg msgType,
- const hardware::hidl_handle& frameData, uint32_t data,
- uint32_t bufferIndex, int64_t timestamp) override;
- hardware::Return<void> handleCallbackTimestampBatch(
- hardware::camera::device::V1_0::DataCallbackMsg msgType,
- const hardware::hidl_vec<
- hardware::camera::device::V1_0::HandleTimestampMessage>&) override;
-
- /**
- * Implementation of android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback
- */
- hardware::Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- enqueueBuffer(uint64_t bufferId) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- cancelBuffer(uint64_t bufferId) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setBufferCount(uint32_t count) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setBuffersGeometry(uint32_t w, uint32_t h,
- hardware::graphics::common::V1_0::PixelFormat format) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setCrop(int32_t left, int32_t top, int32_t right, int32_t bottom) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setUsage(hardware::graphics::common::V1_0::BufferUsage usage) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setSwapInterval(int32_t interval) override;
- hardware::Return<void> getMinUndequeuedBufferCount(
- getMinUndequeuedBufferCount_cb _hidl_cb) override;
- hardware::Return<hardware::camera::common::V1_0::Status>
- setTimestamp(int64_t timestamp) override;
-
- sp<ANativeWindow> mPreviewWindow;
-
- notify_callback mNotifyCb;
- data_callback mDataCb;
- data_callback_timestamp mDataCbTimestamp;
- data_callback_timestamp_batch mDataCbTimestampBatch;
- void *mCbUser;
-
- // Cached values for preview stream parameters
- static const int NOT_SET = -1;
- int mPreviewScalingMode;
- int mPreviewTransform;
- int mPreviewWidth;
- int mPreviewHeight;
- int mPreviewFormat;
- uint64_t mPreviewUsage;
- int mPreviewSwapInterval;
- android_native_rect_t mPreviewCrop;
-
- struct BufferHasher {
- size_t operator()(const buffer_handle_t& buf) const {
- if (buf == nullptr)
- return 0;
-
- size_t result = 1;
- result = 31 * result + buf->numFds;
- result = 31 * result + buf->numInts;
- int length = buf->numFds + buf->numInts;
- for (int i = 0; i < length; i++) {
- result = 31 * result + buf->data[i];
- }
- return result;
- }
- };
-
- struct BufferComparator {
- bool operator()(const buffer_handle_t& buf1, const buffer_handle_t& buf2) const {
- if (buf1->numFds == buf2->numFds && buf1->numInts == buf2->numInts) {
- int length = buf1->numFds + buf1->numInts;
- for (int i = 0; i < length; i++) {
- if (buf1->data[i] != buf2->data[i]) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- };
-
- std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
- typedef std::unordered_map<const buffer_handle_t, uint64_t,
- BufferHasher, BufferComparator> BufferIdMap;
- // stream ID -> per stream buffer ID map
- BufferIdMap mBufferIdMap;
- std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
- uint64_t mNextBufferId = 1;
- static const uint64_t BUFFER_ID_NO_BUFFER = 0;
-
- std::mutex mHidlMemPoolMapLock; // protecting mHidlMemPoolMap
- std::unordered_map<int, camera_memory_t*> mHidlMemPoolMap;
-};
-
-}; // namespace android
-
-#endif
diff --git a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
index 2f4e74b..53fd7ec 100644
--- a/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
+++ b/services/mediatranscoding/tests/MediaTranscodingServiceTestHelper.h
@@ -180,6 +180,18 @@
mCondition.notify_one();
}
+ void updateProgress(int progress) {
+ std::unique_lock lock(mLock);
+ mLastProgress = progress;
+ mUpdateCount++;
+ }
+
+ int getUpdateCount(int *lastProgress) {
+ std::unique_lock lock(mLock);
+ *lastProgress = mLastProgress;
+ return mUpdateCount;
+ }
+
TranscodingErrorCode getLastError() {
std::unique_lock lock(mLock);
return mLastErr;
@@ -191,6 +203,8 @@
Event mPoppedEvent;
std::list<Event> mEventQueue;
TranscodingErrorCode mLastErr;
+ int mUpdateCount = 0;
+ int mLastProgress = -1;
};
// Operators for GTest macros.
@@ -266,7 +280,8 @@
return Status::ok();
}
- Status onProgressUpdate(int32_t /* in_jobId */, int32_t /* in_progress */) override {
+ Status onProgressUpdate(int32_t /* in_jobId */, int32_t in_progress) override {
+ updateProgress(in_progress);
return Status::ok();
}
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp b/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
index c6368a8..0ac03d6 100644
--- a/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
+++ b/services/mediatranscoding/tests/mediatranscodingservice_real_tests.cpp
@@ -100,6 +100,29 @@
unregisterMultipleClients();
}
+TEST_F(MediaTranscodingServiceRealTest, TestTranscodeVideoProgress) {
+ registerMultipleClients();
+
+ const char* dstPath = OUTPATH(TestTranscodeVideoProgress);
+ deleteFile(dstPath);
+
+ // Submit one job.
+ EXPECT_TRUE(
+ submit(mClient1, 0, kLongSrcPath, dstPath, TranscodingJobPriority::kNormal, kBitRate));
+
+ // Wait for job to finish.
+ EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
+ EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
+
+ // Check the progress update messages are received. For this clip (around ~15 second long),
+ // expect at least 10 updates, and the last update should be 100.
+ int lastProgress;
+ EXPECT_GE(mClientCallback1->getUpdateCount(&lastProgress), 10);
+ EXPECT_EQ(lastProgress, 100);
+
+ unregisterMultipleClients();
+}
+
/*
* Test cancel immediately after start.
*/