am dd6a1764: am c08872f9: Merge "NuPlayerRenderer: handle error when resuming an offloaded track" into mnc-dev
* commit 'dd6a17649106fd48b0e69703d339bbc5a1ae9a0b':
NuPlayerRenderer: handle error when resuming an offloaded track
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 9765f0d..dbf524e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -240,7 +240,7 @@
} break;
case SET_DATA_SOURCE_FD: {
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
- int fd = dup(data.readFileDescriptor());
+ int fd = data.readFileDescriptor();
int64_t offset = data.readInt64();
int64_t length = data.readInt64();
reply->writeInt32(setDataSource(fd, offset, length));
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index c5790fb..2a17696 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -23,7 +23,7 @@
#include <utils/Log.h>
#include <utils/Vector.h>
#include <cutils/properties.h>
-#include <libexpat/expat.h>
+#include <expat.h>
#include <media/MediaProfiles.h>
#include <media/stagefright/foundation/ADebug.h>
#include <OMX_Video.h>
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index a7f6f8b..b9cfe80 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -40,9 +40,6 @@
}
static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16(permissionString));
if (!ok) ALOGE("Request requires %s", permissionString);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 56521a2..05a65a3 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -253,9 +253,6 @@
static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16(permissionString));
if (!ok) ALOGE("Request requires %s", permissionString);
@@ -749,7 +746,6 @@
if (offset >= sb.st_size) {
ALOGE("offset error");
- ::close(fd);
return UNKNOWN_ERROR;
}
if (offset + length > sb.st_size) {
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index f761dec..08c7899 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -46,9 +46,6 @@
const char* recordAudioPermission = "android.permission.RECORD_AUDIO";
static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
- return true;
-#endif
if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
bool ok = checkCallingPermission(String16(permissionString));
if (!ok) ALOGE("Request requires %s", permissionString);
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index a5a1fa5..b45fd4f 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -149,7 +149,6 @@
if (offset >= sb.st_size) {
ALOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
- ::close(fd);
return BAD_VALUE;
}
if (offset + length > sb.st_size) {
@@ -165,12 +164,10 @@
ALOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) {
- ::close(fd);
return NO_INIT;
}
status_t status = p->setDataSource(fd, offset, length);
if (status == NO_ERROR) mRetriever = p;
- ::close(fd);
return status;
}
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 3fedd9b..8fc4b29 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -64,7 +64,7 @@
// the method returns, if you want to keep it, dup it!
status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
- return mPlayer->setDataSource(dup(fd), offset, length);
+ return mPlayer->setDataSource(fd, offset, length);
}
status_t StagefrightPlayer::setDataSource(const sp<IStreamSource> &source) {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 4e6c2a6..b451021 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -343,6 +343,7 @@
reset_l();
+ fd = dup(fd);
sp<DataSource> dataSource = new FileSource(fd, offset, length);
status_t err = dataSource->initCheck();
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 5edc04c..c657195 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -39,7 +39,7 @@
#include <utils/threads.h>
#include <cutils/properties.h>
-#include <libexpat/expat.h>
+#include <expat.h>
namespace android {
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 @@
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 @@
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/enc/Android.mk b/media/libstagefright/codecs/amrnb/enc/Android.mk
index bdba8a9..e8b010e 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.mk
+++ b/media/libstagefright/codecs/amrnb/enc/Android.mk
@@ -103,3 +103,25 @@
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+ test/amrnb_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/../common/include
+
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrnbenc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_amrnb_common
+
+LOCAL_MODULE := libstagefright_amrnbenc_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp b/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
index 588abbb..523e482 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
@@ -147,7 +147,7 @@
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
-Word32 L_negate(register Word32 L_var1)
+Word32 L_negate(Word32 L_var1)
{
/*----------------------------------------------------------------------------
; Define all local variables
diff --git a/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp b/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp
new file mode 100644
index 0000000..e2d198e
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdint.h>
+#include <assert.h>
+#include "gsmamr_enc.h"
+
+enum {
+ kInputSize = 320, // 160 samples * 16-bit per sample.
+ kOutputSize = 1024
+};
+
+struct AmrNbEncState {
+ void *encCtx;
+ void *pidSyncCtx;
+};
+
+void usage(void) {
+ printf("Usage:\n");
+ printf("AMRNBEnc [options] <input file> <output file>\n");
+ printf("\n");
+ printf("Options +M* for setting compression bitrate mode, default is 4.75 kbps\n");
+ printf(" +M0 = 4.75 kbps\n");
+ printf(" +M1 = 5.15 kbps\n");
+ printf(" +M2 = 5.90 kbps\n");
+ printf(" +M3 = 6.70 kbps\n");
+ printf(" +M4 = 7.40 kbps\n");
+ printf(" +M5 = 7.95 kbps\n");
+ printf(" +M6 = 10.2 kbps\n");
+ printf(" +M7 = 12.2 kbps\n");
+ printf("\n");
+}
+
+int encode(int mode, const char *srcFile, const char *dstFile) {
+ int retVal = EXIT_SUCCESS;
+ FILE *fSrc = NULL;
+ FILE *fDst = NULL;
+ int frameNum = 0;
+ bool eofReached = false;
+ uint16_t *inputBuf = NULL;
+ uint8_t *outputBuf = NULL;
+ AmrNbEncState *amr = NULL;
+
+ clock_t start, finish;
+ double duration = 0.0;
+
+ // Open input file.
+ fSrc = fopen(srcFile, "rb");
+ if (fSrc == NULL) {
+ fprintf(stderr, "Error opening input file\n");
+ retVal = EXIT_FAILURE;
+ goto safe_exit;
+ }
+
+ // Open output file.
+ fDst = fopen(dstFile, "wb");
+ if (fDst == NULL) {
+ fprintf(stderr, "Error opening output file\n");
+ retVal = EXIT_FAILURE;
+ goto safe_exit;
+ }
+
+ // Allocate input buffer.
+ inputBuf = (uint16_t*) malloc(kInputSize);
+ assert(inputBuf != NULL);
+
+ // Allocate output buffer.
+ outputBuf = (uint8_t*) malloc(kOutputSize);
+ assert(outputBuf != NULL);
+
+ // Initialize encoder.
+ amr = (AmrNbEncState*) malloc(sizeof(AmrNbEncState));
+ AMREncodeInit(&amr->encCtx, &amr->pidSyncCtx, 0);
+
+ // Write file header.
+ fwrite("#!AMR\n", 1, 6, fDst);
+
+ while (1) {
+ // Read next input frame.
+ int bytesRead;
+ bytesRead = fread(inputBuf, 1, kInputSize, fSrc);
+ if (bytesRead != kInputSize && !feof(fSrc)) {
+ retVal = EXIT_FAILURE; // Invalid magic number.
+ fprintf(stderr, "Error reading input file\n");
+ goto safe_exit;
+ } else if (feof(fSrc) && bytesRead == 0) {
+ eofReached = true;
+ break;
+ }
+
+ start = clock();
+
+ // Encode the frame.
+ Frame_Type_3GPP frame_type = (Frame_Type_3GPP) mode;
+ int bytesGenerated;
+ bytesGenerated = AMREncode(amr->encCtx, amr->pidSyncCtx, (Mode)mode,
+ (Word16*)inputBuf, outputBuf, &frame_type,
+ AMR_TX_WMF);
+
+ // Convert from WMF to RFC 3267 format.
+ if (bytesGenerated > 0) {
+ outputBuf[0] = ((outputBuf[0] << 3) | 4) & 0x7c;
+ }
+
+ finish = clock();
+ duration += finish - start;
+
+ if (bytesGenerated < 0) {
+ retVal = EXIT_FAILURE;
+ fprintf(stderr, "Encoding error\n");
+ goto safe_exit;
+ }
+
+ frameNum++;
+ printf(" Frames processed: %d\n", frameNum);
+
+ // Write the output.
+ fwrite(outputBuf, 1, bytesGenerated, fDst);
+ }
+
+ // Dump the time taken by encode.
+ printf("\n%2.5lf seconds\n", (double)duration/CLOCKS_PER_SEC);
+
+safe_exit:
+
+ // Free the encoder instance.
+ if (amr) {
+ AMREncodeExit(&amr->encCtx, &amr->pidSyncCtx);
+ free(amr);
+ }
+
+ // Free input and output buffer.
+ free(inputBuf);
+ free(outputBuf);
+
+ // Close the input and output files.
+ if (fSrc) {
+ fclose(fSrc);
+ }
+ if (fDst) {
+ fclose(fDst);
+ }
+
+ return retVal;
+}
+
+int main(int argc, char *argv[]) {
+ Mode mode = MR475;
+ int retVal;
+ char *inFileName = NULL;
+ char *outFileName = NULL;
+ int arg, filename = 0;
+
+ if (argc < 3) {
+ usage();
+ return EXIT_FAILURE;
+ } else {
+ for (arg = 1; arg < argc; arg++) {
+ if (argv[arg][0] == '+') {
+ if (argv[arg][1] == 'M') {
+ switch (argv[arg][2]) {
+ case '0': mode = MR475;
+ break;
+ case '1': mode = MR515;
+ break;
+ case '2': mode = MR59;
+ break;
+ case '3': mode = MR67;
+ break;
+ case '4': mode = MR74;
+ break;
+ case '5': mode = MR795;
+ break;
+ case '6': mode = MR102;
+ break;
+ case '7': mode = MR122;
+ break;
+ default:
+ usage();
+ fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+ return EXIT_FAILURE;
+ break;
+ }
+ } else {
+ usage();
+ fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+ return EXIT_FAILURE;
+ }
+ } else {
+ switch (filename) {
+ case 0:
+ inFileName = argv[arg];
+ break;
+ case 1:
+ outFileName = argv[arg];
+ break;
+ default:
+ usage();
+ fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+ return EXIT_FAILURE;
+ }
+ filename++;
+ }
+ }
+ }
+
+ retVal = encode(mode, inFileName, outFileName);
+ return retVal;
+}
+
diff --git a/media/libstagefright/codecs/amrwb/Android.mk b/media/libstagefright/codecs/amrwb/Android.mk
index 686f7a3..6ce20ca 100644
--- a/media/libstagefright/codecs/amrwb/Android.mk
+++ b/media/libstagefright/codecs/amrwb/Android.mk
@@ -55,3 +55,24 @@
LOCAL_MODULE := libstagefright_amrwbdec
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+ test/amrwbdec_test.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(call include-path-for, audio-utils)
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrwbdec libsndfile
+
+LOCAL_SHARED_LIBRARIES := \
+ libaudioutils
+
+LOCAL_MODULE := libstagefright_amrwbdec_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp b/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp
new file mode 100644
index 0000000..b04bafd
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "pvamrwbdecoder.h"
+#include <audio_utils/sndfile.h>
+
+// Constants for AMR-WB.
+enum {
+ kInputBufferSize = 64,
+ kSamplesPerFrame = 320,
+ kBitsPerSample = 16,
+ kOutputBufferSize = kSamplesPerFrame * kBitsPerSample/8,
+ kSampleRate = 16000,
+ kChannels = 1,
+ kFileHeaderSize = 9,
+ kMaxSourceDataUnitSize = 477 * sizeof(int16_t)
+};
+
+const uint32_t kFrameSizes[] = { 17, 23, 32, 36, 40, 46, 50, 58, 60 };
+
+int main(int argc, char *argv[]) {
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ // Open the input file.
+ FILE* fpInput = fopen(argv[1], "rb");
+ if (fpInput == NULL) {
+ fprintf(stderr, "Could not open %s\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ // Validate the input AMR file.
+ char header[kFileHeaderSize];
+ int bytesRead = fread(header, 1, kFileHeaderSize, fpInput);
+ if ((bytesRead != kFileHeaderSize) ||
+ (memcmp(header, "#!AMR-WB\n", kFileHeaderSize) != 0)) {
+ fprintf(stderr, "Invalid AMR-WB file\n");
+ fclose(fpInput);
+ return EXIT_FAILURE;
+ }
+
+ // Open the output file.
+ SF_INFO sfInfo;
+ memset(&sfInfo, 0, sizeof(SF_INFO));
+ sfInfo.channels = kChannels;
+ sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ sfInfo.samplerate = kSampleRate;
+ SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
+ if (handle == NULL) {
+ fprintf(stderr, "Could not create %s\n", argv[2]);
+ fclose(fpInput);
+ return EXIT_FAILURE;
+ }
+
+ // Allocate the decoder memory.
+ uint32_t memRequirements = pvDecoder_AmrWbMemRequirements();
+ void *decoderBuf = malloc(memRequirements);
+ assert(decoderBuf != NULL);
+
+ // Create AMR-WB decoder instance.
+ void *amrHandle;
+ int16_t *decoderCookie;
+ pvDecoder_AmrWb_Init(&amrHandle, decoderBuf, &decoderCookie);
+
+ // Allocate input buffer.
+ uint8_t *inputBuf = (uint8_t*) malloc(kInputBufferSize);
+ assert(inputBuf != NULL);
+
+ // Allocate input sample buffer.
+ int16_t *inputSampleBuf = (int16_t*) malloc(kMaxSourceDataUnitSize);
+ assert(inputSampleBuf != NULL);
+
+ // Allocate output buffer.
+ int16_t *outputBuf = (int16_t*) malloc(kOutputBufferSize);
+ assert(outputBuf != NULL);
+
+ // Decode loop.
+ int retVal = EXIT_SUCCESS;
+ while (1) {
+ // Read mode.
+ uint8_t modeByte;
+ bytesRead = fread(&modeByte, 1, 1, fpInput);
+ if (bytesRead != 1) break;
+ int16 mode = ((modeByte >> 3) & 0x0f);
+
+ // AMR-WB file format cannot have mode 10, 11, 12 and 13.
+ if (mode >= 10 && mode <= 13) {
+ fprintf(stderr, "Encountered illegal frame type %d\n", mode);
+ retVal = EXIT_FAILURE;
+ break;
+ }
+
+ if (mode >= 9) {
+ // Produce silence for comfort noise, speech lost and no data.
+ memset(outputBuf, 0, kOutputBufferSize);
+ } else /* if (mode < 9) */ {
+ // Read rest of the frame.
+ int32_t frameSize = kFrameSizes[mode];
+ bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+ if (bytesRead != frameSize) break;
+
+ int16 frameType, frameMode;
+ RX_State_wb rx_state;
+ frameMode = mode;
+ mime_unsorting(
+ (uint8_t *)inputBuf,
+ inputSampleBuf,
+ &frameType, &frameMode, 1, &rx_state);
+
+ int16_t numSamplesOutput;
+ pvDecoder_AmrWb(
+ frameMode, inputSampleBuf,
+ outputBuf,
+ &numSamplesOutput,
+ decoderBuf, frameType, decoderCookie);
+
+ if (numSamplesOutput != kSamplesPerFrame) {
+ fprintf(stderr, "Decoder encountered error\n");
+ retVal = EXIT_FAILURE;
+ break;
+ }
+
+ for (int i = 0; i < kSamplesPerFrame; ++i) {
+ outputBuf[i] &= 0xfffC;
+ }
+ }
+
+ // Write output to wav.
+ sf_writef_short(handle, outputBuf, kSamplesPerFrame / kChannels);
+ }
+
+ // Close input and output file.
+ fclose(fpInput);
+ sf_close(handle);
+
+ // Free allocated memory.
+ free(inputBuf);
+ free(inputSampleBuf);
+ free(outputBuf);
+
+ return retVal;
+}
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index 024a292..c7692cb 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -86,9 +86,6 @@
endif
-# ARMV5E/Filt_6k_7k_opt.s does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-
LOCAL_MODULE := libstagefright_amrwbenc
LOCAL_ARM_MODE := arm
@@ -144,3 +141,6 @@
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index 4ff5f10..0cb0097 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include "voAMRWB.h"
#include "cmnMemory.h"
@@ -222,12 +223,12 @@
fflush(fdst);
}
}
- else if(returnCode == VO_ERR_LICENSE_ERROR)
+ else if((unsigned)returnCode == VO_ERR_LICENSE_ERROR)
{
printf("Encoder time reach upper limit......");
goto safe_exit;
}
- } while(returnCode != VO_ERR_INPUT_BUFFER_SMALL);
+ } while((unsigned)returnCode != VO_ERR_INPUT_BUFFER_SMALL);
finish = clock();
duration += finish - start;
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
index c203f77..65d69a2 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
@@ -5,17 +5,20 @@
AMRWB_E_SAMPLE.c \
../../common/cmnMemory.c
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
LOCAL_MODULE := AMRWBEncTest
LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -DLINUX
+LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := \
libstagefright \
libdl
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrwbenc
+
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/ \
$(LOCAL_PATH)/../../common \
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
index 282db92..42ebc32 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
@@ -99,6 +99,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDP
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
index 4aa317e..3f060ff 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
@@ -75,6 +75,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
index f23b5a0..9cad479 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
@@ -183,6 +183,6 @@
Lable1:
.word fir_6k_7k-Lable1
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
index 49bdc2b..ffedbde 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
@@ -226,6 +226,6 @@
ADD r13, r13, #voSTACK
LDMFD r13!, {r4 - r12, r15}
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
index 3f4930c..9743b9e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
@@ -221,6 +221,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
index 71bb532..cd75179 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
@@ -181,6 +181,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
index 2d4c7cc..eedccc7 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
@@ -143,7 +143,7 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
index deb7efc..60c2a47 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
@@ -45,7 +45,8 @@
SUBLT r5, r5, #2 @x--
SUB r5, r5, #30 @x -= 15
RSB r4, r2, #3 @k = 3 - frac
- ADRL r8, Table
+ ADR r8, Table
+ NOP @space for fixed up relative address of ADR
LDR r6, [r8]
ADD r6, r8
MOV r8, r4, LSL #6
@@ -456,7 +457,7 @@
Table:
.word inter4_2-Table
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
index 5ff0964..d71d790 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
@@ -220,7 +220,7 @@
LDMFD r13!, {r4 -r12,pc}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
index b300224..e8802f5 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
@@ -67,7 +67,7 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
index 0c287a4..2a1e0d7 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
@@ -233,6 +233,6 @@
ADD r13, r13, #700
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
index 1d5893f..91feea0 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
@@ -98,5 +98,5 @@
LDMFD r13!, {r4 - r12, r15}
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
index 8230944..7149a49 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
@@ -123,5 +123,5 @@
LDMFD r13!, {r4 - r12, r15}
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
index 8df0caa..e0f992f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
@@ -226,6 +226,6 @@
Lable1:
.word fir_6k_7k-Lable1
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
index 4263cd4..28e6d6c 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
@@ -265,6 +265,6 @@
ADD r13, r13, #voSTACK
LDMFD r13!, {r4 - r12, r15}
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
index e786dde..9687431 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
@@ -128,6 +128,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
index 8efa9fb..9fb3a6e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
@@ -174,5 +174,5 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
index 8904289..a4deda3 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
@@ -143,7 +143,7 @@
the_end:
LDMFD r13!, {r4 - r12, r15}
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
index 67be1ed..f8b634f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
@@ -99,5 +99,5 @@
Lable1:
.word inter4_2-Lable1
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
index 394fa83..bc3d780 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
@@ -122,6 +122,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
index e45daac..89c0572 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
@@ -133,6 +133,6 @@
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
index 5731bdb..029560e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
@@ -101,6 +101,6 @@
ADD r13, r13, #700
LDMFD r13!, {r4 - r12, r15}
@ENDFUNC
- .END
+ .end
diff --git a/media/libstagefright/codecs/avc/enc/Android.mk b/media/libstagefright/codecs/avc/enc/Android.mk
index 2ceebc8..d5131cb 100644
--- a/media/libstagefright/codecs/avc/enc/Android.mk
+++ b/media/libstagefright/codecs/avc/enc/Android.mk
@@ -74,3 +74,31 @@
LOCAL_CFLAGS += -Werror
include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ test/h264_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/../common/include \
+ $(LOCAL_PATH)/../common
+
+LOCAL_CFLAGS := \
+ -DOSCL_IMPORT_REF= -DOSCL_UNUSED_ARG= -DOSCL_EXPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_avcenc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_avc_common
+
+LOCAL_MODULE := libstagefright_h264enc_test
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
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/avc/enc/test/h264_enc_test.cpp b/media/libstagefright/codecs/avc/enc/test/h264_enc_test.cpp
new file mode 100644
index 0000000..7a782a8
--- /dev/null
+++ b/media/libstagefright/codecs/avc/enc/test/h264_enc_test.cpp
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "avcenc_api.h"
+#include "avcenc_int.h"
+
+// Constants.
+enum {
+ kMaxWidth = 720,
+ kMaxHeight = 480,
+ kMaxFrameRate = 30,
+ kMaxBitrate = 2048, // in kbps.
+ kInputBufferSize = (kMaxWidth * kMaxHeight * 3) / 2, // For YUV 420 format.
+ kOutputBufferSize = kInputBufferSize,
+ kMaxDpbBuffers = 17,
+ kIDRFrameRefreshIntervalInSec = 1,
+};
+
+
+static void *MallocCb(void * /*userData*/, int32_t size, int32_t /*attrs*/) {
+ void *ptr = calloc(size, 1);
+ return ptr;
+}
+
+static void FreeCb(void * /*userData*/, void *ptr) {
+ free(ptr);
+}
+
+static int32_t DpbAllocCb(void * /*userData*/,
+ unsigned int sizeInMbs, unsigned int numBuffers) {
+
+ size_t frameSize = (sizeInMbs << 7) * 3;
+ if(numBuffers < kMaxDpbBuffers && frameSize <= kInputBufferSize) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int32_t BindFrameCb(void *userData, int32_t index, uint8_t **yuv) {
+ assert(index < kMaxDpbBuffers);
+ uint8_t** dpbBuffer = static_cast<uint8_t**>(userData);
+ *yuv = dpbBuffer[index];
+ return 1;
+}
+
+static void UnbindFrameCb(void * /*userData*/, int32_t /*index*/) {
+}
+
+int main(int argc, char *argv[]) {
+
+ if (argc < 7) {
+ fprintf(stderr, "Usage %s <input yuv> <output file> <width> <height>"
+ " <frame rate> <bitrate in kbps>\n", argv[0]);
+ fprintf(stderr, "Max width %d\n", kMaxWidth);
+ fprintf(stderr, "Max height %d\n", kMaxHeight);
+ fprintf(stderr, "Max framerate %d\n", kMaxFrameRate);
+ fprintf(stderr, "Max bitrate %d kbps\n", kMaxBitrate);
+ return EXIT_FAILURE;
+ }
+
+ // Read height and width.
+ int32_t width;
+ int32_t height;
+ width = atoi(argv[3]);
+ height = atoi(argv[4]);
+ if (width > kMaxWidth || height > kMaxHeight || width <= 0 || height <= 0) {
+ fprintf(stderr, "Unsupported dimensions %dx%d\n", width, height);
+ return EXIT_FAILURE;
+ }
+
+ if (width % 16 != 0 || height % 16 != 0) {
+ fprintf(stderr, "Video frame size %dx%d must be a multiple of 16\n",
+ width, height);
+ return EXIT_FAILURE;
+ }
+
+ // Read frame rate.
+ int32_t frameRate;
+ frameRate = atoi(argv[5]);
+ if (frameRate > kMaxFrameRate || frameRate <= 0) {
+ fprintf(stderr, "Unsupported frame rate %d\n", frameRate);
+ return EXIT_FAILURE;
+ }
+
+ // Read bit rate.
+ int32_t bitrate;
+ bitrate = atoi(argv[6]);
+ if (bitrate > kMaxBitrate || bitrate <= 0) {
+ fprintf(stderr, "Unsupported bitrate %d\n", bitrate);
+ return EXIT_FAILURE;
+ }
+ bitrate *= 1024; // kbps to bps.
+
+ // Open the input file.
+ FILE *fpInput = fopen(argv[1], "rb");
+ if (!fpInput) {
+ fprintf(stderr, "Could not open %s\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ // Open the output file.
+ FILE *fpOutput = fopen(argv[2], "wb");
+ if (!fpOutput) {
+ fprintf(stderr, "Could not open %s\n", argv[2]);
+ fclose(fpInput);
+ return EXIT_FAILURE;
+ }
+
+ // Allocate input buffer.
+ uint8_t *inputBuf = (uint8_t *)malloc(kInputBufferSize);
+ assert(inputBuf != NULL);
+
+ // Allocate output buffer.
+ uint8_t *outputBuf = (uint8_t *)malloc(kOutputBufferSize);
+ assert(outputBuf != NULL);
+
+ // Allocate dpb buffers.
+ uint8_t * dpbBuffers[kMaxDpbBuffers];
+ for (int i = 0; i < kMaxDpbBuffers; ++i) {
+ dpbBuffers[i] = (uint8_t *)malloc(kInputBufferSize);
+ assert(dpbBuffers[i] != NULL);
+ }
+
+ // Initialize the encoder parameters.
+ tagAVCEncParam encParams;
+ memset(&encParams, 0, sizeof(tagAVCEncParam));
+ encParams.rate_control = AVC_ON;
+ encParams.initQP = 0;
+ encParams.init_CBP_removal_delay = 1600;
+
+ encParams.intramb_refresh = 0;
+ encParams.auto_scd = AVC_ON;
+ encParams.out_of_band_param_set = AVC_ON;
+ encParams.poc_type = 2;
+ encParams.log2_max_poc_lsb_minus_4 = 12;
+ encParams.delta_poc_zero_flag = 0;
+ encParams.offset_poc_non_ref = 0;
+ encParams.offset_top_bottom = 0;
+ encParams.num_ref_in_cycle = 0;
+ encParams.offset_poc_ref = NULL;
+
+ encParams.num_ref_frame = 1;
+ encParams.num_slice_group = 1;
+ encParams.fmo_type = 0;
+
+ encParams.db_filter = AVC_ON;
+ encParams.disable_db_idc = 0;
+
+ encParams.alpha_offset = 0;
+ encParams.beta_offset = 0;
+ encParams.constrained_intra_pred = AVC_OFF;
+
+ encParams.data_par = AVC_OFF;
+ encParams.fullsearch = AVC_OFF;
+ encParams.search_range = 16;
+ encParams.sub_pel = AVC_OFF;
+ encParams.submb_pred = AVC_OFF;
+ encParams.rdopt_mode = AVC_OFF;
+ encParams.bidir_pred = AVC_OFF;
+
+ encParams.use_overrun_buffer = AVC_OFF;
+
+ encParams.width = width;
+ encParams.height = height;
+ encParams.bitrate = bitrate;
+ encParams.frame_rate = 1000 * frameRate; // In frames/ms.
+ encParams.CPB_size = (uint32_t) (bitrate >> 1);
+
+ int32_t IDRFrameRefreshIntervalInSec = kIDRFrameRefreshIntervalInSec;
+ if (IDRFrameRefreshIntervalInSec == 0) {
+ encParams.idr_period = 1; // All I frames.
+ } else {
+ encParams.idr_period = (IDRFrameRefreshIntervalInSec * frameRate);
+ }
+
+ int32_t nMacroBlocks = ((((width + 15) >> 4) << 4) *
+ (((height + 15) >> 4) << 4)) >> 8;
+ uint32_t *sliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks);
+ assert(sliceGroup != NULL);
+ for (int i = 0, idx = 0; i < nMacroBlocks; ++i) {
+ sliceGroup[i] = idx++;
+ if (idx >= encParams.num_slice_group) {
+ idx = 0;
+ }
+ }
+ encParams.slice_group = sliceGroup;
+ encParams.profile = AVC_BASELINE;
+ encParams.level = AVC_LEVEL2;
+
+ // Initialize the handle.
+ tagAVCHandle handle;
+ memset(&handle, 0, sizeof(tagAVCHandle));
+ handle.AVCObject = NULL;
+ handle.userData = dpbBuffers;
+ handle.CBAVC_DPBAlloc = DpbAllocCb;
+ handle.CBAVC_FrameBind = BindFrameCb;
+ handle.CBAVC_FrameUnbind = UnbindFrameCb;
+ handle.CBAVC_Malloc = MallocCb;
+ handle.CBAVC_Free = FreeCb;
+
+ // Initialize the encoder.
+ AVCEnc_Status status;
+ status = PVAVCEncInitialize(&handle, &encParams, NULL, NULL);
+ if (status != AVCENC_SUCCESS) {
+ fprintf(stderr, "Failed to initialize the encoder\n");
+
+ // Release resources.
+ fclose(fpInput);
+ fclose(fpOutput);
+ free(sliceGroup);
+ free(inputBuf);
+ free(outputBuf);
+ for (int i = 0; i < kMaxDpbBuffers; ++i) {
+ free(dpbBuffers[i]);
+ }
+ return EXIT_FAILURE;
+ }
+
+ // Encode Sequence Parameter Set.
+ uint32_t dataLength = kOutputBufferSize;
+ int32_t type;
+ status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+ assert(type == AVC_NALTYPE_SPS);
+ fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+ fwrite(outputBuf, 1, dataLength, fpOutput); // SPS.
+
+ // Encode Picture Paramater Set.
+ dataLength = kOutputBufferSize;
+ status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+ assert(type == AVC_NALTYPE_PPS);
+ fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+ fwrite(outputBuf, 1, dataLength, fpOutput); // PPS.
+
+ // Core loop.
+ int32_t retVal = EXIT_SUCCESS;
+ int32_t frameSize = (width * height * 3) / 2;
+ int32_t numInputFrames = 0;
+ int32_t numNalEncoded = 0;
+ bool readyForNextFrame = true;
+
+ while (1) {
+ if (readyForNextFrame == true) {
+ // Read the input frame.
+ int32_t bytesRead;
+ bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+ if (bytesRead != frameSize) {
+ break; // End of file.
+ }
+
+ // Set the input frame.
+ AVCFrameIO vin;
+ memset(&vin, 0, sizeof(vin));
+ vin.height = ((height + 15) >> 4) << 4;
+ vin.pitch = ((width + 15) >> 4) << 4;
+ vin.coding_timestamp = (numInputFrames * 1000) / frameRate; // in ms
+ vin.YCbCr[0] = inputBuf;
+ vin.YCbCr[1] = vin.YCbCr[0] + vin.height * vin.pitch;
+ vin.YCbCr[2] = vin.YCbCr[1] + ((vin.height * vin.pitch) >> 2);
+ vin.disp_order = numInputFrames;
+
+ status = PVAVCEncSetInput(&handle, &vin);
+ if (status == AVCENC_SUCCESS || status == AVCENC_NEW_IDR) {
+ readyForNextFrame = false;
+ ++numInputFrames;
+ } else if (status < AVCENC_SUCCESS) {
+ fprintf(stderr, "Error %d while setting input frame\n", status);
+ retVal = EXIT_FAILURE;
+ break;
+ } else {
+ fprintf(stderr, "Frame drop\n");
+ readyForNextFrame = true;
+ ++numInputFrames;
+ continue;
+ }
+ }
+
+ // Encode the input frame.
+ dataLength = kOutputBufferSize;
+ status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+ if (status == AVCENC_SUCCESS) {
+ PVAVCEncGetOverrunBuffer(&handle);
+ } else if (status == AVCENC_PICTURE_READY) {
+ PVAVCEncGetOverrunBuffer(&handle);
+ readyForNextFrame = true;
+ AVCFrameIO recon;
+ if (PVAVCEncGetRecon(&handle, &recon) == AVCENC_SUCCESS) {
+ PVAVCEncReleaseRecon(&handle, &recon);
+ }
+ } else {
+ dataLength = 0;
+ readyForNextFrame = true;
+ }
+
+ if (status < AVCENC_SUCCESS) {
+ fprintf(stderr, "Error %d while encoding frame\n", status);
+ retVal = EXIT_FAILURE;
+ break;
+ }
+
+ numNalEncoded++;
+
+ // Write the output.
+ if (dataLength > 0) {
+ fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+ fwrite(outputBuf, 1, dataLength, fpOutput); // NAL.
+ printf("NAL %d of size %d written\n", numNalEncoded, dataLength + 4);
+ }
+ }
+
+ // Close input and output file.
+ fclose(fpInput);
+ fclose(fpOutput);
+
+ // Free allocated memory.
+ free(sliceGroup);
+ free(inputBuf);
+ free(outputBuf);
+ for (int i = 0; i < kMaxDpbBuffers; ++i) {
+ free(dpbBuffers[i]);
+ }
+
+ // Close encoder instance.
+ PVAVCCleanUpEncoder(&handle);
+
+ return retVal;
+}
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 26568ab..c627be4 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -637,6 +637,7 @@
for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
if (mConversionBuffers[i] != NULL) {
free(mConversionBuffers[i]);
+ mConversionBuffers[i] = 0;
}
if (((uint64_t)mStride * mHeight) > (((uint64_t)INT32_MAX / 3) * 2)) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.mk b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
index 7117692..762e6fe 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.mk
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
@@ -77,3 +77,23 @@
LOCAL_CFLAGS += -Werror
include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+ test/m4v_h263_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include
+
+LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF= -DBX_RC
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_m4vh263enc
+
+LOCAL_MODULE := libstagefright_m4vh263enc_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
new file mode 100644
index 0000000..db2c61a
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "mp4enc_api.h"
+
+// Constants.
+enum {
+ kMaxWidth = 720,
+ kMaxHeight = 480,
+ kMaxFrameRate = 30,
+ kMaxBitrate = 2048, // in kbps.
+ kOutputBufferSize = 250 * 1024,
+ kIDRFrameRefreshIntervalInSec = 1, // in seconds.
+};
+
+int main(int argc, char *argv[]) {
+
+ if (argc < 8) {
+ fprintf(stderr, "Usage %s <input yuv> <output file> <mode> <width> "
+ "<height> <frame rate> <bitrate in kbps>\n", argv[0]);
+ fprintf(stderr, "mode : h263 or mpeg4\n");
+ fprintf(stderr, "Max width %d\n", kMaxWidth);
+ fprintf(stderr, "Max height %d\n", kMaxHeight);
+ fprintf(stderr, "Max framerate %d\n", kMaxFrameRate);
+ fprintf(stderr, "Max bitrate %d kbps\n", kMaxBitrate);
+ return EXIT_FAILURE;
+ }
+
+ // Read mode.
+ bool isH263mode;
+ if (strcmp(argv[3], "mpeg4") == 0) {
+ isH263mode = false;
+ } else if (strcmp(argv[3], "h263") == 0) {
+ isH263mode = true;
+ } else {
+ fprintf(stderr, "Unsupported mode %s\n", argv[3]);
+ return EXIT_FAILURE;
+ }
+
+ // Read height and width.
+ int32_t width;
+ int32_t height;
+ width = atoi(argv[4]);
+ height = atoi(argv[5]);
+ if (width > kMaxWidth || height > kMaxHeight || width <= 0 || height <= 0) {
+ fprintf(stderr, "Unsupported dimensions %dx%d\n", width, height);
+ return EXIT_FAILURE;
+ }
+
+ if (width % 16 != 0 || height % 16 != 0) {
+ fprintf(stderr, "Video frame size %dx%d must be a multiple of 16\n",
+ width, height);
+ return EXIT_FAILURE;
+ }
+
+ // Read frame rate.
+ int32_t frameRate;
+ frameRate = atoi(argv[6]);
+ if (frameRate > kMaxFrameRate || frameRate <= 0) {
+ fprintf(stderr, "Unsupported frame rate %d\n", frameRate);
+ return EXIT_FAILURE;
+ }
+
+ // Read bitrate.
+ int32_t bitrate;
+ bitrate = atoi(argv[7]);
+ if (bitrate > kMaxBitrate || bitrate <= 0) {
+ fprintf(stderr, "Unsupported bitrate %d\n", bitrate);
+ return EXIT_FAILURE;
+ }
+
+ // Allocate input buffer.
+ uint8_t *inputBuf = (uint8_t *)malloc((width * height * 3) / 2);
+ assert(inputBuf != NULL);
+
+ // Allocate output buffer.
+ uint8_t *outputBuf = (uint8_t *)malloc(kOutputBufferSize);
+ assert(outputBuf != NULL);
+
+ // Open the input file.
+ FILE *fpInput = fopen(argv[1], "rb");
+ if (fpInput == NULL) {
+ fprintf(stderr, "Could not open %s\n", argv[1]);
+ free(inputBuf);
+ free(outputBuf);
+ return EXIT_FAILURE;
+ }
+
+ // Open the output file.
+ FILE *fpOutput = fopen(argv[2], "wb");
+ if (fpOutput == NULL) {
+ fprintf(stderr, "Could not open %s\n", argv[2]);
+ free(inputBuf);
+ free(outputBuf);
+ fclose(fpInput);
+ return EXIT_FAILURE;
+ }
+
+ // Initialize the encoder parameters.
+ tagvideoEncOptions encParams;
+ memset(&encParams, 0, sizeof(tagvideoEncOptions));
+ if (!PVGetDefaultEncOption(&encParams, 0)) {
+ fprintf(stderr, "Failed to get default encoding parameters\n");
+ free(inputBuf);
+ free(outputBuf);
+ fclose(fpInput);
+ fclose(fpOutput);
+ return EXIT_FAILURE;
+ }
+
+ if (isH263mode == false) {
+ encParams.encMode = COMBINE_MODE_WITH_ERR_RES;
+ } else {
+ encParams.encMode = H263_MODE;
+ }
+ encParams.encWidth[0] = width;
+ encParams.encHeight[0] = height;
+ encParams.encFrameRate[0] = frameRate;
+ encParams.rcType = VBR_1;
+ encParams.vbvDelay = 5.0f;
+ encParams.profile_level = CORE_PROFILE_LEVEL2;
+ encParams.packetSize = 32;
+ encParams.rvlcEnable = PV_OFF;
+ encParams.numLayers = 1;
+ encParams.timeIncRes = 1000;
+ encParams.tickPerSrc = encParams.timeIncRes / frameRate;
+
+ encParams.bitRate[0] = bitrate * 1024;
+ encParams.iQuant[0] = 15;
+ encParams.pQuant[0] = 12;
+ encParams.quantType[0] = 0;
+ encParams.noFrameSkipped = PV_OFF;
+
+ int32_t IDRFrameRefreshIntervalInSec = kIDRFrameRefreshIntervalInSec;
+ if (IDRFrameRefreshIntervalInSec == 0) {
+ encParams.intraPeriod = 1; // All I frames.
+ } else {
+ encParams.intraPeriod = (IDRFrameRefreshIntervalInSec * frameRate);
+ }
+
+ encParams.numIntraMB = 0;
+ encParams.sceneDetect = PV_ON;
+ encParams.searchRange = 16;
+ encParams.mv8x8Enable = PV_OFF;
+ encParams.gobHeaderInterval = 0;
+ encParams.useACPred = PV_ON;
+ encParams.intraDCVlcTh = 0;
+
+ // Initialize the handle.
+ tagvideoEncControls handle;
+ memset(&handle, 0, sizeof(tagvideoEncControls));
+
+ // Initialize the encoder.
+ if (!PVInitVideoEncoder(&handle, &encParams)) {
+ fprintf(stderr, "Failed to initialize the encoder\n");
+ return EXIT_FAILURE;
+ }
+
+ // Generate the header.
+ int32_t headerLength = kOutputBufferSize;
+ if (!PVGetVolHeader(&handle, outputBuf, &headerLength, 0)) {
+ fprintf(stderr, "Failed to get VOL header\n");
+ return EXIT_FAILURE;
+ }
+ fwrite(outputBuf, 1, headerLength, fpOutput);
+
+ // Core loop.
+ int32_t retVal = EXIT_SUCCESS;
+ int32_t frameSize = (width * height * 3) / 2;
+ int32_t numFramesEncoded = 0;
+
+ while (1) {
+ // Read the input frame.
+ int32_t bytesRead;
+ bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+ if (bytesRead != frameSize) {
+ break; // End of file.
+ }
+
+ // Encode the input frame.
+ VideoEncFrameIO vin, vout;
+ memset(&vin, 0, sizeof(vin));
+ memset(&vout, 0, sizeof(vout));
+ vin.height = height; // height is multiple of 16.
+ vin.pitch = width; // width is multiple of 16.
+ vin.timestamp = (numFramesEncoded * 1000) / frameRate; // in ms.
+ vin.yChan = inputBuf;
+ vin.uChan = vin.yChan + vin.height * vin.pitch;
+ vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
+
+ uint32_t modTimeMs = 0;
+ int32_t nLayer = 0;
+ MP4HintTrack hintTrack;
+ int32_t dataLength = kOutputBufferSize;
+ if (!PVEncodeVideoFrame(&handle, &vin, &vout,
+ &modTimeMs, outputBuf, &dataLength, &nLayer) ||
+ !PVGetHintTrack(&handle, &hintTrack)) {
+ fprintf(stderr, "Failed to encode frame or get hink track at "
+ " frame %d\n", numFramesEncoded);
+ retVal = EXIT_FAILURE;
+ break;
+ }
+ PVGetOverrunBuffer(&handle);
+ numFramesEncoded++;
+
+ // Write the output.
+ fwrite(outputBuf, 1, dataLength, fpOutput);
+ }
+
+ // Close input and output file.
+ fclose(fpInput);
+ fclose(fpOutput);
+
+ // Free allocated memory.
+ free(inputBuf);
+ free(outputBuf);
+
+ // Close encoder instance.
+ PVCleanUpVideoEncoder(&handle);
+ return retVal;
+}
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 948ae29..e611f68 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -83,3 +83,25 @@
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+ test/mp3dec_test.cpp \
+ test/mp3reader.cpp
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/test/include \
+ $(call include-path-for, audio-utils)
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_mp3dec libsndfile
+
+LOCAL_SHARED_LIBRARIES := libaudioutils
+
+LOCAL_MODULE := libstagefright_mp3dec_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp b/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp
new file mode 100644
index 0000000..26d62f3
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "pvmp3decoder_api.h"
+#include "mp3reader.h"
+#include <audio_utils/sndfile.h>
+
+using namespace std;
+
+enum {
+ kInputBufferSize = 10 * 1024,
+ kOutputBufferSize = 4608 * 2,
+};
+
+int main(int argc, const char **argv) {
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ // Initialize the config.
+ tPVMP3DecoderExternal config;
+ config.equalizerType = flat;
+ config.crcEnabled = false;
+
+ // Allocate the decoder memory.
+ uint32_t memRequirements = pvmp3_decoderMemRequirements();
+ void *decoderBuf = malloc(memRequirements);
+ assert(decoderBuf != NULL);
+
+ // Initialize the decoder.
+ pvmp3_InitDecoder(&config, decoderBuf);
+
+ // Open the input file.
+ Mp3Reader mp3Reader;
+ bool success = mp3Reader.init(argv[1]);
+ if (!success) {
+ fprintf(stderr, "Encountered error reading %s\n", argv[1]);
+ free(decoderBuf);
+ return EXIT_FAILURE;
+ }
+
+ // Open the output file.
+ SF_INFO sfInfo;
+ memset(&sfInfo, 0, sizeof(SF_INFO));
+ sfInfo.channels = mp3Reader.getNumChannels();
+ sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ sfInfo.samplerate = mp3Reader.getSampleRate();
+ SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
+ if (handle == NULL) {
+ fprintf(stderr, "Encountered error writing %s\n", argv[2]);
+ mp3Reader.close();
+ free(decoderBuf);
+ return EXIT_FAILURE;
+ }
+
+ // Allocate input buffer.
+ uint8_t *inputBuf = static_cast<uint8_t*>(malloc(kInputBufferSize));
+ assert(inputBuf != NULL);
+
+ // Allocate output buffer.
+ int16_t *outputBuf = static_cast<int16_t*>(malloc(kOutputBufferSize));
+ assert(outputBuf != NULL);
+
+ // Decode loop.
+ int retVal = EXIT_SUCCESS;
+ while (1) {
+ // Read input from the file.
+ uint32_t bytesRead;
+ bool success = mp3Reader.getFrame(inputBuf, &bytesRead);
+ if (!success) break;
+
+ // Set the input config.
+ config.inputBufferCurrentLength = bytesRead;
+ config.inputBufferMaxLength = 0;
+ config.inputBufferUsedLength = 0;
+ config.pInputBuffer = inputBuf;
+ config.pOutputBuffer = outputBuf;
+ config.outputFrameSize = kOutputBufferSize / sizeof(int16_t);
+
+ ERROR_CODE decoderErr;
+ decoderErr = pvmp3_framedecoder(&config, decoderBuf);
+ if (decoderErr != NO_DECODING_ERROR) {
+ fprintf(stderr, "Decoder encountered error\n");
+ retVal = EXIT_FAILURE;
+ break;
+ }
+ sf_writef_short(handle, outputBuf,
+ config.outputFrameSize / sfInfo.channels);
+ }
+
+ // Close input reader and output writer.
+ mp3Reader.close();
+ sf_close(handle);
+
+ // Free allocated memory.
+ free(inputBuf);
+ free(outputBuf);
+ free(decoderBuf);
+
+ return retVal;
+}
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp b/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp
new file mode 100644
index 0000000..b3138ec
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include "mp3reader.h"
+
+static uint32_t U32_AT(const uint8_t *ptr) {
+ return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
+}
+
+static bool parseHeader(
+ uint32_t header, size_t *frame_size,
+ uint32_t *out_sampling_rate = NULL, uint32_t *out_channels = NULL ,
+ uint32_t *out_bitrate = NULL, uint32_t *out_num_samples = NULL) {
+ *frame_size = 0;
+
+ if (out_sampling_rate) {
+ *out_sampling_rate = 0;
+ }
+
+ if (out_channels) {
+ *out_channels = 0;
+ }
+
+ if (out_bitrate) {
+ *out_bitrate = 0;
+ }
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+
+ if ((header & 0xffe00000) != 0xffe00000) {
+ return false;
+ }
+
+ unsigned version = (header >> 19) & 3;
+
+ if (version == 0x01) {
+ return false;
+ }
+
+ unsigned layer = (header >> 17) & 3;
+
+ if (layer == 0x00) {
+ return false;
+ }
+
+ unsigned bitrate_index = (header >> 12) & 0x0f;
+
+ if (bitrate_index == 0 || bitrate_index == 0x0f) {
+ // Disallow "free" bitrate.
+ return false;
+ }
+
+ unsigned sampling_rate_index = (header >> 10) & 3;
+
+ if (sampling_rate_index == 3) {
+ return false;
+ }
+
+ static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
+ int sampling_rate = kSamplingRateV1[sampling_rate_index];
+ if (version == 2 /* V2 */) {
+ sampling_rate /= 2;
+ } else if (version == 0 /* V2.5 */) {
+ sampling_rate /= 4;
+ }
+
+ unsigned padding = (header >> 9) & 1;
+
+ if (layer == 3) {
+ // layer I
+
+ static const int kBitrateV1[] = {
+ 32, 64, 96, 128, 160, 192, 224, 256,
+ 288, 320, 352, 384, 416, 448
+ };
+
+ static const int kBitrateV2[] = {
+ 32, 48, 56, 64, 80, 96, 112, 128,
+ 144, 160, 176, 192, 224, 256
+ };
+
+ int bitrate =
+ (version == 3 /* V1 */)
+ ? kBitrateV1[bitrate_index - 1]
+ : kBitrateV2[bitrate_index - 1];
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+
+ *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+
+ if (out_num_samples) {
+ *out_num_samples = 384;
+ }
+ } else {
+ // layer II or III
+
+ static const int kBitrateV1L2[] = {
+ 32, 48, 56, 64, 80, 96, 112, 128,
+ 160, 192, 224, 256, 320, 384
+ };
+
+ static const int kBitrateV1L3[] = {
+ 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320
+ };
+
+ static const int kBitrateV2[] = {
+ 8, 16, 24, 32, 40, 48, 56, 64,
+ 80, 96, 112, 128, 144, 160
+ };
+
+ int bitrate;
+ if (version == 3 /* V1 */) {
+ bitrate = (layer == 2 /* L2 */)
+ ? kBitrateV1L2[bitrate_index - 1]
+ : kBitrateV1L3[bitrate_index - 1];
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+ } else {
+ // V2 (or 2.5)
+
+ bitrate = kBitrateV2[bitrate_index - 1];
+ if (out_num_samples) {
+ *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
+ }
+ }
+
+ if (out_bitrate) {
+ *out_bitrate = bitrate;
+ }
+
+ if (version == 3 /* V1 */) {
+ *frame_size = 144000 * bitrate / sampling_rate + padding;
+ } else {
+ // V2 or V2.5
+ size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
+ *frame_size = tmp * bitrate / sampling_rate + padding;
+ }
+ }
+
+ if (out_sampling_rate) {
+ *out_sampling_rate = sampling_rate;
+ }
+
+ if (out_channels) {
+ int channel_mode = (header >> 6) & 3;
+
+ *out_channels = (channel_mode == 3) ? 1 : 2;
+ }
+
+ return true;
+}
+
+// Mask to extract the version, layer, sampling rate parts of the MP3 header,
+// which should be same for all MP3 frames.
+static const uint32_t kMask = 0xfffe0c00;
+
+static ssize_t sourceReadAt(FILE *fp, off64_t offset, void *data, size_t size) {
+ int retVal = fseek(fp, offset, SEEK_SET);
+ if (retVal != EXIT_SUCCESS) {
+ return 0;
+ } else {
+ return fread(data, 1, size, fp);
+ }
+}
+
+// Resync to next valid MP3 frame in the file.
+static bool resync(
+ FILE *fp, uint32_t match_header,
+ off64_t *inout_pos, uint32_t *out_header) {
+
+ if (*inout_pos == 0) {
+ // Skip an optional ID3 header if syncing at the very beginning
+ // of the datasource.
+
+ for (;;) {
+ uint8_t id3header[10];
+ int retVal = sourceReadAt(fp, *inout_pos, id3header,
+ sizeof(id3header));
+ if (retVal < (ssize_t)sizeof(id3header)) {
+ // If we can't even read these 10 bytes, we might as well bail
+ // out, even if there _were_ 10 bytes of valid mp3 audio data...
+ return false;
+ }
+
+ if (memcmp("ID3", id3header, 3)) {
+ break;
+ }
+
+ // Skip the ID3v2 header.
+
+ size_t len =
+ ((id3header[6] & 0x7f) << 21)
+ | ((id3header[7] & 0x7f) << 14)
+ | ((id3header[8] & 0x7f) << 7)
+ | (id3header[9] & 0x7f);
+
+ len += 10;
+
+ *inout_pos += len;
+ }
+
+ }
+
+ off64_t pos = *inout_pos;
+ bool valid = false;
+
+ const int32_t kMaxReadBytes = 1024;
+ const int32_t kMaxBytesChecked = 128 * 1024;
+ uint8_t buf[kMaxReadBytes];
+ ssize_t bytesToRead = kMaxReadBytes;
+ ssize_t totalBytesRead = 0;
+ ssize_t remainingBytes = 0;
+ bool reachEOS = false;
+ uint8_t *tmp = buf;
+
+ do {
+ if (pos >= *inout_pos + kMaxBytesChecked) {
+ // Don't scan forever.
+ break;
+ }
+
+ if (remainingBytes < 4) {
+ if (reachEOS) {
+ break;
+ } else {
+ memcpy(buf, tmp, remainingBytes);
+ bytesToRead = kMaxReadBytes - remainingBytes;
+
+ /*
+ * The next read position should start from the end of
+ * the last buffer, and thus should include the remaining
+ * bytes in the buffer.
+ */
+ totalBytesRead = sourceReadAt(fp, pos + remainingBytes,
+ buf + remainingBytes, bytesToRead);
+
+ if (totalBytesRead <= 0) {
+ break;
+ }
+ reachEOS = (totalBytesRead != bytesToRead);
+ remainingBytes += totalBytesRead;
+ tmp = buf;
+ continue;
+ }
+ }
+
+ uint32_t header = U32_AT(tmp);
+
+ if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
+ ++pos;
+ ++tmp;
+ --remainingBytes;
+ continue;
+ }
+
+ size_t frame_size;
+ uint32_t sample_rate, num_channels, bitrate;
+ if (!parseHeader(
+ header, &frame_size,
+ &sample_rate, &num_channels, &bitrate)) {
+ ++pos;
+ ++tmp;
+ --remainingBytes;
+ continue;
+ }
+
+ // We found what looks like a valid frame,
+ // now find its successors.
+
+ off64_t test_pos = pos + frame_size;
+
+ valid = true;
+ const int FRAME_MATCH_REQUIRED = 3;
+ for (int j = 0; j < FRAME_MATCH_REQUIRED; ++j) {
+ uint8_t tmp[4];
+ ssize_t retval = sourceReadAt(fp, test_pos, tmp, sizeof(tmp));
+ if (retval < (ssize_t)sizeof(tmp)) {
+ valid = false;
+ break;
+ }
+
+ uint32_t test_header = U32_AT(tmp);
+
+ if ((test_header & kMask) != (header & kMask)) {
+ valid = false;
+ break;
+ }
+
+ size_t test_frame_size;
+ if (!parseHeader(test_header, &test_frame_size)) {
+ valid = false;
+ break;
+ }
+
+ test_pos += test_frame_size;
+ }
+
+ if (valid) {
+ *inout_pos = pos;
+
+ if (out_header != NULL) {
+ *out_header = header;
+ }
+ }
+
+ ++pos;
+ ++tmp;
+ --remainingBytes;
+ } while (!valid);
+
+ return valid;
+}
+
+Mp3Reader::Mp3Reader() : mFp(NULL) {
+}
+
+// Initialize the MP3 reader.
+bool Mp3Reader::init(const char *file) {
+
+ // Open the file.
+ mFp = fopen(file, "rb");
+ if (mFp == NULL) return false;
+
+ // Sync to the first valid frame.
+ off64_t pos = 0;
+ uint32_t header;
+ bool success = resync(mFp, 0 /*match_header*/, &pos, &header);
+ if (success == false) return false;
+
+ mCurrentPos = pos;
+ mFixedHeader = header;
+
+ size_t frame_size;
+ return parseHeader(header, &frame_size, &mSampleRate,
+ &mNumChannels, &mBitrate);
+}
+
+// Get the next valid MP3 frame.
+bool Mp3Reader::getFrame(void *buffer, uint32_t *size) {
+
+ size_t frame_size;
+ uint32_t bitrate;
+ uint32_t num_samples;
+ uint32_t sample_rate;
+ for (;;) {
+ ssize_t n = sourceReadAt(mFp, mCurrentPos, buffer, 4);
+ if (n < 4) {
+ return false;
+ }
+
+ uint32_t header = U32_AT((const uint8_t *)buffer);
+
+ if ((header & kMask) == (mFixedHeader & kMask)
+ && parseHeader(
+ header, &frame_size, &sample_rate, NULL /*out_channels*/,
+ &bitrate, &num_samples)) {
+ break;
+ }
+
+ // Lost sync.
+ off64_t pos = mCurrentPos;
+ if (!resync(mFp, mFixedHeader, &pos, NULL /*out_header*/)) {
+ // Unable to resync. Signalling end of stream.
+ return false;
+ }
+
+ mCurrentPos = pos;
+
+ // Try again with the new position.
+ }
+ ssize_t n = sourceReadAt(mFp, mCurrentPos, buffer, frame_size);
+ if (n < (ssize_t)frame_size) {
+ return false;
+ }
+
+ *size = frame_size;
+ mCurrentPos += frame_size;
+ return true;
+}
+
+// Close the MP3 reader.
+void Mp3Reader::close() {
+ assert(mFp != NULL);
+ fclose(mFp);
+}
+
+Mp3Reader::~Mp3Reader() {
+}
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.h b/media/libstagefright/codecs/mp3dec/test/mp3reader.h
new file mode 100644
index 0000000..871f664
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3reader.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MP3READER_H_
+#define MP3READER_H_
+
+class Mp3Reader {
+public:
+ Mp3Reader();
+ bool init(const char *file);
+ bool getFrame(void *buffer, uint32_t *size);
+ uint32_t getSampleRate() { return mSampleRate;}
+ uint32_t getNumChannels() { return mNumChannels;}
+ void close();
+ ~Mp3Reader();
+private:
+ FILE *mFp;
+ uint32_t mFixedHeader;
+ off64_t mCurrentPos;
+ uint32_t mSampleRate;
+ uint32_t mNumChannels;
+ uint32_t mBitrate;
+};
+
+
+#endif /* MP3READER_H_ */
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index e161fb8..cd6c3b1 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -102,7 +102,6 @@
}
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;
@@ -193,7 +192,6 @@
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 +215,6 @@
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/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 @@
/* 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 @@
#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 @@
/* 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 @@
#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/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 855ffdc..5620cf8 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -898,11 +898,6 @@
if (!strncmp(value.c_str(), "Basic", 5)) {
mAuthType = BASIC;
} else {
-#if !defined(HAVE_ANDROID_OS)
- // We don't have access to the MD5 implementation on the simulator,
- // so we won't support digest authentication.
- return false;
-#endif
CHECK(!strncmp(value.c_str(), "Digest", 6));
mAuthType = DIGEST;
@@ -919,7 +914,6 @@
return true;
}
-#if defined(HAVE_ANDROID_OS)
static void H(const AString &s, AString *out) {
out->clear();
@@ -948,7 +942,6 @@
out->append(&nibble, 1);
}
}
-#endif
static void GetMethodAndURL(
const AString &request, AString *method, AString *url) {
@@ -990,7 +983,6 @@
return;
}
-#if defined(HAVE_ANDROID_OS)
CHECK_EQ((int)mAuthType, (int)DIGEST);
AString method, url;
@@ -1039,7 +1031,6 @@
fragment.append("\r\n");
request->insert(fragment, i + 2);
-#endif
}
void ARTSPConnection::addUserAgent(AString *request) const {
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 07199e3..3e0f239 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -214,10 +214,11 @@
mResponse.setTransactionID(transaction);
ALOGV("sending response %04X", mResponse.getResponseCode());
ret = mResponse.write(fd);
+ const int savedErrno = errno;
mResponse.dump();
if (ret < 0) {
ALOGE("request write returned %d, errno: %d", ret, errno);
- if (errno == ECANCELED) {
+ if (savedErrno == ECANCELED) {
// return to top of loop and wait for next command
continue;
}
@@ -787,15 +788,19 @@
// then transfer the file
int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
+ if (ret < 0) {
+ if (errno == ECANCELED) {
+ result = MTP_RESPONSE_TRANSACTION_CANCELLED;
+ } else {
+ result = MTP_RESPONSE_GENERAL_ERROR;
+ }
+ } else {
+ result = MTP_RESPONSE_OK;
+ }
+
ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
close(mfr.fd);
- if (ret < 0) {
- if (errno == ECANCELED)
- return MTP_RESPONSE_TRANSACTION_CANCELLED;
- else
- return MTP_RESPONSE_GENERAL_ERROR;
- }
- return MTP_RESPONSE_OK;
+ return result;
}
MtpResponseCode MtpServer::doGetThumb() {
@@ -864,14 +869,15 @@
// transfer the file
int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
- close(mfr.fd);
+ result = MTP_RESPONSE_OK;
if (ret < 0) {
if (errno == ECANCELED)
- return MTP_RESPONSE_TRANSACTION_CANCELLED;
+ result = MTP_RESPONSE_TRANSACTION_CANCELLED;
else
- return MTP_RESPONSE_GENERAL_ERROR;
+ result = MTP_RESPONSE_GENERAL_ERROR;
}
- return MTP_RESPONSE_OK;
+ close(mfr.fd);
+ return result;
}
MtpResponseCode MtpServer::doSendObjectInfo() {
@@ -985,6 +991,7 @@
MtpResponseCode result = MTP_RESPONSE_OK;
mode_t mask;
int ret, initialData;
+ bool isCanceled = false;
if (mSendObjectHandle == kInvalidObjectHandle) {
ALOGE("Expected SendObjectInfo before SendObject");
@@ -1032,6 +1039,10 @@
ALOGV("receiving %s\n", (const char *)mSendObjectFilePath);
// transfer the file
ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+ if ((ret < 0) && (errno == ECANCELED)) {
+ isCanceled = true;
+ }
+
ALOGV("MTP_RECEIVE_FILE returned %d\n", ret);
}
}
@@ -1039,7 +1050,7 @@
if (ret < 0) {
unlink(mSendObjectFilePath);
- if (errno == ECANCELED)
+ if (isCanceled)
result = MTP_RESPONSE_TRANSACTION_CANCELLED;
else
result = MTP_RESPONSE_GENERAL_ERROR;
@@ -1208,6 +1219,7 @@
length -= initialData;
}
+ bool isCanceled = false;
if (ret < 0) {
ALOGE("failed to write initial data");
} else {
@@ -1219,12 +1231,15 @@
// transfer the file
ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+ if ((ret < 0) && (errno == ECANCELED)) {
+ isCanceled = true;
+ }
ALOGV("MTP_RECEIVE_FILE returned %d", ret);
}
}
if (ret < 0) {
mResponse.setParameter(1, 0);
- if (errno == ECANCELED)
+ if (isCanceled)
return MTP_RESPONSE_TRANSACTION_CANCELLED;
else
return MTP_RESPONSE_GENERAL_ERROR;