Merge "Enable FastTrack timestamps" 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/IMediaSource.h b/include/media/IMediaSource.h
index 1420120..f7586a7 100644
--- a/include/media/IMediaSource.h
+++ b/include/media/IMediaSource.h
@@ -26,6 +26,7 @@
struct MediaSource;
class MetaData;
class MediaBuffer;
+class MediaBufferGroup;
class IMediaSource : public IInterface {
public:
@@ -112,6 +113,8 @@
class BnMediaSource: public BnInterface<IMediaSource>
{
public:
+ BnMediaSource();
+
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
@@ -122,6 +125,12 @@
virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) {
return ERROR_UNSUPPORTED;
}
+
+protected:
+ virtual ~BnMediaSource();
+
+private:
+ MediaBufferGroup *mGroup;
};
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/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h
index 1e0c7d4..18b80e3 100644
--- a/include/media/stagefright/MediaBuffer.h
+++ b/include/media/stagefright/MediaBuffer.h
@@ -48,6 +48,9 @@
class MediaBuffer : public MediaBufferBase {
public:
+ // allocations larger than or equal to this will use shared memory.
+ static const size_t kSharedMemThreshold = 64 * 1024;
+
// The underlying data remains the responsibility of the caller!
MediaBuffer(void *data, size_t size);
diff --git a/include/media/stagefright/MediaBufferGroup.h b/include/media/stagefright/MediaBufferGroup.h
index a006f7f..7ca3fa1 100644
--- a/include/media/stagefright/MediaBufferGroup.h
+++ b/include/media/stagefright/MediaBufferGroup.h
@@ -39,7 +39,11 @@
// The returned buffer will have a reference count of 1.
// If nonBlocking is true and a buffer is not immediately available,
// buffer is set to NULL and it returns WOULD_BLOCK.
- status_t acquire_buffer(MediaBuffer **buffer, bool nonBlocking = false);
+ // If requestedSize is 0, any free MediaBuffer will be returned.
+ // If requestedSize is > 0, the returned MediaBuffer should have buffer
+ // size of at least requstedSize.
+ status_t acquire_buffer(
+ MediaBuffer **buffer, bool nonBlocking = false, size_t requestedSize = 0);
protected:
virtual void signalBufferReturned(MediaBuffer *buffer);
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/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index fc9a123..b988c46 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -25,6 +25,7 @@
#include <binder/Parcel.h>
#include <media/IMediaSource.h>
#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
@@ -47,8 +48,9 @@
class RemoteMediaBufferReleaser : public BBinder {
public:
- RemoteMediaBufferReleaser(MediaBuffer *buf) {
+ RemoteMediaBufferReleaser(MediaBuffer *buf, sp<BnMediaSource> owner) {
mBuf = buf;
+ mOwner = owner;
}
~RemoteMediaBufferReleaser() {
if (mBuf) {
@@ -70,6 +72,10 @@
}
private:
MediaBuffer *mBuf;
+ // Keep a ref to ensure MediaBuffer is released before the owner, i.e., BnMediaSource,
+ // because BnMediaSource needs to delete MediaBufferGroup in its dtor and
+ // MediaBufferGroup dtor requires all MediaBuffer's have 0 ref count.
+ sp<BnMediaSource> mOwner;
};
@@ -207,6 +213,15 @@
#undef LOG_TAG
#define LOG_TAG "BnMediaSource"
+BnMediaSource::BnMediaSource()
+ : mGroup(NULL) {
+}
+
+BnMediaSource::~BnMediaSource() {
+ delete mGroup;
+ mGroup = NULL;
+}
+
status_t BnMediaSource::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -263,17 +278,45 @@
size_t usedSize = buf->range_length();
// even if we're using shared memory, we might not want to use it, since for small
// sizes it's faster to copy data through the Binder transaction
- if (buf->mMemory != NULL && usedSize >= 64 * 1024) {
- ALOGV("buffer is using shared memory: %zu", usedSize);
+ // On the other hand, if the data size is large enough, it's better to use shared
+ // memory. When data is too large, binder can't handle it.
+ if (usedSize >= MediaBuffer::kSharedMemThreshold) {
+ ALOGV("use shared memory: %zu", usedSize);
+
+ MediaBuffer *transferBuf = buf;
+ size_t offset = buf->range_offset();
+ if (transferBuf->mMemory == NULL) {
+ if (mGroup == NULL) {
+ mGroup = new MediaBufferGroup;
+ size_t allocateSize = usedSize;
+ if (usedSize < SIZE_MAX / 3) {
+ allocateSize = usedSize * 3 / 2;
+ }
+ mGroup->add_buffer(new MediaBuffer(allocateSize));
+ }
+
+ ret = mGroup->acquire_buffer(
+ &transferBuf, false /* nonBlocking */, usedSize);
+ if (ret != OK || transferBuf == NULL || transferBuf->mMemory == NULL) {
+ ALOGW("failed to acquire shared memory, ret %d", ret);
+ reply->writeInt32(NULL_BUFFER);
+ return NO_ERROR;
+ }
+ memcpy(transferBuf->data(), (uint8_t*)buf->data() + buf->range_offset(),
+ buf->range_length());
+ offset = 0;
+ }
+
reply->writeInt32(SHARED_BUFFER);
- RemoteMediaBufferReleaser *wrapper = new RemoteMediaBufferReleaser(buf);
+ RemoteMediaBufferReleaser *wrapper =
+ new RemoteMediaBufferReleaser(transferBuf, this);
reply->writeStrongBinder(wrapper);
- reply->writeStrongBinder(IInterface::asBinder(buf->mMemory));
- reply->writeInt32(buf->range_offset());
+ reply->writeStrongBinder(IInterface::asBinder(transferBuf->mMemory));
+ reply->writeInt32(offset);
reply->writeInt32(usedSize);
buf->meta_data()->writeToParcel(*reply);
} else {
- // buffer is not in shared memory, or is small: copy it
+ // buffer is small: copy it
if (buf->mMemory != NULL) {
ALOGV("%zu shared mem available, but only %zu used", buf->mMemory->size(), buf->range_length());
}
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 550b506..d1832b6 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;
@@ -856,9 +863,13 @@
OMX_U32 port_index = data.readInt32();
sp<IGraphicBufferProducer> bufferProducer;
- MetadataBufferType type;
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
status_t err = createInputSurface(node, port_index, &bufferProducer, &type);
+ if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
+ android_errorWriteLog(0x534e4554, "26324358");
+ }
+
reply->writeInt32(type);
reply->writeInt32(err);
@@ -899,11 +910,16 @@
interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
MetadataBufferType type = kMetadataBufferTypeInvalid;
+
status_t err = INVALID_OPERATION;
if (bufferConsumer == NULL) {
ALOGE("b/26392700");
} else {
err = setInputSurface(node, port_index, bufferConsumer, &type);
+
+ if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
+ android_errorWriteLog(0x534e4554, "26324358");
+ }
}
reply->writeInt32(type);
@@ -931,8 +947,13 @@
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- MetadataBufferType type;
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
+
+ if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
+ android_errorWriteLog(0x534e4554, "26324358");
+ }
+
reply->writeInt32(type);
reply->writeInt32(err);
@@ -965,7 +986,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 +995,7 @@
return NO_ERROR;
}
- case ALLOC_BUFFER:
+ case ALLOC_SECURE_BUFFER:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
@@ -989,14 +1010,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/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 2528777..d0e7aa9 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2184,12 +2184,8 @@
case Source::kWhatBufferingEnd:
{
- if (mPausedByClient) {
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_END;
- } else {
- notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
- }
+ notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
+ mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index a049a30..0e6a6e6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -91,6 +91,7 @@
const sp<AMessage> ¬ify,
uint32_t flags)
: mAudioSink(sink),
+ mUseVirtualAudioSink(false),
mNotify(notify),
mFlags(flags),
mNumFramesWritten(0),
@@ -1020,6 +1021,15 @@
// Calculate duration of pending samples if played at normal rate (i.e., 1.0).
int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
+ if (mUseVirtualAudioSink) {
+ int64_t nowUs = ALooper::GetNowUs();
+ int64_t mediaUs;
+ if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
+ return 0ll;
+ } else {
+ return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
+ }
+ }
return writtenAudioDurationUs - mAudioSink->getPlayedOutDurationUs(nowUs);
}
@@ -1054,6 +1064,7 @@
if (nowUs >= mNextAudioClockUpdateTimeUs) {
int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
+ mUseVirtualAudioSink = false;
mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs;
}
} else {
@@ -1070,6 +1081,7 @@
// and it's paced by system clock.
ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock.");
mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs);
+ mUseVirtualAudioSink = true;
}
}
mAnchorNumFramesWritten = mNumFramesWritten;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 1bc9c97..c3ce511 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -134,6 +134,7 @@
static const int64_t kMinPositionUpdateDelayUs;
sp<MediaPlayerBase::AudioSink> mAudioSink;
+ bool mUseVirtualAudioSink;
sp<AMessage> mNotify;
Mutex mLock;
uint32_t mFlags;
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/Android.mk b/media/libstagefright/Android.mk
index fd4ed58..68e02e7 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -29,7 +29,6 @@
MPEG4Extractor.cpp \
MPEG4Writer.cpp \
MediaAdapter.cpp \
- MediaBufferGroup.cpp \
MediaClock.cpp \
MediaCodec.cpp \
MediaCodecList.cpp \
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/MediaBufferGroup.cpp b/media/libstagefright/MediaBufferGroup.cpp
deleted file mode 100644
index 6ac6d4a..0000000
--- a/media/libstagefright/MediaBufferGroup.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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_TAG "MediaBufferGroup"
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-
-namespace android {
-
-MediaBufferGroup::MediaBufferGroup()
- : mFirstBuffer(NULL),
- mLastBuffer(NULL) {
-}
-
-MediaBufferGroup::~MediaBufferGroup() {
- MediaBuffer *next;
- for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL;
- buffer = next) {
- next = buffer->nextBuffer();
-
- CHECK_EQ(buffer->refcount(), 0);
-
- buffer->setObserver(NULL);
- buffer->release();
- }
-}
-
-void MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
- Mutex::Autolock autoLock(mLock);
-
- buffer->setObserver(this);
-
- if (mLastBuffer) {
- mLastBuffer->setNextBuffer(buffer);
- } else {
- mFirstBuffer = buffer;
- }
-
- mLastBuffer = buffer;
-}
-
-status_t MediaBufferGroup::acquire_buffer(
- MediaBuffer **out, bool nonBlocking) {
- Mutex::Autolock autoLock(mLock);
-
- for (;;) {
- for (MediaBuffer *buffer = mFirstBuffer;
- buffer != NULL; buffer = buffer->nextBuffer()) {
- if (buffer->refcount() == 0) {
- buffer->add_ref();
- buffer->reset();
-
- *out = buffer;
- goto exit;
- }
- }
-
- if (nonBlocking) {
- *out = NULL;
- return WOULD_BLOCK;
- }
-
- // All buffers are in use. Block until one of them is returned to us.
- mCondition.wait(mLock);
- }
-
-exit:
- return OK;
-}
-
-void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
- Mutex::Autolock autoLock(mLock);
- mCondition.signal();
-}
-
-} // namespace android
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/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index e17534f..711601f 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -16,6 +16,7 @@
AStringUtils.cpp \
AWakeLock.cpp \
MediaBuffer.cpp \
+ MediaBufferGroup.cpp \
MetaData.cpp \
ParsedMessage.cpp \
base64.cpp \
diff --git a/media/libstagefright/foundation/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
index d83a351..fa8e241 100644
--- a/media/libstagefright/foundation/MediaBuffer.cpp
+++ b/media/libstagefright/foundation/MediaBuffer.cpp
@@ -30,9 +30,6 @@
namespace android {
-// allocations larger than this will use shared memory
-static const size_t kSharedMemThreshold = 64 * 1024;
-
MediaBuffer::MediaBuffer(void *data, size_t size)
: mObserver(NULL),
mNextBuffer(NULL),
diff --git a/media/libstagefright/foundation/MediaBufferGroup.cpp b/media/libstagefright/foundation/MediaBufferGroup.cpp
new file mode 100644
index 0000000..9022324
--- /dev/null
+++ b/media/libstagefright/foundation/MediaBufferGroup.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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_TAG "MediaBufferGroup"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
+
+namespace android {
+
+MediaBufferGroup::MediaBufferGroup()
+ : mFirstBuffer(NULL),
+ mLastBuffer(NULL) {
+}
+
+MediaBufferGroup::~MediaBufferGroup() {
+ MediaBuffer *next;
+ for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL;
+ buffer = next) {
+ next = buffer->nextBuffer();
+
+ CHECK_EQ(buffer->refcount(), 0);
+
+ buffer->setObserver(NULL);
+ buffer->release();
+ }
+}
+
+void MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
+ Mutex::Autolock autoLock(mLock);
+
+ buffer->setObserver(this);
+
+ if (mLastBuffer) {
+ mLastBuffer->setNextBuffer(buffer);
+ } else {
+ mFirstBuffer = buffer;
+ }
+
+ mLastBuffer = buffer;
+}
+
+status_t MediaBufferGroup::acquire_buffer(
+ MediaBuffer **out, bool nonBlocking, size_t requestedSize) {
+ Mutex::Autolock autoLock(mLock);
+
+ for (;;) {
+ MediaBuffer *freeBuffer = NULL;
+ MediaBuffer *freeBufferPrevious = NULL;
+ MediaBuffer *buffer = NULL;
+ MediaBuffer *bufferPrevious = NULL;
+ size_t smallest = requestedSize;
+ for (buffer = mFirstBuffer;
+ buffer != NULL; buffer = buffer->nextBuffer()) {
+ if (buffer->refcount() == 0) {
+ if (buffer->size() >= requestedSize) {
+ break;
+ } else if (buffer->size() < smallest) {
+ freeBuffer = buffer;
+ freeBufferPrevious = bufferPrevious;
+ }
+ }
+ bufferPrevious = buffer;
+ }
+
+ if (buffer == NULL && freeBuffer != NULL) {
+ ALOGV("allocate new buffer, requested size %zu vs available %zu",
+ requestedSize, freeBuffer->size());
+ size_t allocateSize = requestedSize;
+ if (requestedSize < SIZE_MAX / 3) {
+ allocateSize = requestedSize * 3 / 2;
+ }
+ MediaBuffer *newBuffer = new MediaBuffer(allocateSize);
+ newBuffer->setObserver(this);
+ if (freeBuffer == mFirstBuffer) {
+ mFirstBuffer = newBuffer;
+ }
+ if (freeBuffer == mLastBuffer) {
+ mLastBuffer = newBuffer;
+ }
+ newBuffer->setNextBuffer(freeBuffer->nextBuffer());
+ if (freeBufferPrevious != NULL) {
+ freeBufferPrevious->setNextBuffer(newBuffer);
+ }
+ freeBuffer->setObserver(NULL);
+ freeBuffer->release();
+
+ buffer = newBuffer;
+ }
+
+ if (buffer != NULL) {
+ buffer->add_ref();
+ buffer->reset();
+
+ *out = buffer;
+ goto exit;
+ }
+
+ if (nonBlocking) {
+ *out = NULL;
+ return WOULD_BLOCK;
+ }
+
+ // All buffers are in use. Block until one of them is returned to us.
+ mCondition.wait(mLock);
+ }
+
+exit:
+ return OK;
+}
+
+void MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
+ Mutex::Autolock autoLock(mLock);
+ mCondition.signal();
+}
+
+} // namespace android
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/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index ee99a26..979143c 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -23,6 +23,7 @@
libmediaplayerservice \
libutils \
libbinder \
+ libicuuc \
LOCAL_STATIC_LIBRARIES := \
libicuandroid_utils \
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index e006e89..e9dede9 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -26,6 +26,7 @@
// from LOCAL_C_INCLUDES
#include "CameraService.h"
+#include "IcuUtils.h"
#include "MediaPlayerService.h"
#include "ResourceManagerService.h"
@@ -38,6 +39,7 @@
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
+ InitializeIcuOrDie();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index 7c20478..4f8b413 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -29,7 +29,8 @@
#include "AudioResamplerDyn.h"
#ifdef __arm__
- #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
+ // bug 13102576
+ //#define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
#endif
namespace android {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 4dcc6b2..dd3f144 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -67,16 +67,6 @@
API_INPUT_TELEPHONY_RX, // used for capture from telephony RX path
} input_type_t;
- enum {
- API_INPUT_CONCURRENCY_NONE = 0,
- API_INPUT_CONCURRENCY_CALL = (1 << 0), // Concurrency with a call
- API_INPUT_CONCURRENCY_CAPTURE = (1 << 1), // Concurrency with another capture
-
- API_INPUT_CONCURRENCY_ALL = (API_INPUT_CONCURRENCY_CALL | API_INPUT_CONCURRENCY_CAPTURE),
- };
-
- typedef uint32_t concurrency_type__mask_t;
-
public:
virtual ~AudioPolicyInterface() {}
//
@@ -150,8 +140,7 @@
input_type_t *inputType) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
- audio_session_t session,
- concurrency_type__mask_t *concurrency) = 0;
+ audio_session_t session) = 0;
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
audio_session_t session) = 0;
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index e3ee4e5..d9e7212 100755
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -30,9 +30,9 @@
/**
* A device mask for all audio input devices that are considered "virtual" when evaluating
- * active inputs in getActiveInputs()
+ * active inputs in getActiveInput()
*/
-#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX)
+#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_FM_TUNER)
/**
@@ -89,40 +89,17 @@
((device & APM_AUDIO_DEVICE_OUT_MATCH_ADDRESS_ALL) != 0));
}
-/**
- * Returns the priority of a given audio source for capture. The priority is used when more than one
- * capture session is active on a given input stream to determine which session drives routing and
- * effect configuration.
- *
- * @param[in] inputSource to consider. Valid sources are:
- * - AUDIO_SOURCE_VOICE_COMMUNICATION
- * - AUDIO_SOURCE_CAMCORDER
- * - AUDIO_SOURCE_MIC
- * - AUDIO_SOURCE_FM_TUNER
- * - AUDIO_SOURCE_VOICE_RECOGNITION
- * - AUDIO_SOURCE_HOTWORD
- *
- * @return the corresponding input source priority or 0 if priority is irrelevant for this source.
- * This happens when the specified source cannot share a given input stream (e.g remote submix)
- * The higher the value, the higher the priority.
+/* Indicates if audio formats are equivalent when considering a match between
+ * audio HAL supported formats and client requested formats
*/
-static inline int32_t source_priority(audio_source_t inputSource)
+static inline bool audio_formats_match(audio_format_t format1,
+ audio_format_t format2)
{
- switch (inputSource) {
- case AUDIO_SOURCE_VOICE_COMMUNICATION:
- return 6;
- case AUDIO_SOURCE_CAMCORDER:
- return 5;
- case AUDIO_SOURCE_MIC:
- return 4;
- case AUDIO_SOURCE_FM_TUNER:
- return 3;
- case AUDIO_SOURCE_VOICE_RECOGNITION:
- return 2;
- case AUDIO_SOURCE_HOTWORD:
- return 1;
- default:
- break;
+ if (audio_is_linear_pcm(format1) &&
+ (audio_bytes_per_sample(format1) > 2) &&
+ audio_is_linear_pcm(format2) &&
+ (audio_bytes_per_sample(format2) > 2)) {
+ return true;
}
- return 0;
+ return format1 == format2;
}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 282bece..77c0d07 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -63,9 +63,7 @@
const sp<AudioSession>& audioSession);
status_t removeAudioSession(audio_session_t session);
sp<AudioSession> getAudioSession(audio_session_t session) const;
- AudioSessionCollection getAudioSessions(bool activeOnly) const;
- size_t getAudioSessionCount(bool activeOnly) const;
- audio_source_t getHighestPrioritySource(bool activeOnly) const;
+ AudioSessionCollection getActiveAudioSessions() const;
private:
audio_port_handle_t mId;
@@ -95,7 +93,7 @@
* Only considers inputs from physical devices (e.g. main mic, headset mic) when
* ignoreVirtualInputs is true.
*/
- Vector<sp <AudioInputDescriptor> > getActiveInputs(bool ignoreVirtualInputs = true);
+ audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
audio_devices_t getSupportedDevices(audio_io_handle_t handle) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 0da3aea..5958f4f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -110,6 +110,12 @@
static int compareFormats(audio_format_t format1, audio_format_t format2);
+ // Used to select an audio HAL output stream with a sample format providing the
+ // less degradation for a given AudioTrack sample format.
+ static bool isBetterFormatMatch(audio_format_t newFormat,
+ audio_format_t currentFormat,
+ audio_format_t targetFormat);
+
audio_module_handle_t getModuleHandle() const;
uint32_t getModuleVersion() const;
const char *getModuleName() const;
@@ -159,10 +165,6 @@
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const = 0;
virtual sp<AudioPort> getAudioPort() const = 0;
- virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
- return (other != 0) &&
- (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
- }
uint32_t mSamplingRate;
audio_format_t mFormat;
audio_channel_mask_t mChannelMask;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 648cc00..576822c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -85,10 +85,8 @@
uint32_t getOpenCount() const;
AudioSessionCollection getActiveSessions() const;
- size_t getActiveSessionCount() const;
bool hasActiveSession() const;
bool isSourceActive(audio_source_t source) const;
- audio_source_t getHighestPrioritySource(bool activeOnly) const;
status_t dump(int fd, int spaces) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 38d7ad5..9b6469c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -132,12 +132,6 @@
return mSessions.isSourceActive(source);
}
-audio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
-{
-
- return mSessions.getHighestPrioritySource(activeOnly);
-}
-
bool AudioInputDescriptor::isSoundTrigger() const {
// sound trigger and non sound trigger sessions are not mixed
// on a given input
@@ -149,22 +143,9 @@
return mSessions.valueFor(session);
}
-AudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
+AudioSessionCollection AudioInputDescriptor::getActiveAudioSessions() const
{
- if (activeOnly) {
- return mSessions.getActiveSessions();
- } else {
- return mSessions;
- }
-}
-
-size_t AudioInputDescriptor::getAudioSessionCount(bool activeOnly) const
-{
- if (activeOnly) {
- return mSessions.getActiveSessionCount();
- } else {
- return mSessions.size();
- }
+ return mSessions.getActiveSessions();
}
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
@@ -235,19 +216,17 @@
return count;
}
-Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
+audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs)
{
- Vector<sp <AudioInputDescriptor> > activeInputs;
-
for (size_t i = 0; i < size(); i++) {
const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
if ((inputDescriptor->isActive())
&& (!ignoreVirtualInputs ||
!is_virtual_input_device(inputDescriptor->mDevice))) {
- activeInputs.add(inputDescriptor);
+ return keyAt(i);
}
}
- return activeInputs;
+ return 0;
}
audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index f5927ab..5d0f03f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -81,7 +81,7 @@
return sharesHwModuleWith(outputDesc->subOutput1()) ||
sharesHwModuleWith(outputDesc->subOutput2());
} else {
- return hasSameHwModuleAs(outputDesc);
+ return (getModuleHandle() == outputDesc->getModuleHandle());
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 191439e..bda59ad 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -268,6 +268,32 @@
return index1 - index2;
}
+bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
+ audio_format_t currentFormat,
+ audio_format_t targetFormat)
+{
+ if (newFormat == currentFormat) {
+ return false;
+ }
+ if (currentFormat == AUDIO_FORMAT_INVALID) {
+ return true;
+ }
+ if (newFormat == targetFormat) {
+ return true;
+ }
+ int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
+ audio_bytes_per_sample(currentFormat);
+ int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
+ audio_bytes_per_sample(newFormat);
+
+ if (abs(newDiffBytes) < abs(currentDiffBytes)) {
+ return true;
+ } else if (abs(newDiffBytes) == abs(currentDiffBytes)) {
+ return (newDiffBytes >= 0);
+ }
+ return false;
+}
+
void AudioPort::pickAudioProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index c599665..961072e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -31,7 +31,7 @@
status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask,
audio_format_t format) const
{
- if (format == mFormat &&
+ if (audio_formats_match(format, mFormat) &&
(mChannelMasks.isEmpty() || supportsChannels(channelMask)) &&
(mSamplingRates.isEmpty() || supportsRate(samplingRate))) {
return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 306ed28..597c029 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -18,7 +18,6 @@
//#define LOG_NDEBUG 0
#include <AudioPolicyInterface.h>
-#include "policy.h"
#include "AudioSession.h"
#include "AudioGain.h"
#include "TypeConverter.h"
@@ -186,20 +185,9 @@
return activeSessions;
}
-size_t AudioSessionCollection::getActiveSessionCount() const
-{
- size_t activeCount = 0;
- for (size_t i = 0; i < size(); i++) {
- if (valueAt(i)->activeCount() != 0) {
- activeCount++;
- }
- }
- return activeCount;
-}
-
bool AudioSessionCollection::hasActiveSession() const
{
- return getActiveSessionCount() != 0;
+ return getActiveSessions().size() != 0;
}
bool AudioSessionCollection::isSourceActive(audio_source_t source) const
@@ -219,24 +207,6 @@
return false;
}
-audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const
-{
- audio_source_t source = AUDIO_SOURCE_DEFAULT;
- int32_t priority = -1;
-
- for (size_t i = 0; i < size(); i++) {
- const sp<AudioSession> audioSession = valueAt(i);
- if (activeOnly && audioSession->activeCount() == 0) {
- continue;
- }
- int32_t curPriority = source_priority(audioSession->inputSource());
- if (curPriority > priority) {
- priority = curPriority;
- source = audioSession->inputSource();
- }
- }
- return source;
-}
status_t AudioSessionCollection::dump(int fd, int spaces) const
{
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8bb49fa..758673b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -420,17 +420,15 @@
// FIXME: would be better to refine to only inputs whose profile connects to the
// call TX device but this information is not in the audio patch and logic here must be
// symmetric to the one in startInput()
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
- if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
- AudioSessionCollection activeSessions =
- activeDesc->getAudioSessions(true /*activeOnly*/);
- for (size_t j = 0; j < activeSessions.size(); j++) {
- audio_session_t activeSession = activeSessions.keyAt(j);
- stopInput(activeDesc->mIoHandle, activeSession);
- releaseInput(activeDesc->mIoHandle, activeSession);
- }
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ if (activeDesc->getModuleHandle() == txSourceDeviceDesc->getModuleHandle()) {
+ //FIXME: consider all active sessions
+ AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
+ audio_session_t activeSession = activeSessions.keyAt(0);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
}
}
@@ -596,16 +594,15 @@
}
}
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
- audio_devices_t newDevice = getNewInputDevice(activeDesc);
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ audio_devices_t newDevice = getNewInputDevice(activeInput);
// Force new input selection if the new device can not be reached via current input
- if (activeDesc->mProfile->getSupportedDevices().types() &
- (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
- setInputDevice(activeDesc->mIoHandle, newDevice);
+ if (activeDesc->mProfile->getSupportedDevices().types() & (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+ setInputDevice(activeInput, newDevice);
} else {
- closeInput(activeDesc->mIoHandle);
+ closeInput(activeInput);
}
}
}
@@ -876,7 +873,7 @@
outputDesc = desc;
// reuse direct output if currently open and configured with same parameters
if ((samplingRate == outputDesc->mSamplingRate) &&
- (format == outputDesc->mFormat) &&
+ audio_formats_match(format, outputDesc->mFormat) &&
(channelMask == outputDesc->mChannelMask)) {
outputDesc->mDirectOpenCount++;
ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
@@ -927,7 +924,7 @@
// only accept an output with the requested parameters
if (status != NO_ERROR ||
(samplingRate != 0 && samplingRate != config.sample_rate) ||
- (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
+ (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) ||
(channelMask != 0 && channelMask != config.channel_mask)) {
ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
"format %d %d, channelMask %04x %04x", output, samplingRate,
@@ -992,8 +989,9 @@
// devices (the list was previously build by getOutputsForDevice()).
// The priority is as follows:
// 1: the output with the highest number of requested policy flags
- // 2: the primary output
- // 3: the first output in the list
+ // 2: the output with the bit depth the closest to the requested one
+ // 3: the primary output
+ // 4: the first output in the list
if (outputs.size() == 0) {
return 0;
@@ -1003,8 +1001,11 @@
}
int maxCommonFlags = 0;
- audio_io_handle_t outputFlags = 0;
- audio_io_handle_t outputPrimary = 0;
+ audio_io_handle_t outputForFlags = 0;
+ audio_io_handle_t outputForPrimary = 0;
+ audio_io_handle_t outputForFormat = 0;
+ audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
+ audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
for (size_t i = 0; i < outputs.size(); i++) {
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
@@ -1012,31 +1013,48 @@
// if a valid format is specified, skip output if not compatible
if (format != AUDIO_FORMAT_INVALID) {
if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
- if (format != outputDesc->mFormat) {
+ if (!audio_formats_match(format, outputDesc->mFormat)) {
continue;
}
} else if (!audio_is_linear_pcm(format)) {
continue;
}
+ if (AudioPort::isBetterFormatMatch(
+ outputDesc->mFormat, bestFormat, format)) {
+ outputForFormat = outputs[i];
+ bestFormat = outputDesc->mFormat;
+ }
}
int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
- if (commonFlags > maxCommonFlags) {
- outputFlags = outputs[i];
- maxCommonFlags = commonFlags;
+ if (commonFlags >= maxCommonFlags) {
+ if (commonFlags == maxCommonFlags) {
+ if (AudioPort::isBetterFormatMatch(
+ outputDesc->mFormat, bestFormatForFlags, format)) {
+ outputForFlags = outputs[i];
+ bestFormatForFlags = outputDesc->mFormat;
+ }
+ } else {
+ outputForFlags = outputs[i];
+ maxCommonFlags = commonFlags;
+ bestFormatForFlags = outputDesc->mFormat;
+ }
ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
}
if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
- outputPrimary = outputs[i];
+ outputForPrimary = outputs[i];
}
}
}
- if (outputFlags != 0) {
- return outputFlags;
+ if (outputForFlags != 0) {
+ return outputForFlags;
}
- if (outputPrimary != 0) {
- return outputPrimary;
+ if (outputForFormat != 0) {
+ return outputForFormat;
+ }
+ if (outputForPrimary != 0) {
+ return outputForPrimary;
}
return outputs[0];
@@ -1337,7 +1355,6 @@
*input = AUDIO_IO_HANDLE_NONE;
*inputType = API_INPUT_INVALID;
-
audio_devices_t device;
// handle legacy remote submix case where the address was not always specified
String8 address = String8("");
@@ -1475,22 +1492,14 @@
isSoundTrigger,
policyMix, mpClientInterface);
-
+// TODO enable input reuse
+#if 0
// reuse an open input if possible
for (size_t i = 0; i < mInputs.size(); i++) {
sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
- // reuse input if:
- // - it shares the same profile
- // AND
- // - it is not a reroute submix input
- // AND
- // - it is: not used for sound trigger
- // OR
- // used for sound trigger and all clients use the same session ID
- //
- if ((profile == desc->mProfile) &&
- (isSoundTrigger == desc->isSoundTrigger()) &&
- !is_virtual_input_device(device)) {
+ // reuse input if it shares the same profile and same sound trigger attribute
+ if (profile == desc->mProfile &&
+ isSoundTrigger == desc->isSoundTrigger()) {
sp<AudioSession> as = desc->getAudioSession(session);
if (as != 0) {
@@ -1500,33 +1509,16 @@
} else {
ALOGW("getInputForDevice() record with different attributes"
" exists for session %d", session);
- break;
+ return input;
}
- } else if (isSoundTrigger) {
- break;
- }
- // force close input if current source is now the highest priority request on this input
- // and current input properties are not exactly as requested.
- if ((desc->mSamplingRate != samplingRate ||
- desc->mChannelMask != channelMask ||
- desc->mFormat != format) &&
- (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
- source_priority(inputSource))) {
- ALOGV("%s: ", __FUNCTION__);
- AudioSessionCollection sessions = desc->getAudioSessions(false /*activeOnly*/);
- for (size_t j = 0; j < sessions.size(); j++) {
- audio_session_t currentSession = sessions.keyAt(j);
- stopInput(desc->mIoHandle, currentSession);
- releaseInput(desc->mIoHandle, currentSession);
- }
- break;
} else {
desc->addAudioSession(session, audioSession);
- ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
- return mInputs.keyAt(i);
}
+ ALOGV("getInputForDevice() reusing input %d", mInputs.keyAt(i));
+ return mInputs.keyAt(i);
}
}
+#endif
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = profileSamplingRate;
@@ -1544,7 +1536,7 @@
// only accept input with the exact requested set of parameters
if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
(profileSamplingRate != config.sample_rate) ||
- (profileFormat != config.format) ||
+ !audio_formats_match(profileFormat, config.format) ||
(profileChannelMask != config.channel_mask)) {
ALOGW("getInputForAttr() failed opening input: samplingRate %d"
", format %d, channelMask %x",
@@ -1569,50 +1561,10 @@
return input;
}
-bool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
- const sp<AudioSession>& audioSession)
-{
- // Do not allow capture if an active voice call is using a software patch and
- // the call TX source device is on the same HW module.
- // FIXME: would be better to refine to only inputs whose profile connects to the
- // call TX device but this information is not in the audio patch
- if (mCallTxPatch != 0 &&
- inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
- return false;
- }
-
- // starting concurrent capture is enabled if:
- // 1) capturing for re-routing
- // 2) capturing for HOTWORD source
- // 3) capturing for FM TUNER source
- // 3) All other active captures are either for re-routing or HOTWORD
-
- if (is_virtual_input_device(inputDesc->mDevice) ||
- audioSession->inputSource() == AUDIO_SOURCE_HOTWORD ||
- audioSession->inputSource() == AUDIO_SOURCE_FM_TUNER) {
- return true;
- }
-
- Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeInput = activeInputs[i];
- if ((activeInput->inputSource() != AUDIO_SOURCE_HOTWORD) &&
- (activeInput->inputSource() != AUDIO_SOURCE_FM_TUNER) &&
- !is_virtual_input_device(activeInput->mDevice)) {
- return false;
- }
- }
-
- return true;
-}
-
-
status_t AudioPolicyManager::startInput(audio_io_handle_t input,
- audio_session_t session,
- concurrency_type__mask_t *concurrency)
+ audio_session_t session)
{
ALOGV("startInput() input %d", input);
- *concurrency = API_INPUT_CONCURRENCY_NONE;
ssize_t index = mInputs.indexOfKey(input);
if (index < 0) {
ALOGW("startInput() unknown input %d", input);
@@ -1626,62 +1578,81 @@
return BAD_VALUE;
}
- if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
- ALOGW("startInput(%d) failed: other input already started", input);
- return INVALID_OPERATION;
- }
+ // virtual input devices are compatible with other input devices
+ if (!is_virtual_input_device(inputDesc->mDevice)) {
- if (isInCall()) {
- *concurrency |= API_INPUT_CONCURRENCY_CALL;
- }
- if (mInputs.activeInputsCount() != 0) {
- *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
- }
+ // for a non-virtual input device, check if there is another (non-virtual) active input
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0 && activeInput != input) {
- // increment activity count before calling getNewInputDevice() below as only active sessions
- // are considered for device selection
- audioSession->changeActiveCount(1);
+ // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
+ // otherwise the active input continues and the new input cannot be started.
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ if ((activeDesc->inputSource() == AUDIO_SOURCE_HOTWORD) &&
+ !activeDesc->hasPreemptedSession(session)) {
+ ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
+ //FIXME: consider all active sessions
+ AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
+ audio_session_t activeSession = activeSessions.keyAt(0);
+ SortedVector<audio_session_t> sessions =
+ activeDesc->getPreemptedSessions();
+ sessions.add(activeSession);
+ inputDesc->setPreemptedSessions(sessions);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
+ } else {
+ ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
+ return INVALID_OPERATION;
+ }
+ }
+
+ // Do not allow capture if an active voice call is using a software patch and
+ // the call TX source device is on the same HW module.
+ // FIXME: would be better to refine to only inputs whose profile connects to the
+ // call TX device but this information is not in the audio patch
+ if (mCallTxPatch != 0 &&
+ inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
+ return INVALID_OPERATION;
+ }
+ }
// Routing?
mInputRoutes.incRouteActivity(session);
- if (audioSession->activeCount() == 1 || mInputRoutes.hasRouteChanged(session)) {
+ if (!inputDesc->isActive() || mInputRoutes.hasRouteChanged(session)) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_MIXING);
+ }
- setInputDevice(input, getNewInputDevice(inputDesc), true /* force */);
+ if (mInputs.activeInputsCount() == 0) {
+ SoundTrigger::setCaptureState(true);
+ }
+ setInputDevice(input, getNewInputDevice(input), true /* force */);
- if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((inputDesc->mPolicyMix != NULL)
- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
- MIX_STATE_MIXING);
+ // automatically enable the remote submix output when input is started if not
+ // used by a policy mix of type MIX_TYPE_RECORDERS
+ // For remote submix (a virtual device), we open only one input per capture request.
+ if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+ String8 address = String8("");
+ if (inputDesc->mPolicyMix == NULL) {
+ address = String8("0");
+ } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
+ address = inputDesc->mPolicyMix->mRegistrationId;
}
-
- if (mInputs.activeInputsCount() == 0) {
- SoundTrigger::setCaptureState(true);
- }
-
- // automatically enable the remote submix output when input is started if not
- // used by a policy mix of type MIX_TYPE_RECORDERS
- // For remote submix (a virtual device), we open only one input per capture request.
- if (audio_is_remote_submix_device(inputDesc->mDevice)) {
- String8 address = String8("");
- if (inputDesc->mPolicyMix == NULL) {
- address = String8("0");
- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
- address = inputDesc->mPolicyMix->mRegistrationId;
- }
- if (address != "") {
- setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address, "remote-submix");
- }
+ if (address != "") {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ address, "remote-submix");
}
}
}
ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
+ audioSession->changeActiveCount(1);
return NO_ERROR;
}
@@ -1712,41 +1683,36 @@
// Routing?
mInputRoutes.decRouteActivity(session);
- if (audioSession->activeCount() == 0) {
-
- if (inputDesc->isActive()) {
- setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
- } else {
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((inputDesc->mPolicyMix != NULL)
- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
- MIX_STATE_IDLE);
- }
-
- // automatically disable the remote submix output when input is stopped if not
- // used by a policy mix of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(inputDesc->mDevice)) {
- String8 address = String8("");
- if (inputDesc->mPolicyMix == NULL) {
- address = String8("0");
- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
- address = inputDesc->mPolicyMix->mRegistrationId;
- }
- if (address != "") {
- setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address, "remote-submix");
- }
- }
-
- resetInputDevice(input);
-
- if (mInputs.activeInputsCount() == 0) {
- SoundTrigger::setCaptureState(false);
- }
- inputDesc->clearPreemptedSessions();
+ if (!inputDesc->isActive()) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_IDLE);
}
+
+ // automatically disable the remote submix output when input is stopped if not
+ // used by a policy mix of type MIX_TYPE_RECORDERS
+ if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+ String8 address = String8("");
+ if (inputDesc->mPolicyMix == NULL) {
+ address = String8("0");
+ } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
+ address = inputDesc->mPolicyMix->mRegistrationId;
+ }
+ if (address != "") {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ address, "remote-submix");
+ }
+ }
+
+ resetInputDevice(input);
+
+ if (mInputs.activeInputsCount() == 0) {
+ SoundTrigger::setCaptureState(false);
+ }
+ inputDesc->clearPreemptedSessions();
}
return NO_ERROR;
}
@@ -2200,6 +2166,15 @@
return false;
}
+ // Check if streaming is off, then only allow offload as of now.
+ // This is a temporary work around until the root cause is fixed in offload
+ // playback path.
+ 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 */);
@@ -2509,7 +2484,7 @@
// create a software bridge in PatchPanel if:
// - source and sink devices are on differnt HW modules OR
// - audio HAL version is < 3.0
- if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
+ if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) ||
(srcDeviceDesc->mModule->getHalVersion() < AUDIO_DEVICE_API_VERSION_3_0)) {
// support only one sink device for now to simplify output selection logic
if (patch->num_sinks > 1) {
@@ -2609,7 +2584,7 @@
return BAD_VALUE;
}
setInputDevice(inputDesc->mIoHandle,
- getNewInputDevice(inputDesc),
+ getNewInputDevice(inputDesc->mIoHandle),
true,
NULL);
} else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
@@ -4235,9 +4210,9 @@
return device;
}
-audio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
+audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
{
- audio_devices_t device = AUDIO_DEVICE_NONE;
+ sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
if (index >= 0) {
@@ -4249,12 +4224,7 @@
}
}
- audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
- if (isInCall()) {
- device = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
- } else if (source != AUDIO_SOURCE_DEFAULT) {
- device = getDeviceAndMixForInputSource(source);
- }
+ audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->inputSource());
return device;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 1b1a9b4..fb9b46b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -139,8 +139,7 @@
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
- audio_session_t session,
- concurrency_type__mask_t *concurrency);
+ audio_session_t session);
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
@@ -406,7 +405,7 @@
void updateDevicesAndOutputs();
// selects the most appropriate device on input for current state
- audio_devices_t getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc);
+ audio_devices_t getNewInputDevice(audio_io_handle_t input);
virtual uint32_t getMaxEffectsCpuLoad()
{
@@ -506,8 +505,6 @@
void clearAudioSources(uid_t uid);
- bool isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
- const sp<AudioSession>& audioSession);
uid_t mUidCached;
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 9a28137..ce77814 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -57,11 +57,11 @@
}
mInputSources.clear();
- for (i = 0; i < mInputSessions.size(); i++) {
- mInputSessions.valueAt(i)->mEffects.clear();
- delete mInputSessions.valueAt(i);
+ for (i = 0; i < mInputs.size(); i++) {
+ mInputs.valueAt(i)->mEffects.clear();
+ delete mInputs.valueAt(i);
}
- mInputSessions.clear();
+ mInputs.clear();
// release audio output processing resources
for (i = 0; i < mOutputStreams.size(); i++) {
@@ -79,7 +79,7 @@
status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
audio_source_t inputSource,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
@@ -93,19 +93,19 @@
ALOGV("addInputEffects(): no processing needs to be attached to this source");
return status;
}
- ssize_t idx = mInputSessions.indexOfKey(audioSession);
- EffectVector *sessionDesc;
+ ssize_t idx = mInputs.indexOfKey(input);
+ EffectVector *inputDesc;
if (idx < 0) {
- sessionDesc = new EffectVector(audioSession);
- mInputSessions.add(audioSession, sessionDesc);
+ inputDesc = new EffectVector(audioSession);
+ mInputs.add(input, inputDesc);
} else {
// EffectVector is existing and we just need to increase ref count
- sessionDesc = mInputSessions.valueAt(idx);
+ inputDesc = mInputs.valueAt(idx);
}
- sessionDesc->mRefCount++;
+ inputDesc->mRefCount++;
- ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
- if (sessionDesc->mRefCount == 1) {
+ ALOGV("addInputEffects(): input: %d, refCount: %d", input, inputDesc->mRefCount);
+ if (inputDesc->mRefCount == 1) {
Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
@@ -123,37 +123,36 @@
}
ALOGV("addInputEffects(): added Fx %s on source: %d",
effect->mName, (int32_t)aliasSource);
- sessionDesc->mEffects.add(fx);
+ inputDesc->mEffects.add(fx);
}
- sessionDesc->setProcessorEnabled(true);
+ inputDesc->setProcessorEnabled(true);
}
return status;
}
-status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
- audio_session_t audioSession)
+status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input)
{
status_t status = NO_ERROR;
Mutex::Autolock _l(mLock);
- ssize_t index = mInputSessions.indexOfKey(audioSession);
+ ssize_t index = mInputs.indexOfKey(input);
if (index < 0) {
return status;
}
- EffectVector *sessionDesc = mInputSessions.valueAt(index);
- sessionDesc->mRefCount--;
- ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
- if (sessionDesc->mRefCount == 0) {
- sessionDesc->setProcessorEnabled(false);
- delete sessionDesc;
- mInputSessions.removeItemsAt(index);
+ EffectVector *inputDesc = mInputs.valueAt(index);
+ inputDesc->mRefCount--;
+ ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, inputDesc->mRefCount);
+ if (inputDesc->mRefCount == 0) {
+ inputDesc->setProcessorEnabled(false);
+ delete inputDesc;
+ mInputs.removeItemsAt(index);
ALOGV("releaseInputEffects(): all effects released");
}
return status;
}
-status_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
+status_t AudioPolicyEffects::queryDefaultInputEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
{
@@ -161,16 +160,16 @@
Mutex::Autolock _l(mLock);
size_t index;
- for (index = 0; index < mInputSessions.size(); index++) {
- if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
+ for (index = 0; index < mInputs.size(); index++) {
+ if (mInputs.valueAt(index)->mSessionId == audioSession) {
break;
}
}
- if (index == mInputSessions.size()) {
+ if (index == mInputs.size()) {
*count = 0;
return BAD_VALUE;
}
- Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
+ Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
effect_descriptor_t desc = effects[i]->descriptor();
@@ -186,7 +185,7 @@
}
-status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
+status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
{
@@ -221,7 +220,7 @@
status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
@@ -276,7 +275,7 @@
status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
(void) output; // argument not used for now
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index f302167..266a45e 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -51,7 +51,7 @@
// Return a list of effect descriptors for default input effects
// associated with audioSession
- status_t queryDefaultInputEffects(audio_session_t audioSession,
+ status_t queryDefaultInputEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
@@ -59,16 +59,15 @@
// Effects are attached depending on the audio_source_t
status_t addInputEffects(audio_io_handle_t input,
audio_source_t inputSource,
- audio_session_t audioSession);
+ int audioSession);
// Add all input effects associated to this input
- status_t releaseInputEffects(audio_io_handle_t input,
- audio_session_t audioSession);
+ status_t releaseInputEffects(audio_io_handle_t input);
// Return a list of effect descriptors for default output effects
// associated with audioSession
- status_t queryDefaultOutputSessionEffects(audio_session_t audioSession,
+ status_t queryDefaultOutputSessionEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
@@ -76,12 +75,12 @@
// Effects are attached depending on the audio_stream_type_t
status_t addOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession);
+ int audioSession);
// release all output effects associated with this output stream and audiosession
status_t releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession);
+ int audioSession);
private:
@@ -179,17 +178,17 @@
size_t *curSize,
size_t *totSize);
- // protects access to mInputSources, mInputSessions, mOutputStreams, mOutputSessions
+ // protects access to mInputSources, mInputs, mOutputStreams, mOutputSessions
Mutex mLock;
// Automatic input effects are configured per audio_source_t
KeyedVector< audio_source_t, EffectDescVector* > mInputSources;
// Automatic input effects are unique for audio_io_handle_t
- KeyedVector< audio_session_t, EffectVector* > mInputSessions;
+ KeyedVector< audio_io_handle_t, EffectVector* > mInputs;
// Automatic output effects are organized per audio_stream_type_t
KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
// Automatic output effects are unique for audiosession ID
- KeyedVector< audio_session_t, EffectVector* > mOutputSessions;
+ KeyedVector< int32_t, EffectVector* > mOutputSessions;
};
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index ae5cf3d..c7486a5 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -349,23 +349,8 @@
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- AudioPolicyInterface::concurrency_type__mask_t concurrency;
- status_t status = mAudioPolicyManager->startInput(input, session, &concurrency);
- if (status == NO_ERROR) {
- LOG_ALWAYS_FATAL_IF(concurrency & ~AudioPolicyInterface::API_INPUT_CONCURRENCY_ALL,
- "startInput(): invalid concurrency type %d", (int)concurrency);
-
- // enforce permission (if any) required for each type of concurrency
- if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CALL) {
- //TODO: check incall capture permission
- }
- if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE) {
- //TODO: check concurrent capture permission
- }
- }
-
- return status;
+ return mAudioPolicyManager->startInput(input, session);
}
status_t AudioPolicyService::stopInput(audio_io_handle_t input,
@@ -393,7 +378,7 @@
}
if (audioPolicyEffects != 0) {
// release audio processors from the input
- status_t status = audioPolicyEffects->releaseInputEffects(input, session);
+ status_t status = audioPolicyEffects->releaseInputEffects(input);
if(status != NO_ERROR) {
ALOGW("Failed to release effects on input %d", input);
}
@@ -566,8 +551,7 @@
*count = 0;
return NO_INIT;
}
- return audioPolicyEffects->queryDefaultInputEffects(
- (audio_session_t)audioSession, descriptors, count);
+ return audioPolicyEffects->queryDefaultInputEffects(audioSession, descriptors, count);
}
bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index 42719f6..08b2a3b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -306,7 +306,7 @@
}
void AudioPolicyService::releaseInput(audio_io_handle_t input,
- audio_session_t session)
+ audio_session_t session __unused)
{
if (mpAudioPolicy == NULL) {
return;
@@ -320,7 +320,7 @@
}
if (audioPolicyEffects != 0) {
// release audio processors from the input
- status_t status = audioPolicyEffects->releaseInputEffects(input, session);
+ status_t status = audioPolicyEffects->releaseInputEffects(input);
if(status != NO_ERROR) {
ALOGW("Failed to release effects on input %d", input);
}
diff --git a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
index 66522cc..5bbd4e3 100644
--- a/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
+++ b/services/mediaextractor/minijail/seccomp_policy/mediaextractor-seccomp-arm.policy
@@ -31,6 +31,7 @@
sched_setscheduler: 1
gettid: 1
rt_sigprocmask: 1
+sched_yield: 1
# for attaching to debuggerd on process crash
sigaction: 1
diff --git a/services/radio/Android.mk b/services/radio/Android.mk
index 9ee5666..6aae31d 100644
--- a/services/radio/Android.mk
+++ b/services/radio/Android.mk
@@ -31,6 +31,8 @@
libradio \
libradio_metadata
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
LOCAL_MODULE:= libradioservice
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/radio/RadioRegions.h b/services/radio/RadioRegions.h
index 3335b8a..d40ee83 100644
--- a/services/radio/RadioRegions.h
+++ b/services/radio/RadioRegions.h
@@ -67,11 +67,14 @@
1,
{RADIO_BAND_SPACING_FM_ITU1},
{
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_50,
+ true,
+ RADIO_RDS_WORLD,
+ true,
+ true,
+ true,
+ }
}
}
},
@@ -85,11 +88,14 @@
1,
{RADIO_BAND_SPACING_FM_ITU2},
{
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_US,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_75,
+ true,
+ RADIO_RDS_US,
+ true,
+ true,
+ true,
+ }
}
}
},
@@ -103,11 +109,14 @@
1,
{RADIO_BAND_SPACING_FM_JAPAN},
{
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_50,
+ true,
+ RADIO_RDS_WORLD,
+ true,
+ true,
+ true,
+ }
}
}
},
@@ -121,11 +130,14 @@
1,
{RADIO_BAND_SPACING_FM_ITU1},
{
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_75,
+ true,
+ RADIO_RDS_WORLD,
+ true,
+ true,
+ true,
+ }
}
}
},
@@ -139,11 +151,14 @@
1,
{RADIO_BAND_SPACING_FM_OIRT},
{
- RADIO_DEEMPHASIS_50,
- true,
- RADIO_RDS_WORLD,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_50,
+ true,
+ RADIO_RDS_WORLD,
+ true,
+ true,
+ true,
+ }
}
}
},
@@ -157,11 +172,14 @@
1,
{RADIO_BAND_SPACING_FM_ITU2},
{
- RADIO_DEEMPHASIS_75,
- true,
- RADIO_RDS_US,
- true,
- true,
+ {
+ RADIO_DEEMPHASIS_75,
+ true,
+ RADIO_RDS_US,
+ true,
+ true,
+ true,
+ }
}
}
},
diff --git a/services/radio/RadioService.cpp b/services/radio/RadioService.cpp
index 57697f3..5a3f750 100644
--- a/services/radio/RadioService.cpp
+++ b/services/radio/RadioService.cpp
@@ -735,7 +735,7 @@
}
} else {
mConfig = *config;
- status == INVALID_OPERATION;
+ status = INVALID_OPERATION;
}
return status;