Merge "stagefright: MPEG4Writer: fix Integer overflow"
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index ad70470..ff5e5d3 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -12,7 +12,6 @@
libjpeg libgui libcutils liblog \
libhidlmemory \
android.hardware.media.omx@1.0 \
- android.hardware.media.omx@1.0-utils \
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index ffa09eb..4d8dd3c 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -65,7 +65,7 @@
#include <gui/SurfaceComposerClient.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
-#include <omx/hal/1.0/utils/WOmx.h>
+#include <media/omx/1.0/WOmx.h>
using namespace android;
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/include/media/omx/1.0/Conversion.h
similarity index 99%
rename from media/libstagefright/omx/hal/1.0/utils/Conversion.h
rename to include/media/omx/1.0/Conversion.h
index c4876ac..ee83713 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/include/media/omx/1.0/Conversion.h
@@ -29,12 +29,12 @@
#include <binder/Binder.h>
#include <binder/Status.h>
#include <ui/FenceTime.h>
-#include <media/OMXFenceParcelable.h>
#include <cutils/native_handle.h>
#include <gui/IGraphicBufferProducer.h>
+#include <media/OMXFenceParcelable.h>
#include <media/OMXBuffer.h>
-#include <VideoAPI.h>
+#include <media/hardware/VideoAPI.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <android/hardware/media/omx/1.0/types.h>
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h b/include/media/omx/1.0/WGraphicBufferSource.h
similarity index 99%
rename from media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
rename to include/media/omx/1.0/WGraphicBufferSource.h
index 1090d52..7c80c2e 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.h
+++ b/include/media/omx/1.0/WGraphicBufferSource.h
@@ -20,8 +20,8 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
-#include <media/IOMX.h>
#include <binder/Binder.h>
+#include <media/IOMX.h>
#include <android/hardware/graphics/common/1.0/types.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.h b/include/media/omx/1.0/WOmx.h
similarity index 97%
rename from media/libstagefright/omx/hal/1.0/utils/WOmx.h
rename to include/media/omx/1.0/WOmx.h
index 7860f46..4aaf470 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.h
+++ b/include/media/omx/1.0/WOmx.h
@@ -20,7 +20,7 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
-#include "../../../../include/OMXNodeInstance.h"
+#include <media/IOMX.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h b/include/media/omx/1.0/WOmxBufferProducer.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.h
rename to include/media/omx/1.0/WOmxBufferProducer.h
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h b/include/media/omx/1.0/WOmxBufferSource.h
similarity index 98%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
rename to include/media/omx/1.0/WOmxBufferSource.h
index 086f648..86322da 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.h
+++ b/include/media/omx/1.0/WOmxBufferSource.h
@@ -21,7 +21,7 @@
#include <hidl/Status.h>
#include <binder/Binder.h>
-#include <media/OMXFenceParcelable.h>
+#include <OMXFenceParcelable.h>
#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
#include <android/BnOMXBufferSource.h>
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h b/include/media/omx/1.0/WOmxNode.h
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
rename to include/media/omx/1.0/WOmxNode.h
index 46dfb49..3176a65 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.h
+++ b/include/media/omx/1.0/WOmxNode.h
@@ -20,9 +20,9 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <binder/HalToken.h>
#include <utils/Errors.h>
-
-#include "../../../../include/OMXNodeInstance.h"
+#include <media/IOMX.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -59,9 +59,8 @@
* - TW = Treble Wrapper --- It wraps a legacy object inside a Treble object.
*/
-struct LWOmxNode : public BnOMXNode {
- sp<IOmxNode> mBase;
- LWOmxNode(sp<IOmxNode> const& base);
+struct LWOmxNode : public H2BConverter<IOmxNode, IOMXNode, BnOMXNode> {
+ LWOmxNode(sp<IOmxNode> const& base) : CBase(base) {}
status_t freeNode() override;
status_t sendCommand(
OMX_COMMANDTYPE cmd, OMX_S32 param) override;
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h b/include/media/omx/1.0/WOmxObserver.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxObserver.h
rename to include/media/omx/1.0/WOmxObserver.h
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h b/include/media/omx/1.0/WOmxProducerListener.h
similarity index 100%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.h
rename to include/media/omx/1.0/WOmxProducerListener.h
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index eac532b..c057cf5 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -55,15 +55,36 @@
OMXBuffer.cpp \
Visualizer.cpp \
StringArray.cpp \
+ omx/1.0/WGraphicBufferSource.cpp \
+ omx/1.0/WOmx.cpp \
+ omx/1.0/WOmxBufferProducer.cpp \
+ omx/1.0/WOmxBufferSource.cpp \
+ omx/1.0/WOmxNode.cpp \
+ omx/1.0/WOmxObserver.cpp \
+ omx/1.0/WOmxProducerListener.cpp \
LOCAL_SHARED_LIBRARIES := \
libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
libcamera_client libstagefright_foundation \
libgui libdl libaudioutils libaudioclient \
libmedia_helper libmediadrm \
+ libbase \
libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libhidlmemory \
+ android.hidl.base@1.0 \
+ android.hidl.memory@1.0 \
+ android.hardware.graphics.common@1.0 \
+ android.hardware.media@1.0 \
+ android.hardware.media.omx@1.0 \
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libsonivox libmediadrm
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ libbinder \
+ libsonivox \
+ libmediadrm \
+ android.hardware.media.omx@1.0 \
+ android.hidl.memory@1.0 \
# for memory heap analysis
LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
@@ -76,8 +97,9 @@
$(TOP)/system/libhidl/base/include \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/frameworks/av/include/media/ \
- $(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/av/media/libmedia/aidl \
+ $(TOP)/frameworks/av/include \
+ $(TOP)/frameworks/native/include \
$(call include-path-for, audio-utils)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 67939b2..223ca6b 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -29,6 +29,7 @@
#include <utils/NativeHandle.h>
#include <gui/IGraphicBufferProducer.h>
+#include <omx/1.0/WOmxNode.h>
#include <android/IGraphicBufferSource.h>
#include <android/IOMXBufferSource.h>
@@ -448,8 +449,115 @@
}
};
+using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
+class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> {
+public:
+ HpOMXNode(const sp<IBinder>& base) : PBase(base) {}
+
+ virtual status_t freeNode() {
+ return mBase->freeNode();
+ }
+
+ virtual status_t sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_S32 param) {
+ return mBase->sendCommand(cmd, param);
+ }
+
+ virtual status_t getParameter(
+ OMX_INDEXTYPE index, void *params, size_t size) {
+ return mBase->getParameter(index, params, size);
+ }
+
+ virtual status_t setParameter(
+ OMX_INDEXTYPE index, const void *params, size_t size) {
+ return mBase->setParameter(index, params, size);
+ }
+
+ virtual status_t getConfig(
+ OMX_INDEXTYPE index, void *params, size_t size) {
+ return mBase->getConfig(index, params, size);
+ }
+
+ virtual status_t setConfig(
+ OMX_INDEXTYPE index, const void *params, size_t size) {
+ return mBase->setConfig(index, params, size);
+ }
+
+ virtual status_t setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) {
+ return mBase->setPortMode(port_index, mode);
+ }
+
+ virtual status_t prepareForAdaptivePlayback(
+ OMX_U32 portIndex, OMX_BOOL enable,
+ OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+ return mBase->prepareForAdaptivePlayback(
+ portIndex, enable, maxFrameWidth, maxFrameHeight);
+ }
+
+ virtual status_t configureVideoTunnelMode(
+ OMX_U32 portIndex, OMX_BOOL tunneled,
+ OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
+ return mBase->configureVideoTunnelMode(
+ portIndex, tunneled, audioHwSync, sidebandHandle);
+ }
+
+ virtual status_t getGraphicBufferUsage(
+ OMX_U32 port_index, OMX_U32* usage) {
+ return mBase->getGraphicBufferUsage(port_index, usage);
+ }
+
+ virtual status_t setInputSurface(
+ const sp<IOMXBufferSource> &bufferSource) {
+ return mBase->setInputSurface(bufferSource);
+ }
+
+ virtual status_t allocateSecureBuffer(
+ OMX_U32 port_index, size_t size, buffer_id *buffer,
+ void **buffer_data, sp<NativeHandle> *native_handle) {
+ return mBase->allocateSecureBuffer(
+ port_index, size, buffer, buffer_data, native_handle);
+ }
+
+ virtual status_t useBuffer(
+ OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
+ return mBase->useBuffer(port_index, omxBuf, buffer);
+ }
+
+ virtual status_t freeBuffer(
+ OMX_U32 port_index, buffer_id buffer) {
+ return mBase->freeBuffer(port_index, buffer);
+ }
+
+ virtual status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) {
+ return mBase->fillBuffer(buffer, omxBuf, fenceFd);
+ }
+
+ virtual status_t emptyBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) {
+ return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
+ }
+
+ virtual status_t getExtensionIndex(
+ const char *parameter_name,
+ OMX_INDEXTYPE *index) {
+ return mBase->getExtensionIndex(parameter_name, index);
+ }
+
+ virtual status_t dispatchMessage(const omx_message &msg) {
+ return mBase->dispatchMessage(msg);
+ }
+
+ // TODO: this is temporary, will be removed when quirks move to OMX side
+ virtual status_t setQuirks(OMX_U32 quirks) {
+ return mBase->setQuirks(quirks);
+ }
+};
+
IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
-IMPLEMENT_META_INTERFACE(OMXNode, "android.hardware.IOMXNode");
+IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
////////////////////////////////////////////////////////////////////////////////
diff --git a/media/libmedia/include/IMediaCodecService.h b/media/libmedia/include/IMediaCodecService.h
index 984a0fd..da3c5a03 100644
--- a/media/libmedia/include/IMediaCodecService.h
+++ b/media/libmedia/include/IMediaCodecService.h
@@ -21,7 +21,7 @@
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/IDataSource.h>
-#include <include/OMX.h>
+#include <media/IOMX.h>
namespace android {
diff --git a/media/libmedia/include/IOMX.h b/media/libmedia/include/IOMX.h
index 39b9ad4..b4fc04c 100644
--- a/media/libmedia/include/IOMX.h
+++ b/media/libmedia/include/IOMX.h
@@ -19,6 +19,7 @@
#define ANDROID_IOMX_H_
#include <binder/IInterface.h>
+#include <binder/HalToken.h>
#include <utils/List.h>
#include <utils/String8.h>
#include <cutils/native_handle.h>
@@ -26,6 +27,7 @@
#include <list>
#include <media/hardware/MetadataBufferType.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <OMX_Core.h>
#include <OMX_Video.h>
@@ -42,6 +44,8 @@
class OMXBuffer;
struct omx_message;
+using hardware::media::omx::V1_0::IOmxNode;
+
class IOMX : public IInterface {
public:
DECLARE_META_INTERFACE(OMX);
@@ -83,7 +87,7 @@
class IOMXNode : public IInterface {
public:
- DECLARE_META_INTERFACE(OMXNode);
+ DECLARE_HYBRID_META_INTERFACE(OMXNode, IOmxNode);
typedef IOMX::buffer_id buffer_id;
diff --git a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
similarity index 93%
rename from media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
rename to media/libmedia/omx/1.0/WGraphicBufferSource.cpp
index 0ba6060..247c540 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WGraphicBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WGraphicBufferSource.cpp
@@ -16,9 +16,9 @@
#include <stagefright/foundation/ColorUtils.h>
-#include "WGraphicBufferSource.h"
-#include "WOmxNode.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
@@ -36,8 +36,10 @@
::android::binder::Status LWGraphicBufferSource::configure(
const sp<IOMXNode>& omxNode, int32_t dataSpace) {
+ sp<IOmxNode> hOmxNode = omxNode->getHalInterface();
return toBinderStatus(mBase->configure(
- new TWOmxNode(omxNode), toHardwareDataspace(dataSpace)));
+ hOmxNode == nullptr ? new TWOmxNode(omxNode) : hOmxNode,
+ toHardwareDataspace(dataSpace)));
}
::android::binder::Status LWGraphicBufferSource::setSuspend(
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp b/media/libmedia/omx/1.0/WOmx.cpp
similarity index 93%
rename from media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
rename to media/libmedia/omx/1.0/WOmx.cpp
index 00f40cd..39871f8 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmx.cpp
+++ b/media/libmedia/omx/1.0/WOmx.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include "WOmx.h"
-#include "WOmxNode.h"
-#include "WOmxObserver.h"
-#include "WOmxBufferProducer.h"
-#include "WGraphicBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmx.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxObserver.h>
+#include <media/omx/1.0/WOmxBufferProducer.h>
+#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp b/media/libmedia/omx/1.0/WOmxBufferProducer.cpp
similarity index 88%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
rename to media/libmedia/omx/1.0/WOmxBufferProducer.cpp
index e9a93b9..03499f2 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferProducer.cpp
+++ b/media/libmedia/omx/1.0/WOmxBufferProducer.cpp
@@ -16,11 +16,11 @@
#define LOG_TAG "WOmxBufferProducer-utils"
-#include <android-base/logging.h>
+#include <utils/Log.h>
-#include "WOmxBufferProducer.h"
-#include "WOmxProducerListener.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxBufferProducer.h>
+#include <media/omx/1.0/WOmxProducerListener.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
@@ -72,8 +72,7 @@
native_handle_t* nh = nullptr;
if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
- LOG(ERROR) << "TWOmxBufferProducer::dequeueBuffer - "
- "Invalid output fence";
+ ALOGE("TWOmxBufferProducer::dequeueBuffer - Invalid output fence");
_hidl_cb(toStatus(status),
static_cast<int32_t>(slot),
tFence,
@@ -82,8 +81,7 @@
}
std::vector<std::vector<native_handle_t*> > nhAA;
if (getFrameTimestamps && !wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
- LOG(ERROR) << "TWOmxBufferProducer::dequeueBuffer - "
- "Invalid output timestamps";
+ ALOGE("TWOmxBufferProducer::dequeueBuffer - Invalid output timestamps");
_hidl_cb(toStatus(status),
static_cast<int32_t>(slot),
tFence,
@@ -120,16 +118,14 @@
hidl_handle tFence;
if (outBuffer == nullptr) {
- LOG(ERROR) << "TWOmxBufferProducer::detachNextBuffer - "
- "Invalid output buffer";
+ ALOGE("TWOmxBufferProducer::detachNextBuffer - Invalid output buffer");
_hidl_cb(toStatus(status), tBuffer, tFence);
return Void();
}
wrapAs(&tBuffer, *outBuffer);
native_handle_t* nh = nullptr;
if ((outFence != nullptr) && !wrapAs(&tFence, &nh, *outFence)) {
- LOG(ERROR) << "TWOmxBufferProducer::detachNextBuffer - "
- "Invalid output fence";
+ ALOGE("TWOmxBufferProducer::detachNextBuffer - Invalid output fence");
_hidl_cb(toStatus(status), tBuffer, tFence);
return Void();
}
@@ -145,8 +141,8 @@
int outSlot;
sp<GraphicBuffer> lBuffer = new GraphicBuffer();
if (!convertTo(lBuffer.get(), buffer)) {
- LOG(ERROR) << "TWOmxBufferProducer::attachBuffer - "
- "Invalid input native window buffer";
+ ALOGE("TWOmxBufferProducer::attachBuffer - "
+ "Invalid input native window buffer");
_hidl_cb(toStatus(BAD_VALUE), -1);
return Void();
}
@@ -166,8 +162,7 @@
NATIVE_WINDOW_SCALING_MODE_FREEZE,
0, ::android::Fence::NO_FENCE);
if (!convertTo(&lInput, input)) {
- LOG(ERROR) << "TWOmxBufferProducer::queueBuffer - "
- "Invalid input";
+ ALOGE("TWOmxBufferProducer::queueBuffer - Invalid input");
_hidl_cb(toStatus(BAD_VALUE), tOutput);
return Void();
}
@@ -177,8 +172,7 @@
std::vector<std::vector<native_handle_t*> > nhAA;
if (!wrapAs(&tOutput, &nhAA, lOutput)) {
- LOG(ERROR) << "TWOmxBufferProducer::queueBuffer - "
- "Invalid output";
+ ALOGE("TWOmxBufferProducer::queueBuffer - Invalid output");
_hidl_cb(toStatus(BAD_VALUE), tOutput);
return Void();
}
@@ -196,8 +190,7 @@
int32_t slot, const hidl_handle& fence) {
sp<Fence> lFence = new Fence();
if (!convertTo(lFence.get(), fence)) {
- LOG(ERROR) << "TWOmxBufferProducer::cancelBuffer - "
- "Invalid input fence";
+ ALOGE("TWOmxBufferProducer::cancelBuffer - Invalid input fence");
return toStatus(BAD_VALUE);
}
return toStatus(mBase->cancelBuffer(static_cast<int>(slot), lFence));
@@ -224,8 +217,7 @@
QueueBufferOutput tOutput;
std::vector<std::vector<native_handle_t*> > nhAA;
if (!wrapAs(&tOutput, &nhAA, lOutput)) {
- LOG(ERROR) << "TWOmxBufferProducer::connect - "
- "Invalid output";
+ ALOGE("TWOmxBufferProducer::connect - Invalid output");
_hidl_cb(toStatus(status), tOutput);
return Void();
}
@@ -300,8 +292,8 @@
hidl_handle tOutFence;
native_handle_t* nh = nullptr;
if ((lOutFence == nullptr) || !wrapAs(&tOutFence, &nh, *lOutFence)) {
- LOG(ERROR) << "TWOmxBufferProducer::getLastQueuedBuffer - "
- "Invalid output fence";
+ ALOGE("TWOmxBufferProducer::getLastQueuedBuffer - "
+ "Invalid output fence");
_hidl_cb(toStatus(status),
tOutBuffer,
tOutFence,
@@ -323,8 +315,8 @@
FrameEventHistoryDelta tDelta;
std::vector<std::vector<native_handle_t*> > nhAA;
if (!wrapAs(&tDelta, &nhAA, lDelta)) {
- LOG(ERROR) << "TWOmxBufferProducer::getFrameTimestamps - "
- "Invalid output frame timestamps";
+ ALOGE("TWOmxBufferProducer::getFrameTimestamps - "
+ "Invalid output frame timestamps");
_hidl_cb(tDelta);
return Void();
}
@@ -392,13 +384,13 @@
fnStatus = toStatusT(status);
*slot = tSlot;
if (!convertTo(fence->get(), tFence)) {
- LOG(ERROR) << "LWOmxBufferProducer::dequeueBuffer - "
- "Invalid output fence";
+ ALOGE("LWOmxBufferProducer::dequeueBuffer - "
+ "Invalid output fence");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
if (outTimestamps && !convertTo(outTimestamps, tTs)) {
- LOG(ERROR) << "LWOmxBufferProducer::dequeueBuffer - "
- "Invalid output timestamps";
+ ALOGE("LWOmxBufferProducer::dequeueBuffer - "
+ "Invalid output timestamps");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
}));
@@ -421,13 +413,13 @@
hidl_handle const& tFence) {
fnStatus = toStatusT(status);
if (!convertTo(outFence->get(), tFence)) {
- LOG(ERROR) << "LWOmxBufferProducer::detachNextBuffer - "
- "Invalid output fence";
+ ALOGE("LWOmxBufferProducer::detachNextBuffer - "
+ "Invalid output fence");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
if (!convertTo(outBuffer->get(), tBuffer)) {
- LOG(ERROR) << "LWOmxBufferProducer::detachNextBuffer - "
- "Invalid output buffer";
+ ALOGE("LWOmxBufferProducer::detachNextBuffer - "
+ "Invalid output buffer");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
}));
@@ -454,8 +446,7 @@
IOmxBufferProducer::QueueBufferInput tInput;
native_handle_t* nh;
if (!wrapAs(&tInput, &nh, input)) {
- LOG(ERROR) << "LWOmxBufferProducer::queueBuffer - "
- "Invalid input";
+ ALOGE("LWOmxBufferProducer::queueBuffer - Invalid input");
return BAD_VALUE;
}
status_t fnStatus;
@@ -465,8 +456,8 @@
IOmxBufferProducer::QueueBufferOutput const& tOutput) {
fnStatus = toStatusT(status);
if (!convertTo(output, tOutput)) {
- LOG(ERROR) << "LWOmxBufferProducer::queueBuffer - "
- "Invalid output";
+ ALOGE("LWOmxBufferProducer::queueBuffer - "
+ "Invalid output");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
}));
@@ -478,8 +469,7 @@
hidl_handle tFence;
native_handle_t* nh = nullptr;
if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
- LOG(ERROR) << "LWOmxBufferProducer::cancelBuffer - "
- "Invalid input fence";
+ ALOGE("LWOmxBufferProducer::cancelBuffer - Invalid input fence");
return BAD_VALUE;
}
@@ -513,8 +503,7 @@
IOmxBufferProducer::QueueBufferOutput const& tOutput) {
fnStatus = toStatusT(status);
if (!convertTo(output, tOutput)) {
- LOG(ERROR) << "LWOmxBufferProducer::connect - "
- "Invalid output";
+ ALOGE("LWOmxBufferProducer::connect - Invalid output");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
}));
@@ -579,14 +568,14 @@
fnStatus = toStatusT(status);
*outBuffer = new GraphicBuffer();
if (!convertTo(outBuffer->get(), buffer)) {
- LOG(ERROR) << "LWOmxBufferProducer::getLastQueuedBuffer - "
- "Invalid output buffer";
+ ALOGE("LWOmxBufferProducer::getLastQueuedBuffer - "
+ "Invalid output buffer");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
*outFence = new Fence();
if (!convertTo(outFence->get(), fence)) {
- LOG(ERROR) << "LWOmxBufferProducer::getLastQueuedBuffer - "
- "Invalid output fence";
+ ALOGE("LWOmxBufferProducer::getLastQueuedBuffer - "
+ "Invalid output fence");
fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
}
std::copy(transformMatrix.data(),
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp b/media/libmedia/omx/1.0/WOmxBufferSource.cpp
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
rename to media/libmedia/omx/1.0/WOmxBufferSource.cpp
index fe565e6..7cca5bd 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxBufferSource.cpp
+++ b/media/libmedia/omx/1.0/WOmxBufferSource.cpp
@@ -16,8 +16,8 @@
#include <utils/String8.h>
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libmedia/omx/1.0/WOmxNode.cpp
similarity index 98%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
rename to media/libmedia/omx/1.0/WOmxNode.cpp
index df191c7..b5186b5 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
+++ b/media/libmedia/omx/1.0/WOmxNode.cpp
@@ -16,9 +16,9 @@
#include <algorithm>
-#include "WOmxNode.h"
-#include "WOmxBufferSource.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/omx/1.0/WOmxBufferSource.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
@@ -30,9 +30,6 @@
using ::android::hardware::Void;
// LWOmxNode
-LWOmxNode::LWOmxNode(sp<IOmxNode> const& base) : mBase(base) {
-}
-
status_t LWOmxNode::freeNode() {
return toStatusT(mBase->freeNode());
}
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libmedia/omx/1.0/WOmxObserver.cpp
similarity index 92%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
rename to media/libmedia/omx/1.0/WOmxObserver.cpp
index 05ec37e..fa0407f 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
+++ b/media/libmedia/omx/1.0/WOmxObserver.cpp
@@ -18,12 +18,12 @@
#include <vector>
-#include <android-base/logging.h>
+#include <utils/Log.h>
#include <cutils/native_handle.h>
#include <binder/Binder.h>
-#include "WOmxObserver.h"
-#include "Conversion.h"
+#include <media/omx/1.0/WOmxObserver.h>
+#include <media/omx/1.0/Conversion.h>
namespace android {
namespace hardware {
@@ -47,7 +47,7 @@
}
auto transResult = mBase->onMessages(tMessages);
if (!transResult.isOk()) {
- LOG(ERROR) << "LWOmxObserver::onMessages - Transaction failed";
+ ALOGE("LWOmxObserver::onMessages - Transaction failed");
}
for (auto& handle : handles) {
native_handle_close(handle);
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp b/media/libmedia/omx/1.0/WOmxProducerListener.cpp
similarity index 96%
rename from media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
rename to media/libmedia/omx/1.0/WOmxProducerListener.cpp
index 80b0f71..3ee381f 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxProducerListener.cpp
+++ b/media/libmedia/omx/1.0/WOmxProducerListener.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "WOmxProducerListener.h"
+#include <media/omx/1.0/WOmxProducerListener.h>
namespace android {
namespace hardware {
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 05e6201..ad4c223 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -258,7 +258,11 @@
}
status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs, MediaPlayerSeekMode mode) {
- return mLiveSession->seekTo(seekTimeUs, mode);
+ if (mLiveSession->isSeekable()) {
+ return mLiveSession->seekTo(seekTimeUs, mode);
+ } else {
+ return INVALID_OPERATION;
+ }
}
void NuPlayer::HTTPLiveSource::pollForRawData(
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 78f28ae..81eecaf 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -45,6 +45,7 @@
#include <media/stagefright/SurfaceUtils.h>
#include <media/hardware/HardwareAPI.h>
#include <media/OMXBuffer.h>
+#include <media/omx/1.0/WOmxNode.h>
#include <hidlmemory/mapping.h>
@@ -63,7 +64,6 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
-#include "omx/hal/1.0/utils/WOmxNode.h"
namespace android {
@@ -6133,10 +6133,7 @@
if (mDeathNotifier != NULL) {
if (mCodec->mOMXNode != NULL) {
if (mCodec->getTrebleFlag()) {
- auto tOmxNode =
- (static_cast<
- ::android::hardware::media::omx::V1_0::utils::
- LWOmxNode*>(mCodec->mOMXNode.get()))->mBase;
+ auto tOmxNode = mCodec->mOMXNode->getHalInterface();
tOmxNode->unlinkToDeath(mDeathNotifier);
} else {
sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
@@ -6304,8 +6301,7 @@
mDeathNotifier = new DeathNotifier(notify);
if (mCodec->getTrebleFlag()) {
- auto tOmxNode = (static_cast<::android::hardware::media::omx::V1_0::
- utils::LWOmxNode*>(omxNode.get()))->mBase;
+ auto tOmxNode = omxNode->getHalInterface();
if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
mDeathNotifier.clear();
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index f25f15d..18cfc0e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -120,7 +120,6 @@
android.hidl.allocator@1.0 \
android.hidl.memory@1.0 \
android.hardware.media.omx@1.0 \
- android.hardware.media.omx@1.0-utils \
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libmedia
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index b77ee1d..1706221 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -28,9 +28,9 @@
#include <media/IMediaCodecService.h>
#include <media/stagefright/OMXClient.h>
-#include "include/OMX.h"
+#include <media/IOMX.h>
-#include "omx/hal/1.0/utils/WOmx.h"
+#include <media/omx/1.0/WOmx.h>
namespace android {
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 4d763d0..e75b48f 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -20,6 +20,10 @@
*******************************************************************************/
+#define LOG_TAG "NoiselessCoder"
+
+#include "log/log.h"
+
#include "aac_rom.h"
#include "dyn_bits.h"
#include "bit_cnt.h"
@@ -296,6 +300,9 @@
case SHORT_WINDOW:
sideInfoTab = sideInfoTabShort;
break;
+ default:
+ ALOGE("invalid blockType: %d", blockType);
+ return;
}
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 82b8143..f70f13b 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -34,6 +34,9 @@
libhidlmemory \
android.hidl.memory@1.0 \
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ android.hidl.memory@1.0
+
LOCAL_MODULE:= libstagefright_omx
LOCAL_CFLAGS += -Werror -Wall
LOCAL_SANITIZE := unsigned-integer-overflow signed-integer-overflow cfi
diff --git a/media/libstagefright/omx/hal/1.0/utils/Android.mk b/media/libstagefright/omx/hal/1.0/utils/Android.mk
deleted file mode 100644
index c44ce25..0000000
--- a/media/libstagefright/omx/hal/1.0/utils/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.media.omx@1.0-utils
-LOCAL_SRC_FILES := \
- WGraphicBufferSource.cpp \
- WOmx.cpp \
- WOmxBufferProducer.cpp \
- WOmxBufferSource.cpp \
- WOmxNode.cpp \
- WOmxObserver.cpp \
- WOmxProducerListener.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libmedia \
- libstagefright_foundation \
- libstagefright_omx \
- libui \
- libgui \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libhidlmemory \
- libutils \
- libcutils \
- libbinder \
- liblog \
- libbase \
- android.hardware.media.omx@1.0 \
- android.hardware.graphics.common@1.0 \
- android.hardware.media@1.0 \
- android.hidl.base@1.0 \
-
-LOCAL_C_INCLUDES += \
- $(TOP)/frameworks/av/include \
- $(TOP)/frameworks/av/media/libstagefright \
- $(TOP)/frameworks/native/include \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/native/include/media/hardware \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 6d0f189..5941b94 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -17,7 +17,6 @@
android.hidl.allocator@1.0 \
android.hidl.memory@1.0 \
android.hardware.media.omx@1.0 \
- android.hardware.media.omx@1.0-utils
LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright \
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 0401796..2be9362 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -41,6 +41,7 @@
api1/client2/CaptureSequencer.cpp \
api1/client2/ZslProcessor.cpp \
api2/CameraDeviceClient.cpp \
+ device1/CameraHardwareInterface.cpp \
device3/Camera3Device.cpp \
device3/Camera3Stream.cpp \
device3/Camera3IOStreamBase.cpp \
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
new file mode 100644
index 0000000..3e4e631
--- /dev/null
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -0,0 +1,1004 @@
+/*
+ * 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 "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 (mDevice) {
+ int rc = mDevice->common.close(&mDevice->common);
+ if (rc != OK)
+ ALOGE("Could not close camera %s: %d", mName.string(), rc);
+ }
+ if (mHidlDevice != nullptr) {
+ mHidlDevice->close();
+ mHidlDevice.clear();
+ cleanupCirculatingBuffers();
+ }
+}
+
+status_t CameraHardwareInterface::initialize(CameraModule *module)
+{
+ if (mHidlDevice != nullptr) {
+ ALOGE("%s: camera hardware interface has been initialized to HIDL path!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ ALOGI("Opening camera %s", mName.string());
+ camera_info info;
+ status_t res = module->getCameraInfo(atoi(mName.string()), &info);
+ if (res != OK) {
+ return res;
+ }
+
+ int rc = OK;
+ if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
+ info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
+ // Open higher version camera device as HAL1.0 device.
+ rc = module->openLegacy(mName.string(),
+ CAMERA_DEVICE_API_VERSION_1_0,
+ (hw_device_t **)&mDevice);
+ } else {
+ rc = module->open(mName.string(), (hw_device_t **)&mDevice);
+ }
+ if (rc != OK) {
+ ALOGE("Could not open camera %s: %d", mName.string(), rc);
+ return rc;
+ }
+ initHalPreviewWindow();
+ return rc;
+}
+
+status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
+ if (mDevice) {
+ ALOGE("%s: camera hardware interface has been initialized to libhardware path!",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ ALOGI("Opening camera %s", mName.string());
+
+ status_t ret = manager->openSession(String8::std_string(mName), 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;
+ }
+ mHidlMemPoolMap.insert(std::make_pair(memPoolId, mem));
+ return memPoolId;
+}
+
+hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
+ if (mHidlMemPoolMap.count(memId) == 0) {
+ ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
+ return hardware::Void();
+ }
+ camera_memory_t* mem = mHidlMemPoolMap.at(memId);
+ sPutMemory(mem);
+ mHidlMemPoolMap.erase(memId);
+ return hardware::Void();
+}
+
+hardware::Return<void> CameraHardwareInterface::dataCallback(
+ DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
+ const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
+ if (mHidlMemPoolMap.count(data) == 0) {
+ ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+ return hardware::Void();
+ }
+ camera_frame_metadata_t md;
+ md.number_of_faces = metadata.faces.size();
+ md.faces = (camera_face_t*) metadata.faces.data();
+ sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
+ return hardware::Void();
+}
+
+hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
+ DataCallbackMsg msgType, uint32_t data,
+ uint32_t bufferIndex, int64_t timestamp) {
+ if (mHidlMemPoolMap.count(data) == 0) {
+ ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+ return hardware::Void();
+ }
+ sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), 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) {
+ if (mHidlMemPoolMap.count(data) == 0) {
+ ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+ return hardware::Void();
+ }
+ sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
+ VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
+ mem->mBuffers[bufferIndex]->pointer();
+ md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
+ sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
+ 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::allocator::V2_0::ProducerUsage usage) {
+ Status s = Status::INTERNAL_ERROR;
+ ANativeWindow *a = mPreviewWindow.get();
+ if (a == nullptr) {
+ ALOGE("%s: preview window is null", __FUNCTION__);
+ return s;
+ }
+ mPreviewUsage = (int) 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));
+ } else if (mDevice) {
+ if (mDevice->ops->set_preview_window) {
+ mPreviewWindow = buf;
+ if (buf != nullptr) {
+ if (mPreviewScalingMode != NOT_SET) {
+ setPreviewScalingMode(mPreviewScalingMode);
+ }
+ if (mPreviewTransform != NOT_SET) {
+ setPreviewTransform(mPreviewTransform);
+ }
+ }
+ mHalPreviewWindow.user = this;
+ ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p",__FUNCTION__,
+ &mHalPreviewWindow, mHalPreviewWindow.user);
+ return mDevice->ops->set_preview_window(mDevice,
+ buf.get() ? &mHalPreviewWindow.nw : 0);
+ }
+ }
+ return INVALID_OPERATION;
+}
+
+void CameraHardwareInterface::setCallbacks(notify_callback notify_cb,
+ data_callback data_cb,
+ data_callback_timestamp data_cb_timestamp,
+ void* user)
+{
+ mNotifyCb = notify_cb;
+ mDataCb = data_cb;
+ mDataCbTimestamp = data_cb_timestamp;
+ mCbUser = user;
+
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+
+ if (mDevice && mDevice->ops->set_callbacks) {
+ mDevice->ops->set_callbacks(mDevice,
+ sNotifyCb,
+ sDataCb,
+ sDataCbTimestamp,
+ sGetMemory,
+ this);
+ }
+}
+
+void CameraHardwareInterface::enableMsgType(int32_t msgType)
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ mHidlDevice->enableMsgType(msgType);
+ } else if (mDevice && mDevice->ops->enable_msg_type) {
+ mDevice->ops->enable_msg_type(mDevice, msgType);
+ }
+}
+
+void CameraHardwareInterface::disableMsgType(int32_t msgType)
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ mHidlDevice->disableMsgType(msgType);
+ } else if (mDevice && mDevice->ops->disable_msg_type) {
+ mDevice->ops->disable_msg_type(mDevice, msgType);
+ }
+}
+
+int CameraHardwareInterface::msgTypeEnabled(int32_t msgType)
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return mHidlDevice->msgTypeEnabled(msgType);
+ } else if (mDevice && mDevice->ops->msg_type_enabled) {
+ return mDevice->ops->msg_type_enabled(mDevice, msgType);
+ }
+ return false;
+}
+
+status_t CameraHardwareInterface::startPreview()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return CameraProviderManager::mapToStatusT(
+ mHidlDevice->startPreview());
+ } else if (mDevice && mDevice->ops->start_preview) {
+ return mDevice->ops->start_preview(mDevice);
+ }
+ return INVALID_OPERATION;
+}
+
+void CameraHardwareInterface::stopPreview()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ mHidlDevice->stopPreview();
+ } else if (mDevice && mDevice->ops->stop_preview) {
+ mDevice->ops->stop_preview(mDevice);
+ }
+}
+
+int CameraHardwareInterface::previewEnabled()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return mHidlDevice->previewEnabled();
+ } else if (mDevice && mDevice->ops->preview_enabled) {
+ return mDevice->ops->preview_enabled(mDevice);
+ }
+ 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));
+ } else if (mDevice && mDevice->ops->store_meta_data_in_buffers) {
+ return mDevice->ops->store_meta_data_in_buffers(mDevice, 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());
+ } else if (mDevice && mDevice->ops->start_recording) {
+ return mDevice->ops->start_recording(mDevice);
+ }
+ return INVALID_OPERATION;
+}
+
+/**
+ * Stop a previously started recording.
+ */
+void CameraHardwareInterface::stopRecording()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ mHidlDevice->stopRecording();
+ } else if (mDevice && mDevice->ops->stop_recording) {
+ mDevice->ops->stop_recording(mDevice);
+ }
+}
+
+/**
+ * Returns true if recording is enabled.
+ */
+int CameraHardwareInterface::recordingEnabled()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return mHidlDevice->recordingEnabled();
+ } else if (mDevice && mDevice->ops->recording_enabled) {
+ return mDevice->ops->recording_enabled(mDevice);
+ }
+ 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)) {
+ VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) mem->pointer();
+ // 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);
+ }
+ } else if (mDevice && mDevice->ops->release_recording_frame) {
+ void *data = ((uint8_t *)heap->base()) + offset;
+ return mDevice->ops->release_recording_frame(mDevice, data);
+ }
+}
+
+status_t CameraHardwareInterface::autoFocus()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return CameraProviderManager::mapToStatusT(
+ mHidlDevice->autoFocus());
+ } else if (mDevice && mDevice->ops->auto_focus) {
+ return mDevice->ops->auto_focus(mDevice);
+ }
+ return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::cancelAutoFocus()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return CameraProviderManager::mapToStatusT(
+ mHidlDevice->cancelAutoFocus());
+ } else if (mDevice && mDevice->ops->cancel_auto_focus) {
+ return mDevice->ops->cancel_auto_focus(mDevice);
+ }
+ return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::takePicture()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return CameraProviderManager::mapToStatusT(
+ mHidlDevice->takePicture());
+ } else if (mDevice && mDevice->ops->take_picture) {
+ return mDevice->ops->take_picture(mDevice);
+ }
+ return INVALID_OPERATION;
+}
+
+status_t CameraHardwareInterface::cancelPicture()
+{
+ ALOGV("%s(%s)", __FUNCTION__, mName.string());
+ if (CC_LIKELY(mHidlDevice != nullptr)) {
+ return CameraProviderManager::mapToStatusT(
+ mHidlDevice->cancelPicture());
+ } else if (mDevice && mDevice->ops->cancel_picture) {
+ return mDevice->ops->cancel_picture(mDevice);
+ }
+ 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()));
+ } else if (mDevice && mDevice->ops->set_parameters) {
+ return mDevice->ops->set_parameters(mDevice, 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);
+ } else if (mDevice && mDevice->ops->get_parameters) {
+ char *temp = mDevice->ops->get_parameters(mDevice);
+ String8 str_parms(temp);
+ if (mDevice->ops->put_parameters)
+ mDevice->ops->put_parameters(mDevice, temp);
+ else
+ free(temp);
+ parms.unflatten(str_parms);
+ }
+ 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));
+ } else if (mDevice && mDevice->ops->send_command) {
+ return mDevice->ops->send_command(mDevice, 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();
+ } else if (mDevice && mDevice->ops->release) {
+ mDevice->ops->release(mDevice);
+ }
+}
+
+/**
+ * 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);
+ } else if (mDevice && mDevice->ops->dump) {
+ return mDevice->ops->dump(mDevice, fd);
+ }
+ return OK; // It's fine if the HAL doesn't implement dump()
+}
+
+/**
+ * Methods for legacy (non-HIDL) path follows
+ */
+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);
+}
+
+ANativeWindow* CameraHardwareInterface::sToAnw(void *user)
+{
+ CameraHardwareInterface *object =
+ reinterpret_cast<CameraHardwareInterface *>(user);
+ return object->mPreviewWindow.get();
+}
+#define anw(n) sToAnw(((struct camera_preview_window *)(n))->user)
+#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
+ ((struct camera_preview_window *)(n))->user)
+
+int CameraHardwareInterface::sDequeueBuffer(struct preview_stream_ops* w,
+ buffer_handle_t** buffer, int *stride)
+{
+ int rc;
+ ANativeWindow *a = anw(w);
+ ANativeWindowBuffer* anb;
+ rc = native_window_dequeue_buffer_and_wait(a, &anb);
+ if (rc == OK) {
+ *buffer = &anb->handle;
+ *stride = anb->stride;
+ }
+ return rc;
+}
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const __typeof__(((type *) 0)->member) *__mptr = (ptr); \
+ (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
+#endif
+
+int CameraHardwareInterface::sLockBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* /*buffer*/)
+{
+ ANativeWindow *a = anw(w);
+ (void)a;
+ return 0;
+}
+
+int CameraHardwareInterface::sEnqueueBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer)
+{
+ ANativeWindow *a = anw(w);
+ return a->queueBuffer(a,
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
+}
+
+int CameraHardwareInterface::sCancelBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer)
+{
+ ANativeWindow *a = anw(w);
+ return a->cancelBuffer(a,
+ container_of(buffer, ANativeWindowBuffer, handle), -1);
+}
+
+int CameraHardwareInterface::sSetBufferCount(struct preview_stream_ops* w, int count)
+{
+ ANativeWindow *a = anw(w);
+
+ 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.
+ CameraHardwareInterface *hw = hwi(w);
+ native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
+ native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
+ if (hw->mPreviewScalingMode != NOT_SET) {
+ native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
+ }
+ if (hw->mPreviewTransform != NOT_SET) {
+ native_window_set_buffers_transform(a, hw->mPreviewTransform);
+ }
+ if (hw->mPreviewWidth != NOT_SET) {
+ native_window_set_buffers_dimensions(a,
+ hw->mPreviewWidth, hw->mPreviewHeight);
+ native_window_set_buffers_format(a, hw->mPreviewFormat);
+ }
+ if (hw->mPreviewUsage != 0) {
+ native_window_set_usage(a, hw->mPreviewUsage);
+ }
+ if (hw->mPreviewSwapInterval != NOT_SET) {
+ a->setSwapInterval(a, hw->mPreviewSwapInterval);
+ }
+ if (hw->mPreviewCrop.left != NOT_SET) {
+ native_window_set_crop(a, &(hw->mPreviewCrop));
+ }
+ }
+
+ return native_window_set_buffer_count(a, count);
+}
+
+int CameraHardwareInterface::sSetBuffersGeometry(struct preview_stream_ops* w,
+ int width, int height, int format)
+{
+ int rc;
+ ANativeWindow *a = anw(w);
+ CameraHardwareInterface *hw = hwi(w);
+ hw->mPreviewWidth = width;
+ hw->mPreviewHeight = height;
+ hw->mPreviewFormat = format;
+ rc = native_window_set_buffers_dimensions(a, width, height);
+ if (rc == OK) {
+ rc = native_window_set_buffers_format(a, format);
+ }
+ return rc;
+}
+
+int CameraHardwareInterface::sSetCrop(struct preview_stream_ops *w,
+ int left, int top, int right, int bottom)
+{
+ ANativeWindow *a = anw(w);
+ CameraHardwareInterface *hw = hwi(w);
+ hw->mPreviewCrop.left = left;
+ hw->mPreviewCrop.top = top;
+ hw->mPreviewCrop.right = right;
+ hw->mPreviewCrop.bottom = bottom;
+ return native_window_set_crop(a, &(hw->mPreviewCrop));
+}
+
+int CameraHardwareInterface::sSetTimestamp(struct preview_stream_ops *w,
+ int64_t timestamp) {
+ ANativeWindow *a = anw(w);
+ return native_window_set_buffers_timestamp(a, timestamp);
+}
+
+int CameraHardwareInterface::sSetUsage(struct preview_stream_ops* w, int usage)
+{
+ ANativeWindow *a = anw(w);
+ CameraHardwareInterface *hw = hwi(w);
+ hw->mPreviewUsage = usage;
+ return native_window_set_usage(a, usage);
+}
+
+int CameraHardwareInterface::sSetSwapInterval(struct preview_stream_ops *w, int interval)
+{
+ ANativeWindow *a = anw(w);
+ CameraHardwareInterface *hw = hwi(w);
+ hw->mPreviewSwapInterval = interval;
+ return a->setSwapInterval(a, interval);
+}
+
+int CameraHardwareInterface::sGetMinUndequeuedBufferCount(
+ const struct preview_stream_ops *w,
+ int *count)
+{
+ ANativeWindow *a = anw(w);
+ return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
+}
+
+void CameraHardwareInterface::initHalPreviewWindow()
+{
+ mHalPreviewWindow.nw.cancel_buffer = sCancelBuffer;
+ mHalPreviewWindow.nw.lock_buffer = sLockBuffer;
+ mHalPreviewWindow.nw.dequeue_buffer = sDequeueBuffer;
+ mHalPreviewWindow.nw.enqueue_buffer = sEnqueueBuffer;
+ mHalPreviewWindow.nw.set_buffer_count = sSetBufferCount;
+ mHalPreviewWindow.nw.set_buffers_geometry = sSetBuffersGeometry;
+ mHalPreviewWindow.nw.set_crop = sSetCrop;
+ mHalPreviewWindow.nw.set_timestamp = sSetTimestamp;
+ mHalPreviewWindow.nw.set_usage = sSetUsage;
+ mHalPreviewWindow.nw.set_swap_interval = sSetSwapInterval;
+
+ mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
+ sGetMinUndequeuedBufferCount;
+}
+
+}; // namespace android
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index c8210b7..88ab2e9 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -17,6 +17,7 @@
#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>
@@ -74,10 +75,15 @@
* provided in a data callback must be copied if it's needed after returning.
*/
-class CameraHardwareInterface : public virtual RefBase {
+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):
mDevice(nullptr),
+ mHidlDevice(nullptr),
mName(name),
mPreviewScalingMode(NOT_SET),
mPreviewTransform(NOT_SET),
@@ -90,115 +96,23 @@
{
}
- ~CameraHardwareInterface()
- {
- ALOGI("Destroying camera %s", mName.string());
- if(mDevice) {
- int rc = mDevice->common.close(&mDevice->common);
- if (rc != OK)
- ALOGE("Could not close camera %s: %d", mName.string(), rc);
- }
- }
+ ~CameraHardwareInterface();
- status_t initialize(CameraModule *module)
- {
- ALOGI("Opening camera %s", mName.string());
- camera_info info;
- status_t res = module->getCameraInfo(atoi(mName.string()), &info);
- if (res != OK) {
- return res;
- }
-
- int rc = OK;
- if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
- info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
- // Open higher version camera device as HAL1.0 device.
- rc = module->openLegacy(mName.string(),
- CAMERA_DEVICE_API_VERSION_1_0,
- (hw_device_t **)&mDevice);
- } else {
- rc = module->open(mName.string(), (hw_device_t **)&mDevice);
- }
- if (rc != OK) {
- ALOGE("Could not open camera %s: %d", mName.string(), rc);
- return rc;
- }
- initHalPreviewWindow();
- return rc;
- }
-
- status_t initialize(sp<CameraProviderManager> manager) {
- (void) manager;
- ALOGE("%s: Not supported yet", __FUNCTION__);
- return INVALID_OPERATION;
- }
+ status_t initialize(CameraModule *module);
+ status_t initialize(sp<CameraProviderManager> manager);
/** Set the ANativeWindow to which preview frames are sent */
- status_t setPreviewWindow(const sp<ANativeWindow>& buf)
- {
- ALOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
- if (mDevice->ops->set_preview_window) {
- mPreviewWindow = buf;
- if (buf != nullptr) {
- if (mPreviewScalingMode != NOT_SET) {
- setPreviewScalingMode(mPreviewScalingMode);
- }
- if (mPreviewTransform != NOT_SET) {
- setPreviewTransform(mPreviewTransform);
- }
- }
- mHalPreviewWindow.user = this;
- ALOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
- &mHalPreviewWindow, mHalPreviewWindow.user);
- return mDevice->ops->set_preview_window(mDevice,
- buf.get() ? &mHalPreviewWindow.nw : 0);
- }
- return INVALID_OPERATION;
- }
+ status_t setPreviewWindow(const sp<ANativeWindow>& buf);
- status_t setPreviewScalingMode(int scalingMode)
- {
- int rc = OK;
- mPreviewScalingMode = scalingMode;
- if (mPreviewWindow != nullptr) {
- rc = native_window_set_scaling_mode(mPreviewWindow.get(),
- scalingMode);
- }
- return rc;
- }
+ status_t setPreviewScalingMode(int scalingMode);
- status_t setPreviewTransform(int transform) {
- int rc = OK;
- mPreviewTransform = transform;
- if (mPreviewWindow != nullptr) {
- rc = native_window_set_buffers_transform(mPreviewWindow.get(),
- mPreviewTransform);
- }
- return rc;
- }
+ 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,
- void* user)
- {
- mNotifyCb = notify_cb;
- mDataCb = data_cb;
- mDataCbTimestamp = data_cb_timestamp;
- mCbUser = user;
-
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
-
- if (mDevice->ops->set_callbacks) {
- mDevice->ops->set_callbacks(mDevice,
- __notify_cb,
- __data_cb,
- __data_cb_timestamp,
- __get_memory,
- this);
- }
- }
+ void* user);
/**
* The following three functions all take a msgtype,
@@ -209,12 +123,7 @@
/**
* Enable a message, or set of messages.
*/
- void enableMsgType(int32_t msgType)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->enable_msg_type)
- mDevice->ops->enable_msg_type(mDevice, msgType);
- }
+ void enableMsgType(int32_t msgType);
/**
* Disable a message, or a set of messages.
@@ -226,57 +135,29 @@
* modify/access any video recording frame after calling
* disableMsgType(CAMERA_MSG_VIDEO_FRAME).
*/
- void disableMsgType(int32_t msgType)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->disable_msg_type)
- mDevice->ops->disable_msg_type(mDevice, msgType);
- }
+ 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)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->msg_type_enabled)
- return mDevice->ops->msg_type_enabled(mDevice, msgType);
- return false;
- }
+ int msgTypeEnabled(int32_t msgType);
/**
* Start preview mode.
*/
- status_t startPreview()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->start_preview)
- return mDevice->ops->start_preview(mDevice);
- return INVALID_OPERATION;
- }
+ status_t startPreview();
/**
* Stop a previously started preview.
*/
- void stopPreview()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->stop_preview)
- mDevice->ops->stop_preview(mDevice);
- }
+ void stopPreview();
/**
* Returns true if preview is enabled.
*/
- int previewEnabled()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->preview_enabled)
- return mDevice->ops->preview_enabled(mDevice);
- return false;
- }
+ int previewEnabled();
/**
* Request the camera hal to store meta data or real YUV data in
@@ -310,13 +191,7 @@
* @return OK on success.
*/
- status_t storeMetaDataInBuffers(int enable)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->store_meta_data_in_buffers)
- return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
- return enable ? INVALID_OPERATION: OK;
- }
+ status_t storeMetaDataInBuffers(int enable);
/**
* Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
@@ -327,34 +202,17 @@
* to manage the life-cycle of the video recording frames, and the client must
* not modify/access any video recording frames.
*/
- status_t startRecording()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->start_recording)
- return mDevice->ops->start_recording(mDevice);
- return INVALID_OPERATION;
- }
+ status_t startRecording();
/**
* Stop a previously started recording.
*/
- void stopRecording()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->stop_recording)
- mDevice->ops->stop_recording(mDevice);
- }
+ void stopRecording();
/**
* Returns true if recording is enabled.
*/
- int recordingEnabled()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->recording_enabled)
- return mDevice->ops->recording_enabled(mDevice);
- return false;
- }
+ int recordingEnabled();
/**
* Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
@@ -366,30 +224,14 @@
* responsibility of managing the life-cycle of the video recording
* frames.
*/
- void releaseRecordingFrame(const sp<IMemory>& mem)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->release_recording_frame) {
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
- void *data = ((uint8_t *)heap->base()) + offset;
- return mDevice->ops->release_recording_frame(mDevice, data);
- }
- }
+ void releaseRecordingFrame(const sp<IMemory>& mem);
/**
* 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()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->auto_focus)
- return mDevice->ops->auto_focus(mDevice);
- return INVALID_OPERATION;
- }
+ status_t autoFocus();
/**
* Cancels auto-focus function. If the auto-focus is still in progress,
@@ -397,151 +239,73 @@
* 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()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->cancel_auto_focus)
- return mDevice->ops->cancel_auto_focus(mDevice);
- return INVALID_OPERATION;
- }
+ status_t cancelAutoFocus();
/**
* Take a picture.
*/
- status_t takePicture()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->take_picture)
- return mDevice->ops->take_picture(mDevice);
- return INVALID_OPERATION;
- }
+ 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()
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->cancel_picture)
- return mDevice->ops->cancel_picture(mDevice);
- return INVALID_OPERATION;
- }
+ 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)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->set_parameters)
- return mDevice->ops->set_parameters(mDevice,
- params.flatten().string());
- return INVALID_OPERATION;
- }
+ status_t setParameters(const CameraParameters ¶ms);
/** Return the camera parameters. */
- CameraParameters getParameters() const
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- CameraParameters parms;
- if (mDevice->ops->get_parameters) {
- char *temp = mDevice->ops->get_parameters(mDevice);
- String8 str_parms(temp);
- if (mDevice->ops->put_parameters)
- mDevice->ops->put_parameters(mDevice, temp);
- else
- free(temp);
- parms.unflatten(str_parms);
- }
- return parms;
- }
+ CameraParameters getParameters() const;
/**
* Send command to camera driver.
*/
- status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->send_command)
- return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
- return INVALID_OPERATION;
- }
+ 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() {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->release)
- mDevice->ops->release(mDevice);
- }
+ void release();
/**
* Dump state of the camera hardware
*/
- status_t dump(int fd, const Vector<String16>& /*args*/) const
- {
- ALOGV("%s(%s)", __FUNCTION__, mName.string());
- if (mDevice->ops->dump)
- return mDevice->ops->dump(mDevice, fd);
- return OK; // It's fine if the HAL doesn't implement dump()
- }
+ status_t dump(int fd, const Vector<String16>& /*args*/) const;
private:
camera_device_t *mDevice;
+ sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;
String8 mName;
- static void __notify_cb(int32_t msg_type, int32_t ext1,
- int32_t ext2, void *user)
- {
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *__this =
- static_cast<CameraHardwareInterface *>(user);
- __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
- }
+ static void sNotifyCb(int32_t msg_type, int32_t ext1,
+ int32_t ext2, void *user);
- static void __data_cb(int32_t msg_type,
+ static void sDataCb(int32_t msg_type,
const camera_memory_t *data, unsigned int index,
camera_frame_metadata_t *metadata,
- void *user)
- {
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *__this =
- 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;
- }
- __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
- }
+ void *user);
- static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
+ static void sDataCbTimestamp(nsecs_t timestamp, int32_t msg_type,
const camera_memory_t *data, unsigned index,
- void *user)
- {
- ALOGV("%s", __FUNCTION__);
- CameraHardwareInterface *__this =
- 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;
- }
- __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser);
- }
+ void *user);
+
+ // TODO: b/35625849
+ // Meta data buffer layout for passing a native_handle to codec
+ // matching frameworks/native/include/media/hardware/MetadataBufferType.h and
+ // frameworks/native/include/media/hardware/HardwareAPI.h
+ struct VideoNativeHandleMetadata {
+ static const uint32_t kMetadataBufferTypeNativeHandleSource = 3;
+ uint32_t eType; // must be kMetadataBufferTypeNativeHandleSource
+ native_handle_t* pHandle;
+ };
// 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) :
@@ -572,7 +336,7 @@
i * mBufSize,
mBufSize);
- handle.release = __put_memory;
+ handle.release = sPutMemory;
}
virtual ~CameraHeapMemory()
@@ -588,199 +352,94 @@
camera_memory_t handle;
};
- static camera_memory_t* __get_memory(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;
- }
+ static camera_memory_t* sGetMemory(int fd, size_t buf_size, uint_t num_bufs,
+ void *user __attribute__((unused)));
- static void __put_memory(camera_memory_t *data)
- {
- if (!data)
- return;
+ static void sPutMemory(camera_memory_t *data);
- CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle);
- mem->decStrong(mem);
- }
+ static ANativeWindow *sToAnw(void *user);
- static ANativeWindow *__to_anw(void *user)
- {
- CameraHardwareInterface *__this =
- reinterpret_cast<CameraHardwareInterface *>(user);
- return __this->mPreviewWindow.get();
- }
-#define anw(n) __to_anw(((struct camera_preview_window *)(n))->user)
-#define hwi(n) reinterpret_cast<CameraHardwareInterface *>(\
- ((struct camera_preview_window *)(n))->user)
+ static int sDequeueBuffer(struct preview_stream_ops* w,
+ buffer_handle_t** buffer, int *stride);
- static int __dequeue_buffer(struct preview_stream_ops* w,
- buffer_handle_t** buffer, int *stride)
- {
- int rc;
- ANativeWindow *a = anw(w);
- ANativeWindowBuffer* anb;
- rc = native_window_dequeue_buffer_and_wait(a, &anb);
- if (!rc) {
- *buffer = &anb->handle;
- *stride = anb->stride;
- }
- return rc;
- }
+ static int sLockBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* /*buffer*/);
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const __typeof__(((type *) 0)->member) *__mptr = (ptr); \
- (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
-#endif
+ static int sEnqueueBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer);
- static int __lock_buffer(struct preview_stream_ops* w,
- buffer_handle_t* /*buffer*/)
- {
- ANativeWindow *a = anw(w);
- (void)a;
- return 0;
- }
+ static int sCancelBuffer(struct preview_stream_ops* w,
+ buffer_handle_t* buffer);
- static int __enqueue_buffer(struct preview_stream_ops* w,
- buffer_handle_t* buffer)
- {
- ANativeWindow *a = anw(w);
- return a->queueBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle), -1);
- }
+ static int sSetBufferCount(struct preview_stream_ops* w, int count);
- static int __cancel_buffer(struct preview_stream_ops* w,
- buffer_handle_t* buffer)
- {
- ANativeWindow *a = anw(w);
- return a->cancelBuffer(a,
- container_of(buffer, ANativeWindowBuffer, handle), -1);
- }
+ static int sSetBuffersGeometry(struct preview_stream_ops* w,
+ int width, int height, int format);
- static int __set_buffer_count(struct preview_stream_ops* w, int count)
- {
- ANativeWindow *a = anw(w);
+ static int sSetCrop(struct preview_stream_ops *w,
+ int left, int top, int right, int bottom);
- 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.
- CameraHardwareInterface *hw = hwi(w);
- native_window_api_disconnect(a, NATIVE_WINDOW_API_CAMERA);
- native_window_api_connect(a, NATIVE_WINDOW_API_CAMERA);
- if (hw->mPreviewScalingMode != NOT_SET) {
- native_window_set_scaling_mode(a, hw->mPreviewScalingMode);
- }
- if (hw->mPreviewTransform != NOT_SET) {
- native_window_set_buffers_transform(a, hw->mPreviewTransform);
- }
- if (hw->mPreviewWidth != NOT_SET) {
- native_window_set_buffers_dimensions(a,
- hw->mPreviewWidth, hw->mPreviewHeight);
- native_window_set_buffers_format(a, hw->mPreviewFormat);
- }
- if (hw->mPreviewUsage != 0) {
- native_window_set_usage(a, hw->mPreviewUsage);
- }
- if (hw->mPreviewSwapInterval != NOT_SET) {
- a->setSwapInterval(a, hw->mPreviewSwapInterval);
- }
- if (hw->mPreviewCrop.left != NOT_SET) {
- native_window_set_crop(a, &(hw->mPreviewCrop));
- }
- }
+ static int sSetTimestamp(struct preview_stream_ops *w,
+ int64_t timestamp);
- return native_window_set_buffer_count(a, count);
- }
+ static int sSetUsage(struct preview_stream_ops* w, int usage);
- static int __set_buffers_geometry(struct preview_stream_ops* w,
- int width, int height, int format)
- {
- int rc;
- ANativeWindow *a = anw(w);
- CameraHardwareInterface *hw = hwi(w);
- hw->mPreviewWidth = width;
- hw->mPreviewHeight = height;
- hw->mPreviewFormat = format;
- rc = native_window_set_buffers_dimensions(a, width, height);
- if (!rc) {
- rc = native_window_set_buffers_format(a, format);
- }
- return rc;
- }
+ static int sSetSwapInterval(struct preview_stream_ops *w, int interval);
- static int __set_crop(struct preview_stream_ops *w,
- int left, int top, int right, int bottom)
- {
- ANativeWindow *a = anw(w);
- CameraHardwareInterface *hw = hwi(w);
- hw->mPreviewCrop.left = left;
- hw->mPreviewCrop.top = top;
- hw->mPreviewCrop.right = right;
- hw->mPreviewCrop.bottom = bottom;
- return native_window_set_crop(a, &(hw->mPreviewCrop));
- }
-
- static int __set_timestamp(struct preview_stream_ops *w,
- int64_t timestamp) {
- ANativeWindow *a = anw(w);
- return native_window_set_buffers_timestamp(a, timestamp);
- }
-
- static int __set_usage(struct preview_stream_ops* w, int usage)
- {
- ANativeWindow *a = anw(w);
- CameraHardwareInterface *hw = hwi(w);
- hw->mPreviewUsage = usage;
- return native_window_set_usage(a, usage);
- }
-
- static int __set_swap_interval(struct preview_stream_ops *w, int interval)
- {
- ANativeWindow *a = anw(w);
- CameraHardwareInterface *hw = hwi(w);
- hw->mPreviewSwapInterval = interval;
- return a->setSwapInterval(a, interval);
- }
-
- static int __get_min_undequeued_buffer_count(
+ static int sGetMinUndequeuedBufferCount(
const struct preview_stream_ops *w,
- int *count)
- {
- ANativeWindow *a = anw(w);
- return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
- }
+ int *count);
- void initHalPreviewWindow()
- {
- mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
- mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
- mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
- mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
- mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
- mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
- mHalPreviewWindow.nw.set_crop = __set_crop;
- mHalPreviewWindow.nw.set_timestamp = __set_timestamp;
- mHalPreviewWindow.nw.set_usage = __set_usage;
- mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
+ void initHalPreviewWindow();
- mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
- __get_min_undequeued_buffer_count;
- }
+ 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;
+
+ /**
+ * 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::allocator::V2_0::ProducerUsage 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;
@@ -806,6 +465,48 @@
int 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::unordered_map<int, camera_memory_t*> mHidlMemPoolMap;
};
}; // namespace android