From 3ba0bbe12904d0dfa2245fa3abf2b92034b15db3 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Mon, 8 Feb 2016 10:56:13 -0800 Subject: IOMX.cpp uninitialized pointer in BnOMX::onTransact This can lead to local code execution in media server. Fix initializes the pointer and checks the error conditions before returning Bug: 26403627 Change-Id: I7fa90682060148448dba01d6acbe3471d1ddb500 --- media/libmedia/IOMX.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 5423c2a..8f55eb9 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -446,7 +446,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; @@ -948,11 +948,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; } -- cgit v1.1 From 638e5bad20b9d05f0d10b5e216cf5860a18ffc70 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Mon, 8 Feb 2016 17:52:25 -0800 Subject: Fix info leak vulnerability of IDrm bug: 26323455 Change-Id: I25bb30d3666ab38d5150496375ed2f55ecb23ba8 --- media/libmedia/IDrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index b1ad0c5..7c709cd 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -658,7 +658,7 @@ status_t BnDrm::onTransact( Vector request; String8 defaultUrl; - DrmPlugin::KeyRequestType keyRequestType; + DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown; status_t result = getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters, request, defaultUrl, -- cgit v1.1 From 57bf4973b57dc62e7171c1cb2e0854f9e21fd3e4 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Mon, 8 Feb 2016 17:07:06 -0800 Subject: 3 uninitialized variables in IOMX.cpp Uninitialized MetadataBufferType pointer in case: SET_INPUT_SURFACE STORE_META_DATA_IN_BUFFERS CREATE_INPUT_SURFACE Fix: initialize them to kMetadataBufferTypeInvalid Bug: 26324358 Change-Id: Ib3bcac9bedc98bc65efa39f67cdbffbd90b374c9 --- media/libmedia/IOMX.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 8f55eb9..07f3697 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -844,9 +844,13 @@ status_t BnOMX::onTransact( OMX_U32 port_index = data.readInt32(); sp 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); @@ -886,9 +890,13 @@ status_t BnOMX::onTransact( sp bufferConsumer = interface_cast(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; @@ -914,8 +922,13 @@ status_t BnOMX::onTransact( 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); -- cgit v1.1 From 1f76ce4e2c13d0347523e8c9a27077c820715f08 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Fri, 19 Feb 2016 12:10:48 -0800 Subject: Fixing safteynet logging bug introduced in ag/862848 We moved the safteynet logging into storeMetaDataInBuffers_l Bug: 26324358 Change-Id: I2171742b53192ebb71d546bcb8970bb3c68f366f --- media/libmedia/IOMX.cpp | 4 ---- media/libstagefright/omx/OMXNodeInstance.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 07f3697..97b7ff0 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -925,10 +925,6 @@ status_t BnOMX::onTransact( 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); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 94a213a..8735eff 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -519,6 +519,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers( status_t OMXNodeInstance::storeMetaDataInBuffers_l( OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) { if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { + android_errorWriteLog(0x534e4554, "26324358"); return BAD_VALUE; } -- cgit v1.1 From 3a90a02bb6c4e8352112dbb9f2316935e4dd7315 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 22 Feb 2016 13:05:15 -0800 Subject: Clear allocation to avoid info leak Bug: 26914474 Change-Id: Ie1a86e86d78058d041149fe599a4996e7f8185cf --- media/libmedia/IOMX.cpp | 59 +++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 97b7ff0..865d575 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -692,34 +692,39 @@ 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 = NO_MEMORY; + void *params = calloc(size, 1); + if (params) { + err = data.read(params, size); + if (err != OK) { + android_errorWriteLog(0x534e4554, "26914474"); + } 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(); + } } - - default: - TRESPASS(); } reply->writeInt32(err); -- cgit v1.1 From 582c02ea5c9c8db5f993d784a0a85b275b2e59fd Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 23 Feb 2016 14:48:46 -0800 Subject: Also fix out of bounds access for normal read Previous fix accidentally only fixed the fragmented read case. Bug: 27208621 Change-Id: Ie16f1920b84c8aba613842659238fcd5925694ad --- media/libstagefright/MPEG4Extractor.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index e4f8384..f8789da 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -4228,7 +4228,15 @@ status_t MPEG4Source::read( continue; } - CHECK(dstOffset + 4 <= mBuffer->size()); + if (dstOffset > SIZE_MAX - 4 || + dstOffset + 4 > SIZE_MAX - nalLength || + dstOffset + 4 + nalLength > mBuffer->size()) { + ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); + android_errorWriteLog(0x534e4554, "27208621"); + mBuffer->release(); + mBuffer = NULL; + return ERROR_MALFORMED; + } dstData[dstOffset++] = 0; dstData[dstOffset++] = 0; -- cgit v1.1 From de2430fd7855b7941250e1c3744756ec9e699bd1 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 18 Feb 2016 08:25:47 -0800 Subject: Get service by value instead of reference to prevent a cleared service binder from being used. Bug: 26040840 Change-Id: Ifb5483c55b172d3553deb80dbe27f2204b86ecdb --- include/media/mediametadataretriever.h | 2 +- media/libmedia/mediametadataretriever.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index f655f35..8ed07ee 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -82,7 +82,7 @@ public: const char* extractMetadata(int keyCode); private: - static const sp& getService(); + static const sp getService(); class DeathNotifier: public IBinder::DeathRecipient { 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 MediaMetadataRetriever::sService; sp MediaMetadataRetriever::sDeathNotifier; -const sp& MediaMetadataRetriever::getService() +const sp MediaMetadataRetriever::getService() { Mutex::Autolock lock(sServiceLock); if (sService == 0) { @@ -62,7 +62,7 @@ const sp& MediaMetadataRetriever::getService() MediaMetadataRetriever::MediaMetadataRetriever() { ALOGV("constructor"); - const sp& service(getService()); + const sp service(getService()); if (service == 0) { ALOGE("failed to obtain MediaMetadataRetrieverService"); return; -- cgit v1.1 From 52fbd46e2b7bc185628e94178cc3ec8e2a340b40 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Mon, 8 Feb 2016 10:56:13 -0800 Subject: IOMX.cpp uninitialized pointer in BnOMX::onTransact This can lead to local code execution in media server. Fix initializes the pointer and checks the error conditions before returning Bug: 26403627 Change-Id: I7fa90682060148448dba01d6acbe3471d1ddb500 --- media/libmedia/IOMX.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 5423c2a..8f55eb9 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -446,7 +446,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; @@ -948,11 +948,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; } -- cgit v1.1 From 7227fe0eb793c3e9e313df7454862d360c9bd360 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Mon, 8 Feb 2016 17:52:25 -0800 Subject: Fix info leak vulnerability of IDrm bug: 26323455 Change-Id: I25bb30d3666ab38d5150496375ed2f55ecb23ba8 --- media/libmedia/IDrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index b1ad0c5..7c709cd 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -658,7 +658,7 @@ status_t BnDrm::onTransact( Vector request; String8 defaultUrl; - DrmPlugin::KeyRequestType keyRequestType; + DrmPlugin::KeyRequestType keyRequestType = DrmPlugin::kKeyRequestType_Unknown; status_t result = getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters, request, defaultUrl, -- cgit v1.1 From 1a5ab71d6a43a53535f37648b09d22b741265bb2 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Mon, 8 Feb 2016 17:07:06 -0800 Subject: 3 uninitialized variables in IOMX.cpp Uninitialized MetadataBufferType pointer in case: SET_INPUT_SURFACE STORE_META_DATA_IN_BUFFERS CREATE_INPUT_SURFACE Fix: initialize them to kMetadataBufferTypeInvalid Bug: 26324358 Change-Id: Ib3bcac9bedc98bc65efa39f67cdbffbd90b374c9 --- media/libmedia/IOMX.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 8f55eb9..07f3697 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -844,9 +844,13 @@ status_t BnOMX::onTransact( OMX_U32 port_index = data.readInt32(); sp 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); @@ -886,9 +890,13 @@ status_t BnOMX::onTransact( sp bufferConsumer = interface_cast(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; @@ -914,8 +922,13 @@ status_t BnOMX::onTransact( 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); -- cgit v1.1 From a685aea781026471ad82f5729198c60bcb4f8fe9 Mon Sep 17 00:00:00 2001 From: "mspector@google.com" Date: Fri, 19 Feb 2016 12:10:48 -0800 Subject: Fixing safteynet logging bug introduced in ag/862848 We moved the safteynet logging into storeMetaDataInBuffers_l Bug: 26324358 Change-Id: I2171742b53192ebb71d546bcb8970bb3c68f366f --- media/libmedia/IOMX.cpp | 4 ---- media/libstagefright/omx/OMXNodeInstance.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 07f3697..97b7ff0 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -925,10 +925,6 @@ status_t BnOMX::onTransact( 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); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 94a213a..8735eff 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -519,6 +519,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers( status_t OMXNodeInstance::storeMetaDataInBuffers_l( OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) { if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { + android_errorWriteLog(0x534e4554, "26324358"); return BAD_VALUE; } -- cgit v1.1 From d3e5eca42feaa337cd3aa36b7eaa2b7aadbbab15 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 22 Feb 2016 13:05:15 -0800 Subject: Clear allocation to avoid info leak Bug: 26914474 Change-Id: Ie1a86e86d78058d041149fe599a4996e7f8185cf --- media/libmedia/IOMX.cpp | 59 +++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 97b7ff0..865d575 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -692,34 +692,39 @@ 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 = NO_MEMORY; + void *params = calloc(size, 1); + if (params) { + err = data.read(params, size); + if (err != OK) { + android_errorWriteLog(0x534e4554, "26914474"); + } 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(); + } } - - default: - TRESPASS(); } reply->writeInt32(err); -- cgit v1.1 From b7c8681b7f3c093b1c0f667007c490d9c563655c Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 23 Feb 2016 14:48:46 -0800 Subject: Also fix out of bounds access for normal read Previous fix accidentally only fixed the fragmented read case. Bug: 27208621 Change-Id: Ie16f1920b84c8aba613842659238fcd5925694ad --- media/libstagefright/MPEG4Extractor.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index e4f8384..f8789da 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -4228,7 +4228,15 @@ status_t MPEG4Source::read( continue; } - CHECK(dstOffset + 4 <= mBuffer->size()); + if (dstOffset > SIZE_MAX - 4 || + dstOffset + 4 > SIZE_MAX - nalLength || + dstOffset + 4 + nalLength > mBuffer->size()) { + ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size()); + android_errorWriteLog(0x534e4554, "27208621"); + mBuffer->release(); + mBuffer = NULL; + return ERROR_MALFORMED; + } dstData[dstOffset++] = 0; dstData[dstOffset++] = 0; -- cgit v1.1 From 5db73079cbd9bbe5bf2c6fb7d029537a085170ca Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 18 Feb 2016 08:25:47 -0800 Subject: Get service by value instead of reference to prevent a cleared service binder from being used. Bug: 26040840 Change-Id: Ifb5483c55b172d3553deb80dbe27f2204b86ecdb --- include/media/mediametadataretriever.h | 2 +- media/libmedia/mediametadataretriever.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index f655f35..8ed07ee 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -82,7 +82,7 @@ public: const char* extractMetadata(int keyCode); private: - static const sp& getService(); + static const sp getService(); class DeathNotifier: public IBinder::DeathRecipient { 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 MediaMetadataRetriever::sService; sp MediaMetadataRetriever::sDeathNotifier; -const sp& MediaMetadataRetriever::getService() +const sp MediaMetadataRetriever::getService() { Mutex::Autolock lock(sServiceLock); if (sService == 0) { @@ -62,7 +62,7 @@ const sp& MediaMetadataRetriever::getService() MediaMetadataRetriever::MediaMetadataRetriever() { ALOGV("constructor"); - const sp& service(getService()); + const sp service(getService()); if (service == 0) { ALOGE("failed to obtain MediaMetadataRetrieverService"); return; -- cgit v1.1 From 811391b5e9634116b88abfdcb262986e778aa436 Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Tue, 22 Mar 2016 08:52:48 -0700 Subject: Revert "Fixed comparison on 64 bit system" AOSP has a different fix. This reverts commit 65890a73d53a25b0809b22e41cdee19e3f4aa68d. Change-Id: I88fc05c791b9d5cef181e94d1cd3c40f0076f827 --- media/libstagefright/SampleTable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index ee5def5..93cf055 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -246,7 +246,7 @@ status_t SampleTable::setSampleToChunkParams( for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; - if ((off64_t)(INT64_MAX - 8 - (i * 12)) < mSampleToChunkOffset) { + if ((off64_t)(SIZE_MAX - 8 - (i * 12)) < mSampleToChunkOffset) { return ERROR_MALFORMED; } -- cgit v1.1 From f97015ad37e8386a4215e2d25a4196edef5f7c8d Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 21 Mar 2016 09:29:06 -0700 Subject: Fix 64-bit comparison A 64-bit SIZE_MAX value cast to off64_t is always negative, causing valid files to be rejected in 64-bit mode. Change-Id: I8f61c19951f9c73292fa917081b8b2f3bfc405a0 --- media/libstagefright/SampleTable.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 93cf055..2f69fd8 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -209,6 +209,11 @@ status_t SampleTable::setChunkOffsetParams( status_t SampleTable::setSampleToChunkParams( off64_t data_offset, size_t data_size) { if (mSampleToChunkOffset >= 0) { + // already set + return ERROR_MALFORMED; + } + + if (data_offset < 0) { return ERROR_MALFORMED; } @@ -246,7 +251,7 @@ status_t SampleTable::setSampleToChunkParams( for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; - if ((off64_t)(SIZE_MAX - 8 - (i * 12)) < mSampleToChunkOffset) { + if ((SIZE_MAX - 8 - (i * 12)) < (size_t)mSampleToChunkOffset) { return ERROR_MALFORMED; } -- cgit v1.1 From d954486023aea49be22b53495166f40a028fdb67 Mon Sep 17 00:00:00 2001 From: "tao.pei" Date: Fri, 17 Jul 2015 17:18:41 +0800 Subject: Use errno correctly. After a failed write() or ioctl(), errno wasn't being checked until after some other function calls that could also modify errno, thus checking the wrong errno. Make sure to check it prior to doing anything else that can modify it. [Preconditions] 1.PC connects with phone(mtp). [Procedures] 1.Copy a file from PC to phone. 2.Cancel the copying. 3.Recopy the file. Change-Id: Id772fca7ccb96d3f43bd4beb210bedd8d3ac17fa --- media/mtp/MtpServer.cpp | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 6a334e6..3c91ffd 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -215,10 +215,11 @@ void MtpServer::run() { mResponse.setTransactionID(transaction); ALOGV("sending response %04X", mResponse.getResponseCode()); ret = mResponse.write(fd); + const int savedErrno = errno; mResponse.dump(); if (ret < 0) { ALOGE("request write returned %d, errno: %d", ret, errno); - if (errno == ECANCELED) { + if (savedErrno == ECANCELED) { // return to top of loop and wait for next command continue; } @@ -793,15 +794,19 @@ MtpResponseCode MtpServer::doGetObject() { // then transfer the file int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr); - ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret); - close(mfr.fd); if (ret < 0) { - if (errno == ECANCELED) - return MTP_RESPONSE_TRANSACTION_CANCELLED; - else - return MTP_RESPONSE_GENERAL_ERROR; + if (errno == ECANCELED) { + result = MTP_RESPONSE_TRANSACTION_CANCELLED; + } else { + result = MTP_RESPONSE_GENERAL_ERROR; + } + } else { + result = MTP_RESPONSE_OK; } - return MTP_RESPONSE_OK; + + ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret); + close(mfr.fd); + return result; } MtpResponseCode MtpServer::doGetThumb() { @@ -870,14 +875,15 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) { // transfer the file int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr); ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret); - close(mfr.fd); + result = MTP_RESPONSE_OK; if (ret < 0) { if (errno == ECANCELED) - return MTP_RESPONSE_TRANSACTION_CANCELLED; + result = MTP_RESPONSE_TRANSACTION_CANCELLED; else - return MTP_RESPONSE_GENERAL_ERROR; + result = MTP_RESPONSE_GENERAL_ERROR; } - return MTP_RESPONSE_OK; + close(mfr.fd); + return result; } MtpResponseCode MtpServer::doSendObjectInfo() { @@ -991,6 +997,7 @@ MtpResponseCode MtpServer::doSendObject() { MtpResponseCode result = MTP_RESPONSE_OK; mode_t mask; int ret, initialData; + bool isCanceled = false; if (mSendObjectHandle == kInvalidObjectHandle) { ALOGE("Expected SendObjectInfo before SendObject"); @@ -1038,6 +1045,10 @@ MtpResponseCode MtpServer::doSendObject() { ALOGV("receiving %s\n", (const char *)mSendObjectFilePath); // transfer the file ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); + if ((ret < 0) && (errno == ECANCELED)) { + isCanceled = true; + } + ALOGV("MTP_RECEIVE_FILE returned %d\n", ret); } } @@ -1045,7 +1056,7 @@ MtpResponseCode MtpServer::doSendObject() { if (ret < 0) { unlink(mSendObjectFilePath); - if (errno == ECANCELED) + if (isCanceled) result = MTP_RESPONSE_TRANSACTION_CANCELLED; else result = MTP_RESPONSE_GENERAL_ERROR; @@ -1214,6 +1225,7 @@ MtpResponseCode MtpServer::doSendPartialObject() { length -= initialData; } + bool isCanceled = false; if (ret < 0) { ALOGE("failed to write initial data"); } else { @@ -1225,12 +1237,15 @@ MtpResponseCode MtpServer::doSendPartialObject() { // transfer the file ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); + if ((ret < 0) && (errno == ECANCELED)) { + isCanceled = true; + } ALOGV("MTP_RECEIVE_FILE returned %d", ret); } } if (ret < 0) { mResponse.setParameter(1, 0); - if (errno == ECANCELED) + if (isCanceled) return MTP_RESPONSE_TRANSACTION_CANCELLED; else return MTP_RESPONSE_GENERAL_ERROR; -- cgit v1.1 From c27fc358c91ed67965243294387dfb5ce7cd7fbf Mon Sep 17 00:00:00 2001 From: "Joshua J. Drake" Date: Thu, 9 Apr 2015 00:46:42 -0500 Subject: MPEG4Extractor: still more NULL dereference fixes When processing various FourCC values within MP4 media, mLastTrack is accessed without first ensuring that a track has been encoutered. Check for NULL and bail out instead of crashing. Bug: 20139950 Change-Id: Ie16687024d17348f576a0e13bd60bd4d6898de91 --- media/libstagefright/MPEG4Extractor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index c7c238e..2d2e8fb 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1980,6 +1980,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_IO; } + if (mLastTrack == NULL) + return ERROR_MALFORMED; + uint32_t type = ntohl(buffer); // For the 3GPP file format, the handler-type within the 'hdlr' box // shall be 'text'. We also want to support 'sbtl' handler type -- cgit v1.1 From c727e175576bcc74d47f5390c34542d5c2ebafc6 Mon Sep 17 00:00:00 2001 From: Ashok Bhat Date: Tue, 3 Jun 2014 12:48:51 +0100 Subject: h264dec: Use intptr_t when a pointer is treated as an integer Change-Id: I83057565a842da31ee137fac674af496c1fc18af Signed-off-by: Ashok Bhat --- .../libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h | 6 +++--- .../libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h index 91e38b8..1992885 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h @@ -86,7 +86,7 @@ typedef OMX_S16 ARM_BLOCK8x8[64]; /* Alignment operation */ -#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) )) +#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(intptr_t)Ptr)&(N-1)) / sizeof(*Ptr) )) #define armAlignTo2Bytes(Ptr) armAlignToBytes(Ptr,2) #define armAlignTo4Bytes(Ptr) armAlignToBytes(Ptr,4) #define armAlignTo8Bytes(Ptr) armAlignToBytes(Ptr,8) @@ -98,8 +98,8 @@ typedef OMX_S16 ARM_BLOCK8x8[64]; #define armRetDataErrIf(condition, code) if(condition) { return (code); } #ifndef ALIGNMENT_DOESNT_MATTER -#define armIsByteAligned(Ptr,N) ((((int)(Ptr)) % N)==0) -#define armNotByteAligned(Ptr,N) ((((int)(Ptr)) % N)!=0) +#define armIsByteAligned(Ptr,N) ((((intptr_t)(Ptr)) % N)==0) +#define armNotByteAligned(Ptr,N) ((((intptr_t)(Ptr)) % N)!=0) #else #define armIsByteAligned(Ptr,N) (1) #define armNotByteAligned(Ptr,N) (0) diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h index fbb97e2..7304863 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h @@ -86,7 +86,7 @@ typedef OMX_S16 ARM_BLOCK8x8[64]; /* Alignment operation */ -#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) )) +#define armAlignToBytes(Ptr,N) (Ptr + ( ((N-(intptr_t)Ptr)&(N-1)) / sizeof(*Ptr) )) #define armAlignTo2Bytes(Ptr) armAlignToBytes(Ptr,2) #define armAlignTo4Bytes(Ptr) armAlignToBytes(Ptr,4) #define armAlignTo8Bytes(Ptr) armAlignToBytes(Ptr,8) @@ -98,8 +98,8 @@ typedef OMX_S16 ARM_BLOCK8x8[64]; #define armRetDataErrIf(condition, code) if(condition) { return (code); } #ifndef ALIGNMENT_DOESNT_MATTER -#define armIsByteAligned(Ptr,N) ((((int)(Ptr)) % N)==0) -#define armNotByteAligned(Ptr,N) ((((int)(Ptr)) % N)!=0) +#define armIsByteAligned(Ptr,N) ((((intptr_t)(Ptr)) % N)==0) +#define armNotByteAligned(Ptr,N) ((((intptr_t)(Ptr)) % N)!=0) #else #define armIsByteAligned(Ptr,N) (1) #define armNotByteAligned(Ptr,N) (0) -- cgit v1.1 From 429372d0c568768eb754e827cc63c2a486ced050 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 29 Jul 2015 16:46:25 -0700 Subject: Stagefright: Remove unused variables and files For build-system CFLAGS clean-up. Bug: 18632512 (cherry picked from commit 765b4172f1ffb2c4e2de89163bb888fa352de664) Change-Id: I765dc394f39f60801843851760fdf9838958d7a4 --- .../libstagefright/codecs/amrnb/common/Android.mk | 2 - .../codecs/amrnb/common/include/bytesused.h | 109 ----------- .../codecs/amrnb/common/src/bytesused.cpp | 208 --------------------- .../codecs/amrnb/common/src/overflow_tbl.cpp | 174 ----------------- .../codecs/avc/enc/src/findhalfpel.cpp | 13 -- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 4 - 6 files changed, 510 deletions(-) delete mode 100644 media/libstagefright/codecs/amrnb/common/include/bytesused.h delete mode 100644 media/libstagefright/codecs/amrnb/common/src/bytesused.cpp delete mode 100644 media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp diff --git a/media/libstagefright/codecs/amrnb/common/Android.mk b/media/libstagefright/codecs/amrnb/common/Android.mk index 5e632a6..80b67bb 100644 --- a/media/libstagefright/codecs/amrnb/common/Android.mk +++ b/media/libstagefright/codecs/amrnb/common/Android.mk @@ -7,7 +7,6 @@ LOCAL_SRC_FILES := \ src/bitno_tab.cpp \ src/bitreorder_tab.cpp \ src/bits2prm.cpp \ - src/bytesused.cpp \ src/c2_9pf_tab.cpp \ src/copy.cpp \ src/div_32.cpp \ @@ -38,7 +37,6 @@ LOCAL_SRC_FILES := \ src/mult_r.cpp \ src/norm_l.cpp \ src/norm_s.cpp \ - src/overflow_tbl.cpp \ src/ph_disp_tab.cpp \ src/pow2.cpp \ src/pow2_tbl.cpp \ diff --git a/media/libstagefright/codecs/amrnb/common/include/bytesused.h b/media/libstagefright/codecs/amrnb/common/include/bytesused.h deleted file mode 100644 index 934efbe..0000000 --- a/media/libstagefright/codecs/amrnb/common/include/bytesused.h +++ /dev/null @@ -1,109 +0,0 @@ -/* ------------------------------------------------------------------ - * Copyright (C) 1998-2009 PacketVideo - * - * 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. - * ------------------------------------------------------------------- - */ -/**************************************************************************************** -Portions of this file are derived from the following 3GPP standard: - - 3GPP TS 26.073 - ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec - Available from http://www.3gpp.org - -(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) -Permission to distribute, modify and use this file under the standard license -terms listed above has been obtained from the copyright holder. -****************************************************************************************/ -/* - - Pathname: .audio/gsm-amr/c/include/BytesUsed.h - ------------------------------------------------------------------------------- - REVISION HISTORY - - Description: Added #ifdef __cplusplus after Include section. - - Who: Date: - Description: - ------------------------------------------------------------------------------- - INCLUDE DESCRIPTION - - This file declares a table BytesUsed. - ------------------------------------------------------------------------------- -*/ - -/*---------------------------------------------------------------------------- -; CONTINUE ONLY IF NOT ALREADY DEFINED -----------------------------------------------------------------------------*/ -#ifndef BYTESUSED_H -#define BYTESUSED_H - -/*---------------------------------------------------------------------------- -; INCLUDES -----------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" -{ -#endif - - /*---------------------------------------------------------------------------- - ; MACROS - ; Define module specific macros here - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; DEFINES - ; Include all pre-processor statements here. - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; EXTERNAL VARIABLES REFERENCES - ; Declare variables used in this module but defined elsewhere - ----------------------------------------------------------------------------*/ - extern const short BytesUsed[]; - - /*---------------------------------------------------------------------------- - ; SIMPLE TYPEDEF'S - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; ENUMERATED TYPEDEF'S - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; STRUCTURES TYPEDEF'S - ----------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------------- - ; GLOBAL FUNCTION DEFINITIONS - ; Function Prototype declaration - ----------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------------- - ; END - ----------------------------------------------------------------------------*/ -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp deleted file mode 100644 index b61bac4..0000000 --- a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* ------------------------------------------------------------------ - * Copyright (C) 1998-2009 PacketVideo - * - * 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. - * ------------------------------------------------------------------- - */ -/**************************************************************************************** -Portions of this file are derived from the following 3GPP standard: - - 3GPP TS 26.073 - ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec - Available from http://www.3gpp.org - -(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) -Permission to distribute, modify and use this file under the standard license -terms listed above has been obtained from the copyright holder. -****************************************************************************************/ -/* - - Pathname: ./audio/gsm-amr/c/src/BytesUsed.c - ------------------------------------------------------------------------------- - REVISION HISTORY - - Description: Corrected entries for all SID frames and updated function - description. Updated copyright year. - - Description: Added #ifdef __cplusplus and removed "extern" from table - definition. Removed corresponding header file from Include - section. - - Description: Put "extern" back. - - Who: Date: - Description: - ------------------------------------------------------------------------------- - INPUT AND OUTPUT DEFINITIONS - - Inputs: - None - - Local Stores/Buffers/Pointers Needed: - None - - Global Stores/Buffers/Pointers Needed: - None - - Outputs: - None - - Pointers and Buffers Modified: - None - - Local Stores Modified: - None - - Global Stores Modified: - None - ------------------------------------------------------------------------------- - FUNCTION DESCRIPTION - - This function creates a table called BytesUsed that holds the value that - describes the number of bytes required to hold one frame worth of data in - the WMF (non-IF2) frame format. Each table entry is the sum of the frame - type byte and the number of bytes used up by the core speech data for each - 3GPP frame type. - ------------------------------------------------------------------------------- - REQUIREMENTS - - None - ------------------------------------------------------------------------------- - REFERENCES - - [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 - Release 4, June 2001, page 13. - ------------------------------------------------------------------------------- - PSEUDO-CODE - - ------------------------------------------------------------------------------- - RESOURCES USED - When the code is written for a specific target processor the - the resources used should be documented below. - - STACK USAGE: [stack count for this module] + [variable to represent - stack usage for each subroutine called] - - where: [stack usage variable] = stack usage for [subroutine - name] (see [filename].ext) - - DATA MEMORY USED: x words - - PROGRAM MEMORY USED: x words - - CLOCK CYCLES: [cycle count equation for this module] + [variable - used to represent cycle count for each subroutine - called] - - where: [cycle count variable] = cycle count for [subroutine - name] (see [filename].ext) - ------------------------------------------------------------------------------- -*/ - - -/*---------------------------------------------------------------------------- -; INCLUDES -----------------------------------------------------------------------------*/ -#include "typedef.h" - -/*--------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" -{ -#endif - - /*---------------------------------------------------------------------------- - ; MACROS - ; Define module specific macros here - ----------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------------- - ; DEFINES - ; Include all pre-processor statements here. Include conditional - ; compile variables also. - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; LOCAL FUNCTION DEFINITIONS - ; Function Prototype declaration - ----------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------------- - ; LOCAL STORE/BUFFER/POINTER DEFINITIONS - ; Variable declaration - defined here and used outside this module - ----------------------------------------------------------------------------*/ - const short BytesUsed[16] = - { - 13, /* 4.75 */ - 14, /* 5.15 */ - 16, /* 5.90 */ - 18, /* 6.70 */ - 20, /* 7.40 */ - 21, /* 7.95 */ - 27, /* 10.2 */ - 32, /* 12.2 */ - 6, /* GsmAmr comfort noise */ - 7, /* Gsm-Efr comfort noise */ - 6, /* IS-641 comfort noise */ - 6, /* Pdc-Efr comfort noise */ - 0, /* future use */ - 0, /* future use */ - 0, /* future use */ - 1 /* No transmission */ - }; - /*---------------------------------------------------------------------------- - ; EXTERNAL FUNCTION REFERENCES - ; Declare functions defined elsewhere and referenced in this module - ----------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------------- - ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES - ; Declare variables used in this module but defined elsewhere - ----------------------------------------------------------------------------*/ - - - /*--------------------------------------------------------------------------*/ -#ifdef __cplusplus -} -#endif - -/*---------------------------------------------------------------------------- -; FUNCTION CODE -----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -; Define all local variables -----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- -; Function body here -----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- -; Return nothing or data or data pointer -----------------------------------------------------------------------------*/ - diff --git a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp deleted file mode 100644 index c4a016d..0000000 --- a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* ------------------------------------------------------------------ - * Copyright (C) 1998-2009 PacketVideo - * - * 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. - * ------------------------------------------------------------------- - */ -/**************************************************************************************** -Portions of this file are derived from the following 3GPP standard: - - 3GPP TS 26.073 - ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec - Available from http://www.3gpp.org - -(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) -Permission to distribute, modify and use this file under the standard license -terms listed above has been obtained from the copyright holder. -****************************************************************************************/ -/* - - Filename: /audio/gsm_amr/c/src/overflow_tbl.c - ------------------------------------------------------------------------------- - REVISION HISTORY - - Description: Added #ifdef __cplusplus and removed "extern" from table - definition. - - Description: Put "extern" back. - - Who: Date: - Description: - ------------------------------------------------------------------------------- - MODULE DESCRIPTION - - This file contains the declaration for overflow_tbl[] used by the l_shl() - and l_shr() functions. - ------------------------------------------------------------------------------- -*/ - -/*---------------------------------------------------------------------------- -; INCLUDES -----------------------------------------------------------------------------*/ -#include "typedef.h" - -/*--------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" -{ -#endif - - /*---------------------------------------------------------------------------- - ; MACROS - ; [Define module specific macros here] - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; DEFINES - ; [Include all pre-processor statements here. Include conditional - ; compile variables also.] - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; LOCAL FUNCTION DEFINITIONS - ; [List function prototypes here] - ----------------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------------- - ; LOCAL VARIABLE DEFINITIONS - ; [Variable declaration - defined here and used outside this module] - ----------------------------------------------------------------------------*/ - const Word32 overflow_tbl [32] = {0x7fffffffL, 0x3fffffffL, - 0x1fffffffL, 0x0fffffffL, - 0x07ffffffL, 0x03ffffffL, - 0x01ffffffL, 0x00ffffffL, - 0x007fffffL, 0x003fffffL, - 0x001fffffL, 0x000fffffL, - 0x0007ffffL, 0x0003ffffL, - 0x0001ffffL, 0x0000ffffL, - 0x00007fffL, 0x00003fffL, - 0x00001fffL, 0x00000fffL, - 0x000007ffL, 0x000003ffL, - 0x000001ffL, 0x000000ffL, - 0x0000007fL, 0x0000003fL, - 0x0000001fL, 0x0000000fL, - 0x00000007L, 0x00000003L, - 0x00000001L, 0x00000000L - }; - - /*--------------------------------------------------------------------------*/ -#ifdef __cplusplus -} -#endif - -/* ------------------------------------------------------------------------------- - FUNCTION NAME: ------------------------------------------------------------------------------- - INPUT AND OUTPUT DEFINITIONS - - Inputs: - None - - Outputs: - None - - Returns: - None - - Global Variables Used: - None - - Local Variables Needed: - None - ------------------------------------------------------------------------------- - FUNCTION DESCRIPTION - - None - ------------------------------------------------------------------------------- - REQUIREMENTS - - None - ------------------------------------------------------------------------------- - REFERENCES - - [1] l_shl() function in basic_op2.c, UMTS GSM AMR speech codec, R99 - - Version 3.2.0, March 2, 2001 - ------------------------------------------------------------------------------- - PSEUDO-CODE - - ------------------------------------------------------------------------------- - RESOURCES USED [optional] - - When the code is written for a specific target processor the - the resources used should be documented below. - - HEAP MEMORY USED: x bytes - - STACK MEMORY USED: x bytes - - CLOCK CYCLES: (cycle count equation for this function) + (variable - used to represent cycle count for each subroutine - called) - where: (cycle count variable) = cycle count for [subroutine - name] - ------------------------------------------------------------------------------- - CAUTION [optional] - [State any special notes, constraints or cautions for users of this function] - ------------------------------------------------------------------------------- -*/ - -/*---------------------------------------------------------------------------- -; FUNCTION CODE -----------------------------------------------------------------------------*/ - diff --git a/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp b/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp index 0b8d9e2..d0bbee2 100644 --- a/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp +++ b/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp @@ -23,19 +23,6 @@ #define PREF_16_VEC 129 /* 1MV bias versus 4MVs*/ -const static int distance_tab[9][9] = /* [hp_guess][k] */ -{ - {0, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 0, 1, 2, 3, 4, 3, 2, 1}, - {1, 0, 0, 0, 1, 2, 3, 2, 1}, - {1, 2, 1, 0, 1, 2, 3, 4, 3}, - {1, 2, 1, 0, 0, 0, 1, 2, 3}, - {1, 4, 3, 2, 1, 0, 1, 2, 3}, - {1, 2, 3, 2, 1, 0, 0, 0, 1}, - {1, 2, 3, 4, 3, 2, 1, 0, 1}, - {1, 0, 1, 2, 3, 2, 1, 0, 0} -}; - #define CLIP_RESULT(x) if((uint)x > 0xFF){ \ x = 0xFF & (~(x>>31));} diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index e161fb8..cd6c3b1 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -102,7 +102,6 @@ status_t SoftVPX::destroyDecoder() { } bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset) { - List &inQueue = getPortQueue(0); List &outQueue = getPortQueue(1); BufferInfo *outInfo = NULL; OMX_BUFFERHEADERTYPE *outHeader = NULL; @@ -193,7 +192,6 @@ void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) { List &inQueue = getPortQueue(0); List &outQueue = getPortQueue(1); bool EOSseen = false; - vpx_codec_err_t err; bool portWillReset = false; while ((mEOSStatus == INPUT_EOS_SEEN || !inQueue.empty()) @@ -217,8 +215,6 @@ void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) { OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp; - BufferInfo *outInfo = *outQueue.begin(); - OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { mEOSStatus = INPUT_EOS_SEEN; EOSseen = true; -- cgit v1.1 From 985e33c71917a8c7f3cc5bbb2bd0d1feb188c258 Mon Sep 17 00:00:00 2001 From: "Joshua J. Drake" Date: Sat, 15 Aug 2015 08:31:32 -0500 Subject: Prevent integer underflows in ID3::Iterator If mFrameSize is less than or equal to getHeaderLength(), an integer underflow will occur. This typically leads to a crash reading out of bounds in the following code. Prevent this from happening by validating mFrameSize. Also add NULL checks after references to ID3::Iterator::getData. Bug: 23285887 Change-Id: I35eeda3c5349ebbd9ffb3ea49b79af6a940d1395 --- media/libstagefright/httplive/PlaylistFetcher.cpp | 3 +++ media/libstagefright/id3/ID3.cpp | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index 52be368..b030e90 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -1911,6 +1911,9 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( while (!it.done()) { size_t length; const uint8_t *data = it.getData(&length); + if (!data) { + return ERROR_MALFORMED; + } static const char *kMatchName = "com.apple.streaming.transportStreamTimestamp"; diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 76d65f0..4f4248c 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -619,6 +619,11 @@ const uint8_t *ID3::Iterator::getData(size_t *length) const { return NULL; } + // Prevent integer underflow + if (mFrameSize < getHeaderLength()) { + return NULL; + } + *length = mFrameSize - getHeaderLength(); return mFrameData; @@ -833,6 +838,9 @@ ID3::getAlbumArt(size_t *length, String8 *mime) const { while (!it.done()) { size_t size; const uint8_t *data = it.getData(&size); + if (!data) { + return NULL; + } if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { uint8_t encoding = data[0]; -- cgit v1.1 From 92742eb7af414d5818fd09fafddb6d6f79c0d9a9 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 20 Aug 2015 15:29:05 -0700 Subject: OMXCodec: fix potential OOB read in parseHEVCCodecSpecificData Bug: 23279597 Change-Id: Ibaa3d52e586e65230ec6df3680d9456ce873390c --- media/libstagefright/OMXCodec.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index abe19a0..7f97039 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -399,7 +399,7 @@ status_t OMXCodec::parseHEVCCodecSpecificData( const uint8_t *ptr = (const uint8_t *)data; // verify minimum size and configurationVersion == 1. - if (size < 7 || ptr[0] != 1) { + if (size < 23 || ptr[0] != 1) { return ERROR_MALFORMED; } @@ -414,6 +414,9 @@ status_t OMXCodec::parseHEVCCodecSpecificData( size -= 1; size_t j = 0, i = 0; for (i = 0; i < numofArrays; i++) { + if (size < 3) { + return ERROR_MALFORMED; + } ptr += 1; size -= 1; -- cgit v1.1 From 4e35e8fa2a6c3d06a1de0add38ee8e994fcf2d42 Mon Sep 17 00:00:00 2001 From: "Joshua J. Drake" Date: Sat, 15 Aug 2015 07:43:39 -0500 Subject: Prevent divide by zero in WAVExtractor In the case that mNumChannels, bytesPerSample, or mSampleRate are zero, a divide by zero occurs. None of these parameters of a WAV file should ever be zero. Check that they aren't and return an error otherwise. Bug: 23285883 Change-Id: Id67b8620944405ca59572221f6f1c2b19c363e69 --- media/libstagefright/WAVExtractor.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp index cc1d7ce..62bb416 100644 --- a/media/libstagefright/WAVExtractor.cpp +++ b/media/libstagefright/WAVExtractor.cpp @@ -315,9 +315,17 @@ status_t WAVExtractor::init() { 1000000LL * (mDataSize / 65 * 320) / 8000; } else { size_t bytesPerSample = mBitsPerSample >> 3; + + if (!bytesPerSample || !mNumChannels) + return ERROR_MALFORMED; + + size_t num_samples = mDataSize / (mNumChannels * bytesPerSample); + + if (!mSampleRate) + return ERROR_MALFORMED; + durationUs = - 1000000LL * (mDataSize / (mNumChannels * bytesPerSample)) - / mSampleRate; + 1000000LL * num_samples / mSampleRate; } mTrackMeta->setInt64(kKeyDuration, durationUs); -- cgit v1.1 From b821ad110a85fa27f84e732ecbf7322319ec4db9 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 17 Sep 2015 15:48:37 -0700 Subject: Fix integer overflow in time conversion Converting unix epoch time to mpeg4 time requires adding over 2B seconds, which caused an overflow in a calculation involving time_t, which is signed. Bug: 23574783 Change-Id: I21bacc9f5a422091f3c903fb8cf1c760fc078953 --- media/libstagefright/MPEG4Writer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 2f1b6ac..f5e0fbf 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -1023,7 +1023,11 @@ uint32_t MPEG4Writer::getMpeg4Time() { // MP4 file uses time counting seconds since midnight, Jan. 1, 1904 // while time function returns Unix epoch values which starts // at 1970-01-01. Lets add the number of seconds between them - uint32_t mpeg4Time = now + (66 * 365 + 17) * (24 * 60 * 60); + static const uint32_t delta = (66 * 365 + 17) * (24 * 60 * 60); + if (now < 0 || uint32_t(now) > UINT32_MAX - delta) { + return 0; + } + uint32_t mpeg4Time = uint32_t(now) + delta; return mpeg4Time; } -- cgit v1.1 From 37c5d30af6797192de58586ab4ef64b2fcdc7ae9 Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Fri, 31 Jul 2015 16:03:44 -0700 Subject: Fix harmless unsigned overflow in recoverPTS Change-Id: I89e3a827cf566421e8dd9b6a3c842e73a19c140f --- media/libstagefright/mpeg2ts/ATSParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index e3c3e80..f9a9c4c 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -509,7 +509,7 @@ int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) { mLastRecoveredPTS = static_cast(PTS_33bit); } else { mLastRecoveredPTS = static_cast( - ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll) + ((mLastRecoveredPTS - static_cast(PTS_33bit) + 0x100000000ll) & 0xfffffffe00000000ull) | PTS_33bit); // We start from 0, but recovered PTS could be slightly below 0. // Clamp it to 0 as rest of the pipeline doesn't take negative pts. -- cgit v1.1 From 3df4facd824693020ec412cd4afcc8e469e31bb7 Mon Sep 17 00:00:00 2001 From: Dan Austin Date: Thu, 15 Oct 2015 13:06:41 -0700 Subject: Fix benign integer overflow conditions for VSYNC add and removal. There are integer overflow conditions that could occur on vsyncsForLastFrame in VideoFrameScheduler::schedule upon a VSYNC add or removal. Additional checks have been put in place to remove the overflowable conditions. Bug: 24980200 Change-Id: I7dfc25ae1d2f3e3b3382e990adb3c56518c64e8d --- media/libstagefright/VideoFrameScheduler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp index 02b8783..c17faf3 100644 --- a/media/libstagefright/VideoFrameScheduler.cpp +++ b/media/libstagefright/VideoFrameScheduler.cpp @@ -459,14 +459,16 @@ nsecs_t VideoFrameScheduler::schedule(nsecs_t renderTime) { mTimeCorrection -= mVsyncPeriod / 2; renderTime -= mVsyncPeriod / 2; nextVsyncTime -= mVsyncPeriod; - --vsyncsForLastFrame; + if (vsyncsForLastFrame > 0) + --vsyncsForLastFrame; } else if (mTimeCorrection < -correctionLimit && (vsyncsPerFrameAreNearlyConstant || vsyncsForLastFrame == minVsyncsPerFrame)) { // add a VSYNC mTimeCorrection += mVsyncPeriod / 2; renderTime += mVsyncPeriod / 2; nextVsyncTime += mVsyncPeriod; - ++vsyncsForLastFrame; + if (vsyncsForLastFrame < ULONG_MAX) + ++vsyncsForLastFrame; } ATRACE_INT("FRAME_VSYNCS", vsyncsForLastFrame); } -- cgit v1.1 From d7a4d6dcb9a82eb5daad7ab897a1be5357ce19c3 Mon Sep 17 00:00:00 2001 From: "Wang, Jianfeng XA" Date: Tue, 27 May 2014 17:48:08 +0900 Subject: libcameraservice: Allow media server to disconnect camera even unlocked The camera service may fail to release the camera hardware instance in some use cases. When an application unlocked the camera before disconnect, disconnect from the application will not be accepted. And disconnect from media server will not be accepted also. Then, the camera hardware instance will not be released and a resource leak will be caused. Allow media server to disconnect the camera at all times even if the camera is unlocked. Change-Id: Icd5ed81bed242fa5947aa40ca85e4ca7fa7286e7 --- services/camera/libcameraservice/api1/CameraClient.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 55555fd..735a4ae 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -243,11 +243,6 @@ void CameraClient::disconnect() { return; } - if (mClientPid <= 0) { - LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); - return; - } - // Make sure disconnect() is done once and once only, whether it is called // from the user directly, or called by the destructor. if (mHardware == 0) return; -- cgit v1.1 From 4b17bd19e9eceade55dd27aea10b2cefa4e929c7 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 27 Jan 2016 14:41:58 -0800 Subject: Overflow fixes for amrwbenc Most of these were encountered while running a mixed sanitized/unsanitized AMR encoder, so may not be reachable in real conditions. Change-Id: I85af7d40214133234009323e7e64432fc1be39ca --- .../libstagefright/codecs/amrwbenc/inc/basic_op.h | 10 ++++++--- media/libstagefright/codecs/amrwbenc/src/c2t64fx.c | 2 +- media/libstagefright/codecs/amrwbenc/src/c4t64fx.c | 6 +++--- media/libstagefright/codecs/amrwbenc/src/cor_h_x.c | 24 ++++++++++++++-------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h index e63a55a..d36f455 100644 --- a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h +++ b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h @@ -222,14 +222,18 @@ static_vo Word16 shl (Word16 var1, Word16 var2) } else { - result = (Word32) var1 *((Word32) 1 << var2); - if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result))) + if (var2 > 15 && var1 != 0) { var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16); } else { - var_out = extract_l (result); + result = (Word32) var1 *((Word32) 1 << var2); + if ((result != (Word32) ((Word16) result))) { + var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16); + } else { + var_out = extract_l (result); + } } } return (var_out); diff --git a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c index c7c9279..dbb94c6 100644 --- a/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c +++ b/media/libstagefright/codecs/amrwbenc/src/c2t64fx.c @@ -93,7 +93,7 @@ void ACELP_2t64_fx( #endif Isqrt_n(&s, &exp); - k_dn = vo_round(L_shl(s, (exp + 8))); /* k_dn = 256..4096 */ + k_dn = voround(L_shl(s, (exp + 8))); /* k_dn = 256..4096 */ k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */ /* mix normalized cn[] and dn[] */ diff --git a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c index b9a9e26..49a89a1 100644 --- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c +++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c @@ -257,7 +257,7 @@ void ACELP_4t64_fx( #endif Isqrt_n(&s, &exp); - k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16; /* k_dn = 256..4096 */ + k_dn = voround(L_shl(s, (exp + 5 + 3))); /* k_dn = 256..4096 */ k_dn = vo_mult_r(alp, k_dn); /* alp in Q12 */ /* mix normalized cn[] and dn[] */ @@ -1005,7 +1005,7 @@ void search_ixiy( for (x = track_x; x < L_SUBFR; x += STEP) { ps1 = *ps + dn[x]; - alp1 = alp0 + ((*p0++)<<13); + alp1 = L_add(alp0, ((*p0++)<<13)); if (dn2[x] < thres_ix) { @@ -1018,7 +1018,7 @@ void search_ixiy( alp2 = alp2 + ((*p2++)<<14); alp_16 = extract_h(alp2); sq = vo_mult(ps2, ps2); - s = vo_L_mult(alpk, sq) - ((sqk * alp_16)<<1); + s = L_sub(vo_L_mult(alpk, sq), L_mult(sqk, alp_16)); if (s > 0) { diff --git a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c index b2aa759..e834396 100644 --- a/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c +++ b/media/libstagefright/codecs/amrwbenc/src/cor_h_x.c @@ -55,10 +55,10 @@ void cor_h_x( p1 = &x[i]; p2 = &h[0]; for (j = i; j < L_SUBFR; j++) - L_tmp += vo_L_mult(*p1++, *p2++); + L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++)); y32[i] = L_tmp; - L_tmp = (L_tmp > 0)? L_tmp:-L_tmp; + L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp); if(L_tmp > L_max) { L_max = L_tmp; @@ -68,10 +68,10 @@ void cor_h_x( p1 = &x[i+1]; p2 = &h[0]; for (j = i+1; j < L_SUBFR; j++) - L_tmp += vo_L_mult(*p1++, *p2++); + L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++)); y32[i+1] = L_tmp; - L_tmp = (L_tmp > 0)? L_tmp:-L_tmp; + L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp); if(L_tmp > L_max1) { L_max1 = L_tmp; @@ -81,10 +81,10 @@ void cor_h_x( p1 = &x[i+2]; p2 = &h[0]; for (j = i+2; j < L_SUBFR; j++) - L_tmp += vo_L_mult(*p1++, *p2++); + L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++)); y32[i+2] = L_tmp; - L_tmp = (L_tmp > 0)? L_tmp:-L_tmp; + L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp); if(L_tmp > L_max2) { L_max2 = L_tmp; @@ -94,17 +94,23 @@ void cor_h_x( p1 = &x[i+3]; p2 = &h[0]; for (j = i+3; j < L_SUBFR; j++) - L_tmp += vo_L_mult(*p1++, *p2++); + L_tmp = L_add(L_tmp, vo_L_mult(*p1++, *p2++)); y32[i+3] = L_tmp; - L_tmp = (L_tmp > 0)? L_tmp:-L_tmp; + L_tmp = (L_tmp > 0)? L_tmp: (L_tmp == INT_MIN ? INT_MAX : -L_tmp); if(L_tmp > L_max3) { L_max3 = L_tmp; } } /* tot += 3*max / 8 */ - L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2); + if (L_max > INT_MAX - L_max1 || + L_max + L_max1 > INT_MAX - L_max2 || + L_max + L_max1 + L_max2 > INT_MAX - L_max3) { + L_max = INT_MAX >> 2; + } else { + L_max = ((L_max + L_max1 + L_max2 + L_max3) >> 2); + } L_tot = vo_L_add(L_tot, L_max); /* +max/4 */ L_tot = vo_L_add(L_tot, (L_max >> 1)); /* +max/8 */ -- cgit v1.1 From c4795f0ab03bc1188f2b6ca25b333b8a7220daf3 Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Wed, 3 Feb 2016 14:28:00 -0800 Subject: MPEG4Extractor: cast media time to int64_t in order to avoid check on unsigned integer overflow. Change-Id: Iad5ae41f0bbfc5e837b4b78e8acaa3f9462329e6 --- media/libstagefright/MPEG4Extractor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 2d2e8fb..c056a25 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1032,7 +1032,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { int64_t delay = (media_time * samplerate + 500000) / 1000000; mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); - int64_t paddingus = duration - (segment_duration + media_time); + int64_t paddingus = duration - (int64_t)(segment_duration + media_time); if (paddingus < 0) { // track duration from media header (which is what kKeyDuration is) might // be slightly shorter than the segment duration, which would make the -- cgit v1.1 From 5a4c1f8f409a28508075562277e4d19c4650513c Mon Sep 17 00:00:00 2001 From: Bin Chen Date: Mon, 22 Feb 2016 18:19:58 +1100 Subject: CameraService: Fix cameraId type of onDeviceStatusChanged The cameraId should be of type int, instead of camera_device_status_t. Change-Id: I26d587bb74f7100028f09928984c2e8dad6eebef Signed-off-by: Bin Chen --- services/camera/libcameraservice/CameraService.cpp | 4 ++-- services/camera/libcameraservice/CameraService.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index a560b93..3c9fd16 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -81,7 +81,7 @@ static void camera_device_status_change( sp cs = const_cast( static_cast(callbacks)); - cs->onDeviceStatusChanged(static_cast(camera_id), + cs->onDeviceStatusChanged(camera_id, static_cast(new_status)); } @@ -277,7 +277,7 @@ CameraService::~CameraService() { gCameraService = nullptr; } -void CameraService::onDeviceStatusChanged(camera_device_status_t cameraId, +void CameraService::onDeviceStatusChanged(int cameraId, camera_device_status_t newStatus) { ALOGI("%s: Status changed for cameraId=%d, newStatus=%d", __FUNCTION__, cameraId, newStatus); diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index ee4c3f9..53233bd 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -102,7 +102,7 @@ public: ///////////////////////////////////////////////////////////////////// // HAL Callbacks - virtual void onDeviceStatusChanged(camera_device_status_t cameraId, + virtual void onDeviceStatusChanged(int cameraId, camera_device_status_t newStatus); virtual void onTorchStatusChanged(const String8& cameraId, ICameraServiceListener::TorchStatus -- cgit v1.1 From 536fd16fa6d56008ba3d6f46275fd52dac25fd8c Mon Sep 17 00:00:00 2001 From: Patrik2 Carlsson Date: Mon, 25 May 2015 15:12:49 +0200 Subject: Avoid parsing CC SEI payload beyond buffer end Break CC SEI parsing when payload size exceeds buffer size to avoid a CHECK that have been seen in MTBF statistics. Change-Id: Ifd97648678a935ac815dd616301d46f9bf583838 --- media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp index ac3c6b6..2c07f28 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp @@ -235,6 +235,12 @@ bool NuPlayer::CCDecoder::parseSEINalUnit( payload_size += last_byte; } while (last_byte == 0xFF); + if (payload_size > SIZE_MAX / 8 + || !br.atLeastNumBitsLeft(payload_size * 8)) { + ALOGV("Malformed SEI payload"); + break; + } + // sei_payload() if (payload_type == 4) { bool isCC = false; -- cgit v1.1 From 27ee071a98549919b92c195d51455c62a83ddd1b Mon Sep 17 00:00:00 2001 From: Mohan Kumar Date: Fri, 12 Dec 2014 15:16:46 +0530 Subject: audioflinger: clear mMixerBuffer if frame is not ready Clear the mMixerBuffer if frame is not ready before the FastMixer starts processing. Otherwise it might result in large glitches on output device due to junk data present in the mixbuffer. Change-Id: I9f025234d4ac100f85d2ec67c06a8df4195bea98 --- services/audioflinger/FastMixer.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 45c68b5..2bc8066 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -334,6 +334,11 @@ void FastMixer::onWork() if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) { ALOG_ASSERT(mMixerBuffer != NULL); + + // AudioMixer::mState.enabledTracks is undefined if mState.hook == process__validate, + // so we keep a side copy of enabledTracks + bool anyEnabledTracks = false; + // for each track, update volume and check for underrun unsigned currentTrackMask = current->mTrackMask; while (currentTrackMask != 0) { @@ -392,11 +397,13 @@ void FastMixer::onWork() underruns.mBitFields.mPartial++; underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL; mMixer->enable(name); + anyEnabledTracks = true; } } else { underruns.mBitFields.mFull++; underruns.mBitFields.mMostRecent = UNDERRUN_FULL; mMixer->enable(name); + anyEnabledTracks = true; } ftDump->mUnderruns = underruns; ftDump->mFramesReady = framesReady; @@ -407,9 +414,14 @@ void FastMixer::onWork() pts = AudioBufferProvider::kInvalidPTS; } - // process() is CPU-bound - mMixer->process(pts); - mMixerBufferState = MIXED; + if (anyEnabledTracks) { + // process() is CPU-bound + mMixer->process(pts); + mMixerBufferState = MIXED; + } else if (mMixerBufferState != ZEROED) { + mMixerBufferState = UNDEFINED; + } + } else if (mMixerBufferState == MIXED) { mMixerBufferState = UNDEFINED; } -- cgit v1.1 From f9ed2fe6d61259e779a37d4c2d7edb33a1c1f8ba Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 16 Mar 2016 10:32:05 -0700 Subject: Add VPX output buffer size check and handle dead observers more gracefully Bug: 27597103 Change-Id: Id7acb25d5ef69b197da15ec200a9e4f9e7b03518 --- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 23 ++++++++++++++--------- media/libstagefright/omx/OMX.cpp | 7 ++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index e161fb8..02e85a1 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -149,15 +149,20 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por outHeader->nFlags = 0; outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2; outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv; - - uint8_t *dst = outHeader->pBuffer; - const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y]; - const uint8_t *srcU = (const uint8_t *)mImg->planes[VPX_PLANE_U]; - const uint8_t *srcV = (const uint8_t *)mImg->planes[VPX_PLANE_V]; - size_t srcYStride = mImg->stride[VPX_PLANE_Y]; - size_t srcUStride = mImg->stride[VPX_PLANE_U]; - size_t srcVStride = mImg->stride[VPX_PLANE_V]; - copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride); + if (outHeader->nAllocLen >= outHeader->nFilledLen) { + uint8_t *dst = outHeader->pBuffer; + const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y]; + const uint8_t *srcU = (const uint8_t *)mImg->planes[VPX_PLANE_U]; + const uint8_t *srcV = (const uint8_t *)mImg->planes[VPX_PLANE_V]; + size_t srcYStride = mImg->stride[VPX_PLANE_Y]; + size_t srcUStride = mImg->stride[VPX_PLANE_U]; + size_t srcVStride = mImg->stride[VPX_PLANE_V]; + copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride); + } else { + ALOGE("b/27597103, buffer too small"); + android_errorWriteLog(0x534e4554, "27597103"); + outHeader->nFilledLen = 0; + } mImg = NULL; outInfo->mOwnedByUs = false; diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 7f357c9..56b6055 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -179,7 +179,12 @@ void OMX::binderDied(const wp &the_late_who) { Mutex::Autolock autoLock(mLock); ssize_t index = mLiveNodes.indexOfKey(the_late_who); - CHECK(index >= 0); + + if (index < 0) { + ALOGE("b/27597103, nonexistent observer on binderDied"); + android_errorWriteLog(0x534e4554, "27597103"); + return; + } instance = mLiveNodes.editValueAt(index); mLiveNodes.removeItemsAt(index); -- cgit v1.1 From b04aee833c5cfb6b31b8558350feb14bb1a0f353 Mon Sep 17 00:00:00 2001 From: Chien-Yu Chen Date: Wed, 9 Mar 2016 12:21:01 -0800 Subject: Camera3Device: Validate template ID Validate template ID before creating a default request. Bug: 26866110 Bug: 27568958 Change-Id: Ifda457024f1d5c2b1382f189c1a8d5fda852d30d --- services/camera/libcameraservice/device3/Camera3Device.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 50d9d75..8b43154 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -43,6 +43,7 @@ #include #include +#include "CameraService.h" #include "utils/CameraTraces.h" #include "mediautils/SchedulingPolicyService.h" #include "device3/Camera3Device.h" @@ -1115,6 +1116,13 @@ status_t Camera3Device::createDefaultRequest(int templateId, CameraMetadata *request) { ATRACE_CALL(); ALOGV("%s: for template %d", __FUNCTION__, templateId); + + if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) { + android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110", + IPCThreadState::self()->getCallingUid(), NULL, 0); + return BAD_VALUE; + } + Mutex::Autolock il(mInterfaceLock); Mutex::Autolock l(mLock); -- cgit v1.1 From a2d1d85726aa2a3126e9c331a8e00a8c319c9e2b Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 18 Mar 2016 14:34:57 -0700 Subject: NuPlayerStreamListener: NULL and bounds check before memcpy Bug: 27533704 Change-Id: I992a7709b92b1cbc3114c97bec48a3fc5b22ba6e --- .../libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp index f53afbd..ee70306 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp @@ -144,8 +144,17 @@ ssize_t NuPlayer::NuPlayerStreamListener::read( copy = size; } + if (entry->mIndex >= mBuffers.size()) { + return ERROR_MALFORMED; + } + + sp mem = mBuffers.editItemAt(entry->mIndex); + if (mem == NULL || mem->size() < copy || mem->size() - copy < entry->mOffset) { + return ERROR_MALFORMED; + } + memcpy(data, - (const uint8_t *)mBuffers.editItemAt(entry->mIndex)->pointer() + (const uint8_t *)mem->pointer() + entry->mOffset, copy); -- cgit v1.1 From 7fd96ebfc4c9da496c59d7c45e1f62be178e626d Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Sun, 20 Mar 2016 10:44:44 +0900 Subject: codecs: check OMX buffer size before use in VP8 encoder. Bug: 27569635 Change-Id: I469573f40e21dc9f4c200749d4f220e3a2d31761 --- .../codecs/on2/enc/SoftVPXEncoder.cpp | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index 410f9d0..d9895f0 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -688,9 +688,10 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) { const uint8_t *source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset; + size_t frameSize = mWidth * mHeight * 3 / 2; if (mInputDataIsMeta) { source = extractGraphicBuffer( - mConversionBuffer, mWidth * mHeight * 3 / 2, + mConversionBuffer, frameSize, source, inputBufferHeader->nFilledLen, mWidth, mHeight); if (source == NULL) { @@ -698,11 +699,21 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) { notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); return; } - } else if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { - ConvertYUV420SemiPlanarToYUV420Planar( - source, mConversionBuffer, mWidth, mHeight); + } else { + if (inputBufferHeader->nFilledLen < frameSize) { + android_errorWriteLog(0x534e4554, "27569635"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); + return; + } else if (inputBufferHeader->nFilledLen > frameSize) { + ALOGW("Input buffer contains too many pixels"); + } - source = mConversionBuffer; + if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { + ConvertYUV420SemiPlanarToYUV420Planar( + source, mConversionBuffer, mWidth, mHeight); + + source = mConversionBuffer; + } } vpx_image_t raw_frame; vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, mWidth, mHeight, @@ -764,9 +775,14 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) { outputBufferHeader->nTimeStamp = encoded_packet->data.frame.pts; outputBufferHeader->nFlags = 0; if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY) - outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; outputBufferHeader->nOffset = 0; outputBufferHeader->nFilledLen = encoded_packet->data.frame.sz; + if (outputBufferHeader->nFilledLen > outputBufferHeader->nAllocLen) { + android_errorWriteLog(0x534e4554, "27569635"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); + return; + } memcpy(outputBufferHeader->pBuffer, encoded_packet->data.frame.buf, encoded_packet->data.frame.sz); -- cgit v1.1 From 44749eb4f273f0eb681d0fa013e3beef754fa687 Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Thu, 17 Mar 2016 11:15:02 -0700 Subject: SoftAMR: check output buffer size to avoid overflow. Bug: 27662364 Change-Id: I7b26892c41d6f2e690e77478ab855c2fed1ff6b0 --- media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index a9723ea..bcf6a62 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -312,6 +312,15 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { int32_t numBytesRead; if (mMode == MODE_NARROW) { + if (outHeader->nAllocLen < kNumSamplesPerFrameNB * sizeof(int16_t)) { + ALOGE("b/27662364: NB expected output buffer %zu bytes vs %u", + kNumSamplesPerFrameNB * sizeof(int16_t), outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "27662364"); + notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL); + mSignalledError = true; + return; + } + numBytesRead = AMRDecode(mState, (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f), @@ -339,6 +348,15 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { return; } } else { + if (outHeader->nAllocLen < kNumSamplesPerFrameWB * sizeof(int16_t)) { + ALOGE("b/27662364: WB expected output buffer %zu bytes vs %u", + kNumSamplesPerFrameWB * sizeof(int16_t), outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "27662364"); + notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL); + mSignalledError = true; + return; + } + int16 mode = ((inputPtr[0] >> 3) & 0x0f); if (mode >= 10 && mode <= 13) { -- cgit v1.1 From 65756b4082cd79a2d99b2ccb5b392291fd53703f Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Fri, 18 Mar 2016 18:17:14 -0700 Subject: SoftAMR: check input buffer size to avoid overflow. Bug: 27662364 Change-Id: I47380545ea7d85845e141e722b0d84f498d27145 --- media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 25 +++++++++++++++++++++- .../codecs/amrnb/dec/src/amrdecode.h | 1 - .../codecs/amrnb/dec/src/gsmamr_dec.h | 14 +----------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index bcf6a62..77c3742 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -286,6 +286,13 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; + if (inHeader->nFilledLen == 0) { + inInfo->mOwnedByUs = false; + inQueue.erase(inQueue.begin()); + notifyEmptyBufferDone(inHeader); + continue; + } + BufferInfo *outInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; @@ -321,6 +328,17 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { return; } + int16 mode = ((inputPtr[0] >> 3) & 0x0f); + // for WMF since MIME_IETF is used when calling AMRDecode. + size_t frameSize = WmfDecBytesPerFrame[mode] + 1; + + if (inHeader->nFilledLen < frameSize) { + ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen); + notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); + mSignalledError = true; + return; + } + numBytesRead = AMRDecode(mState, (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f), @@ -370,7 +388,12 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { } size_t frameSize = getFrameSize(mode); - CHECK_GE(inHeader->nFilledLen, frameSize); + if (inHeader->nFilledLen < frameSize) { + ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen); + notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); + mSignalledError = true; + return; + } int16_t *outPtr = (int16_t *)outHeader->pBuffer; diff --git a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h b/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h index 0988e17..f224fb6 100644 --- a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h +++ b/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h @@ -104,7 +104,6 @@ terms listed above has been obtained from the copyright holder. ; INCLUDES ----------------------------------------------------------------------------*/ #include "typedef.h" -#include "mode.h" #include "frame_type_3gpp.h" /*--------------------------------------------------------------------------*/ diff --git a/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h b/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h index 8f54ee8..dc64d67 100644 --- a/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h +++ b/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h @@ -87,6 +87,7 @@ terms listed above has been obtained from the copyright holder. #include "gsm_amr_typedefs.h" #include "frame_type_3gpp.h" +#include "amrdecode.h" /*--------------------------------------------------------------------------*/ #ifdef __cplusplus @@ -136,19 +137,6 @@ extern "C" Word8 *id); /* - * AMRDecode steps into the part of the library that decodes the raw data - * speech bits for the decoding process. It returns the address offset of - * the next frame to be decoded. - */ - Word16 AMRDecode( - void *state_data, - enum Frame_Type_3GPP frame_type, - UWord8 *speech_bits_ptr, - Word16 *raw_pcm_buffer, - Word16 input_format - ); - - /* * This function resets the state memory used by the GSM AMR decoder. This * function returns zero. It will return negative one if there is an error. */ -- cgit v1.1 From daa85dac2055b22dabbb3b4e537597e6ab73a866 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Fri, 25 Mar 2016 08:26:18 -0700 Subject: Fix AMR decoder Previous change caused EOS to be ignored. Bug: 27843673 Related-to-bug: 27662364 Change-Id: Ia148a88abc861a9b393f42bc7cd63d8d3ae349bc --- media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index 77c3742..955309a 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -286,13 +286,6 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { BufferInfo *inInfo = *inQueue.begin(); OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; - if (inHeader->nFilledLen == 0) { - inInfo->mOwnedByUs = false; - inQueue.erase(inQueue.begin()); - notifyEmptyBufferDone(inHeader); - continue; - } - BufferInfo *outInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; @@ -310,6 +303,13 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { return; } + if (inHeader->nFilledLen == 0) { + inInfo->mOwnedByUs = false; + inQueue.erase(inQueue.begin()); + notifyEmptyBufferDone(inHeader); + continue; + } + if (inHeader->nOffset == 0) { mAnchorTimeUs = inHeader->nTimeStamp; mNumSamplesOutput = 0; -- cgit v1.1 From af76b10d0bce63c7e5896ddbe6fe897ed0110186 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Mon, 7 Mar 2016 22:12:56 +0800 Subject: audio: allow standby for direct track Delay standby for offload track use case is not suitable for direct track in PCM format, because player torn down doesn't necessarily happen. To avoid AP looping infinitely, allow standby right after direct track in PCM format is paused. CRs-Fixed: 986784 Change-Id: Id0026ac9891a12acc4affa446b2bc841559fcc28 --- services/audioflinger/Threads.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index c3ee6c2..6f223af 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -4863,6 +4863,10 @@ bool AudioFlinger::DirectOutputThread::shouldStandby_l() bool trackPaused = false; bool trackStopped = false; + if ((mType == DIRECT) && audio_is_linear_pcm(mFormat) && !usesHwAvSync()) { + return !mStandby; + } + // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack // after a timeout and we will enter standby then. if (mTracks.size() > 0) { -- cgit v1.1 From e5c901e16fdb7ed1d37bd7aa1232973588692a91 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Fri, 26 Feb 2016 18:07:49 +0800 Subject: audio: use offload standby delay for direct pcm Default standby delay for legacy direct is too aggressive for track offloaded use case. Using offload standby delay instead, which allows sufficient time for track transition before standby the output. CRs-Fixed: 982822 Change-Id: Ifd0e39c5b3fe4a4af9f444dbbad21ef1e1a5edfa --- services/audioflinger/Threads.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 6f223af..e1e4980 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -4987,6 +4987,8 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l() mStandbyDelayNs = 0; } else if ((mType == OFFLOAD) && !audio_is_linear_pcm(mFormat)) { mStandbyDelayNs = kOffloadStandbyDelayNs; + } else if (mType == DIRECT && mIsDirectPcm) { + mStandbyDelayNs = kOffloadStandbyDelayNs; } else { mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2); } -- cgit v1.1 From f42cede4106389bc99c86dea857afd04b4a79805 Mon Sep 17 00:00:00 2001 From: Preetam Singh Ranawat Date: Mon, 22 Feb 2016 16:10:01 +0530 Subject: audio: Update anchor time only when sink start is successful - During offload (WH) to non-offload fallback (BT), anchor time is getting updated incorrectly with offload renderer position when it tries to start sink using offload mode only. - update anchor time post resume only when sink is started successfully. Change-Id: I2c2992afa90506e08389226964b0bd5a5be07529 CRs-Fixed: 978596 --- media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 2336eb7..d888cf4 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -1591,7 +1591,7 @@ void NuPlayer::Renderer::onResume() { notifyAudioTearDown(); } //Update anchor time after resuming playback. - if (offloadingAudio()) { + if (offloadingAudio() && status == NO_ERROR) { int64_t nowUs = ALooper::GetNowUs(); int64_t nowMediaUs = mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs); -- cgit v1.1 From e13b58b988ab642d4ae5ca6d0a89013510714956 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 3 Apr 2016 11:50:58 -0700 Subject: audio: Send effect session notifications after startOutput success * Because we get a hellish firestorm during offload fallback, and our effects library really dislikes this. Change-Id: I22adb55d04502eedf03ce22f35f8b9f61de1c7b0 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 3 +-- services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index f2d7f6f..725bc64 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -246,8 +246,6 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); - - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, true); } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -275,6 +273,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, } procDesc->setProcessorEnabled(true); + return 1; } return status; } diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index c0d3866..766012e 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -206,15 +206,22 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output, Mutex::Autolock _l(mLock); audioPolicyEffects = mAudioPolicyEffects; } + + status_t status = NO_ERROR; if (audioPolicyEffects != 0) { // create audio processors according to stream - status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); - if (status != NO_ERROR && status != ALREADY_EXISTS) { + status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); + if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { ALOGW("Failed to add effects on session %d", session); } } Mutex::Autolock _l(mLock); - return mAudioPolicyManager->startOutput(output, stream, session); + status_t status2 = mAudioPolicyManager->startOutput(output, stream, session); + + if (audioPolicyEffects != 0 && status > 0 && status2 == NO_ERROR) { + onOutputSessionEffectsUpdate(stream, session, true); + } + return status2; } status_t AudioPolicyService::stopOutput(audio_io_handle_t output, -- cgit v1.1 From a4123803d0a0e9e0c69faa4207d357cc74a65d58 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 6 Apr 2016 18:35:02 -0700 Subject: audiopolicy: Be a little smarter with auto-attach * The edge cases, ZOMG! * Instead of relying on effects to be automatically attached, let's just always notify userspace and send a bit more information. This lets the application decide if effects should be attached rather than relying on a hard-coded configuration file. * Perform the setup in getOutputForAttr, but do it on the command thread so we don't block the client. OPO-593 Change-Id: I3900b349f2e895d51fa3a3dcc2de0c4bdf6dbc08 --- include/media/AudioSystem.h | 10 ++- include/media/IAudioPolicyServiceClient.h | 6 +- media/libmedia/AudioSystem.cpp | 6 +- media/libmedia/IAudioPolicyServiceClient.cpp | 15 ++++- services/audiopolicy/AudioPolicyInterface.h | 5 +- .../audiopolicy/service/AudioPolicyClientImpl.cpp | 7 ++- .../audiopolicy/service/AudioPolicyEffects.cpp | 32 +++++++++- services/audiopolicy/service/AudioPolicyEffects.h | 5 ++ .../service/AudioPolicyInterfaceImpl.cpp | 68 +++++++++++--------- .../audiopolicy/service/AudioPolicyService.cpp | 72 +++++++++++++++++++--- services/audiopolicy/service/AudioPolicyService.h | 55 +++++++++++++++-- 11 files changed, 222 insertions(+), 59 deletions(-) diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 35b06ba..be1d114 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -32,7 +32,9 @@ namespace android { typedef void (*audio_error_callback)(status_t err); typedef void (*dynamic_policy_callback)(int event, String8 regId, int val); typedef void (*effect_session_callback)(int event, - audio_stream_type_t stream, audio_unique_id_t sessionId, bool added); + audio_stream_type_t stream, audio_unique_id_t sessionId, + audio_output_flags_t flags, audio_channel_mask_t channelMask, + uid_t uid, bool added); class IAudioFlinger; class IAudioPolicyService; @@ -423,8 +425,10 @@ private: virtual void onAudioPatchListUpdate(); virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, - bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); private: Mutex mLock; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h index 3bdeb5a..18aed8d 100644 --- a/include/media/IAudioPolicyServiceClient.h +++ b/include/media/IAudioPolicyServiceClient.h @@ -39,8 +39,10 @@ public: virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; // Notifies when a default effect set is attached to a session/stream virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, - bool added) = 0; + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added) = 0; }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 10ec495..5bd8747 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -1239,7 +1239,9 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate( } void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) + audio_stream_type_t stream, audio_session_t sessionId, + audio_output_flags_t flags, audio_channel_mask_t channelMask, + uid_t uid, bool added) { ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)", stream, sessionId, added); effect_session_callback cb = NULL; @@ -1249,7 +1251,7 @@ void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate( } if (cb != NULL) { - cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, stream, sessionId, added); + cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, stream, sessionId, flags, channelMask, uid, added); } } diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp index d6207ce..ecf0d1f 100644 --- a/media/libmedia/IAudioPolicyServiceClient.cpp +++ b/media/libmedia/IAudioPolicyServiceClient.cpp @@ -66,12 +66,18 @@ public: } void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added) + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor()); data.writeInt32(stream); data.writeInt32(sessionId); + data.writeInt32(flags); + data.writeInt32(channelMask); + data.writeInt32(uid); data.writeInt32(added ? 1 : 0); remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); } @@ -105,9 +111,12 @@ status_t BnAudioPolicyServiceClient::onTransact( case OUTPUT_SESSION_EFFECTS_UPDATE: { CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply); audio_stream_type_t stream = static_cast(data.readInt32()); - audio_unique_id_t sessionId = static_cast(data.readInt32()); + audio_session_t sessionId = static_cast(data.readInt32()); + audio_output_flags_t flags = static_cast(data.readInt32()); + audio_channel_mask_t channelMask = static_cast(data.readInt32()); + uid_t uid = static_cast(data.readInt32()); bool added = data.readInt32() > 0; - onOutputSessionEffectsUpdate(stream, sessionId, added); + onOutputSessionEffectsUpdate(stream, sessionId, flags, channelMask, uid, added); return NO_ERROR; } default: diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index a5edc14..bf9dd64 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -333,7 +333,10 @@ public: virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added) = 0; + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added) = 0; }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index d71daa4..f1a2ae9 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -220,9 +220,12 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate( } void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) + audio_stream_type_t stream, audio_session_t sessionId, + audio_output_flags_t flags, audio_channel_mask_t channelMask, + uid_t uid, bool added) { - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, added); + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, + flags, channelMask, uid, added); } audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId() diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 725bc64..bd1cc33 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -246,6 +246,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); + } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -273,11 +274,35 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, } procDesc->setProcessorEnabled(true); - return 1; } return status; } +status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + int session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + ALOGV("doAddOutputSessionEffects()"); + + // create audio processors according to stream + status_t status = addOutputSessionEffects(output, stream, session); + if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { + ALOGW("Failed to add effects on session %d", session); + } + + // notify listeners + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, + flags, channelMask, uid, true); + + // Never return an error if effects setup fails. + return NO_ERROR; +} + status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -335,10 +360,13 @@ status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t out procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false); ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", audioSession); } + + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)audioSession, + AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); + return status; } diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 7988515..6364e40 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -91,6 +91,11 @@ public: audio_stream_type_t stream, int audioSession); + status_t doAddOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + int audioSession, + audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, + audio_channel_mask_t channelMask = 0, uid_t uid = 0); private: diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 766012e..51af20b 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -18,6 +18,7 @@ //#define LOG_NDEBUG 0 #include +#include #include "AudioPolicyService.h" #include "ServiceUtilities.h" @@ -162,18 +163,47 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, return NO_INIT; } ALOGV("getOutput()"); - Mutex::Autolock _l(mLock); + status_t status; + sp audioPolicyEffects; + { + Mutex::Autolock _l(mLock); - // if the caller is us, trust the specified uid - if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { - uid_t newclientUid = IPCThreadState::self()->getCallingUid(); - if (uid != (uid_t)-1 && uid != newclientUid) { - ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); + // if the caller is us, trust the specified uid + if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { + uid_t newclientUid = IPCThreadState::self()->getCallingUid(); + if (uid != (uid_t)-1 && uid != newclientUid) { + ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); + } + uid = newclientUid; } - uid = newclientUid; + status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, + format, channelMask, flags, selectedDeviceId, offloadInfo); + audioPolicyEffects = mAudioPolicyEffects; + } + + if (audioPolicyEffects != 0) { + addOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); + } + + return status; +} + +status_t AudioPolicyService::addOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; } - return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, - format, channelMask, flags, selectedDeviceId, offloadInfo); + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + ALOGV("addOutputSessionEffects()"); + return mOutputCommandThread->addOutputSessionEffectsCommand( + output, stream, session, flags, channelMask, uid); } status_t AudioPolicyService::startOutput(audio_io_handle_t output, @@ -201,27 +231,9 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output, return NO_INIT; } ALOGV("doStartOutput()"); - spaudioPolicyEffects; - { - Mutex::Autolock _l(mLock); - audioPolicyEffects = mAudioPolicyEffects; - } - - status_t status = NO_ERROR; - if (audioPolicyEffects != 0) { - // create audio processors according to stream - status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); - if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { - ALOGW("Failed to add effects on session %d", session); - } - } Mutex::Autolock _l(mLock); - status_t status2 = mAudioPolicyManager->startOutput(output, stream, session); - if (audioPolicyEffects != 0 && status > 0 && status2 == NO_ERROR) { - onOutputSessionEffectsUpdate(stream, session, true); - } - return status2; + return mAudioPolicyManager->startOutput(output, stream, session); } status_t AudioPolicyService::stopOutput(audio_io_handle_t output, diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 58cfe37..0e871c2 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -272,21 +272,27 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co } void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, - bool added) + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added) { ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)", stream, sessionId, added); - mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, added); + mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, + flags, channelMask, uid, added); } void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, - bool added) + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added) { Mutex::Autolock _l(mNotificationClientsLock); for (size_t i = 0; i < mNotificationClients.size(); i++) { - mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, added); + mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, + flags, channelMask, uid, added); } } @@ -327,10 +333,13 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) + audio_stream_type_t stream, audio_session_t sessionId, + audio_output_flags_t flags, audio_channel_mask_t channelMask, + uid_t uid, bool added) { if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) { - mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, added); + mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, + flags, channelMask, uid, added); } } @@ -645,7 +654,8 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() break; } mLock.unlock(); - svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded); + svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, + data->mFlags, data->mChannelMask, data->mUid, data->mAdded); mLock.lock(); } break; case RELEASE_OUTPUT_SESSION_EFFECTS: { @@ -662,6 +672,20 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() data->mOutput, data->mStream, data->mSessionId); mLock.lock(); } break; + case ADD_OUTPUT_SESSION_EFFECTS: { + AddOutputSessionEffectsData *data = (AddOutputSessionEffectsData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing add output session effects %d", + data->mOutput); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->mAudioPolicyEffects->doAddOutputSessionEffects( + data->mOutput, data->mStream, data->mSessionId, + data->mFlags, data->mChannelMask, data->mUid); + mLock.lock(); + }break; default: @@ -828,6 +852,29 @@ status_t AudioPolicyService::AudioCommandThread::startOutputCommand(audio_io_han return sendCommand(command); } +status_t AudioPolicyService::AudioCommandThread::addOutputSessionEffectsCommand(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid) +{ + sp command = new AudioCommand(); + command->mCommand = ADD_OUTPUT_SESSION_EFFECTS; + sp data = new AddOutputSessionEffectsData(); + data->mOutput = output; + data->mStream = stream; + data->mSessionId = session; + data->mFlags = flags; + data->mChannelMask = channelMask; + data->mUid = uid; + command->mParam = data; + command->mWaitStatus = false; + ALOGV("AudioCommandThread() adding start output %d", output); + return sendCommand(command); +} + + void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session) @@ -937,13 +984,18 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( } void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( - audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) + audio_stream_type_t stream, audio_session_t sessionId, + audio_output_flags_t flags, audio_channel_mask_t channelMask, + uid_t uid, bool added) { sp command = new AudioCommand(); command->mCommand = EFFECT_SESSION_UPDATE; EffectSessionUpdateData *data = new EffectSessionUpdateData(); data->mStream = stream; data->mSessionId = sessionId; + data->mFlags = flags; + data->mChannelMask = channelMask; + data->mUid = uid; data->mAdded = added; command->mParam = data; ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)", diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 9b17a26..01e0e5e 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -204,6 +204,13 @@ public: virtual status_t setEffectSessionCallbacksEnabled(bool enabled); + virtual status_t addOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid); + status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -232,9 +239,15 @@ public: void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); void releaseOutputSessionEffectsDelayed(audio_io_handle_t output, audio_stream_type_t stream, audio_unique_id_t sessionId, @@ -274,6 +287,7 @@ private: DYN_POLICY_MIX_STATE_UPDATE, EFFECT_SESSION_UPDATE, RELEASE_OUTPUT_SESSION_EFFECTS, + ADD_OUTPUT_SESSION_EFFECTS }; AudioCommandThread (String8 name, const wp& service); @@ -317,11 +331,21 @@ private: void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); void effectSessionUpdateCommand(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); void releaseOutputSessionEffectsCommand(audio_io_handle_t output, audio_stream_type_t stream, audio_unique_id_t sessionId, int delayMs = 0); + status_t addOutputSessionEffectsCommand(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid); + private: class AudioCommandData; @@ -421,7 +445,10 @@ private: class EffectSessionUpdateData : public AudioCommandData { public: audio_stream_type_t mStream; - audio_unique_id_t mSessionId; + audio_session_t mSessionId; + audio_output_flags_t mFlags; + audio_channel_mask_t mChannelMask; + uid_t mUid; bool mAdded; }; @@ -432,6 +459,16 @@ private: audio_unique_id_t mSessionId; }; + class AddOutputSessionEffectsData : public AudioCommandData { + public: + audio_io_handle_t mOutput; + audio_stream_type_t mStream; + audio_session_t mSessionId; + audio_output_flags_t mFlags; + audio_channel_mask_t mChannelMask; + uid_t mUid; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands @@ -542,7 +579,10 @@ private: virtual audio_unique_id_t newAudioUniqueId(); virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); private: AudioPolicyService *mAudioPolicyService; @@ -562,7 +602,10 @@ private: void setAudioPortCallbacksEnabled(bool enabled); void setEffectSessionCallbacksEnabled(bool enabled); void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_unique_id_t sessionId, bool added); + audio_session_t sessionId, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid, bool added); // IBinder::DeathRecipient virtual void binderDied(const wp& who); -- cgit v1.1 From baf93ea325ca416aa5a0fc0c6892dda4cef1f444 Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 16 Mar 2016 20:02:38 +0000 Subject: CameraClient: MTK Support Return on MTK hardware, the HAL does this internally and duplicating it here causes an infinite loop. Change-Id: I5bdb925ddb49980747b58dfae4543f812cef4c7d --- services/camera/libcameraservice/api1/CameraClient.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 735a4ae..af46d63 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -695,6 +695,9 @@ void CameraClient::disableMsgType(int32_t msgType) { #define CHECK_MESSAGE_INTERVAL 10 // 10ms bool CameraClient::lockIfMessageWanted(int32_t msgType) { +#ifdef MTK_HARDWARE + return true; +#endif int sleepCount = 0; while (mMsgEnabled & msgType) { if (mLock.tryLock() == NO_ERROR) { -- cgit v1.1 From 6635a582f449f86c1099de11aae6b27e6a33d21f Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Wed, 23 Mar 2016 17:45:20 +0000 Subject: omx: softcodecs: Support HAL_PIXEL_FORMAT_RGBX_8888 Adds support for the HAL_PIXEL_FORMAT_RGBX_8888 format used by mediatek's hardware. Fixes several CTS tests where interaction between hardware and software encoders and decoders is tested. Change-Id: Ie3267c7d34706c49ad415ebc04ad05f2f2ef3506 --- media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp index 8ea7a6e..dc3ed39 100644 --- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp @@ -606,6 +606,9 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( break; case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_BGRA_8888: +#ifdef MTK_HARDWARE + case HAL_PIXEL_FORMAT_RGBX_8888: +#endif ConvertRGB32ToPlanar( dst, dstStride, dstVStride, (const uint8_t *)bits, width, height, srcStride, -- cgit v1.1 From 135352e8ed65ec4650fc1132e7802753109d9a74 Mon Sep 17 00:00:00 2001 From: Sidipotu Ashok Date: Fri, 4 Sep 2015 10:36:00 +0530 Subject: NuPlayer: extend onResume funtion - Extend onResume in-order to implement the Audio Voice Concurrency changes. Change-Id: I2b02f644df23f35b6d37d07a99d74ad56470b142 --- media/libmediaplayerservice/nuplayer/NuPlayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 1c51c4b..725a1b2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -247,7 +247,7 @@ protected: void finishFlushIfPossible(); void onStart(int64_t startPositionUs = -1); - void onResume(); + virtual void onResume(); void onPause(); bool audioDecoderStillNeeded(); -- cgit v1.1 From 804eeffb2da5f954177a297dd54966eb865424a5 Mon Sep 17 00:00:00 2001 From: William Clark Date: Thu, 22 Oct 2015 18:21:08 -0700 Subject: Update Instrumentation code Add support for enhancements in QSSP instrumentation code. Change-Id: I00aa0b2bee5044d91eeeddaa43d3d28518a5ba93 --- media/libmedia/AudioRecord.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 40f6c44..fc35a4c 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -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; -- cgit v1.1 From d38f17584c22d77b8b0bac85279ce72e1576c34c Mon Sep 17 00:00:00 2001 From: Ramjee Singh Date: Thu, 22 Oct 2015 12:57:55 +0530 Subject: audioflinger: Compile 192k resampler for 32 bit environment Current makefile compiles the resampler only for 64 bit environment. Allow compilation for 32 bit environment as well. CRs-Fixed: 735776 Change-Id: I626725551af73fc5ea98a7dbf87cacea9dbbc0ef --- services/audioflinger/Android.mk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 0dd2af6..8ea26d3 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -160,12 +160,19 @@ LOCAL_SHARED_LIBRARIES := \ libaudioutils #QTI Resampler -ifeq ($(call is-vendor-board-platform,QCOM), true) -ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true) +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true) +ifdef TARGET_2ND_ARCH LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += AudioResamplerQTI.cpp.arm LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH) += $(TARGET_OUT_HEADERS)/mm-audio/audio-src LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH) += libqct_resampler LOCAL_CFLAGS_$(TARGET_2ND_ARCH) += -DQTI_RESAMPLER +else +LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src +LOCAL_SHARED_LIBRARIES += libqct_resampler +LOCAL_CFLAGS += -DQTI_RESAMPLER +endif endif endif #QTI Resampler -- cgit v1.1 From 322d0a4dd98eae78c0f0acbebc2b622be9fd5438 Mon Sep 17 00:00:00 2001 From: Deva Ramasubramanian Date: Mon, 9 Nov 2015 18:55:59 -0800 Subject: libstagefright: Allow for MPEG4Writer extension Defer MPEG4 muxer creation to AVFactory. Change-Id: If0918be77ab7f8d82c78203f371df789e3cc29b8 --- include/media/stagefright/MPEG4Writer.h | 9 ++++++++- media/libavextensions/stagefright/AVExtensions.h | 3 +++ media/libavextensions/stagefright/AVFactory.cpp | 6 ++++++ media/libmediaplayerservice/StagefrightRecorder.cpp | 2 +- media/libstagefright/MPEG4Writer.cpp | 2 +- media/libstagefright/MediaMuxer.cpp | 3 ++- 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index aeaad8f..09a48f9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -77,13 +77,17 @@ private: int mFd; status_t mInitCheck; bool mIsRealTimeRecording; +protected: bool mUse4ByteNalLength; +private: bool mUse32BitOffset; bool mIsFileSizeLimitExplicitlyRequested; bool mPaused; bool mStarted; // Writer thread + track threads started successfully bool mWriterThreadStarted; // Only writer thread started successfully +protected: off64_t mOffset; +private: off_t mMdatOffset; uint8_t *mMoovBoxBuffer; off64_t mMoovBoxBufferOffset; @@ -194,8 +198,11 @@ private: // Acquire lock before calling these methods off64_t addSample_l(MediaBuffer *buffer); - off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); +protected: + static void StripStartcode(MediaBuffer *buffer); + virtual off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); +private: bool exceedsFileSizeLimit(); bool use32BitFileOffset() const; bool exceedsFileDurationLimit(); diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h index b0e4bb5..c4c9aae 100644 --- a/media/libavextensions/stagefright/AVExtensions.h +++ b/media/libavextensions/stagefright/AVExtensions.h @@ -59,6 +59,7 @@ class ICameraRecordingProxy; class String16; class IGraphicBufferProducer; struct Size; +class MPEG4Writer; /* * Factory to create objects of base-classes in libstagefright @@ -107,6 +108,8 @@ struct AVFactory { const sp& surface, int64_t timeBetweenFrameCaptureUs, bool storeMetaDataInVideoBuffers = true); + + virtual MPEG4Writer *CreateMPEG4Writer(int fd); // ----- NO TRESSPASSING BEYOND THIS LINE ------ DECLARE_LOADABLE_SINGLETON(AVFactory); }; diff --git a/media/libavextensions/stagefright/AVFactory.cpp b/media/libavextensions/stagefright/AVFactory.cpp index f6d5f53..7420d12 100644 --- a/media/libavextensions/stagefright/AVFactory.cpp +++ b/media/libavextensions/stagefright/AVFactory.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include "common/ExtensionsLoader.hpp" #include "stagefright/AVExtensions.h" @@ -120,6 +121,11 @@ CameraSourceTimeLapse* AVFactory::CreateCameraSourceTimeLapseFromCamera( clientName, clientUid, videoSize, videoFrameRate, surface, timeBetweenFrameCaptureUs, storeMetaDataInVideoBuffers); } + +MPEG4Writer* AVFactory::CreateMPEG4Writer(int fd) { + return new MPEG4Writer(fd); +} + // ----- NO TRESSPASSING BEYOND THIS LINE ------ AVFactory::AVFactory() { } diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index d182a68..18df1fc 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -1743,7 +1743,7 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() { if (mOutputFormat == OUTPUT_FORMAT_WEBM) { writer = new WebmWriter(mOutputFd); } else { - writer = mp4writer = new MPEG4Writer(mOutputFd); + writer = mp4writer = AVFactory::get()->CreateMPEG4Writer(mOutputFd); } if (mVideoSource < VIDEO_SOURCE_LIST_END) { diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index f5e0fbf..24da000 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -1148,7 +1148,7 @@ off64_t MPEG4Writer::addSample_l(MediaBuffer *buffer) { return old_offset; } -static void StripStartcode(MediaBuffer *buffer) { +void MPEG4Writer::StripStartcode(MediaBuffer *buffer) { if (buffer->range_length() < 4) { return; } diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp index b13877d..798a855 100644 --- a/media/libstagefright/MediaMuxer.cpp +++ b/media/libstagefright/MediaMuxer.cpp @@ -35,6 +35,7 @@ #include #include #include +#include namespace android { @@ -42,7 +43,7 @@ MediaMuxer::MediaMuxer(int fd, OutputFormat format) : mFormat(format), mState(UNINITIALIZED) { if (format == OUTPUT_FORMAT_MPEG_4) { - mWriter = new MPEG4Writer(fd); + mWriter = AVFactory::get()->CreateMPEG4Writer(fd); } else if (format == OUTPUT_FORMAT_WEBM) { mWriter = new WebmWriter(fd); } -- cgit v1.1 From 9fd0a690245e0a87592e5578397bc46b5af6e473 Mon Sep 17 00:00:00 2001 From: Li Sun Date: Wed, 28 Oct 2015 14:02:17 +0800 Subject: rtsp: keep video damaged access unit to enhance fault tolerance Make RTSPSource to accept some video damaged access units to enhance fault tolerance. Disable this change as default. add the property to enable it such as: "adb shell setprop rtsp.video.keep-damaged-au video/3gpp" for H263 "adb shell setprop rtsp.video.keep-damaged-au video/avc" for H264 Change-Id: I3b7fb4b098aba5daf149cf36dab7e9380c6d2f69 --- .../libmediaplayerservice/nuplayer/RTSPSource.cpp | 32 ++++++++++++++++++++-- media/libmediaplayerservice/nuplayer/RTSPSource.h | 4 +++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 35567a5..4962520 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -24,6 +24,7 @@ #include "MyHandler.h" #include "SDPLoader.h" +#include #include #include #include @@ -32,6 +33,7 @@ namespace android { const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs +const uint32_t kMaxNumKeepDamagedAccessUnits = 30; NuPlayer::RTSPSource::RTSPSource( const sp ¬ify, @@ -54,7 +56,10 @@ NuPlayer::RTSPSource::RTSPSource( mBuffering(false), mSeekGeneration(0), mEOSTimeoutAudio(0), - mEOSTimeoutVideo(0) { + mEOSTimeoutVideo(0), + mVideoTrackIndex(-1), + mKeepDamagedAccessUnits(false), + mNumKeepDamagedAccessUnits(0) { if (headers) { mExtraHeaders = *headers; @@ -433,11 +438,22 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp &msg) { sp accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); + bool isVideo = trackIndex == (size_t)mVideoTrackIndex; int32_t damaged; if (accessUnit->meta()->findInt32("damaged", &damaged) && damaged) { - ALOGI("dropping damaged access unit."); - break; + if (isVideo && mKeepDamagedAccessUnits + && mNumKeepDamagedAccessUnits < kMaxNumKeepDamagedAccessUnits) { + ALOGI("keep a damaged access unit."); + ++mNumKeepDamagedAccessUnits; + } else { + ALOGI("dropping damaged access unit."); + break; + } + } else { + if (isVideo) { + mNumKeepDamagedAccessUnits = 0; + } } if (mTSParser != NULL) { @@ -613,6 +629,16 @@ void NuPlayer::RTSPSource::onConnected() { bool isAudio = !strncasecmp(mime, "audio/", 6); bool isVideo = !strncasecmp(mime, "video/", 6); + if (isVideo) { + mVideoTrackIndex = i; + char value[PROPERTY_VALUE_MAX]; + if (property_get("rtsp.video.keep-damaged-au", value, NULL) + && !strcasecmp(mime, value)) { + ALOGV("enable to keep damaged au for %s", mime); + mKeepDamagedAccessUnits = true; + } + } + TrackInfo info; info.mTimeScale = timeScale; info.mRTPTime = 0; diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 6438a1e..c431174 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -118,6 +118,10 @@ private: sp mSeekReplyID; + int32_t mVideoTrackIndex; + bool mKeepDamagedAccessUnits; + uint32_t mNumKeepDamagedAccessUnits; + sp getSource(bool audio); void onConnected(); -- cgit v1.1 From 02d9acdc44c96db48f28e79fd60cfbfe8e6ddfd9 Mon Sep 17 00:00:00 2001 From: Manikanta Sivapala Date: Mon, 21 Dec 2015 15:30:51 +0530 Subject: nuplayer: Reverting GenericSource changes done for STA integration - Remove Virtual for SetDataSource() Change-Id: Ie8502297376f6663a38f95195ff8329b7a42dcb9 --- media/libmediaplayerservice/nuplayer/GenericSource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 9f8556e..5deb61e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -42,7 +42,7 @@ class WVMExtractor; struct NuPlayer::GenericSource : public NuPlayer::Source { GenericSource(const sp ¬ify, bool uidValid, uid_t uid); - virtual status_t setDataSource( + status_t setDataSource( const sp &httpService, const char *url, const KeyedVector *headers); -- cgit v1.1 From 0d34354e3e6e70ecce4cbef30d7dc6a1b9bcf328 Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Thu, 19 Nov 2015 13:49:18 +0800 Subject: audio: QTI resampler supports for 32 bit input format Configure QTI resampler as 32 bit input format to avoid losing precision. audioflinger: add channel count check to use QTI resampler Change-Id: I8f76dd82b72a0dd8b77343e77e0d0545e1be2114 CRs-Fixed: 940287 Change-Id: I7e1b8582cd6bb106ab0bd25f9bc1bd9e4092318b --- services/audioflinger/AudioMixer.cpp | 3 ++- services/audioflinger/AudioResamplerQTI.cpp | 21 +++++++++++++-------- services/audioflinger/AudioResamplerQTI.h | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 806eaf1..bb9d4e5 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -781,7 +781,8 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam #ifdef QTI_RESAMPLER if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) && (trackSampleRate > devSampleRate * 2) && - ((devSampleRate == 48000)||(devSampleRate == 44100))) { + ((devSampleRate == 48000)||(devSampleRate == 44100)) && + (resamplerChannelCount <= 2)) { quality = AudioResampler::QTI_QUALITY; } #endif diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp index 44b741e..0d57e09 100644 --- a/services/audioflinger/AudioResamplerQTI.cpp +++ b/services/audioflinger/AudioResamplerQTI.cpp @@ -51,8 +51,9 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, { int16_t vl = mVolume[0]; int16_t vr = mVolume[1]; - int16_t *pBuf; + int32_t *pBuf; + int64_t tempL, tempR; size_t inFrameRequest; size_t inFrameCount = getNumInSample(outFrameCount); size_t index = 0; @@ -74,7 +75,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, if(mResamplerOutBuf) { delete [] mResamplerOutBuf; } - mTmpBuf = new int16_t[inFrameRequest + 16]; + mTmpBuf = new int32_t[inFrameRequest + 16]; mResamplerOutBuf = new int32_t[out_count]; } @@ -95,7 +96,7 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount) { provider->releaseBuffer(&mBuffer); @@ -121,8 +122,8 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, goto resample_exit; } - mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); - pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++)); + mTmpBuf[index] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); + pBuf[index++] = clampq4_27_from_float(*((float *)mBuffer.raw + frameIndex++)); if (frameIndex >= mBuffer.frameCount * 2) { provider->releaseBuffer(&mBuffer); } @@ -133,8 +134,12 @@ size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount, resample_exit: for (int i = 0; i < out_count; i += 2) { - fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl); - fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr); + // Multiplying q4.27 data with u4.12 gain could result in 39 fractional bit data(27+12) + // To get back the 27 fractional bit format output data, do right shift by 12 + tempL = (int64_t)mResamplerOutBuf[i] * vl; + tempR = (int64_t)mResamplerOutBuf[i+1] * vr; + fout[i] += float_from_q4_27((int32_t)(tempL>>12)); + fout[i+1] += float_from_q4_27((int32_t)(tempR>>12)); } mFrameIndex = frameIndex; @@ -151,7 +156,7 @@ void AudioResamplerQTI::setSampleRate(int32_t inSampleRate) void AudioResamplerQTI::init() { - QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate); + QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate, 1/*32bit in*/); } size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount) diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h index 0b30a9f..1cf93fc 100644 --- a/services/audioflinger/AudioResamplerQTI.h +++ b/services/audioflinger/AudioResamplerQTI.h @@ -35,7 +35,7 @@ public: size_t getNumInSample(size_t outFrameCount); int16_t *mState; - int16_t *mTmpBuf; + int32_t *mTmpBuf; int32_t *mResamplerOutBuf; size_t mFrameIndex; size_t stateSize; -- cgit v1.1 From 0ecd6fb627dabf286b7742862e25a592bc1f606c Mon Sep 17 00:00:00 2001 From: Abhishek Kondaveeti Date: Tue, 5 Jan 2016 18:06:15 +0530 Subject: cameraservice: Run HAL3 in Non ZSL mode ZSL mode is not working on HAL3 due to camera backend failures. Run HAL3 forcefully in Non zsl mode till the problem in camera backend fixed. This change will be reverted once the backend issue is fixed. CRs-Fixed: 956182 Change-Id: I1dfcda8eb0fe5cd2d9be6cb2e103f5fd84955ecb --- services/camera/libcameraservice/api1/client2/Parameters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 44447b4..4df8361 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -910,7 +910,7 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) { } else { zslMode = true; } - + zslMode = false; ALOGI("%s: zslMode: %d slowJpegMode %d", __FUNCTION__, zslMode, slowJpegMode); lightFx = LIGHTFX_NONE; -- cgit v1.1 From f888cedf170f6d3cc060cc14ad9c56918f3a03c3 Mon Sep 17 00:00:00 2001 From: xiaoqiny Date: Tue, 13 Jan 2015 17:59:04 +0800 Subject: libstagefright: handle error when B-frame is sent to MPEG4Writer Without this patch, writing B-frame to MediaMuxer will be blocked and cannot return a result. This may cause an endless progress bar shown in gallery when triming or muting some videos. Change-Id: Ib9f902a57da470c0357ec68aab00a35fbb26fb77 CRs-Fixed: 521005 --- include/media/stagefright/MediaAdapter.h | 4 ++++ include/media/stagefright/MediaBuffer.h | 1 + include/media/stagefright/MediaSource.h | 1 + media/libstagefright/MPEG4Writer.cpp | 4 +++- media/libstagefright/MediaAdapter.cpp | 18 ++++++++++++++++-- 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/media/stagefright/MediaAdapter.h b/include/media/stagefright/MediaAdapter.h index 369fce6..8622546 100644 --- a/include/media/stagefright/MediaAdapter.h +++ b/include/media/stagefright/MediaAdapter.h @@ -56,6 +56,8 @@ public: // deep copy, such that after pushBuffer return, the buffer can be re-used. status_t pushBuffer(MediaBuffer *buffer); + virtual void notifyError(status_t err); + private: Mutex mAdapterLock; // Make sure the read() wait for the incoming buffer. @@ -68,6 +70,8 @@ private: bool mStarted; sp mOutputFormat; + status_t mStatus; + DISALLOW_EVIL_CONSTRUCTORS(MediaAdapter); }; diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h index c8a50e8..5ab266f 100644 --- a/include/media/stagefright/MediaBuffer.h +++ b/include/media/stagefright/MediaBuffer.h @@ -93,6 +93,7 @@ protected: private: friend class MediaBufferGroup; friend class OMXDecoder; + friend class MediaAdapter; // For use by OMXDecoder, reference count must be 1, drop reference // count to 0 without signalling the observer. diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index a653db9..7ab5f62 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -59,6 +59,7 @@ struct MediaSource : public virtual RefBase { virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL) = 0; + virtual void notifyError(status_t) {} // Options that modify read() behaviour. The default is to // a) not request a seek // b) not be late, i.e. lateness_us = 0 diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 24da000..6a8664e 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -2452,7 +2452,9 @@ status_t MPEG4Writer::Track::threadEntry() { ALOGE("timestampUs %" PRId64 " < lastTimestampUs %" PRId64 " for %s track", timestampUs, lastTimestampUs, trackName); copy->release(); - return UNKNOWN_ERROR; + err = UNKNOWN_ERROR; + mSource->notifyError(err); + return err; } // if the duration is different for this sample, see if it is close enough to the previous diff --git a/media/libstagefright/MediaAdapter.cpp b/media/libstagefright/MediaAdapter.cpp index d680e0c..ec4550f 100644 --- a/media/libstagefright/MediaAdapter.cpp +++ b/media/libstagefright/MediaAdapter.cpp @@ -27,7 +27,8 @@ namespace android { MediaAdapter::MediaAdapter(const sp &meta) : mCurrentMediaBuffer(NULL), mStarted(false), - mOutputFormat(meta) { + mOutputFormat(meta), + mStatus(OK) { } MediaAdapter::~MediaAdapter() { @@ -51,6 +52,9 @@ status_t MediaAdapter::stop() { // If stop() happens immediately after a pushBuffer(), we should // clean up the mCurrentMediaBuffer if (mCurrentMediaBuffer != NULL) { + mCurrentMediaBuffer->setObserver(this); + mCurrentMediaBuffer->claim(); + mCurrentMediaBuffer->setObserver(0); mCurrentMediaBuffer->release(); mCurrentMediaBuffer = NULL; } @@ -113,13 +117,23 @@ status_t MediaAdapter::pushBuffer(MediaBuffer *buffer) { ALOGE("pushBuffer called before start"); return INVALID_OPERATION; } + if (mStatus != OK) { + ALOGE("pushBuffer called when MediaAdapter in error status"); + return mStatus; + } mCurrentMediaBuffer = buffer; mBufferReadCond.signal(); ALOGV("wait for the buffer returned @ pushBuffer! %p", buffer); mBufferReturnedCond.wait(mAdapterLock); - return OK; + return mStatus; +} + +void MediaAdapter::notifyError(status_t err) { + Mutex::Autolock autoLock(mAdapterLock); + mStatus = err; + mBufferReturnedCond.signal(); } } // namespace android -- cgit v1.1 From 8a69897a5a6a461e9c564dbab88bf966ededb55e Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Wed, 23 Dec 2015 17:56:47 -0800 Subject: libavextensions: Add LOG_NDEBUG define LOG_NDEBUG is inherited indirectly from both MyHandler.h & Log.h if no LOG_NDEBUG is defined locally within AVMediaServiceUtils. Add a local definition to keep debug usage for this file straightforward. Change-Id: I878cdc747e8349e937b13dd27c738d45f99dee0a --- media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp index 0e42367..5306a39 100644 --- a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 - 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013 - 2016, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,6 +28,7 @@ */ #define LOG_TAG "AVMediaServiceUtils" +//#define LOG_NDEBUG 0 #include #include -- cgit v1.1 From d27aa05a1e160badde0ae4ff9b09c72b1d688371 Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Wed, 23 Dec 2015 17:54:33 -0800 Subject: frameworks/av: Fix LOG_NDEBUG compilation issues Fix compilation issues that appear when enabling LOG_NDEBUG. Change-Id: I87e9e5ac66157759dd6f521fab0dd346089a011a --- media/libmediaplayerservice/nuplayer/StreamingSource.cpp | 2 ++ media/libstagefright/rtsp/MyHandler.h | 2 ++ services/audioflinger/FastCapture.cpp | 1 + services/audioflinger/FastCaptureDumpState.cpp | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index 136eda5..b9c915e 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -18,6 +18,8 @@ #define LOG_TAG "StreamingSource" #include +#include + #include "StreamingSource.h" #include "ATSParser.h" diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 7290ee2..70063b1 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -18,7 +18,9 @@ #define MY_HANDLER_H_ +#ifndef LOG_NDEBUG //#define LOG_NDEBUG 0 +#endif #ifndef LOG_TAG #define LOG_TAG "MyHandler" diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp index 2493fb7..7c8a25f 100644 --- a/services/audioflinger/FastCapture.cpp +++ b/services/audioflinger/FastCapture.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "AudioFlinger.h" #include "FastCapture.h" namespace android { diff --git a/services/audioflinger/FastCaptureDumpState.cpp b/services/audioflinger/FastCaptureDumpState.cpp index 53eeba5..de4a6db 100644 --- a/services/audioflinger/FastCaptureDumpState.cpp +++ b/services/audioflinger/FastCaptureDumpState.cpp @@ -15,7 +15,7 @@ */ #define LOG_TAG "FastCaptureDumpState" -//define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #include "Configuration.h" #include -- cgit v1.1 From 3fe0fe6a389cfd63fac0c8e32f31001d3d95bd83 Mon Sep 17 00:00:00 2001 From: Sharad Sangle Date: Thu, 12 Nov 2015 13:18:04 +0530 Subject: nuplayer: update anchor time for offload usecase In non-offload usecase, mAnchorTmeMediaUs is updated for every audio FillBufferDone. Added the same logic for offload case, otherwise video updates max media duration as ZERO, for clips which have small audio data, and all the buffers are sent to DSP before first video buffer is processed at NuPlayerRenderer level Change-Id: Ib6e0f251207c87ad1525041d07187cef91f4dda5 --- media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index d888cf4..156ad9b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -780,6 +780,7 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) { mAudioFirstAnchorTimeMediaUs + getPlayedOutAudioDurationUs(nowUs); // we don't know how much data we are queueing for offloaded tracks. mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX); + mAnchorTimeMediaUs = nowMediaUs; } // for non-offloaded audio, we need to compute the frames written because -- cgit v1.1 From 7262eae1402f3256606ad1776e35c4a08ed267c3 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Thu, 25 Feb 2016 13:48:33 +0530 Subject: nuplayer: ignore openAudioSink while waiting for teardown completion - AudioSink is reopened on AudioTearDown event as well as on decoder output format change. These events are from different contexts, independent of each other and can occur concurrently, doing set of thread-unsafe operations on audioSink, which sometimes may result in fatal error. - Any request to openSink, after teardown event is received but before its completed, is redundant since once teardown is completed sink is anyway going to be opened again. Also ignoring sink reopen while in teardown would avoid concurrent processing of thread-unsafe operations on audioSink. - Update nuplayer to prevent reopening of sink while teardown is still going on. CRs-Fixed: 978013 Change-Id: Ieb3825f133c2099e07d6e92ef101dd5156af8a20 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 1 + .../nuplayer/NuPlayerRenderer.cpp | 28 ++++++++++++++++++---- .../nuplayer/NuPlayerRenderer.h | 5 +++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 1835101..2ffd184 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1157,6 +1157,7 @@ void NuPlayer::onMessageReceived(const sp &msg) { mRenderer->flush( false /* audio */, false /* notifyComplete */); } + mRenderer->signalAudioTearDownComplete(); int64_t positionUs; if (!msg->findInt64("positionUs", &positionUs)) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 156ad9b..aa9842b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -127,7 +127,7 @@ NuPlayer::Renderer::Renderer( mAudioRenderingStartGeneration(0), mRenderingDataDelivered(false), mAudioOffloadPauseTimeoutGeneration(0), - mAudioTornDown(false), + mAudioTearingDown(false), mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER), mTotalBuffersQueued(0), @@ -626,6 +626,12 @@ void NuPlayer::Renderer::onMessageReceived(const sp &msg) { break; } + case kWhatAudioTearDownComplete: + { + onAudioTearDownComplete(); + break; + } + case kWhatAudioOffloadPauseTimeout: { int32_t generation; @@ -837,7 +843,7 @@ void NuPlayer::Renderer::drainAudioQueueUntilLastEOS() { bool NuPlayer::Renderer::onDrainAudioQueue() { // do not drain audio during teardown as queued buffers may be invalid. - if (mAudioTornDown) { + if (mAudioTearingDown) { return false; } // TODO: This call to getPosition checks if AudioTrack has been created @@ -1718,10 +1724,10 @@ int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) { } void NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) { - if (mAudioTornDown) { + if (mAudioTearingDown) { return; } - mAudioTornDown = true; + mAudioTearingDown = true; int64_t currentPositionUs; sp notify = mNotify->dup(); @@ -1761,6 +1767,11 @@ status_t NuPlayer::Renderer::onOpenAudioSink( bool isStreaming) { ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)", offloadOnly, offloadingAudio()); + + if (mAudioTearingDown) { + ALOGW("openAudioSink: not opening now!, would happen after teardown"); + return OK; + } bool audioSinkChanged = false; int32_t numChannels; @@ -1958,7 +1969,6 @@ status_t NuPlayer::Renderer::onOpenAudioSink( if (audioSinkChanged) { onAudioSinkChanged(); } - mAudioTornDown = false; return OK; } @@ -1968,5 +1978,13 @@ void NuPlayer::Renderer::onCloseAudioSink() { mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; } +void NuPlayer::Renderer::signalAudioTearDownComplete() { + (new AMessage(kWhatAudioTearDownComplete, this))->post(); +} + +void NuPlayer::Renderer::onAudioTearDownComplete() { + mAudioTearingDown = false; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index e872227..a84e673 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -83,6 +83,7 @@ struct NuPlayer::Renderer : public AHandler { bool *isOffloaded, bool isStreaming); void closeAudioSink(); + void signalAudioTearDownComplete(); enum { kWhatEOS = 'eos ', @@ -92,6 +93,7 @@ struct NuPlayer::Renderer : public AHandler { kWhatMediaRenderingStart = 'mdrd', kWhatAudioTearDown = 'adTD', kWhatAudioOffloadPauseTimeout = 'aOPT', + kWhatAudioTearDownComplete = 'aTDC', }; enum AudioTearDownReason { @@ -184,7 +186,7 @@ protected: int64_t mLastPositionUpdateUs; int32_t mAudioOffloadPauseTimeoutGeneration; - bool mAudioTornDown; + bool mAudioTearingDown; audio_offload_info_t mCurrentOffloadInfo; struct PcmInfo { @@ -257,6 +259,7 @@ protected: uint32_t flags, bool isStreaming); void onCloseAudioSink(); + void onAudioTearDownComplete(); void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0); void notifyFlushComplete(bool audio); -- cgit v1.1 From 51b3174ac272f146f7a4fb502103d8130b6f4703 Mon Sep 17 00:00:00 2001 From: Surajit Podder Date: Thu, 25 Feb 2016 20:23:24 +0530 Subject: video: Use boot clock for recording start time Camera HAL3 uses boot time for buffer timestamp, rather than system monotonic time. This leads to issues as framework uses system monotonic time as reference start time for timestamp adjustment. Add change to use boot time for reference start time. CRs-Fixed: 946735 Change-Id: Id0af9c8aed1a983095275ac03f7f59abc31594cc --- include/media/stagefright/MetaData.h | 1 + media/libmediaplayerservice/StagefrightRecorder.cpp | 2 ++ media/libstagefright/CameraSource.cpp | 10 +++++++++- media/libstagefright/MPEG4Writer.cpp | 10 ++++++++++ media/libstagefright/MediaCodecSource.cpp | 10 +++++++++- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index 2a3df22..66e7d63 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -68,6 +68,7 @@ enum { kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) kKeyTime = 'time', // int64_t (usecs) + kKeyTimeBoot = 'timb', // int64_t (usecs) kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs) kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) kKeyTargetTime = 'tarT', // int64_t (usecs) diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 18df1fc..442dba1 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -1814,6 +1814,8 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() { void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp *meta) { int64_t startTimeUs = systemTime() / 1000; (*meta)->setInt64(kKeyTime, startTimeUs); + int64_t startTimeBootUs = systemTime(SYSTEM_TIME_BOOTTIME) / 1000; + (*meta)->setInt64(kKeyTimeBoot, startTimeBootUs); (*meta)->setInt32(kKeyFileType, mOutputFormat); (*meta)->setInt32(kKeyBitRate, mTotalBitRate); if (mMovieTimeScale > 0) { diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index e2ad924..64e7f90 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -701,7 +701,15 @@ status_t CameraSource::start(MetaData *meta) { if (meta) { int64_t startTimeUs; - if (meta->findInt64(kKeyTime, &startTimeUs)) { + + auto key = kKeyTimeBoot; + char value[PROPERTY_VALUE_MAX]; + if (property_get("media.camera.ts.monotonic", value, "0") && + atoi(value)) { + key = kKeyTime; + } + + if (meta->findInt64(key, &startTimeUs)) { mStartTimeUs = startTimeUs; } diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 6a8664e..16da3eb 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -1837,9 +1837,16 @@ status_t MPEG4Writer::Track::start(MetaData *params) { } int64_t startTimeUs; + if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { startTimeUs = 0; } + + int64_t startTimeBootUs; + if (params == NULL || !params->findInt64(kKeyTimeBoot, &startTimeBootUs)) { + startTimeBootUs = 0; + } + mStartTimeRealUs = startTimeUs; int32_t rotationDegrees; @@ -1850,6 +1857,7 @@ status_t MPEG4Writer::Track::start(MetaData *params) { initTrackingProgressStatus(params); sp meta = new MetaData; + if (mOwner->isRealTimeRecording() && mOwner->numTracks() > 1) { /* * This extra delay of accepting incoming audio/video signals @@ -1865,10 +1873,12 @@ status_t MPEG4Writer::Track::start(MetaData *params) { startTimeOffsetUs = kInitialDelayTimeUs; } startTimeUs += startTimeOffsetUs; + startTimeBootUs += startTimeOffsetUs; ALOGI("Start time offset: %" PRId64 " us", startTimeOffsetUs); } meta->setInt64(kKeyTime, startTimeUs); + meta->setInt64(kKeyTimeBoot, startTimeBootUs); status_t err = mSource->start(meta.get()); if (err != OK) { diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index adbde54..b15ee64 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace android { @@ -663,8 +664,15 @@ status_t MediaCodecSource::onStart(MetaData *params) { status_t err = OK; if (mFlags & FLAG_USE_SURFACE_INPUT) { + auto key = kKeyTimeBoot; + char value[PROPERTY_VALUE_MAX]; + if (property_get("media.camera.ts.monotonic", value, "0") && + atoi(value)) { + key = kKeyTime; + } + int64_t startTimeUs; - if (!params || !params->findInt64(kKeyTime, &startTimeUs)) { + if (!params || !params->findInt64(key, &startTimeUs)) { startTimeUs = -1ll; } resume(startTimeUs); -- cgit v1.1 From 48827966831de92e0190f96820fa6e7d9e149b50 Mon Sep 17 00:00:00 2001 From: Manikanta Kanamarlapudi Date: Tue, 23 Feb 2016 17:25:40 +0530 Subject: nuplayer: Seek to valid position in setVideoSurface - If flush is called on both A/V tracks and video decoder is not yet created, In offload case the first audio buffer will get flush and audio playback starts from timestamp of second buffer, where as video playback starts from zero leads to AV sync issue in start and cause framedrops. - Call seek to current position to align the Audio and Video tracks. Seek to zero if playback has not yet started. Change-Id: I4f75d0aa908714ad292f348fa8bf7aa5f837f8d7 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 2ffd184..ef2e6ec 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -681,10 +681,9 @@ void NuPlayer::onMessageReceived(const sp &msg) { // If the video decoder is not set (perhaps audio only in this case) // do not perform a seek as it is not needed. int64_t currentPositionUs = 0; - if (getCurrentPosition(¤tPositionUs) == OK) { - mDeferredActions.push_back( - new SeekAction(currentPositionUs)); - } + getCurrentPosition(¤tPositionUs); + mDeferredActions.push_back( + new SeekAction(currentPositionUs)); } // If there is a new surface texture, instantiate decoders -- cgit v1.1 From 20f078273de062f24b603e12197667b47ab20d05 Mon Sep 17 00:00:00 2001 From: Leena Winterrowd Date: Tue, 26 Jan 2016 13:41:38 -0800 Subject: stagefright: Fix CLANG compilation for AMR decoder Fix invalid type in error log's format string. Change-Id: I26aabfcdc1a03c0a7d9cd10fb3b39a660a9be03a --- media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index f8316fd..1a4ed55 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -353,7 +353,7 @@ void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) { size_t frameSize = getFrameSize(mode); if (inHeader->nFilledLen < frameSize) { - ALOGE("Filled length vs frameSize %u vs %lu. Corrupt clip?", + ALOGE("Filled length vs frameSize %u vs %zu. Corrupt clip?", inHeader->nFilledLen, frameSize); notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); -- cgit v1.1 From 5153cdc35e816a2224da1dac0e4d316bf847473d Mon Sep 17 00:00:00 2001 From: Zhou Song Date: Tue, 22 Mar 2016 16:13:09 +0800 Subject: libmedia: Initialize mState/mActive value to avoid possible crash If track creation fails on server side, mState/mActive is left unitialized. After this a crash can happen when track stop() is called because of a reference to a NULL object. Initialize mState/mActive to specific value in initialized list of track constructor. Change-Id: If8c3611e3229c0c1b14b81285e07b9357fec7658 CRs-Fixed: 992608 --- media/libmedia/AudioRecord.cpp | 6 +++--- media/libmedia/AudioTrack.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index fc35a4c..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 || 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; -- cgit v1.1 From c38d4f266ee016950bff2e08a8987e84f1d6461e Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Fri, 15 Apr 2016 10:24:22 -0700 Subject: frameworks/av: Fix video recording breaks Change Id0af9c8aed1a983095275ac03f7f59abc31594cc using boot time for video recording start time as default, but it is specific on devices using qcom camera HAL3 and it breaks all devices using camera HAL1. Fix by changing the default behaviour when property media.camera.ts.monotonic is not set. And newer devices such as 8996 might need to setprop media.camera.ts.monotonic 0 in order to work properly when using camera HAL3. Change-Id: Iee07ed1147713a6397fff43e3bbd4f4ed08b56b7 --- media/libstagefright/CameraSource.cpp | 9 ++++----- media/libstagefright/MediaCodecSource.cpp | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 64e7f90..1f26872 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -702,11 +702,10 @@ status_t CameraSource::start(MetaData *meta) { if (meta) { int64_t startTimeUs; - auto key = kKeyTimeBoot; - char value[PROPERTY_VALUE_MAX]; - if (property_get("media.camera.ts.monotonic", value, "0") && - atoi(value)) { - key = kKeyTime; + auto key = kKeyTime; + if (property_get_bool("persist.camera.HAL3.enabled", true) && + !property_get_bool("media.camera.ts.monotonic", true)) { + key = kKeyTimeBoot; } if (meta->findInt64(key, &startTimeUs)) { diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index b15ee64..94427ef 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -664,11 +664,10 @@ status_t MediaCodecSource::onStart(MetaData *params) { status_t err = OK; if (mFlags & FLAG_USE_SURFACE_INPUT) { - auto key = kKeyTimeBoot; - char value[PROPERTY_VALUE_MAX]; - if (property_get("media.camera.ts.monotonic", value, "0") && - atoi(value)) { - key = kKeyTime; + auto key = kKeyTime; + if (property_get_bool("persist.camera.HAL3.enabled", true) && + !property_get_bool("media.camera.ts.monotonic", true)) { + key = kKeyTimeBoot; } int64_t startTimeUs; -- cgit v1.1 From 489c9fb62f02e1d23d6d6c89b22f7d19c596e65e Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 15 Apr 2016 01:21:35 -0700 Subject: audiopolicy: Update legacy policy for session callbacks Change-Id: Id6f24195721a48dc5a0d3a7ff7fbee2bd8614128 --- .../service/AudioPolicyInterfaceImplLegacy.cpp | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index 318c6d2..e3d69ba 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -147,6 +147,24 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream, format, channelMask, flags, offloadInfo); } +status_t AudioPolicyService::addOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, + uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + ALOGV("addOutputSessionEffects()"); + return mOutputCommandThread->addOutputSessionEffectsCommand( + output, stream, session, flags, channelMask, uid); +} + status_t AudioPolicyService::startOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session) @@ -172,18 +190,6 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output, return NO_INIT; } ALOGV("doStartOutput()"); - spaudioPolicyEffects; - { - Mutex::Autolock _l(mLock); - audioPolicyEffects = mAudioPolicyEffects; - } - if (audioPolicyEffects != 0) { - // create audio processors according to stream - status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); - if (status != NO_ERROR && status != ALREADY_EXISTS) { - ALOGW("Failed to add effects on session %d", session); - } - } Mutex::Autolock _l(mLock); return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session); @@ -609,6 +615,14 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, if (*output == AUDIO_IO_HANDLE_NONE) { return INVALID_OPERATION; } + + Mutex::Autolock _l(mLock); + sp audioPolicyEffects; + audioPolicyEffects = mAudioPolicyEffects; + if (audioPolicyEffects != 0) { + addOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); + } + return NO_ERROR; } -- cgit v1.1 From 32ef0556ae58ff6b7c6fe6fb0a17d3ff7f01de31 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 19 Apr 2016 02:41:45 -0700 Subject: audiopolicy: Clean up the mess * Since we're not using the policy directly to auto-attach, let's clean it up and remove the unused stuff. * Also fixes notifications for session release. This reverts commit 47f8c7303c9e2054f1492b02b6c7472385c52dc9. Change-Id: Ibe65f427773c6ef012dde4f289d10e4089c094ea --- .../audiopolicy/service/AudioPolicyEffects.cpp | 42 +----------- services/audiopolicy/service/AudioPolicyEffects.h | 5 -- .../service/AudioPolicyInterfaceImpl.cpp | 33 ++++------ .../service/AudioPolicyInterfaceImplLegacy.cpp | 38 ++++------- .../audiopolicy/service/AudioPolicyService.cpp | 76 ---------------------- services/audiopolicy/service/AudioPolicyService.h | 41 ------------ 6 files changed, 27 insertions(+), 208 deletions(-) diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index bd1cc33..6a43bea 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -275,10 +275,11 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, procDesc->setProcessorEnabled(true); } + return status; } -status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, +status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t /* output */, audio_stream_type_t stream, int session, audio_output_flags_t flags, @@ -289,12 +290,6 @@ status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, } ALOGV("doAddOutputSessionEffects()"); - // create audio processors according to stream - status_t status = addOutputSessionEffects(output, stream, session); - if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { - ALOGW("Failed to add effects on session %d", session); - } - // notify listeners mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, flags, channelMask, uid, true); @@ -319,42 +314,9 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu } EffectVector *procDesc = mOutputSessions.valueAt(index); - - // just in case it already has a death wish - if (procDesc->mRefCount == 0) { - return NO_ERROR; - } - procDesc->mRefCount--; ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount); - - if (procDesc->mRefCount == 0) { - mAudioPolicyService->releaseOutputSessionEffectsDelayed( - output, stream, audioSession, 10000); - } - - return status; -} - -status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - int audioSession) -{ - status_t status = NO_ERROR; - (void) output; // argument not used for now - - Mutex::Autolock _l(mLock); - ssize_t index = mOutputSessions.indexOfKey(audioSession); - if (index < 0) { - ALOGV("doReleaseOutputSessionEffects: no output processing was attached to this stream"); - return NO_ERROR; - } - - EffectVector *procDesc = mOutputSessions.valueAt(index); - ALOGV("doReleaseOutputSessionEffects(): session: %d, refCount: %d", - audioSession, procDesc->mRefCount); - if (procDesc->mRefCount == 0) { procDesc->setProcessorEnabled(false); procDesc->mEffects.clear(); diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 6364e40..1c251e0 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -86,11 +86,6 @@ public: audio_stream_type_t stream, int audioSession); - // For deferred release - status_t doReleaseOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - int audioSession); - status_t doAddOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession, diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 51af20b..96bc4c7 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -182,30 +182,12 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, } if (audioPolicyEffects != 0) { - addOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); + audioPolicyEffects->doAddOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); } return status; } -status_t AudioPolicyService::addOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid) -{ - if (uint32_t(stream) >= AUDIO_STREAM_CNT) { - return BAD_VALUE; - } - if (mAudioPolicyManager == NULL) { - return NO_INIT; - } - ALOGV("addOutputSessionEffects()"); - return mOutputCommandThread->addOutputSessionEffectsCommand( - output, stream, session, flags, channelMask, uid); -} - status_t AudioPolicyService::startOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session) @@ -231,8 +213,19 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output, return NO_INIT; } ALOGV("doStartOutput()"); + spaudioPolicyEffects; + { + Mutex::Autolock _l(mLock); + audioPolicyEffects = mAudioPolicyEffects; + } + if (audioPolicyEffects != 0) { + // create audio processors according to stream + status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); + if (status != NO_ERROR && status != ALREADY_EXISTS) { + ALOGW("Failed to add effects on session %d", session); + } + } Mutex::Autolock _l(mLock); - return mAudioPolicyManager->startOutput(output, stream, session); } diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index e3d69ba..318c6d2 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -147,24 +147,6 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream, format, channelMask, flags, offloadInfo); } -status_t AudioPolicyService::addOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid) -{ - if (uint32_t(stream) >= AUDIO_STREAM_CNT) { - return BAD_VALUE; - } - if (mAudioPolicyManager == NULL) { - return NO_INIT; - } - ALOGV("addOutputSessionEffects()"); - return mOutputCommandThread->addOutputSessionEffectsCommand( - output, stream, session, flags, channelMask, uid); -} - status_t AudioPolicyService::startOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session) @@ -190,6 +172,18 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output, return NO_INIT; } ALOGV("doStartOutput()"); + spaudioPolicyEffects; + { + Mutex::Autolock _l(mLock); + audioPolicyEffects = mAudioPolicyEffects; + } + if (audioPolicyEffects != 0) { + // create audio processors according to stream + status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session); + if (status != NO_ERROR && status != ALREADY_EXISTS) { + ALOGW("Failed to add effects on session %d", session); + } + } Mutex::Autolock _l(mLock); return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session); @@ -615,14 +609,6 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, if (*output == AUDIO_IO_HANDLE_NONE) { return INVALID_OPERATION; } - - Mutex::Autolock _l(mLock); - sp audioPolicyEffects; - audioPolicyEffects = mAudioPolicyEffects; - if (audioPolicyEffects != 0) { - addOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); - } - return NO_ERROR; } diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 0e871c2..eead3ac 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -366,13 +366,6 @@ void AudioPolicyService::binderDied(const wp& who) { IPCThreadState::self()->getCallingPid()); } -void AudioPolicyService::releaseOutputSessionEffectsDelayed( - audio_io_handle_t output, audio_stream_type_t stream, - audio_unique_id_t sessionId, int delayMs) -{ - mAudioCommandThread->releaseOutputSessionEffectsCommand(output, stream, sessionId, delayMs); -} - static bool tryLock(Mutex& mutex) { bool locked = false; @@ -658,35 +651,6 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() data->mFlags, data->mChannelMask, data->mUid, data->mAdded); mLock.lock(); } break; - case RELEASE_OUTPUT_SESSION_EFFECTS: { - ReleaseOutputSessionEffectsData *data = - (ReleaseOutputSessionEffectsData *)command->mParam.get(); - ALOGV("AudioCommandThread() processing release output session effects %d %d %d", - data->mOutput, data->mStream, data->mSessionId); - svc = mService.promote(); - if (svc == 0) { - break; - } - mLock.unlock(); - svc->mAudioPolicyEffects->doReleaseOutputSessionEffects( - data->mOutput, data->mStream, data->mSessionId); - mLock.lock(); - } break; - case ADD_OUTPUT_SESSION_EFFECTS: { - AddOutputSessionEffectsData *data = (AddOutputSessionEffectsData *)command->mParam.get(); - ALOGV("AudioCommandThread() processing add output session effects %d", - data->mOutput); - svc = mService.promote(); - if (svc == 0) { - break; - } - mLock.unlock(); - svc->mAudioPolicyEffects->doAddOutputSessionEffects( - data->mOutput, data->mStream, data->mSessionId, - data->mFlags, data->mChannelMask, data->mUid); - mLock.lock(); - }break; - default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); @@ -852,29 +816,6 @@ status_t AudioPolicyService::AudioCommandThread::startOutputCommand(audio_io_han return sendCommand(command); } -status_t AudioPolicyService::AudioCommandThread::addOutputSessionEffectsCommand(audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid) -{ - sp command = new AudioCommand(); - command->mCommand = ADD_OUTPUT_SESSION_EFFECTS; - sp data = new AddOutputSessionEffectsData(); - data->mOutput = output; - data->mStream = stream; - data->mSessionId = session; - data->mFlags = flags; - data->mChannelMask = channelMask; - data->mUid = uid; - command->mParam = data; - command->mWaitStatus = false; - ALOGV("AudioCommandThread() adding start output %d", output); - return sendCommand(command); -} - - void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session) @@ -1003,23 +944,6 @@ void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( sendCommand(command); } -void AudioPolicyService::AudioCommandThread::releaseOutputSessionEffectsCommand( - audio_io_handle_t output, audio_stream_type_t stream, - audio_unique_id_t sessionId, int delayMs) -{ - sp command = new AudioCommand(); - command->mCommand = RELEASE_OUTPUT_SESSION_EFFECTS; - ReleaseOutputSessionEffectsData *data = new ReleaseOutputSessionEffectsData(); - data->mOutput = output; - data->mStream = stream; - data->mSessionId = sessionId; - command->mParam = data; - ALOGV("AudioCommandThread() sending release output session effects (id=%d) for stream %d", - sessionId, stream); - sendCommand(command, delayMs); -} - - status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index 01e0e5e..bc2875d 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -204,13 +204,6 @@ public: virtual status_t setEffectSessionCallbacksEnabled(bool enabled); - virtual status_t addOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid); - status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -248,10 +241,6 @@ public: audio_output_flags_t flags, audio_channel_mask_t channelMask, uid_t uid, bool added); - void releaseOutputSessionEffectsDelayed(audio_io_handle_t output, - audio_stream_type_t stream, - audio_unique_id_t sessionId, - int delayMs); private: AudioPolicyService() ANDROID_API; @@ -286,8 +275,6 @@ private: SET_AUDIOPORT_CONFIG, DYN_POLICY_MIX_STATE_UPDATE, EFFECT_SESSION_UPDATE, - RELEASE_OUTPUT_SESSION_EFFECTS, - ADD_OUTPUT_SESSION_EFFECTS }; AudioCommandThread (String8 name, const wp& service); @@ -335,17 +322,6 @@ private: audio_output_flags_t flags, audio_channel_mask_t channelMask, uid_t uid, bool added); - void releaseOutputSessionEffectsCommand(audio_io_handle_t output, - audio_stream_type_t stream, - audio_unique_id_t sessionId, - int delayMs = 0); - status_t addOutputSessionEffectsCommand(audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid); - private: class AudioCommandData; @@ -452,23 +428,6 @@ private: bool mAdded; }; - class ReleaseOutputSessionEffectsData : public AudioCommandData { - public: - audio_io_handle_t mOutput; - audio_stream_type_t mStream; - audio_unique_id_t mSessionId; - }; - - class AddOutputSessionEffectsData : public AudioCommandData { - public: - audio_io_handle_t mOutput; - audio_stream_type_t mStream; - audio_session_t mSessionId; - audio_output_flags_t mFlags; - audio_channel_mask_t mChannelMask; - uid_t mUid; - }; - Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands -- cgit v1.1 From 295c883fe3105b19bcd0f9e07d54c6b589fc5bff Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 29 Feb 2016 12:47:20 -0800 Subject: DO NOT MERGE Verify OMX buffer sizes prior to access Bug: 27207275 Change-Id: I4412825d1ee233d993af0a67708bea54304ff62d --- media/libmedia/IOMX.cpp | 96 +++++++++++----- media/libstagefright/codecs/aacdec/SoftAAC2.cpp | 25 +++++ .../codecs/aacenc/SoftAACEncoder.cpp | 28 +++++ .../codecs/aacenc/SoftAACEncoder2.cpp | 28 +++++ media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp | 20 ++++ .../codecs/amrnb/enc/SoftAMRNBEncoder.cpp | 28 +++++ .../codecs/amrwbenc/SoftAMRWBEncoder.cpp | 28 +++++ .../codecs/avc/enc/SoftAVCEncoder.cpp | 16 +++ media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp | 30 ++++- .../codecs/flac/enc/SoftFlacEncoder.cpp | 26 +++++ media/libstagefright/codecs/g711/dec/SoftG711.cpp | 12 ++ media/libstagefright/codecs/gsm/dec/SoftGSM.cpp | 12 ++ .../codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp | 24 ++++ media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 16 +++ .../codecs/on2/enc/SoftVPXEncoder.cpp | 121 ++++++++++++++------- media/libstagefright/codecs/opus/dec/SoftOpus.cpp | 16 +++ media/libstagefright/codecs/raw/SoftRaw.cpp | 12 ++ .../codecs/vorbis/dec/SoftVorbis.cpp | 16 +++ media/libstagefright/include/SoftOMXComponent.h | 16 +++ .../libstagefright/omx/SimpleSoftOMXComponent.cpp | 8 ++ .../omx/SoftVideoDecoderOMXComponent.cpp | 30 +++++ 21 files changed, 536 insertions(+), 72 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 865d575..84925f1 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -18,6 +18,8 @@ #define LOG_TAG "IOMX" #include +#include + #include #include #include @@ -692,38 +694,70 @@ status_t BnOMX::onTransact( size_t size = data.readInt64(); - status_t err = NO_MEMORY; - void *params = calloc(size, 1); - if (params) { - err = data.read(params, size); - if (err != OK) { - android_errorWriteLog(0x534e4554, "26914474"); + status_t err = NOT_ENOUGH_DATA; + void *params = NULL; + size_t pageSize = 0; + size_t allocSize = 0; + if (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)", size); + 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 { - 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; + 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 && 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 + mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE); + 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(); + } } - - default: - TRESPASS(); } + } else { + ALOGE("couldn't map: %s", strerror(errno)); } } @@ -733,7 +767,9 @@ status_t BnOMX::onTransact( reply->write(params, size); } - free(params); + if (params) { + munmap(params, allocSize); + } params = NULL; return NO_ERROR; diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp index 965c55e..520ecb4 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp @@ -209,6 +209,10 @@ OMX_ERRORTYPE SoftAAC2::internalGetParameter( OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -244,6 +248,10 @@ OMX_ERRORTYPE SoftAAC2::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -284,6 +292,10 @@ OMX_ERRORTYPE SoftAAC2::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.aac", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -298,6 +310,10 @@ OMX_ERRORTYPE SoftAAC2::internalSetParameter( const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -318,6 +334,11 @@ OMX_ERRORTYPE SoftAAC2::internalSetParameter( { const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *aacPresParams = (const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *)params; + + if (!isValidOMXParam(aacPresParams)) { + return OMX_ErrorBadParameter; + } + // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure, // a value of -1 implies the parameter is not set by the application: // nMaxOutputChannels uses default platform properties, see configureDownmix() @@ -384,6 +405,10 @@ OMX_ERRORTYPE SoftAAC2::internalSetParameter( const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp index c6724c2..ab0a228 100644 --- a/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp +++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp @@ -154,6 +154,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalGetParameter( OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -174,6 +178,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalGetParameter( OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -198,6 +206,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -229,6 +241,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_encoder.aac", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -243,6 +259,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalSetParameter( const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -266,6 +286,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalSetParameter( OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -286,6 +310,10 @@ OMX_ERRORTYPE SoftAACEncoder::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp index 35aa883..e8dabed 100644 --- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp +++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp @@ -123,6 +123,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter( OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -143,6 +147,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter( OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -202,6 +210,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -233,6 +245,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_encoder.aac", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -247,6 +263,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalSetParameter( const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -270,6 +290,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalSetParameter( OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams = (OMX_AUDIO_PARAM_AACPROFILETYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -310,6 +334,10 @@ OMX_ERRORTYPE SoftAACEncoder2::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index 955309a..edf648d 100644 --- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp +++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp @@ -148,6 +148,10 @@ OMX_ERRORTYPE SoftAMR::internalGetParameter( OMX_AUDIO_PARAM_AMRTYPE *amrParams = (OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(amrParams)) { + return OMX_ErrorBadParameter; + } + if (amrParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -174,6 +178,10 @@ OMX_ERRORTYPE SoftAMR::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -207,6 +215,10 @@ OMX_ERRORTYPE SoftAMR::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (mMode == MODE_NARROW) { if (strncmp((const char *)roleParams->cRole, "audio_decoder.amrnb", @@ -229,6 +241,10 @@ OMX_ERRORTYPE SoftAMR::internalSetParameter( const OMX_AUDIO_PARAM_AMRTYPE *aacParams = (const OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(aacParams)) { + return OMX_ErrorBadParameter; + } + if (aacParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -241,6 +257,10 @@ OMX_ERRORTYPE SoftAMR::internalSetParameter( const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp index 9489457..aaa6731 100644 --- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp +++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp @@ -120,6 +120,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalGetParameter( OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -140,6 +144,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalGetParameter( OMX_AUDIO_PARAM_AMRTYPE *amrParams = (OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(amrParams)) { + return OMX_ErrorBadParameter; + } + if (amrParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -158,6 +166,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -188,6 +200,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_encoder.amrnb", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -202,6 +218,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter( const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -225,6 +245,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter( OMX_AUDIO_PARAM_AMRTYPE *amrParams = (OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(amrParams)) { + return OMX_ErrorBadParameter; + } + if (amrParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -252,6 +276,10 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp index 91a512d..9d50c4e 100644 --- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp +++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp @@ -155,6 +155,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalGetParameter( OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -175,6 +179,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalGetParameter( OMX_AUDIO_PARAM_AMRTYPE *amrParams = (OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(amrParams)) { + return OMX_ErrorBadParameter; + } + if (amrParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -196,6 +204,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -226,6 +238,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_encoder.amrwb", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -240,6 +256,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter( const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -263,6 +283,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter( OMX_AUDIO_PARAM_AMRTYPE *amrParams = (OMX_AUDIO_PARAM_AMRTYPE *)params; + if (!isValidOMXParam(amrParams)) { + return OMX_ErrorBadParameter; + } + if (amrParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -299,6 +323,10 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp index fa6ec40..cce6d15 100644 --- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp +++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp @@ -370,6 +370,10 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter( OMX_VIDEO_PARAM_BITRATETYPE *bitRate = (OMX_VIDEO_PARAM_BITRATETYPE *) params; + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + if (bitRate->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -384,6 +388,10 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter( OMX_VIDEO_PARAM_AVCTYPE *avcParams = (OMX_VIDEO_PARAM_AVCTYPE *)params; + if (!isValidOMXParam(avcParams)) { + return OMX_ErrorBadParameter; + } + if (avcParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -427,6 +435,10 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( OMX_VIDEO_PARAM_BITRATETYPE *bitRate = (OMX_VIDEO_PARAM_BITRATETYPE *) params; + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + if (bitRate->nPortIndex != 1 || bitRate->eControlRate != OMX_Video_ControlRateVariable) { return OMX_ErrorUndefined; @@ -441,6 +453,10 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( OMX_VIDEO_PARAM_AVCTYPE *avcType = (OMX_VIDEO_PARAM_AVCTYPE *)params; + if (!isValidOMXParam(avcType)) { + return OMX_ErrorBadParameter; + } + if (avcType->nPortIndex != 1) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp index 387d17d..e4e8fd7 100644 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp @@ -926,6 +926,10 @@ OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) OMX_VIDEO_PARAM_BITRATETYPE *bitRate = (OMX_VIDEO_PARAM_BITRATETYPE *)params; + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + if (bitRate->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -939,6 +943,10 @@ OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) { OMX_VIDEO_PARAM_AVCTYPE *avcParams = (OMX_VIDEO_PARAM_AVCTYPE *)params; + if (!isValidOMXParam(avcParams)) { + return OMX_ErrorBadParameter; + } + if (avcParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -976,14 +984,24 @@ OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR p switch (indexFull) { case OMX_IndexParamVideoBitrate: { - return internalSetBitrateParams( - (const OMX_VIDEO_PARAM_BITRATETYPE *)params); + OMX_VIDEO_PARAM_BITRATETYPE *bitRate = + (OMX_VIDEO_PARAM_BITRATETYPE *)params; + + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + + return internalSetBitrateParams(bitRate); } case OMX_IndexParamVideoAvc: { OMX_VIDEO_PARAM_AVCTYPE *avcType = (OMX_VIDEO_PARAM_AVCTYPE *)params; + if (!isValidOMXParam(avcType)) { + return OMX_ErrorBadParameter; + } + if (avcType->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -1035,6 +1053,10 @@ OMX_ERRORTYPE SoftAVC::setConfig( OMX_CONFIG_INTRAREFRESHVOPTYPE *params = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params; + if (!isValidOMXParam(params)) { + return OMX_ErrorBadParameter; + } + if (params->nPortIndex != kOutputPortIndex) { return OMX_ErrorBadPortIndex; } @@ -1048,6 +1070,10 @@ OMX_ERRORTYPE SoftAVC::setConfig( OMX_VIDEO_CONFIG_BITRATETYPE *params = (OMX_VIDEO_CONFIG_BITRATETYPE *)_params; + if (!isValidOMXParam(params)) { + return OMX_ErrorBadParameter; + } + if (params->nPortIndex != kOutputPortIndex) { return OMX_ErrorBadPortIndex; } diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp index 9edffd2..caceda9 100644 --- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp +++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp @@ -159,6 +159,10 @@ OMX_ERRORTYPE SoftFlacEncoder::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -180,6 +184,11 @@ OMX_ERRORTYPE SoftFlacEncoder::internalGetParameter( case OMX_IndexParamAudioFlac: { OMX_AUDIO_PARAM_FLACTYPE *flacParams = (OMX_AUDIO_PARAM_FLACTYPE *)params; + + if (!isValidOMXParam(flacParams)) { + return OMX_ErrorBadParameter; + } + flacParams->nCompressionLevel = mCompressionLevel; flacParams->nChannels = mNumChannels; flacParams->nSampleRate = mSampleRate; @@ -199,6 +208,10 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( ALOGV("SoftFlacEncoder::internalSetParameter(OMX_IndexParamAudioPcm)"); OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { ALOGE("SoftFlacEncoder::internalSetParameter() Error #1"); return OMX_ErrorUndefined; @@ -221,6 +234,10 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_encoder.flac", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -236,6 +253,11 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( { // used only for setting the compression level OMX_AUDIO_PARAM_FLACTYPE *flacParams = (OMX_AUDIO_PARAM_FLACTYPE *)params; + + if (!isValidOMXParam(flacParams)) { + return OMX_ErrorBadParameter; + } + mCompressionLevel = flacParams->nCompressionLevel; // range clamping done inside encoder return OMX_ErrorNone; } @@ -245,6 +267,10 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( OMX_PARAM_PORTDEFINITIONTYPE *defParams = (OMX_PARAM_PORTDEFINITIONTYPE *)params; + if (!isValidOMXParam(defParams)) { + return OMX_ErrorBadParameter; + } + if (defParams->nPortIndex == 0) { if (defParams->nBufferSize > kMaxInputBufferSize) { ALOGE("Input buffer size must be at most %d bytes", diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp index 015515e..3de95a5 100644 --- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp +++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp @@ -110,6 +110,10 @@ OMX_ERRORTYPE SoftG711::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -148,6 +152,10 @@ OMX_ERRORTYPE SoftG711::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -170,6 +178,10 @@ OMX_ERRORTYPE SoftG711::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (mIsMLaw) { if (strncmp((const char *)roleParams->cRole, "audio_decoder.g711mlaw", diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp index bd01a1a..7916c45 100644 --- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp +++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp @@ -110,6 +110,10 @@ OMX_ERRORTYPE SoftGSM::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -141,6 +145,10 @@ OMX_ERRORTYPE SoftGSM::internalSetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -161,6 +169,10 @@ OMX_ERRORTYPE SoftGSM::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.gsm", OMX_MAX_STRINGNAME_SIZE - 1)) { diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index f2a4e65..7638bb7 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -232,6 +232,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( OMX_VIDEO_PARAM_BITRATETYPE *bitRate = (OMX_VIDEO_PARAM_BITRATETYPE *) params; + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + if (bitRate->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -246,6 +250,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( OMX_VIDEO_PARAM_H263TYPE *h263type = (OMX_VIDEO_PARAM_H263TYPE *)params; + if (!isValidOMXParam(h263type)) { + return OMX_ErrorBadParameter; + } + if (h263type->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -267,6 +275,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter( OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = (OMX_VIDEO_PARAM_MPEG4TYPE *)params; + if (!isValidOMXParam(mpeg4type)) { + return OMX_ErrorBadParameter; + } + if (mpeg4type->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -301,6 +313,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( OMX_VIDEO_PARAM_BITRATETYPE *bitRate = (OMX_VIDEO_PARAM_BITRATETYPE *) params; + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + if (bitRate->nPortIndex != 1 || bitRate->eControlRate != OMX_Video_ControlRateVariable) { return OMX_ErrorUndefined; @@ -315,6 +331,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( OMX_VIDEO_PARAM_H263TYPE *h263type = (OMX_VIDEO_PARAM_H263TYPE *)params; + if (!isValidOMXParam(h263type)) { + return OMX_ErrorBadParameter; + } + if (h263type->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -337,6 +357,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter( OMX_VIDEO_PARAM_MPEG4TYPE *mpeg4type = (OMX_VIDEO_PARAM_MPEG4TYPE *)params; + if (!isValidOMXParam(mpeg4type)) { + return OMX_ErrorBadParameter; + } + if (mpeg4type->nPortIndex != 1) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index f743b1c..9988015 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -128,6 +128,10 @@ OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -151,6 +155,10 @@ OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_AUDIO_PARAM_MP3TYPE *mp3Params = (OMX_AUDIO_PARAM_MP3TYPE *)params; + if (!isValidOMXParam(mp3Params)) { + return OMX_ErrorBadParameter; + } + if (mp3Params->nPortIndex > 1) { return OMX_ErrorUndefined; } @@ -176,6 +184,10 @@ OMX_ERRORTYPE SoftMP3::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.mp3", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -190,6 +202,10 @@ OMX_ERRORTYPE SoftMP3::internalSetParameter( const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (const OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index d9895f0..5c950c7 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -368,20 +368,24 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index, OMX_VIDEO_PARAM_BITRATETYPE *bitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)param; - if (bitrate->nPortIndex != kOutputPortIndex) { - return OMX_ErrorUnsupportedIndex; - } + if (!isValidOMXParam(bitrate)) { + return OMX_ErrorBadParameter; + } - bitrate->nTargetBitrate = mBitrate; + if (bitrate->nPortIndex != kOutputPortIndex) { + return OMX_ErrorUnsupportedIndex; + } - if (mBitrateControlMode == VPX_VBR) { - bitrate->eControlRate = OMX_Video_ControlRateVariable; - } else if (mBitrateControlMode == VPX_CBR) { - bitrate->eControlRate = OMX_Video_ControlRateConstant; - } else { - return OMX_ErrorUnsupportedSetting; - } - return OMX_ErrorNone; + bitrate->nTargetBitrate = mBitrate; + + if (mBitrateControlMode == VPX_VBR) { + bitrate->eControlRate = OMX_Video_ControlRateVariable; + } else if (mBitrateControlMode == VPX_CBR) { + bitrate->eControlRate = OMX_Video_ControlRateConstant; + } else { + return OMX_ErrorUnsupportedSetting; + } + return OMX_ErrorNone; } // VP8 specific parameters that use extension headers @@ -389,33 +393,41 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index, OMX_VIDEO_PARAM_VP8TYPE *vp8Params = (OMX_VIDEO_PARAM_VP8TYPE *)param; - if (vp8Params->nPortIndex != kOutputPortIndex) { - return OMX_ErrorUnsupportedIndex; - } + if (!isValidOMXParam(vp8Params)) { + return OMX_ErrorBadParameter; + } - vp8Params->eProfile = OMX_VIDEO_VP8ProfileMain; - vp8Params->eLevel = mLevel; - vp8Params->nDCTPartitions = mDCTPartitions; - vp8Params->bErrorResilientMode = mErrorResilience; - return OMX_ErrorNone; + if (vp8Params->nPortIndex != kOutputPortIndex) { + return OMX_ErrorUnsupportedIndex; + } + + vp8Params->eProfile = OMX_VIDEO_VP8ProfileMain; + vp8Params->eLevel = mLevel; + vp8Params->nDCTPartitions = mDCTPartitions; + vp8Params->bErrorResilientMode = mErrorResilience; + return OMX_ErrorNone; } case OMX_IndexParamVideoAndroidVp8Encoder: { OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8AndroidParams = (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)param; - if (vp8AndroidParams->nPortIndex != kOutputPortIndex) { - return OMX_ErrorUnsupportedIndex; - } + if (!isValidOMXParam(vp8AndroidParams)) { + return OMX_ErrorBadParameter; + } - vp8AndroidParams->nKeyFrameInterval = mKeyFrameInterval; - vp8AndroidParams->eTemporalPattern = mTemporalPatternType; - vp8AndroidParams->nTemporalLayerCount = mTemporalLayers; - vp8AndroidParams->nMinQuantizer = mMinQuantizer; - vp8AndroidParams->nMaxQuantizer = mMaxQuantizer; - memcpy(vp8AndroidParams->nTemporalLayerBitrateRatio, - mTemporalLayerBitrateRatio, sizeof(mTemporalLayerBitrateRatio)); - return OMX_ErrorNone; + if (vp8AndroidParams->nPortIndex != kOutputPortIndex) { + return OMX_ErrorUnsupportedIndex; + } + + vp8AndroidParams->nKeyFrameInterval = mKeyFrameInterval; + vp8AndroidParams->eTemporalPattern = mTemporalPatternType; + vp8AndroidParams->nTemporalLayerCount = mTemporalLayers; + vp8AndroidParams->nMinQuantizer = mMinQuantizer; + vp8AndroidParams->nMaxQuantizer = mMaxQuantizer; + memcpy(vp8AndroidParams->nTemporalLayerBitrateRatio, + mTemporalLayerBitrateRatio, sizeof(mTemporalLayerBitrateRatio)); + return OMX_ErrorNone; } default: @@ -430,17 +442,38 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index, const int32_t indexFull = index; switch (indexFull) { - case OMX_IndexParamVideoBitrate: - return internalSetBitrateParams( - (const OMX_VIDEO_PARAM_BITRATETYPE *)param); + case OMX_IndexParamVideoBitrate: { + const OMX_VIDEO_PARAM_BITRATETYPE *bitRate = + (const OMX_VIDEO_PARAM_BITRATETYPE*) param; + + if (!isValidOMXParam(bitRate)) { + return OMX_ErrorBadParameter; + } + + return internalSetBitrateParams(bitRate); + } + + case OMX_IndexParamVideoVp8: { + const OMX_VIDEO_PARAM_VP8TYPE *vp8Params = + (const OMX_VIDEO_PARAM_VP8TYPE*) param; + + if (!isValidOMXParam(vp8Params)) { + return OMX_ErrorBadParameter; + } + + return internalSetVp8Params(vp8Params); + } - case OMX_IndexParamVideoVp8: - return internalSetVp8Params( - (const OMX_VIDEO_PARAM_VP8TYPE *)param); + case OMX_IndexParamVideoAndroidVp8Encoder: { + const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8AndroidParams = + (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE*) param; + + if (!isValidOMXParam(vp8AndroidParams)) { + return OMX_ErrorBadParameter; + } - case OMX_IndexParamVideoAndroidVp8Encoder: - return internalSetAndroidVp8Params( - (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)param); + return internalSetAndroidVp8Params(vp8AndroidParams); + } default: return SoftVideoEncoderOMXComponent::internalSetParameter(index, param); @@ -455,6 +488,10 @@ OMX_ERRORTYPE SoftVPXEncoder::setConfig( OMX_CONFIG_INTRAREFRESHVOPTYPE *params = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params; + if (!isValidOMXParam(params)) { + return OMX_ErrorBadParameter; + } + if (params->nPortIndex != kOutputPortIndex) { return OMX_ErrorBadPortIndex; } @@ -468,6 +505,10 @@ OMX_ERRORTYPE SoftVPXEncoder::setConfig( OMX_VIDEO_CONFIG_BITRATETYPE *params = (OMX_VIDEO_CONFIG_BITRATETYPE *)_params; + if (!isValidOMXParam(params)) { + return OMX_ErrorBadParameter; + } + if (params->nPortIndex != kOutputPortIndex) { return OMX_ErrorBadPortIndex; } diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp index cb10bce..2afa0ed 100644 --- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp +++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp @@ -134,6 +134,10 @@ OMX_ERRORTYPE SoftOpus::internalGetParameter( OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams = (OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params; + if (!isValidOMXParam(opusParams)) { + return OMX_ErrorBadParameter; + } + if (opusParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -156,6 +160,10 @@ OMX_ERRORTYPE SoftOpus::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -191,6 +199,10 @@ OMX_ERRORTYPE SoftOpus::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.opus", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -205,6 +217,10 @@ OMX_ERRORTYPE SoftOpus::internalSetParameter( const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams = (const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params; + if (!isValidOMXParam(opusParams)) { + return OMX_ErrorBadParameter; + } + if (opusParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp index 9d514a6..4f7ae95 100644 --- a/media/libstagefright/codecs/raw/SoftRaw.cpp +++ b/media/libstagefright/codecs/raw/SoftRaw.cpp @@ -103,6 +103,10 @@ OMX_ERRORTYPE SoftRaw::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -134,6 +138,10 @@ OMX_ERRORTYPE SoftRaw::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.raw", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -148,6 +156,10 @@ OMX_ERRORTYPE SoftRaw::internalSetParameter( const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp index c559682..4e1e6a5 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -130,6 +130,10 @@ OMX_ERRORTYPE SoftVorbis::internalGetParameter( OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = (OMX_AUDIO_PARAM_VORBISTYPE *)params; + if (!isValidOMXParam(vorbisParams)) { + return OMX_ErrorBadParameter; + } + if (vorbisParams->nPortIndex != 0) { return OMX_ErrorUndefined; } @@ -161,6 +165,10 @@ OMX_ERRORTYPE SoftVorbis::internalGetParameter( OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + if (!isValidOMXParam(pcmParams)) { + return OMX_ErrorBadParameter; + } + if (pcmParams->nPortIndex != 1) { return OMX_ErrorUndefined; } @@ -197,6 +205,10 @@ OMX_ERRORTYPE SoftVorbis::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, "audio_decoder.vorbis", OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -211,6 +223,10 @@ OMX_ERRORTYPE SoftVorbis::internalSetParameter( const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = (const OMX_AUDIO_PARAM_VORBISTYPE *)params; + if (!isValidOMXParam(vorbisParams)) { + return OMX_ErrorBadParameter; + } + if (vorbisParams->nPortIndex != 0) { return OMX_ErrorUndefined; } diff --git a/media/libstagefright/include/SoftOMXComponent.h b/media/libstagefright/include/SoftOMXComponent.h index a808611..3ab6f88 100644 --- a/media/libstagefright/include/SoftOMXComponent.h +++ b/media/libstagefright/include/SoftOMXComponent.h @@ -168,6 +168,22 @@ private: DISALLOW_EVIL_CONSTRUCTORS(SoftOMXComponent); }; +template +bool isValidOMXParam(T *a) { + static_assert(offsetof(typeof(*a), nSize) == 0, "nSize not at offset 0"); + static_assert(std::is_same< decltype(a->nSize), OMX_U32>::value, "nSize has wrong type"); + static_assert(offsetof(typeof(*a), nVersion) == 4, "nVersion not at offset 4"); + static_assert(std::is_same< decltype(a->nVersion), OMX_VERSIONTYPE>::value, + "nVersion has wrong type"); + + if (a->nSize < sizeof(*a)) { + ALOGE("b/27207275: need %zu, got %u", sizeof(*a), a->nSize); + android_errorWriteLog(0x534e4554, "27207275"); + return false; + } + return true; +} + } // namespace android #endif // SOFT_OMX_COMPONENT_H_ diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp index e6a0c49..60c1e2e 100644 --- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp +++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp @@ -125,6 +125,10 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::internalGetParameter( OMX_PARAM_PORTDEFINITIONTYPE *defParams = (OMX_PARAM_PORTDEFINITIONTYPE *)params; + if (!isValidOMXParam(defParams)) { + return OMX_ErrorBadParameter; + } + if (defParams->nPortIndex >= mPorts.size() || defParams->nSize != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) { @@ -152,6 +156,10 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetParameter( OMX_PARAM_PORTDEFINITIONTYPE *defParams = (OMX_PARAM_PORTDEFINITIONTYPE *)params; + if (!isValidOMXParam(defParams)) { + return OMX_ErrorBadParameter; + } + if (defParams->nPortIndex >= mPorts.size()) { return OMX_ErrorBadPortIndex; } diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp index 4ce165b..19dde83 100644 --- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp @@ -264,6 +264,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter( OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > kMaxPortIndex) { return OMX_ErrorBadPortIndex; } @@ -292,6 +296,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter( OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params; + if (!isValidOMXParam(profileLevel)) { + return OMX_ErrorBadParameter; + } + if (profileLevel->nPortIndex != kInputPortIndex) { ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex); return OMX_ErrorUnsupportedIndex; @@ -322,6 +330,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( const OMX_PARAM_COMPONENTROLETYPE *roleParams = (const OMX_PARAM_COMPONENTROLETYPE *)params; + if (!isValidOMXParam(roleParams)) { + return OMX_ErrorBadParameter; + } + if (strncmp((const char *)roleParams->cRole, mComponentRole, OMX_MAX_STRINGNAME_SIZE - 1)) { @@ -336,6 +348,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; + if (!isValidOMXParam(formatParams)) { + return OMX_ErrorBadParameter; + } + if (formatParams->nPortIndex > kMaxPortIndex) { return OMX_ErrorBadPortIndex; } @@ -363,6 +379,11 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( { const PrepareForAdaptivePlaybackParams* adaptivePlaybackParams = (const PrepareForAdaptivePlaybackParams *)params; + + if (!isValidOMXParam(adaptivePlaybackParams)) { + return OMX_ErrorBadParameter; + } + mIsAdaptive = adaptivePlaybackParams->bEnable; if (mIsAdaptive) { mAdaptiveMaxWidth = adaptivePlaybackParams->nMaxFrameWidth; @@ -381,6 +402,11 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( { OMX_PARAM_PORTDEFINITIONTYPE *newParams = (OMX_PARAM_PORTDEFINITIONTYPE *)params; + + if (!isValidOMXParam(newParams)) { + return OMX_ErrorBadParameter; + } + OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &newParams->format.video; OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(newParams->nPortIndex)->mDef; @@ -421,6 +447,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig( { OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params; + if (!isValidOMXParam(rectParams)) { + return OMX_ErrorBadParameter; + } + if (rectParams->nPortIndex != kOutputPortIndex) { return OMX_ErrorUndefined; } -- cgit v1.1 From 94d9e646454f6246bf823b6897bd6aea5f08eda3 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 10 Mar 2016 14:29:26 -0800 Subject: Fix initialization of AAC presentation struct Otherwise the new size checks trip on this. Bug: 27207275 Change-Id: I1f8f01097e3a88ff041b69279a6121be842f1766 --- media/libstagefright/ACodec.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 8d9bd21..6399b79 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -2418,6 +2418,7 @@ status_t ACodec::setupAACCodec( : OMX_AUDIO_AACStreamFormatMP4FF; OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation; + InitOMXParams(&presentation); presentation.nMaxOutputChannels = maxOutputChannelCount; presentation.nDrcCut = drc.drcCut; presentation.nDrcBoost = drc.drcBoost; -- cgit v1.1 From 0bb5ced60304da7f61478ffd359e7ba65d72f181 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 10 Mar 2016 15:02:13 -0800 Subject: Fix size check for OMX_IndexParamConsumerUsageBits since it doesn't follow the OMX convention. And remove support for the kClientNeedsFrameBuffer flag. Bug: 27207275 Change-Id: Ia2c119e2456ebf9e2f4e1de5104ef9032a212255 --- include/media/stagefright/OMXCodec.h | 4 ---- media/libmedia/IOMX.cpp | 8 +++++-- media/libstagefright/OMXCodec.cpp | 44 ------------------------------------ 3 files changed, 6 insertions(+), 50 deletions(-) diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 7fabcb3..b0404aa 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -40,10 +40,6 @@ struct OMXCodec : public MediaSource, kPreferSoftwareCodecs = 1, kIgnoreCodecSpecificData = 2, - // The client wants to access the output buffer's video - // data for example for thumbnail extraction. - kClientNeedsFramebuffer = 4, - // Request for software or hardware codecs. If request // can not be fullfilled, Create() returns NULL. kSoftwareCodecsOnly = 8, diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 84925f1..9be9b41 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace android { @@ -698,7 +699,8 @@ status_t BnOMX::onTransact( void *params = NULL; size_t pageSize = 0; size_t allocSize = 0; - if (code != SET_INTERNAL_OPTION && size < 8) { + if ((index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && size < 4) || + (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)", size); @@ -720,7 +722,9 @@ status_t BnOMX::onTransact( } else { err = NOT_ENOUGH_DATA; OMX_U32 declaredSize = *(OMX_U32*)params; - if (code != SET_INTERNAL_OPTION && declaredSize > size) { + 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"); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index b1dde80..4618e21 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -349,21 +349,6 @@ sp OMXCodec::Create( ALOGV("Attempting to allocate OMX node '%s'", componentName); - if (!createEncoder - && (quirks & kOutputBuffersAreUnreadable) - && (flags & kClientNeedsFramebuffer)) { - if (strncmp(componentName, "OMX.SEC.", 8)) { - // For OMX.SEC.* decoders we can enable a special mode that - // gives the client access to the framebuffer contents. - - ALOGW("Component '%s' does not give the client access to " - "the framebuffer contents. Skipping.", - componentName); - - continue; - } - } - status_t err = omx->allocateNode(componentName, observer, &node); if (err == OK) { ALOGV("Successfully allocated OMX node '%s'", componentName); @@ -672,35 +657,6 @@ status_t OMXCodec::configureCodec(const sp &meta) { initOutputFormat(meta); - if ((mFlags & kClientNeedsFramebuffer) - && !strncmp(mComponentName, "OMX.SEC.", 8)) { - // This appears to no longer be needed??? - - OMX_INDEXTYPE index; - - status_t err = - mOMX->getExtensionIndex( - mNode, - "OMX.SEC.index.ThumbnailMode", - &index); - - if (err != OK) { - return err; - } - - OMX_BOOL enable = OMX_TRUE; - err = mOMX->setConfig(mNode, index, &enable, sizeof(enable)); - - if (err != OK) { - CODEC_LOGE("setConfig('OMX.SEC.index.ThumbnailMode') " - "returned error 0x%08x", err); - - return err; - } - - mQuirks &= ~kOutputBuffersAreUnreadable; - } - if (mNativeWindow != NULL && !mIsEncoder && !strncasecmp(mMIME, "video/", 6) -- cgit v1.1 From db829699d3293f254a7387894303451a91278986 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 21 Mar 2016 11:31:53 -0700 Subject: Fix OMX_IndexParamConsumerUsageBits size check Bug: 27207275 Change-Id: I9a7c9fb22a0e84a490ff09c151bd2f88141fdbc0 --- media/libmedia/IOMX.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 9be9b41..b082fe4 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -699,11 +699,12 @@ status_t BnOMX::onTransact( void *params = NULL; size_t pageSize = 0; size_t allocSize = 0; - if ((index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && size < 4) || - (code != SET_INTERNAL_OPTION && size < 8)) { + 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)", size); + ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); android_errorWriteLog(0x534e4554, "27207275"); } else { err = NO_MEMORY; -- cgit v1.1 From 4e32001e4196f39ddd0b86686ae0231c8f5ed944 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Wed, 30 Mar 2016 17:13:00 +0900 Subject: DO NOT MERGE codecs: check OMX buffer size before use in (vorbis|opus)dec Bug: 27833616 Change-Id: I1ccdd16a00741da072527a6d13e87fd7c7fe8c54 --- media/libstagefright/codecs/opus/dec/SoftOpus.cpp | 7 ++++++- media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp index 2afa0ed..2e44ed7 100644 --- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp +++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp @@ -458,12 +458,17 @@ void SoftOpus::onQueueFilled(OMX_U32 portIndex) { const uint8_t *data = inHeader->pBuffer + inHeader->nOffset; const uint32_t size = inHeader->nFilledLen; + size_t frameSize = kMaxOpusOutputPacketSizeSamples; + if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) { + frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels; + android_errorWriteLog(0x534e4554, "27833616"); + } int numFrames = opus_multistream_decode(mDecoder, data, size, (int16_t *)outHeader->pBuffer, - kMaxOpusOutputPacketSizeSamples, + frameSize, 0); if (numFrames < 0) { ALOGE("opus_multistream_decode returned %d", numFrames); diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp index 4e1e6a5..5f4e346 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -273,6 +273,12 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) { const uint8_t *data = header->pBuffer + header->nOffset; size_t size = header->nFilledLen; + if (size < 7) { + ALOGE("Too small input buffer: %zu bytes", size); + android_errorWriteLog(0x534e4554, "27833616"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + return; + } ogg_buffer buf; ogg_reference ref; @@ -378,9 +384,14 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) { ALOGW("vorbis_dsp_synthesis returned %d", err); #endif } else { + size_t numSamplesPerBuffer = kMaxNumSamplesPerBuffer; + if (numSamplesPerBuffer > outHeader->nAllocLen / sizeof(int16_t)) { + numSamplesPerBuffer = outHeader->nAllocLen / sizeof(int16_t); + android_errorWriteLog(0x534e4554, "27833616"); + } numFrames = vorbis_dsp_pcmout( mState, (int16_t *)outHeader->pBuffer, - (kMaxNumSamplesPerBuffer / mVi->channels)); + (numSamplesPerBuffer / mVi->channels)); if (numFrames < 0) { ALOGE("vorbis_dsp_pcmout returned %d", numFrames); -- cgit v1.1 From d2f47191538837e796e2b10c1ff7e1ee35f6e0ab Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Sun, 20 Mar 2016 10:44:44 +0900 Subject: codecs: check OMX buffer size before use in (h263|h264)dec Bug: 27833616 Change-Id: I0fd599b3da431425d89236ffdd9df423c11947c0 --- .../codecs/m4v_h263/dec/SoftMPEG4.cpp | 10 ++++++++- .../libstagefright/codecs/on2/h264dec/SoftAVC.cpp | 26 +++++++++++++++++----- media/libstagefright/codecs/on2/h264dec/SoftAVC.h | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index 0c1a149..bb59ae4 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -229,6 +229,14 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { int32_t bufferSize = inHeader->nFilledLen; int32_t tmp = bufferSize; + OMX_U32 frameSize = (mWidth * mHeight * 3) / 2; + if (outHeader->nAllocLen < frameSize) { + android_errorWriteLog(0x534e4554, "27833616"); + ALOGE("Insufficient output buffer size"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } // The PV decoder is lying to us, sometimes it'll claim to only have // consumed a subset of the buffer when it clearly consumed all of it. // ignore whatever it says... @@ -272,7 +280,7 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { ++mInputBufferCount; outHeader->nOffset = 0; - outHeader->nFilledLen = (mWidth * mHeight * 3) / 2; + outHeader->nFilledLen = frameSize; List::iterator it = outQueue.begin(); while ((*it)->mHeader != outHeader) { diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp index 6b8b395..2f61d12 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp @@ -202,7 +202,12 @@ void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) { } if (mFirstPicture && !outQueue.empty()) { - drainOneOutputBuffer(mFirstPictureId, mFirstPicture); + if (!drainOneOutputBuffer(mFirstPictureId, mFirstPicture)) { + ALOGE("Drain failed"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } delete[] mFirstPicture; mFirstPicture = NULL; mFirstPictureId = -1; @@ -242,15 +247,20 @@ void SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) { memcpy(mFirstPicture, data, pictureSize); } -void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) { +bool SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) { List &outQueue = getPortQueue(kOutputPortIndex); BufferInfo *outInfo = *outQueue.begin(); - outQueue.erase(outQueue.begin()); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; + OMX_U32 frameSize = mWidth * mHeight * 3 / 2; + if (outHeader->nAllocLen - outHeader->nOffset < frameSize) { + android_errorWriteLog(0x534e4554, "27833616"); + return false; + } + outQueue.erase(outQueue.begin()); OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId); outHeader->nTimeStamp = header->nTimeStamp; outHeader->nFlags = header->nFlags; - outHeader->nFilledLen = mWidth * mHeight * 3 / 2; + outHeader->nFilledLen = frameSize; uint8_t *dst = outHeader->pBuffer + outHeader->nOffset; const uint8_t *srcY = data; @@ -265,6 +275,7 @@ void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) { delete header; outInfo->mOwnedByUs = false; notifyFillBufferDone(outHeader); + return true; } void SoftAVC::drainAllOutputBuffers(bool eos) { @@ -277,7 +288,12 @@ void SoftAVC::drainAllOutputBuffers(bool eos) { mHandle, &decodedPicture, eos /* flush */)) { int32_t picId = decodedPicture.picId; uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture; - drainOneOutputBuffer(picId, data); + if (!drainOneOutputBuffer(picId, data)) { + ALOGE("Drain failed"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } } } diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h index 069107d..b8c1807 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h @@ -71,7 +71,7 @@ private: status_t initDecoder(); void drainAllOutputBuffers(bool eos); - void drainOneOutputBuffer(int32_t picId, uint8_t *data); + bool drainOneOutputBuffer(int32_t picId, uint8_t *data); void saveFirstOutputBuffer(int32_t pidId, uint8_t *data); CropSettingsMode handleCropParams(const H264SwDecInfo& decInfo); -- cgit v1.1 From ad40e57890f81a3cf436c5f06da66396010bd9e5 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 23 Mar 2016 15:36:36 -0700 Subject: Check mp3 output buffer size Bug: 27793371 Change-Id: I0fe40a4cfd0a5b488f93d3f3ba6f9495235926ac --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index 9988015..aa946e6 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -263,6 +263,14 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { mConfig->inputBufferUsedLength = 0; mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t); + if ((int32)outHeader->nAllocLen < mConfig->outputFrameSize) { + ALOGE("input buffer too small: got %lu, expected %u", + outHeader->nAllocLen, mConfig->outputFrameSize); + android_errorWriteLog(0x534e4554, "27793371"); + notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); + mSignalledError = true; + return; + } mConfig->pOutputBuffer = reinterpret_cast(outHeader->pBuffer); -- cgit v1.1 From dd3546765710ce8dd49eb23901d90345dec8282f Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 5 Apr 2016 14:20:11 -0700 Subject: AudioSource: initialize variables to prevent info leak Bug: 27855172 Change-Id: I3d33e0a9cc5cf8a758d7b0794590b09c43a24561 --- media/libstagefright/AudioSource.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index 6e4a1dd..55f4361 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -55,8 +55,12 @@ AudioSource::AudioSource( : mStarted(false), mSampleRate(sampleRate), mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate), + mTrackMaxAmplitude(false), + mStartTimeUs(0), + mMaxAmplitude(0), mPrevSampleTimeUs(0), mFirstSampleTimeUs(-1ll), + mInitialReadTimeUs(0), mNumFramesReceived(0), mNumClientOwnedBuffers(0) { ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u", -- cgit v1.1 From 7cea5cb64b83d690fe02bc210bbdf08f5a87636f Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Thu, 7 Apr 2016 17:45:02 +0900 Subject: codecs: check OMX buffer size before use in (gsm|g711)dec Bug: 27793163 Bug: 27793367 Change-Id: Iec3de8a237ee2379d87a8371c13e543878c6652c --- media/libstagefright/codecs/g711/dec/SoftG711.cpp | 9 +++++++++ media/libstagefright/codecs/gsm/dec/SoftGSM.cpp | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp index 3de95a5..c8277de 100644 --- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp +++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp @@ -240,6 +240,15 @@ void SoftG711::onQueueFilled(OMX_U32 /* portIndex */) { mSignalledError = true; } + if (inHeader->nFilledLen * sizeof(int16_t) > outHeader->nAllocLen) { + ALOGE("output buffer too small (%d).", outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "27793163"); + + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + const uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset; if (mIsMLaw) { diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp index 7916c45..04d5a33 100644 --- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp +++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp @@ -228,6 +228,14 @@ void SoftGSM::onQueueFilled(OMX_U32 /* portIndex */) { mSignalledError = true; } + if (outHeader->nAllocLen < (inHeader->nFilledLen / kMSGSMFrameSize) * 320) { + ALOGE("output buffer is not large enough (%d).", outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "27793367"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset; int n = mSignalledError ? 0 : DecodeGSM(mGsm, -- cgit v1.1 From 918eeaa29d99d257282fafec931b4bda0e3bae12 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Sun, 20 Mar 2016 10:44:44 +0900 Subject: codecs: check OMX buffer size before use in (avc|hevc|mpeg2)dec Bug: 27833616 Change-Id: Ic4045a3f56f53b08d0b1264b2a91b8f43e91b738 (cherry picked from commit 87fdee0bc9e3ac4d2a88ef0a8e150cfdf08c161d) --- media/libstagefright/codecs/avcdec/SoftAVCDec.cpp | 28 ++++++++++++------ media/libstagefright/codecs/avcdec/SoftAVCDec.h | 2 +- media/libstagefright/codecs/hevcdec/SoftHEVC.cpp | 28 ++++++++++++------ media/libstagefright/codecs/hevcdec/SoftHEVC.h | 2 +- media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp | 33 ++++++++++++++-------- media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h | 2 +- 6 files changed, 62 insertions(+), 33 deletions(-) diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp index afbe230..2130ccf 100644 --- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp +++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp @@ -381,7 +381,7 @@ void SoftAVC::onReset() { resetPlugin(); } -void SoftAVC::setDecodeArgs( +bool SoftAVC::setDecodeArgs( ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, @@ -389,7 +389,6 @@ void SoftAVC::setDecodeArgs( size_t timeStampIx) { size_t sizeY = outputBufferWidth() * outputBufferHeight(); size_t sizeUV; - uint8_t *pBuf; ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t); ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); @@ -409,22 +408,28 @@ void SoftAVC::setDecodeArgs( ps_dec_ip->u4_num_Bytes = 0; } + sizeUV = sizeY / 4; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; + + uint8_t *pBuf; if (outHeader) { + if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) { + android_errorWriteLog(0x534e4554, "27569635"); + return false; + } pBuf = outHeader->pBuffer; } else { + // mFlushOutBuffer always has the right size. pBuf = mFlushOutBuffer; } - sizeUV = sizeY / 4; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; - ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf; ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY; ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV; ps_dec_ip->s_out_buffer.u4_num_bufs = 3; - return; + return true; } void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) { /* Once the output buffers are flushed, ignore any buffers that are held in decoder */ @@ -573,7 +578,12 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { WORD32 timeDelay, timeTaken; size_t sizeY, sizeUV; - setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx); + if (!setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { + ALOGE("Decoder arg setup failed"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } // If input dump is enabled, then write to file DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes); diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.h b/media/libstagefright/codecs/avcdec/SoftAVCDec.h index 9dcabb4..c710c76 100644 --- a/media/libstagefright/codecs/avcdec/SoftAVCDec.h +++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.h @@ -109,7 +109,7 @@ private: status_t resetPlugin(); - void setDecodeArgs( + bool setDecodeArgs( ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp index e601125..a70755c 100644 --- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp +++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp @@ -343,14 +343,13 @@ void SoftHEVC::onReset() { resetPlugin(); } -void SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip, +bool SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, OMX_BUFFERHEADERTYPE *outHeader, size_t timeStampIx) { size_t sizeY = outputBufferWidth() * outputBufferHeight(); size_t sizeUV; - uint8_t *pBuf; ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t); ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); @@ -370,22 +369,28 @@ void SoftHEVC::setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip, ps_dec_ip->u4_num_Bytes = 0; } + sizeUV = sizeY / 4; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; + + uint8_t *pBuf; if (outHeader) { + if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) { + android_errorWriteLog(0x534e4554, "27569635"); + return false; + } pBuf = outHeader->pBuffer; } else { + // mFlushOutBuffer always has the right size. pBuf = mFlushOutBuffer; } - sizeUV = sizeY / 4; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; - ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf; ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY; ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV; ps_dec_ip->s_out_buffer.u4_num_bufs = 3; - return; + return true; } void SoftHEVC::onPortFlushCompleted(OMX_U32 portIndex) { /* Once the output buffers are flushed, ignore any buffers that are held in decoder */ @@ -520,7 +525,12 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) { WORD32 timeDelay, timeTaken; size_t sizeY, sizeUV; - setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx); + if (!setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { + ALOGE("Decoder arg setup failed"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } GETTIME(&mTimeStart, NULL); /* Compute time elapsed between end of previous decode() diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.h b/media/libstagefright/codecs/hevcdec/SoftHEVC.h index 21bb99e..943edfd 100644 --- a/media/libstagefright/codecs/hevcdec/SoftHEVC.h +++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.h @@ -106,7 +106,7 @@ private: status_t resetDecoder(); status_t resetPlugin(); - void setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip, + bool setDecodeArgs(ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, OMX_BUFFERHEADERTYPE *outHeader, diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp index 4307c4e..e134d38 100644 --- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp +++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp @@ -466,7 +466,7 @@ OMX_ERRORTYPE SoftMPEG2::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR return ret; } -void SoftMPEG2::setDecodeArgs( +bool SoftMPEG2::setDecodeArgs( ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, @@ -474,7 +474,6 @@ void SoftMPEG2::setDecodeArgs( size_t timeStampIx) { size_t sizeY = outputBufferWidth() * outputBufferHeight(); size_t sizeUV; - uint8_t *pBuf; ps_dec_ip->u4_size = sizeof(ivd_video_decode_ip_t); ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); @@ -494,22 +493,28 @@ void SoftMPEG2::setDecodeArgs( ps_dec_ip->u4_num_Bytes = 0; } + sizeUV = sizeY / 4; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; + ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; + + uint8_t *pBuf; if (outHeader) { + if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) { + android_errorWriteLog(0x534e4554, "27569635"); + return false; + } pBuf = outHeader->pBuffer; } else { + // mFlushOutBuffer always has the right size. pBuf = mFlushOutBuffer; } - sizeUV = sizeY / 4; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[0] = sizeY; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[1] = sizeUV; - ps_dec_ip->s_out_buffer.u4_min_out_buf_size[2] = sizeUV; - ps_dec_ip->s_out_buffer.pu1_bufs[0] = pBuf; ps_dec_ip->s_out_buffer.pu1_bufs[1] = pBuf + sizeY; ps_dec_ip->s_out_buffer.pu1_bufs[2] = pBuf + sizeY + sizeUV; ps_dec_ip->s_out_buffer.u4_num_bufs = 3; - return; + return true; } void SoftMPEG2::onPortFlushCompleted(OMX_U32 portIndex) { /* Once the output buffers are flushed, ignore any buffers that are held in decoder */ @@ -622,7 +627,11 @@ void SoftMPEG2::onQueueFilled(OMX_U32 portIndex) { WORD32 timeDelay, timeTaken; size_t sizeY, sizeUV; - setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx); + if (!setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { + ALOGE("Decoder arg setup failed"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + return; + } // If input dump is enabled, then write to file DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes); @@ -665,9 +674,9 @@ void SoftMPEG2::onQueueFilled(OMX_U32 portIndex) { CHECK_EQ(reInitDecoder(), (status_t)OK); - setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx); - - ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); + if (setDecodeArgs(&s_dec_ip, &s_dec_op, inHeader, outHeader, timeStampIx)) { + ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); + } return; } diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h index a625e08..f48b70b 100644 --- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h +++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.h @@ -117,7 +117,7 @@ private: status_t resetPlugin(); status_t reInitDecoder(); - void setDecodeArgs( + bool setDecodeArgs( ivd_video_decode_ip_t *ps_dec_ip, ivd_video_decode_op_t *ps_dec_op, OMX_BUFFERHEADERTYPE *inHeader, -- cgit v1.1 From 2b6f22dc64d456471a1dc6df09d515771d1427c8 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Fri, 8 Apr 2016 10:04:48 -0700 Subject: h264dec: check for overflows when calculating allocation size. Bug: 27855419 Change-Id: Idabedca52913ec31ea5cb6a6109ab94e3fb2badd --- media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h | 2 +- .../libstagefright/codecs/on2/h264dec/source/DecTestBench.c | 9 ++++++--- .../codecs/on2/h264dec/source/EvaluationTestBench.c | 9 ++++++--- .../libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c | 13 ++++++++++--- .../codecs/on2/h264dec/source/TestBenchMultipleInstance.c | 7 +++++-- .../codecs/on2/h264dec/source/h264bsd_decoder.c | 2 +- .../libstagefright/codecs/on2/h264dec/source/h264bsd_util.h | 2 +- 7 files changed, 30 insertions(+), 14 deletions(-) diff --git a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h index fe112bc..9814e73 100644 --- a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h +++ b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h @@ -161,7 +161,7 @@ extern "C" void H264SwDecTrace(char *); /* function prototype for memory allocation */ - void* H264SwDecMalloc(u32 size); + void* H264SwDecMalloc(u32 size, u32 num); /* function prototype for memory free */ void H264SwDecFree(void *ptr); diff --git a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c index dcf2ef6..55c0065 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c +++ b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c @@ -700,18 +700,21 @@ void H264SwDecTrace(char *string) library function malloc for allocation of memory. ------------------------------------------------------------------------------*/ -void* H264SwDecMalloc(u32 size) +void* H264SwDecMalloc(u32 size, u32 num) { + if (size > UINT32_MAX / num) { + return NULL; + } #if defined(CHECK_MEMORY_USAGE) /* Note that if the decoder has to free and reallocate some of the buffers * the total value will be invalid */ static u32 numBytes = 0; - numBytes += size; + numBytes += size * num; DEBUG(("Allocated %d bytes, total %d\n", size, numBytes)); #endif - return malloc(size); + return malloc(size * num); } /*------------------------------------------------------------------------------ diff --git a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c index aadc75f..e756a1f 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c +++ b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c @@ -85,7 +85,7 @@ int main(int argc, char **argv) rewind(finput); /* allocate memory for stream buffer, exit if unsuccessful */ - byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8)*strmLen); + byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8), strmLen); if (byteStrm == NULL) { printf("UNABLE TO ALLOCATE MEMORY\n"); @@ -298,9 +298,12 @@ void H264SwDecTrace(char *string) library function malloc for allocation of memory. ------------------------------------------------------------------------------*/ -void* H264SwDecMalloc(u32 size) +void* H264SwDecMalloc(u32 size, u32 num) { - return malloc(size); + if (size > UINT32_MAX / num) { + return NULL; + } + return malloc(size * num); } /*------------------------------------------------------------------------------ diff --git a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c index a073dcb..f820dfd 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c +++ b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c @@ -35,6 +35,8 @@ /*------------------------------------------------------------------------------ 1. Include headers ------------------------------------------------------------------------------*/ +#include + #include #include #include "basetype.h" @@ -79,8 +81,13 @@ void H264SwDecTrace(char *string) { UNUSED(string); } -void* H264SwDecMalloc(u32 size) { - return malloc(size); +void* H264SwDecMalloc(u32 size, u32 num) { + if (size > UINT32_MAX / num) { + ALOGE("can't allocate %u * %u bytes", size, num); + android_errorWriteLog(0x534e4554, "27855419"); + return NULL; + } + return malloc(size * num); } void H264SwDecFree(void *ptr) { @@ -144,7 +151,7 @@ H264SwDecRet H264SwDecInit(H264SwDecInst *decInst, u32 noOutputReordering) return(H264SWDEC_PARAM_ERR); } - pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t)); + pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t), 1); if (pDecCont == NULL) { diff --git a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c index 42170d3..9a386bb 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c +++ b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c @@ -413,9 +413,12 @@ void H264SwDecTrace(char *string) Function name: H264SwDecmalloc ------------------------------------------------------------------------------*/ -void* H264SwDecMalloc(u32 size) +void* H264SwDecMalloc(u32 size, u32 num) { - return malloc(size); + if (size > UINT32_MAX / num) { + return NULL; + } + return malloc(size * num); } /*------------------------------------------------------------------------------ diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c index a816871..0ac480f 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c @@ -101,7 +101,7 @@ u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering) * specific NEON optimized "memset" for clearing the structure */ size = (sizeof(macroblockLayer_t) + 63) & ~0x3F; - pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size); + pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size, 1); if (!pStorage->mbLayer) return HANTRO_NOK; diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h index 216ad04..9f0eb7d 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h @@ -141,7 +141,7 @@ /* macro to allocate memory */ #define ALLOCATE(ptr, count, type) \ { \ - (ptr) = H264SwDecMalloc((count) * sizeof(type)); \ + (ptr) = H264SwDecMalloc(sizeof(type), (count)); \ } /* macro to free allocated memory */ -- cgit v1.1 From 45737cb776625f17384540523674761e6313e6d4 Mon Sep 17 00:00:00 2001 From: Zach Jang Date: Thu, 21 Apr 2016 16:10:50 -0700 Subject: Resolve merge conflict when cp'ing ag/931301 to mnc-mr1-release Change-Id: I079d1db2d30d126f8aed348bd62451acf741037d --- include/media/stagefright/DataSource.h | 61 +++++++++++++++++++++++++++++- media/libstagefright/SampleTable.cpp | 37 +++++++++--------- media/libstagefright/include/SampleTable.h | 3 +- 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index dcde36f..47c5c34 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -19,7 +19,7 @@ #define DATA_SOURCE_H_ #include - +#include #include #include #include @@ -71,6 +71,20 @@ public: bool getUInt32(off64_t offset, uint32_t *x); bool getUInt64(off64_t offset, uint64_t *x); + // Reads in "count" entries of type T into vector *x. + // Returns true if "count" entries can be read. + // If fewer than "count" entries can be read, return false. In this case, + // the output vector *x will still have those entries that were read. Call + // x->size() to obtain the number of entries read. + // The optional parameter chunkSize specifies how many entries should be + // read from the data source at one time into a temporary buffer. Increasing + // chunkSize can improve the performance at the cost of extra memory usage. + // The default value for chunkSize is set to read at least 4k bytes at a + // time, depending on sizeof(T). + template + bool getVector(off64_t offset, Vector* x, size_t count, + size_t chunkSize = (4095 / sizeof(T)) + 1); + // May return ERROR_UNSUPPORTED. virtual status_t getSize(off64_t *size); @@ -121,6 +135,51 @@ private: DataSource &operator=(const DataSource &); }; +template +bool DataSource::getVector(off64_t offset, Vector* x, size_t count, + size_t chunkSize) +{ + x->clear(); + if (chunkSize == 0) { + return false; + } + if (count == 0) { + return true; + } + + T tmp[chunkSize]; + ssize_t numBytesRead; + size_t numBytesPerChunk = chunkSize * sizeof(T); + size_t i; + + for (i = 0; i + chunkSize < count; i += chunkSize) { + // This loops is executed when more than chunkSize records need to be + // read. + numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk); + if (numBytesRead == -1) { // If readAt() returns -1, there is an error. + return false; + } + if (numBytesRead < numBytesPerChunk) { + // This case is triggered when the stream ends before the whole + // chunk is read. + x->appendArray(tmp, (size_t)numBytesRead / sizeof(T)); + return false; + } + x->appendArray(tmp, chunkSize); + offset += numBytesPerChunk; + } + + // There are (count - i) more records to read. + // Right now, (count - i) <= chunkSize. + // We do the same thing as above, but with chunkSize replaced by count - i. + numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T)); + if (numBytesRead == -1) { + return false; + } + x->appendArray(tmp, (size_t)numBytesRead / sizeof(T)); + return x->size() == count; +} + } // namespace android #endif // DATA_SOURCE_H_ diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 97dff43..5344ae4 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -122,7 +122,7 @@ SampleTable::SampleTable(const sp &source) mDefaultSampleSize(0), mNumSampleSizes(0), mTimeToSampleCount(0), - mTimeToSample(NULL), + mTimeToSample(), mSampleTimeEntries(NULL), mCompositionTimeDeltaEntries(NULL), mNumCompositionTimeDeltaEntries(0), @@ -151,9 +151,6 @@ SampleTable::~SampleTable() { delete[] mSampleTimeEntries; mSampleTimeEntries = NULL; - delete[] mTimeToSample; - mTimeToSample = NULL; - delete mSampleIterator; mSampleIterator = NULL; } @@ -162,7 +159,7 @@ bool SampleTable::isValid() const { return mChunkOffsetOffset >= 0 && mSampleToChunkOffset >= 0 && mSampleSizeOffset >= 0 - && mTimeToSample != NULL; + && !mTimeToSample.empty(); } status_t SampleTable::setChunkOffsetParams( @@ -327,7 +324,7 @@ status_t SampleTable::setSampleSizeParams( status_t SampleTable::setTimeToSampleParams( off64_t data_offset, size_t data_size) { - if (mTimeToSample != NULL || data_size < 8) { + if (!mTimeToSample.empty() || data_size < 8) { return ERROR_MALFORMED; } @@ -343,24 +340,30 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); - uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); - if (allocSize > UINT32_MAX) { + if ((uint64_t)mTimeToSampleCount > + (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { + // Choose this bound because + // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one + // time-to-sample entry in the time-to-sample table. + // 2) mTimeToSampleCount is the number of entries of the time-to-sample + // table. + // 3) We hope that the table size does not exceed UINT32_MAX. + ALOGE(" Error: Time-to-sample table size too large."); + return ERROR_OUT_OF_RANGE; } - mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; - if (!mTimeToSample) - return ERROR_OUT_OF_RANGE; - size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; - if (mDataSource->readAt( - data_offset + 8, mTimeToSample, size) < (ssize_t)size) { + // Note: At this point, we know that mTimeToSampleCount * 2 will not + // overflow because of the above condition. + if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, + mTimeToSampleCount * 2)) { + ALOGE(" Error: Incomplete data read for time-to-sample table."); return ERROR_IO; } - for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { - mTimeToSample[i] = ntohl(mTimeToSample[i]); + for (size_t i = 0; i < mTimeToSample.size(); ++i) { + mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); } - return OK; } diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index 460492b..3764adb 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace android { @@ -111,7 +112,7 @@ private: uint32_t mNumSampleSizes; uint32_t mTimeToSampleCount; - uint32_t *mTimeToSample; + Vector mTimeToSample; struct SampleTimeEntry { uint32_t mSampleIndex; -- cgit v1.1 From b57b3967b1a42dd505dbe4fcf1e1d810e3ae3777 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Wed, 20 Apr 2016 15:51:48 -0700 Subject: SampleTable.cpp: Fixed a regression caused by a fix for bug 28076789. Detail: Before the original fix (Id207f369ab7b27787d83f5d8fc48dc53ed9fcdc9) for 28076789, the code allowed a time-to-sample table size to be 0. The change made in that fix disallowed such situation, which in fact should be allowed. This current patch allows it again while maintaining the security of the previous fix. Bug: 28288202 Bug: 28076789 Change-Id: I1c9a60c7f0cfcbd3d908f24998dde15d5136a295 --- media/libstagefright/SampleTable.cpp | 7 +++++-- media/libstagefright/include/SampleTable.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 5344ae4..8df9cb8 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -121,6 +121,7 @@ SampleTable::SampleTable(const sp &source) mSampleSizeFieldSize(0), mDefaultSampleSize(0), mNumSampleSizes(0), + mHasTimeToSample(false), mTimeToSampleCount(0), mTimeToSample(), mSampleTimeEntries(NULL), @@ -159,7 +160,7 @@ bool SampleTable::isValid() const { return mChunkOffsetOffset >= 0 && mSampleToChunkOffset >= 0 && mSampleSizeOffset >= 0 - && !mTimeToSample.empty(); + && mHasTimeToSample; } status_t SampleTable::setChunkOffsetParams( @@ -324,7 +325,7 @@ status_t SampleTable::setSampleSizeParams( status_t SampleTable::setTimeToSampleParams( off64_t data_offset, size_t data_size) { - if (!mTimeToSample.empty() || data_size < 8) { + if (mHasTimeToSample || data_size < 8) { return ERROR_MALFORMED; } @@ -364,6 +365,8 @@ status_t SampleTable::setTimeToSampleParams( for (size_t i = 0; i < mTimeToSample.size(); ++i) { mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); } + + mHasTimeToSample = true; return OK; } diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index 3764adb..465f37c 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -111,6 +111,7 @@ private: uint32_t mDefaultSampleSize; uint32_t mNumSampleSizes; + bool mHasTimeToSample; uint32_t mTimeToSampleCount; Vector mTimeToSample; -- cgit v1.1 From c27a16c33c78a36482336a16199b1b8be794cea4 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 21 Apr 2016 23:22:00 -0700 Subject: audiopolicy: Fix notification not sent for session release Change-Id: Ifba4025532debc50c7931d08a9bcd1593d9b1721 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 4 ---- services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 6a43bea..fce471f 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -325,10 +325,6 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", audioSession); } - - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)audioSession, - AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); - return status; } diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 96bc4c7..54b1982 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -282,6 +282,8 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output, { ALOGV("doReleaseOutput from tid %d", gettid()); Mutex::Autolock _l(mLock); + onOutputSessionEffectsUpdate(stream, session, + AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); mAudioPolicyManager->releaseOutput(output, stream, session); } -- cgit v1.1 From 244deea89aaf3c5dfa8bd369a845276ae501cb5a Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 22 Apr 2016 18:26:43 -0700 Subject: audiopolicy: Revert all session callback patches. * This has been rearchitected in a better way, as this feature turns out to be more difficult than it seems. * Reverting all of this stuff and rolling it into a single commit. This reverts commit c27a16c33c78a36482336a16199b1b8be794cea4. This reverts commit 32ef0556ae58ff6b7c6fe6fb0a17d3ff7f01de31. This reverts commit 489c9fb62f02e1d23d6d6c89b22f7d19c596e65e. This reverts commit a4123803d0a0e9e0c69faa4207d357cc74a65d58. This reverts commit e13b58b988ab642d4ae5ca6d0a89013510714956. This reverts commit 47f8c7303c9e2054f1492b02b6c7472385c52dc9. This reverts commit 0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa. Change-Id: Iaed9f198d806aa414c95960713e8187c98db248b --- include/media/AudioPolicy.h | 1 - include/media/AudioSystem.h | 11 --- include/media/IAudioPolicyService.h | 2 - include/media/IAudioPolicyServiceClient.h | 6 -- media/libmedia/AudioSystem.cpp | 34 +------- media/libmedia/IAudioPolicyService.cpp | 20 ----- media/libmedia/IAudioPolicyServiceClient.cpp | 31 +------ services/audiopolicy/AudioPolicyInterface.h | 6 -- .../audiopolicy/service/AudioPolicyClientImpl.cpp | 9 -- .../audiopolicy/service/AudioPolicyEffects.cpp | 27 +----- services/audiopolicy/service/AudioPolicyEffects.h | 12 +-- .../service/AudioPolicyInterfaceImpl.cpp | 32 ++----- .../audiopolicy/service/AudioPolicyService.cpp | 97 +--------------------- services/audiopolicy/service/AudioPolicyService.h | 45 +--------- 14 files changed, 18 insertions(+), 315 deletions(-) diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h index 5a82bae..feed402 100644 --- a/include/media/AudioPolicy.h +++ b/include/media/AudioPolicy.h @@ -42,7 +42,6 @@ namespace android { // AudioSystem's implementation of the AudioPolicyClient interface // keep in sync with AudioSystem.java #define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0 -#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10 #define MIX_STATE_DISABLED -1 #define MIX_STATE_IDLE 0 diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index be1d114..26a0bb2 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -31,10 +31,6 @@ namespace android { typedef void (*audio_error_callback)(status_t err); typedef void (*dynamic_policy_callback)(int event, String8 regId, int val); -typedef void (*effect_session_callback)(int event, - audio_stream_type_t stream, audio_unique_id_t sessionId, - audio_output_flags_t flags, audio_channel_mask_t channelMask, - uid_t uid, bool added); class IAudioFlinger; class IAudioPolicyService; @@ -96,7 +92,6 @@ public: static void setErrorCallback(audio_error_callback cb); static void setDynPolicyCallback(dynamic_policy_callback cb); - static status_t setEffectSessionCallback(effect_session_callback cb); // helper function to obtain AudioFlinger service handle static const sp get_audio_flinger(); @@ -424,11 +419,6 @@ private: virtual void onAudioPortListUpdate(); virtual void onAudioPatchListUpdate(); virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); - virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); private: Mutex mLock; @@ -448,7 +438,6 @@ private: static sp gAudioFlinger; static audio_error_callback gAudioErrorCallback; static dynamic_policy_callback gDynPolicyCallback; - static effect_session_callback gEffectSessionCallback; static size_t gInBuffSize; // previous parameters for recording buffer size queries diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 3a7bd68..6b93f6f 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -165,8 +165,6 @@ public: const audio_attributes_t *attributes, audio_io_handle_t *handle) = 0; virtual status_t stopAudioSource(audio_io_handle_t handle) = 0; - - virtual status_t setEffectSessionCallbacksEnabled(bool enabled) = 0; }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h index 18aed8d..a7f2cc3 100644 --- a/include/media/IAudioPolicyServiceClient.h +++ b/include/media/IAudioPolicyServiceClient.h @@ -37,12 +37,6 @@ public: virtual void onAudioPatchListUpdate() = 0; // Notifies a change in the mixing state of a specific mix in a dynamic audio policy virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; - // Notifies when a default effect set is attached to a session/stream - virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added) = 0; }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 5bd8747..9d645f0 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -37,7 +37,7 @@ sp AudioSystem::gAudioFlinger; sp AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; -effect_session_callback AudioSystem::gEffectSessionCallback = NULL; + // establish binder interface to AudioFlinger service const sp AudioSystem::get_audio_flinger() @@ -652,21 +652,6 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback( gDynPolicyCallback = cb; } -/*static*/ status_t AudioSystem::setEffectSessionCallback(effect_session_callback cb) -{ - const sp& aps = AudioSystem::get_audio_policy_service(); - if (aps == 0) return PERMISSION_DENIED; - - Mutex::Autolock _l(gLock); - gEffectSessionCallback = cb; - - status_t status = aps->setEffectSessionCallbacksEnabled(cb != NULL); - if (status != OK) { - gEffectSessionCallback = NULL; - } - return status; -} - // client singleton for AudioPolicyService binder interface // protected by gLockAPS sp AudioSystem::gAudioPolicyService; @@ -1238,23 +1223,6 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate( } } -void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_session_t sessionId, - audio_output_flags_t flags, audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)", stream, sessionId, added); - effect_session_callback cb = NULL; - { - Mutex::Autolock _l(AudioSystem::gLock); - cb = gEffectSessionCallback; - } - - if (cb != NULL) { - cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, stream, sessionId, flags, channelMask, uid, added); - } -} - void AudioSystem::AudioPolicyServiceClient::binderDied(const wp& who __unused) { { diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 6ff8149..76b5924 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -74,7 +74,6 @@ enum { START_AUDIO_SOURCE, STOP_AUDIO_SOURCE, SET_AUDIO_PORT_CALLBACK_ENABLED, - SET_EFFECT_SESSION_CALLBACK_ENABLED, }; #define MAX_ITEMS_PER_LIST 1024 @@ -656,18 +655,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) @@ -1251,13 +1238,6 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; - case SET_EFFECT_SESSION_CALLBACK_ENABLED: { - CHECK_INTERFACE(IAudioPolicyService, data, reply); - status_t status = setEffectSessionCallbacksEnabled(data.readInt32() == 1); - reply->writeInt32(status); - return NO_ERROR; - } break; - case ACQUIRE_SOUNDTRIGGER_SESSION: { CHECK_INTERFACE(IAudioPolicyService, data, reply); sp client = interface_cast( diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp index ecf0d1f..65cc7d6 100644 --- a/media/libmedia/IAudioPolicyServiceClient.cpp +++ b/media/libmedia/IAudioPolicyServiceClient.cpp @@ -30,8 +30,7 @@ namespace android { enum { PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION, PATCH_LIST_UPDATE, - MIX_STATE_UPDATE, - OUTPUT_SESSION_EFFECTS_UPDATE + MIX_STATE_UPDATE }; class BpAudioPolicyServiceClient : public BpInterface @@ -64,23 +63,6 @@ public: data.writeInt32(state); remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); } - - void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added) - { - Parcel data, reply; - data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor()); - data.writeInt32(stream); - data.writeInt32(sessionId); - data.writeInt32(flags); - data.writeInt32(channelMask); - data.writeInt32(uid); - data.writeInt32(added ? 1 : 0); - remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); - } }; IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient"); @@ -108,17 +90,6 @@ status_t BnAudioPolicyServiceClient::onTransact( onDynamicPolicyMixStateUpdate(regId, state); return NO_ERROR; } - case OUTPUT_SESSION_EFFECTS_UPDATE: { - CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply); - audio_stream_type_t stream = static_cast(data.readInt32()); - audio_session_t sessionId = static_cast(data.readInt32()); - audio_output_flags_t flags = static_cast(data.readInt32()); - audio_channel_mask_t channelMask = static_cast(data.readInt32()); - uid_t uid = static_cast(data.readInt32()); - bool added = data.readInt32() > 0; - onOutputSessionEffectsUpdate(stream, sessionId, flags, channelMask, uid, added); - return NO_ERROR; - } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index bf9dd64..c1e7bc0 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -331,12 +331,6 @@ public: virtual audio_unique_id_t newAudioUniqueId() = 0; virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; - - virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added) = 0; }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index f1a2ae9..489a9be 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -219,15 +219,6 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate( mAudioPolicyService->onDynamicPolicyMixStateUpdate(regId, state); } -void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_session_t sessionId, - audio_output_flags_t flags, audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, - flags, channelMask, uid, added); -} - audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId() { return AudioSystem::newAudioUniqueId(); diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index fce471f..26857b1 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -28,7 +28,6 @@ #include #include #include -#include "AudioPolicyService.h" #include "AudioPolicyEffects.h" #include "ServiceUtilities.h" @@ -38,8 +37,7 @@ namespace android { // AudioPolicyEffects Implementation // ---------------------------------------------------------------------------- -AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) : - mAudioPolicyService(audioPolicyService) +AudioPolicyEffects::AudioPolicyEffects() { // load automatic audio effect modules if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE2, R_OK) == 0) { @@ -246,7 +244,6 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); - } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -275,29 +272,9 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, procDesc->setProcessorEnabled(true); } - return status; } -status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t /* output */, - audio_stream_type_t stream, - int session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, uid_t uid) -{ - if (uint32_t(stream) >= AUDIO_STREAM_CNT) { - return BAD_VALUE; - } - ALOGV("doAddOutputSessionEffects()"); - - // notify listeners - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, - flags, channelMask, uid, true); - - // Never return an error if effects setup fails. - return NO_ERROR; -} - status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -322,7 +299,7 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); - ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", + ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", audioSession); } return status; diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 1c251e0..3845050 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -31,8 +31,6 @@ namespace android { -class AudioPolicyService; - // ---------------------------------------------------------------------------- // AudioPolicyEffects class @@ -46,7 +44,7 @@ public: // The constructor will parse audio_effects.conf // First it will look whether vendor specific file exists, // otherwise it will parse the system default file. - AudioPolicyEffects(AudioPolicyService *audioPolicyService); + AudioPolicyEffects(); virtual ~AudioPolicyEffects(); // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService @@ -86,12 +84,6 @@ public: audio_stream_type_t stream, int audioSession); - status_t doAddOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - int audioSession, - audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, - audio_channel_mask_t channelMask = 0, uid_t uid = 0); - private: // class to store the description of an effects and its parameters @@ -200,8 +192,6 @@ private: KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams; // Automatic output effects are unique for audiosession ID KeyedVector< int32_t, EffectVector* > mOutputSessions; - - AudioPolicyService *mAudioPolicyService; }; }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 54b1982..c0d3866 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -18,7 +18,6 @@ //#define LOG_NDEBUG 0 #include -#include #include "AudioPolicyService.h" #include "ServiceUtilities.h" @@ -163,29 +162,18 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, return NO_INIT; } ALOGV("getOutput()"); - status_t status; - sp audioPolicyEffects; - { - Mutex::Autolock _l(mLock); + Mutex::Autolock _l(mLock); - // if the caller is us, trust the specified uid - if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { - uid_t newclientUid = IPCThreadState::self()->getCallingUid(); - if (uid != (uid_t)-1 && uid != newclientUid) { - ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); - } - uid = newclientUid; + // if the caller is us, trust the specified uid + if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { + uid_t newclientUid = IPCThreadState::self()->getCallingUid(); + if (uid != (uid_t)-1 && uid != newclientUid) { + ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); } - status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, - format, channelMask, flags, selectedDeviceId, offloadInfo); - audioPolicyEffects = mAudioPolicyEffects; - } - - if (audioPolicyEffects != 0) { - audioPolicyEffects->doAddOutputSessionEffects(*output, *stream, session, flags, channelMask, uid); + uid = newclientUid; } - - return status; + return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, + format, channelMask, flags, selectedDeviceId, offloadInfo); } status_t AudioPolicyService::startOutput(audio_io_handle_t output, @@ -282,8 +270,6 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output, { ALOGV("doReleaseOutput from tid %d", gettid()); Mutex::Autolock _l(mLock); - onOutputSessionEffectsUpdate(stream, session, - AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); mAudioPolicyManager->releaseOutput(output, stream, session); } diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index eead3ac..12cca65 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -116,7 +116,7 @@ void AudioPolicyService::onFirstRef() #endif } // load audio processing modules - spaudioPolicyEffects = new AudioPolicyEffects(this); + spaudioPolicyEffects = new AudioPolicyEffects(); { Mutex::Autolock _l(mLock); mAudioPolicyEffects = audioPolicyEffects; @@ -177,23 +177,6 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); } -status_t AudioPolicyService::setEffectSessionCallbacksEnabled(bool enabled) -{ - Mutex::Autolock _l(mNotificationClientsLock); - - uid_t uid = IPCThreadState::self()->getCallingUid(); - if (mNotificationClients.indexOfKey(uid) < 0) { - return NO_INIT; - } - if (!modifyAudioRoutingAllowed()) { - ALOGE("setEffectSessionCallbacksEnabled requires MODIFY_AUDIO_ROUTING"); - return PERMISSION_DENIED; - } - mNotificationClients.valueFor(uid)->setEffectSessionCallbacksEnabled(enabled); - return OK; -} - - // removeNotificationClient() is called when the client process dies. void AudioPolicyService::removeNotificationClient(uid_t uid) { @@ -271,37 +254,11 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); } -void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)", - stream, sessionId, added); - mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, - flags, channelMask, uid, added); -} - -void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - Mutex::Autolock _l(mNotificationClientsLock); - for (size_t i = 0; i < mNotificationClients.size(); i++) { - mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, - flags, channelMask, uid, added); - } -} - AudioPolicyService::NotificationClient::NotificationClient(const sp& service, const sp& client, uid_t uid) : mService(service), mUid(uid), mAudioPolicyServiceClient(client), - mAudioPortCallbacksEnabled(false), - mEffectSessionCallbacksEnabled(false) + mAudioPortCallbacksEnabled(false) { } @@ -332,17 +289,6 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } } -void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate( - audio_stream_type_t stream, audio_session_t sessionId, - audio_output_flags_t flags, audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) { - mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, - flags, channelMask, uid, added); - } -} - void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( String8 regId, int32_t state) { @@ -356,10 +302,6 @@ void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool e mAudioPortCallbacksEnabled = enabled; } -void AudioPolicyService::NotificationClient::setEffectSessionCallbacksEnabled(bool enabled) -{ - mEffectSessionCallbacksEnabled = enabled; -} void AudioPolicyService::binderDied(const wp& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), @@ -637,21 +579,6 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); mLock.lock(); } break; - case EFFECT_SESSION_UPDATE: { - EffectSessionUpdateData *data = - (EffectSessionUpdateData *)command->mParam.get(); - ALOGV("AudioCommandThread() processing effect session update %d %d %d", - data->mStream, data->mSessionId, data->mAdded); - svc = mService.promote(); - if (svc == 0) { - break; - } - mLock.unlock(); - svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, - data->mFlags, data->mChannelMask, data->mUid, data->mAdded); - mLock.lock(); - } break; - default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -924,26 +851,6 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( sendCommand(command); } -void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( - audio_stream_type_t stream, audio_session_t sessionId, - audio_output_flags_t flags, audio_channel_mask_t channelMask, - uid_t uid, bool added) -{ - sp command = new AudioCommand(); - command->mCommand = EFFECT_SESSION_UPDATE; - EffectSessionUpdateData *data = new EffectSessionUpdateData(); - data->mStream = stream; - data->mSessionId = sessionId; - data->mFlags = flags; - data->mChannelMask = channelMask; - data->mUid = uid; - data->mAdded = added; - command->mParam = data; - ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)", - stream, sessionId, added); - sendCommand(command); -} - status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index bc2875d..d11294b 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -202,8 +202,6 @@ public: audio_io_handle_t *handle); virtual status_t stopAudioSource(audio_io_handle_t handle); - virtual status_t setEffectSessionCallbacksEnabled(bool enabled); - status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -231,17 +229,6 @@ public: void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); - void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); - void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); - private: AudioPolicyService() ANDROID_API; virtual ~AudioPolicyService(); @@ -273,8 +260,7 @@ private: UPDATE_AUDIOPORT_LIST, UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, - DYN_POLICY_MIX_STATE_UPDATE, - EFFECT_SESSION_UPDATE, + DYN_POLICY_MIX_STATE_UPDATE }; AudioCommandThread (String8 name, const wp& service); @@ -317,11 +303,6 @@ private: int delayMs); void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); - void effectSessionUpdateCommand(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); private: class AudioCommandData; @@ -418,16 +399,6 @@ private: int32_t mState; }; - class EffectSessionUpdateData : public AudioCommandData { - public: - audio_stream_type_t mStream; - audio_session_t mSessionId; - audio_output_flags_t mFlags; - audio_channel_mask_t mChannelMask; - uid_t mUid; - bool mAdded; - }; - Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands @@ -537,12 +508,6 @@ private: virtual audio_unique_id_t newAudioUniqueId(); - virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); - private: AudioPolicyService *mAudioPolicyService; }; @@ -559,12 +524,7 @@ private: void onAudioPatchListUpdate(); void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void setAudioPortCallbacksEnabled(bool enabled); - void setEffectSessionCallbacksEnabled(bool enabled); - void onOutputSessionEffectsUpdate(audio_stream_type_t stream, - audio_session_t sessionId, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, - uid_t uid, bool added); + // IBinder::DeathRecipient virtual void binderDied(const wp& who); @@ -576,7 +536,6 @@ private: const uid_t mUid; const sp mAudioPolicyServiceClient; bool mAudioPortCallbacksEnabled; - bool mEffectSessionCallbacksEnabled; }; // Internal dump utilities. -- cgit v1.1 From 3f9eb321481de3e118632a594bf1b0c9001c281c Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 22 Apr 2016 18:32:39 -0700 Subject: audiopolicy: Add AudioSessionInfo API * This patch introduces a new API which allows applications to query the state of the audio effects system, and receive callbacks with the necessary information to attach effects to any stream. * In the future, this may come as part of the AudioPort system, but since that's an active area of development by Google, we will dodge it for now. * The policy now simply keeps a refcounted list of objects which hold various bits of stream metadata. Callbacks are sent on stream open/close to applications which might be listening for them. Change-Id: I2d554d36e1378f4eb7b276010a3bfe8345c22ecd --- include/media/AudioPolicy.h | 2 + include/media/AudioSession.h | 71 +++++++++++++ include/media/AudioSystem.h | 7 ++ include/media/IAudioPolicyService.h | 3 + include/media/IAudioPolicyServiceClient.h | 3 + media/libmedia/AudioSystem.cpp | 39 +++++++- media/libmedia/IAudioPolicyService.cpp | 42 ++++++++ media/libmedia/IAudioPolicyServiceClient.cpp | 30 +++++- services/audiopolicy/AudioPolicyInterface.h | 3 + .../audiopolicy/service/AudioPolicyClientImpl.cpp | 6 ++ .../audiopolicy/service/AudioPolicyEffects.cpp | 111 ++++++++++++++++++++- services/audiopolicy/service/AudioPolicyEffects.h | 21 +++- .../service/AudioPolicyInterfaceImpl.cpp | 66 +++++++++--- .../service/AudioPolicyInterfaceImplLegacy.cpp | 5 + .../audiopolicy/service/AudioPolicyService.cpp | 54 +++++++++- services/audiopolicy/service/AudioPolicyService.h | 22 +++- 16 files changed, 465 insertions(+), 20 deletions(-) create mode 100644 include/media/AudioSession.h diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h index feed402..7e33df7 100644 --- a/include/media/AudioPolicy.h +++ b/include/media/AudioPolicy.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace android { @@ -42,6 +43,7 @@ namespace android { // AudioSystem's implementation of the AudioPolicyClient interface // keep in sync with AudioSystem.java #define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0 +#define AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE 10 #define MIX_STATE_DISABLED -1 #define MIX_STATE_IDLE 0 diff --git a/include/media/AudioSession.h b/include/media/AudioSession.h new file mode 100644 index 0000000..d9658cc --- /dev/null +++ b/include/media/AudioSession.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 The CyanogenMod 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 ANDROID_AUDIOSESSION_H +#define ANDROID_AUDIOSESSION_H + +#include +#include + +#include + +#include +#include +#include + +namespace android { + +// class to store streaminfo +class AudioSessionInfo : public RefBase { +public: + AudioSessionInfo(int session, audio_stream_type_t stream, audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid) : + mSessionId(session), mStream(stream), mFlags(flags), mChannelMask(channelMask), + mUid(uid), mRefCount(0) {} + + AudioSessionInfo() : mSessionId(0), mStream(AUDIO_STREAM_DEFAULT), mFlags(AUDIO_OUTPUT_FLAG_NONE), mChannelMask(AUDIO_CHANNEL_NONE), mUid(0) {} + + /*virtual*/ ~AudioSessionInfo() {} + + int mSessionId; + audio_stream_type_t mStream; + audio_output_flags_t mFlags; + audio_channel_mask_t mChannelMask; + uid_t mUid; + + // AudioPolicyManager keeps mLock, no need for lock on reference count here + int mRefCount; + + void readFromParcel(const Parcel &parcel) { + mSessionId = parcel.readInt32(); + mStream = static_cast(parcel.readInt32()); + mFlags = static_cast(parcel.readInt32()); + mChannelMask = static_cast(parcel.readInt32()); + mUid = static_cast(parcel.readInt32()); + } + + void writeToParcel(Parcel *parcel) const { + parcel->writeInt32(mSessionId); + parcel->writeInt32(mStream); + parcel->writeInt32(mFlags); + parcel->writeInt32(mChannelMask); + parcel->writeInt32(mUid); + } +}; + +}; // namespace android + +#endif // ANDROID_AUDIOSESSION_H diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 26a0bb2..3f4a610 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -31,6 +31,8 @@ namespace android { typedef void (*audio_error_callback)(status_t err); typedef void (*dynamic_policy_callback)(int event, String8 regId, int val); +typedef void (*audio_session_callback)(int event, + sp& session, bool added); class IAudioFlinger; class IAudioPolicyService; @@ -92,6 +94,7 @@ public: static void setErrorCallback(audio_error_callback cb); static void setDynPolicyCallback(dynamic_policy_callback cb); + static status_t setAudioSessionCallback(audio_session_callback cb); // helper function to obtain AudioFlinger service handle static const sp get_audio_flinger(); @@ -319,6 +322,8 @@ public: audio_io_handle_t *handle); static status_t stopAudioSource(audio_io_handle_t handle); + static status_t listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions); // ---------------------------------------------------------------------------- @@ -419,6 +424,7 @@ private: virtual void onAudioPortListUpdate(); virtual void onAudioPatchListUpdate(); virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + virtual void onOutputSessionEffectsUpdate(sp& info, bool added); private: Mutex mLock; @@ -438,6 +444,7 @@ private: static sp gAudioFlinger; static audio_error_callback gAudioErrorCallback; static dynamic_policy_callback gDynPolicyCallback; + static audio_session_callback gAudioSessionCallback; static size_t gInBuffSize; // previous parameters for recording buffer size queries diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 6b93f6f..1df91ee 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -165,6 +165,9 @@ public: const audio_attributes_t *attributes, audio_io_handle_t *handle) = 0; virtual status_t stopAudioSource(audio_io_handle_t handle) = 0; + + virtual status_t listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions) = 0; }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h index a7f2cc3..ec38157 100644 --- a/include/media/IAudioPolicyServiceClient.h +++ b/include/media/IAudioPolicyServiceClient.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace android { @@ -37,6 +38,8 @@ public: virtual void onAudioPatchListUpdate() = 0; // Notifies a change in the mixing state of a specific mix in a dynamic audio policy virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; + // Notifies when a default effect set is attached to a session/stream + virtual void onOutputSessionEffectsUpdate(sp& info, bool added) = 0; }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 9d645f0..2e9fca9 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -37,7 +37,7 @@ sp AudioSystem::gAudioFlinger; sp AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; - +audio_session_callback AudioSystem::gAudioSessionCallback = NULL; // establish binder interface to AudioFlinger service const sp AudioSystem::get_audio_flinger() @@ -652,6 +652,17 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback( gDynPolicyCallback = cb; } +/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + + Mutex::Autolock _l(gLock); + gAudioSessionCallback = cb; + + return NO_ERROR; +} + // client singleton for AudioPolicyService binder interface // protected by gLockAPS sp AudioSystem::gAudioPolicyService; @@ -1223,6 +1234,32 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate( } } +// --------------------------------------------------------------------------- + +status_t AudioSystem::listAudioSessions(audio_stream_type_t stream, + Vector< sp> &sessions) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->listAudioSessions(stream, sessions); +} + +void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate( + sp& info, bool added) +{ + ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)", + info->mStream, info->mSessionId, added); + audio_session_callback cb = NULL; + { + Mutex::Autolock _l(AudioSystem::gLock); + cb = gAudioSessionCallback; + } + + if (cb != NULL) { + cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added); + } +} + void AudioSystem::AudioPolicyServiceClient::binderDied(const wp& who __unused) { { diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 76b5924..abae614 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -74,6 +74,7 @@ enum { START_AUDIO_SOURCE, STOP_AUDIO_SOURCE, SET_AUDIO_PORT_CALLBACK_ENABLED, + LIST_AUDIO_SESSIONS, }; #define MAX_ITEMS_PER_LIST 1024 @@ -767,6 +768,30 @@ public: status = (status_t)reply.readInt32(); return status; } + + virtual status_t listAudioSessions(audio_stream_type_t streams, + Vector< sp> &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 info = new AudioSessionInfo(); + info->readFromParcel(reply); + sessions.push_back(info); + } + } + return status; + } + }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -1238,6 +1263,23 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; + case LIST_AUDIO_SESSIONS: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_stream_type_t streams = (audio_stream_type_t)data.readInt32(); + + Vector< sp> sessions; + status_t status = listAudioSessions(streams, sessions); + + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeUint32(static_cast(sessions.size())); + for (size_t i = 0; i < sessions.size(); i++) { + sessions[i]->writeToParcel(reply); + } + } + return NO_ERROR; + } + case ACQUIRE_SOUNDTRIGGER_SESSION: { CHECK_INTERFACE(IAudioPolicyService, data, reply); sp client = interface_cast( diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp index 65cc7d6..a325996 100644 --- a/media/libmedia/IAudioPolicyServiceClient.cpp +++ b/media/libmedia/IAudioPolicyServiceClient.cpp @@ -30,7 +30,8 @@ namespace android { enum { PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION, PATCH_LIST_UPDATE, - MIX_STATE_UPDATE + MIX_STATE_UPDATE, + OUTPUT_SESSION_EFFECTS_UPDATE }; class BpAudioPolicyServiceClient : public BpInterface @@ -63,6 +64,19 @@ public: data.writeInt32(state); remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); } + + void onOutputSessionEffectsUpdate(sp& info, bool added) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor()); + 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); + } }; IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient"); @@ -90,6 +104,20 @@ status_t BnAudioPolicyServiceClient::onTransact( onDynamicPolicyMixStateUpdate(regId, state); return NO_ERROR; } + case OUTPUT_SESSION_EFFECTS_UPDATE: { + CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply); + audio_stream_type_t stream = static_cast(data.readInt32()); + audio_session_t sessionId = static_cast(data.readInt32()); + audio_output_flags_t flags = static_cast(data.readInt32()); + audio_channel_mask_t channelMask = static_cast(data.readInt32()); + uid_t uid = static_cast(data.readInt32()); + bool added = data.readInt32() > 0; + + sp info = new AudioSessionInfo( + sessionId, stream, flags, channelMask, uid); + onOutputSessionEffectsUpdate(info, added); + return NO_ERROR; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index c1e7bc0..93e6266 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -331,6 +331,9 @@ public: virtual audio_unique_id_t newAudioUniqueId() = 0; virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0; + + virtual void onOutputSessionEffectsUpdate(sp& streamInfo, bool added) = 0; + }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp index 489a9be..82720f4 100644 --- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp @@ -219,6 +219,12 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate( mAudioPolicyService->onDynamicPolicyMixStateUpdate(regId, state); } +void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate( + sp& info, bool added) +{ + mAudioPolicyService->onOutputSessionEffectsUpdate(info, added); +} + audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId() { return AudioSystem::newAudioUniqueId(); diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 26857b1..31b1637 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "AudioPolicyService.h" #include "AudioPolicyEffects.h" #include "ServiceUtilities.h" @@ -37,7 +38,8 @@ namespace android { // AudioPolicyEffects Implementation // ---------------------------------------------------------------------------- -AudioPolicyEffects::AudioPolicyEffects() +AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) : + mAudioPolicyService(audioPolicyService) { // load automatic audio effect modules if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE2, R_OK) == 0) { @@ -226,6 +228,8 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, { status_t status = NO_ERROR; + ALOGV("addOutputSessionEffects %d", audioSession); + Mutex::Autolock _l(mLock); // create audio processors according to stream // FIXME: should we have specific post processing settings for internal streams? @@ -233,6 +237,22 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (stream >= AUDIO_STREAM_PUBLIC_CNT) { stream = AUDIO_STREAM_MUSIC; } + + // send the streaminfo notification only once + ssize_t sidx = mOutputAudioSessionInfo.indexOfKey(audioSession); + if (sidx >= 0) { + // AudioSessionInfo is existing and we just need to increase ref count + sp info = mOutputAudioSessionInfo.valueAt(sidx); + info->mRefCount++; + + if (info->mRefCount == 1) { + mAudioPolicyService->onOutputSessionEffectsUpdate(info, true); + } + ALOGV("addOutputSessionEffects(): session info %d refCount=%d", audioSession, info->mRefCount); + } else { + ALOGV("addOutputSessionEffects(): no output stream info found for stream"); + } + ssize_t index = mOutputStreams.indexOfKey(stream); if (index < 0) { ALOGV("addOutputSessionEffects(): no output processing needed for this stream"); @@ -275,6 +295,81 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, return status; } +status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */, + audio_stream_type_t stream, + int session) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mLock); + + ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session); + if (idx >= 0) { + sp info = mOutputAudioSessionInfo.valueAt(idx); + if (info->mRefCount == 0) { + mOutputAudioSessionInfo.removeItemsAt(idx); + } + ALOGV("releaseOutputAudioSessionInfo() sessionId=%d refcount=%d", + session, info->mRefCount); + } else { + ALOGV("releaseOutputAudioSessionInfo() no session info found"); + } + return NO_ERROR; +} + +status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* output */, + audio_stream_type_t stream, + int session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mLock); + + // update AudioSessionInfo. This is used in the stream open/close path + // to notify userspace applications about session creation and + // teardown, allowing the app to make decisions about effects for + // a particular stream. This is independent of the current + // output_session_processing feature which forcibly attaches a + // static list of effects to a stream. + ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session); + sp info; + if (idx < 0) { + info = new AudioSessionInfo(session, stream, flags, channelMask, uid); + mOutputAudioSessionInfo.add(session, info); + } else { + // the streaminfo may actually change + info = mOutputAudioSessionInfo.valueAt(idx); + info->mFlags = flags; + info->mChannelMask = channelMask; + } + + ALOGV("updateOutputAudioSessionInfo() sessionId=%d, flags=0x%x, channelMask=0x%x uid=%d refCount=%d", + info->mSessionId, info->mFlags, info->mChannelMask, info->mUid, info->mRefCount); + + return NO_ERROR; +} + +status_t AudioPolicyEffects::listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions) +{ + ALOGV("listAudioSessions() streams %d", streams); + + for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) { + sp info = mOutputAudioSessionInfo.valueAt(i); + if (streams == -1 || info->mStream == streams) { + sessions.push_back(info); + } + } + + return NO_ERROR; +} + status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -284,7 +379,19 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu (void) stream; // argument not used for now Mutex::Autolock _l(mLock); - ssize_t index = mOutputSessions.indexOfKey(audioSession); + ssize_t index = mOutputAudioSessionInfo.indexOfKey(audioSession); + if (index >= 0) { + sp info = mOutputAudioSessionInfo.valueAt(index); + info->mRefCount--; + if (info->mRefCount == 0) { + mAudioPolicyService->onOutputSessionEffectsUpdate(info, false); + } + ALOGV("releaseOutputSessionEffects(): session=%d refCount=%d", info->mSessionId, info->mRefCount); + } else { + ALOGV("releaseOutputSessionEffects: no stream info was attached to this stream"); + } + + index = mOutputSessions.indexOfKey(audioSession); if (index < 0) { ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); return NO_ERROR; diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 3845050..a95d49f 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -31,6 +31,8 @@ namespace android { +class AudioPolicyService; + // ---------------------------------------------------------------------------- // AudioPolicyEffects class @@ -44,7 +46,7 @@ public: // The constructor will parse audio_effects.conf // First it will look whether vendor specific file exists, // otherwise it will parse the system default file. - AudioPolicyEffects(); + AudioPolicyEffects(AudioPolicyService *audioPolicyService); virtual ~AudioPolicyEffects(); // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService @@ -84,6 +86,19 @@ public: audio_stream_type_t stream, int audioSession); + status_t updateOutputAudioSessionInfo(audio_io_handle_t output, + audio_stream_type_t stream, + int audioSession, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid); + + status_t releaseOutputAudioSessionInfo(audio_io_handle_t output, + audio_stream_type_t stream, + int audioSession); + + status_t listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions); + private: // class to store the description of an effects and its parameters @@ -192,6 +207,10 @@ private: KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams; // Automatic output effects are unique for audiosession ID KeyedVector< int32_t, EffectVector* > mOutputSessions; + // Stream info for session events + KeyedVector< int32_t, sp > mOutputAudioSessionInfo; + + AudioPolicyService *mAudioPolicyService; }; }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index c0d3866..f0be341 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -161,19 +161,32 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, if (mAudioPolicyManager == NULL) { return NO_INIT; } - ALOGV("getOutput()"); - Mutex::Autolock _l(mLock); + ALOGV("getOutputForAttr()"); + status_t status = NO_ERROR; + sp audioPolicyEffects; + { + Mutex::Autolock _l(mLock); - // if the caller is us, trust the specified uid - if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { - uid_t newclientUid = IPCThreadState::self()->getCallingUid(); - if (uid != (uid_t)-1 && uid != newclientUid) { - ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); + // if the caller is us, trust the specified uid + if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { + uid_t newclientUid = IPCThreadState::self()->getCallingUid(); + if (uid != (uid_t)-1 && uid != newclientUid) { + ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); + } + uid = newclientUid; } - uid = newclientUid; + status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, + format, channelMask, flags, selectedDeviceId, offloadInfo); + + audioPolicyEffects = mAudioPolicyEffects; + } + + if (status == NO_ERROR && audioPolicyEffects != 0) { + audioPolicyEffects->updateOutputAudioSessionInfo(*output, + *stream, session, flags, channelMask, uid); } - return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate, - format, channelMask, flags, selectedDeviceId, offloadInfo); + + return status; } status_t AudioPolicyService::startOutput(audio_io_handle_t output, @@ -269,8 +282,16 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output, audio_session_t session) { ALOGV("doReleaseOutput from tid %d", gettid()); - Mutex::Autolock _l(mLock); - mAudioPolicyManager->releaseOutput(output, stream, session); + spaudioPolicyEffects; + { + Mutex::Autolock _l(mLock); + audioPolicyEffects = mAudioPolicyEffects; + mAudioPolicyManager->releaseOutput(output, stream, session); + } + if (audioPolicyEffects != 0) { + audioPolicyEffects->releaseOutputAudioSessionInfo(output, + stream, session); + } } status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, @@ -717,4 +738,25 @@ status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle) return mAudioPolicyManager->stopAudioSource(handle); } +status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions) +{ + sp audioPolicyEffects; + { + Mutex::Autolock _l(mLock); + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + audioPolicyEffects = mAudioPolicyEffects; + } + + if (audioPolicyEffects != 0) { + return audioPolicyEffects->listAudioSessions(streams, sessions); + } + + // no errors here if effects are not available + return NO_ERROR; +} + + }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index 318c6d2..0aad54d 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -642,4 +642,9 @@ status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle) return INVALID_OPERATION; } +status_t AudioPolicyService::listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions) +{ + return INVALID_OPERATION; +} }; // namespace android diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 12cca65..79370f4 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -116,7 +116,7 @@ void AudioPolicyService::onFirstRef() #endif } // load audio processing modules - spaudioPolicyEffects = new AudioPolicyEffects(); + spaudioPolicyEffects = new AudioPolicyEffects(this); { Mutex::Autolock _l(mLock); mAudioPolicyEffects = audioPolicyEffects; @@ -254,6 +254,21 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); } +void AudioPolicyService::onOutputSessionEffectsUpdate(sp& info, bool added) +{ + ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)", + info->mStream, info->mSessionId, added); + mOutputCommandThread->effectSessionUpdateCommand(info, added); +} + +void AudioPolicyService::doOnOutputSessionEffectsUpdate(sp& info, bool added) +{ + Mutex::Autolock _l(mNotificationClientsLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(info, added); + } +} + AudioPolicyService::NotificationClient::NotificationClient(const sp& service, const sp& client, uid_t uid) @@ -289,6 +304,14 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } } +void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate( + sp& info, bool added) +{ + if (mAudioPolicyServiceClient != 0) { + mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(info, added); + } +} + void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( String8 regId, int32_t state) { @@ -579,6 +602,21 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); mLock.lock(); } break; + case EFFECT_SESSION_UPDATE: { + EffectSessionUpdateData *data = + (EffectSessionUpdateData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing effect session update %d %d %d", + data->mAudioSessionInfo->mStream, data->mAudioSessionInfo->mSessionId, + data->mAdded); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnOutputSessionEffectsUpdate(data->mAudioSessionInfo, data->mAdded); + mLock.lock(); + } break; + default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -851,6 +889,20 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( sendCommand(command); } +void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( + sp& streamInfo, bool added) +{ + sp command = new AudioCommand(); + command->mCommand = EFFECT_SESSION_UPDATE; + EffectSessionUpdateData *data = new EffectSessionUpdateData(); + data->mAudioSessionInfo = streamInfo; + data->mAdded = added; + command->mParam = data; + ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)", + streamInfo->mStream, streamInfo->mSessionId, added); + sendCommand(command); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp& command, int delayMs) { { diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index d11294b..b7f55ae 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -202,6 +202,9 @@ public: audio_io_handle_t *handle); virtual status_t stopAudioSource(audio_io_handle_t handle); + virtual status_t listAudioSessions(audio_stream_type_t stream, + Vector< sp>& sessions); + status_t doStartOutput(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t session); @@ -229,6 +232,9 @@ public: void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + void onOutputSessionEffectsUpdate(sp& info, bool added); + void doOnOutputSessionEffectsUpdate(sp& info, bool added); + private: AudioPolicyService() ANDROID_API; virtual ~AudioPolicyService(); @@ -260,7 +266,8 @@ private: UPDATE_AUDIOPORT_LIST, UPDATE_AUDIOPATCH_LIST, SET_AUDIOPORT_CONFIG, - DYN_POLICY_MIX_STATE_UPDATE + DYN_POLICY_MIX_STATE_UPDATE, + EFFECT_SESSION_UPDATE, }; AudioCommandThread (String8 name, const wp& service); @@ -303,6 +310,7 @@ private: int delayMs); void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state); void insertCommand_l(AudioCommand *command, int delayMs = 0); + void effectSessionUpdateCommand(sp& info, bool added); private: class AudioCommandData; @@ -399,6 +407,12 @@ private: int32_t mState; }; + class EffectSessionUpdateData : public AudioCommandData { + public: + sp mAudioSessionInfo; + bool mAdded; + }; + Mutex mLock; Condition mWaitWorkCV; Vector < sp > mAudioCommands; // list of pending commands @@ -508,6 +522,9 @@ private: virtual audio_unique_id_t newAudioUniqueId(); + virtual void onOutputSessionEffectsUpdate(sp& info, bool added); + + private: AudioPolicyService *mAudioPolicyService; }; @@ -524,7 +541,8 @@ private: void onAudioPatchListUpdate(); void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); void setAudioPortCallbacksEnabled(bool enabled); - + void onOutputSessionEffectsUpdate(sp& info, + bool added); // IBinder::DeathRecipient virtual void binderDied(const wp& who); -- cgit v1.1 From 7592f6cde9d6a228e07377fc822adab0cad0faf7 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sat, 30 Apr 2016 19:49:32 -0700 Subject: avextensions: Fix warnings on 64-bit clang Change-Id: Ie4f49819ded3a6a0e308446829a109f57a607e88 --- media/libavextensions/common/ExtensionsLoader.hpp | 2 +- media/libavextensions/mediaplayerservice/AVNuUtils.cpp | 2 +- media/libavextensions/stagefright/AVUtils.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/media/libavextensions/common/ExtensionsLoader.hpp b/media/libavextensions/common/ExtensionsLoader.hpp index 48bcf3b..15728ed 100644 --- a/media/libavextensions/common/ExtensionsLoader.hpp +++ b/media/libavextensions/common/ExtensionsLoader.hpp @@ -49,7 +49,7 @@ static const char * CUSTOMIZATION_LIB_NAME = "libavenhancements.so"; template T *ExtensionsLoader::createInstance(const char *createFunctionName) { - ALOGV("createInstance(%dbit) : %s", sizeof(intptr_t)*8, createFunctionName); + (void)createFunctionName; // create extended object if extensions-lib is available and // AV_ENHANCEMENTS is enabled #if ENABLE_AV_ENHANCEMENTS diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp index 5f146c7..773a098 100644 --- a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp @@ -277,7 +277,7 @@ status_t AVNuUtils::convertToSinkFormatIfNeeded( return BAD_VALUE; } - ALOGV("convert %zu bytes (frames %d) of format %x", + ALOGV("convert %zu bytes (frames %zu) of format %x", buffer->size(), frames, srcFormat); audio_format_t dstFormat; diff --git a/media/libavextensions/stagefright/AVUtils.cpp b/media/libavextensions/stagefright/AVUtils.cpp index 413026b..a9cd4b2 100644 --- a/media/libavextensions/stagefright/AVUtils.cpp +++ b/media/libavextensions/stagefright/AVUtils.cpp @@ -812,7 +812,7 @@ status_t AVUtils::HEVCMuxer::parserProfileTierLevel(const uint8_t *data, size_t } static const uint8_t *findNextStartCode( const uint8_t *data, size_t length) { - ALOGV("findNextStartCode: %p %d", data, length); + ALOGV("findNextStartCode: %p %zu", data, length); size_t bytesLeft = length; -- cgit v1.1 From e67a2babcccf11e5209afc39d368eb79b1d35c21 Mon Sep 17 00:00:00 2001 From: Roman Birg Date: Tue, 3 May 2016 11:54:28 -0700 Subject: soundtrigger: fill in default extras from dsp We seem to get an improper offset when getting the value from the DSP (offset 100, data size 1), when this happens, return a new phrase event with valid extras which are initialized to some default values. Change-Id: Ie041f78fec6bdbcd82286b54a7b7fb0c98c740f5 Signed-off-by: Roman Birg --- services/soundtrigger/SoundTriggerHwService.cpp | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 9de6fe2..371c81a 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -270,6 +270,37 @@ void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognitio if (module == NULL) { return; } + if (event-> type == SOUND_MODEL_TYPE_KEYPHRASE && event->data_size != 0 + && event->data_offset != sizeof(struct sound_trigger_phrase_recognition_event)) { + // set some defaults for the phrase if the recognition event won't be parsed properly + // TODO: read defaults from the config + + struct sound_trigger_phrase_recognition_event newEvent; + memset(&newEvent, 0, sizeof(struct sound_trigger_phrase_recognition_event)); + + sp model = module->getModel(event->model); + + newEvent.num_phrases = 1; + newEvent.phrase_extras[0].id = 100; + newEvent.phrase_extras[0].recognition_modes = RECOGNITION_MODE_VOICE_TRIGGER; + newEvent.phrase_extras[0].confidence_level = 100; + newEvent.phrase_extras[0].num_levels = 1; + newEvent.phrase_extras[0].levels[0].level = 100; + newEvent.phrase_extras[0].levels[0].user_id = 100; + newEvent.common.status = event->status; + newEvent.common.type = event->type; + newEvent.common.model = event->model; + newEvent.common.capture_available = event->capture_available; + newEvent.common.capture_session = event->capture_session; + newEvent.common.capture_delay_ms = event->capture_delay_ms; + newEvent.common.capture_preamble_ms = event->capture_preamble_ms; + newEvent.common.trigger_in_data = event->trigger_in_data; + newEvent.common.audio_config = event->audio_config; + newEvent.common.data_size = event->data_size; + newEvent.common.data_offset = sizeof(struct sound_trigger_phrase_recognition_event); + + event = &newEvent.common; + } sp eventMemory = prepareRecognitionEvent_l(event); if (eventMemory == 0) { return; -- cgit v1.1 From eb6bd31da259ea399a8bb5b13e83929aaf9e3ac3 Mon Sep 17 00:00:00 2001 From: Sanjeev Garg Date: Fri, 1 Apr 2016 18:54:28 +0530 Subject: Revert "cameraservice: Run HAL3 in Non ZSL mode". Reverting the Temp change. This reverts commit f300e17bf3451bf821ccc48c45b243c84ebaff7f. Change-Id: Ib11e38eb8edd7523cb6cdb21caa511152ee62e45 --- services/camera/libcameraservice/api1/client2/Parameters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 4df8361..44447b4 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -910,7 +910,7 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) { } else { zslMode = true; } - zslMode = false; + ALOGI("%s: zslMode: %d slowJpegMode %d", __FUNCTION__, zslMode, slowJpegMode); lightFx = LIGHTFX_NONE; -- cgit v1.1 From 5c7669385726b8aab6a554e31cc720e27dd446e8 Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 11 May 2016 16:26:44 +0100 Subject: FFMPEGSoftCodec: Initialize the OMX param struct before using it Make sure all the items in the port param config are filled out, not just those we expect to use. Ref: CYNGNOS-2797 Change-Id: I9271a83fc6496cfe5ad14e45841cd8a05ffece30 --- media/libstagefright/FFMPEGSoftCodec.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/libstagefright/FFMPEGSoftCodec.cpp b/media/libstagefright/FFMPEGSoftCodec.cpp index 26afd89..f981c71 100644 --- a/media/libstagefright/FFMPEGSoftCodec.cpp +++ b/media/libstagefright/FFMPEGSoftCodec.cpp @@ -325,6 +325,7 @@ status_t FFMPEGSoftCodec::setVideoFormat( int32_t mode = 0; OMX_QCOM_PARAM_PORTDEFINITIONTYPE portFmt; + InitOMXParams(&portFmt); portFmt.nPortIndex = kPortIndexInput; if (msg->findInt32("use-arbitrary-mode", &mode) && mode) { -- cgit v1.1 From 8436846aeb997577415288270a2e4648f2a52ded Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Thu, 12 May 2016 10:19:57 -0700 Subject: Revert "nuplayer: Fix audio EOS notifiy on AudioSink not ready" This patch is buggy, and causing notifyConsume not called when the buffer is erased, causing audio discontinous cannot resume properly. This patch is not in 8994 CAF also. FEIJ-276 This reverts commit dc5f0eb0bb08885f63a97a111b02e234efc5c413. Change-Id: Idcb5ec9a419a979afe170d3a518ee7696a6fac6c --- media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index aa9842b..8afdefe 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -857,18 +857,6 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { // immediately after start. Investigate error message // "vorbis_dsp_synthesis returned -135", along with RTSP. uint32_t numFramesPlayed; - if(!mAudioSink->ready() && !mAudioQueue.empty()) { - while (!mAudioQueue.empty()) { - QueueEntry *entry = &*mAudioQueue.begin(); - if (entry->mBuffer == NULL) { - notifyEOS(true /* audio */, entry->mFinalResult); - } - mAudioQueue.erase(mAudioQueue.begin()); - entry = NULL; - } - return false; - } - if (mAudioSink->getPosition(&numFramesPlayed) != OK) { // When getPosition fails, renderer will not reschedule the draining // unless new samples are queued. -- cgit v1.1 From 0eb2f24bf01894947fededbc097b47c962287dda Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Wed, 18 May 2016 14:26:49 -0700 Subject: stagefright: Fix cts issue with divx test 8909 is using soft-ip divx decoder using component name starts with "OMX.ittiam." instead of "OMX.qcom." leading to FFMPEGSoftCodec override with wrong compression format using OMX_VIDEO_CodingDIVX (0x7F000003) defined in OMX_FFMPEG_Extn.h. But qcom omx component actually use QOMX_VIDEO_CodingDivx (0x7FA30C02) which defined in OMX_QCOMExtns.h. Add checking for OMX.ittiam in additional to OMX.qcom solved the problem. FEIJ-700 Change-Id: I4071eb3978974d1072373f0c88ea83653c0c53a9 --- media/libstagefright/FFMPEGSoftCodec.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/FFMPEGSoftCodec.cpp b/media/libstagefright/FFMPEGSoftCodec.cpp index f981c71..7233162 100644 --- a/media/libstagefright/FFMPEGSoftCodec.cpp +++ b/media/libstagefright/FFMPEGSoftCodec.cpp @@ -319,7 +319,8 @@ status_t FFMPEGSoftCodec::setVideoFormat( // from the CAF L release. It was unfortunately moved to a proprietary // blob and an architecture which is hellish for OEMs who wish to // customize the platform. - if (err == OK && (!strncmp(componentName, "OMX.qcom.", 9))) { + if (err == OK && (!strncmp(componentName, "OMX.qcom.", 9) + || !strncmp(componentName, "OMX.ittiam.", 11))) { status_t xerr = OK; -- cgit v1.1 From af1fa68cd4038409c941b6ef09ff7c43a75e0007 Mon Sep 17 00:00:00 2001 From: Caio Schnepper Date: Wed, 5 Aug 2015 16:17:14 -0300 Subject: stagefright: Correct Exynos4 stride alignment For the OMX_COLOR_FormatYUV420Planar color format case, Google's VP9 codec is used, in that case the colors were shifting 16 bytes per horizontal line, causing green lines to appear on video playback. Change-Id: I4cf0fd40b79e53882d99f1c3f263c8a98fff1f30 --- media/libstagefright/colorconversion/SoftwareRenderer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index 3fa29a2..59af12a 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -261,8 +261,14 @@ std::list SoftwareRenderer::render( uint8_t *dst_y = (uint8_t *)dst; size_t dst_y_size = buf->stride * buf->height; + +#ifdef EXYNOS4_ENHANCEMENTS + size_t dst_c_stride = buf->stride / 2; + size_t dst_c_size = ALIGN(dst_c_stride, 16) * buf->height / 2; +#else size_t dst_c_stride = ALIGN(buf->stride / 2, 16); size_t dst_c_size = dst_c_stride * buf->height / 2; +#endif uint8_t *dst_v = dst_y + dst_y_size; uint8_t *dst_u = dst_v + dst_c_size; -- cgit v1.1 From 8f270dc1ec91d3b34d62202463e0b03939900449 Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Mon, 23 May 2016 18:10:55 +0100 Subject: audiopolicy: engineconfigurable: Don't include the example When using the configurable policy engine, the audiopolicy makefile implicitly declares dependencies on the configuration files. However, the example folder already contains the example files which we wan't to override. This patch removes the example from the makefile inclusion path so that we can declare it on a per-device basis without getting errored out by duplicate module names. Change-Id: Ie47ebff6b13606c93630c017252ebaa204203a76 --- services/audiopolicy/engineconfigurable/parameter-framework/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk index c402fd5..be86231 100644 --- a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk +++ b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk @@ -4,4 +4,4 @@ LOCAL_PATH := $(call my-dir) # Recursive call sub-folder Android.mk ####################################################################### -include $(call all-makefiles-under,$(LOCAL_PATH)) +include $(LOCAL_PATH)/plugin/Android.mk -- cgit v1.1 From 4f236c532039a61f0cf681d2e3c6e022911bbb5c Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Thu, 28 Apr 2016 13:32:41 -0700 Subject: Check section size when verifying CRC Bug: 28333006 Change-Id: Ief7a2da848face78f0edde21e2f2009316076679 --- media/libstagefright/mpeg2ts/ATSParser.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index e3c3e80..2f2b115 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -1713,6 +1713,13 @@ bool ATSParser::PSISection::isCRCOkay() const { unsigned sectionLength = U16_AT(data + 1) & 0xfff; ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes); + + if(sectionLength < mSkipBytes) { + ALOGE("b/28333006"); + android_errorWriteLog(0x534e4554, "28333006"); + return false; + } + // Skip the preceding field present when payload start indicator is on. sectionLength -= mSkipBytes; -- cgit v1.1 From daef4327fe0c75b0a90bb8627458feec7a301e1f Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 2 May 2016 14:12:34 -0700 Subject: Clear unused pointer field when sending across binder Bug: 28377502 Change-Id: Iad5ebfb0a9ef89f09755bb332579dbd3534f9c98 --- media/libmediaplayerservice/MetadataRetrieverClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index a5a1fa5..f6acdf6 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -231,6 +231,7 @@ sp MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option) ALOGV("rotation: %d", frameCopy->mRotationAngle); frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame); memcpy(frameCopy->mData, frame->mData, frame->mSize); + frameCopy->mData = 0; delete frame; // Fix memory leakage return mThumbnail; } -- cgit v1.1 From 60547808ca4e9cfac50028c00c58a6ceb2319301 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Wed, 11 May 2016 16:08:21 -0700 Subject: h264bsdActivateParamSets: Prevent multiplication overflow. Report MEMORY_ALLOCATION_ERROR if pStorage->picSizeInMbs would exceed UINT32_MAX bytes. Bug: 28532266 Change-Id: Ia6f11efb18818afcdb5fa2a38a14f2a2d8c8447a --- .../codecs/on2/h264dec/source/h264bsd_storage.c | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c index 3234754..ff7a42a 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c @@ -58,6 +58,10 @@ 3. Module defines ------------------------------------------------------------------------------*/ +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + /*------------------------------------------------------------------------------ 4. Local function prototypes ------------------------------------------------------------------------------*/ @@ -326,9 +330,23 @@ u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr) pStorage->activePps = pStorage->pps[ppsId]; pStorage->activeSpsId = pStorage->activePps->seqParameterSetId; pStorage->activeSps = pStorage->sps[pStorage->activeSpsId]; - pStorage->picSizeInMbs = - pStorage->activeSps->picWidthInMbs * - pStorage->activeSps->picHeightInMbs; + + /* report error before multiplication to prevent integer overflow */ + if (pStorage->activeSps->picWidthInMbs == 0) + { + pStorage->picSizeInMbs = 0; + } + else if (pStorage->activeSps->picHeightInMbs > + UINT32_MAX / pStorage->activeSps->picWidthInMbs) + { + return(MEMORY_ALLOCATION_ERROR); + } + else + { + pStorage->picSizeInMbs = + pStorage->activeSps->picWidthInMbs * + pStorage->activeSps->picHeightInMbs; + } pStorage->currImage->width = pStorage->activeSps->picWidthInMbs; pStorage->currImage->height = pStorage->activeSps->picHeightInMbs; -- cgit v1.1 From e248db02fbab2ee9162940bc19f087fd7d96cb9d Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Fri, 13 May 2016 11:48:11 -0700 Subject: Fix security vulnerability in libstagefright bug: 28175045 Change-Id: Icee6c7eb5b761da4aa3e412fb71825508d74d38f --- media/libstagefright/DRMExtractor.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp index 9cb6e86..e2bc89c 100644 --- a/media/libstagefright/DRMExtractor.cpp +++ b/media/libstagefright/DRMExtractor.cpp @@ -200,7 +200,17 @@ status_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) { continue; } - CHECK(dstOffset + 4 <= (*buffer)->size()); + if (dstOffset > SIZE_MAX - 4 || + dstOffset + 4 > SIZE_MAX - nalLength || + dstOffset + 4 + nalLength > (*buffer)->size()) { + (*buffer)->release(); + (*buffer) = NULL; + if (decryptedDrmBuffer.data) { + delete [] decryptedDrmBuffer.data; + decryptedDrmBuffer.data = NULL; + } + return ERROR_MALFORMED; + } dstData[dstOffset++] = 0; dstData[dstOffset++] = 0; -- cgit v1.1 From e7142a0703bc93f75e213e96ebc19000022afed9 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 11 May 2016 11:11:20 -0700 Subject: Check malloc result to avoid NPD Bug: 28471206 Change-Id: Id5d055d76893d6f53a2e524ff5f282d1ddca3345 --- media/libstagefright/MPEG4Extractor.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index f8789da..f6206d2 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -535,6 +535,10 @@ status_t MPEG4Extractor::readMetaData() { } if (psshsize > 0 && psshsize <= UINT32_MAX) { char *buf = (char*)malloc(psshsize); + if (!buf) { + ALOGE("b/28471206"); + return NO_MEMORY; + } char *ptr = buf; for (size_t i = 0; i < mPssh.size(); i++) { memcpy(ptr, mPssh[i].uuid, 20); // uuid + length @@ -1702,6 +1706,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { sp buffer = new ABuffer(chunk_data_size); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } + if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; @@ -1719,6 +1728,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { { sp buffer = new ABuffer(chunk_data_size); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } + if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; @@ -2051,6 +2065,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_MALFORMED; } sp buffer = new ABuffer(chunk_data_size + 1); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { return ERROR_IO; -- cgit v1.1 From 6fdee2a83432b3b150d6a34f231c4e2f7353c01e Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Fri, 13 May 2016 10:39:23 -0700 Subject: limit mediaserver memory Limit mediaserver using rlimit, to prevent it from bringing down the system via the low memory killer. Default max is 65% of total RAM, but can be customized via system property. Bug: 28471206 Bug: 28615448 Change-Id: Ic84137435d1ef0a6883e9789a4b4f399e4283f05 --- media/libmedia/Android.mk | 1 + media/libmedia/MediaUtils.cpp | 74 ++++++++++++++++++++++++++++++++++ media/libmedia/MediaUtils.h | 35 ++++++++++++++++ media/mediaserver/Android.mk | 1 + media/mediaserver/main_mediaserver.cpp | 6 +++ 5 files changed, 117 insertions(+) create mode 100644 media/libmedia/MediaUtils.cpp create mode 100644 media/libmedia/MediaUtils.h diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index a3c3d3c..9f836f0 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/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 + +#include +#include +#include + +#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/mediaserver/Android.mk b/media/mediaserver/Android.mk index b6de0d9..7e017b9 100644 --- a/media/mediaserver/Android.mk +++ b/media/mediaserver/Android.mk @@ -37,6 +37,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_C_INCLUDES := \ frameworks/av/media/libmediaplayerservice \ + frameworks/av/media/libmedia \ frameworks/av/services/medialog \ frameworks/av/services/audioflinger \ frameworks/av/services/audiopolicy \ diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp index 4a485ed..8cc9508 100644 --- a/media/mediaserver/main_mediaserver.cpp +++ b/media/mediaserver/main_mediaserver.cpp @@ -36,6 +36,7 @@ #include "MediaPlayerService.h" #include "ResourceManagerService.h" #include "service/AudioPolicyService.h" +#include "MediaUtils.h" #include "SoundTriggerHwService.h" #include "RadioService.h" @@ -43,6 +44,11 @@ using namespace android; int main(int argc __unused, char** argv) { + limitProcessMemory( + "ro.media.maxmem", /* property that defines limit */ + SIZE_MAX, /* upper limit in bytes */ + 65 /* upper limit as percentage of physical RAM */); + signal(SIGPIPE, SIG_IGN); char value[PROPERTY_VALUE_MAX]; bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1); -- cgit v1.1 From f81038006b4c59a5a148dcad887371206033c28f Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Fri, 28 Aug 2015 10:35:35 -0700 Subject: MPEG4Extractor: ensure kKeyTrackID exists before creating an MPEG4Source as track. GenericSource: return error when no track exists. SampleIterator: make sure mSamplesPerChunk is not zero before using it as divisor. Bug: 21657957 Bug: 23705695 Bug: 22802344 Bug: 28799341 Change-Id: I7664992ade90b935d3f255dcd43ecc2898f30b04 (cherry picked from commit 0386c91b8a910a134e5898ffa924c1b6c7560b13) --- .../nuplayer/GenericSource.cpp | 34 +++++++++++++--------- media/libstagefright/MPEG4Extractor.cpp | 8 +++++ media/libstagefright/SampleIterator.cpp | 5 ++++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 45da218..0598254 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -211,6 +211,9 @@ status_t NuPlayer::GenericSource::initFromDataSource() { for (size_t i = 0; i < numtracks; ++i) { sp track = extractor->getTrack(i); + if (track == NULL) { + continue; + } sp meta = extractor->getTrackMetaData(i); @@ -253,24 +256,27 @@ status_t NuPlayer::GenericSource::initFromDataSource() { } } - if (track != NULL) { - mSources.push(track); - int64_t durationUs; - if (meta->findInt64(kKeyDuration, &durationUs)) { - if (durationUs > mDurationUs) { - mDurationUs = durationUs; - } + mSources.push(track); + int64_t durationUs; + if (meta->findInt64(kKeyDuration, &durationUs)) { + if (durationUs > mDurationUs) { + mDurationUs = durationUs; } + } - int32_t bitrate; - if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) { - totalBitrate += bitrate; - } else { - totalBitrate = -1; - } + int32_t bitrate; + if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) { + totalBitrate += bitrate; + } else { + totalBitrate = -1; } } + if (mSources.size() == 0) { + ALOGE("b/23705695"); + return UNKNOWN_ERROR; + } + mBitrate = totalBitrate; return OK; @@ -318,7 +324,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() { status_t NuPlayer::GenericSource::setBuffers( bool audio, Vector &buffers) { - if (mIsSecure && !audio) { + if (mIsWidevine && !audio && mVideoTrack.mSource != NULL) { return mVideoTrack.mSource->setBuffers(buffers); } return INVALID_OPERATION; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index f6206d2..4c10cc9 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -933,6 +933,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } if (isTrack) { + int32_t trackId; + // There must be exact one track header per track. + if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { + mLastTrack->skipTrack = true; + } if (mLastTrack->skipTrack) { Track *cur = mFirstTrack; @@ -2869,6 +2874,9 @@ sp MPEG4Extractor::getTrack(size_t index) { break; } } + } else { + ALOGE("b/21657957"); + return NULL; } ALOGV("getTrack called, pssh: %zu", mPssh.size()); diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp index 2748349..c5f359e 100644 --- a/media/libstagefright/SampleIterator.cpp +++ b/media/libstagefright/SampleIterator.cpp @@ -84,6 +84,11 @@ status_t SampleIterator::seekTo(uint32_t sampleIndex) { CHECK(sampleIndex < mStopChunkSampleIndex); + if (mSamplesPerChunk == 0) { + ALOGE("b/22802344"); + return ERROR_MALFORMED; + } + uint32_t chunk = (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk + mFirstChunk; -- cgit v1.1 From 9bdc0f69492d90fbceca68d3b40716b4722a3222 Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Thu, 2 Jun 2016 10:35:32 -0700 Subject: MTP: Fix crash when no storages are available Change-Id: I6d7202ade46a5d781a3db5a1a3bdde17c8e70a60 --- media/mtp/MtpServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 3c91ffd..96ce81b 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -138,7 +138,7 @@ void MtpServer::removeStorage(MtpStorage* storage) { MtpStorage* MtpServer::getStorage(MtpStorageID id) { if (id == 0) - return mStorages[0]; + return mStorages.empty() ? NULL : mStorages[0]; for (size_t i = 0; i < mStorages.size(); i++) { MtpStorage* storage = mStorages[i]; if (storage->getStorageID() == id) -- cgit v1.1 From b3fbce13d6a0c30012e069c4a2131407beb31ab7 Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Mon, 6 Jun 2016 10:09:50 -0700 Subject: MtpServer: Fix concurrent access to mStorages * getStorage is called both internally with mMutex held and externally without mMutex held. Create getStorageLocked for internal use and make getStorage a wrapper. * hasStorage is only called internally with mMutex held. Make it a private method. Change-Id: I8f73310ad6cca14cd88b8e29f20cc181b3a4fac3 --- media/mtp/MtpServer.cpp | 36 +++++++++++++++++++++--------------- media/mtp/MtpServer.h | 6 ++++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 96ce81b..d5f8ff4 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -137,20 +137,9 @@ void MtpServer::removeStorage(MtpStorage* storage) { } MtpStorage* MtpServer::getStorage(MtpStorageID id) { - if (id == 0) - return mStorages.empty() ? NULL : mStorages[0]; - for (size_t i = 0; i < mStorages.size(); i++) { - MtpStorage* storage = mStorages[i]; - if (storage->getStorageID() == id) - return storage; - } - return NULL; -} + Mutex::Autolock autoLock(mMutex); -bool MtpServer::hasStorage(MtpStorageID id) { - if (id == 0 || id == 0xFFFFFFFF) - return mStorages.size() > 0; - return (getStorage(id) != NULL); + return getStorageLocked(id); } void MtpServer::run() { @@ -260,6 +249,23 @@ void MtpServer::sendObjectUpdated(MtpObjectHandle handle) { sendEvent(MTP_EVENT_OBJECT_PROP_CHANGED, handle); } +MtpStorage* MtpServer::getStorageLocked(MtpStorageID id) { + if (id == 0) + return mStorages.empty() ? NULL : mStorages[0]; + for (size_t i = 0; i < mStorages.size(); i++) { + MtpStorage* storage = mStorages[i]; + if (storage->getStorageID() == id) + return storage; + } + return NULL; +} + +bool MtpServer::hasStorage(MtpStorageID id) { + if (id == 0 || id == 0xFFFFFFFF) + return mStorages.size() > 0; + return (getStorageLocked(id) != NULL); +} + void MtpServer::sendStoreAdded(MtpStorageID id) { ALOGV("sendStoreAdded %08X\n", id); sendEvent(MTP_EVENT_STORE_ADDED, id); @@ -543,7 +549,7 @@ MtpResponseCode MtpServer::doGetStorageInfo() { return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID id = mRequest.getParameter(1); - MtpStorage* storage = getStorage(id); + MtpStorage* storage = getStorageLocked(id); if (!storage) return MTP_RESPONSE_INVALID_STORAGE_ID; @@ -894,7 +900,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() { if (mRequest.getParameterCount() < 2) return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID storageID = mRequest.getParameter(1); - MtpStorage* storage = getStorage(storageID); + MtpStorage* storage = getStorageLocked(storageID); MtpObjectHandle parent = mRequest.getParameter(2); if (!storage) return MTP_RESPONSE_INVALID_STORAGE_ID; diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h index 8bd0472..a79e199 100644 --- a/media/mtp/MtpServer.h +++ b/media/mtp/MtpServer.h @@ -95,8 +95,6 @@ public: virtual ~MtpServer(); MtpStorage* getStorage(MtpStorageID id); - inline bool hasStorage() { return mStorages.size() > 0; } - bool hasStorage(MtpStorageID id); void addStorage(MtpStorage* storage); void removeStorage(MtpStorage* storage); @@ -108,6 +106,10 @@ public: void sendObjectUpdated(MtpObjectHandle handle); private: + MtpStorage* getStorageLocked(MtpStorageID id); + inline bool hasStorage() { return mStorages.size() > 0; } + bool hasStorage(MtpStorageID id); + void sendStoreAdded(MtpStorageID id); void sendStoreRemoved(MtpStorageID id); void sendEvent(MtpEventCode code, uint32_t param1); -- cgit v1.1 From fdc7d1f59c2da25246ec1dce7a6bbc32fcd6525d Mon Sep 17 00:00:00 2001 From: Jessica Wagantall Date: Tue, 7 Jun 2016 15:27:51 -0700 Subject: Fixing ALOGE message in commit ad40e57890f81a3cf436c5f06da66396010bd9e5 Change-Id: Icdfe4662ff6b53cff53142706bbd5ade1636fb27 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index ba13338..cd4b0ba 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -279,7 +279,7 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t); if ((int32)outHeader->nAllocLen < mConfig->outputFrameSize) { - ALOGE("input buffer too small: got %lu, expected %u", + ALOGE("input buffer too small: got %u, expected %u", outHeader->nAllocLen, mConfig->outputFrameSize); android_errorWriteLog(0x534e4554, "27793371"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); -- cgit v1.1 From fbef511c958b5f1b3e015d032dcac4ed7cc84876 Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Thu, 9 Jun 2016 18:55:14 +0200 Subject: OMXCodec: Remove kClientNeedsFrameBuffer for S3D Upstream commit 0bb5ced removed support for this flag. Reference: https://github.com/CyanogenMod/android_frameworks_av/commit/0bb5ced60304da7f61478ffd359e7ba65d72f181 Change-Id: I56c8c0957b556f70b1a52cd6dd8a2bdd8f958381 --- media/libstagefright/OMXCodec.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index af30780..ca310bc 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -2358,9 +2358,6 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { #ifdef USE_S3D_SUPPORT case (OMX_EVENTTYPE)OMX_EventS3DInformation: { - if (mFlags & kClientNeedsFramebuffer) - break; - sp sm = defaultServiceManager(); sp hwc = interface_cast( sm->getService(String16("Exynos.HWCService"))); -- cgit v1.1 From d112f7d0c1dbaf0368365885becb11ca8d3f13a4 Mon Sep 17 00:00:00 2001 From: Dave Weinstein Date: Tue, 14 Jun 2016 11:05:01 -0700 Subject: Resolve a merge issue between lmp and lmp-mr1+ Change-Id: I336cb003fb7f50fd7d95c30ca47e45530a7ad503 (cherry picked from commit 33f6da1092834f1e4be199cfa3b6310d66b521c0) (cherry picked from commit bb3a0338b58fafb01ac5b34efc450b80747e71e4) --- media/libmediaplayerservice/nuplayer/GenericSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 0598254..e8c28d5 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -324,7 +324,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() { status_t NuPlayer::GenericSource::setBuffers( bool audio, Vector &buffers) { - if (mIsWidevine && !audio && mVideoTrack.mSource != NULL) { + if (mIsSecure && !audio && mVideoTrack.mSource != NULL) { return mVideoTrack.mSource->setBuffers(buffers); } return INVALID_OPERATION; -- cgit v1.1 From 590d1729883f700ab905cdc9ad850f3ddd7e1f56 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 7 Jun 2016 15:48:07 -0700 Subject: Fix potential overflow Bug: 28533562 Change-Id: I798ab24caa4c81f3ba564cad7c9ee019284fb702 --- media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c index 9517d0a..799bd16 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c @@ -60,6 +60,7 @@ #include "h264bsd_util.h" #include "basetype.h" +#include /*------------------------------------------------------------------------------ 2. External compiler flags -------------------------------------------------------------------------------- @@ -998,6 +999,13 @@ u32 h264bsdInitDpb( ASSERT(maxFrameNum); ASSERT(dpbSize); + // see comment in loop below about size calculation + if (picSizeInMbs > (UINT32_MAX - 32 - 15) / 384) { + ALOGE("b/28533562"); + android_errorWriteLog(0x534e4554, "28533562"); + return(MEMORY_ALLOCATION_ERROR); + } + dpb->maxLongTermFrameIdx = NO_LONG_TERM_FRAME_INDICES; dpb->maxRefFrames = MAX(maxRefFrames, 1); if (noReordering) -- cgit v1.1 From 8e438e153f661e9df8db0ac41d587e940352df06 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 8 Jun 2016 14:31:42 -0700 Subject: SoftAAC2: fix crash on all-zero adts buffer Bug: 29153599 Change-Id: I1cb81c054098b86cf24f024f8479909ca7bc85a6 --- media/libstagefright/codecs/aacdec/SoftAAC2.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp index 520ecb4..8ddff90 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp @@ -625,12 +625,15 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) { signalError = true; } else { adtsHeaderSize = (protectionAbsent ? 7 : 9); - - inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; - inBufferLength[0] = aac_frame_length - adtsHeaderSize; - - inHeader->nOffset += adtsHeaderSize; - inHeader->nFilledLen -= adtsHeaderSize; + if (aac_frame_length < adtsHeaderSize) { + signalError = true; + } else { + inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize; + inBufferLength[0] = aac_frame_length - adtsHeaderSize; + + inHeader->nOffset += adtsHeaderSize; + inHeader->nFilledLen -= adtsHeaderSize; + } } } -- cgit v1.1 From 42a25c46b844518ff0d0b920c20c519e1417be69 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 7 Jun 2016 12:26:43 -0700 Subject: Don't use sp<>& because they may end up pointing to NULL after a NULL check was performed. Bug: 28166152 Change-Id: Iab2ea30395b620628cc6f3d067dd4f6fcda824fe --- include/media/IMediaDeathNotifier.h | 2 +- media/libmedia/IMediaDeathNotifier.cpp | 2 +- media/libmedia/mediaplayer.cpp | 6 +++--- media/libmedia/mediarecorder.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/media/IMediaDeathNotifier.h b/include/media/IMediaDeathNotifier.h index bb3d0d8..aca6678 100644 --- a/include/media/IMediaDeathNotifier.h +++ b/include/media/IMediaDeathNotifier.h @@ -30,7 +30,7 @@ public: virtual ~IMediaDeathNotifier() { removeObitRecipient(this); } virtual void died() = 0; - static const sp& getMediaPlayerService(); + static const sp getMediaPlayerService(); private: IMediaDeathNotifier &operator=(const IMediaDeathNotifier &); 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::sDeathNotifier; SortedVector< wp > IMediaDeathNotifier::sObitRecipients; // establish binder interface to MediaPlayerService -/*static*/const sp& +/*static*/const sp IMediaDeathNotifier::getMediaPlayerService() { ALOGV("getMediaPlayerService"); diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 502ab2d..dcce3cc 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& service(getMediaPlayerService()); + const sp service(getMediaPlayerService()); if (service != 0) { sp 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& service(getMediaPlayerService()); + const sp service(getMediaPlayerService()); if (service != 0) { sp player(service->create(this, mAudioSessionId)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || @@ -185,7 +185,7 @@ status_t MediaPlayer::setDataSource(const sp &source) { ALOGV("setDataSource"); status_t err = UNKNOWN_ERROR; - const sp& service(getMediaPlayerService()); + const sp service(getMediaPlayerService()); if (service != 0) { sp player(service->create(this, mAudioSessionId)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp index 8bbd8f1..0eb7de5 100644 --- a/media/libmedia/mediarecorder.cpp +++ b/media/libmedia/mediarecorder.cpp @@ -617,7 +617,7 @@ MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSourc { ALOGV("constructor"); - const sp& service(getMediaPlayerService()); + const sp service(getMediaPlayerService()); if (service != NULL) { mMediaRecorder = service->createMediaRecorder(opPackageName); } -- cgit v1.1 From a4567c66f4764442c6cb7b5c1858810194480fb5 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Mon, 12 Oct 2015 19:24:18 +0530 Subject: SoftHEVC: Exit gracefully in case of decoder errors Exit for error in allocation and unsupported resolutions Bug: 28816956 Change-Id: Ieb830bedeb3a7431d1d21a024927df630f7eda1e --- media/libstagefright/codecs/hevcdec/SoftHEVC.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp index a70755c..1dac868 100644 --- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp +++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp @@ -444,6 +444,9 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) { if (NULL == mCodecCtx) { if (OK != initDecoder()) { + ALOGE("Failed to initialize decoder"); + notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL); + mSignalledError = true; return; } } @@ -540,6 +543,25 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) { IV_API_CALL_STATUS_T status; status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op); + bool unsupportedResolution = + (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF)); + + /* Check for unsupported dimensions */ + if (unsupportedResolution) { + ALOGE("Unsupported resolution : %dx%d", mWidth, mHeight); + notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL); + mSignalledError = true; + return; + } + + bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF)); + if (allocationFailed) { + ALOGE("Allocation failure in decoder"); + notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL); + mSignalledError = true; + return; + } + bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF)); GETTIME(&mTimeEnd, NULL); -- cgit v1.1 From 9cd8c3289c91254b3955bd7347cf605d6fa032c6 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Mon, 20 Jun 2016 15:22:52 -0700 Subject: Check effect command reply size in AudioFlinger Bug: 29251553 Change-Id: I1bcc1281f1f0542bb645f6358ce31631f2a8ffbf --- services/audioflinger/Effects.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index 949c91d..eb52dee 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -558,6 +558,12 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, if (mStatus != NO_ERROR) { return mStatus; } + if (cmdCode == EFFECT_CMD_GET_PARAM && + (*replySize < sizeof(effect_param_t) || + ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t))) { + android_errorWriteLog(0x534e4554, "29251553"); + return -EINVAL; + } status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, -- cgit v1.1 From b351eabb428c7ca85a34513c64601f437923d576 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Wed, 25 May 2016 16:54:08 +0900 Subject: DO NOT MERGE omx: check buffer port before using Bug: 28816827 Change-Id: I3d5bad4a1ef96dec544b05bb31cc6f7109aae0a5 --- media/libstagefright/include/OMXNodeInstance.h | 2 +- media/libstagefright/omx/OMXNodeInstance.cpp | 73 +++++++++++++++++++------- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index e5fb45b..babf5b7 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -187,7 +187,7 @@ private: // For buffer id management OMX::buffer_id makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader); - OMX_BUFFERHEADERTYPE *findBufferHeader(OMX::buffer_id buffer); + OMX_BUFFERHEADERTYPE *findBufferHeader(OMX::buffer_id buffer, OMX_U32 portIndex); OMX::buffer_id findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader); void invalidateBufferID(OMX::buffer_id buffer); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 8735eff..7f534b5 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -101,19 +101,22 @@ static void InitOMXParams(T *params) { namespace android { struct BufferMeta { - BufferMeta(const sp &mem, bool is_backup = false) + BufferMeta(const sp &mem, OMX_U32 portIndex, bool is_backup = false) : mMem(mem), - mIsBackup(is_backup) { + mIsBackup(is_backup), + mPortIndex(portIndex) { } - BufferMeta(size_t size) + BufferMeta(size_t size, OMX_U32 portIndex) : mSize(size), - mIsBackup(false) { + mIsBackup(false), + mPortIndex(portIndex) { } - BufferMeta(const sp &graphicBuffer) + BufferMeta(const sp &graphicBuffer, OMX_U32 portIndex) : mGraphicBuffer(graphicBuffer), - mIsBackup(false) { + mIsBackup(false), + mPortIndex(portIndex) { } void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) { @@ -160,11 +163,16 @@ struct BufferMeta { mGraphicBuffer = graphicBuffer; } + OMX_U32 getPortIndex() { + return mPortIndex; + } + private: sp mGraphicBuffer; sp mMem; size_t mSize; bool mIsBackup; + OMX_U32 mPortIndex; BufferMeta(const BufferMeta &); BufferMeta &operator=(const BufferMeta &); @@ -661,7 +669,7 @@ status_t OMXNodeInstance::useBuffer( return BAD_VALUE; } - BufferMeta *buffer_meta = new BufferMeta(params); + BufferMeta *buffer_meta = new BufferMeta(params, portIndex); OMX_BUFFERHEADERTYPE *header; @@ -713,7 +721,7 @@ status_t OMXNodeInstance::useGraphicBuffer2_l( return UNKNOWN_ERROR; } - BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); + BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex); OMX_BUFFERHEADERTYPE *header = NULL; OMX_U8* bufferHandle = const_cast( @@ -771,7 +779,7 @@ status_t OMXNodeInstance::useGraphicBuffer( return StatusFromOMXError(err); } - BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); + BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex); OMX_BUFFERHEADERTYPE *header; @@ -812,6 +820,9 @@ status_t OMXNodeInstance::useGraphicBuffer( status_t OMXNodeInstance::updateGraphicBufferInMeta_l( OMX_U32 portIndex, const sp& graphicBuffer, OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) { + if (header == NULL) { + return BAD_VALUE; + } if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { return BAD_VALUE; } @@ -845,7 +856,7 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta( OMX_U32 portIndex, const sp& graphicBuffer, OMX::buffer_id buffer) { Mutex::Autolock autoLock(mLock); - OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); + OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex); return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header); } @@ -974,7 +985,7 @@ status_t OMXNodeInstance::allocateBuffer( void **buffer_data) { Mutex::Autolock autoLock(mLock); - BufferMeta *buffer_meta = new BufferMeta(size); + BufferMeta *buffer_meta = new BufferMeta(size, portIndex); OMX_BUFFERHEADERTYPE *header; @@ -1015,7 +1026,7 @@ status_t OMXNodeInstance::allocateBufferWithBackup( return BAD_VALUE; } - BufferMeta *buffer_meta = new BufferMeta(params, true); + BufferMeta *buffer_meta = new BufferMeta(params, portIndex, true); OMX_BUFFERHEADERTYPE *header; @@ -1056,7 +1067,10 @@ status_t OMXNodeInstance::freeBuffer( removeActiveBuffer(portIndex, buffer); - OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); + OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex); + if (header == NULL) { + return BAD_VALUE; + } BufferMeta *buffer_meta = static_cast(header->pAppPrivate); OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); @@ -1072,7 +1086,10 @@ status_t OMXNodeInstance::freeBuffer( status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) { Mutex::Autolock autoLock(mLock); - OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); + OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput); + if (header == NULL) { + return BAD_VALUE; + } header->nFilledLen = 0; header->nOffset = 0; header->nFlags = 0; @@ -1105,7 +1122,10 @@ status_t OMXNodeInstance::emptyBuffer( OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { Mutex::Autolock autoLock(mLock); - OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); + OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput); + if (header == NULL) { + return BAD_VALUE; + } BufferMeta *buffer_meta = static_cast(header->pAppPrivate); sp backup = buffer_meta->getBuffer(header, true /* backup */, false /* limit */); @@ -1385,7 +1405,10 @@ bool OMXNodeInstance::handleMessage(omx_message &msg) { if (msg.type == omx_message::FILL_BUFFER_DONE) { OMX_BUFFERHEADERTYPE *buffer = - findBufferHeader(msg.u.extended_buffer_data.buffer); + findBufferHeader(msg.u.extended_buffer_data.buffer, kPortIndexOutput); + if (buffer == NULL) { + return false; + } { Mutex::Autolock _l(mDebugLock); @@ -1416,7 +1439,10 @@ bool OMXNodeInstance::handleMessage(omx_message &msg) { } } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { OMX_BUFFERHEADERTYPE *buffer = - findBufferHeader(msg.u.buffer_data.buffer); + findBufferHeader(msg.u.buffer_data.buffer, kPortIndexInput); + if (buffer == NULL) { + return false; + } { Mutex::Autolock _l(mDebugLock); @@ -1613,7 +1639,8 @@ OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) return buffer; } -OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) { +OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader( + OMX::buffer_id buffer, OMX_U32 portIndex) { if (buffer == 0) { return NULL; } @@ -1623,7 +1650,15 @@ OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) { CLOGW("findBufferHeader: buffer %u not found", buffer); return NULL; } - return mBufferIDToBufferHeader.valueAt(index); + OMX_BUFFERHEADERTYPE *header = mBufferIDToBufferHeader.valueAt(index); + BufferMeta *buffer_meta = + static_cast(header->pAppPrivate); + if (buffer_meta->getPortIndex() != portIndex) { + CLOGW("findBufferHeader: buffer %u found but with incorrect port index.", buffer); + android_errorWriteLog(0x534e4554, "28816827"); + return NULL; + } + return header; } OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) { -- cgit v1.1 From 1f24c730ab6ca5aff1e3137b340b8aeaeda4bdbc Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 20 Jun 2016 17:00:14 -0700 Subject: DO NOT MERGE: Camera: Adjust pointers to ANW buffers to avoid infoleak Subtract address of a random static object from pointers being routed through app process. Bug: 28466701 Change-Id: Idcbfe81e9507433769672f3dc6d67db5eeed4e04 --- camera/ICameraRecordingProxy.cpp | 6 ++++- include/camera/ICameraRecordingProxy.h | 6 +++++ include/media/stagefright/CameraSource.h | 3 +++ media/libstagefright/CameraSource.cpp | 29 ++++++++++++++++++++++ .../api1/client2/StreamingProcessor.cpp | 8 ++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/camera/ICameraRecordingProxy.cpp b/camera/ICameraRecordingProxy.cpp index 3dc0ffb..517b64f 100644 --- a/camera/ICameraRecordingProxy.cpp +++ b/camera/ICameraRecordingProxy.cpp @@ -31,6 +31,11 @@ enum { RELEASE_RECORDING_FRAME, }; +uint8_t ICameraRecordingProxy::baseObject = 0; + +size_t ICameraRecordingProxy::getCommonBaseAddress() { + return (size_t)&baseObject; +} class BpCameraRecordingProxy: public BpInterface { @@ -106,4 +111,3 @@ status_t BnCameraRecordingProxy::onTransact( // ---------------------------------------------------------------------------- }; // namespace android - diff --git a/include/camera/ICameraRecordingProxy.h b/include/camera/ICameraRecordingProxy.h index 2aac284..4edf9cd 100644 --- a/include/camera/ICameraRecordingProxy.h +++ b/include/camera/ICameraRecordingProxy.h @@ -83,6 +83,12 @@ public: virtual status_t startRecording(const sp& listener) = 0; virtual void stopRecording() = 0; virtual void releaseRecordingFrame(const sp& mem) = 0; + + // b/28466701 + static size_t getCommonBaseAddress(); + private: + + static uint8_t baseObject; }; // ---------------------------------------------------------------------------- diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index 069e897..6c938a5 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -236,6 +236,9 @@ private: status_t checkFrameRate(const CameraParameters& params, int32_t frameRate); + static void adjustIncomingANWBuffer(IMemory* data); + static void adjustOutgoingANWBuffer(IMemory* data); + void stopCameraRecording(); status_t reset(); diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 66280da..fa30644 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -792,6 +794,8 @@ void CameraSource::releaseQueuedFrames() { List >::iterator it; while (!mFramesReceived.empty()) { it = mFramesReceived.begin(); + // b/28466701 + adjustOutgoingANWBuffer(it->get()); releaseRecordingFrame(*it); mFramesReceived.erase(it); ++mNumFramesDropped; @@ -812,6 +816,9 @@ void CameraSource::signalBufferReturned(MediaBuffer *buffer) { for (List >::iterator it = mFramesBeingEncoded.begin(); it != mFramesBeingEncoded.end(); ++it) { if ((*it)->pointer() == buffer->data()) { + // b/28466701 + adjustOutgoingANWBuffer(it->get()); + releaseOneRecordingFrame((*it)); mFramesBeingEncoded.erase(it); ++mNumFramesEncoded; @@ -917,6 +924,10 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs, ++mNumFramesReceived; CHECK(data != NULL && data->size() > 0); + + // b/28466701 + adjustIncomingANWBuffer(data.get()); + mFramesReceived.push_back(data); int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); mFrameTimes.push_back(timeUs); @@ -930,6 +941,24 @@ bool CameraSource::isMetaDataStoredInVideoBuffers() const { return mIsMetaDataStoredInVideoBuffers; } +void CameraSource::adjustIncomingANWBuffer(IMemory* data) { + VideoNativeMetadata *payload = + reinterpret_cast(data->pointer()); + if (payload->eType == kMetadataBufferTypeANWBuffer) { + payload->pBuffer = (ANativeWindowBuffer*)(((uint8_t*)payload->pBuffer) + + ICameraRecordingProxy::getCommonBaseAddress()); + } +} + +void CameraSource::adjustOutgoingANWBuffer(IMemory* data) { + VideoNativeMetadata *payload = + reinterpret_cast(data->pointer()); + if (payload->eType == kMetadataBufferTypeANWBuffer) { + payload->pBuffer = (ANativeWindowBuffer*)(((uint8_t*)payload->pBuffer) - + ICameraRecordingProxy::getCommonBaseAddress()); + } +} + CameraSource::ProxyListener::ProxyListener(const sp& source) { mSource = source; } diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index 66d7b00..9e6c0db 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "common/CameraDeviceBase.h" @@ -826,6 +827,9 @@ status_t StreamingProcessor::processRecordingFrame() { (uint8_t*)heap->getBase() + offset); payload->eType = kMetadataBufferTypeANWBuffer; payload->pBuffer = imgBuffer.mGraphicBuffer->getNativeBuffer(); + // b/28466701 + payload->pBuffer = (ANativeWindowBuffer*)((uint8_t*)payload->pBuffer - + ICameraRecordingProxy::getCommonBaseAddress()); payload->nFenceFd = -1; ALOGVV("%s: Camera %d: Sending out ANWBuffer %p", @@ -874,6 +878,10 @@ void StreamingProcessor::releaseRecordingFrame(const sp& mem) { return; } + // b/28466701 + payload->pBuffer = (ANativeWindowBuffer*)(((uint8_t*)payload->pBuffer) + + ICameraRecordingProxy::getCommonBaseAddress()); + // Release the buffer back to the recording queue size_t itemIndex; for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) { -- cgit v1.1 From 940b28bc37f819c62386e393614354f55069e8f6 Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Wed, 6 Jul 2016 10:18:52 -0700 Subject: Enforce permission for accessing fm tuner Change-Id: I13f3ba8fc9caaeee21597a2405a8c3629e985502 --- services/audioflinger/ServiceUtilities.cpp | 8 ++++++++ services/audioflinger/ServiceUtilities.h | 1 + services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 5 +++++ services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp index 2e68dad..031ff05 100644 --- a/services/audioflinger/ServiceUtilities.cpp +++ b/services/audioflinger/ServiceUtilities.cpp @@ -106,6 +106,14 @@ bool captureAudioOutputAllowed() { return ok; } +bool accessFmRadioAllowed() { + static const String16 sAccessFmRadio("android.permission.ACCESS_FM_RADIO"); + // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. + bool ok = PermissionCache::checkCallingPermission(sAccessFmRadio); + if (!ok) ALOGE("Request requires android.permission.ACCESS_FM_RADIO"); + return ok; +} + bool captureHotwordAllowed() { static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD"); // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h index fba6dce..dffb114 100644 --- a/services/audioflinger/ServiceUtilities.h +++ b/services/audioflinger/ServiceUtilities.h @@ -21,6 +21,7 @@ namespace android { extern pid_t getpid_cached; bool recordingAllowed(const String16& opPackageName); +bool accessFmRadioAllowed(); bool captureAudioOutputAllowed(); bool captureHotwordAllowed(); bool settingsAllowed(); diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index f0be341..b23c35e 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -316,6 +316,11 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) { return BAD_VALUE; } + + if ((attr->source == AUDIO_SOURCE_FM_TUNER) && !accessFmRadioAllowed()) { + return BAD_VALUE; + } + spaudioPolicyEffects; status_t status; AudioPolicyInterface::input_type_t inputType; diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp index 0aad54d..da7f45d 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp @@ -275,6 +275,10 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, return BAD_VALUE; } + if ((inputSource == AUDIO_SOURCE_FM_TUNER) && !accessFmRadioAllowed()) { + return BAD_VALUE; + } + #ifdef HAVE_PRE_KITKAT_AUDIO_POLICY_BLOB if (inputSource == AUDIO_SOURCE_HOTWORD) inputSource = AUDIO_SOURCE_VOICE_RECOGNITION; -- cgit v1.1 From a5ec3545f879e882ed5397707f65a4757f7232d5 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 18 Jul 2016 16:50:06 -0700 Subject: audiopolicy: Constrain session events to music streams * We're really only interested in music streams right now, but events are being generated for all streams (system sounds, etc). * Constrain for now, in the future we will filter based on client registrations. Change-Id: Ic445052028c454eed146addebcdb28c4b26c4f20 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 31b1637..d6fabfe 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -331,6 +331,11 @@ status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* o Mutex::Autolock _l(mLock); + // TODO: Handle other stream types based on client registration + if (stream != AUDIO_STREAM_MUSIC) { + return NO_ERROR; + } + // update AudioSessionInfo. This is used in the stream open/close path // to notify userspace applications about session creation and // teardown, allowing the app to make decisions about effects for -- cgit v1.1 From 030001de8b26291b139a8c1d594f05130dafac1b Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Tue, 21 Jun 2016 19:10:21 -0700 Subject: Impose a size bound for dynamically allocated tables in stbl. Impose a restriction of 200MiB for tables in stsc, stts, ctts and stss boxes. Also change mTimeToSample from Vector to array. Bug: 29367429 Change-Id: I953bea9fe0590268cf27376740f582dc88563d42 Merge conflict resolution of ag/1170200 to mnc-mr2-release --- media/libstagefright/SampleTable.cpp | 150 ++++++++++++++++++++++++----- media/libstagefright/include/SampleTable.h | 9 +- 2 files changed, 133 insertions(+), 26 deletions(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 8df9cb8..bc01a2d 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -123,7 +123,7 @@ SampleTable::SampleTable(const sp &source) mNumSampleSizes(0), mHasTimeToSample(false), mTimeToSampleCount(0), - mTimeToSample(), + mTimeToSample(NULL), mSampleTimeEntries(NULL), mCompositionTimeDeltaEntries(NULL), mNumCompositionTimeDeltaEntries(0), @@ -132,7 +132,8 @@ SampleTable::SampleTable(const sp &source) mNumSyncSamples(0), mSyncSamples(NULL), mLastSyncSampleIndex(0), - mSampleToChunkEntries(NULL) { + mSampleToChunkEntries(NULL), + mTotalSize(0) { mSampleIterator = new SampleIterator(this); } @@ -143,6 +144,9 @@ SampleTable::~SampleTable() { delete[] mSyncSamples; mSyncSamples = NULL; + delete[] mTimeToSample; + mTimeToSample = NULL; + delete mCompositionDeltaLookup; mCompositionDeltaLookup = NULL; @@ -233,13 +237,43 @@ status_t SampleTable::setSampleToChunkParams( return ERROR_MALFORMED; } - if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets) + if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <= + (uint64_t)mNumSampleToChunkOffsets) { + ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; + } + + mTotalSize += (uint64_t)mNumSampleToChunkOffsets * + sizeof(SampleToChunkEntry); + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sample-to-chunk table size would make sample table too large.\n" + " Requested sample-to-chunk table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)mNumSampleToChunkOffsets * + sizeof(SampleToChunkEntry), + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return ERROR_OUT_OF_RANGE; + } mSampleToChunkEntries = new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; - if (!mSampleToChunkEntries) + if (!mSampleToChunkEntries) { + ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", + (unsigned long long)mNumSampleToChunkOffsets); return ERROR_OUT_OF_RANGE; + } + + if (mNumSampleToChunkOffsets == 0) { + return OK; + } + + if ((off64_t)(SIZE_MAX - 8 - + ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) + < mSampleToChunkOffset) { + return ERROR_MALFORMED; + } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; @@ -248,8 +282,11 @@ status_t SampleTable::setSampleToChunkParams( != (ssize_t)sizeof(buffer)) { return ERROR_IO; } - - CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. + // chunk index is 1 based in the spec. + if (U32_AT(buffer) < 1) { + ALOGE("b/23534160"); + return ERROR_OUT_OF_RANGE; + } // We want the chunk index to be 0-based. mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; @@ -349,21 +386,41 @@ status_t SampleTable::setTimeToSampleParams( // 2) mTimeToSampleCount is the number of entries of the time-to-sample // table. // 3) We hope that the table size does not exceed UINT32_MAX. - ALOGE(" Error: Time-to-sample table size too large."); - + ALOGE("Time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } // Note: At this point, we know that mTimeToSampleCount * 2 will not // overflow because of the above condition. - if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, - mTimeToSampleCount * 2)) { - ALOGE(" Error: Incomplete data read for time-to-sample table."); + + uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Time-to-sample table size would make sample table too large.\n" + " Requested time-to-sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return ERROR_OUT_OF_RANGE; + } + + mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; + if (!mTimeToSample) { + ALOGE("Cannot allocate time-to-sample table with %llu entries.", + (unsigned long long)mTimeToSampleCount); + return ERROR_OUT_OF_RANGE; + } + + if (mDataSource->readAt(data_offset + 8, mTimeToSample, + (size_t)allocSize) < (ssize_t)allocSize) { + ALOGE("Incomplete data read for time-to-sample table."); return ERROR_IO; } - for (size_t i = 0; i < mTimeToSample.size(); ++i) { - mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); + for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { + mTimeToSample[i] = ntohl(mTimeToSample[i]); } mHasTimeToSample = true; @@ -398,17 +455,32 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); - if (allocSize > UINT32_MAX) { + if (allocSize > SIZE_MAX) { + ALOGE("Composition-time-to-sample table size too large."); + return ERROR_OUT_OF_RANGE; + } + + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Composition-time-to-sample table would make sample table too large.\n" + " Requested composition-time-to-sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries]; - if (!mCompositionTimeDeltaEntries) + if (!mCompositionTimeDeltaEntries) { + ALOGE("Cannot allocate composition-time-to-sample table with %llu " + "entries.", (unsigned long long)numEntries); return ERROR_OUT_OF_RANGE; + } - if (mDataSource->readAt( - data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) - < (ssize_t)numEntries * 8) { + if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, + (size_t)allocSize) < (ssize_t)allocSize) { delete[] mCompositionTimeDeltaEntries; mCompositionTimeDeltaEntries = NULL; @@ -449,18 +521,33 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) ALOGV("Table of sync samples is empty or has only a single entry!"); } - uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); + uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); if (allocSize > SIZE_MAX) { + ALOGE("Sync sample table size too large."); + return ERROR_OUT_OF_RANGE; + } + + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sync sample table size would make sample table too large.\n" + " Requested sync sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; - if (!mSyncSamples) + if (!mSyncSamples) { + ALOGE("Cannot allocate sync sample table with %llu entries.", + (unsigned long long)mNumSyncSamples); return ERROR_OUT_OF_RANGE; + } - size_t size = mNumSyncSamples * sizeof(uint32_t); - if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) - != (ssize_t)size) { + if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, + (size_t)allocSize) != (ssize_t)allocSize) { return ERROR_IO; } @@ -525,9 +612,24 @@ void SampleTable::buildSampleEntriesTable() { return; } + mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sample entry table size would make sample table too large.\n" + " Requested sample entry table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return; + } + mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; - if (!mSampleTimeEntries) + if (!mSampleTimeEntries) { + ALOGE("Cannot allocate sample entry table with %llu entries.", + (unsigned long long)mNumSampleSizes); return; + } uint32_t sampleIndex = 0; uint32_t sampleTime = 0; diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index 465f37c..552eef7 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -24,7 +24,6 @@ #include #include #include -#include namespace android { @@ -96,6 +95,9 @@ private: static const uint32_t kSampleSizeType32; static const uint32_t kSampleSizeTypeCompact; + // Limit the total size of all internal tables to 200MiB. + static const size_t kMaxTotalSize = 200 * (1 << 20); + sp mDataSource; Mutex mLock; @@ -113,7 +115,7 @@ private: bool mHasTimeToSample; uint32_t mTimeToSampleCount; - Vector mTimeToSample; + uint32_t* mTimeToSample; struct SampleTimeEntry { uint32_t mSampleIndex; @@ -139,6 +141,9 @@ private: }; SampleToChunkEntry *mSampleToChunkEntries; + // Approximate size of all tables combined. + uint64_t mTotalSize; + friend struct SampleIterator; // normally we don't round -- cgit v1.1 From 9871fae25b351268e359682e6c149acbf47620c1 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 27 Jun 2016 13:55:14 -0700 Subject: SoftMP3: memset safely Bug: 29422022 Change-Id: I70c9e33269d16bf8c163815706ac24e18e34fe97 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 22 ++++++++++++++++++---- media/libstagefright/codecs/mp3dec/SoftMP3.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index aa946e6..daef471 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -120,6 +120,17 @@ void SoftMP3::initDecoder() { mIsFirst = true; } +void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { + if (len > outHeader->nAllocLen) { + ALOGE("memset buffer too small: got %lu, expected %zu", outHeader->nAllocLen, len); + android_errorWriteLog(0x534e4554, "29422022"); + notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); + mSignalledError = true; + return NULL; + } + return memset(outHeader->pBuffer, c, len); +} + OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_INDEXTYPE index, OMX_PTR params) { switch (index) { @@ -300,7 +311,10 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { outHeader->nOffset = 0; outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); - memset(outHeader->pBuffer, 0, outHeader->nFilledLen); + if (!memsetSafe(outHeader, 0, outHeader->nFilledLen)) { + return; + } + } outHeader->nFlags = OMX_BUFFERFLAG_EOS; mSignalledOutputEos = true; @@ -312,9 +326,9 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { // if mIsFirst is true as we may not have a valid // mConfig->samplingRate and mConfig->num_channels? ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence"); - memset(outHeader->pBuffer, - 0, - mConfig->outputFrameSize * sizeof(int16_t)); + if (!memsetSafe(outHeader, 0, mConfig->outputFrameSize * sizeof(int16_t))) { + return; + } if (inHeader) { mConfig->inputBufferUsedLength = inHeader->nFilledLen; diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h index f9e7b53..3bfa6c7 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.h +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h @@ -72,6 +72,7 @@ private: void initPorts(); void initDecoder(); + void *memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len); DISALLOW_EVIL_CONSTRUCTORS(SoftMP3); }; -- cgit v1.1 From 49a847e0f6558849adef32d64d2a1093fc527c96 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Fri, 17 Jun 2016 01:24:30 +0900 Subject: DO NOT MERGE stagefright: fix possible stack overflow in AVCC reassemble Additionally, remove use of variable length array which is non-standard in C++. Bug: 29161888 Change-Id: Ifdc3e7435f2225214c053b13f3bfe71c7d0ff506 --- media/libstagefright/Utils.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index 17f0201..0d9dc3a 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -671,20 +671,30 @@ void convertMessageToMetaData(const sp &msg, sp &meta) { // reassemble the csd data into its original form sp csd0; if (msg->findBuffer("csd-0", &csd0)) { + int csd0size = csd0->size(); if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { sp csd1; if (msg->findBuffer("csd-1", &csd1)) { - char avcc[1024]; // that oughta be enough, right? - size_t outsize = reassembleAVCC(csd0, csd1, avcc); - meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); + Vector avcc; + int avccSize = csd0size + csd1->size() + 1024; + if (avcc.resize(avccSize) < 0) { + ALOGE("error allocating avcc (size %d); abort setting avcc.", avccSize); + } else { + size_t outsize = reassembleAVCC(csd0, csd1, avcc.editArray()); + meta->setData(kKeyAVCC, kKeyAVCC, avcc.array(), outsize); + } } } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { - int csd0size = csd0->size(); - char esds[csd0size + 31]; - // The written ESDS is actually for an audio stream, but it's enough - // for transporting the CSD to muxers. - reassembleESDS(csd0, esds); - meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); + Vector esds; + int esdsSize = csd0size + 31; + if (esds.resize(esdsSize) < 0) { + ALOGE("error allocating esds (size %d); abort setting esds.", esdsSize); + } else { + // The written ESDS is actually for an audio stream, but it's enough + // for transporting the CSD to muxers. + reassembleESDS(csd0, esds.editArray()); + meta->setData(kKeyESDS, kKeyESDS, esds.array(), esds.size()); + } } } -- cgit v1.1 From f9391b39b1f0c98191ad3fff1a54b5f26e954421 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Wed, 6 Jul 2016 10:13:25 -0700 Subject: Fix corruption via buffer overflow in mediaserver change unbound sprintf() to snprintf() so network-provided values can't overflow the buffers. Applicable to all K/L/M/N branches. Bug: 25747670 Change-Id: Id6a5120c2d08a6fbbd47deffb680ecf82015f4f6 --- media/libstagefright/rtsp/ASessionDescription.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp index 98498e9..47573c3 100644 --- a/media/libstagefright/rtsp/ASessionDescription.cpp +++ b/media/libstagefright/rtsp/ASessionDescription.cpp @@ -17,6 +17,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "ASessionDescription" #include +#include #include "ASessionDescription.h" @@ -211,12 +212,12 @@ void ASessionDescription::getFormatType( *PT = x; - char key[20]; - sprintf(key, "a=rtpmap:%lu", x); + char key[32]; + snprintf(key, sizeof(key), "a=rtpmap:%lu", x); CHECK(findAttribute(index, key, desc)); - sprintf(key, "a=fmtp:%lu", x); + snprintf(key, sizeof(key), "a=fmtp:%lu", x); if (!findAttribute(index, key, params)) { params->clear(); } @@ -228,8 +229,11 @@ bool ASessionDescription::getDimensions( *width = 0; *height = 0; - char key[20]; - sprintf(key, "a=framesize:%lu", PT); + char key[33]; + snprintf(key, sizeof(key), "a=framesize:%lu", PT); + if (PT > 9999999) { + android_errorWriteLog(0x534e4554, "25747670"); + } AString value; if (!findAttribute(index, key, &value)) { return false; -- cgit v1.1 From 97837bb6cbac21ea679843a0037779d3834bed64 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 12 Jul 2016 18:00:53 -0700 Subject: OMXCodec: check IMemory::pointer() before using allocation Bug: 29421811 Change-Id: I0a73ba12bae4122f1d89fc92e5ea4f6a96cd1ed1 --- media/libstagefright/OMXCodec.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 4618e21..7e15e18 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1622,7 +1622,9 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { sp mem = mDealer[portIndex]->allocate(def.nBufferSize); - CHECK(mem.get() != NULL); + if (mem == NULL || mem->pointer() == NULL) { + return NO_MEMORY; + } BufferInfo info; info.mData = NULL; -- cgit v1.1 From ee44d7cdbdea9a8a67e967b3bc05f0cd409ae2b1 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 24 Jun 2016 12:37:45 -0700 Subject: SoftVPX: fix nFilledLen overflow Bug: 29421675 Change-Id: I25d4cf54a5df22c2130c37e95c7c7f75063111f3 --- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 22 +++++++++++++++++++--- media/libstagefright/codecs/on2/dec/SoftVPX.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 02e85a1..58a2660 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -149,7 +149,7 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por outHeader->nFlags = 0; outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2; outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv; - if (outHeader->nAllocLen >= outHeader->nFilledLen) { + if (outputBufferSafe(outHeader)) { uint8_t *dst = outHeader->pBuffer; const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y]; const uint8_t *srcU = (const uint8_t *)mImg->planes[VPX_PLANE_U]; @@ -159,8 +159,6 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por size_t srcVStride = mImg->stride[VPX_PLANE_V]; copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride); } else { - ALOGE("b/27597103, buffer too small"); - android_errorWriteLog(0x534e4554, "27597103"); outHeader->nFilledLen = 0; } @@ -190,6 +188,24 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por return true; } +bool SoftVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) { + uint32_t width = outputBufferWidth(); + uint32_t height = outputBufferHeight(); + uint64_t nFilledLen = width; + nFilledLen *= height; + if (nFilledLen > UINT32_MAX / 3) { + ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", nFilledLen, width, height); + android_errorWriteLog(0x534e4554, "29421675"); + return false; + } else if (outHeader->nAllocLen < outHeader->nFilledLen) { + ALOGE("b/27597103, buffer too small"); + android_errorWriteLog(0x534e4554, "27597103"); + return false; + } + + return true; +} + void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) { if (mOutputPortSettingsChange != NONE || mEOSStatus == OUTPUT_FRAMES_FLUSHED) { return; diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h index 8ccbae2..84cf79c 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.h +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h @@ -66,6 +66,7 @@ private: status_t initDecoder(); status_t destroyDecoder(); bool outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset); + bool outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader); DISALLOW_EVIL_CONSTRUCTORS(SoftVPX); }; -- cgit v1.1 From 50643aadeb8dfe53da7848a5d5e995d5486678e1 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 13 Jul 2016 20:27:32 -0700 Subject: fix build Change-Id: I9bb8c659d3fc97a8e748451d82d0f3448faa242b --- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 58a2660..912fac2 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -194,7 +194,8 @@ bool SoftVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) { uint64_t nFilledLen = width; nFilledLen *= height; if (nFilledLen > UINT32_MAX / 3) { - ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", nFilledLen, width, height); + ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", + (unsigned long long)nFilledLen, width, height); android_errorWriteLog(0x534e4554, "29421675"); return false; } else if (outHeader->nAllocLen < outHeader->nFilledLen) { -- cgit v1.1 From 36dd3c28898248fe5ecb7e256025499bb8d6275a Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Tue, 28 Jun 2016 18:24:52 +0100 Subject: Add bound checks to utf16_to_utf8 Bug: 29250543 Change-Id: I3518416e89ed901021970958fb6005fd69129f7c (cherry picked from commit 1d3f4278b2666d1a145af2f54782c993aa07d1d9) --- media/libmediaplayerservice/MediaPlayerService.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index bcfd83a..b8c610d 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -237,7 +237,8 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ? AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize; - utf16_to_utf8(tags.string(), tagSize, attributes->tags); + utf16_to_utf8(tags.string(), tagSize, attributes->tags, + sizeof(attributes->tags) / sizeof(attributes->tags[0])); } } else { ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values"); -- cgit v1.1 From ae1810fab90cd6ec19d4f0386b80aa0391882fba Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 14 Jul 2016 12:37:52 -0700 Subject: Fix build Change-Id: I96a9c437eec53a285ac96794cc1ad0c8954b27e0 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index daef471..54fe622 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -122,7 +122,7 @@ void SoftMP3::initDecoder() { void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { - ALOGE("memset buffer too small: got %lu, expected %zu", outHeader->nAllocLen, len); + ALOGE("memset buffer too small: got %lu, expected %zu", (unsigned long)outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; -- cgit v1.1 From d67bab69a322990aa386dad608ad2a823ef21578 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 14 Jul 2016 13:50:32 -0700 Subject: Fix build Change-Id: I48ba34b3df9c9a896d4b18c3f48e41744b7dab54 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index 54fe622..9f7dd59 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -122,7 +122,7 @@ void SoftMP3::initDecoder() { void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { - ALOGE("memset buffer too small: got %lu, expected %zu", (unsigned long)outHeader->nAllocLen, len); + ALOGE("memset buffer too small: got %u, expected %zu", outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; -- cgit v1.1 From c174665ec2f19904550daeb65d08f4959654d9a4 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Thu, 7 Jul 2016 12:57:02 +0900 Subject: omx: prevent input port enable/disable for software codecs Bug: 29421804 Change-Id: Iba1011e9af942a6dff7f659af769a51e3f5ba66f --- media/libstagefright/omx/SimpleSoftOMXComponent.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp index 60c1e2e..13afd45 100644 --- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp +++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp @@ -469,6 +469,13 @@ void SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) { CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE); CHECK(port->mDef.bEnabled == !enable); + if (port->mDef.eDir != OMX_DirOutput) { + ALOGE("Port enable/disable allowed only on output ports."); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + android_errorWriteLog(0x534e4554, "29421804"); + return; + } + if (!enable) { port->mDef.bEnabled = OMX_FALSE; port->mTransition = PortInfo::DISABLING; -- cgit v1.1 From 6679b5088f36693f5708dcaedd0c9ab7c66df27c Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Thu, 21 Jul 2016 14:43:38 +0900 Subject: DO NOT MERGE - stagefright: fix integer overflow error Bug: 30103394 Change-Id: If449d3e30a0bf2ebea5317f41813bfed094f7408 (cherry picked from commit 2c74a3cd5d1d66b9a35424b9c4443dafa6db5bef) --- media/libstagefright/SampleTable.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index bc01a2d..72e30f1 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #include +#include + #include "include/SampleTable.h" #include "include/SampleIterator.h" @@ -27,11 +29,6 @@ #include #include -/* TODO: remove after being merged into other branches */ -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - namespace android { // static @@ -45,6 +42,8 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); //////////////////////////////////////////////////////////////////////////////// +const off64_t kMaxOffset = std::numeric_limits::max(); + struct SampleTable::CompositionDeltaLookup { CompositionDeltaLookup(); @@ -233,11 +232,11 @@ status_t SampleTable::setSampleToChunkParams( mNumSampleToChunkOffsets = U32_AT(&header[4]); - if (data_size < 8 + mNumSampleToChunkOffsets * 12) { + if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { return ERROR_MALFORMED; } - if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <= + if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= (uint64_t)mNumSampleToChunkOffsets) { ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; @@ -269,16 +268,19 @@ status_t SampleTable::setSampleToChunkParams( return OK; } - if ((off64_t)(SIZE_MAX - 8 - + if ((off64_t)(kMaxOffset - 8 - ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) < mSampleToChunkOffset) { return ERROR_MALFORMED; } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { - uint8_t buffer[12]; + uint8_t buffer[sizeof(SampleToChunkEntry)]; + if (mDataSource->readAt( - mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) + mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), + buffer, + sizeof(buffer)) != (ssize_t)sizeof(buffer)) { return ERROR_IO; } @@ -378,8 +380,7 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); - if ((uint64_t)mTimeToSampleCount > - (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { + if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { // Choose this bound because // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one // time-to-sample entry in the time-to-sample table. @@ -455,7 +456,7 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); - if (allocSize > SIZE_MAX) { + if (allocSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } @@ -522,7 +523,7 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) } uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); - if (allocSize > SIZE_MAX) { + if (allocSize > kMaxTotalSize) { ALOGE("Sync sample table size too large."); return ERROR_OUT_OF_RANGE; } -- cgit v1.1 From 2071f20583103d1ccf6102f84b2eedd6bb1214ba Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Wed, 10 Aug 2016 13:55:18 +0100 Subject: stagefright: Remove the HAL3 limitation from the video reference clock selection Usage of boot-time as the timestamp reference isn't necessarily limited to HAL3. A single property check for media.camera.ts.monotonic is enough to cover all cases. Change-Id: Ic56dbcc6ba32c25bccde6dd0bbf07d4c918af43e --- media/libstagefright/CameraSource.cpp | 3 +-- media/libstagefright/MediaCodecSource.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 4caee78..f6b4741 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -705,8 +705,7 @@ status_t CameraSource::start(MetaData *meta) { int64_t startTimeUs; auto key = kKeyTime; - if (property_get_bool("persist.camera.HAL3.enabled", true) && - !property_get_bool("media.camera.ts.monotonic", true)) { + if (!property_get_bool("media.camera.ts.monotonic", true)) { key = kKeyTimeBoot; } diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 94427ef..14a3c0d 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -665,8 +665,7 @@ status_t MediaCodecSource::onStart(MetaData *params) { if (mFlags & FLAG_USE_SURFACE_INPUT) { auto key = kKeyTime; - if (property_get_bool("persist.camera.HAL3.enabled", true) && - !property_get_bool("media.camera.ts.monotonic", true)) { + if (!property_get_bool("media.camera.ts.monotonic", true)) { key = kKeyTimeBoot; } -- cgit v1.1 From 8d41a10e57903142b9daba6a31a47f101757130c Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Tue, 9 Aug 2016 09:51:51 +0200 Subject: mediascanner: Accept .opus file extension. Apparently there are a number of people and/or tools that name their opus coded audio in ogg containers *.opus. Reflect that fact. Change-Id: I0617a6d93fe793cdef06ffd4e334001e5f9b054e --- media/libstagefright/StagefrightMediaScanner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp index 8d3392e..d5ef1a6 100644 --- a/media/libstagefright/StagefrightMediaScanner.cpp +++ b/media/libstagefright/StagefrightMediaScanner.cpp @@ -46,7 +46,7 @@ static bool FileHasAcceptableExtension(const char *extension) { ".mov", ".ra", ".rm", ".rmvb", ".ac3", ".ape", ".dts", ".mp1", ".mp2", ".f4v", "hlv", "nrg", "m2v", ".swf", ".avi", ".mpg", ".mpeg", ".awb", ".vc1", ".vob", ".divx", - ".mpga", ".mov", ".qcp", ".ec3" + ".mpga", ".mov", ".qcp", ".ec3", ".opus" }; static const size_t kNumValidExtensions = sizeof(kValidExtensions) / sizeof(kValidExtensions[0]); -- cgit v1.1 From 10db5e094e4d7501ec277622dc29e714927dc588 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 27 Jun 2016 13:55:14 -0700 Subject: SoftMP3: memset safely Bug: 29422022 Change-Id: I70c9e33269d16bf8c163815706ac24e18e34fe97 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 22 ++++++++++++++++++---- media/libstagefright/codecs/mp3dec/SoftMP3.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index aa946e6..daef471 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -120,6 +120,17 @@ void SoftMP3::initDecoder() { mIsFirst = true; } +void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { + if (len > outHeader->nAllocLen) { + ALOGE("memset buffer too small: got %lu, expected %zu", outHeader->nAllocLen, len); + android_errorWriteLog(0x534e4554, "29422022"); + notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); + mSignalledError = true; + return NULL; + } + return memset(outHeader->pBuffer, c, len); +} + OMX_ERRORTYPE SoftMP3::internalGetParameter( OMX_INDEXTYPE index, OMX_PTR params) { switch (index) { @@ -300,7 +311,10 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { outHeader->nOffset = 0; outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); - memset(outHeader->pBuffer, 0, outHeader->nFilledLen); + if (!memsetSafe(outHeader, 0, outHeader->nFilledLen)) { + return; + } + } outHeader->nFlags = OMX_BUFFERFLAG_EOS; mSignalledOutputEos = true; @@ -312,9 +326,9 @@ void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { // if mIsFirst is true as we may not have a valid // mConfig->samplingRate and mConfig->num_channels? ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence"); - memset(outHeader->pBuffer, - 0, - mConfig->outputFrameSize * sizeof(int16_t)); + if (!memsetSafe(outHeader, 0, mConfig->outputFrameSize * sizeof(int16_t))) { + return; + } if (inHeader) { mConfig->inputBufferUsedLength = inHeader->nFilledLen; diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h index f9e7b53..3bfa6c7 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.h +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h @@ -72,6 +72,7 @@ private: void initPorts(); void initDecoder(); + void *memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len); DISALLOW_EVIL_CONSTRUCTORS(SoftMP3); }; -- cgit v1.1 From e441275efea14a98d5a059328e660d9a08b13932 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Fri, 17 Jun 2016 01:24:30 +0900 Subject: DO NOT MERGE stagefright: fix possible stack overflow in AVCC reassemble Additionally, remove use of variable length array which is non-standard in C++. Bug: 29161888 Change-Id: Ifdc3e7435f2225214c053b13f3bfe71c7d0ff506 --- media/libstagefright/Utils.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index 17f0201..0d9dc3a 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -671,20 +671,30 @@ void convertMessageToMetaData(const sp &msg, sp &meta) { // reassemble the csd data into its original form sp csd0; if (msg->findBuffer("csd-0", &csd0)) { + int csd0size = csd0->size(); if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { sp csd1; if (msg->findBuffer("csd-1", &csd1)) { - char avcc[1024]; // that oughta be enough, right? - size_t outsize = reassembleAVCC(csd0, csd1, avcc); - meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); + Vector avcc; + int avccSize = csd0size + csd1->size() + 1024; + if (avcc.resize(avccSize) < 0) { + ALOGE("error allocating avcc (size %d); abort setting avcc.", avccSize); + } else { + size_t outsize = reassembleAVCC(csd0, csd1, avcc.editArray()); + meta->setData(kKeyAVCC, kKeyAVCC, avcc.array(), outsize); + } } } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { - int csd0size = csd0->size(); - char esds[csd0size + 31]; - // The written ESDS is actually for an audio stream, but it's enough - // for transporting the CSD to muxers. - reassembleESDS(csd0, esds); - meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); + Vector esds; + int esdsSize = csd0size + 31; + if (esds.resize(esdsSize) < 0) { + ALOGE("error allocating esds (size %d); abort setting esds.", esdsSize); + } else { + // The written ESDS is actually for an audio stream, but it's enough + // for transporting the CSD to muxers. + reassembleESDS(csd0, esds.editArray()); + meta->setData(kKeyESDS, kKeyESDS, esds.array(), esds.size()); + } } } -- cgit v1.1 From e9ef8505a1a33667ef97b752f77190c24b468015 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Wed, 6 Jul 2016 10:13:25 -0700 Subject: Fix corruption via buffer overflow in mediaserver change unbound sprintf() to snprintf() so network-provided values can't overflow the buffers. Applicable to all K/L/M/N branches. Bug: 25747670 Change-Id: Id6a5120c2d08a6fbbd47deffb680ecf82015f4f6 --- media/libstagefright/rtsp/ASessionDescription.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp index 98498e9..47573c3 100644 --- a/media/libstagefright/rtsp/ASessionDescription.cpp +++ b/media/libstagefright/rtsp/ASessionDescription.cpp @@ -17,6 +17,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "ASessionDescription" #include +#include #include "ASessionDescription.h" @@ -211,12 +212,12 @@ void ASessionDescription::getFormatType( *PT = x; - char key[20]; - sprintf(key, "a=rtpmap:%lu", x); + char key[32]; + snprintf(key, sizeof(key), "a=rtpmap:%lu", x); CHECK(findAttribute(index, key, desc)); - sprintf(key, "a=fmtp:%lu", x); + snprintf(key, sizeof(key), "a=fmtp:%lu", x); if (!findAttribute(index, key, params)) { params->clear(); } @@ -228,8 +229,11 @@ bool ASessionDescription::getDimensions( *width = 0; *height = 0; - char key[20]; - sprintf(key, "a=framesize:%lu", PT); + char key[33]; + snprintf(key, sizeof(key), "a=framesize:%lu", PT); + if (PT > 9999999) { + android_errorWriteLog(0x534e4554, "25747670"); + } AString value; if (!findAttribute(index, key, &value)) { return false; -- cgit v1.1 From ed4f365e8b158934937ad0a2e14ede566923bc33 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 12 Jul 2016 18:00:53 -0700 Subject: OMXCodec: check IMemory::pointer() before using allocation Bug: 29421811 Change-Id: I0a73ba12bae4122f1d89fc92e5ea4f6a96cd1ed1 --- media/libstagefright/OMXCodec.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 4618e21..7e15e18 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1622,7 +1622,9 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) { sp mem = mDealer[portIndex]->allocate(def.nBufferSize); - CHECK(mem.get() != NULL); + if (mem == NULL || mem->pointer() == NULL) { + return NO_MEMORY; + } BufferInfo info; info.mData = NULL; -- cgit v1.1 From 356f1ded898c5708ea95fe22ece052c3a094950d Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 24 Jun 2016 12:37:45 -0700 Subject: SoftVPX: fix nFilledLen overflow Bug: 29421675 Change-Id: I25d4cf54a5df22c2130c37e95c7c7f75063111f3 --- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 22 +++++++++++++++++++--- media/libstagefright/codecs/on2/dec/SoftVPX.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 02e85a1..58a2660 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -149,7 +149,7 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por outHeader->nFlags = 0; outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2; outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv; - if (outHeader->nAllocLen >= outHeader->nFilledLen) { + if (outputBufferSafe(outHeader)) { uint8_t *dst = outHeader->pBuffer; const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y]; const uint8_t *srcU = (const uint8_t *)mImg->planes[VPX_PLANE_U]; @@ -159,8 +159,6 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por size_t srcVStride = mImg->stride[VPX_PLANE_V]; copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride); } else { - ALOGE("b/27597103, buffer too small"); - android_errorWriteLog(0x534e4554, "27597103"); outHeader->nFilledLen = 0; } @@ -190,6 +188,24 @@ bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *por return true; } +bool SoftVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) { + uint32_t width = outputBufferWidth(); + uint32_t height = outputBufferHeight(); + uint64_t nFilledLen = width; + nFilledLen *= height; + if (nFilledLen > UINT32_MAX / 3) { + ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", nFilledLen, width, height); + android_errorWriteLog(0x534e4554, "29421675"); + return false; + } else if (outHeader->nAllocLen < outHeader->nFilledLen) { + ALOGE("b/27597103, buffer too small"); + android_errorWriteLog(0x534e4554, "27597103"); + return false; + } + + return true; +} + void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) { if (mOutputPortSettingsChange != NONE || mEOSStatus == OUTPUT_FRAMES_FLUSHED) { return; diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h index 8ccbae2..84cf79c 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.h +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h @@ -66,6 +66,7 @@ private: status_t initDecoder(); status_t destroyDecoder(); bool outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset); + bool outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader); DISALLOW_EVIL_CONSTRUCTORS(SoftVPX); }; -- cgit v1.1 From 2a1a0fd88e84fc845cd6bce3a161672d80c1df39 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 13 Jul 2016 20:27:32 -0700 Subject: fix build Change-Id: I9bb8c659d3fc97a8e748451d82d0f3448faa242b --- media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 58a2660..912fac2 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -194,7 +194,8 @@ bool SoftVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) { uint64_t nFilledLen = width; nFilledLen *= height; if (nFilledLen > UINT32_MAX / 3) { - ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", nFilledLen, width, height); + ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u", + (unsigned long long)nFilledLen, width, height); android_errorWriteLog(0x534e4554, "29421675"); return false; } else if (outHeader->nAllocLen < outHeader->nFilledLen) { -- cgit v1.1 From 3d4cb8bbc03aab52c71bb339624170f2b7238cdf Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Tue, 28 Jun 2016 18:24:52 +0100 Subject: Add bound checks to utf16_to_utf8 Bug: 29250543 Change-Id: I3518416e89ed901021970958fb6005fd69129f7c (cherry picked from commit 1d3f4278b2666d1a145af2f54782c993aa07d1d9) --- media/libmediaplayerservice/MediaPlayerService.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index bcfd83a..b8c610d 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -237,7 +237,8 @@ void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attribu // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ? AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize; - utf16_to_utf8(tags.string(), tagSize, attributes->tags); + utf16_to_utf8(tags.string(), tagSize, attributes->tags, + sizeof(attributes->tags) / sizeof(attributes->tags[0])); } } else { ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values"); -- cgit v1.1 From 361db9e07657a6de075b5f23b5cfcecfd5a73fd3 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 14 Jul 2016 12:37:52 -0700 Subject: Fix build Change-Id: I96a9c437eec53a285ac96794cc1ad0c8954b27e0 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index daef471..54fe622 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -122,7 +122,7 @@ void SoftMP3::initDecoder() { void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { - ALOGE("memset buffer too small: got %lu, expected %zu", outHeader->nAllocLen, len); + ALOGE("memset buffer too small: got %lu, expected %zu", (unsigned long)outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; -- cgit v1.1 From 05713f1d239566bff957177f1a7aaba380fbc978 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 14 Jul 2016 13:50:32 -0700 Subject: Fix build Change-Id: I48ba34b3df9c9a896d4b18c3f48e41744b7dab54 --- media/libstagefright/codecs/mp3dec/SoftMP3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp index 54fe622..9f7dd59 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -122,7 +122,7 @@ void SoftMP3::initDecoder() { void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) { if (len > outHeader->nAllocLen) { - ALOGE("memset buffer too small: got %lu, expected %zu", (unsigned long)outHeader->nAllocLen, len); + ALOGE("memset buffer too small: got %u, expected %zu", outHeader->nAllocLen, len); android_errorWriteLog(0x534e4554, "29422022"); notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL); mSignalledError = true; -- cgit v1.1 From 9d32255b7302922bac4141bf557277d87bc81388 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Thu, 7 Jul 2016 12:57:02 +0900 Subject: omx: prevent input port enable/disable for software codecs Bug: 29421804 Change-Id: Iba1011e9af942a6dff7f659af769a51e3f5ba66f --- media/libstagefright/omx/SimpleSoftOMXComponent.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp index 60c1e2e..13afd45 100644 --- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp +++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp @@ -469,6 +469,13 @@ void SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) { CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE); CHECK(port->mDef.bEnabled == !enable); + if (port->mDef.eDir != OMX_DirOutput) { + ALOGE("Port enable/disable allowed only on output ports."); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + android_errorWriteLog(0x534e4554, "29421804"); + return; + } + if (!enable) { port->mDef.bEnabled = OMX_FALSE; port->mTransition = PortInfo::DISABLING; -- cgit v1.1 From 2bef075f91e203e96130c88320b7d13eddc17d89 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Tue, 21 Jun 2016 19:10:21 -0700 Subject: Impose a size bound for dynamically allocated tables in stbl. Impose a restriction of 200MiB for tables in stsc, stts, ctts and stss boxes. Also change mTimeToSample from Vector to array. Bug: 29367429 Change-Id: I953bea9fe0590268cf27376740f582dc88563d42 Merge conflict resolution of ag/1170200 to mnc-mr2-release --- media/libstagefright/SampleTable.cpp | 150 ++++++++++++++++++++++++----- media/libstagefright/include/SampleTable.h | 9 +- 2 files changed, 133 insertions(+), 26 deletions(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index 8df9cb8..bc01a2d 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -123,7 +123,7 @@ SampleTable::SampleTable(const sp &source) mNumSampleSizes(0), mHasTimeToSample(false), mTimeToSampleCount(0), - mTimeToSample(), + mTimeToSample(NULL), mSampleTimeEntries(NULL), mCompositionTimeDeltaEntries(NULL), mNumCompositionTimeDeltaEntries(0), @@ -132,7 +132,8 @@ SampleTable::SampleTable(const sp &source) mNumSyncSamples(0), mSyncSamples(NULL), mLastSyncSampleIndex(0), - mSampleToChunkEntries(NULL) { + mSampleToChunkEntries(NULL), + mTotalSize(0) { mSampleIterator = new SampleIterator(this); } @@ -143,6 +144,9 @@ SampleTable::~SampleTable() { delete[] mSyncSamples; mSyncSamples = NULL; + delete[] mTimeToSample; + mTimeToSample = NULL; + delete mCompositionDeltaLookup; mCompositionDeltaLookup = NULL; @@ -233,13 +237,43 @@ status_t SampleTable::setSampleToChunkParams( return ERROR_MALFORMED; } - if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets) + if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <= + (uint64_t)mNumSampleToChunkOffsets) { + ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; + } + + mTotalSize += (uint64_t)mNumSampleToChunkOffsets * + sizeof(SampleToChunkEntry); + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sample-to-chunk table size would make sample table too large.\n" + " Requested sample-to-chunk table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)mNumSampleToChunkOffsets * + sizeof(SampleToChunkEntry), + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return ERROR_OUT_OF_RANGE; + } mSampleToChunkEntries = new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; - if (!mSampleToChunkEntries) + if (!mSampleToChunkEntries) { + ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", + (unsigned long long)mNumSampleToChunkOffsets); return ERROR_OUT_OF_RANGE; + } + + if (mNumSampleToChunkOffsets == 0) { + return OK; + } + + if ((off64_t)(SIZE_MAX - 8 - + ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) + < mSampleToChunkOffset) { + return ERROR_MALFORMED; + } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { uint8_t buffer[12]; @@ -248,8 +282,11 @@ status_t SampleTable::setSampleToChunkParams( != (ssize_t)sizeof(buffer)) { return ERROR_IO; } - - CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. + // chunk index is 1 based in the spec. + if (U32_AT(buffer) < 1) { + ALOGE("b/23534160"); + return ERROR_OUT_OF_RANGE; + } // We want the chunk index to be 0-based. mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; @@ -349,21 +386,41 @@ status_t SampleTable::setTimeToSampleParams( // 2) mTimeToSampleCount is the number of entries of the time-to-sample // table. // 3) We hope that the table size does not exceed UINT32_MAX. - ALOGE(" Error: Time-to-sample table size too large."); - + ALOGE("Time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } // Note: At this point, we know that mTimeToSampleCount * 2 will not // overflow because of the above condition. - if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, - mTimeToSampleCount * 2)) { - ALOGE(" Error: Incomplete data read for time-to-sample table."); + + uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Time-to-sample table size would make sample table too large.\n" + " Requested time-to-sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return ERROR_OUT_OF_RANGE; + } + + mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; + if (!mTimeToSample) { + ALOGE("Cannot allocate time-to-sample table with %llu entries.", + (unsigned long long)mTimeToSampleCount); + return ERROR_OUT_OF_RANGE; + } + + if (mDataSource->readAt(data_offset + 8, mTimeToSample, + (size_t)allocSize) < (ssize_t)allocSize) { + ALOGE("Incomplete data read for time-to-sample table."); return ERROR_IO; } - for (size_t i = 0; i < mTimeToSample.size(); ++i) { - mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); + for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { + mTimeToSample[i] = ntohl(mTimeToSample[i]); } mHasTimeToSample = true; @@ -398,17 +455,32 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); - if (allocSize > UINT32_MAX) { + if (allocSize > SIZE_MAX) { + ALOGE("Composition-time-to-sample table size too large."); + return ERROR_OUT_OF_RANGE; + } + + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Composition-time-to-sample table would make sample table too large.\n" + " Requested composition-time-to-sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries]; - if (!mCompositionTimeDeltaEntries) + if (!mCompositionTimeDeltaEntries) { + ALOGE("Cannot allocate composition-time-to-sample table with %llu " + "entries.", (unsigned long long)numEntries); return ERROR_OUT_OF_RANGE; + } - if (mDataSource->readAt( - data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) - < (ssize_t)numEntries * 8) { + if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, + (size_t)allocSize) < (ssize_t)allocSize) { delete[] mCompositionTimeDeltaEntries; mCompositionTimeDeltaEntries = NULL; @@ -449,18 +521,33 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) ALOGV("Table of sync samples is empty or has only a single entry!"); } - uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); + uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); if (allocSize > SIZE_MAX) { + ALOGE("Sync sample table size too large."); + return ERROR_OUT_OF_RANGE; + } + + mTotalSize += allocSize; + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sync sample table size would make sample table too large.\n" + " Requested sync sample table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)allocSize, + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); return ERROR_OUT_OF_RANGE; } mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; - if (!mSyncSamples) + if (!mSyncSamples) { + ALOGE("Cannot allocate sync sample table with %llu entries.", + (unsigned long long)mNumSyncSamples); return ERROR_OUT_OF_RANGE; + } - size_t size = mNumSyncSamples * sizeof(uint32_t); - if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) - != (ssize_t)size) { + if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, + (size_t)allocSize) != (ssize_t)allocSize) { return ERROR_IO; } @@ -525,9 +612,24 @@ void SampleTable::buildSampleEntriesTable() { return; } + mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); + if (mTotalSize > kMaxTotalSize) { + ALOGE("Sample entry table size would make sample table too large.\n" + " Requested sample entry table size = %llu\n" + " Eventual sample table size >= %llu\n" + " Allowed sample table size = %llu\n", + (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), + (unsigned long long)mTotalSize, + (unsigned long long)kMaxTotalSize); + return; + } + mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; - if (!mSampleTimeEntries) + if (!mSampleTimeEntries) { + ALOGE("Cannot allocate sample entry table with %llu entries.", + (unsigned long long)mNumSampleSizes); return; + } uint32_t sampleIndex = 0; uint32_t sampleTime = 0; diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h index 465f37c..552eef7 100644 --- a/media/libstagefright/include/SampleTable.h +++ b/media/libstagefright/include/SampleTable.h @@ -24,7 +24,6 @@ #include #include #include -#include namespace android { @@ -96,6 +95,9 @@ private: static const uint32_t kSampleSizeType32; static const uint32_t kSampleSizeTypeCompact; + // Limit the total size of all internal tables to 200MiB. + static const size_t kMaxTotalSize = 200 * (1 << 20); + sp mDataSource; Mutex mLock; @@ -113,7 +115,7 @@ private: bool mHasTimeToSample; uint32_t mTimeToSampleCount; - Vector mTimeToSample; + uint32_t* mTimeToSample; struct SampleTimeEntry { uint32_t mSampleIndex; @@ -139,6 +141,9 @@ private: }; SampleToChunkEntry *mSampleToChunkEntries; + // Approximate size of all tables combined. + uint64_t mTotalSize; + friend struct SampleIterator; // normally we don't round -- cgit v1.1 From eb11f3a9e6638805c4473c3bf448584893bae519 Mon Sep 17 00:00:00 2001 From: Wonsik Kim Date: Thu, 21 Jul 2016 14:43:38 +0900 Subject: DO NOT MERGE - stagefright: fix integer overflow error Bug: 30103394 Change-Id: If449d3e30a0bf2ebea5317f41813bfed094f7408 (cherry picked from commit 2c74a3cd5d1d66b9a35424b9c4443dafa6db5bef) --- media/libstagefright/SampleTable.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp index bc01a2d..72e30f1 100644 --- a/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/SampleTable.cpp @@ -18,6 +18,8 @@ //#define LOG_NDEBUG 0 #include +#include + #include "include/SampleTable.h" #include "include/SampleIterator.h" @@ -27,11 +29,6 @@ #include #include -/* TODO: remove after being merged into other branches */ -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - namespace android { // static @@ -45,6 +42,8 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); //////////////////////////////////////////////////////////////////////////////// +const off64_t kMaxOffset = std::numeric_limits::max(); + struct SampleTable::CompositionDeltaLookup { CompositionDeltaLookup(); @@ -233,11 +232,11 @@ status_t SampleTable::setSampleToChunkParams( mNumSampleToChunkOffsets = U32_AT(&header[4]); - if (data_size < 8 + mNumSampleToChunkOffsets * 12) { + if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { return ERROR_MALFORMED; } - if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <= + if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= (uint64_t)mNumSampleToChunkOffsets) { ALOGE("Sample-to-chunk table size too large."); return ERROR_OUT_OF_RANGE; @@ -269,16 +268,19 @@ status_t SampleTable::setSampleToChunkParams( return OK; } - if ((off64_t)(SIZE_MAX - 8 - + if ((off64_t)(kMaxOffset - 8 - ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) < mSampleToChunkOffset) { return ERROR_MALFORMED; } for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { - uint8_t buffer[12]; + uint8_t buffer[sizeof(SampleToChunkEntry)]; + if (mDataSource->readAt( - mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) + mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), + buffer, + sizeof(buffer)) != (ssize_t)sizeof(buffer)) { return ERROR_IO; } @@ -378,8 +380,7 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); - if ((uint64_t)mTimeToSampleCount > - (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { + if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { // Choose this bound because // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one // time-to-sample entry in the time-to-sample table. @@ -455,7 +456,7 @@ status_t SampleTable::setCompositionTimeToSampleParams( mNumCompositionTimeDeltaEntries = numEntries; uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); - if (allocSize > SIZE_MAX) { + if (allocSize > kMaxTotalSize) { ALOGE("Composition-time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } @@ -522,7 +523,7 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) } uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t); - if (allocSize > SIZE_MAX) { + if (allocSize > kMaxTotalSize) { ALOGE("Sync sample table size too large."); return ERROR_OUT_OF_RANGE; } -- cgit v1.1 From e72652f039b9067f9e747d70184507d41ef1f6d7 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Wed, 2 Dec 2015 11:40:09 -0800 Subject: Don't place large objects on the stack Bug: 25020816 Change-Id: Ife4da9fc3000e645f654f2eb28b37ad3a89d61f9 --- services/audioflinger/Threads.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index e1e4980..ecdbf43 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -4470,8 +4470,12 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector& ar dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames()); // Make a non-atomic copy of fast mixer dump state so it won't change underneath us - const FastMixerDumpState copy(mFastMixerDumpState); - copy.dump(fd); + // while we are dumping it. It may be inconsistent, but it won't mutate! + // This is a large object so we place it on the heap. + // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. + const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState); + copy->dump(fd); + delete copy; #ifdef STATE_QUEUE_DUMP // Similar for state queue @@ -6460,9 +6464,13 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector& a dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no"); dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no"); - // Make a non-atomic copy of fast capture dump state so it won't change underneath us - const FastCaptureDumpState copy(mFastCaptureDumpState); - copy.dump(fd); + // Make a non-atomic copy of fast capture dump state so it won't change underneath us + // while we are dumping it. It may be inconsistent, but it won't mutate! + // This is a large object so we place it on the heap. + // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. + const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState); + copy->dump(fd); + delete copy; } void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector& args __unused) -- cgit v1.1 From 6fde774471629832951e9b9b2e0d758e10f6431d Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Tue, 3 May 2016 16:34:26 -0700 Subject: audioflinger: set flush pending on invalidating offload track On invalidating an offload track, the IAudioTrack instance is destroyed and the offload output is released. If it so happens that APM::getOutputForAttr for the new IAudioTrack is called before OffloadThread::prepareTracks_l checks and removes an invalid track, the same output can get reused. The side effect of this is data present in HAL and below from before the invalidate will be rendered before data from the new seek position is rendered. This is unexpected. To fix this, set hint to issue flush when an offload track is invalidated. Bug: 28566885 CRs-Fixed: 1002438 Change-Id: Ib6c38a3abb600598b87591bac90d03b7150d5216 --- services/audioflinger/Threads.cpp | 16 ++++++++++++++-- services/audioflinger/Threads.h | 4 +++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index ecdbf43..ee5dc24 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -2574,11 +2574,10 @@ void AudioFlinger::PlaybackThread::cacheParameters_l() } } -void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) +void AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) { ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d", this, streamType, mTracks.size()); - Mutex::Autolock _l(mLock); size_t size = mTracks.size(); for (size_t i = 0; i < size; i++) { @@ -2589,6 +2588,12 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy } } +void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) +{ + Mutex::Autolock _l(mLock); + invalidateTracks_l(streamType); +} + status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp& chain) { int session = chain->sessionId(); @@ -5371,6 +5376,13 @@ void AudioFlinger::OffloadThread::flushHw_l() } } +void AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType) +{ + Mutex::Autolock _l(mLock); + mFlushPending = true; + PlaybackThread::invalidateTracks_l(streamType); +} + // ---------------------------------------------------------------------------- AudioFlinger::DuplicatingThread::DuplicatingThread(const sp& audioFlinger, diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 48ff77d..8fab1e4 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -617,7 +617,8 @@ public: virtual bool isValidSyncEvent(const sp& event) const; // called with AudioFlinger lock held - void invalidateTracks(audio_stream_type_t streamType); + void invalidateTracks_l(audio_stream_type_t streamType); + virtual void invalidateTracks(audio_stream_type_t streamType); virtual size_t frameCount() const { return mNormalFrameCount; } @@ -1000,6 +1001,7 @@ protected: virtual bool waitingAsyncCallback(); virtual bool waitingAsyncCallback_l(); + virtual void invalidateTracks(audio_stream_type_t streamType); private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause -- cgit v1.1 From e4575aeb5d66f71b6ef6c611570ea96df81c1246 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Thu, 5 May 2016 19:02:06 -0700 Subject: audioflinger: Always process volume commands from a latest track Process them irrespective of whether the track is invalid. Ignoring to do so may lead to glitches/loud bursts in audio when a new track reuses the same output. CRs-Fixed: 1002448 Change-Id: I9afbdd221db3a7311eb0ec8bb75852cf5409084e --- services/audioflinger/Threads.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index ee5dc24..e5e8bdb 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -5169,15 +5169,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr if (track->isInvalid()) { ALOGW("An invalidated track shouldn't be in active list"); tracksToRemove->add(track); - continue; - } - - if (track->mState == TrackBase::IDLE) { + } else if (track->mState == TrackBase::IDLE) { ALOGW("An idle track shouldn't be in active list"); - continue; - } - - if (track->isPausing()) { + } else if (track->isPausing()) { track->setPaused(); if (last) { if (mHwSupportsPause && !mHwPaused) { @@ -5200,7 +5194,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr if (last) { mFlushPending = true; } - } else if (track->isResumePending()){ + } else if (track->isResumePending()) { track->resumeAck(); if (last) { if (mPausedBytesRemaining) { -- cgit v1.1 From 16d14e178003b193db1422c11c95bc0b1d44b690 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 19 Aug 2016 17:41:21 -0700 Subject: stagefright: Disable thumbnail mode for 8996-class devices * The hardware is freezing when used for certain media types. Disable it until the issue is understood. Change-Id: Iaec2420b4f8d3ceacf2c6f72ab14db424092c96b --- media/libstagefright/FFMPEGSoftCodec.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/FFMPEGSoftCodec.cpp b/media/libstagefright/FFMPEGSoftCodec.cpp index 7233162..0d5802b 100644 --- a/media/libstagefright/FFMPEGSoftCodec.cpp +++ b/media/libstagefright/FFMPEGSoftCodec.cpp @@ -35,6 +35,8 @@ #include #include +#include + #include #include #include @@ -394,9 +396,13 @@ status_t FFMPEGSoftCodec::setVideoFormat( } // Enable Sync-frame decode mode for thumbnails + char board[PROPERTY_VALUE_MAX]; + property_get("ro.board.platform", board, NULL); int32_t thumbnailMode = 0; if (msg->findInt32("thumbnail-mode", &thumbnailMode) && - thumbnailMode > 0) { + thumbnailMode > 0 && + !(!strcmp(board, "msm8996") || !strcmp(board, "msm8937") || + !strcmp(board, "msm8953") || !strcmp(board, "msm8976"))) { ALOGV("Enabling thumbnail mode."); QOMX_ENABLETYPE enableType; OMX_INDEXTYPE indexType; -- cgit v1.1 From b52c75787d068a92c961d29f973e975b7651abe5 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Mon, 18 Jul 2016 20:12:02 -0700 Subject: SoftMPEG4: Check the buffer size before writing the reference frame. Also prevent overflow in SoftMPEG4 and division by zero in SoftMPEG4Encoder. Bug: 30033990 Change-Id: I7701f5fc54c2670587d122330e5dc851f64ed3c2 (cherry picked from commit 695123195034402ca76169b195069c28c30342d3) --- .../codecs/m4v_h263/dec/SoftMPEG4.cpp | 22 ++++++++++++++++++++-- .../codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp | 4 ++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index bb59ae4..e1cfc06 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -210,8 +210,17 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { PortInfo *port = editPortInfo(1); OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader; + OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size; + if ((outHeader->nAllocLen < yFrameSize) || + (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) { + ALOGE("Too small output buffer for reference frame: %zu bytes", + outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "30033990"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } PVSetReferenceYUV(mHandle, outHeader->pBuffer); - mFramesConfigured = true; } @@ -229,7 +238,16 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { int32_t bufferSize = inHeader->nFilledLen; int32_t tmp = bufferSize; - OMX_U32 frameSize = (mWidth * mHeight * 3) / 2; + OMX_U32 frameSize; + OMX_U64 yFrameSize = (OMX_U64)mWidth * (OMX_U64)mHeight; + if (yFrameSize > ((OMX_U64)UINT32_MAX / 3) * 2) { + ALOGE("Frame size too large"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + frameSize = (OMX_U32)(yFrameSize + (yFrameSize / 2)); + if (outHeader->nAllocLen < frameSize) { android_errorWriteLog(0x534e4554, "27833616"); ALOGE("Insufficient output buffer size"); diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index 7638bb7..2eb51c9 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -116,6 +116,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { ALOGE("Failed to get default encoding parameters"); return OMX_ErrorUndefined; } + if (mFramerate == 0) { + ALOGE("Framerate should not be 0"); + return OMX_ErrorUndefined; + } mEncParams->encMode = mEncodeMode; mEncParams->encWidth[0] = mWidth; mEncParams->encHeight[0] = mHeight; -- cgit v1.1 From 173e6eb58c8df2b934a5602732fe0b0aac1cd03f Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Tue, 16 Aug 2016 14:24:43 -0700 Subject: better validation lengths of strings in ID3 tags Validate lengths on strings in ID3 tags, particularly around 0. Also added code to handle cases when we can't get memory for copies of strings we want to extract from these tags. Affects L/M/N/master, same patch for all of them. Bug: 30744884 Change-Id: I2675a817a39f0927ec1f7e9f9c09f2e61020311e Test: play mp3 file which caused a <0 length. (cherry picked from commit d23c01546c4f82840a01a380def76ab6cae5d43f) --- media/libstagefright/id3/ID3.cpp | 57 +++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 4410579..6e14197 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -77,7 +77,10 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1) mFirstFrameOffset(0), mVersion(ID3_UNKNOWN), mRawSize(0) { - sp source = new MemorySource(data, size); + sp source = new (std::nothrow) MemorySource(data, size); + + if (source == NULL) + return; mIsValid = parseV2(source, 0); @@ -542,6 +545,10 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { n -= skipped; } + if (n <= 0) { + return; + } + if (encoding == 0x00) { // supposedly ISO 8859-1 id->setTo((const char*)frameData + 1, n); @@ -555,11 +562,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; #if BYTE_ORDER == LITTLE_ENDIAN - framedatacopy = new char16_t[len]; - for (int i = 0; i < len; i++) { - framedatacopy[i] = bswap_16(framedata[i]); + if (len > 0) { + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } + for (int i = 0; i < len; i++) { + framedatacopy[i] = bswap_16(framedata[i]); + } + framedata = framedatacopy; } - framedata = framedatacopy; #endif id->setTo(framedata, len); if (framedatacopy != NULL) { @@ -572,15 +584,26 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; if (*framedata == 0xfffe) { - // endianness marker doesn't match host endianness, convert - framedatacopy = new char16_t[len]; + // endianness marker != host endianness, convert & skip + if (len <= 1) { + return; // nothing after the marker + } + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } for (int i = 0; i < len; i++) { framedatacopy[i] = bswap_16(framedata[i]); } framedata = framedatacopy; - } - // If the string starts with an endianness marker, skip it - if (*framedata == 0xfeff) { + // and skip over the marker + framedata++; + len--; + } else if (*framedata == 0xfeff) { + // endianness marker == host endianness, skip it + if (len <= 1) { + return; // nothing after the marker + } framedata++; len--; } @@ -595,12 +618,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { } if (eightBit) { // collapse to 8 bit, then let the media scanner client figure out the real encoding - char *frame8 = new char[len]; - for (int i = 0; i < len; i++) { - frame8[i] = framedata[i]; + char *frame8 = new (std::nothrow) char[len]; + if (frame8 != NULL) { + for (int i = 0; i < len; i++) { + frame8[i] = framedata[i]; + } + id->setTo(frame8, len); + delete [] frame8; + } else { + id->setTo(framedata, len); } - id->setTo(frame8, len); - delete [] frame8; } else { id->setTo(framedata, len); } -- cgit v1.1 From 54ac34642df5b547afef19b94f6cc9a8062a49b5 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 16 Aug 2016 16:50:54 -0700 Subject: MediaPlayerService: avoid invalid static cast Bug: 30204103 Change-Id: Ie0dd3568a375f1e9fed8615ad3d85184bcc99028 (cherry picked from commit ee0a0e39acdcf8f97e0d6945c31ff36a06a36e9d) --- media/libmediaplayerservice/MediaPlayerService.cpp | 10 ++++++++++ media/libmediaplayerservice/MediaPlayerService.h | 1 + 2 files changed, 11 insertions(+) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index b8c610d..0483228 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -559,6 +559,12 @@ void MediaPlayerService::removeClient(wp client) mClients.remove(client); } +bool MediaPlayerService::hasClient(wp client) +{ + Mutex::Autolock lock(mLock); + return mClients.indexOf(client) != NAME_NOT_FOUND; +} + MediaPlayerService::Client::Client( const sp& service, pid_t pid, int32_t connId, const sp& client, @@ -1056,6 +1062,10 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp& playe ALOGV("setNextPlayer"); Mutex::Autolock l(mLock); sp c = static_cast(player.get()); + if (!mService->hasClient(c)) { + return BAD_VALUE; + } + mNextClient = c; if (c != NULL) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 60d4617..e8e5360 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -226,6 +226,7 @@ public: virtual status_t dump(int fd, const Vector& args); void removeClient(wp client); + bool hasClient(wp client); // For battery usage tracking purpose struct BatteryUsageInfo { -- cgit v1.1 From 4d96096488a9e5b0a65638f93e71b79bee80e760 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 17 Aug 2016 06:19:32 -0700 Subject: soundtrigger: add size check on sound model and recogntion data Bug: 30148546 Change-Id: I082f535a853c96571887eeea37c6d41ecee7d8c0 (cherry picked from commit bb00d8f139ff51336ab3c810d35685003949bcf8) (cherry picked from commit ef0c91518446e65533ca8bab6726a845f27c73fd) --- services/soundtrigger/SoundTriggerHwService.cpp | 38 +++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 9de6fe2..e428388 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -534,6 +534,22 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp& modelM struct sound_trigger_sound_model *sound_model = (struct sound_trigger_sound_model *)modelMemory->pointer(); + size_t structSize; + if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { + structSize = sizeof(struct sound_trigger_phrase_sound_model); + } else { + structSize = sizeof(struct sound_trigger_sound_model); + } + + if (sound_model->data_offset < structSize || + sound_model->data_size > (UINT_MAX - sound_model->data_offset) || + modelMemory->size() < sound_model->data_offset || + sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { + android_errorWriteLog(0x534e4554, "30148546"); + ALOGE("loadSoundModel() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mModels.size() >= mDescriptor.properties.max_sound_models) { @@ -603,11 +619,23 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha return PERMISSION_DENIED; } - if (dataMemory != 0 && dataMemory->pointer() == NULL) { - ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()"); + if (dataMemory == 0 || dataMemory->pointer() == NULL) { + ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); return BAD_VALUE; } + + struct sound_trigger_recognition_config *config = + (struct sound_trigger_recognition_config *)dataMemory->pointer(); + + if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || + config->data_size > (UINT_MAX - config->data_offset) || + dataMemory->size() < config->data_offset || + config->data_size > (dataMemory->size() - config->data_offset)) { + ALOGE("startRecognition() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { return INVALID_OPERATION; @@ -616,17 +644,11 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha if (model == 0) { return BAD_VALUE; } - if ((dataMemory == 0) || - (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) { - return BAD_VALUE; - } if (model->mState == Model::STATE_ACTIVE) { return INVALID_OPERATION; } - struct sound_trigger_recognition_config *config = - (struct sound_trigger_recognition_config *)dataMemory->pointer(); //TODO: get capture handle and device from audio policy service config->capture_handle = model->mCaptureIOHandle; -- cgit v1.1 From 497fcd71dd221dd2ccf6b32127ece5ec43c8660e Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Wed, 17 Aug 2016 14:11:13 -0700 Subject: Add EFFECT_CMD_SET_PARAM parameter checking Bug: 30204301 Change-Id: Ib9c3ee1c2f23c96f8f7092dd9e146bc453d7a290 (cherry picked from commit e4a1d91501d47931dbae19c47815952378787ab6) --- services/audioflinger/Effects.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index eb52dee..f87b8f5 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -543,6 +543,13 @@ status_t AudioFlinger::EffectModule::remove_effect_from_hal_l() return NO_ERROR; } +// round up delta valid if value and divisor are positive. +template +static T roundUpDelta(const T &value, const T &divisor) { + T remainder = value % divisor; + return remainder == 0 ? 0 : divisor - remainder; +} + status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -564,6 +571,22 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, android_errorWriteLog(0x534e4554, "29251553"); return -EINVAL; } + if ((cmdCode == EFFECT_CMD_SET_PARAM + || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used + (sizeof(effect_param_t) > cmdSize + || ((effect_param_t *)pCmdData)->psize > cmdSize + - sizeof(effect_param_t) + || ((effect_param_t *)pCmdData)->vsize > cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) > + cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + - ((effect_param_t *)pCmdData)->vsize)) { + android_errorWriteLog(0x534e4554, "30204301"); + return -EINVAL; + } status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, -- cgit v1.1 From 45f500ac36958b36afa649c8d68490cd38442252 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Fri, 19 Aug 2016 02:07:33 -0700 Subject: Fix build breakage caused by commit 940829f69b52d6038db66a9c727534636ecc456d. Change-Id: I4776db4a26fb3c31bb994d48788373fe569c812a (cherry picked from commit baa9146401e28c5acf54dea21ddd197f0d3a8fcd) --- media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index e1cfc06..1dd631a 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -213,8 +213,8 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size; if ((outHeader->nAllocLen < yFrameSize) || (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) { - ALOGE("Too small output buffer for reference frame: %zu bytes", - outHeader->nAllocLen); + ALOGE("Too small output buffer for reference frame: %lu bytes", + (unsigned long)outHeader->nAllocLen); android_errorWriteLog(0x534e4554, "30033990"); notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); mSignalledError = true; -- cgit v1.1 From 4f7b529d2405e4929e424d4bb12e4fa5bce2fa04 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Wed, 17 Aug 2016 14:11:13 -0700 Subject: Add EFFECT_CMD_SET_PARAM parameter checking Fix merge conflict to mnc-mr3-release Bug: 30204301 Change-Id: Ib9c3ee1c2f23c96f8f7092dd9e146bc453d7a290 --- services/audioflinger/Effects.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index 949c91d..f87b8f5 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -543,6 +543,13 @@ status_t AudioFlinger::EffectModule::remove_effect_from_hal_l() return NO_ERROR; } +// round up delta valid if value and divisor are positive. +template +static T roundUpDelta(const T &value, const T &divisor) { + T remainder = value % divisor; + return remainder == 0 ? 0 : divisor - remainder; +} + status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -558,6 +565,28 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, if (mStatus != NO_ERROR) { return mStatus; } + if (cmdCode == EFFECT_CMD_GET_PARAM && + (*replySize < sizeof(effect_param_t) || + ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t))) { + android_errorWriteLog(0x534e4554, "29251553"); + return -EINVAL; + } + if ((cmdCode == EFFECT_CMD_SET_PARAM + || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED) && // DEFERRED not generally used + (sizeof(effect_param_t) > cmdSize + || ((effect_param_t *)pCmdData)->psize > cmdSize + - sizeof(effect_param_t) + || ((effect_param_t *)pCmdData)->vsize > cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + || roundUpDelta(((effect_param_t *)pCmdData)->psize, (uint32_t)sizeof(int)) > + cmdSize + - sizeof(effect_param_t) + - ((effect_param_t *)pCmdData)->psize + - ((effect_param_t *)pCmdData)->vsize)) { + android_errorWriteLog(0x534e4554, "30204301"); + return -EINVAL; + } status_t status = (*mEffectInterface)->command(mEffectInterface, cmdCode, cmdSize, -- cgit v1.1 From b569311fe413fef4f35114f00485340cc6e322ee Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Mon, 18 Jul 2016 20:12:02 -0700 Subject: SoftMPEG4: Check the buffer size before writing the reference frame. Also prevent overflow in SoftMPEG4 and division by zero in SoftMPEG4Encoder. Bug: 30033990 Change-Id: I7701f5fc54c2670587d122330e5dc851f64ed3c2 (cherry picked from commit 695123195034402ca76169b195069c28c30342d3) --- .../codecs/m4v_h263/dec/SoftMPEG4.cpp | 22 ++++++++++++++++++++-- .../codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp | 4 ++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index bb59ae4..e1cfc06 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -210,8 +210,17 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { PortInfo *port = editPortInfo(1); OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader; + OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size; + if ((outHeader->nAllocLen < yFrameSize) || + (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) { + ALOGE("Too small output buffer for reference frame: %zu bytes", + outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "30033990"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } PVSetReferenceYUV(mHandle, outHeader->pBuffer); - mFramesConfigured = true; } @@ -229,7 +238,16 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { int32_t bufferSize = inHeader->nFilledLen; int32_t tmp = bufferSize; - OMX_U32 frameSize = (mWidth * mHeight * 3) / 2; + OMX_U32 frameSize; + OMX_U64 yFrameSize = (OMX_U64)mWidth * (OMX_U64)mHeight; + if (yFrameSize > ((OMX_U64)UINT32_MAX / 3) * 2) { + ALOGE("Frame size too large"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } + frameSize = (OMX_U32)(yFrameSize + (yFrameSize / 2)); + if (outHeader->nAllocLen < frameSize) { android_errorWriteLog(0x534e4554, "27833616"); ALOGE("Insufficient output buffer size"); diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index 7638bb7..2eb51c9 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -116,6 +116,10 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() { ALOGE("Failed to get default encoding parameters"); return OMX_ErrorUndefined; } + if (mFramerate == 0) { + ALOGE("Framerate should not be 0"); + return OMX_ErrorUndefined; + } mEncParams->encMode = mEncodeMode; mEncParams->encWidth[0] = mWidth; mEncParams->encHeight[0] = mHeight; -- cgit v1.1 From dda9d703d7dd2129ff6242fae84ca156caa38632 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Tue, 16 Aug 2016 14:24:43 -0700 Subject: better validation lengths of strings in ID3 tags Validate lengths on strings in ID3 tags, particularly around 0. Also added code to handle cases when we can't get memory for copies of strings we want to extract from these tags. Affects L/M/N/master, same patch for all of them. Bug: 30744884 Change-Id: I2675a817a39f0927ec1f7e9f9c09f2e61020311e Test: play mp3 file which caused a <0 length. (cherry picked from commit d23c01546c4f82840a01a380def76ab6cae5d43f) --- media/libstagefright/id3/ID3.cpp | 57 +++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 4410579..6e14197 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -77,7 +77,10 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1) mFirstFrameOffset(0), mVersion(ID3_UNKNOWN), mRawSize(0) { - sp source = new MemorySource(data, size); + sp source = new (std::nothrow) MemorySource(data, size); + + if (source == NULL) + return; mIsValid = parseV2(source, 0); @@ -542,6 +545,10 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { n -= skipped; } + if (n <= 0) { + return; + } + if (encoding == 0x00) { // supposedly ISO 8859-1 id->setTo((const char*)frameData + 1, n); @@ -555,11 +562,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; #if BYTE_ORDER == LITTLE_ENDIAN - framedatacopy = new char16_t[len]; - for (int i = 0; i < len; i++) { - framedatacopy[i] = bswap_16(framedata[i]); + if (len > 0) { + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } + for (int i = 0; i < len; i++) { + framedatacopy[i] = bswap_16(framedata[i]); + } + framedata = framedatacopy; } - framedata = framedatacopy; #endif id->setTo(framedata, len); if (framedatacopy != NULL) { @@ -572,15 +584,26 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { const char16_t *framedata = (const char16_t *) (frameData + 1); char16_t *framedatacopy = NULL; if (*framedata == 0xfffe) { - // endianness marker doesn't match host endianness, convert - framedatacopy = new char16_t[len]; + // endianness marker != host endianness, convert & skip + if (len <= 1) { + return; // nothing after the marker + } + framedatacopy = new (std::nothrow) char16_t[len]; + if (framedatacopy == NULL) { + return; + } for (int i = 0; i < len; i++) { framedatacopy[i] = bswap_16(framedata[i]); } framedata = framedatacopy; - } - // If the string starts with an endianness marker, skip it - if (*framedata == 0xfeff) { + // and skip over the marker + framedata++; + len--; + } else if (*framedata == 0xfeff) { + // endianness marker == host endianness, skip it + if (len <= 1) { + return; // nothing after the marker + } framedata++; len--; } @@ -595,12 +618,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const { } if (eightBit) { // collapse to 8 bit, then let the media scanner client figure out the real encoding - char *frame8 = new char[len]; - for (int i = 0; i < len; i++) { - frame8[i] = framedata[i]; + char *frame8 = new (std::nothrow) char[len]; + if (frame8 != NULL) { + for (int i = 0; i < len; i++) { + frame8[i] = framedata[i]; + } + id->setTo(frame8, len); + delete [] frame8; + } else { + id->setTo(framedata, len); } - id->setTo(frame8, len); - delete [] frame8; } else { id->setTo(framedata, len); } -- cgit v1.1 From 4c086a8dc1d9c9772ac705d2a1509b311985e374 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 16 Aug 2016 16:50:54 -0700 Subject: MediaPlayerService: avoid invalid static cast Bug: 30204103 Change-Id: Ie0dd3568a375f1e9fed8615ad3d85184bcc99028 (cherry picked from commit ee0a0e39acdcf8f97e0d6945c31ff36a06a36e9d) --- media/libmediaplayerservice/MediaPlayerService.cpp | 10 ++++++++++ media/libmediaplayerservice/MediaPlayerService.h | 1 + 2 files changed, 11 insertions(+) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index b8c610d..0483228 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -559,6 +559,12 @@ void MediaPlayerService::removeClient(wp client) mClients.remove(client); } +bool MediaPlayerService::hasClient(wp client) +{ + Mutex::Autolock lock(mLock); + return mClients.indexOf(client) != NAME_NOT_FOUND; +} + MediaPlayerService::Client::Client( const sp& service, pid_t pid, int32_t connId, const sp& client, @@ -1056,6 +1062,10 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp& playe ALOGV("setNextPlayer"); Mutex::Autolock l(mLock); sp c = static_cast(player.get()); + if (!mService->hasClient(c)) { + return BAD_VALUE; + } + mNextClient = c; if (c != NULL) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 60d4617..e8e5360 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -226,6 +226,7 @@ public: virtual status_t dump(int fd, const Vector& args); void removeClient(wp client); + bool hasClient(wp client); // For battery usage tracking purpose struct BatteryUsageInfo { -- cgit v1.1 From b6af3b9bc072c4d832db9dc93ff818472cd50069 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 17 Aug 2016 06:19:32 -0700 Subject: soundtrigger: add size check on sound model and recogntion data Bug: 30148546 Change-Id: I082f535a853c96571887eeea37c6d41ecee7d8c0 (cherry picked from commit bb00d8f139ff51336ab3c810d35685003949bcf8) (cherry picked from commit ef0c91518446e65533ca8bab6726a845f27c73fd) --- services/soundtrigger/SoundTriggerHwService.cpp | 38 +++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index 9de6fe2..e428388 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -534,6 +534,22 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp& modelM struct sound_trigger_sound_model *sound_model = (struct sound_trigger_sound_model *)modelMemory->pointer(); + size_t structSize; + if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) { + structSize = sizeof(struct sound_trigger_phrase_sound_model); + } else { + structSize = sizeof(struct sound_trigger_sound_model); + } + + if (sound_model->data_offset < structSize || + sound_model->data_size > (UINT_MAX - sound_model->data_offset) || + modelMemory->size() < sound_model->data_offset || + sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) { + android_errorWriteLog(0x534e4554, "30148546"); + ALOGE("loadSoundModel() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mModels.size() >= mDescriptor.properties.max_sound_models) { @@ -603,11 +619,23 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha return PERMISSION_DENIED; } - if (dataMemory != 0 && dataMemory->pointer() == NULL) { - ALOGE("startRecognition() dataMemory is non-0 but has NULL pointer()"); + if (dataMemory == 0 || dataMemory->pointer() == NULL) { + ALOGE("startRecognition() dataMemory is 0 or has NULL pointer()"); return BAD_VALUE; } + + struct sound_trigger_recognition_config *config = + (struct sound_trigger_recognition_config *)dataMemory->pointer(); + + if (config->data_offset < sizeof(struct sound_trigger_recognition_config) || + config->data_size > (UINT_MAX - config->data_offset) || + dataMemory->size() < config->data_offset || + config->data_size > (dataMemory->size() - config->data_offset)) { + ALOGE("startRecognition() data_size is too big"); + return BAD_VALUE; + } + AutoMutex lock(mLock); if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) { return INVALID_OPERATION; @@ -616,17 +644,11 @@ status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t ha if (model == 0) { return BAD_VALUE; } - if ((dataMemory == 0) || - (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) { - return BAD_VALUE; - } if (model->mState == Model::STATE_ACTIVE) { return INVALID_OPERATION; } - struct sound_trigger_recognition_config *config = - (struct sound_trigger_recognition_config *)dataMemory->pointer(); //TODO: get capture handle and device from audio policy service config->capture_handle = model->mCaptureIOHandle; -- cgit v1.1 From 089104004f5aeb2634764c56b948ef83318a9f95 Mon Sep 17 00:00:00 2001 From: Pawin Vongmasa Date: Fri, 19 Aug 2016 02:07:33 -0700 Subject: Fix build breakage caused by commit 940829f69b52d6038db66a9c727534636ecc456d. Change-Id: I4776db4a26fb3c31bb994d48788373fe569c812a (cherry picked from commit baa9146401e28c5acf54dea21ddd197f0d3a8fcd) --- media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index e1cfc06..1dd631a 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -213,8 +213,8 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { OMX_U32 yFrameSize = sizeof(uint8) * mHandle->size; if ((outHeader->nAllocLen < yFrameSize) || (outHeader->nAllocLen - yFrameSize < yFrameSize / 2)) { - ALOGE("Too small output buffer for reference frame: %zu bytes", - outHeader->nAllocLen); + ALOGE("Too small output buffer for reference frame: %lu bytes", + (unsigned long)outHeader->nAllocLen); android_errorWriteLog(0x534e4554, "30033990"); notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); mSignalledError = true; -- cgit v1.1 From bdb54da9baf8349a1f030064c3af4ff7318f4771 Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Tue, 30 Aug 2016 11:41:42 +0100 Subject: libstagefright: mtk: Use vendor extensions to check if we should fixup cropping For mediatek video codecs, validate that the current cropped rectangle is valid and use the full frame size otherwise. This fixes a bug where format changes in the same native window would preserve the previous cropping and cause most of the image to be off-screen. Change-Id: If56ca11453f5d2e04a4138b2efe28203f30ba569 Ticket: PORRIDGE-440 --- media/libstagefright/ACodec.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 427728f..e00e673 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -4209,6 +4209,16 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { rect.nWidth = videoDef->nFrameWidth; rect.nHeight = videoDef->nFrameHeight; } +#ifdef MTK_HARDWARE + if (!strncmp(mComponentName.c_str(), "OMX.MTK.", 8) && mOMX->getConfig( + mNode, (OMX_INDEXTYPE) 0x7f00001c /* OMX_IndexVendorMtkOmxVdecGetCropInfo */, + &rect, sizeof(rect)) != OK) { + rect.nLeft = 0; + rect.nTop = 0; + rect.nWidth = videoDef->nFrameWidth; + rect.nHeight = videoDef->nFrameHeight; + } +#endif if (rect.nLeft < 0 || rect.nTop < 0 || -- cgit v1.1 From f42ee8bd0cb51c571dd6dfcf71c61dce377768cd Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Tue, 30 Aug 2016 13:49:06 -0700 Subject: MediaPlayerService: allow next player to be NULL Bug: 31155917 Bug: 30204103 Change-Id: I9a2a59ddb900fc942e7c19b31b53a110d790474c (cherry picked from commit 282841278723166e74039329ca56e444ad472daf) --- media/libmediaplayerservice/MediaPlayerService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 0483228..f802de1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1062,7 +1062,7 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp& playe ALOGV("setNextPlayer"); Mutex::Autolock l(mLock); sp c = static_cast(player.get()); - if (!mService->hasClient(c)) { + if (c != NULL && !mService->hasClient(c)) { return BAD_VALUE; } -- cgit v1.1 From 4b459da1ee3bb52ddfcc649dc2686975a9d72ab7 Mon Sep 17 00:00:00 2001 From: Wei Jia Date: Tue, 30 Aug 2016 13:49:06 -0700 Subject: MediaPlayerService: allow next player to be NULL Bug: 31155917 Bug: 30204103 Change-Id: I9a2a59ddb900fc942e7c19b31b53a110d790474c (cherry picked from commit 282841278723166e74039329ca56e444ad472daf) --- media/libmediaplayerservice/MediaPlayerService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 0483228..f802de1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1062,7 +1062,7 @@ status_t MediaPlayerService::Client::setNextPlayer(const sp& playe ALOGV("setNextPlayer"); Mutex::Autolock l(mLock); sp c = static_cast(player.get()); - if (!mService->hasClient(c)) { + if (c != NULL && !mService->hasClient(c)) { return BAD_VALUE; } -- cgit v1.1 From 3f6bb688b22b184b0bfc2739cda3c3cf0dd06a14 Mon Sep 17 00:00:00 2001 From: irii Date: Sun, 11 Sep 2016 16:51:37 +0200 Subject: libcameraservice: Don't pass NULL args on setCallbacks call *This fixes the torch light for cameras with hal 1 *This fix works on the htc m7ul *Fixed line length *Fixed unused parameter names Change-Id: I89c6112546e36dbcca099f4d5cd70371b2c5340a --- services/camera/libcameraservice/CameraFlashlight.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp index 406c1c4..62ce610 100644 --- a/services/camera/libcameraservice/CameraFlashlight.cpp +++ b/services/camera/libcameraservice/CameraFlashlight.cpp @@ -828,6 +828,18 @@ status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow( return device->setPreviewWindow(mSurface); } +static void notifyCallback(int32_t, int32_t, int32_t, void*) { + /* Empty */ +} + +static void dataCallback(int32_t, const sp&, camera_frame_metadata_t*, void*) { + /* Empty */ +} + +static void dataCallbackTimestamp(nsecs_t, int32_t, const sp&, void*) { + /* Empty */ +} + status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( const String8& cameraId) { sp device = @@ -841,7 +853,7 @@ status_t CameraHardwareInterfaceFlashControl::connectCameraDevice( } // need to set __get_memory in set_callbacks(). - device->setCallbacks(NULL, NULL, NULL, NULL); + device->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, this); mParameters = device->getParameters(); -- cgit v1.1 From bc8a45f506a8be33250c523d71fab637a5fdaf81 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Tue, 2 Aug 2016 07:07:05 -0700 Subject: IOMX: work against metadata buffer spoofing - Prohibit direct set/getParam/Settings for extensions meant for OMXNodeInstance alone. This disallows enabling metadata mode without the knowledge of OMXNodeInstance. - Do not share metadata mode buffers cross process. - Disallow setting up metadata mode/tunneling/input surface after first sendCommand. - Disallow store-meta for input cross process. - Disallow emptyBuffer for surface input (via IOMX). - Fix checking for input surface. Bug: 29422020 Change-Id: I801c77b80e703903f62e42d76fd2e76a34e4bc8e (cherry picked from commit f8a4cb410115045278f534e54b41ac78d6bf6c07) --- include/media/IOMX.h | 4 +- media/libmedia/IOMX.cpp | 14 +- media/libstagefright/OMXClient.cpp | 13 +- media/libstagefright/include/OMX.h | 4 +- media/libstagefright/include/OMXNodeInstance.h | 10 +- media/libstagefright/omx/OMX.cpp | 8 +- media/libstagefright/omx/OMXNodeInstance.cpp | 184 ++++++++++++++++++++++--- 7 files changed, 196 insertions(+), 41 deletions(-) diff --git a/include/media/IOMX.h b/include/media/IOMX.h index 27ad694..83a177a 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -107,7 +107,7 @@ public: // Use |params| as an OMX buffer, but limit the size of the OMX buffer to |allottedSize|. virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) = 0; + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess = OMX_FALSE) = 0; virtual status_t useGraphicBuffer( node_id node, OMX_U32 port_index, @@ -149,7 +149,7 @@ public: // may be larger. virtual status_t allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) = 0; + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess = OMX_FALSE) = 0; virtual status_t freeBuffer( node_id node, OMX_U32 port_index, buffer_id buffer) = 0; diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index b082fe4..c28eac8 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -248,7 +248,7 @@ public: virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp ¶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); @@ -481,7 +481,7 @@ public: virtual status_t allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶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); @@ -834,7 +834,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) { @@ -969,7 +970,10 @@ status_t BnOMX::onTransact( OMX_BOOL enable = (OMX_BOOL)data.readInt32(); MetadataBufferType type = kMetadataBufferTypeInvalid; - status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); + 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); @@ -1054,7 +1058,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/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp index e69890d..d252cb6 100644 --- a/media/libstagefright/OMXClient.cpp +++ b/media/libstagefright/OMXClient.cpp @@ -90,7 +90,7 @@ struct MuxOMX : public IOMX { virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize); + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); virtual status_t useGraphicBuffer( node_id node, OMX_U32 port_index, @@ -120,7 +120,7 @@ struct MuxOMX : public IOMX { virtual status_t allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize); + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); virtual status_t freeBuffer( node_id node, OMX_U32 port_index, buffer_id buffer); @@ -322,8 +322,9 @@ status_t MuxOMX::getGraphicBufferUsage( status_t MuxOMX::useBuffer( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { - return getOMX(node)->useBuffer(node, port_index, params, buffer, allottedSize); + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) { + return getOMX(node)->useBuffer( + node, port_index, params, buffer, allottedSize, OMX_FALSE /* crossProcess */); } status_t MuxOMX::useGraphicBuffer( @@ -375,9 +376,9 @@ status_t MuxOMX::allocateBuffer( status_t MuxOMX::allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL /* crossProcess */) { return getOMX(node)->allocateBufferWithBackup( - node, port_index, params, buffer, allottedSize); + node, port_index, params, buffer, allottedSize, OMX_FALSE /* crossProcess */); } status_t MuxOMX::freeBuffer( diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index e7c4f6d..b20b2ea 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -81,7 +81,7 @@ public: virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize); + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); virtual status_t useGraphicBuffer( node_id node, OMX_U32 port_index, @@ -113,7 +113,7 @@ public: virtual status_t allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize); + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); virtual status_t freeBuffer( node_id node, OMX_U32 port_index, buffer_id buffer); diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index babf5b7..bd33ab7 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -21,6 +21,7 @@ #include "OMX.h" #include +#include #include namespace android { @@ -71,7 +72,7 @@ struct OMXNodeInstance { status_t useBuffer( OMX_U32 portIndex, const sp ¶ms, - OMX::buffer_id *buffer, OMX_U32 allottedSize); + OMX::buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); status_t useGraphicBuffer( OMX_U32 portIndex, const sp &graphicBuffer, @@ -101,7 +102,7 @@ struct OMXNodeInstance { status_t allocateBufferWithBackup( OMX_U32 portIndex, const sp ¶ms, - OMX::buffer_id *buffer, OMX_U32 allottedSize); + OMX::buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess); status_t freeBuffer(OMX_U32 portIndex, OMX::buffer_id buffer); @@ -146,6 +147,9 @@ private: OMX_HANDLETYPE mHandle; sp mObserver; bool mDying; + bool mSailed; // configuration is set (no more meta-mode changes) + bool mQueriedProhibitedExtensions; + SortedVector mProhibitedExtensions; bool mIsSecure; // Lock only covers mGraphicBufferSource. We can't always use mLock @@ -191,6 +195,8 @@ private: OMX::buffer_id findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader); void invalidateBufferID(OMX::buffer_id buffer); + bool isProhibitedIndex_l(OMX_INDEXTYPE index); + status_t useGraphicBuffer2_l( OMX_U32 portIndex, const sp &graphicBuffer, OMX::buffer_id *buffer); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 56b6055..5898b4e 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -368,9 +368,9 @@ status_t OMX::configureVideoTunnelMode( status_t OMX::useBuffer( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess) { return findInstance(node)->useBuffer( - port_index, params, buffer, allottedSize); + port_index, params, buffer, allottedSize, crossProcess); } status_t OMX::useGraphicBuffer( @@ -421,9 +421,9 @@ status_t OMX::allocateBuffer( status_t OMX::allocateBufferWithBackup( node_id node, OMX_U32 port_index, const sp ¶ms, - buffer_id *buffer, OMX_U32 allottedSize) { + buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess) { return findInstance(node)->allocateBufferWithBackup( - port_index, params, buffer, allottedSize); + port_index, params, buffer, allottedSize, crossProcess); } status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) { diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 7f534b5..a0dc2ec 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -101,26 +101,34 @@ static void InitOMXParams(T *params) { namespace android { struct BufferMeta { - BufferMeta(const sp &mem, OMX_U32 portIndex, bool is_backup = false) + BufferMeta( + const sp &mem, OMX_U32 portIndex, bool copyToOmx, + bool copyFromOmx, OMX_U8 *backup) : mMem(mem), - mIsBackup(is_backup), - mPortIndex(portIndex) { + mCopyFromOmx(copyFromOmx), + mCopyToOmx(copyToOmx), + mPortIndex(portIndex), + mBackup(backup) { } BufferMeta(size_t size, OMX_U32 portIndex) : mSize(size), - mIsBackup(false), - mPortIndex(portIndex) { + mCopyFromOmx(false), + mCopyToOmx(false), + mPortIndex(portIndex), + mBackup(NULL) { } BufferMeta(const sp &graphicBuffer, OMX_U32 portIndex) : mGraphicBuffer(graphicBuffer), - mIsBackup(false), - mPortIndex(portIndex) { + mCopyFromOmx(false), + mCopyToOmx(false), + mPortIndex(portIndex), + mBackup(NULL) { } void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) { - if (!mIsBackup) { + if (!mCopyFromOmx) { return; } @@ -131,7 +139,7 @@ struct BufferMeta { } void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { - if (!mIsBackup) { + if (!mCopyToOmx) { return; } @@ -167,12 +175,18 @@ struct BufferMeta { return mPortIndex; } + ~BufferMeta() { + delete[] mBackup; + } + private: sp mGraphicBuffer; sp mMem; size_t mSize; - bool mIsBackup; + bool mCopyFromOmx; + bool mCopyToOmx; OMX_U32 mPortIndex; + OMX_U8 *mBackup; BufferMeta(const BufferMeta &); BufferMeta &operator=(const BufferMeta &); @@ -199,6 +213,8 @@ OMXNodeInstance::OMXNodeInstance( mHandle(NULL), mObserver(observer), mDying(false), + mSailed(false), + mQueriedProhibitedExtensions(false), mBufferIDCount(0) { mName = ADebug::GetDebugName(name); @@ -370,7 +386,12 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { status_t OMXNodeInstance::sendCommand( OMX_COMMANDTYPE cmd, OMX_S32 param) { - const sp& bufferSource(getGraphicBufferSource()); + if (cmd == OMX_CommandStateSet) { + // We do not support returning from unloaded state, so there are no configurations past + // first StateSet command. + mSailed = true; + } + const sp bufferSource(getGraphicBufferSource()); if (bufferSource != NULL && cmd == OMX_CommandStateSet) { if (param == OMX_StateIdle) { // Initiating transition from Executing -> Idle @@ -403,10 +424,57 @@ status_t OMXNodeInstance::sendCommand( return StatusFromOMXError(err); } +bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) { + // these extensions can only be used from OMXNodeInstance, not by clients directly. + static const char *restricted_extensions[] = { + "OMX.google.android.index.storeMetaDataInBuffers", + "OMX.google.android.index.storeANWBufferInMetadata", + "OMX.google.android.index.prepareForAdaptivePlayback", + "OMX.google.android.index.configureVideoTunnelMode", + "OMX.google.android.index.useAndroidNativeBuffer2", + "OMX.google.android.index.useAndroidNativeBuffer", + "OMX.google.android.index.enableAndroidNativeBuffers", + "OMX.google.android.index.allocateNativeHandle", + "OMX.google.android.index.getAndroidNativeBufferUsage", + }; + + if ((index > OMX_IndexComponentStartUnused && index <= OMX_IndexParamStandardComponentRole) + || (index > OMX_IndexPortStartUnused && index <= OMX_IndexParamCompBufferSupplier) + || (index > OMX_IndexAudioStartUnused && index <= OMX_IndexConfigAudioChannelVolume) + || (index > OMX_IndexVideoStartUnused && index <= OMX_IndexConfigVideoNalSize) + || (index > OMX_IndexCommonStartUnused + && index <= OMX_IndexConfigCommonTransitionEffect) + || (index > (OMX_INDEXTYPE)OMX_IndexExtAudioStartUnused + && index <= (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3) + || (index > (OMX_INDEXTYPE)OMX_IndexExtVideoStartUnused + && index <= (OMX_INDEXTYPE)OMX_IndexParamSliceSegments) + || (index > (OMX_INDEXTYPE)OMX_IndexExtOtherStartUnused + && index <= (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits)) { + return false; + } + + if (!mQueriedProhibitedExtensions) { + for (size_t i = 0; i < NELEM(restricted_extensions); ++i) { + OMX_INDEXTYPE ext; + if (OMX_GetExtensionIndex(mHandle, (OMX_STRING)restricted_extensions[i], &ext) == OMX_ErrorNone) { + mProhibitedExtensions.add(ext); + } + } + mQueriedProhibitedExtensions = true; + } + + return mProhibitedExtensions.indexOf(index) >= 0; +} + status_t OMXNodeInstance::getParameter( OMX_INDEXTYPE index, void *params, size_t /* size */) { Mutex::Autolock autoLock(mLock); + if (isProhibitedIndex_l(index)) { + android_errorWriteLog(0x534e4554, "29422020"); + return BAD_INDEX; + } + OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; // some errors are expected for getParameter @@ -422,6 +490,11 @@ status_t OMXNodeInstance::setParameter( OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); + if (isProhibitedIndex_l(index)) { + android_errorWriteLog(0x534e4554, "29422020"); + return BAD_INDEX; + } + OMX_ERRORTYPE err = OMX_SetParameter( mHandle, index, const_cast(params)); CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index); @@ -432,6 +505,11 @@ status_t OMXNodeInstance::getConfig( OMX_INDEXTYPE index, void *params, size_t /* size */) { Mutex::Autolock autoLock(mLock); + if (isProhibitedIndex_l(index)) { + android_errorWriteLog(0x534e4554, "29422020"); + return BAD_INDEX; + } + OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params); OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; // some errors are expected for getConfig @@ -447,6 +525,11 @@ status_t OMXNodeInstance::setConfig( OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); + if (isProhibitedIndex_l(index)) { + android_errorWriteLog(0x534e4554, "29422020"); + return BAD_INDEX; + } + OMX_ERRORTYPE err = OMX_SetConfig( mHandle, index, const_cast(params)); CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index); @@ -526,6 +609,10 @@ status_t OMXNodeInstance::storeMetaDataInBuffers( status_t OMXNodeInstance::storeMetaDataInBuffers_l( OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) { + if (mSailed) { + android_errorWriteLog(0x534e4554, "29422020"); + return INVALID_OPERATION; + } if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { android_errorWriteLog(0x534e4554, "26324358"); return BAD_VALUE; @@ -593,6 +680,10 @@ status_t OMXNodeInstance::prepareForAdaptivePlayback( OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { Mutex::Autolock autolock(mLock); + if (mSailed) { + android_errorWriteLog(0x534e4554, "29422020"); + return INVALID_OPERATION; + } CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u", portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); @@ -623,6 +714,10 @@ status_t OMXNodeInstance::configureVideoTunnelMode( OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { Mutex::Autolock autolock(mLock); + if (mSailed) { + android_errorWriteLog(0x534e4554, "29422020"); + return INVALID_OPERATION; + } CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u", portString(portIndex), portIndex, tunneled, audioHwSync); @@ -663,23 +758,48 @@ status_t OMXNodeInstance::configureVideoTunnelMode( status_t OMXNodeInstance::useBuffer( OMX_U32 portIndex, const sp ¶ms, - OMX::buffer_id *buffer, OMX_U32 allottedSize) { + OMX::buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess) { Mutex::Autolock autoLock(mLock); - if (allottedSize > params->size()) { + if (allottedSize > params->size() || portIndex >= NELEM(mNumPortBuffers)) { return BAD_VALUE; } - BufferMeta *buffer_meta = new BufferMeta(params, portIndex); + // metadata buffers are not connected cross process + BufferMeta *buffer_meta; + bool isMeta = mMetadataType[portIndex] != kMetadataBufferTypeInvalid; + bool useBackup = crossProcess && isMeta; // use a backup buffer instead of the actual buffer + OMX_U8 *data = static_cast(params->pointer()); + // allocate backup buffer + if (useBackup) { + data = new (std::nothrow) OMX_U8[allottedSize]; + if (data == NULL) { + return NO_MEMORY; + } + memset(data, 0, allottedSize); + + // if we are not connecting the buffers, the sizes must match + if (allottedSize != params->size()) { + CLOG_ERROR(useBuffer, BAD_VALUE, SIMPLE_BUFFER(portIndex, (size_t)allottedSize, data)); + delete[] data; + return BAD_VALUE; + } + + buffer_meta = new BufferMeta( + params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, data); + } else { + buffer_meta = new BufferMeta( + params, portIndex, false /* copyFromOmx */, false /* copyToOmx */, NULL); + } OMX_BUFFERHEADERTYPE *header; OMX_ERRORTYPE err = OMX_UseBuffer( mHandle, &header, portIndex, buffer_meta, - allottedSize, static_cast(params->pointer())); + allottedSize, data); if (err != OMX_ErrorNone) { CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER( - portIndex, (size_t)allottedSize, params->pointer())); + portIndex, (size_t)allottedSize, data)); delete buffer_meta; buffer_meta = NULL; @@ -864,7 +984,16 @@ status_t OMXNodeInstance::createGraphicBufferSource( OMX_U32 portIndex, sp bufferConsumer, MetadataBufferType *type) { status_t err; - const sp& surfaceCheck = getGraphicBufferSource(); + // only allow graphic source on input port, when there are no allocated buffers yet + if (portIndex != kPortIndexInput) { + android_errorWriteLog(0x534e4554, "29422020"); + return BAD_VALUE; + } else if (mNumPortBuffers[portIndex] > 0) { + android_errorWriteLog(0x534e4554, "29422020"); + return INVALID_OPERATION; + } + + const sp surfaceCheck = getGraphicBufferSource(); if (surfaceCheck != NULL) { if (portIndex < NELEM(mMetadataType) && type != NULL) { *type = mMetadataType[portIndex]; @@ -1020,13 +1149,21 @@ status_t OMXNodeInstance::allocateBuffer( status_t OMXNodeInstance::allocateBufferWithBackup( OMX_U32 portIndex, const sp ¶ms, - OMX::buffer_id *buffer, OMX_U32 allottedSize) { + OMX::buffer_id *buffer, OMX_U32 allottedSize, OMX_BOOL crossProcess) { Mutex::Autolock autoLock(mLock); - if (allottedSize > params->size()) { + if (allottedSize > params->size() || portIndex >= NELEM(mNumPortBuffers)) { return BAD_VALUE; } - BufferMeta *buffer_meta = new BufferMeta(params, portIndex, true); + // metadata buffers are not connected cross process + bool isMeta = mMetadataType[portIndex] != kMetadataBufferTypeInvalid; + bool copy = !(crossProcess && isMeta); + + BufferMeta *buffer_meta = new BufferMeta( + params, portIndex, + (portIndex == kPortIndexInput) && copy /* copyToOmx */, + (portIndex == kPortIndexOutput) && copy /* copyFromOmx */, + NULL /* data */); OMX_BUFFERHEADERTYPE *header; @@ -1044,6 +1181,7 @@ status_t OMXNodeInstance::allocateBufferWithBackup( } CHECK_EQ(header->pAppPrivate, buffer_meta); + memset(header->pBuffer, 0, header->nAllocLen); *buffer = makeBufferID(header); @@ -1122,6 +1260,12 @@ status_t OMXNodeInstance::emptyBuffer( OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { Mutex::Autolock autoLock(mLock); + // no emptybuffer if using input surface + if (getGraphicBufferSource() != NULL) { + android_errorWriteLog(0x534e4554, "29422020"); + return INVALID_OPERATION; + } + OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput); if (header == NULL) { return BAD_VALUE; -- cgit v1.1 From 23ffe421812180b20043b8a108a72b2e95ef1f0c Mon Sep 17 00:00:00 2001 From: rago Date: Mon, 22 Aug 2016 17:20:26 -0700 Subject: Fix potential overflow in Visualizer effect Bug: 30229821 Change-Id: Idd3c1563dc9d3261e6e168e945005bf133ab2cdb (cherry picked from commit 099ab280775946e7c36c73fde47f2ee5a2579f53) (cherry picked from commit 46dc714d523a41a4f886eecbe5b9947a4c900510) --- media/libeffects/visualizer/EffectVisualizer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index 0c310c5..91f9fc7 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -25,6 +25,7 @@ #include #include #include +#include extern "C" { @@ -599,6 +600,14 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, } break; case VISUALIZER_CMD_MEASURE: { + if (pReplyData == NULL || replySize == NULL || + *replySize < (sizeof(int32_t) * MEASUREMENT_COUNT)) { + ALOGV("VISUALIZER_CMD_MEASURE() error *replySize %" PRIu32 + " < (sizeof(int32_t) * MEASUREMENT_COUNT) %" PRIu32, *replySize, + sizeof(int32_t) * MEASUREMENT_COUNT); + android_errorWriteLog(0x534e4554, "30229821"); + return -EINVAL; + } uint16_t peakU16 = 0; float sumRmsSquared = 0.0f; uint8_t nbValidMeasurements = 0; -- cgit v1.1 From ace612c5f838944d1b88be18e317709e640becc2 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Fri, 2 Sep 2016 11:36:46 -0700 Subject: Fix stack content leak vulnerability in mediaserver bug: 30875060 Change-Id: I03f4d08b7b31ac5b507cfc9e65e5607c73972d95 (cherry picked from commit 9a6861cbd3bb0e1b8fe4c105795256ee032f9664) --- media/libmedia/IDrm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index 7c709cd..6f6530b 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -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); -- cgit v1.1 From d8cf9aa813be5363fb5425b4f818a267edd5e750 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 7 Sep 2016 16:58:39 -0700 Subject: SoundTrigger: get service by value. Get strong pointer to service interface by value and not reference to prevent race conditions where the service pointer can be cleared by another thread while in use. Bug: 30907212 Change-Id: I6f02ec3fd1e6392b842b334e1cc4f9aa23916009 (cherry picked from commit 3b01b3019b1c62132792a1a94e2dc1f7cfc84f2e) --- include/soundtrigger/SoundTrigger.h | 2 +- soundtrigger/SoundTrigger.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/soundtrigger/SoundTrigger.h b/include/soundtrigger/SoundTrigger.h index bf5e1de..9a05cac 100644 --- a/include/soundtrigger/SoundTrigger.h +++ b/include/soundtrigger/SoundTrigger.h @@ -68,7 +68,7 @@ public: private: SoundTrigger(sound_trigger_module_handle_t module, const sp&); - static const sp& getSoundTriggerHwService(); + static const sp getSoundTriggerHwService(); Mutex mLock; sp mISoundTrigger; diff --git a/soundtrigger/SoundTrigger.cpp b/soundtrigger/SoundTrigger.cpp index 2138cb7..e959b83 100644 --- a/soundtrigger/SoundTrigger.cpp +++ b/soundtrigger/SoundTrigger.cpp @@ -55,7 +55,7 @@ namespace { sp gDeathNotifier; }; // namespace anonymous -const sp& SoundTrigger::getSoundTriggerHwService() +const sp SoundTrigger::getSoundTriggerHwService() { Mutex::Autolock _l(gLock); if (gSoundTriggerHwService.get() == 0) { @@ -84,7 +84,7 @@ status_t SoundTrigger::listModules(struct sound_trigger_module_descriptor *modul uint32_t *numModules) { ALOGV("listModules()"); - const sp& service = getSoundTriggerHwService(); + const sp service = getSoundTriggerHwService(); if (service == 0) { return NO_INIT; } @@ -96,7 +96,7 @@ sp SoundTrigger::attach(const sound_trigger_module_handle_t module { ALOGV("attach()"); sp soundTrigger; - const sp& service = getSoundTriggerHwService(); + const sp service = getSoundTriggerHwService(); if (service == 0) { return soundTrigger; } @@ -116,7 +116,7 @@ sp SoundTrigger::attach(const sound_trigger_module_handle_t module status_t SoundTrigger::setCaptureState(bool active) { ALOGV("setCaptureState(%d)", active); - const sp& service = getSoundTriggerHwService(); + const sp service = getSoundTriggerHwService(); if (service == 0) { return NO_INIT; } -- cgit v1.1 From 128035617a8cafd4ea717ceb8d6fe56564b07262 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 7 Sep 2016 16:58:39 -0700 Subject: Radio: get service by value. Get strong pointer to service interface by value and not reference to prevent race conditions where the service pointer can be cleared by another thread while in use. Bug: 30907212 Change-Id: Iae838b3b672562c1d0cd63968399a6bfdda7f5ab (cherry picked from commit 28a0e9ec74e5192aacffb279c80619ef284062b0) --- include/radio/Radio.h | 2 +- radio/Radio.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/radio/Radio.h b/include/radio/Radio.h index 302bf16..a4dfdd1 100644 --- a/include/radio/Radio.h +++ b/include/radio/Radio.h @@ -75,7 +75,7 @@ public: private: Radio(radio_handle_t handle, const sp&); - static const sp& getRadioService(); + static const sp getRadioService(); Mutex mLock; sp mIRadio; diff --git a/radio/Radio.cpp b/radio/Radio.cpp index e3554c2..3c04fb0 100644 --- a/radio/Radio.cpp +++ b/radio/Radio.cpp @@ -55,7 +55,7 @@ namespace { sp gDeathNotifier; }; // namespace anonymous -const sp& Radio::getRadioService() +const sp Radio::getRadioService() { Mutex::Autolock _l(gLock); if (gRadioService.get() == 0) { @@ -84,7 +84,7 @@ status_t Radio::listModules(struct radio_properties *properties, uint32_t *numModules) { ALOGV("listModules()"); - const sp& service = getRadioService(); + const sp service = getRadioService(); if (service == 0) { return NO_INIT; } @@ -98,7 +98,7 @@ sp Radio::attach(radio_handle_t handle, { ALOGV("attach()"); sp radio; - const sp& service = getRadioService(); + const sp service = getRadioService(); if (service == 0) { return radio; } -- cgit v1.1 From c2dd82bfd6d7aea5b6760efc0712ae11d7a52e6b Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 20 Sep 2016 13:36:40 -0700 Subject: Check mprotect result mprotect can theoretically fail, which could then let one exploit a vulnerable codec if one exists on the device. Bug: 31350239 Change-Id: I7b99c190619f0fb2eb93119596e6da0d2deb8ba5 (cherry picked from commit 866c800c0624bb13eee44973cc8a2ecd0012de6e) --- media/libmedia/IOMX.cpp | 52 ++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index c28eac8..365d9ac 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -733,31 +733,35 @@ status_t BnOMX::onTransact( // 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 - mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE); - 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; + 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(); } - - default: - TRESPASS(); } } } -- cgit v1.1 From 2af81c25f462ba958507bfe6ba43200e3c2e2a0e Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 20 Sep 2016 17:37:55 -0700 Subject: SampleIterator: clear members on seekTo error Bug: 31091777 Change-Id: Iddf99d0011961d0fd3d755e57db4365b6a6a1193 (cherry picked from commit 03237ce0f9584c98ccda76c2474a4ae84c763f5b) --- media/libstagefright/SampleIterator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp index c5f359e..335bd5d 100644 --- a/media/libstagefright/SampleIterator.cpp +++ b/media/libstagefright/SampleIterator.cpp @@ -94,8 +94,6 @@ status_t SampleIterator::seekTo(uint32_t sampleIndex) { + mFirstChunk; if (!mInitialized || chunk != mCurrentChunkIndex) { - mCurrentChunkIndex = chunk; - status_t err; if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) { ALOGE("getChunkOffset return error"); @@ -106,18 +104,21 @@ status_t SampleIterator::seekTo(uint32_t sampleIndex) { uint32_t firstChunkSampleIndex = mFirstChunkSampleIndex - + mSamplesPerChunk * (mCurrentChunkIndex - mFirstChunk); + + mSamplesPerChunk * (chunk - mFirstChunk); for (uint32_t i = 0; i < mSamplesPerChunk; ++i) { size_t sampleSize; if ((err = getSampleSizeDirect( firstChunkSampleIndex + i, &sampleSize)) != OK) { ALOGE("getSampleSizeDirect return error"); + mCurrentChunkSampleSizes.clear(); return err; } mCurrentChunkSampleSizes.push(sampleSize); } + + mCurrentChunkIndex = chunk; } uint32_t chunkRelativeSampleIndex = -- cgit v1.1 From b5203aba00dc60bee526d78e5851f0a34c4b5bd7 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Mon, 19 Sep 2016 16:22:56 -0700 Subject: Limit mp4 atom size to something reasonable Bug: 28615448 Change-Id: I5916f6839b4a9bbee4388a106e7373bcd4154f5a (cherry picked from commit cb898dca47ac03738db91ddc371207435d2a1526) --- media/libstagefright/MPEG4Extractor.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 4c10cc9..9e7f298 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -50,6 +50,12 @@ namespace android { +enum { + // maximum size of an atom. Some atoms can be bigger according to the spec, + // but we only allow up to this size. + kMaxAtomSize = 64 * 1024 * 1024, +}; + class MPEG4Source : public MediaSource { public: // Caller retains ownership of both "dataSource" and "sampleTable". @@ -836,6 +842,13 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { PathAdder autoAdder(&mPath, chunk_type); off64_t chunk_data_size = *offset + chunk_size - data_offset; + if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) { + char errMsg[100]; + sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size); + ALOGE("%s (b/28615448)", errMsg); + android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg)); + return ERROR_MALFORMED; + } if (chunk_type != FOURCC('c', 'p', 'r', 't') && chunk_type != FOURCC('c', 'o', 'v', 'r') -- cgit v1.1 From b1463a7e50d22414c62cb9872ef9078f5a962923 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Mon, 12 Sep 2016 14:40:47 -0700 Subject: IOMX: restrict conversion of ANWB to gralloc source in emptyBuffer This is only allowed in-process (if backup and codec buffers are connected.) Bug: 29422020 Bug: 31412859 Change-Id: If48e3e0b6f1af99a459fdc3f6f03744bbf0dc375 (cherry picked from commit 087ff38490016f4a0b6a1e717ae8af781d9b750c) --- media/libstagefright/omx/OMXNodeInstance.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index a0dc2ec..13b7cbb 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -167,6 +167,10 @@ struct BufferMeta { return buf; } + bool copyToOmx() const { + return mCopyToOmx; + } + void setGraphicBuffer(const sp &graphicBuffer) { mGraphicBuffer = graphicBuffer; } @@ -788,7 +792,7 @@ status_t OMXNodeInstance::useBuffer( params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, data); } else { buffer_meta = new BufferMeta( - params, portIndex, false /* copyFromOmx */, false /* copyToOmx */, NULL); + params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, NULL); } OMX_BUFFERHEADERTYPE *header; @@ -1277,7 +1281,8 @@ status_t OMXNodeInstance::emptyBuffer( // convert incoming ANW meta buffers if component is configured for gralloc metadata mode // ignore rangeOffset in this case - if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource + if (buffer_meta->copyToOmx() + && mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource && backup->capacity() >= sizeof(VideoNativeMetadata) && codec->capacity() >= sizeof(VideoGrallocMetadata) && ((VideoNativeMetadata *)backup->base())->eType -- cgit v1.1 From 8cbd1c5cb14e771982965a530b34282effc39b8c Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 14 Sep 2016 10:01:37 -0700 Subject: IOMX: allow configuration after going to loaded state This was disallowed recently but we still use it as MediaCodcec.stop only goes to loaded state, and does not free component. Bug: 31450460 Change-Id: I72e092e4e55c9f23b1baee3e950d76e84a5ef28d (cherry picked from commit e03b22839d78c841ce0a1a0a1ee1960932188b0b) --- media/libstagefright/omx/OMXNodeInstance.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 13b7cbb..b86611f 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -391,8 +391,7 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { status_t OMXNodeInstance::sendCommand( OMX_COMMANDTYPE cmd, OMX_S32 param) { if (cmd == OMX_CommandStateSet) { - // We do not support returning from unloaded state, so there are no configurations past - // first StateSet command. + // There are no configurations past first StateSet command. mSailed = true; } const sp bufferSource(getGraphicBufferSource()); @@ -1689,6 +1688,13 @@ void OMXNodeInstance::onEvent( && arg2 == OMX_StateExecuting) { bufferSource->omxExecuting(); } + + // allow configuration if we return to the loaded state + if (event == OMX_EventCmdComplete + && arg1 == OMX_CommandStateSet + && arg2 == OMX_StateLoaded) { + mSailed = false; + } } // static -- cgit v1.1 From c2a27ba1c949d1409f75bfef5cc052b7d88e4610 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Mon, 19 Sep 2016 15:29:04 -0700 Subject: IOMX: do not clear buffer if it's allocated by component The component might depends on their buffers to be initialized in certain ways to work. Don't clear unless we're allocating it. bug: 31586647 Change-Id: Ia0a125797e414998ef0cd8ce03672f5b1e0bbf7a (cherry picked from commit ea76573aa276f51950007217a97903c4fe64f685) --- media/libstagefright/omx/OMXNodeInstance.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index b86611f..1e76e01 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -1184,7 +1184,6 @@ status_t OMXNodeInstance::allocateBufferWithBackup( } CHECK_EQ(header->pAppPrivate, buffer_meta); - memset(header->pBuffer, 0, header->nAllocLen); *buffer = makeBufferID(header); -- cgit v1.1 From c13a507aa0badeb5f8482c25e2845780ba021ce7 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Tue, 11 Oct 2016 08:41:51 -0700 Subject: stagefright: don't fail MediaCodec.configure if clients use store-meta key Even though storing metadata is not supported in MediaCodec.configure and is only meant to be used by Stagefright recorder, don't fail configure. Bug: 31986922 Change-Id: Id9f083be6e857e7a0d8d4a74159be5b8894e28be (cherry picked from commit ae52fd383a43ac239f459078fd003ce8ac2efb55) --- media/libstagefright/ACodec.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 6399b79..cd2408b 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1655,7 +1655,10 @@ status_t ACodec::configureCodec( ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d", mComponentName.c_str(), err); - return err; + if (mOMX->livesLocally(mNode, getpid())) { + return err; + } + ALOGI("ignoring failure to use internal MediaCodec key."); } // For this specific case we could be using camera source even if storeMetaDataInBuffers // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize. -- cgit v1.1 From 2e39b85cae7025786fade45ba90583c1729ffe42 Mon Sep 17 00:00:00 2001 From: Ziyan Date: Tue, 21 Apr 2015 15:07:13 +0200 Subject: libstagefright: wfd: don't use intra macroblock refresh mode on omap4 Most, if not all OMAP4 Ducatis doesn't support intra macroblock refresh mode, causing the encoder to fail initializing. This patch disables intra macroblock refresh mode for wifi display on omap4. Note: Ideally, the decoder shouldn't fail if intra macroblock refresh mode can't be configured. However, that would trick higher layers into thinking that it's on, because they set that parameter. As of now, this mode seems to only ever be used for wifi display. Change-Id: I9696af8f22db82cc436a351e4d93bf7323588f43 --- media/libstagefright/wifi-display/Android.mk | 4 ++++ media/libstagefright/wifi-display/source/Converter.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk index fb28624..6f17747 100644 --- a/media/libstagefright/wifi-display/Android.mk +++ b/media/libstagefright/wifi-display/Android.mk @@ -33,6 +33,10 @@ LOCAL_SHARED_LIBRARIES:= \ LOCAL_CFLAGS += -Wno-multichar -Werror -Wall LOCAL_CLANG := true +ifeq ($(BOARD_NO_INTRA_MACROBLOCK_MODE_SUPPORT),true) +LOCAL_CFLAGS += -DBOARD_NO_INTRA_MACROBLOCK_MODE_SUPPORT +endif + LOCAL_MODULE:= libstagefright_wfd LOCAL_MODULE_TAGS:= optional diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index 471152e..9a2d08a 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -173,8 +173,10 @@ status_t Converter::initEncoder() { mOutputFormat->setInt32("frame-rate", 30); mOutputFormat->setInt32("i-frame-interval", 15); // Iframes every 15 secs +#ifndef BOARD_NO_INTRA_MACROBLOCK_MODE_SUPPORT // Configure encoder to use intra macroblock refresh mode mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic); +#endif int width, height, mbs; if (!mOutputFormat->findInt32("width", &width) -- cgit v1.1 From 1c6e16c0b4082c0edaca4fcc0838f33bf14ffac8 Mon Sep 17 00:00:00 2001 From: Andreas Blaesius Date: Tue, 8 Nov 2016 03:24:23 -0700 Subject: Allow to use baseline profile for AVC recording - some encoder seem to crash using higher h264 profiles Change-Id: I2beb881e76519f872e3e99957f8b981eeaa53b56 --- media/libstagefright/ACodec.cpp | 2 +- media/libstagefright/Android.mk | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index e00e673..d2389f6 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -3568,7 +3568,7 @@ status_t ACodec::setupAVCEncoderParameters(const sp &msg) { // XXX // Allow higher profiles to be set since the encoder seems to support -#if 0 +#ifdef USE_AVC_BASELINE_PROFILE if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) { ALOGW("Use baseline profile instead of %d for AVC recording", h264type.eProfile); diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 29fb418..792c139 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -173,6 +173,10 @@ ifeq ($(TARGET_BOARD_PLATFORM),omap4) LOCAL_CFLAGS += -DBOARD_CANT_REALLOCATE_OMX_BUFFERS endif +ifeq ($(TARGET_USE_AVC_BASELINE_PROFILE), true) +LOCAL_CFLAGS += -DUSE_AVC_BASELINE_PROFILE +endif + ifeq ($(call is-vendor-board-platform,QCOM),true) LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true) -- cgit v1.1