summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-12 15:01:24 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-12 15:01:24 +0100
commite15fd68c5dc4089690b5d3086776c3851e504bb7 (patch)
tree2c75274dee02b07463c9164efdf6888e1a9c75dc /media/libmedia
parent185e2110a53feb7720d91b6f8366ad27402f21cc (diff)
parent26c5fa31d17a638bf314de6e12e86bb8a86db44b (diff)
downloadframeworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.zip
frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.gz
frameworks_av-e15fd68c5dc4089690b5d3086776c3851e504bb7.tar.bz2
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_av into replicant-6.0
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/Android.mk1
-rw-r--r--media/libmedia/AudioRecord.cpp9
-rw-r--r--media/libmedia/AudioSystem.cpp33
-rw-r--r--media/libmedia/AudioTrack.cpp4
-rw-r--r--media/libmedia/IAudioPolicyService.cpp54
-rw-r--r--media/libmedia/IAudioPolicyServiceClient.cpp20
-rw-r--r--media/libmedia/IDrm.cpp4
-rw-r--r--media/libmedia/IMediaDeathNotifier.cpp2
-rw-r--r--media/libmedia/IOMX.cpp143
-rw-r--r--media/libmedia/MediaUtils.cpp74
-rw-r--r--media/libmedia/MediaUtils.h35
-rw-r--r--media/libmedia/mediametadataretriever.cpp4
-rw-r--r--media/libmedia/mediaplayer.cpp6
-rwxr-xr-xmedia/libmedia/mediarecorder.cpp2
14 files changed, 302 insertions, 89 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 74e4eb1..efcd541 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -44,6 +44,7 @@ LOCAL_SRC_FILES:= \
IResourceManagerService.cpp \
IStreamSource.cpp \
MediaCodecInfo.cpp \
+ MediaUtils.cpp \
Metadata.cpp \
mediarecorder.cpp \
IMediaMetadataRetriever.cpp \
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 40f6c44..40cad59 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -67,7 +67,7 @@ status_t AudioRecord::getMinFrameCount(
// ---------------------------------------------------------------------------
AudioRecord::AudioRecord(const String16 &opPackageName)
- : mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
+ : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
{
@@ -89,7 +89,8 @@ AudioRecord::AudioRecord(
int uid,
pid_t pid,
const audio_attributes_t* pAttributes)
- : mStatus(NO_INIT),
+ : mActive(false),
+ mStatus(NO_INIT),
mOpPackageName(opPackageName),
mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -273,7 +274,6 @@ status_t AudioRecord::set(
}
mStatus = NO_ERROR;
- mActive = false;
mUserData = user;
// TODO: add audio hardware input latency here
if (mTransfer == TRANSFER_CALLBACK ||
@@ -299,7 +299,7 @@ status_t AudioRecord::set(
status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
{
ALOGV("start, sync event %d trigger session %d", event, triggerSession);
- SEEMPLOG_RECORD(89,"");
+ SEEMPLOG_RECORD(71,"");
AutoMutex lock(mLock);
if (mActive) {
@@ -347,7 +347,6 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
void AudioRecord::stop()
{
- SEEMPLOG_RECORD(90,"");
AutoMutex lock(mLock);
if (!mActive) {
return;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 10ec495..2e9fca9 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -37,7 +37,7 @@ sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
-effect_session_callback AudioSystem::gEffectSessionCallback = NULL;
+audio_session_callback AudioSystem::gAudioSessionCallback = NULL;
// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
@@ -652,19 +652,15 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
gDynPolicyCallback = cb;
}
-/*static*/ status_t AudioSystem::setEffectSessionCallback(effect_session_callback cb)
+/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
Mutex::Autolock _l(gLock);
- gEffectSessionCallback = cb;
+ gAudioSessionCallback = cb;
- status_t status = aps->setEffectSessionCallbacksEnabled(cb != NULL);
- if (status != OK) {
- gEffectSessionCallback = NULL;
- }
- return status;
+ return NO_ERROR;
}
// client singleton for AudioPolicyService binder interface
@@ -1238,18 +1234,29 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(
}
}
+// ---------------------------------------------------------------------------
+
+status_t AudioSystem::listAudioSessions(audio_stream_type_t stream,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->listAudioSessions(stream, sessions);
+}
+
void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ sp<AudioSessionInfo>& info, bool added)
{
- ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)", stream, sessionId, added);
- effect_session_callback cb = NULL;
+ ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)",
+ info->mStream, info->mSessionId, added);
+ audio_session_callback cb = NULL;
{
Mutex::Autolock _l(AudioSystem::gLock);
- cb = gEffectSessionCallback;
+ cb = gAudioSessionCallback;
}
if (cb != NULL) {
- cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, stream, sessionId, added);
+ cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added);
}
}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d7256f8..ae016ef 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -165,6 +165,7 @@ status_t AudioTrack::getMinFrameCount(
AudioTrack::AudioTrack()
: mStatus(NO_INIT),
+ mState(STATE_STOPPED),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
@@ -196,6 +197,7 @@ AudioTrack::AudioTrack(
const audio_attributes_t* pAttributes,
bool doNotReconnect)
: mStatus(NO_INIT),
+ mState(STATE_STOPPED),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
@@ -227,6 +229,7 @@ AudioTrack::AudioTrack(
const audio_attributes_t* pAttributes,
bool doNotReconnect)
: mStatus(NO_INIT),
+ mState(STATE_STOPPED),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
@@ -478,7 +481,6 @@ status_t AudioTrack::set(
}
mStatus = NO_ERROR;
- mState = STATE_STOPPED;
mUserData = user;
mLoopCount = 0;
mLoopStart = 0;
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 6ff8149..abae614 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -74,7 +74,7 @@ enum {
START_AUDIO_SOURCE,
STOP_AUDIO_SOURCE,
SET_AUDIO_PORT_CALLBACK_ENABLED,
- SET_EFFECT_SESSION_CALLBACK_ENABLED,
+ LIST_AUDIO_SESSIONS,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -656,18 +656,6 @@ public:
remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, data, &reply);
}
- virtual status_t setEffectSessionCallbacksEnabled(bool enabled)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
- data.writeInt32(enabled ? 1 : 0);
- status_t status = remote()->transact(SET_EFFECT_SESSION_CALLBACK_ENABLED, data, &reply);
- if (status != NO_ERROR) {
- return status;
- }
- return (status_t)reply.readInt32();
- }
-
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device)
@@ -780,6 +768,30 @@ public:
status = (status_t)reply.readInt32();
return status;
}
+
+ virtual status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(streams);
+ status_t status = remote()->transact(LIST_AUDIO_SESSIONS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ size_t size = (size_t)reply.readUint32();
+ for (size_t i = 0; i < size && reply.dataAvail() > 0; i++) {
+ sp<AudioSessionInfo> info = new AudioSessionInfo();
+ info->readFromParcel(reply);
+ sessions.push_back(info);
+ }
+ }
+ return status;
+ }
+
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1251,12 +1263,22 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
- case SET_EFFECT_SESSION_CALLBACK_ENABLED: {
+ case LIST_AUDIO_SESSIONS: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- status_t status = setEffectSessionCallbacksEnabled(data.readInt32() == 1);
+ audio_stream_type_t streams = (audio_stream_type_t)data.readInt32();
+
+ Vector< sp<AudioSessionInfo>> sessions;
+ status_t status = listAudioSessions(streams, sessions);
+
reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeUint32(static_cast<uint32_t>(sessions.size()));
+ for (size_t i = 0; i < sessions.size(); i++) {
+ sessions[i]->writeToParcel(reply);
+ }
+ }
return NO_ERROR;
- } break;
+ }
case ACQUIRE_SOUNDTRIGGER_SESSION: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp
index d6207ce..a325996 100644
--- a/media/libmedia/IAudioPolicyServiceClient.cpp
+++ b/media/libmedia/IAudioPolicyServiceClient.cpp
@@ -65,13 +65,15 @@ public:
remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
- void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added)
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
- data.writeInt32(stream);
- data.writeInt32(sessionId);
+ data.writeInt32(info->mStream);
+ data.writeInt32(info->mSessionId);
+ data.writeInt32(info->mFlags);
+ data.writeInt32(info->mChannelMask);
+ data.writeInt32(info->mUid);
data.writeInt32(added ? 1 : 0);
remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -105,9 +107,15 @@ status_t BnAudioPolicyServiceClient::onTransact(
case OUTPUT_SESSION_EFFECTS_UPDATE: {
CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
audio_stream_type_t stream = static_cast<audio_stream_type_t>(data.readInt32());
- audio_unique_id_t sessionId = static_cast<audio_unique_id_t>(data.readInt32());
+ audio_session_t sessionId = static_cast<audio_session_t>(data.readInt32());
+ audio_output_flags_t flags = static_cast<audio_output_flags_t>(data.readInt32());
+ audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(data.readInt32());
+ uid_t uid = static_cast<uid_t>(data.readInt32());
bool added = data.readInt32() > 0;
- onOutputSessionEffectsUpdate(stream, sessionId, added);
+
+ sp<AudioSessionInfo> info = new AudioSessionInfo(
+ sessionId, stream, flags, channelMask, uid);
+ onOutputSessionEffectsUpdate(info, added);
return NO_ERROR;
}
default:
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index b1ad0c5..6f6530b 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -658,7 +658,7 @@ status_t BnDrm::onTransact(
Vector<uint8_t> request;
String8 defaultUrl;
- DrmPlugin::KeyRequestType keyRequestType;
+ DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
status_t result = getKeyRequest(sessionId, initData, mimeType,
keyType, optionalParameters, request, defaultUrl,
@@ -912,7 +912,7 @@ status_t BnDrm::onTransact(
readVector(data, keyId);
readVector(data, message);
readVector(data, signature);
- bool match;
+ bool match = false;
uint32_t result = verify(sessionId, keyId, message, signature, match);
reply->writeInt32(match);
reply->writeInt32(result);
diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp
index d4360ea..c43ef66 100644
--- a/media/libmedia/IMediaDeathNotifier.cpp
+++ b/media/libmedia/IMediaDeathNotifier.cpp
@@ -31,7 +31,7 @@ sp<IMediaDeathNotifier::DeathNotifier> IMediaDeathNotifier::sDeathNotifier;
SortedVector< wp<IMediaDeathNotifier> > IMediaDeathNotifier::sObitRecipients;
// establish binder interface to MediaPlayerService
-/*static*/const sp<IMediaPlayerService>&
+/*static*/const sp<IMediaPlayerService>
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 5356494..7e951c9 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -18,11 +18,14 @@
#define LOG_TAG "IOMX"
#include <utils/Log.h>
+#include <sys/mman.h>
+
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/IOMX.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/AVMediaExtensions.h>
+#include <media/openmax/OMX_IndexExt.h>
namespace android {
@@ -246,7 +249,7 @@ public:
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
- buffer_id *buffer, OMX_U32 allottedSize) {
+ buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
@@ -447,7 +450,7 @@ public:
remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
status_t err = reply.readInt32();
- if (sidebandHandle) {
+ if (err == OK && sidebandHandle) {
*sidebandHandle = (native_handle_t *)reply.readNativeHandle();
}
return err;
@@ -480,7 +483,7 @@ public:
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> &params,
- buffer_id *buffer, OMX_U32 allottedSize) {
+ buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
@@ -694,34 +697,79 @@ status_t BnOMX::onTransact(
size_t size = data.readInt64();
- void *params = malloc(size);
- data.read(params, size);
-
- status_t err;
- switch (code) {
- case GET_PARAMETER:
- err = getParameter(node, index, params, size);
- break;
- case SET_PARAMETER:
- err = setParameter(node, index, params, size);
- break;
- case GET_CONFIG:
- err = getConfig(node, index, params, size);
- break;
- case SET_CONFIG:
- err = setConfig(node, index, params, size);
- break;
- case SET_INTERNAL_OPTION:
- {
- InternalOptionType type =
- (InternalOptionType)data.readInt32();
-
- err = setInternalOption(node, index, type, params, size);
- break;
+ status_t err = NOT_ENOUGH_DATA;
+ void *params = NULL;
+ size_t pageSize = 0;
+ size_t allocSize = 0;
+ bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
+ if ((isUsageBits && size < 4) ||
+ (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) {
+ // we expect the structure to contain at least the size and
+ // version, 8 bytes total
+ ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
+ android_errorWriteLog(0x534e4554, "27207275");
+ } else {
+ err = NO_MEMORY;
+ pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
+ if (size > SIZE_MAX - (pageSize * 2)) {
+ ALOGE("requested param size too big");
+ } else {
+ allocSize = (size + pageSize * 2) & ~(pageSize - 1);
+ params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
+ }
+ if (params != MAP_FAILED) {
+ err = data.read(params, size);
+ if (err != OK) {
+ android_errorWriteLog(0x534e4554, "26914474");
+ } else {
+ err = NOT_ENOUGH_DATA;
+ OMX_U32 declaredSize = *(OMX_U32*)params;
+ if (code != SET_INTERNAL_OPTION &&
+ index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
+ declaredSize > size) {
+ // the buffer says it's bigger than it actually is
+ ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
+ android_errorWriteLog(0x534e4554, "27207275");
+ } else {
+ // mark the last page as inaccessible, to avoid exploitation
+ // of codecs that access past the end of the allocation because
+ // they didn't check the size
+ if (mprotect((char*)params + allocSize - pageSize, pageSize,
+ PROT_NONE) != 0) {
+ ALOGE("mprotect failed: %s", strerror(errno));
+ } else {
+ switch (code) {
+ case GET_PARAMETER:
+ err = getParameter(node, index, params, size);
+ break;
+ case SET_PARAMETER:
+ err = setParameter(node, index, params, size);
+ break;
+ case GET_CONFIG:
+ err = getConfig(node, index, params, size);
+ break;
+ case SET_CONFIG:
+ err = setConfig(node, index, params, size);
+ break;
+ case SET_INTERNAL_OPTION:
+ {
+ InternalOptionType type =
+ (InternalOptionType)data.readInt32();
+
+ err = setInternalOption(node, index, type, params, size);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+ }
+ }
+ }
+ } else {
+ ALOGE("couldn't map: %s", strerror(errno));
}
-
- default:
- TRESPASS();
}
reply->writeInt32(err);
@@ -730,7 +778,9 @@ status_t BnOMX::onTransact(
reply->write(params, size);
}
- free(params);
+ if (params) {
+ munmap(params, allocSize);
+ }
params = NULL;
return NO_ERROR;
@@ -790,7 +840,8 @@ status_t BnOMX::onTransact(
OMX_U32 allottedSize = data.readInt32();
buffer_id buffer;
- status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
+ status_t err = useBuffer(
+ node, port_index, params, &buffer, allottedSize, OMX_TRUE /* crossProcess */);
reply->writeInt32(err);
if (err == OK) {
@@ -846,9 +897,13 @@ status_t BnOMX::onTransact(
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);
@@ -888,9 +943,13 @@ status_t BnOMX::onTransact(
sp<IGraphicBufferConsumer> bufferConsumer =
interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
- MetadataBufferType type;
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
status_t err = setInputSurface(node, port_index, bufferConsumer, &type);
+ if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
+ android_errorWriteLog(0x534e4554, "26324358");
+ }
+
reply->writeInt32(type);
reply->writeInt32(err);
return NO_ERROR;
@@ -916,8 +975,12 @@ status_t BnOMX::onTransact(
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- MetadataBufferType type;
- status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
+ MetadataBufferType type = kMetadataBufferTypeInvalid;
+ status_t err =
+ // only control output metadata via Binder
+ port_index != 1 /* kOutputPortIndex */ ? BAD_VALUE :
+ storeMetaDataInBuffers(node, port_index, enable, &type);
+
reply->writeInt32(type);
reply->writeInt32(err);
@@ -950,11 +1013,13 @@ status_t BnOMX::onTransact(
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);
- reply->writeNativeHandle(sideband_handle);
+ if(err == OK){
+ reply->writeNativeHandle(sideband_handle);
+ }
return NO_ERROR;
}
@@ -1000,7 +1065,7 @@ status_t BnOMX::onTransact(
buffer_id buffer;
status_t err = allocateBufferWithBackup(
- node, port_index, params, &buffer, allottedSize);
+ node, port_index, params, &buffer, allottedSize, OMX_TRUE /* crossProcess */);
reply->writeInt32(err);
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
new file mode 100644
index 0000000..a02ca65
--- /dev/null
+++ b/media/libmedia/MediaUtils.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "MediaUtils"
+#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <cutils/properties.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+#include "MediaUtils.h"
+
+namespace android {
+
+void limitProcessMemory(
+ const char *property,
+ size_t numberOfBytes,
+ size_t percentageOfTotalMem) {
+
+ long pageSize = sysconf(_SC_PAGESIZE);
+ long numPages = sysconf(_SC_PHYS_PAGES);
+ size_t maxMem = SIZE_MAX;
+
+ if (pageSize > 0 && numPages > 0) {
+ if (size_t(numPages) < SIZE_MAX / size_t(pageSize)) {
+ maxMem = size_t(numPages) * size_t(pageSize);
+ }
+ ALOGV("physMem: %zu", maxMem);
+ if (percentageOfTotalMem > 100) {
+ ALOGW("requested %zu%% of total memory, using 100%%", percentageOfTotalMem);
+ percentageOfTotalMem = 100;
+ }
+ maxMem = maxMem / 100 * percentageOfTotalMem;
+ if (numberOfBytes < maxMem) {
+ maxMem = numberOfBytes;
+ }
+ ALOGV("requested limit: %zu", maxMem);
+ } else {
+ ALOGW("couldn't determine total RAM");
+ }
+
+ int64_t propVal = property_get_int64(property, maxMem);
+ if (propVal > 0 && uint64_t(propVal) <= SIZE_MAX) {
+ maxMem = propVal;
+ }
+ ALOGV("actual limit: %zu", maxMem);
+
+ struct rlimit limit;
+ getrlimit(RLIMIT_AS, &limit);
+ ALOGV("original limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
+ limit.rlim_cur = maxMem;
+ setrlimit(RLIMIT_AS, &limit);
+ limit.rlim_cur = -1;
+ limit.rlim_max = -1;
+ getrlimit(RLIMIT_AS, &limit);
+ ALOGV("new limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max);
+
+}
+
+} // namespace android
diff --git a/media/libmedia/MediaUtils.h b/media/libmedia/MediaUtils.h
new file mode 100644
index 0000000..f80dd30
--- /dev/null
+++ b/media/libmedia/MediaUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MEDIA_UTILS_H
+#define _MEDIA_UTILS_H
+
+namespace android {
+
+/**
+ Limit the amount of memory a process can allocate using setrlimit(RLIMIT_AS).
+ The value to use will be read from the specified system property, or if the
+ property doesn't exist it will use the specified number of bytes or the
+ specified percentage of total memory, whichever is smaller.
+*/
+void limitProcessMemory(
+ const char *property,
+ size_t numberOfBytes,
+ size_t percentageOfTotalMem);
+
+} // namespace android
+
+#endif // _MEDIA_UTILS_H
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 9a76f58..08a9e6a 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -35,7 +35,7 @@ Mutex MediaMetadataRetriever::sServiceLock;
sp<IMediaPlayerService> MediaMetadataRetriever::sService;
sp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier;
-const sp<IMediaPlayerService>& MediaMetadataRetriever::getService()
+const sp<IMediaPlayerService> MediaMetadataRetriever::getService()
{
Mutex::Autolock lock(sServiceLock);
if (sService == 0) {
@@ -62,7 +62,7 @@ const sp<IMediaPlayerService>& MediaMetadataRetriever::getService()
MediaMetadataRetriever::MediaMetadataRetriever()
{
ALOGV("constructor");
- const sp<IMediaPlayerService>& service(getService());
+ const sp<IMediaPlayerService> service(getService());
if (service == 0) {
ALOGE("failed to obtain MediaMetadataRetrieverService");
return;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 3c6bef3..1057fc0 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -152,7 +152,7 @@ status_t MediaPlayer::setDataSource(
ALOGV("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
- const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
@@ -169,7 +169,7 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
status_t err = UNKNOWN_ERROR;
- const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
@@ -185,7 +185,7 @@ status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
{
ALOGV("setDataSource");
status_t err = UNKNOWN_ERROR;
- const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 8b7b171..144654c 100755
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -641,7 +641,7 @@ MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSourc
{
ALOGV("constructor");
- const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != NULL) {
mMediaRecorder = service->createMediaRecorder(opPackageName);
}