diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2016-12-12 15:01:24 +0100 |
commit | e15fd68c5dc4089690b5d3086776c3851e504bb7 (patch) | |
tree | 2c75274dee02b07463c9164efdf6888e1a9c75dc /media/libmedia | |
parent | 185e2110a53feb7720d91b6f8366ad27402f21cc (diff) | |
parent | 26c5fa31d17a638bf314de6e12e86bb8a86db44b (diff) | |
download | frameworks_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.mk | 1 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 9 | ||||
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 33 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 4 | ||||
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 54 | ||||
-rw-r--r-- | media/libmedia/IAudioPolicyServiceClient.cpp | 20 | ||||
-rw-r--r-- | media/libmedia/IDrm.cpp | 4 | ||||
-rw-r--r-- | media/libmedia/IMediaDeathNotifier.cpp | 2 | ||||
-rw-r--r-- | media/libmedia/IOMX.cpp | 143 | ||||
-rw-r--r-- | media/libmedia/MediaUtils.cpp | 74 | ||||
-rw-r--r-- | media/libmedia/MediaUtils.h | 35 | ||||
-rw-r--r-- | media/libmedia/mediametadataretriever.cpp | 4 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 6 | ||||
-rwxr-xr-x | media/libmedia/mediarecorder.cpp | 2 |
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> ¶ms, - 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> ¶ms, - 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); } |