diff options
Diffstat (limited to 'media/libstagefright/codecs')
51 files changed, 809 insertions, 677 deletions
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp index c945305..0d3151d 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp @@ -211,6 +211,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; } @@ -246,6 +250,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; } @@ -286,6 +294,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)) { @@ -300,6 +312,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; } @@ -320,6 +336,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() @@ -386,6 +407,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; } @@ -623,12 +648,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; + } } } 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/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/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp index f8316fd..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; } @@ -303,6 +323,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; @@ -312,6 +339,26 @@ 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; + } + + 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), @@ -339,6 +386,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) { @@ -353,10 +409,8 @@ 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?", - inHeader->nFilledLen, frameSize); - - notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen); + notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); mSignalledError = true; return; } 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. */ 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/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 */ 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/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/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/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..c8277de 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", @@ -228,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 bd01a1a..04d5a33 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)) { @@ -216,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, diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp index e601125..1dac868 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 */ @@ -439,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; } } @@ -520,7 +528,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() @@ -530,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); 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/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index 0c1a149..1dd631a 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: %lu bytes", + (unsigned long)outHeader->nAllocLen); + android_errorWriteLog(0x534e4554, "30033990"); + notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); + mSignalledError = true; + return; + } PVSetReferenceYUV(mHandle, outHeader->pBuffer); - mFramesConfigured = true; } @@ -229,6 +238,23 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { int32_t bufferSize = inHeader->nFilledLen; int32_t tmp = bufferSize; + 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"); + 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 +298,7 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { ++mInputBufferCount; outHeader->nOffset = 0; - outHeader->nFilledLen = (mWidth * mHeight * 3) / 2; + outHeader->nFilledLen = frameSize; List<BufferInfo *>::iterator it = outQueue.begin(); while ((*it)->mHeader != outHeader) { diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index f2a4e65..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; @@ -232,6 +236,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 +254,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 +279,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 +317,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 +335,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 +361,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 4c4da60..005956d 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp @@ -122,6 +122,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 %u, 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) { @@ -130,6 +141,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; } @@ -153,6 +168,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; } @@ -178,6 +197,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)) { @@ -192,6 +215,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; } @@ -262,6 +289,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 %u, 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<int16_t *>(outHeader->pBuffer); @@ -294,7 +329,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; @@ -306,9 +344,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 c769795..5b6af88 100644 --- a/media/libstagefright/codecs/mp3dec/SoftMP3.h +++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h @@ -75,6 +75,7 @@ private: void initPorts(); void initDecoder(); + void *memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len); DISALLOW_EVIL_CONSTRUCTORS(SoftMP3); }; 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, diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index e161fb8..444a7fc 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<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); BufferInfo *outInfo = NULL; OMX_BUFFERHEADERTYPE *outHeader = NULL; @@ -149,15 +148,18 @@ 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 (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]; + 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 { + outHeader->nFilledLen = 0; + } mImg = NULL; outInfo->mOwnedByUs = false; @@ -185,6 +187,25 @@ 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", + (unsigned long long)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; @@ -193,7 +214,6 @@ void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) { List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); bool EOSseen = false; - vpx_codec_err_t err; bool portWillReset = false; while ((mEOSStatus == INPUT_EOS_SEEN || !inQueue.empty()) @@ -217,8 +237,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; 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); }; diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index 410f9d0..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; + } + + if (vp8Params->nPortIndex != kOutputPortIndex) { + return OMX_ErrorUnsupportedIndex; + } - vp8Params->eProfile = OMX_VIDEO_VP8ProfileMain; - vp8Params->eLevel = mLevel; - vp8Params->nDCTPartitions = mDCTPartitions; - vp8Params->bErrorResilientMode = mErrorResilience; - return OMX_ErrorNone; + 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; + } - case OMX_IndexParamVideoVp8: - return internalSetVp8Params( - (const OMX_VIDEO_PARAM_VP8TYPE *)param); + return internalSetBitrateParams(bitRate); + } - case OMX_IndexParamVideoAndroidVp8Encoder: - return internalSetAndroidVp8Params( - (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)param); + 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_IndexParamVideoAndroidVp8Encoder: { + const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8AndroidParams = + (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE*) param; + + if (!isValidOMXParam(vp8AndroidParams)) { + return OMX_ErrorBadParameter; + } + + 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; } @@ -688,9 +729,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 +740,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 +816,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); 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<BufferInfo *> &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); 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/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) 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 <log/log.h> + #include <stdlib.h> #include <string.h> #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_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 <log/log.h> /*------------------------------------------------------------------------------ 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) 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; 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 */ diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp index cb10bce..2e44ed7 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; } @@ -442,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/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp index 0d80098..f90c1b3 100644 --- a/media/libstagefright/codecs/raw/SoftRaw.cpp +++ b/media/libstagefright/codecs/raw/SoftRaw.cpp @@ -104,6 +104,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; } @@ -135,6 +139,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)) { @@ -149,6 +157,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 08200c1..7209796 100644 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -131,6 +131,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; } @@ -162,6 +166,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; } @@ -198,6 +206,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)) { @@ -212,6 +224,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; } @@ -269,6 +285,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; @@ -374,9 +396,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); |