Revert "Remove unused modules made for non-Treble OMX"
This reverts commit 37c79ffe2fa52a1eaa4db74b5e15c6d41646efbf
Bug: 68340092
Test: revert
Change-Id: If7736b745f981105bed4ffda2e63691d8862d259
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 71c1ffb..2761578 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -43,7 +43,9 @@
"aidl/android/IOMXBufferSource.aidl",
"IMediaCodecList.cpp",
+ "IMediaCodecService.cpp",
"IOMX.cpp",
+ "IOMXStore.cpp",
"MediaCodecBuffer.cpp",
"MediaCodecInfo.cpp",
"OMXBuffer.cpp",
diff --git a/media/libmedia/IMediaCodecService.cpp b/media/libmedia/IMediaCodecService.cpp
new file mode 100644
index 0000000..adfa93d
--- /dev/null
+++ b/media/libmedia/IMediaCodecService.cpp
@@ -0,0 +1,86 @@
+/*
+**
+** Copyright 2015, 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 "IMediaCodecService"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <media/IMediaCodecService.h>
+
+namespace android {
+
+enum {
+ GET_OMX = IBinder::FIRST_CALL_TRANSACTION,
+ GET_OMX_STORE
+};
+
+class BpMediaCodecService : public BpInterface<IMediaCodecService>
+{
+public:
+ explicit BpMediaCodecService(const sp<IBinder>& impl)
+ : BpInterface<IMediaCodecService>(impl)
+ {
+ }
+
+ virtual sp<IOMX> getOMX() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaCodecService::getInterfaceDescriptor());
+ remote()->transact(GET_OMX, data, &reply);
+ return interface_cast<IOMX>(reply.readStrongBinder());
+ }
+
+ virtual sp<IOMXStore> getOMXStore() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaCodecService::getInterfaceDescriptor());
+ remote()->transact(GET_OMX_STORE, data, &reply);
+ return interface_cast<IOMXStore>(reply.readStrongBinder());
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(MediaCodecService, "android.media.IMediaCodecService");
+
+// ----------------------------------------------------------------------
+
+status_t BnMediaCodecService::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch (code) {
+
+ case GET_OMX: {
+ CHECK_INTERFACE(IMediaCodecService, data, reply);
+ sp<IOMX> omx = getOMX();
+ reply->writeStrongBinder(IInterface::asBinder(omx));
+ return NO_ERROR;
+ }
+ case GET_OMX_STORE: {
+ CHECK_INTERFACE(IMediaCodecService, data, reply);
+ sp<IOMXStore> omxStore = getOMXStore();
+ reply->writeStrongBinder(IInterface::asBinder(omxStore));
+ return NO_ERROR;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace android
diff --git a/media/libmedia/IOMXStore.cpp b/media/libmedia/IOMXStore.cpp
new file mode 100644
index 0000000..4948f1a
--- /dev/null
+++ b/media/libmedia/IOMXStore.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2009 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 "IOMXStore"
+
+#include <utils/Log.h>
+
+#include <media/IOMX.h>
+#include <media/IOMXStore.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+#include <binder/Parcel.h>
+
+#include <vector>
+#include <string>
+
+namespace android {
+
+namespace {
+
+enum {
+ CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+ LIST_SERVICE_ATTRIBUTES,
+ GET_NODE_PREFIX,
+ LIST_ROLES,
+ GET_OMX,
+};
+
+// Forward declarations of std::vector<T> <-> Parcel conversion funcitons that
+// depend on writeToParcel() and readToParcel() for T <-> Parcel.
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p);
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p);
+
+// std::string <-> Parcel
+
+status_t writeToParcel(const std::string& s, Parcel* p) {
+ if (s.size() > INT32_MAX) {
+ return BAD_VALUE;
+ }
+ return p->writeByteArray(
+ s.size(), reinterpret_cast<const uint8_t*>(s.c_str()));
+}
+
+status_t readFromParcel(std::string* s, const Parcel& p) {
+ int32_t len;
+ status_t status = p.readInt32(&len);
+ if (status != NO_ERROR) {
+ return status;
+ } else if ((len < 0) || (static_cast<uint64_t>(len) > SIZE_MAX)) {
+ return BAD_VALUE;
+ }
+ s->resize(len);
+ if (len == 0) {
+ return NO_ERROR;
+ }
+ return p.read(static_cast<void*>(&s->front()), static_cast<size_t>(len));
+}
+
+// IOMXStore::Attribute <-> Parcel
+
+status_t writeToParcel(const IOMXStore::Attribute& a, Parcel* p) {
+ status_t status = writeToParcel(a.key, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(a.value, p);
+}
+
+status_t readFromParcel(IOMXStore::Attribute* a, const Parcel& p) {
+ status_t status = readFromParcel(&(a->key), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(a->value), p);
+}
+
+// IOMXStore::NodeInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::NodeInfo& n, Parcel* p) {
+ status_t status = writeToParcel(n.name, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(n.owner, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(n.attributes, p);
+}
+
+status_t readFromParcel(IOMXStore::NodeInfo* n, const Parcel& p) {
+ status_t status = readFromParcel(&(n->name), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = readFromParcel(&(n->owner), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(n->attributes), p);
+}
+
+// IOMXStore::RoleInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::RoleInfo& r, Parcel* p) {
+ status_t status = writeToParcel(r.role, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(r.type, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p->writeBool(r.isEncoder);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p->writeBool(r.preferPlatformNodes);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(r.nodes, p);
+}
+
+status_t readFromParcel(IOMXStore::RoleInfo* r, const Parcel& p) {
+ status_t status = readFromParcel(&(r->role), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = readFromParcel(&(r->type), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p.readBool(&(r->isEncoder));
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p.readBool(&(r->preferPlatformNodes));
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(r->nodes), p);
+}
+
+// std::vector<NodeInfo> <-> Parcel
+// std::vector<RoleInfo> <-> Parcel
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p) {
+ status_t status = p->writeVectorSize(v);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ for (const T& x : v) {
+ status = writeToParcel(x, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p) {
+ status_t status = p.resizeOutVector(v);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ for (T& x : *v) {
+ status = readFromParcel(&x, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+} // unnamed namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BpOMXStore : public BpInterface<IOMXStore> {
+public:
+ explicit BpOMXStore(const sp<IBinder> &impl)
+ : BpInterface<IOMXStore>(impl) {
+ }
+
+ status_t listServiceAttributes(
+ std::vector<Attribute>* attributes) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(LIST_SERVICE_ATTRIBUTES, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(attributes, reply);
+ }
+
+ status_t getNodePrefix(std::string* prefix) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(GET_NODE_PREFIX, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(prefix, reply);
+ }
+
+ status_t listRoles(std::vector<RoleInfo>* roleList) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(LIST_ROLES, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(roleList, reply);
+ }
+
+ status_t getOmx(const std::string& name, sp<IOMX>* omx) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(name, &data);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(GET_OMX, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return reply.readStrongBinder(omx);
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(OMXStore, "android.hardware.IOMXStore");
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define CHECK_OMX_INTERFACE(interface, data, reply) \
+ do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
+ ALOGW("Call incorrectly routed to " #interface); \
+ return PERMISSION_DENIED; \
+ } } while (0)
+
+status_t BnOMXStore::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case LIST_SERVICE_ATTRIBUTES: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::vector<Attribute> attributes;
+
+ status = listServiceAttributes(&attributes);
+ if (status != NO_ERROR) {
+ ALOGE("listServiceAttributes() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(attributes, reply);
+ if (status != NO_ERROR) {
+ ALOGE("listServiceAttributes() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case GET_NODE_PREFIX: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::string prefix;
+
+ status = getNodePrefix(&prefix);
+ if (status != NO_ERROR) {
+ ALOGE("getNodePrefix() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(prefix, reply);
+ if (status != NO_ERROR) {
+ ALOGE("getNodePrefix() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case LIST_ROLES: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::vector<RoleInfo> roleList;
+
+ status = listRoles(&roleList);
+ if (status != NO_ERROR) {
+ ALOGE("listRoles() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(roleList, reply);
+ if (status != NO_ERROR) {
+ ALOGE("listRoles() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case GET_OMX: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::string name;
+ sp<IOMX> omx;
+
+ status = readFromParcel(&name, data);
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails to retrieve name");
+ return NO_ERROR;
+ }
+ status = getOmx(name, &omx);
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = reply->writeStrongBinder(IInterface::asBinder(omx));
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
diff --git a/media/libmedia/include/media/IMediaCodecService.h b/media/libmedia/include/media/IMediaCodecService.h
new file mode 100644
index 0000000..59fb1c0
--- /dev/null
+++ b/media/libmedia/include/media/IMediaCodecService.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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_IMEDIACODECSERVICE_H
+#define ANDROID_IMEDIACODECSERVICE_H
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <media/IDataSource.h>
+#include <media/IOMX.h>
+#include <media/IOMXStore.h>
+
+namespace android {
+
+class IMediaCodecService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaCodecService);
+
+ virtual sp<IOMX> getOMX() = 0;
+ virtual sp<IOMXStore> getOMXStore() = 0;
+};
+
+class BnMediaCodecService: public BnInterface<IMediaCodecService>
+{
+public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IMEDIACODECSERVICE_H
diff --git a/media/libmedia/include/media/IOMXStore.h b/media/libmedia/include/media/IOMXStore.h
new file mode 100644
index 0000000..628db70
--- /dev/null
+++ b/media/libmedia/include/media/IOMXStore.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009 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_IOMXSTORE_H_
+
+#define ANDROID_IOMXSTORE_H_
+
+#include <media/IOMX.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+
+#include <vector>
+#include <string>
+
+namespace android {
+
+using hardware::media::omx::V1_0::IOmxStore;
+
+class IOMXStore : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMXStore);
+
+ struct Attribute {
+ std::string key;
+ std::string value;
+ };
+
+ struct NodeInfo {
+ std::string name;
+ std::string owner;
+ std::vector<Attribute> attributes;
+ };
+
+ struct RoleInfo {
+ std::string role;
+ std::string type;
+ bool isEncoder;
+ bool preferPlatformNodes;
+ std::vector<NodeInfo> nodes;
+ };
+
+ virtual status_t listServiceAttributes(
+ std::vector<Attribute>* attributes) = 0;
+
+ virtual status_t getNodePrefix(std::string* prefix) = 0;
+
+ virtual status_t listRoles(std::vector<RoleInfo>* roleList) = 0;
+
+ virtual status_t getOmx(const std::string& name, sp<IOMX>* omx) = 0;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BnOMXStore : public BnInterface<IOMXStore> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IOMX_H_
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8645680..246c746 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -729,13 +729,25 @@
mExtractorDeathListener = new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
binder->linkToDeath(mExtractorDeathListener);
- sp<IOmx> omx = IOmx::getService();
- if (omx == nullptr) {
- ALOGE("IOmx service is not available");
- return NULL;
+ if (property_get_bool("persist.media.treble_omx", true)) {
+ // Treble IOmx
+ sp<IOmx> omx = IOmx::getService();
+ if (omx == nullptr) {
+ ALOGE("Treble IOmx not available");
+ return NULL;
+ }
+ mCodecDeathListener = new ServiceDeathNotifier(omx, p, MEDIACODEC_PROCESS_DEATH);
+ omx->linkToDeath(mCodecDeathListener, 0);
+ } else {
+ // Legacy IOMX
+ binder = sm->getService(String16("media.codec"));
+ if (binder == NULL) {
+ ALOGE("codec service not available");
+ return NULL;
+ }
+ mCodecDeathListener = new ServiceDeathNotifier(binder, p, MEDIACODEC_PROCESS_DEATH);
+ binder->linkToDeath(mCodecDeathListener);
}
- mCodecDeathListener = new ServiceDeathNotifier(omx, p, MEDIACODEC_PROCESS_DEATH);
- omx->linkToDeath(mCodecDeathListener, 0);
if (!p->hardwareOutput()) {
Mutex::Autolock l(mLock);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index f2565dd..6400481 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -450,14 +450,27 @@
}
sCameraChecked = true;
- sp<IOmx> omx = IOmx::getService();
- if (omx == nullptr) {
- ALOGE("IOmx service is not available");
- return NO_INIT;
+ if (property_get_bool("persist.media.treble_omx", true)) {
+ // Treble IOmx
+ sp<IOmx> omx = IOmx::getService();
+ if (omx == nullptr) {
+ ALOGE("Treble IOmx not available");
+ return NO_INIT;
+ }
+ mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
+ MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+ omx->linkToDeath(mCodecDeathListener, 0);
+ } else {
+ // Legacy IOMX
+ binder = sm->getService(String16("media.codec"));
+ if (binder == NULL) {
+ ALOGE("Unable to connect to media codec service");
+ return NO_INIT;
+ }
+ mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
+ MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+ binder->linkToDeath(mCodecDeathListener);
}
- mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
- MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
- omx->linkToDeath(mCodecDeathListener, 0);
return OK;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d9fdfe3..a7a1b05 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -28,6 +28,8 @@
#include <media/stagefright/ACodec.h>
+#include <binder/MemoryDealer.h>
+
#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -573,6 +575,8 @@
memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
changeState(mUninitializedState);
+
+ mTrebleFlag = false;
}
ACodec::~ACodec() {
@@ -824,7 +828,11 @@
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
- CHECK(mAllocator[portIndex] == NULL);
+ if (getTrebleFlag()) {
+ CHECK(mAllocator[portIndex] == NULL);
+ } else {
+ CHECK(mDealer[portIndex] == NULL);
+ }
CHECK(mBuffers[portIndex].isEmpty());
status_t err;
@@ -866,10 +874,7 @@
}
}
- size_t alignment = 32; // This is the value currently returned by
- // MemoryDealer::getAllocationAlignment().
- // TODO: Fix this when Treble has
- // MemoryHeap/MemoryDealer.
+ size_t alignment = MemoryDealer::getAllocationAlignment();
ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
mComponentName.c_str(),
@@ -891,15 +896,18 @@
}
if (mode != IOMX::kPortModePresetSecureBuffer) {
- mAllocator[portIndex] = TAllocator::getService("ashmem");
- if (mAllocator[portIndex] == nullptr) {
- ALOGE("hidl allocator on port %d is null",
- (int)portIndex);
- return NO_MEMORY;
+ if (getTrebleFlag()) {
+ mAllocator[portIndex] = TAllocator::getService("ashmem");
+ if (mAllocator[portIndex] == nullptr) {
+ ALOGE("hidl allocator on port %d is null",
+ (int)portIndex);
+ return NO_MEMORY;
+ }
+ } else {
+ size_t totalSize = def.nBufferCountActual *
+ (alignedSize + alignedConvSize);
+ mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
}
- // TODO: When Treble has MemoryHeap/MemoryDealer, we should
- // specify the heap size to be
- // def.nBufferCountActual * (alignedSize + alignedConvSize).
}
const sp<AMessage> &format =
@@ -928,55 +936,23 @@
: new SecureBuffer(format, native_handle, bufSize);
info.mCodecData = info.mData;
} else {
- bool success;
- auto transStatus = mAllocator[portIndex]->allocate(
- bufSize,
- [&success, &hidlMemToken](
- bool s,
- hidl_memory const& m) {
- success = s;
- hidlMemToken = m;
- });
-
- if (!transStatus.isOk()) {
- ALOGE("hidl's AshmemAllocator failed at the "
- "transport: %s",
- transStatus.description().c_str());
- return NO_MEMORY;
- }
- if (!success) {
- return NO_MEMORY;
- }
- hidlMem = mapMemory(hidlMemToken);
- if (hidlMem == nullptr) {
- return NO_MEMORY;
- }
- err = mOMXNode->useBuffer(
- portIndex, hidlMemToken, &info.mBufferID);
-
- if (mode == IOMX::kPortModeDynamicANWBuffer) {
- VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
- (void*)hidlMem->getPointer());
- metaData->nFenceFd = -1;
- }
-
- info.mCodecData = new SharedMemoryBuffer(
- format, hidlMem);
- info.mCodecRef = hidlMem;
-
- // if we require conversion, allocate conversion buffer for client use;
- // otherwise, reuse codec buffer
- if (mConverter[portIndex] != NULL) {
- CHECK_GT(conversionBufferSize, (size_t)0);
+ if (getTrebleFlag()) {
bool success;
- mAllocator[portIndex]->allocate(
- conversionBufferSize,
+ auto transStatus = mAllocator[portIndex]->allocate(
+ bufSize,
[&success, &hidlMemToken](
bool s,
hidl_memory const& m) {
success = s;
hidlMemToken = m;
});
+
+ if (!transStatus.isOk()) {
+ ALOGE("hidl's AshmemAllocator failed at the "
+ "transport: %s",
+ transStatus.description().c_str());
+ return NO_MEMORY;
+ }
if (!success) {
return NO_MEMORY;
}
@@ -984,8 +960,67 @@
if (hidlMem == nullptr) {
return NO_MEMORY;
}
- info.mData = new SharedMemoryBuffer(format, hidlMem);
- info.mMemRef = hidlMem;
+ err = mOMXNode->useBuffer(
+ portIndex, hidlMemToken, &info.mBufferID);
+ } else {
+ mem = mDealer[portIndex]->allocate(bufSize);
+ if (mem == NULL || mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
+
+ err = mOMXNode->useBuffer(
+ portIndex, mem, &info.mBufferID);
+ }
+
+ if (mode == IOMX::kPortModeDynamicANWBuffer) {
+ VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
+ getTrebleFlag() ?
+ (void*)hidlMem->getPointer() : mem->pointer());
+ metaData->nFenceFd = -1;
+ }
+
+ if (getTrebleFlag()) {
+ info.mCodecData = new SharedMemoryBuffer(
+ format, hidlMem);
+ info.mCodecRef = hidlMem;
+ } else {
+ info.mCodecData = new SharedMemoryBuffer(
+ format, mem);
+ info.mCodecRef = mem;
+ }
+
+ // if we require conversion, allocate conversion buffer for client use;
+ // otherwise, reuse codec buffer
+ if (mConverter[portIndex] != NULL) {
+ CHECK_GT(conversionBufferSize, (size_t)0);
+ if (getTrebleFlag()) {
+ bool success;
+ mAllocator[portIndex]->allocate(
+ conversionBufferSize,
+ [&success, &hidlMemToken](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ hidlMemToken = m;
+ });
+ if (!success) {
+ return NO_MEMORY;
+ }
+ hidlMem = mapMemory(hidlMemToken);
+ if (hidlMem == nullptr) {
+ return NO_MEMORY;
+ }
+ info.mData = new SharedMemoryBuffer(format, hidlMem);
+ info.mMemRef = hidlMem;
+ } else {
+ mem = mDealer[portIndex]->allocate(
+ conversionBufferSize);
+ if (mem == NULL|| mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
+ info.mData = new SharedMemoryBuffer(format, mem);
+ info.mMemRef = mem;
+ }
} else {
info.mData = info.mCodecData;
info.mMemRef = info.mCodecRef;
@@ -1546,7 +1581,11 @@
}
}
- mAllocator[portIndex].clear();
+ if (getTrebleFlag()) {
+ mAllocator[portIndex].clear();
+ } else {
+ mDealer[portIndex].clear();
+ }
return err;
}
@@ -6212,8 +6251,13 @@
if (mDeathNotifier != NULL) {
if (mCodec->mOMXNode != NULL) {
- auto tOmxNode = mCodec->mOMXNode->getHalInterface();
- tOmxNode->unlinkToDeath(mDeathNotifier);
+ if (mCodec->getTrebleFlag()) {
+ auto tOmxNode = mCodec->mOMXNode->getHalInterface();
+ tOmxNode->unlinkToDeath(mDeathNotifier);
+ } else {
+ sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
+ binder->unlinkToDeath(mDeathNotifier);
+ }
}
mDeathNotifier.clear();
}
@@ -6361,7 +6405,8 @@
componentName = matchingCodecs[matchIndex];
OMXClient client;
- if (client.connect(owners[matchIndex].c_str()) != OK) {
+ bool trebleFlag;
+ if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) {
mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
return false;
}
@@ -6374,6 +6419,7 @@
androidSetThreadPriority(tid, prevPriority);
if (err == OK) {
+ mCodec->setTrebleFlag(trebleFlag);
break;
} else {
ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
@@ -6395,9 +6441,17 @@
}
mDeathNotifier = new DeathNotifier(notify);
- auto tOmxNode = omxNode->getHalInterface();
- if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
- mDeathNotifier.clear();
+ if (mCodec->getTrebleFlag()) {
+ auto tOmxNode = omxNode->getHalInterface();
+ if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+ mDeathNotifier.clear();
+ }
+ } else {
+ if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
+ // This was a local binder, if it dies so do we, we won't care
+ // about any notifications in the afterlife.
+ mDeathNotifier.clear();
+ }
}
notify = new AMessage(kWhatOMXMessageList, mCodec);
@@ -7804,7 +7858,11 @@
mCodec->mBuffers[kPortIndexOutput].size());
err = FAILED_TRANSACTION;
} else {
- mCodec->mAllocator[kPortIndexOutput].clear();
+ if (mCodec->getTrebleFlag()) {
+ mCodec->mAllocator[kPortIndexOutput].clear();
+ } else {
+ mCodec->mDealer[kPortIndexOutput].clear();
+ }
}
if (err == OK) {
@@ -8406,4 +8464,12 @@
return OK;
}
+void ACodec::setTrebleFlag(bool trebleFlag) {
+ mTrebleFlag = trebleFlag;
+}
+
+bool ACodec::getTrebleFlag() const {
+ return mTrebleFlag;
+}
+
} // namespace android
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 54265a4..4feba37 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -24,6 +24,7 @@
#include <media/IMediaCodecList.h>
#include <media/IMediaPlayerService.h>
+#include <media/IMediaCodecService.h>
#include <media/MediaCodecInfo.h>
#include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index cd07262..5f50e46 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -25,6 +25,7 @@
#include <cutils/properties.h>
#include <binder/IServiceManager.h>
+#include <media/IMediaCodecService.h>
#include <media/stagefright/OMXClient.h>
#include <media/IOMX.h>
@@ -36,22 +37,71 @@
OMXClient::OMXClient() {
}
-status_t OMXClient::connect(const char* name) {
+status_t OMXClient::connect() {
+ return connect("default", nullptr);
+}
+
+status_t OMXClient::connect(bool* trebleFlag) {
+ if (property_get_bool("persist.media.treble_omx", true)) {
+ if (trebleFlag != nullptr) {
+ *trebleFlag = true;
+ }
+ return connectTreble();
+ }
+ if (trebleFlag != nullptr) {
+ *trebleFlag = false;
+ }
+ return connectLegacy();
+}
+
+status_t OMXClient::connect(const char* name, bool* trebleFlag) {
+ if (property_get_bool("persist.media.treble_omx", true)) {
+ if (trebleFlag != nullptr) {
+ *trebleFlag = true;
+ }
+ return connectTreble(name);
+ }
+ if (trebleFlag != nullptr) {
+ *trebleFlag = false;
+ }
+ return connectLegacy();
+}
+
+status_t OMXClient::connectLegacy() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> codecbinder = sm->getService(String16("media.codec"));
+ sp<IMediaCodecService> codecservice = interface_cast<IMediaCodecService>(codecbinder);
+
+ if (codecservice.get() == NULL) {
+ ALOGE("Cannot obtain IMediaCodecService");
+ return NO_INIT;
+ }
+
+ mOMX = codecservice->getOMX();
+ if (mOMX.get() == NULL) {
+ ALOGE("Cannot obtain mediacodec IOMX");
+ return NO_INIT;
+ }
+
+ return OK;
+}
+
+status_t OMXClient::connectTreble(const char* name) {
using namespace ::android::hardware::media::omx::V1_0;
if (name == nullptr) {
name = "default";
}
sp<IOmx> tOmx = IOmx::getService(name);
if (tOmx.get() == nullptr) {
- ALOGE("Cannot obtain IOmx service.");
+ ALOGE("Cannot obtain Treble IOmx.");
return NO_INIT;
}
if (!tOmx->isRemote()) {
- ALOGE("IOmx service running in passthrough mode.");
+ ALOGE("Treble IOmx is in passthrough mode.");
return NO_INIT;
}
mOMX = new utils::LWOmx(tOmx);
- ALOGI("IOmx service obtained");
+ ALOGI("Treble IOmx obtained");
return OK;
}
@@ -59,8 +109,4 @@
mOMX.clear();
}
-sp<IOMX> OMXClient::interface() {
- return mOMX;
-}
-
} // namespace android
diff --git a/media/libstagefright/OmxInfoBuilder.cpp b/media/libstagefright/OmxInfoBuilder.cpp
index 1cd8873..063d13e 100644
--- a/media/libstagefright/OmxInfoBuilder.cpp
+++ b/media/libstagefright/OmxInfoBuilder.cpp
@@ -24,6 +24,8 @@
#include <utils/Log.h>
#include <cutils/properties.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaCodecService.h>
#include <media/stagefright/foundation/MediaDefs.h>
#include <media/stagefright/OmxInfoBuilder.h>
#include <media/stagefright/ACodec.h>
@@ -33,6 +35,7 @@
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <media/stagefright/omx/OMXUtils.h>
+#include <media/IOMXStore.h>
#include <media/IOMX.h>
#include <media/omx/1.0/WOmx.h>
@@ -45,24 +48,10 @@
namespace android {
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using namespace ::android::hardware::media::omx::V1_0;
-
namespace /* unnamed */ {
-bool hasPrefix(const hidl_string& s, const char* prefix) {
- return strncmp(s.c_str(), prefix, strlen(prefix)) == 0;
-}
-
-struct HidlStringCompare {
- bool operator()(const hidl_string& lhs, const hidl_string& rhs) const {
- return strcmp(lhs.c_str(), rhs.c_str()) < 0;
- }
-};
-
status_t queryCapabilities(
- const IOmxStore::NodeInfo& node, const char* mime, bool isEncoder,
+ const IOMXStore::NodeInfo& node, const char* mime, bool isEncoder,
MediaCodecInfo::CapabilitiesWriter* caps) {
sp<ACodec> codec = new ACodec();
status_t err = codec->queryCapabilities(
@@ -73,13 +62,14 @@
for (const auto& attribute : node.attributes) {
// All features have an int32 value except
// "feature-bitrate-modes", which has a string value.
- if (hasPrefix(attribute.key, "feature-") &&
- !hasPrefix(attribute.key, "feature-bitrate-modes")) {
- // If this attribute.key is a feature that is not bitrate modes,
- // add an int32 value.
+ if ((attribute.key.compare(0, 8, "feature-") == 0) &&
+ (attribute.key.compare(8, 15, "bitrate-modes")
+ != 0)) {
+ // If this attribute.key is a feature that is not a bitrate
+ // control, add an int32 value.
caps->addDetail(
attribute.key.c_str(),
- hasPrefix(attribute.value, "1") ? 1 : 0);
+ attribute.value == "1" ? 1 : 0);
} else {
// Non-feature attributes
caps->addDetail(
@@ -95,61 +85,138 @@
}
status_t OmxInfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
- hidl_vec<IOmxStore::RoleInfo> roles;
+ bool treble;
+ sp<IOMX> omx;
+ std::vector<IOMXStore::RoleInfo> roles;
- // Obtain IOmxStore
- sp<IOmxStore> omxStore = IOmxStore::tryGetService();
- if (omxStore == nullptr) {
- omxStore = IOmxStore::tryGetService("vendor");
+ treble = property_get_bool("persist.media.treble_omx", true);
+ if (treble) {
+ using namespace ::android::hardware::media::omx::V1_0;
+ using ::android::hardware::hidl_vec;
+ using ::android::hardware::hidl_string;
+
+ // Obtain IOmxStore
+ sp<IOmxStore> omxStore = IOmxStore::getService();
if (omxStore == nullptr) {
- omxStore = IOmxStore::tryGetService("platform");
- if (omxStore == nullptr) {
- ALOGE("Cannot find an IOmxStore service.");
- return NO_INIT;
- }
+ ALOGE("Cannot connect to an IOmxStore instance.");
+ return NO_INIT;
}
- }
- // List service attributes (global settings)
- Status status;
- hidl_vec<IOmxStore::ServiceAttribute> serviceAttributes;
- auto transStatus = omxStore->listServiceAttributes(
- [&status, &serviceAttributes] (
- Status inStatus,
- const hidl_vec<IOmxStore::ServiceAttribute>& inAttributes) {
- status = inStatus;
- serviceAttributes = inAttributes;
- });
- if (!transStatus.isOk()) {
- ALOGE("Fail to obtain global settings from IOmxStore.");
- return NO_INIT;
- }
- if (status != Status::OK) {
- ALOGE("IOmxStore reports parsing error.");
- return NO_INIT;
- }
- for (const auto& p : serviceAttributes) {
- writer->addGlobalSetting(
- p.key.c_str(), p.value.c_str());
- }
+ // List service attributes (global settings)
+ Status status;
+ hidl_vec<IOmxStore::ServiceAttribute> serviceAttributes;
+ auto transStatus = omxStore->listServiceAttributes(
+ [&status, &serviceAttributes]
+ (Status inStatus, const hidl_vec<IOmxStore::ServiceAttribute>&
+ inAttributes) {
+ status = inStatus;
+ serviceAttributes = inAttributes;
+ });
+ if (!transStatus.isOk()) {
+ ALOGE("Fail to obtain global settings from IOmxStore.");
+ return NO_INIT;
+ }
+ if (status != Status::OK) {
+ ALOGE("IOmxStore reports parsing error.");
+ return NO_INIT;
+ }
+ for (const auto& p : serviceAttributes) {
+ writer->addGlobalSetting(
+ p.key.c_str(), p.value.c_str());
+ }
- transStatus = omxStore->listRoles(
- [&roles] (
- const hidl_vec<IOmxStore::RoleInfo>& inRoleList) {
- roles = inRoleList;
- });
- if (!transStatus.isOk()) {
- ALOGE("Fail to obtain codec roles from IOmxStore.");
- return NO_INIT;
+ // List roles and convert to IOMXStore's format
+ transStatus = omxStore->listRoles(
+ [&roles]
+ (const hidl_vec<IOmxStore::RoleInfo>& inRoleList) {
+ roles.reserve(inRoleList.size());
+ for (const auto& inRole : inRoleList) {
+ IOMXStore::RoleInfo role;
+ role.role = inRole.role;
+ role.type = inRole.type;
+ role.isEncoder = inRole.isEncoder;
+ role.preferPlatformNodes = inRole.preferPlatformNodes;
+ std::vector<IOMXStore::NodeInfo>& nodes =
+ role.nodes;
+ nodes.reserve(inRole.nodes.size());
+ for (const auto& inNode : inRole.nodes) {
+ IOMXStore::NodeInfo node;
+ node.name = inNode.name;
+ node.owner = inNode.owner;
+ std::vector<IOMXStore::Attribute>& attributes =
+ node.attributes;
+ attributes.reserve(inNode.attributes.size());
+ for (const auto& inAttr : inNode.attributes) {
+ IOMXStore::Attribute attr;
+ attr.key = inAttr.key;
+ attr.value = inAttr.value;
+ attributes.push_back(std::move(attr));
+ }
+ nodes.push_back(std::move(node));
+ }
+ roles.push_back(std::move(role));
+ }
+ });
+ if (!transStatus.isOk()) {
+ ALOGE("Fail to obtain codec roles from IOmxStore.");
+ return NO_INIT;
+ }
+ } else {
+ // Obtain IOMXStore
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == nullptr) {
+ ALOGE("Cannot obtain the default service manager.");
+ return NO_INIT;
+ }
+ sp<IBinder> codecBinder = sm->getService(String16("media.codec"));
+ if (codecBinder == nullptr) {
+ ALOGE("Cannot obtain the media codec service.");
+ return NO_INIT;
+ }
+ sp<IMediaCodecService> codecService =
+ interface_cast<IMediaCodecService>(codecBinder);
+ if (codecService == nullptr) {
+ ALOGE("Wrong type of media codec service obtained.");
+ return NO_INIT;
+ }
+ omx = codecService->getOMX();
+ if (omx == nullptr) {
+ ALOGE("Cannot connect to an IOMX instance.");
+ }
+ sp<IOMXStore> omxStore = codecService->getOMXStore();
+ if (omxStore == nullptr) {
+ ALOGE("Cannot connect to an IOMXStore instance.");
+ return NO_INIT;
+ }
+
+ // List service attributes (global settings)
+ std::vector<IOMXStore::Attribute> serviceAttributes;
+ status_t status = omxStore->listServiceAttributes(&serviceAttributes);
+ if (status != OK) {
+ ALOGE("Fail to obtain global settings from IOMXStore.");
+ return NO_INIT;
+ }
+ for (const auto& p : serviceAttributes) {
+ writer->addGlobalSetting(
+ p.key.c_str(), p.value.c_str());
+ }
+
+ // List roles
+ status = omxStore->listRoles(&roles);
+ if (status != OK) {
+ ALOGE("Fail to obtain codec roles from IOMXStore.");
+ return NO_INIT;
+ }
}
// Convert roles to lists of codecs
- // codec name -> index into swCodecs/hwCodecs
- std::map<hidl_string,
- std::unique_ptr<MediaCodecInfoWriter>,
- HidlStringCompare>
- swCodecName2Info, hwCodecName2Info;
+ // codec name -> index into swCodecs
+ std::map<std::string, std::unique_ptr<MediaCodecInfoWriter> >
+ swCodecName2Info;
+ // codec name -> index into hwCodecs
+ std::map<std::string, std::unique_ptr<MediaCodecInfoWriter> >
+ hwCodecName2Info;
// owner name -> MediaCodecInfo
// This map will be used to obtain the correct IOmx service(s) needed for
// creating IOmxNode instances and querying capabilities.
@@ -163,10 +230,10 @@
// If preferPlatformNodes is true, hardware nodes must be added after
// platform (software) nodes. hwCodecs is used to hold hardware nodes
// that need to be added after software nodes for the same role.
- std::vector<const IOmxStore::NodeInfo*> hwCodecs;
+ std::vector<const IOMXStore::NodeInfo*> hwCodecs;
for (const auto& node : role.nodes) {
const auto& nodeName = node.name;
- bool isSoftware = hasPrefix(nodeName, "OMX.google");
+ bool isSoftware = nodeName.compare(0, 10, "OMX.google") == 0;
MediaCodecInfoWriter* info;
if (isSoftware) {
auto c2i = swCodecName2Info.find(nodeName);
diff --git a/media/libstagefright/filters/Android.bp b/media/libstagefright/filters/Android.bp
index 64a6197..e944224 100644
--- a/media/libstagefright/filters/Android.bp
+++ b/media/libstagefright/filters/Android.bp
@@ -13,12 +13,8 @@
"ZeroFilter.cpp",
],
- header_libs: [
- "media_plugin_headers",
- ],
-
- export_include_dirs: [
- ".",
+ include_dirs: [
+ "frameworks/native/include/media/openmax",
],
cflags: [
diff --git a/media/libstagefright/include/OmxNodeOwner.h b/media/libstagefright/include/OmxNodeOwner.h
new file mode 100644
index 0000000..64ec7f7
--- /dev/null
+++ b/media/libstagefright/include/OmxNodeOwner.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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 OMX_NODE_OWNER_H_
+
+#define OMX_NODE_OWNER_H_
+
+namespace android {
+
+struct OMXNodeInstance;
+
+/**
+ * This struct is needed to separate OMX from OMXNodeInstance.
+ *
+ * TODO: This might not be needed after Treble transition is complete.
+ */
+struct OmxNodeOwner {
+ virtual status_t freeNode(const sp<OMXNodeInstance> &instance) = 0;
+ virtual ~OmxNodeOwner() {}
+};
+
+}
+
+#endif // OMX_NODE_OWNER_H_
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index d1a9d25..424246d 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -95,6 +95,11 @@
static status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]);
+ // Save the flag.
+ void setTrebleFlag(bool trebleFlag);
+ // Return the saved flag.
+ bool getTrebleFlag() const;
+
protected:
virtual ~ACodec();
@@ -228,7 +233,9 @@
sp<IOMX> mOMX;
sp<IOMXNode> mOMXNode;
int32_t mNodeGeneration;
+ bool mTrebleFlag;
sp<TAllocator> mAllocator[2];
+ sp<MemoryDealer> mDealer[2];
bool mUsingNativeWindow;
sp<ANativeWindow> mNativeWindow;
diff --git a/media/libstagefright/include/media/stagefright/OMXClient.h b/media/libstagefright/include/media/stagefright/OMXClient.h
index e7b9be5..b1864b8 100644
--- a/media/libstagefright/include/media/stagefright/OMXClient.h
+++ b/media/libstagefright/include/media/stagefright/OMXClient.h
@@ -18,19 +18,25 @@
#define OMX_CLIENT_H_
-namespace android {
+#include <media/IOMX.h>
-class IOMX;
+namespace android {
class OMXClient {
public:
OMXClient();
- status_t connect(const char* name = "default");
+ status_t connect();
+ status_t connect(bool* trebleFlag);
+ status_t connect(const char* name, bool* trebleFlag = nullptr);
+ status_t connectLegacy();
+ status_t connectTreble(const char* name = "default");
void disconnect();
- sp<IOMX> interface();
+ sp<IOMX> interface() {
+ return mOMX;
+ }
private:
sp<IOMX> mOMX;
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 8539864..f388a48 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -9,6 +9,8 @@
"FrameDropper.cpp",
"GraphicBufferSource.cpp",
"BWGraphicBufferSource.cpp",
+ "OMX.cpp",
+ "OMXStore.cpp",
"OMXMaster.cpp",
"OMXNodeInstance.cpp",
"OMXUtils.cpp",
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
new file mode 100644
index 0000000..09c4019
--- /dev/null
+++ b/media/libstagefright/omx/OMX.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#include <inttypes.h>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OMX"
+#include <utils/Log.h>
+
+#include <dlfcn.h>
+
+#include <media/stagefright/omx/OMX.h>
+#include <media/stagefright/omx/OMXNodeInstance.h>
+#include <media/stagefright/omx/BWGraphicBufferSource.h>
+#include <media/stagefright/omx/OMXMaster.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+// node ids are created by concatenating the pid with a 16-bit counter
+static size_t kMaxNodeInstances = (1 << 16);
+
+OMX::OMX() : mMaster(new OMXMaster), mParser() {
+}
+
+OMX::~OMX() {
+ delete mMaster;
+ mMaster = NULL;
+}
+
+void OMX::binderDied(const wp<IBinder> &the_late_who) {
+ sp<OMXNodeInstance> instance;
+
+ {
+ Mutex::Autolock autoLock(mLock);
+
+ ssize_t index = mLiveNodes.indexOfKey(the_late_who);
+
+ if (index < 0) {
+ ALOGE("b/27597103, nonexistent observer on binderDied");
+ android_errorWriteLog(0x534e4554, "27597103");
+ return;
+ }
+
+ instance = mLiveNodes.editValueAt(index);
+ mLiveNodes.removeItemsAt(index);
+ }
+
+ instance->onObserverDied();
+}
+
+status_t OMX::listNodes(List<ComponentInfo> *list) {
+ list->clear();
+
+ OMX_U32 index = 0;
+ char componentName[256];
+ while (mMaster->enumerateComponents(
+ componentName, sizeof(componentName), index) == OMX_ErrorNone) {
+ list->push_back(ComponentInfo());
+ ComponentInfo &info = *--list->end();
+
+ info.mName = componentName;
+
+ Vector<String8> roles;
+ OMX_ERRORTYPE err =
+ mMaster->getRolesOfComponent(componentName, &roles);
+
+ if (err == OMX_ErrorNone) {
+ for (OMX_U32 i = 0; i < roles.size(); ++i) {
+ info.mRoles.push_back(roles[i]);
+ }
+ }
+
+ ++index;
+ }
+
+ return OK;
+}
+
+status_t OMX::allocateNode(
+ const char *name, const sp<IOMXObserver> &observer,
+ sp<IOMXNode> *omxNode) {
+ Mutex::Autolock autoLock(mLock);
+
+ omxNode->clear();
+
+ if (mLiveNodes.size() == kMaxNodeInstances) {
+ return NO_MEMORY;
+ }
+
+ sp<OMXNodeInstance> instance = new OMXNodeInstance(this, observer, name);
+
+ OMX_COMPONENTTYPE *handle;
+ OMX_ERRORTYPE err = mMaster->makeComponentInstance(
+ name, &OMXNodeInstance::kCallbacks,
+ instance.get(), &handle);
+
+ if (err != OMX_ErrorNone) {
+ ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err);
+
+ return StatusFromOMXError(err);
+ }
+ instance->setHandle(handle);
+
+ // Find quirks from mParser
+ const auto& codec = mParser.getCodecMap().find(name);
+ if (codec == mParser.getCodecMap().cend()) {
+ ALOGW("Failed to obtain quirks for omx component '%s' from XML files",
+ name);
+ } else {
+ uint32_t quirks = 0;
+ for (const auto& quirk : codec->second.quirkSet) {
+ if (quirk == "requires-allocate-on-input-ports") {
+ quirks |= OMXNodeInstance::
+ kRequiresAllocateBufferOnInputPorts;
+ }
+ if (quirk == "requires-allocate-on-output-ports") {
+ quirks |= OMXNodeInstance::
+ kRequiresAllocateBufferOnOutputPorts;
+ }
+ }
+ instance->setQuirks(quirks);
+ }
+
+ mLiveNodes.add(IInterface::asBinder(observer), instance);
+ IInterface::asBinder(observer)->linkToDeath(this);
+
+ *omxNode = instance;
+
+ return OK;
+}
+
+status_t OMX::freeNode(const sp<OMXNodeInstance> &instance) {
+ if (instance == NULL) {
+ return OK;
+ }
+
+ {
+ Mutex::Autolock autoLock(mLock);
+ ssize_t index = mLiveNodes.indexOfKey(IInterface::asBinder(instance->observer()));
+ if (index < 0) {
+ // This could conceivably happen if the observer dies at roughly the
+ // same time that a client attempts to free the node explicitly.
+
+ // NOTE: it's guaranteed that this method is called at most once per
+ // instance.
+ ALOGV("freeNode: instance already removed from book-keeping.");
+ } else {
+ mLiveNodes.removeItemsAt(index);
+ IInterface::asBinder(instance->observer())->unlinkToDeath(this);
+ }
+ }
+
+ CHECK(instance->handle() != NULL);
+ OMX_ERRORTYPE err = mMaster->destroyComponentInstance(
+ static_cast<OMX_COMPONENTTYPE *>(instance->handle()));
+ ALOGV("freeNode: handle destroyed: %p", instance->handle());
+
+ return StatusFromOMXError(err);
+}
+
+status_t OMX::createInputSurface(
+ sp<IGraphicBufferProducer> *bufferProducer,
+ sp<IGraphicBufferSource> *bufferSource) {
+ if (bufferProducer == NULL || bufferSource == NULL) {
+ ALOGE("b/25884056");
+ return BAD_VALUE;
+ }
+
+ sp<GraphicBufferSource> graphicBufferSource = new GraphicBufferSource();
+ status_t err = graphicBufferSource->initCheck();
+ if (err != OK) {
+ ALOGE("Failed to create persistent input surface: %s (%d)",
+ strerror(-err), err);
+ return err;
+ }
+
+ *bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
+ *bufferSource = new BWGraphicBufferSource(graphicBufferSource);
+
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index ff58eb6..015a148 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -344,7 +344,7 @@
////////////////////////////////////////////////////////////////////////////////
OMXNodeInstance::OMXNodeInstance(
- Omx *owner, const sp<IOMXObserver> &observer, const char *name)
+ OmxNodeOwner *owner, const sp<IOMXObserver> &observer, const char *name)
: mOwner(owner),
mHandle(NULL),
mObserver(observer),
diff --git a/media/libstagefright/omx/OMXStore.cpp b/media/libstagefright/omx/OMXStore.cpp
new file mode 100644
index 0000000..345336d
--- /dev/null
+++ b/media/libstagefright/omx/OMXStore.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2009 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 "OMXStore"
+#include <utils/Log.h>
+
+#include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/omx/OMX.h>
+#include <media/stagefright/omx/OMXStore.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include <map>
+#include <string>
+
+namespace android {
+
+namespace {
+ struct RoleProperties {
+ std::string type;
+ bool isEncoder;
+ bool preferPlatformNodes;
+ std::multimap<size_t, IOMXStore::NodeInfo> nodeList;
+ };
+} // Unnamed namespace
+
+OMXStore::OMXStore(
+ const char* owner,
+ const char* const* searchDirs,
+ const char* mainXmlName,
+ const char* performanceXmlName,
+ const char* profilingResultsXmlPath) {
+ MediaCodecsXmlParser parser(
+ searchDirs,
+ mainXmlName,
+ performanceXmlName,
+ profilingResultsXmlPath);
+ mParsingStatus = parser.getParsingStatus();
+
+ const auto& serviceAttributeMap = parser.getServiceAttributeMap();
+ mServiceAttributeList.reserve(serviceAttributeMap.size());
+ for (const auto& attributePair : serviceAttributeMap) {
+ Attribute attribute;
+ attribute.key = attributePair.first;
+ attribute.value = attributePair.second;
+ mServiceAttributeList.push_back(std::move(attribute));
+ }
+
+ const auto& roleMap = parser.getRoleMap();
+ mRoleList.reserve(roleMap.size());
+ for (const auto& rolePair : roleMap) {
+ RoleInfo role;
+ role.role = rolePair.first;
+ role.type = rolePair.second.type;
+ role.isEncoder = rolePair.second.isEncoder;
+ // TODO: Currently, preferPlatformNodes information is not available in
+ // the xml file. Once we have a way to provide this information, it
+ // should be parsed properly.
+ role.preferPlatformNodes = rolePair.first.compare(0, 5, "audio") == 0;
+ std::vector<NodeInfo>& nodeList = role.nodes;
+ nodeList.reserve(rolePair.second.nodeList.size());
+ for (const auto& nodePair : rolePair.second.nodeList) {
+ NodeInfo node;
+ node.name = nodePair.second.name;
+ node.owner = owner;
+ std::vector<Attribute>& attributeList = node.attributes;
+ attributeList.reserve(nodePair.second.attributeList.size());
+ for (const auto& attributePair : nodePair.second.attributeList) {
+ Attribute attribute;
+ attribute.key = attributePair.first;
+ attribute.value = attributePair.second;
+ attributeList.push_back(std::move(attribute));
+ }
+ nodeList.push_back(std::move(node));
+ }
+ mRoleList.push_back(std::move(role));
+ }
+
+ mPrefix = parser.getCommonPrefix();
+}
+
+status_t OMXStore::listServiceAttributes(std::vector<Attribute>* attributes) {
+ *attributes = mServiceAttributeList;
+ return mParsingStatus;
+}
+
+status_t OMXStore::getNodePrefix(std::string* prefix) {
+ *prefix = mPrefix;
+ return mParsingStatus;
+}
+
+status_t OMXStore::listRoles(std::vector<RoleInfo>* roleList) {
+ *roleList = mRoleList;
+ return mParsingStatus;
+}
+
+status_t OMXStore::getOmx(const std::string& name, sp<IOMX>* omx) {
+ *omx = new OMX();
+ return NO_ERROR;
+}
+
+OMXStore::~OMXStore() {
+}
+
+} // namespace android
+
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
index baa7b81..a6a9d3e 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Omx.h
@@ -20,13 +20,13 @@
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <media/stagefright/omx/OMXNodeInstance.h>
#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
namespace android {
struct OMXMaster;
-struct OMXNodeInstance;
namespace hardware {
namespace media {
@@ -50,9 +50,10 @@
using ::android::wp;
using ::android::OMXMaster;
+using ::android::OmxNodeOwner;
using ::android::OMXNodeInstance;
-struct Omx : public IOmx, public hidl_death_recipient {
+struct Omx : public IOmx, public hidl_death_recipient, public OmxNodeOwner {
Omx();
virtual ~Omx();
@@ -67,8 +68,8 @@
// Method from hidl_death_recipient
void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
- // Method for OMXNodeInstance
- status_t freeNode(sp<OMXNodeInstance> const& instance);
+ // Method from OmxNodeOwner
+ virtual status_t freeNode(sp<OMXNodeInstance> const& instance) override;
protected:
OMXMaster* mMaster;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMX.h b/media/libstagefright/omx/include/media/stagefright/omx/OMX.h
new file mode 100644
index 0000000..594b4c0
--- /dev/null
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMX.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 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_OMX_H_
+#define ANDROID_OMX_H_
+
+#include <media/IOMX.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+#include "OmxNodeOwner.h"
+
+namespace android {
+
+struct OMXMaster;
+struct OMXNodeInstance;
+
+class OMX : public BnOMX,
+ public OmxNodeOwner,
+ public IBinder::DeathRecipient {
+public:
+ OMX();
+
+ virtual status_t listNodes(List<ComponentInfo> *list);
+
+ virtual status_t allocateNode(
+ const char *name, const sp<IOMXObserver> &observer,
+ sp<IOMXNode> *omxNode);
+
+ virtual status_t createInputSurface(
+ sp<IGraphicBufferProducer> *bufferProducer,
+ sp<IGraphicBufferSource> *bufferSource);
+
+ virtual void binderDied(const wp<IBinder> &the_late_who);
+
+ virtual status_t freeNode(const sp<OMXNodeInstance>& instance);
+
+protected:
+ virtual ~OMX();
+
+private:
+ Mutex mLock;
+ OMXMaster *mMaster;
+ MediaCodecsXmlParser mParser;
+
+ KeyedVector<wp<IBinder>, sp<OMXNodeInstance> > mLiveNodes;
+
+ OMX(const OMX &);
+ OMX &operator=(const OMX &);
+};
+
+} // namespace android
+
+#endif // ANDROID_OMX_H_
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
index c436121..1065ca5 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXNodeInstance.h
@@ -25,9 +25,9 @@
#include <utils/threads.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
+#include "OmxNodeOwner.h"
#include <android/hidl/memory/1.0/IMemory.h>
-#include <media/stagefright/omx/1.0/Omx.h>
namespace android {
class GraphicBuffer;
@@ -35,12 +35,11 @@
class IOMXObserver;
struct OMXMaster;
class OMXBuffer;
-using IHidlMemory = hidl::memory::V1_0::IMemory;
-using hardware::media::omx::V1_0::implementation::Omx;
+typedef hidl::memory::V1_0::IMemory IHidlMemory;
struct OMXNodeInstance : public BnOMXNode {
OMXNodeInstance(
- Omx *owner, const sp<IOMXObserver> &observer, const char *name);
+ OmxNodeOwner *owner, const sp<IOMXObserver> &observer, const char *name);
void setHandle(OMX_HANDLETYPE handle);
@@ -123,7 +122,7 @@
Mutex mLock;
- Omx *mOwner;
+ OmxNodeOwner *mOwner;
OMX_HANDLETYPE mHandle;
sp<IOMXObserver> mObserver;
sp<CallbackDispatcher> mDispatcher;
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
new file mode 100644
index 0000000..e00d713
--- /dev/null
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OMXStore.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 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_OMXSTORE_H_
+#define ANDROID_OMXSTORE_H_
+
+#include <media/IOMXStore.h>
+#include <media/IOMX.h>
+#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
+
+#include <vector>
+#include <string>
+
+namespace android {
+
+class OMXStore : public BnOMXStore {
+public:
+ OMXStore(
+ const char* owner = "default",
+ const char* const* searchDirs
+ = MediaCodecsXmlParser::defaultSearchDirs,
+ const char* mainXmlName
+ = MediaCodecsXmlParser::defaultMainXmlName,
+ const char* performanceXmlName
+ = MediaCodecsXmlParser::defaultPerformanceXmlName,
+ const char* profilingResultsXmlPath
+ = MediaCodecsXmlParser::defaultProfilingResultsXmlPath);
+
+ status_t listServiceAttributes(
+ std::vector<Attribute>* attributes) override;
+
+ status_t getNodePrefix(std::string* prefix) override;
+
+ status_t listRoles(std::vector<RoleInfo>* roleList) override;
+
+ status_t getOmx(const std::string& name, sp<IOMX>* omx) override;
+
+ ~OMXStore() override;
+
+protected:
+ status_t mParsingStatus;
+ std::string mPrefix;
+ std::vector<Attribute> mServiceAttributeList;
+ std::vector<RoleInfo> mRoleList;
+};
+
+} // namespace android
+
+#endif // ANDROID_OMXSTORE_H_
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 86c7211..8092887 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -25,9 +25,11 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/IMediaHTTPService.h>
+#include <media/IMediaCodecService.h>
#include <media/MediaExtractor.h>
#include <media/MediaSource.h>
#include <media/OMXBuffer.h>
@@ -69,7 +71,7 @@
/////////////////////////////////////////////////////////////////////
Harness::Harness()
- : mInitCheck(NO_INIT) {
+ : mInitCheck(NO_INIT), mUseTreble(false) {
mInitCheck = initOMX();
}
@@ -81,12 +83,21 @@
}
status_t Harness::initOMX() {
- using namespace ::android::hardware::media::omx::V1_0;
- sp<IOmx> tOmx = IOmx::getService();
- if (tOmx == nullptr) {
- return NO_INIT;
+ if (property_get_bool("persist.media.treble_omx", true)) {
+ using namespace ::android::hardware::media::omx::V1_0;
+ sp<IOmx> tOmx = IOmx::getService();
+ if (tOmx == nullptr) {
+ return NO_INIT;
+ }
+ mOMX = new utils::LWOmx(tOmx);
+ mUseTreble = true;
+ } else {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.codec"));
+ sp<IMediaCodecService> service = interface_cast<IMediaCodecService>(binder);
+ mOMX = service->getOMX();
+ mUseTreble = false;
}
- mOMX = new utils::LWOmx(tOmx);
return mOMX != 0 ? OK : NO_INIT;
}
@@ -214,19 +225,25 @@
for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
Buffer buffer;
buffer.mFlags = 0;
- bool success;
- auto transStatus = mAllocator->allocate(def.nBufferSize,
- [&success, &buffer](
- bool s,
- hidl_memory const& m) {
- success = s;
- buffer.mHidlMemory = m;
- });
- EXPECT(transStatus.isOk(),
- "Cannot call allocator");
- EXPECT(success,
- "Cannot allocate memory");
- err = mOMXNode->useBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
+ if (mUseTreble) {
+ bool success;
+ auto transStatus = mAllocator->allocate(def.nBufferSize,
+ [&success, &buffer](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ EXPECT(transStatus.isOk(),
+ "Cannot call allocator");
+ EXPECT(success,
+ "Cannot allocate memory");
+ err = mOMXNode->useBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
+ } else {
+ buffer.mMemory = mDealer->allocate(def.nBufferSize);
+ CHECK(buffer.mMemory != NULL);
+ err = mOMXNode->useBuffer(portIndex, buffer.mMemory, &buffer.mID);
+ }
EXPECT_SUCCESS(err, "useBuffer");
@@ -295,11 +312,13 @@
return OK;
}
- mAllocator = IAllocator::getService("ashmem");
- EXPECT(mAllocator != nullptr,
- "Cannot obtain hidl AshmemAllocator");
- // TODO: When Treble has MemoryHeap/MemoryDealer, we should specify the heap
- // size to be 16 * 1024 * 1024.
+ if (mUseTreble) {
+ mAllocator = IAllocator::getService("ashmem");
+ EXPECT(mAllocator != nullptr,
+ "Cannot obtain hidl AshmemAllocator");
+ } else {
+ mDealer = new MemoryDealer(16 * 1024 * 1024, "OMXHarness");
+ }
sp<CodecObserver> observer = new CodecObserver(this, ++mCurGeneration);
diff --git a/media/libstagefright/omx/tests/OMXHarness.h b/media/libstagefright/omx/tests/OMXHarness.h
index dca787c..4fc0f79 100644
--- a/media/libstagefright/omx/tests/OMXHarness.h
+++ b/media/libstagefright/omx/tests/OMXHarness.h
@@ -93,6 +93,8 @@
Condition mMessageAddedCondition;
int32_t mLastMsgGeneration;
int32_t mCurGeneration;
+ bool mUseTreble;
+ sp<MemoryDealer> mDealer;
sp<IAllocator> mAllocator;
status_t initOMX();