Merge "audio policy: select output with best sample format match" into nyc-dev
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index 5e324ad..a4bfaf8 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -46,8 +46,14 @@
virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
+ enum DestinationType {
+ kDestinationTypeVmPointer, // non-secure
+ kDestinationTypeOpaqueHandle, // secure
+ kDestinationTypeNativeHandle // secure
+ };
+
virtual ssize_t decrypt(
- bool secure,
+ DestinationType dstType,
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 27ad694..d6db67a 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -98,8 +98,8 @@
node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
@@ -137,13 +137,14 @@
virtual status_t signalEndOfInputStream(node_id node) = 0;
- // This API clearly only makes sense if the caller lives in the
- // same process as the callee, i.e. is the media_server, as the
- // returned "buffer_data" pointer is just that, a pointer into local
- // address space.
- virtual status_t allocateBuffer(
+ // Allocate an opaque buffer as a native handle. If component supports returning native
+ // handles, those are returned in *native_handle. Otherwise, the allocated buffer is
+ // returned in *buffer_data. This clearly only makes sense if the caller lives in the
+ // same process as the callee, i.e. is the media_server, as the returned "buffer_data"
+ // pointer is just that, a pointer into local address space.
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) = 0;
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) = 0;
// Allocate an OMX buffer of size |allotedSize|. Use |params| as the backup buffer, which
// may be larger.
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 349db64..cc5b486 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -26,6 +26,7 @@
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/FrameRenderTracker.h>
#include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
#include <OMX_Audio.h>
#define TRACK_BUFFER_TIMING 0
@@ -72,6 +73,7 @@
size_t countBuffers();
IOMX::buffer_id bufferIDAt(size_t index) const;
sp<ABuffer> bufferAt(size_t index) const;
+ sp<NativeHandle> handleAt(size_t index) const;
sp<RefBase> memRefAt(size_t index) const;
private:
@@ -79,10 +81,13 @@
Vector<IOMX::buffer_id> mBufferIDs;
Vector<sp<ABuffer> > mBuffers;
+ Vector<sp<NativeHandle> > mHandles;
Vector<sp<RefBase> > mMemRefs;
PortDescription();
- void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef);
+ void addBuffer(
+ IOMX::buffer_id id, const sp<ABuffer> &buffer,
+ const sp<NativeHandle> &handle, const sp<RefBase> &memRef);
DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
};
@@ -186,6 +191,7 @@
sp<ABuffer> mData;
sp<RefBase> mMemRef;
sp<GraphicBuffer> mGraphicBuffer;
+ sp<NativeHandle> mNativeHandle;
int mFenceFd;
FrameRenderTracker::Info *mRenderInfo;
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index 01b744b..cbf9839 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -23,6 +23,7 @@
#include <media/MediaCodecInfo.h>
#include <media/stagefright/foundation/AHandler.h>
+#include <utils/NativeHandle.h>
namespace android {
@@ -77,6 +78,7 @@
virtual size_t countBuffers() = 0;
virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+ virtual sp<NativeHandle> handleAt(size_t index) { return NULL; };
virtual sp<RefBase> memRefAt(size_t index) const { return NULL; }
protected:
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index ea708e3..2bb1291 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -254,6 +254,7 @@
struct BufferInfo {
uint32_t mBufferID;
sp<ABuffer> mData;
+ sp<NativeHandle> mNativeHandle;
sp<RefBase> mMemRef;
sp<ABuffer> mEncryptedData;
sp<IMemory> mSharedEncryptedBuffer;
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 79059c6..26dd2c9 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -95,7 +95,7 @@
}
virtual ssize_t decrypt(
- bool secure,
+ DestinationType dstType,
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
@@ -105,7 +105,7 @@
AString *errorDetailMsg) {
Parcel data, reply;
data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeInt32(secure);
+ data.writeInt32((int32_t)dstType);
data.writeInt32(mode);
data.writeInt32(pattern.mEncryptBlocks);
data.writeInt32(pattern.mSkipBlocks);
@@ -136,8 +136,12 @@
data.writeInt32(numSubSamples);
data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
- if (secure) {
+ if (dstType == kDestinationTypeNativeHandle) {
+ data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
+ } else if (dstType == kDestinationTypeOpaqueHandle) {
data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
+ } else {
+ dstType = kDestinationTypeVmPointer;
}
remote()->transact(DECRYPT, data, &reply);
@@ -148,7 +152,7 @@
errorDetailMsg->setTo(reply.readCString());
}
- if (!secure && result >= 0) {
+ if (dstType == kDestinationTypeVmPointer && result >= 0) {
reply.read(dstPtr, result);
}
@@ -276,7 +280,7 @@
{
CHECK_INTERFACE(ICrypto, data, reply);
- bool secure = data.readInt32() != 0;
+ DestinationType dstType = (DestinationType)data.readInt32();
CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
CryptoPlugin::Pattern pattern;
pattern.mEncryptBlocks = data.readInt32();
@@ -306,10 +310,16 @@
subSamples,
sizeof(CryptoPlugin::SubSample) * numSubSamples);
- void *secureBufferId, *dstPtr;
- if (secure) {
+ native_handle_t *nativeHandle = NULL;
+ void *secureBufferId = NULL, *dstPtr;
+ if (dstType == kDestinationTypeNativeHandle) {
+ nativeHandle = data.readNativeHandle();
+ dstPtr = static_cast<void *>(nativeHandle);
+ } else if (dstType == kDestinationTypeOpaqueHandle) {
secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
+ dstPtr = secureBufferId;
} else {
+ dstType = kDestinationTypeVmPointer;
dstPtr = malloc(totalSize);
}
@@ -340,13 +350,13 @@
result = -EINVAL;
} else {
result = decrypt(
- secure,
+ dstType,
key,
iv,
mode, pattern,
sharedBuffer, offset,
subSamples, numSubSamples,
- secure ? secureBufferId : dstPtr,
+ dstPtr,
&errorDetailMsg);
}
@@ -356,13 +366,21 @@
reply->writeCString(errorDetailMsg.c_str());
}
- if (!secure) {
+ if (dstType == kDestinationTypeVmPointer) {
if (result >= 0) {
CHECK_LE(result, static_cast<ssize_t>(totalSize));
reply->write(dstPtr, result);
}
free(dstPtr);
dstPtr = NULL;
+ } else if (dstType == kDestinationTypeNativeHandle) {
+ int err;
+ if ((err = native_handle_close(nativeHandle)) < 0) {
+ ALOGW("secure buffer native_handle_close failed: %d", err);
+ }
+ if ((err = native_handle_delete(nativeHandle)) < 0) {
+ ALOGW("secure buffer native_handle_delete failed: %d", err);
+ }
}
delete[] subSamples;
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 550b506..9a7dff6 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -37,7 +37,7 @@
GET_CONFIG,
SET_CONFIG,
GET_STATE,
- ENABLE_GRAPHIC_BUFFERS,
+ ENABLE_NATIVE_BUFFERS,
USE_BUFFER,
USE_GRAPHIC_BUFFER,
CREATE_INPUT_SURFACE,
@@ -46,7 +46,7 @@
SIGNAL_END_OF_INPUT_STREAM,
STORE_META_DATA_IN_BUFFERS,
PREPARE_FOR_ADAPTIVE_PLAYBACK,
- ALLOC_BUFFER,
+ ALLOC_SECURE_BUFFER,
ALLOC_BUFFER_WITH_BACKUP,
FREE_BUFFER,
FILL_BUFFER,
@@ -217,14 +217,15 @@
return reply.readInt32();
}
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
data.writeInt32(port_index);
+ data.writeInt32((uint32_t)graphic);
data.writeInt32((uint32_t)enable);
- remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
+ remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
status_t err = reply.readInt32();
return err;
@@ -453,26 +454,31 @@
}
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeInt64(size);
- remote()->transact(ALLOC_BUFFER, data, &reply);
+ remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
status_t err = reply.readInt32();
if (err != OK) {
*buffer = 0;
-
+ *buffer_data = NULL;
+ *native_handle = NULL;
return err;
}
*buffer = (buffer_id)reply.readInt32();
*buffer_data = (void *)reply.readInt64();
-
+ if (*buffer_data == NULL) {
+ *native_handle = reply.readNativeHandle();
+ } else {
+ *native_handle = NULL;
+ }
return err;
}
@@ -754,15 +760,16 @@
return NO_ERROR;
}
- case ENABLE_GRAPHIC_BUFFERS:
+ case ENABLE_NATIVE_BUFFERS:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
+ OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- status_t err = enableGraphicBuffers(node, port_index, enable);
+ status_t err = enableNativeBuffers(node, port_index, graphic, enable);
reply->writeInt32(err);
return NO_ERROR;
@@ -965,7 +972,7 @@
OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
OMX_U32 audio_hw_sync = data.readInt32();
- native_handle_t *sideband_handle;
+ native_handle_t *sideband_handle = NULL;
status_t err = configureVideoTunnelMode(
node, port_index, tunneled, audio_hw_sync, &sideband_handle);
reply->writeInt32(err);
@@ -974,7 +981,7 @@
return NO_ERROR;
}
- case ALLOC_BUFFER:
+ case ALLOC_SECURE_BUFFER:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
@@ -989,14 +996,18 @@
size_t size = data.readInt64();
buffer_id buffer;
- void *buffer_data;
- status_t err = allocateBuffer(
- node, port_index, size, &buffer, &buffer_data);
+ void *buffer_data = NULL;
+ native_handle_t *native_handle = NULL;
+ status_t err = allocateSecureBuffer(
+ node, port_index, size, &buffer, &buffer_data, &native_handle);
reply->writeInt32(err);
if (err == OK) {
reply->writeInt32((int32_t)buffer);
reply->writeInt64((uintptr_t)buffer_data);
+ if (buffer_data == NULL) {
+ reply->writeNativeHandle(native_handle);
+ }
}
return NO_ERROR;
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index b57f6ef..9165b9d 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -235,7 +235,7 @@
}
ssize_t Crypto::decrypt(
- bool secure,
+ DestinationType dstType,
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
@@ -257,7 +257,8 @@
const void *srcPtr = static_cast<uint8_t *>(sharedBuffer->pointer()) + offset;
return mPlugin->decrypt(
- secure, key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
+ dstType != kDestinationTypeVmPointer,
+ key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
errorDetailMsg);
}
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 7705f30..7d181d3 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -50,7 +50,7 @@
virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
virtual ssize_t decrypt(
- bool secure,
+ DestinationType dstType,
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 5f13ebc..0dc5d4c 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -828,6 +828,7 @@
info.mStatus = BufferInfo::OWNED_BY_US;
info.mFenceFd = -1;
info.mRenderInfo = NULL;
+ info.mNativeHandle = NULL;
uint32_t requiresAllocateBufferBit =
(portIndex == kPortIndexInput)
@@ -837,12 +838,22 @@
if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
mem.clear();
- void *ptr;
- err = mOMX->allocateBuffer(
+ void *ptr = NULL;
+ native_handle_t *native_handle = NULL;
+ err = mOMX->allocateSecureBuffer(
mNode, portIndex, bufSize, &info.mBufferID,
- &ptr);
+ &ptr, &native_handle);
- info.mData = new ABuffer(ptr, bufSize);
+ // TRICKY: this representation is unorthodox, but ACodec requires
+ // an ABuffer with a proper size to validate range offsets and lengths.
+ // Since mData is never referenced for secure input, it is used to store
+ // either the pointer to the secure buffer, or the opaque handle as on
+ // some devices ptr is actually an opaque handle, not a pointer.
+
+ // TRICKY2: use native handle as the base of the ABuffer if received one,
+ // because Widevine source only receives these base addresses.
+ info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
+ info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
} else if (mQuirks & requiresAllocateBufferBit) {
err = mOMX->allocateBufferWithBackup(
mNode, portIndex, mem, &info.mBufferID, allottedSize);
@@ -876,7 +887,7 @@
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
const BufferInfo &info = mBuffers[portIndex][i];
- desc->addBuffer(info.mBufferID, info.mData, info.mMemRef);
+ desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
}
notify->setObject("portDesc", desc);
@@ -1774,6 +1785,14 @@
mFlags |= kFlagIsGrallocUsageProtected;
mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
}
+
+ if (mFlags & kFlagIsSecure) {
+ // use native_handles for secure input buffers
+ err = mOMX->enableNativeBuffers(
+ mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
+ ALOGI_IF(err != OK, "falling back to non-native_handles");
+ err = OK; // ignore error for now
+ }
}
if (haveNativeWindow) {
sp<ANativeWindow> nativeWindow =
@@ -1985,7 +2004,8 @@
inputFormat->setInt32("adaptive-playback", false);
}
if (err == OK) {
- err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+ err = mOMX->enableNativeBuffers(
+ mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
}
if (mFlags & kFlagIsGrallocUsageProtected) {
// fallback is not supported for protected playback
@@ -3879,10 +3899,10 @@
status_t ACodec::initNativeWindow() {
if (mNativeWindow != NULL) {
- return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
+ return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
}
- mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+ mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
return OK;
}
@@ -4646,9 +4666,11 @@
}
void ACodec::PortDescription::addBuffer(
- IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef) {
+ IOMX::buffer_id id, const sp<ABuffer> &buffer,
+ const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
mBufferIDs.push_back(id);
mBuffers.push_back(buffer);
+ mHandles.push_back(handle);
mMemRefs.push_back(memRef);
}
@@ -4664,6 +4686,10 @@
return mBuffers.itemAt(index);
}
+sp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
+ return mHandles.itemAt(index);
+}
+
sp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
return mMemRefs.itemAt(index);
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index d302f82..64d4302 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -792,10 +792,14 @@
void CameraSource::stopCameraRecording() {
ALOGV("stopCameraRecording");
if (mCameraFlags & FLAGS_HOT_CAMERA) {
- mCameraRecordingProxy->stopRecording();
+ if (mCameraRecordingProxy != 0) {
+ mCameraRecordingProxy->stopRecording();
+ }
} else {
- mCamera->setListener(NULL);
- mCamera->stopRecording();
+ if (mCamera != 0) {
+ mCamera->setListener(NULL);
+ mCamera->stopRecording();
+ }
}
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ce67d78..fb1f401 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1357,6 +1357,7 @@
info.mBufferID = portDesc->bufferIDAt(i);
info.mOwnedByClient = false;
info.mData = portDesc->bufferAt(i);
+ info.mNativeHandle = portDesc->handleAt(i);
info.mMemRef = portDesc->memRefAt(i);
if (portIndex == kPortIndexInput && mCrypto != NULL) {
@@ -2493,8 +2494,18 @@
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
+ void *dst_pointer = info->mData->base();
+ ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle;
+
+ if (info->mNativeHandle != NULL) {
+ dst_pointer = (void *)info->mNativeHandle.get();
+ dst_type = ICrypto::kDestinationTypeNativeHandle;
+ } else if ((mFlags & kFlagIsSecure) == 0) {
+ dst_type = ICrypto::kDestinationTypeVmPointer;
+ }
+
ssize_t result = mCrypto->decrypt(
- (mFlags & kFlagIsSecure) != 0,
+ dst_type,
key,
iv,
mode,
@@ -2503,7 +2514,7 @@
offset,
subSamples,
numSubSamples,
- info->mData->base(),
+ dst_pointer,
errorDetailMsg);
if (result < 0) {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index e69890d..50f235e 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -82,8 +82,8 @@
node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable);
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -114,9 +114,9 @@
virtual status_t signalEndOfInputStream(node_id node);
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
@@ -310,9 +310,9 @@
node, portIndex, enable, audioHwSync, sidebandHandle);
}
-status_t MuxOMX::enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
- return getOMX(node)->enableGraphicBuffers(node, port_index, enable);
+status_t MuxOMX::enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
+ return getOMX(node)->enableNativeBuffers(node, port_index, graphic, enable);
}
status_t MuxOMX::getGraphicBufferUsage(
@@ -366,11 +366,11 @@
return getOMX(node)->signalEndOfInputStream(node);
}
-status_t MuxOMX::allocateBuffer(
+status_t MuxOMX::allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
- return getOMX(node)->allocateBuffer(
- node, port_index, size, buffer, buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
+ return getOMX(node)->allocateSecureBuffer(
+ node, port_index, size, buffer, buffer_data, native_handle);
}
status_t MuxOMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 9f2e5e7..4c27360 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -62,8 +62,8 @@
virtual status_t getState(
node_id node, OMX_STATETYPE* state);
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable);
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -107,9 +107,9 @@
virtual status_t signalEndOfInputStream(node_id node);
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index e5fb45b..732894c 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -54,7 +54,7 @@
status_t getState(OMX_STATETYPE* state);
- status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+ status_t enableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable);
status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
@@ -95,9 +95,9 @@
status_t signalEndOfInputStream();
- status_t allocateBuffer(
+ status_t allocateSecureBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
- void **buffer_data);
+ void **buffer_data, native_handle_t **native_handle);
status_t allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
@@ -165,7 +165,15 @@
uint32_t mBufferIDCount;
KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+
+ // metadata and secure buffer type tracking
MetadataBufferType mMetadataType[2];
+ enum SecureBufferType {
+ kSecureBufferTypeUnknown,
+ kSecureBufferTypeOpaque,
+ kSecureBufferTypeNativeHandle,
+ };
+ SecureBufferType mSecureBufferType[2];
// For debug support
char *mName;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index b3625b4..a20028b 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -380,15 +380,15 @@
state);
}
-status_t OMX::enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+status_t OMX::enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
OMXNodeInstance *instance = findInstance(node);
if (instance == NULL) {
return NAME_NOT_FOUND;
}
- return instance->enableGraphicBuffers(port_index, enable);
+ return instance->enableNativeBuffers(port_index, graphic, enable);
}
status_t OMX::getGraphicBufferUsage(
@@ -521,17 +521,17 @@
return instance->signalEndOfInputStream();
}
-status_t OMX::allocateBuffer(
+status_t OMX::allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
OMXNodeInstance *instance = findInstance(node);
if (instance == NULL) {
return NAME_NOT_FOUND;
}
- return instance->allocateBuffer(
- port_index, size, buffer, buffer_data);
+ return instance->allocateSecureBuffer(
+ port_index, size, buffer, buffer_data, native_handle);
}
status_t OMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 9ae238a..a8c55fa 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -29,6 +29,7 @@
#include <OMX_AsString.h>
#include <binder/IMemory.h>
+#include <cutils/properties.h>
#include <gui/BufferQueue.h>
#include <HardwareAPI.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -203,6 +204,8 @@
mDebugLevelBumpPendingBuffers[1] = 0;
mMetadataType[0] = kMetadataBufferTypeInvalid;
mMetadataType[1] = kMetadataBufferTypeInvalid;
+ mSecureBufferType[0] = kSecureBufferTypeUnknown;
+ mSecureBufferType[1] = kSecureBufferTypeUnknown;
mIsSecure = AString(name).endsWith(".secure");
}
@@ -453,12 +456,14 @@
return StatusFromOMXError(err);
}
-status_t OMXNodeInstance::enableGraphicBuffers(
- OMX_U32 portIndex, OMX_BOOL enable) {
+status_t OMXNodeInstance::enableNativeBuffers(
+ OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable) {
Mutex::Autolock autoLock(mLock);
- CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable);
+ CLOG_CONFIG(enableNativeBuffers, "%s:%u%s, %d", portString(portIndex), portIndex,
+ graphic ? ", graphic" : "", enable);
OMX_STRING name = const_cast<OMX_STRING>(
- "OMX.google.android.index.enableAndroidNativeBuffers");
+ graphic ? "OMX.google.android.index.enableAndroidNativeBuffers"
+ : "OMX.google.android.index.allocateNativeHandle");
OMX_INDEXTYPE index;
OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
@@ -476,6 +481,25 @@
err = OMX_SetParameter(mHandle, index, ¶ms);
CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
portString(portIndex), portIndex, enable);
+ if (!graphic) {
+ if (err == OK) {
+ mSecureBufferType[portIndex] =
+ enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;
+ } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
+
+ // BEGIN ALTERNATE SIGNALING FOR USING NATIVE HANDLES
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.mediadrmservice.enable", value, NULL)
+ && (!strcmp("1", value) || !strcasecmp("true", value))) {
+ CLOG_CONFIG(enableNativeBuffers, "system property override: using native-handles");
+ mSecureBufferType[portIndex] = kSecureBufferTypeNativeHandle;
+ return OK;
+ }
+ // END ALTERNATE SIGNALING FOR USING NATIVE HANDLES
+
+ mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
+ }
+ }
return StatusFromOMXError(err);
}
@@ -996,10 +1020,10 @@
return bufferSource->signalEndOfInputStream();
}
-status_t OMXNodeInstance::allocateBuffer(
+status_t OMXNodeInstance::allocateSecureBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
- void **buffer_data) {
- if (buffer == NULL || buffer_data == NULL) {
+ void **buffer_data, native_handle_t **native_handle) {
+ if (buffer == NULL || buffer_data == NULL || native_handle == NULL) {
ALOGE("b/25884056");
return BAD_VALUE;
}
@@ -1026,7 +1050,13 @@
CHECK_EQ(header->pAppPrivate, buffer_meta);
*buffer = makeBufferID(header);
- *buffer_data = header->pBuffer;
+ if (mSecureBufferType[portIndex] == kSecureBufferTypeNativeHandle) {
+ *buffer_data = NULL;
+ *native_handle = (native_handle_t *)header->pBuffer;
+ } else {
+ *buffer_data = header->pBuffer;
+ *native_handle = NULL;
+ }
addActiveBuffer(portIndex, *buffer);
@@ -1034,7 +1064,8 @@
if (bufferSource != NULL && portIndex == kPortIndexInput) {
bufferSource->addCodecBuffer(header);
}
- CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data));
+ CLOG_BUFFER(allocateSecureBuffer, NEW_BUFFER_FMT(
+ *buffer, portIndex, "%zu@%p:%p", size, *buffer_data, *native_handle));
return OK;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 6b9cb83..b6a7547 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2221,6 +2221,13 @@
return false;
}
+ // Check if streaming is off, then only allow offload as of now.
+ if (offloadInfo.is_streaming)
+ {
+ ALOGV("isOffloadSupported: is_streaming == true, returning false");
+ return false;
+ }
+
//TODO: enable audio offloading with video when ready
const bool allowOffloadWithVideo =
property_get_bool("audio.offload.video", false /* default_value */);