Enable full migration of OMX to Treble.
1. Toggling between Treble and non-Treble OMX will now be controlled by
two properties: "persist.hal.binderization" and
"persist.media.treble_omx". (Before this CL, this was controlled by
"debug.treble_omx".)
- If persist.media.treble_omx is not set, it will assume a default value
of -1.
- If persist.media.treble_omx is -1, persist.hal.binderization will be
used to determine whether OMX will be created as a Treble or non-Treble
service.
- If persist.media.treble_omx is 1, OMX will be created as a Treble
service.
- If persist.media.treble_omx has any other value, OMX will be created
as a non-Treble service.
- persist.media.treble_omx can be changed without rebooting, but it will
only take effect after media.codec and mediaserver processes are killed.
2. Remove all dependencies on non-Treble service. This was not done for
MediaCodec, MediaPlayerService::Client, MediaRecorderClient, stagefright
command, and omx_tests command. OMXClient and media.codec process will
now pick the right version of OMX based on properties mentioned above.
Before this CL, media.codec would always present the non-Treble version
of OMX regardless of the flag.
3. Provide workarounds for some HIDL issues.
- A sequence of nested binder and hwbinder calls require many threads to
handle. (b/35283480) The workaround is to increase the number of threads
in the thread pool of media.codec process.
- android.hidl.base@1.0::IBase::unlinkToDeath takes a strong pointer
instead of a weak pointer. (b/35233970) This causes an infinite
recursion in the destructor of ServiceDeathNotifier in
MediaPlayerService::Client and MediaRecorderClient. The workaround moves
calls to unlinkToDeath() outside of the destructor.
Test: Recorded and played videos with Camera app. Ran stagefright and
omx_tests commands.
Bug: 31399200
Change-Id: Id1940ed982838e10bf10fe8ed5b7bb912a5a2d3a
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 64627fb..e6d9b71 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -36,6 +36,8 @@
libstagefright_omx \
libstagefright_wfd \
libutils \
+ libhidlbase \
+ android.hardware.media.omx@1.0 \
LOCAL_STATIC_LIBRARIES := \
libstagefright_nuplayer \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 62e5ec8..dbc7e21 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -597,6 +597,7 @@
if (mAudioAttributes != NULL) {
free(mAudioAttributes);
}
+ clearDeathNotifiers();
}
void MediaPlayerService::Client::disconnect()
@@ -654,12 +655,22 @@
const sp<MediaPlayerBase>& listener,
int which) {
mService = service;
+ mOmx = nullptr;
+ mListener = listener;
+ mWhich = which;
+}
+
+MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
+ const sp<IOmx>& omx,
+ const sp<MediaPlayerBase>& listener,
+ int which) {
+ mService = nullptr;
+ mOmx = omx;
mListener = listener;
mWhich = which;
}
MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
- mService->unlinkToDeath(this);
}
void MediaPlayerService::Client::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
@@ -671,10 +682,43 @@
}
}
+void MediaPlayerService::Client::ServiceDeathNotifier::serviceDied(
+ uint64_t /* cookie */,
+ const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
+ listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
+ } else {
+ ALOGW("listener for process %d death is gone", mWhich);
+ }
+}
+
+void MediaPlayerService::Client::ServiceDeathNotifier::unlinkToDeath() {
+ if (mService != nullptr) {
+ mService->unlinkToDeath(this);
+ mService = nullptr;
+ } else if (mOmx != nullptr) {
+ mOmx->unlinkToDeath(this);
+ mOmx = nullptr;
+ }
+}
+
+void MediaPlayerService::Client::clearDeathNotifiers() {
+ if (mExtractorDeathListener != nullptr) {
+ mExtractorDeathListener->unlinkToDeath();
+ mExtractorDeathListener = nullptr;
+ }
+ if (mCodecDeathListener != nullptr) {
+ mCodecDeathListener->unlinkToDeath();
+ mCodecDeathListener = nullptr;
+ }
+}
+
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
player_type playerType)
{
ALOGV("player type = %d", playerType);
+ clearDeathNotifiers();
// create the right type of player
sp<MediaPlayerBase> p = createPlayer(playerType);
@@ -691,13 +735,27 @@
mExtractorDeathListener = new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
binder->linkToDeath(mExtractorDeathListener);
- binder = sm->getService(String16("media.codec"));
- if (binder == NULL) {
- ALOGE("codec service not available");
- return NULL;
+ int32_t trebleOmx = property_get_int32("persist.media.treble_omx", -1);
+ if ((trebleOmx == 1) || ((trebleOmx == -1) &&
+ property_get_bool("persist.hal.binderization", 0))) {
+ // 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(binder, p, MEDIACODEC_PROCESS_DEATH);
- binder->linkToDeath(mCodecDeathListener);
if (!p->hardwareOutput()) {
Mutex::Autolock l(mLock);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index f5a540b..dff7322 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,6 +30,8 @@
#include <media/Metadata.h>
#include <media/stagefright/foundation/ABase.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+
#include <system/audio.h>
namespace android {
@@ -69,6 +71,7 @@
class MediaPlayerService : public BnMediaPlayerService
{
class Client;
+ typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
class AudioOutput : public MediaPlayerBase::AudioSink
{
@@ -362,22 +365,35 @@
virtual status_t releaseDrm();
private:
- class ServiceDeathNotifier: public IBinder::DeathRecipient
+ class ServiceDeathNotifier:
+ public IBinder::DeathRecipient,
+ public ::android::hardware::hidl_death_recipient
{
public:
ServiceDeathNotifier(
const sp<IBinder>& service,
const sp<MediaPlayerBase>& listener,
int which);
+ ServiceDeathNotifier(
+ const sp<IOmx>& omx,
+ const sp<MediaPlayerBase>& listener,
+ int which);
virtual ~ServiceDeathNotifier();
virtual void binderDied(const wp<IBinder>& who);
+ virtual void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who);
+ void unlinkToDeath();
private:
int mWhich;
sp<IBinder> mService;
+ sp<IOmx> mOmx;
wp<MediaPlayerBase> mListener;
};
+ void clearDeathNotifiers();
+
friend class MediaPlayerService;
Client( const sp<MediaPlayerService>& service,
pid_t pid,
@@ -437,8 +453,8 @@
// getMetadata clears this set.
media::Metadata::Filter mMetadataUpdated; // protected by mLock
- sp<IBinder::DeathRecipient> mExtractorDeathListener;
- sp<IBinder::DeathRecipient> mCodecDeathListener;
+ sp<ServiceDeathNotifier> mExtractorDeathListener;
+ sp<ServiceDeathNotifier> mCodecDeathListener;
#if CALLBACK_ANTAGONIZER
Antagonizer* mAntagonizer;
#endif
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index bb2d28b..763f509 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -328,6 +328,7 @@
wp<MediaRecorderClient> client(this);
mMediaPlayerService->removeMediaRecorderClient(client);
}
+ clearDeathNotifiers();
return NO_ERROR;
}
@@ -351,15 +352,25 @@
const sp<IMediaRecorderClient>& listener,
int which) {
mService = service;
+ mOmx = nullptr;
+ mListener = listener;
+ mWhich = which;
+}
+
+MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
+ const sp<IOmx>& omx,
+ const sp<IMediaRecorderClient>& listener,
+ int which) {
+ mService = nullptr;
+ mOmx = omx;
mListener = listener;
mWhich = which;
}
MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
- mService->unlinkToDeath(this);
}
-void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
+void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
sp<IMediaRecorderClient> listener = mListener.promote();
if (listener != NULL) {
listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
@@ -368,9 +379,42 @@
}
}
+void MediaRecorderClient::ServiceDeathNotifier::serviceDied(
+ uint64_t /* cookie */,
+ const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+ sp<IMediaRecorderClient> listener = mListener.promote();
+ if (listener != NULL) {
+ listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
+ } else {
+ ALOGW("listener for process %d death is gone", mWhich);
+ }
+}
+
+void MediaRecorderClient::ServiceDeathNotifier::unlinkToDeath() {
+ if (mService != nullptr) {
+ mService->unlinkToDeath(this);
+ mService = nullptr;
+ } else if (mOmx != nullptr) {
+ mOmx->unlinkToDeath(this);
+ mOmx = nullptr;
+ }
+}
+
+void MediaRecorderClient::clearDeathNotifiers() {
+ if (mCameraDeathListener != nullptr) {
+ mCameraDeathListener->unlinkToDeath();
+ mCameraDeathListener = nullptr;
+ }
+ if (mCodecDeathListener != nullptr) {
+ mCodecDeathListener->unlinkToDeath();
+ mCodecDeathListener = nullptr;
+ }
+}
+
status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
{
ALOGV("setListener");
+ clearDeathNotifiers();
Mutex::Autolock lock(mLock);
if (mRecorder == NULL) {
ALOGE("recorder is not initialized");
@@ -395,10 +439,25 @@
}
sCameraChecked = true;
- binder = sm->getService(String16("media.codec"));
- mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
- MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
- binder->linkToDeath(mCodecDeathListener);
+ int32_t trebleOmx = property_get_int32("persist.media.treble_omx", -1);
+ if ((trebleOmx == 1) || ((trebleOmx == -1) &&
+ property_get_bool("persist.hal.binderization", 0))) {
+ // 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"));
+ mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
+ MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+ binder->linkToDeath(mCodecDeathListener);
+ }
return OK;
}
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 8ddd680..101b8f6 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -20,6 +20,8 @@
#include <media/IMediaRecorder.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+
namespace android {
struct MediaRecorderBase;
@@ -28,22 +30,36 @@
class MediaRecorderClient : public BnMediaRecorder
{
- class ServiceDeathNotifier: public IBinder::DeathRecipient
+ typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
+
+ class ServiceDeathNotifier :
+ public IBinder::DeathRecipient,
+ public ::android::hardware::hidl_death_recipient
{
public:
ServiceDeathNotifier(
const sp<IBinder>& service,
const sp<IMediaRecorderClient>& listener,
int which);
+ ServiceDeathNotifier(
+ const sp<IOmx>& omx,
+ const sp<IMediaRecorderClient>& listener,
+ int which);
virtual ~ServiceDeathNotifier();
virtual void binderDied(const wp<IBinder>& who);
-
+ virtual void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who);
+ void unlinkToDeath();
private:
int mWhich;
sp<IBinder> mService;
+ sp<IOmx> mOmx;
wp<IMediaRecorderClient> mListener;
};
+ void clearDeathNotifiers();
+
public:
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy);
@@ -84,8 +100,8 @@
const String16& opPackageName);
virtual ~MediaRecorderClient();
- sp<IBinder::DeathRecipient> mCameraDeathListener;
- sp<IBinder::DeathRecipient> mCodecDeathListener;
+ sp<ServiceDeathNotifier> mCameraDeathListener;
+ sp<ServiceDeathNotifier> mCodecDeathListener;
pid_t mPid;
Mutex mLock;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3235e81..834afb4 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -575,7 +575,7 @@
changeState(mUninitializedState);
- updateTrebleFlag();
+ mTrebleFlag = false;
}
ACodec::~ACodec() {
@@ -6229,11 +6229,12 @@
CHECK(mCodec->mOMXNode == NULL);
OMXClient client;
- if ((mCodec->updateTrebleFlag() ?
- client.connectTreble() : client.connect()) != OK) {
+ bool trebleFlag;
+ if (client.connect(&trebleFlag) != OK) {
mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
return false;
}
+ mCodec->setTrebleFlag(trebleFlag);
sp<IOMX> omx = client.interface();
@@ -7676,8 +7677,7 @@
}
OMXClient client;
- status_t err = getTrebleFlag() ?
- client.connectTreble() : client.connect();
+ status_t err = client.connect();
if (err != OK) {
return err;
}
@@ -7893,11 +7893,8 @@
return OK;
}
-bool ACodec::updateTrebleFlag() {
- mTrebleFlag = bool(property_get_bool("debug.treble_omx", 0));
- ALOGV("updateTrebleFlag() returns %s",
- mTrebleFlag ? "true" : "false");
- return mTrebleFlag;
+void ACodec::setTrebleFlag(bool trebleFlag) {
+ mTrebleFlag = trebleFlag;
}
bool ACodec::getTrebleFlag() const {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index b4e694c..b77ee1d 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -22,6 +22,7 @@
#endif
#include <utils/Log.h>
+#include <cutils/properties.h>
#include <binder/IServiceManager.h>
#include <media/IMediaCodecService.h>
@@ -36,7 +37,22 @@
OMXClient::OMXClient() {
}
-status_t OMXClient::connect() {
+status_t OMXClient::connect(bool* trebleFlag) {
+ int32_t trebleOmx = property_get_int32("persist.media.treble_omx", -1);
+ if ((trebleOmx == 1) || ((trebleOmx == -1) &&
+ property_get_bool("persist.hal.binderization", 0))) {
+ if (trebleFlag != nullptr) {
+ *trebleFlag = true;
+ }
+ return connectTreble();
+ }
+ 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);
@@ -67,6 +83,7 @@
return NO_INIT;
}
mOMX = new utils::LWOmx(tOmx);
+ ALOGI("Treble IOmx obtained");
return OK;
}
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 3433bb4..d164faa 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -560,6 +560,76 @@
}
/**
+ * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
+ *
+ * \param[out] t The wrapper of type `AnwBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: GraphicBuffer -> AnwBuffer
+inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
+ t->attr.width = l.getWidth();
+ t->attr.height = l.getHeight();
+ t->attr.stride = l.getStride();
+ t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
+ t->attr.layerCount = l.getLayerCount();
+ t->attr.usage = l.getUsage();
+ t->attr.id = l.getId();
+ t->attr.generationNumber = l.getGenerationNumber();
+ t->nativeHandle = hidl_handle(l.handle);
+}
+
+/**
+ * \brief Convert `AnwBuffer` to `GraphicBuffer`.
+ *
+ * \param[out] l The destination `GraphicBuffer`.
+ * \param[in] t The source `AnwBuffer`.
+ *
+ * This function will duplicate all file descriptors in \p t.
+ */
+// convert: AnwBuffer -> GraphicBuffer
+// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
+inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
+ native_handle_t* handle = t.nativeHandle == nullptr ?
+ nullptr : native_handle_clone(t.nativeHandle);
+
+ size_t const numInts = 12 + (handle ? handle->numInts : 0);
+ int32_t* ints = new int32_t[numInts];
+
+ size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
+ int* fds = new int[numFds];
+
+ ints[0] = 'GBFR';
+ ints[1] = static_cast<int32_t>(t.attr.width);
+ ints[2] = static_cast<int32_t>(t.attr.height);
+ ints[3] = static_cast<int32_t>(t.attr.stride);
+ ints[4] = static_cast<int32_t>(t.attr.format);
+ ints[5] = static_cast<int32_t>(t.attr.layerCount);
+ ints[6] = static_cast<int32_t>(t.attr.usage);
+ ints[7] = static_cast<int32_t>(t.attr.id >> 32);
+ ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
+ ints[9] = static_cast<int32_t>(t.attr.generationNumber);
+ ints[10] = 0;
+ ints[11] = 0;
+ if (handle) {
+ ints[10] = static_cast<int32_t>(handle->numFds);
+ ints[11] = static_cast<int32_t>(handle->numInts);
+ int* intsStart = handle->data + handle->numFds;
+ std::copy(handle->data, intsStart, fds);
+ std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
+ }
+
+ void const* constBuffer = static_cast<void const*>(ints);
+ size_t size = numInts * sizeof(int32_t);
+ int const* constFds = static_cast<int const*>(fds);
+ status_t status = l->unflatten(constBuffer, size, constFds, numFds);
+
+ delete [] fds;
+ delete [] ints;
+ native_handle_delete(handle);
+ return status == NO_ERROR;
+}
+
+/**
* \brief Wrap `OMXBuffer` in `CodecBuffer`.
*
* \param[out] t The wrapper of type `CodecBuffer`.
@@ -568,8 +638,8 @@
*/
// wrap: OMXBuffer -> CodecBuffer
inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
- t->nativeHandle = hidl_handle();
t->sharedMemory = hidl_memory();
+ t->nativeHandle = hidl_handle();
switch (l.mBufferType) {
case OMXBuffer::kBufferTypeInvalid: {
t->type = CodecBuffer::Type::INVALID;
@@ -599,7 +669,6 @@
t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
t->attr.anwBuffer.layerCount = 0;
t->attr.anwBuffer.usage = 0;
- t->nativeHandle = hidl_handle();
return true;
}
t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
@@ -609,12 +678,12 @@
l.mGraphicBuffer->getPixelFormat());
t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
- t->nativeHandle = hidl_handle(l.mGraphicBuffer->handle);
+ t->nativeHandle = l.mGraphicBuffer->handle;
return true;
}
case OMXBuffer::kBufferTypeNativeHandle: {
t->type = CodecBuffer::Type::NATIVE_HANDLE;
- t->nativeHandle = hidl_handle(l.mNativeHandle->handle());
+ t->nativeHandle = l.mNativeHandle->handle();
return true;
}
}
@@ -650,16 +719,14 @@
*l = OMXBuffer(sp<GraphicBuffer>(nullptr));
return true;
}
- *l = OMXBuffer(sp<GraphicBuffer>(new GraphicBuffer(
- t.attr.anwBuffer.width,
- t.attr.anwBuffer.height,
- static_cast<::android::PixelFormat>(
- t.attr.anwBuffer.format),
- t.attr.anwBuffer.layerCount,
- t.attr.anwBuffer.usage,
- t.attr.anwBuffer.stride,
- native_handle_clone(t.nativeHandle),
- true)));
+ AnwBuffer anwBuffer;
+ anwBuffer.nativeHandle = t.nativeHandle;
+ anwBuffer.attr = t.attr.anwBuffer;
+ sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
+ if (!convertTo(graphicBuffer.get(), anwBuffer)) {
+ return false;
+ }
+ *l = OMXBuffer(graphicBuffer);
return true;
}
case CodecBuffer::Type::NATIVE_HANDLE: {
@@ -834,76 +901,6 @@
}
/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
- t->attr.width = l.getWidth();
- t->attr.height = l.getHeight();
- t->attr.stride = l.getStride();
- t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
- t->attr.layerCount = l.getLayerCount();
- t->attr.usage = l.getUsage();
- t->attr.id = l.getId();
- t->attr.generationNumber = l.getGenerationNumber();
- t->nativeHandle = hidl_handle(l.handle);
-}
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
- native_handle_t* handle = t.nativeHandle == nullptr ?
- nullptr : native_handle_clone(t.nativeHandle);
-
- size_t const numInts = 12 + (handle ? handle->numInts : 0);
- int32_t* ints = new int32_t[numInts];
-
- size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
- int* fds = new int[numFds];
-
- ints[0] = 'GBFR';
- ints[1] = static_cast<int32_t>(t.attr.width);
- ints[2] = static_cast<int32_t>(t.attr.height);
- ints[3] = static_cast<int32_t>(t.attr.stride);
- ints[4] = static_cast<int32_t>(t.attr.format);
- ints[5] = static_cast<int32_t>(t.attr.layerCount);
- ints[6] = static_cast<int32_t>(t.attr.usage);
- ints[7] = static_cast<int32_t>(t.attr.id >> 32);
- ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
- ints[9] = static_cast<int32_t>(t.attr.generationNumber);
- ints[10] = 0;
- ints[11] = 0;
- if (handle) {
- ints[10] = static_cast<int32_t>(handle->numFds);
- ints[11] = static_cast<int32_t>(handle->numInts);
- int* intsStart = handle->data + handle->numFds;
- std::copy(handle->data, intsStart, fds);
- std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
- }
-
- void const* constBuffer = static_cast<void const*>(ints);
- size_t size = numInts * sizeof(int32_t);
- int const* constFds = static_cast<int const*>(fds);
- status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
- delete [] fds;
- delete [] ints;
- native_handle_delete(handle);
- return status == NO_ERROR;
-}
-
-/**
* Conversion functions for types outside media
* ============================================
*
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
index 2319cd9..5050687 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -560,6 +560,76 @@
}
/**
+ * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
+ *
+ * \param[out] t The wrapper of type `AnwBuffer`.
+ * \param[in] l The source `GraphicBuffer`.
+ */
+// wrap: GraphicBuffer -> AnwBuffer
+inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
+ t->attr.width = l.getWidth();
+ t->attr.height = l.getHeight();
+ t->attr.stride = l.getStride();
+ t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
+ t->attr.layerCount = l.getLayerCount();
+ t->attr.usage = l.getUsage();
+ t->attr.id = l.getId();
+ t->attr.generationNumber = l.getGenerationNumber();
+ t->nativeHandle = hidl_handle(l.handle);
+}
+
+/**
+ * \brief Convert `AnwBuffer` to `GraphicBuffer`.
+ *
+ * \param[out] l The destination `GraphicBuffer`.
+ * \param[in] t The source `AnwBuffer`.
+ *
+ * This function will duplicate all file descriptors in \p t.
+ */
+// convert: AnwBuffer -> GraphicBuffer
+// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
+inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
+ native_handle_t* handle = t.nativeHandle == nullptr ?
+ nullptr : native_handle_clone(t.nativeHandle);
+
+ size_t const numInts = 12 + (handle ? handle->numInts : 0);
+ int32_t* ints = new int32_t[numInts];
+
+ size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
+ int* fds = new int[numFds];
+
+ ints[0] = 'GBFR';
+ ints[1] = static_cast<int32_t>(t.attr.width);
+ ints[2] = static_cast<int32_t>(t.attr.height);
+ ints[3] = static_cast<int32_t>(t.attr.stride);
+ ints[4] = static_cast<int32_t>(t.attr.format);
+ ints[5] = static_cast<int32_t>(t.attr.layerCount);
+ ints[6] = static_cast<int32_t>(t.attr.usage);
+ ints[7] = static_cast<int32_t>(t.attr.id >> 32);
+ ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
+ ints[9] = static_cast<int32_t>(t.attr.generationNumber);
+ ints[10] = 0;
+ ints[11] = 0;
+ if (handle) {
+ ints[10] = static_cast<int32_t>(handle->numFds);
+ ints[11] = static_cast<int32_t>(handle->numInts);
+ int* intsStart = handle->data + handle->numFds;
+ std::copy(handle->data, intsStart, fds);
+ std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
+ }
+
+ void const* constBuffer = static_cast<void const*>(ints);
+ size_t size = numInts * sizeof(int32_t);
+ int const* constFds = static_cast<int const*>(fds);
+ status_t status = l->unflatten(constBuffer, size, constFds, numFds);
+
+ delete [] fds;
+ delete [] ints;
+ native_handle_delete(handle);
+ return status == NO_ERROR;
+}
+
+/**
* \brief Wrap `OMXBuffer` in `CodecBuffer`.
*
* \param[out] t The wrapper of type `CodecBuffer`.
@@ -568,8 +638,8 @@
*/
// wrap: OMXBuffer -> CodecBuffer
inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) {
- t->nativeHandle = hidl_handle();
t->sharedMemory = hidl_memory();
+ t->nativeHandle = hidl_handle();
switch (l.mBufferType) {
case OMXBuffer::kBufferTypeInvalid: {
t->type = CodecBuffer::Type::INVALID;
@@ -599,7 +669,6 @@
t->attr.anwBuffer.format = static_cast<PixelFormat>(1);
t->attr.anwBuffer.layerCount = 0;
t->attr.anwBuffer.usage = 0;
- t->nativeHandle = hidl_handle();
return true;
}
t->attr.anwBuffer.width = l.mGraphicBuffer->getWidth();
@@ -609,12 +678,12 @@
l.mGraphicBuffer->getPixelFormat());
t->attr.anwBuffer.layerCount = l.mGraphicBuffer->getLayerCount();
t->attr.anwBuffer.usage = l.mGraphicBuffer->getUsage();
- t->nativeHandle = hidl_handle(l.mGraphicBuffer->handle);
+ t->nativeHandle = l.mGraphicBuffer->handle;
return true;
}
case OMXBuffer::kBufferTypeNativeHandle: {
t->type = CodecBuffer::Type::NATIVE_HANDLE;
- t->nativeHandle = hidl_handle(l.mNativeHandle->handle());
+ t->nativeHandle = l.mNativeHandle->handle();
return true;
}
}
@@ -650,16 +719,14 @@
*l = OMXBuffer(sp<GraphicBuffer>(nullptr));
return true;
}
- *l = OMXBuffer(sp<GraphicBuffer>(new GraphicBuffer(
- t.attr.anwBuffer.width,
- t.attr.anwBuffer.height,
- static_cast<::android::PixelFormat>(
- t.attr.anwBuffer.format),
- t.attr.anwBuffer.layerCount,
- t.attr.anwBuffer.usage,
- t.attr.anwBuffer.stride,
- native_handle_clone(t.nativeHandle),
- true)));
+ AnwBuffer anwBuffer;
+ anwBuffer.nativeHandle = t.nativeHandle;
+ anwBuffer.attr = t.attr.anwBuffer;
+ sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
+ if (!convertTo(graphicBuffer.get(), anwBuffer)) {
+ return false;
+ }
+ *l = OMXBuffer(graphicBuffer);
return true;
}
case CodecBuffer::Type::NATIVE_HANDLE: {
@@ -834,76 +901,6 @@
}
/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
- t->attr.width = l.getWidth();
- t->attr.height = l.getHeight();
- t->attr.stride = l.getStride();
- t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
- t->attr.layerCount = l.getLayerCount();
- t->attr.usage = l.getUsage();
- t->attr.id = l.getId();
- t->attr.generationNumber = l.getGenerationNumber();
- t->nativeHandle = hidl_handle(l.handle);
-}
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
- native_handle_t* handle = t.nativeHandle == nullptr ?
- nullptr : native_handle_clone(t.nativeHandle);
-
- size_t const numInts = 12 + (handle ? handle->numInts : 0);
- int32_t* ints = new int32_t[numInts];
-
- size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
- int* fds = new int[numFds];
-
- ints[0] = 'GBFR';
- ints[1] = static_cast<int32_t>(t.attr.width);
- ints[2] = static_cast<int32_t>(t.attr.height);
- ints[3] = static_cast<int32_t>(t.attr.stride);
- ints[4] = static_cast<int32_t>(t.attr.format);
- ints[5] = static_cast<int32_t>(t.attr.layerCount);
- ints[6] = static_cast<int32_t>(t.attr.usage);
- ints[7] = static_cast<int32_t>(t.attr.id >> 32);
- ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
- ints[9] = static_cast<int32_t>(t.attr.generationNumber);
- ints[10] = 0;
- ints[11] = 0;
- if (handle) {
- ints[10] = static_cast<int32_t>(handle->numFds);
- ints[11] = static_cast<int32_t>(handle->numInts);
- int* intsStart = handle->data + handle->numFds;
- std::copy(handle->data, intsStart, fds);
- std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
- }
-
- void const* constBuffer = static_cast<void const*>(ints);
- size_t size = numInts * sizeof(int32_t);
- int const* constFds = static_cast<int const*>(fds);
- status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
- delete [] fds;
- delete [] ints;
- native_handle_delete(handle);
- return status == NO_ERROR;
-}
-
-/**
* Conversion functions for types outside media
* ============================================
*
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 5e4ba10..08deaab 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -2,15 +2,26 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES = \
- OMXHarness.cpp \
+ OMXHarness.cpp \
LOCAL_SHARED_LIBRARIES := \
- libstagefright libbinder libmedia libutils liblog libstagefright_foundation
+ libstagefright \
+ libbinder \
+ libmedia \
+ libutils \
+ liblog \
+ libstagefright_foundation \
+ libcutils \
+ libhidlbase \
+ libhidlmemory \
+ 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 \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/system/libhidl/base/include \
+ $(TOP)/frameworks/av/media/libstagefright \
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/system/libhidl/base/include \
LOCAL_CFLAGS += -Werror -Wall
@@ -29,14 +40,14 @@
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := \
- FrameDropper_test.cpp \
+ FrameDropper_test.cpp \
LOCAL_SHARED_LIBRARIES := \
- libstagefright_omx \
- libutils \
+ libstagefright_omx \
+ libutils \
LOCAL_C_INCLUDES := \
- frameworks/av/media/libstagefright/omx \
+ frameworks/av/media/libstagefright/omx \
LOCAL_CFLAGS += -Werror -Wall
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 1ce5d1a..8817cf9 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -39,6 +39,8 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/SimpleDecodingSource.h>
#include <media/OMXBuffer.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <omx/hal/1.0/utils/WOmx.h>
#define DEFAULT_TIMEOUT 500000
@@ -64,7 +66,7 @@
/////////////////////////////////////////////////////////////////////
Harness::Harness()
- : mInitCheck(NO_INIT) {
+ : mInitCheck(NO_INIT), mUseTreble(false) {
mInitCheck = initOMX();
}
@@ -76,10 +78,23 @@
}
status_t Harness::initOMX() {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.codec"));
- sp<IMediaCodecService> service = interface_cast<IMediaCodecService>(binder);
- mOMX = service->getOMX();
+ int32_t trebleOmx = property_get_int32("persist.media.treble_omx", -1);
+ if ((trebleOmx == 1) || ((trebleOmx == -1) &&
+ property_get_bool("persist.hal.binderization", 0))) {
+ 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;
+ }
return mOMX != 0 ? OK : NO_INIT;
}
@@ -197,7 +212,6 @@
EXPECT((err) == OK, info " failed")
status_t Harness::allocatePortBuffers(
- const sp<MemoryDealer> &dealer,
OMX_U32 portIndex, Vector<Buffer> *buffers) {
buffers->clear();
@@ -207,11 +221,27 @@
for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
Buffer buffer;
- buffer.mMemory = dealer->allocate(def.nBufferSize);
buffer.mFlags = 0;
- CHECK(buffer.mMemory != NULL);
+ 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);
+ }
- err = mOMXNode->useBuffer(portIndex, buffer.mMemory, &buffer.mID);
EXPECT_SUCCESS(err, "useBuffer");
buffers->push(buffer);
@@ -279,7 +309,13 @@
return OK;
}
- sp<MemoryDealer> dealer = new MemoryDealer(16 * 1024 * 1024, "OMXHarness");
+ 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);
@@ -305,14 +341,14 @@
// Now allocate buffers.
Vector<Buffer> inputBuffers;
- err = allocatePortBuffers(dealer, 0, &inputBuffers);
+ err = allocatePortBuffers(0, &inputBuffers);
EXPECT_SUCCESS(err, "allocatePortBuffers(input)");
err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
CHECK_EQ(err, (status_t)TIMED_OUT);
Vector<Buffer> outputBuffers;
- err = allocatePortBuffers(dealer, 1, &outputBuffers);
+ err = allocatePortBuffers(1, &outputBuffers);
EXPECT_SUCCESS(err, "allocatePortBuffers(output)");
err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
diff --git a/media/libstagefright/omx/tests/OMXHarness.h b/media/libstagefright/omx/tests/OMXHarness.h
index 0fe00a6..022707f 100644
--- a/media/libstagefright/omx/tests/OMXHarness.h
+++ b/media/libstagefright/omx/tests/OMXHarness.h
@@ -23,6 +23,9 @@
#include <utils/Vector.h>
#include <utils/threads.h>
+#include <binder/MemoryDealer.h>
+#include <android/hidl/memory/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
#include <OMX_Component.h>
namespace android {
@@ -30,12 +33,15 @@
class MemoryDealer;
struct Harness : public RefBase {
+ typedef hidl::memory::V1_0::IMemory TMemory;
+ typedef hardware::hidl_memory hidl_memory;
enum BufferFlags {
kBufferBusy = 1
};
struct Buffer {
IOMX::buffer_id mID;
sp<IMemory> mMemory;
+ hidl_memory mHidlMemory;
uint32_t mFlags;
};
@@ -54,7 +60,6 @@
OMX_U32 portIndex, OMX_PARAM_PORTDEFINITIONTYPE *def);
status_t allocatePortBuffers(
- const sp<MemoryDealer> &dealer,
OMX_U32 portIndex, Vector<Buffer> *buffers);
status_t setRole(const char *role);
@@ -74,6 +79,8 @@
virtual ~Harness();
private:
+ typedef hidl::memory::V1_0::IAllocator IAllocator;
+
friend struct NodeReaper;
struct CodecObserver;
@@ -86,6 +93,9 @@
Condition mMessageAddedCondition;
int32_t mLastMsgGeneration;
int32_t mCurGeneration;
+ bool mUseTreble;
+ sp<MemoryDealer> mDealer;
+ sp<IAllocator> mAllocator;
status_t initOMX();
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index a4cb66d..f7597db 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -12,23 +12,24 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- main_mediaserver.cpp
+ main_mediaserver.cpp
LOCAL_SHARED_LIBRARIES := \
- libresourcemanagerservice \
- liblog \
- libmediaplayerservice \
- libutils \
- libbinder \
- libicuuc \
+ libresourcemanagerservice \
+ liblog \
+ libmediaplayerservice \
+ libutils \
+ libbinder \
+ libicuuc \
+ android.hardware.media.omx@1.0 \
LOCAL_STATIC_LIBRARIES := \
libicuandroid_utils \
libregistermsext
LOCAL_C_INCLUDES := \
- frameworks/av/media/libmediaplayerservice \
- frameworks/av/services/mediaresourcemanager \
+ frameworks/av/media/libmediaplayerservice \
+ frameworks/av/services/mediaresourcemanager \
LOCAL_MODULE:= mediaserver
LOCAL_32_BIT_ONLY := true