Merge "aaudio: Update language to comply with Android's inclusive language guidance"
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
index cb69f91..466e571 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
@@ -62,8 +62,8 @@
}
ALOGV("descriptor_size=%zu", container.descriptor_size());
- // Sanity check to verify that the BroadcastEncryptor is sending a properly
- // formed EcmContainer. If it contains two Ecms, the ids should have different
+ // Validate that the BroadcastEncryptor is sending a properly formed
+ // EcmContainer. If it contains two Ecms, the ids should have different
// parity (one odd, one even). This does not necessarily affect decryption
// but indicates a problem with Ecm generation.
if (container.descriptor_size() == 2) {
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 0773387..2599c2c 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -546,11 +546,11 @@
continue;
}
ALOGV("Image item id %d uses thumbnail item id %d", mRefs[i], mItemId);
- ImageItem &masterImage = itemIdToItemMap.editValueAt(itemIndex);
- if (!masterImage.thumbnails.empty()) {
+ ImageItem &imageItem = itemIdToItemMap.editValueAt(itemIndex);
+ if (!imageItem.thumbnails.empty()) {
ALOGW("already has thumbnails!");
}
- masterImage.thumbnails.push_back(mItemId);
+ imageItem.thumbnails.push_back(mItemId);
}
break;
}
@@ -929,7 +929,7 @@
status_t IpcoBox::parse(off64_t offset, size_t size) {
ALOGV("%s: offset %lld, size %zu", __FUNCTION__, (long long)offset, size);
- // push dummy as the index is 1-based
+ // push a placeholder as the index is 1-based
mItemProperties->push_back(new ItemProperty());
return parseChunks(offset, size);
}
@@ -1614,17 +1614,17 @@
return BAD_VALUE;
}
- uint32_t masterItemIndex = mDisplayables[imageIndex];
+ uint32_t imageItemIndex = mDisplayables[imageIndex];
- const ImageItem &masterImage = mItemIdToItemMap[masterItemIndex];
- if (masterImage.thumbnails.empty()) {
- *itemIndex = masterItemIndex;
+ const ImageItem &imageItem = mItemIdToItemMap[imageItemIndex];
+ if (imageItem.thumbnails.empty()) {
+ *itemIndex = imageItemIndex;
return OK;
}
- ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(masterImage.thumbnails[0]);
+ ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(imageItem.thumbnails[0]);
if (thumbItemIndex < 0) {
- // Do not return the master image in this case, fail it so that the
+ // Do not return the image item in this case, fail it so that the
// thumbnail extraction code knows we really don't have it.
return INVALID_OPERATION;
}
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 2d92f75..342b128 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1069,7 +1069,7 @@
} else if (chunk_type == FOURCC("moov")) {
mInitCheck = OK;
- return UNKNOWN_ERROR; // Return a dummy error.
+ return UNKNOWN_ERROR; // Return a generic error.
}
break;
}
@@ -5515,7 +5515,7 @@
return -EINVAL;
}
- // apply some sanity (vs strict legality) checks
+ // apply some quick (vs strict legality) checks
//
static constexpr uint32_t kMaxTrunSampleCount = 10000;
if (sampleCount > kMaxTrunSampleCount) {
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 3d0d622..e42a8cd 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -1022,7 +1022,7 @@
}
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
- // sanity-check. user is most-likely passing an error code, and it would
+ // Validation. user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
__func__, mPortId, buffer, userSize, userSize);
@@ -1249,7 +1249,7 @@
mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
size_t readSize = audioBuffer.size;
- // Sanity check on returned size
+ // Validate on returned size
if (ssize_t(readSize) < 0 || readSize > reqSize) {
ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
__func__, mPortId, reqSize, ssize_t(readSize));
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 9a66d48..afb44f3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1796,7 +1796,7 @@
}
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
- // Sanity-check: user is most-likely passing an error code, and it would
+ // Validation: user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
ALOGE("%s(%d): AudioTrack::write(buffer=%p, size=%zu (%zd)",
__func__, mPortId, buffer, userSize, userSize);
@@ -2186,7 +2186,7 @@
mUserData, &audioBuffer);
size_t writtenSize = audioBuffer.size;
- // Sanity check on returned size
+ // Validate on returned size
if (ssize_t(writtenSize) < 0 || writtenSize > reqSize) {
ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
__func__, mPortId, reqSize, ssize_t(writtenSize));
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 53d46f1..5879a93 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -998,7 +998,7 @@
break;
}
- // Whitelist of relevant events to trigger log merging.
+ // List of relevant events that trigger log merging.
// Log merging should activate during audio activity of any kind. This are considered the
// most relevant events.
// TODO should select more wisely the items from the list
diff --git a/media/libaudioprocessing/AudioResamplerDyn.cpp b/media/libaudioprocessing/AudioResamplerDyn.cpp
index ec56b00..96d6104 100644
--- a/media/libaudioprocessing/AudioResamplerDyn.cpp
+++ b/media/libaudioprocessing/AudioResamplerDyn.cpp
@@ -636,7 +636,7 @@
const uint32_t phaseWrapLimit = c.mL << c.mShift;
size_t inFrameCount = (phaseIncrement * (uint64_t)outFrameCount + phaseFraction)
/ phaseWrapLimit;
- // sanity check that inFrameCount is in signed 32 bit integer range.
+ // validate that inFrameCount is in signed 32 bit integer range.
ALOG_ASSERT(0 <= inFrameCount && inFrameCount < (1U << 31));
//ALOGV("inFrameCount:%d outFrameCount:%d"
@@ -646,7 +646,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
// the following logic is a bit convoluted to keep the main processing loop
// as tight as possible with register allocation.
diff --git a/media/libaudioprocessing/AudioResamplerFirProcess.h b/media/libaudioprocessing/AudioResamplerFirProcess.h
index 9b70a1c..1fcffcc 100644
--- a/media/libaudioprocessing/AudioResamplerFirProcess.h
+++ b/media/libaudioprocessing/AudioResamplerFirProcess.h
@@ -381,7 +381,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
if (LOCKED) {
// locked polyphase (no interpolation)
diff --git a/media/libaudioprocessing/AudioResamplerSinc.cpp b/media/libaudioprocessing/AudioResamplerSinc.cpp
index 5a03a0d..f2c386d 100644
--- a/media/libaudioprocessing/AudioResamplerSinc.cpp
+++ b/media/libaudioprocessing/AudioResamplerSinc.cpp
@@ -404,7 +404,7 @@
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
// to generate far less efficient code.
- // Always sanity check the result with objdump or test-resample.
+ // Always validate the result with objdump or test-resample.
// compute the index of the coefficient on the positive side and
// negative side
diff --git a/media/libeffects/factory/EffectsConfigLoader.c b/media/libeffects/factory/EffectsConfigLoader.c
index fcef36f..e23530e 100644
--- a/media/libeffects/factory/EffectsConfigLoader.c
+++ b/media/libeffects/factory/EffectsConfigLoader.c
@@ -394,7 +394,7 @@
}
sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object;
effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object);
- // Since we return a dummy descriptor for the proxy during
+ // Since we return a stub descriptor for the proxy during
// get_descriptor call,we replace it with the correspoding
// sw effect descriptor, but with Proxy UUID
// check for Sw desc
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
index 505be7c..30a9007 100644
--- a/media/libeffects/factory/EffectsXmlConfigLoader.cpp
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -283,7 +283,7 @@
}
listPush(effectLoadResult.effectDesc.get(), subEffectList);
- // Since we return a dummy descriptor for the proxy during
+ // Since we return a stub descriptor for the proxy during
// get_descriptor call, we replace it with the corresponding
// sw effect descriptor, but keep the Proxy UUID
*effectLoadResult.effectDesc = *swEffectLoadResult.effectDesc;
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 2af1eeb..b27bac5 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -37,6 +37,7 @@
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
void Copy_Float_Stereo_Mc( const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames,
LVM_INT32 NrChannels);
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 7cb642f..3a50554 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -116,30 +116,31 @@
}
}
-// Merge a multichannel source with stereo contained in dst, to dst.
+// Merge a multichannel source with stereo contained in StereoOut, to dst.
void Copy_Float_Stereo_Mc(const LVM_FLOAT *src,
+ LVM_FLOAT *StereoOut,
LVM_FLOAT *dst,
LVM_INT16 NrFrames, /* Number of frames*/
LVM_INT32 NrChannels)
{
LVM_INT16 ii, jj;
- LVM_FLOAT *src_st = dst + 2 * (NrFrames - 1);
- // repack dst which carries stereo information
+ // pack dst with stereo information of StereoOut
// together with the upper channels of src.
+ StereoOut += 2 * (NrFrames - 1);
dst += NrChannels * (NrFrames - 1);
src += NrChannels * (NrFrames - 1);
for (ii = NrFrames; ii != 0; ii--)
{
- dst[1] = src_st[1];
- dst[0] = src_st[0]; // copy 1 before 0 is required for NrChannels == 3.
+ dst[1] = StereoOut[1];
+ dst[0] = StereoOut[0]; // copy 1 before 0 is required for NrChannels == 3.
for (jj = 2; jj < NrChannels; jj++)
{
dst[jj] = src[jj];
}
dst -= NrChannels;
src -= NrChannels;
- src_st -= 2;
+ StereoOut -= 2;
}
}
#endif
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index 620b341..154ea55 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -54,7 +54,11 @@
#define LVCS_COMPGAINFRAME 64 /* Compressor gain update interval */
/* Memory */
+#ifdef SUPPORT_MC
+#define LVCS_SCRATCHBUFFERS 8 /* Number of buffers required for inplace processing */
+#else
#define LVCS_SCRATCHBUFFERS 6 /* Number of buffers required for inplace processing */
+#endif
#ifdef SUPPORT_MC
/*
* The Concert Surround module applies processing only on the first two
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
index ded3bfa..8e09be2 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Process.cpp
@@ -104,7 +104,7 @@
* The Concert Surround module carries out processing only on L, R.
*/
pInput = pScratch + (2 * NrFrames);
- pStIn = pScratch + (LVCS_SCRATCHBUFFERS * NrFrames);
+ pStIn = pScratch + ((LVCS_SCRATCHBUFFERS - 2) * NrFrames);
/* The first two channel data is extracted from the input data and
* copied into pInput buffer
*/
@@ -232,13 +232,45 @@
*/
if (pInstance->Params.OperatingMode != LVCS_OFF)
{
+#ifdef SUPPORT_MC
+ LVM_FLOAT *pStereoOut;
+ /*
+ * LVCS_Process_CS uses output buffer to store intermediate outputs of StereoEnhancer,
+ * Equalizer, ReverbGenerator and BypassMixer.
+ * So, to avoid i/o data overlapping, when i/o buffers are common, use scratch buffer
+ * to store intermediate outputs.
+ */
+ if (pOutData == pInData)
+ {
+ /*
+ * Scratch memory is used in 4 chunks of (2 * NrFrames) size.
+ * First chunk of memory is used by LVCS_StereoEnhancer and LVCS_ReverbGenerator,
+ * second and fourth are used as input buffers by pInput and pStIn in LVCS_Process_CS.
+ * Hence, pStereoOut is pointed to use unused third portion of scratch memory.
+ */
+ pStereoOut = (LVM_FLOAT *) \
+ pInstance->MemoryTable. \
+ Region[LVCS_MEMREGION_TEMPORARY_FAST].pBaseAddress +
+ ((LVCS_SCRATCHBUFFERS - 4) * NrFrames);
+ }
+ else
+ {
+ pStereoOut = pOutData;
+ }
+
/*
* Call CS process function
*/
err = LVCS_Process_CS(hInstance,
pInData,
+ pStereoOut,
+ NrFrames);
+#else
+ err = LVCS_Process_CS(hInstance,
+ pInData,
pOutData,
NumSamples);
+#endif
/*
* Compress to reduce expansion effect of Concert Sound and correct volume
@@ -257,10 +289,17 @@
if(NumSamples < LVCS_COMPGAINFRAME)
{
+#ifdef SUPPORT_MC
+ NonLinComp_Float(Gain, /* Compressor gain setting */
+ pStereoOut,
+ pStereoOut,
+ (LVM_INT32)(2 * NrFrames));
+#else
NonLinComp_Float(Gain, /* Compressor gain setting */
pOutData,
pOutData,
(LVM_INT32)(2 * NumSamples));
+#endif
}
else
{
@@ -289,7 +328,11 @@
FinalGain = Gain;
Gain = pInstance->CompressGain;
+#ifdef SUPPORT_MC
+ pOutPtr = pStereoOut;
+#else
pOutPtr = pOutData;
+#endif
while(SampleToProcess > 0)
{
@@ -355,6 +398,7 @@
}
#ifdef SUPPORT_MC
Copy_Float_Stereo_Mc(pInData,
+ pStereoOut,
pOutData,
NrFrames,
channels);
diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp
index 42e44f0..c010d68 100644
--- a/media/libeffects/proxy/EffectProxy.cpp
+++ b/media/libeffects/proxy/EffectProxy.cpp
@@ -30,7 +30,7 @@
#include <media/EffectsFactoryApi.h>
namespace android {
-// This is a dummy proxy descriptor just to return to Factory during the initial
+// This is a stub proxy descriptor just to return to Factory during the initial
// GetDescriptor call. Later in the factory, it is replaced with the
// SW sub effect descriptor
// proxy UUID af8da7e0-2ca1-11e3-b71d-0002a5d5c51b
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
new file mode 100644
index 0000000..5a52ea5
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_test {
+ name: "StagefrightRecorderTest",
+ gtest: true,
+
+ srcs: [
+ "StagefrightRecorderTest.cpp",
+ ],
+
+ include_dirs: [
+ "system/media/audio/include",
+ "frameworks/av/include",
+ "frameworks/av/camera/include",
+ "frameworks/av/media/libmediaplayerservice",
+ "frameworks/av/media/libmediametrics/include",
+ "frameworks/av/media/ndk/include",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmedia",
+ "libbinder",
+ "libutils",
+ "libmediaplayerservice",
+ "libstagefright",
+ "libmediandk",
+ ],
+
+ compile_multilib: "32",
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
new file mode 100644
index 0000000..ac17ef3
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/StagefrightRecorderTest.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "StagefrightRecorderTest"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <ctime>
+#include <iostream>
+#include <string>
+#include <thread>
+
+#include <MediaPlayerService.h>
+#include <media/NdkMediaExtractor.h>
+#include <media/stagefright/MediaCodec.h>
+#include <system/audio-base.h>
+
+#include "StagefrightRecorder.h"
+
+#define OUTPUT_INFO_FILE_NAME "/data/local/tmp/stfrecorder_audio.info"
+#define OUTPUT_FILE_NAME_AUDIO "/data/local/tmp/stfrecorder_audio.raw"
+
+const bool kDebug = false;
+constexpr int32_t kMaxLoopCount = 10;
+constexpr int32_t kClipDurationInSec = 4;
+constexpr int32_t kPauseTimeInSec = 2;
+// Tolerance value for extracted clipduration is maximum 10% of total clipduration
+constexpr int32_t kToleranceValueInUs = kClipDurationInSec * 100000;
+
+using namespace android;
+
+class StagefrightRecorderTest
+ : public ::testing::TestWithParam<std::pair<output_format, audio_encoder>> {
+ public:
+ StagefrightRecorderTest() : mStfRecorder(nullptr), mOutputAudioFp(nullptr) {
+ mExpectedDurationInMs = 0;
+ mExpectedPauseInMs = 0;
+ }
+
+ ~StagefrightRecorderTest() {
+ if (mStfRecorder) free(mStfRecorder);
+ if (mOutputAudioFp) fclose(mOutputAudioFp);
+ }
+
+ void SetUp() override {
+ mStfRecorder = new StagefrightRecorder(String16(LOG_TAG));
+ ASSERT_NE(mStfRecorder, nullptr) << "Failed to create the instance of recorder";
+
+ mOutputAudioFp = fopen(OUTPUT_FILE_NAME_AUDIO, "wb");
+ ASSERT_NE(mOutputAudioFp, nullptr) << "Failed to open output file "
+ << OUTPUT_FILE_NAME_AUDIO << " for stagefright recorder";
+
+ int32_t fd = fileno(mOutputAudioFp);
+ ASSERT_GE(fd, 0) << "Failed to get the file descriptor of the output file for "
+ << OUTPUT_FILE_NAME_AUDIO;
+
+ status_t status = mStfRecorder->setOutputFile(fd);
+ ASSERT_EQ(status, OK) << "Failed to set the output file " << OUTPUT_FILE_NAME_AUDIO
+ << " for stagefright recorder";
+ }
+
+ void TearDown() override {
+ if (mOutputAudioFp) {
+ fclose(mOutputAudioFp);
+ mOutputAudioFp = nullptr;
+ }
+ if (!kDebug) {
+ int32_t status = remove(OUTPUT_FILE_NAME_AUDIO);
+ ASSERT_EQ(status, 0) << "Unable to delete the output file " << OUTPUT_FILE_NAME_AUDIO;
+ }
+ }
+
+ void setAudioRecorderFormat(output_format outputFormat, audio_encoder encoder,
+ audio_source_t audioSource = AUDIO_SOURCE_DEFAULT);
+ void recordMedia(bool isPaused = false, int32_t numStart = 0, int32_t numPause = 0);
+ void dumpInfo();
+ void setupExtractor(AMediaExtractor *extractor, int32_t &trackCount);
+ void validateOutput();
+
+ MediaRecorderBase *mStfRecorder;
+ FILE *mOutputAudioFp;
+ double mExpectedDurationInMs;
+ double mExpectedPauseInMs;
+};
+
+void StagefrightRecorderTest::setAudioRecorderFormat(output_format outputFormat,
+ audio_encoder encoder,
+ audio_source_t audioSource) {
+ status_t status = mStfRecorder->setAudioSource(audioSource);
+ ASSERT_EQ(status, OK) << "Failed to set the audio source: " << audioSource;
+
+ status = mStfRecorder->setOutputFormat(outputFormat);
+ ASSERT_EQ(status, OK) << "Failed to set the output format: " << outputFormat;
+
+ status = mStfRecorder->setAudioEncoder(encoder);
+ ASSERT_EQ(status, OK) << "Failed to set the audio encoder: " << encoder;
+}
+
+void StagefrightRecorderTest::recordMedia(bool isPause, int32_t numStart, int32_t numPause) {
+ status_t status = mStfRecorder->init();
+ ASSERT_EQ(status, OK) << "Failed to initialize stagefright recorder";
+
+ status = mStfRecorder->prepare();
+ ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+ // first start should succeed.
+ status = mStfRecorder->start();
+ ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+ for (int32_t count = 0; count < numStart; count++) {
+ status = mStfRecorder->start();
+ }
+
+ auto tStart = std::chrono::high_resolution_clock::now();
+ // Recording media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+ auto tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedDurationInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+ if (isPause) {
+ // first pause should succeed.
+ status = mStfRecorder->pause();
+ ASSERT_EQ(status, OK) << "Failed to pause the recorder";
+
+ tStart = std::chrono::high_resolution_clock::now();
+ // Paused recorder for 2 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kPauseTimeInSec));
+
+ for (int32_t count = 0; count < numPause; count++) {
+ status = mStfRecorder->pause();
+ }
+
+ tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedPauseInMs = std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+
+ status = mStfRecorder->resume();
+ ASSERT_EQ(status, OK) << "Failed to resume the recorder";
+
+ auto tStart = std::chrono::high_resolution_clock::now();
+ // Recording media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+ auto tEnd = std::chrono::high_resolution_clock::now();
+ mExpectedDurationInMs += std::chrono::duration<double, std::milli>(tEnd - tStart).count();
+ }
+ status = mStfRecorder->stop();
+ ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+}
+
+void StagefrightRecorderTest::dumpInfo() {
+ FILE *dumpOutput = fopen(OUTPUT_INFO_FILE_NAME, "wb");
+ int32_t dumpFd = fileno(dumpOutput);
+ Vector<String16> args;
+ status_t status = mStfRecorder->dump(dumpFd, args);
+ ASSERT_EQ(status, OK) << "Failed to dump the info for the recorder";
+ fclose(dumpOutput);
+}
+
+void StagefrightRecorderTest::setupExtractor(AMediaExtractor *extractor, int32_t &trackCount) {
+ int32_t fd = open(OUTPUT_FILE_NAME_AUDIO, O_RDONLY);
+ ASSERT_GE(fd, 0) << "Failed to open recorder's output file " << OUTPUT_FILE_NAME_AUDIO
+ << " to validate";
+
+ struct stat buf;
+ int32_t status = fstat(fd, &buf);
+ ASSERT_EQ(status, 0) << "Failed to get properties of input file " << OUTPUT_FILE_NAME_AUDIO
+ << " for extractor";
+
+ size_t fileSize = buf.st_size;
+ ASSERT_GT(fileSize, 0) << "Size of input file " << OUTPUT_FILE_NAME_AUDIO
+ << " to extractor cannot be zero";
+ ALOGV("Size of input file to extractor: %zu", fileSize);
+
+ status = AMediaExtractor_setDataSourceFd(extractor, fd, 0, fileSize);
+ ASSERT_EQ(status, AMEDIA_OK) << "Failed to set data source for extractor";
+
+ trackCount = AMediaExtractor_getTrackCount(extractor);
+ ALOGV("Number of tracks reported by extractor : %d", trackCount);
+}
+
+// Validate recoder's output using extractor
+void StagefrightRecorderTest::validateOutput() {
+ int32_t trackCount = -1;
+ AMediaExtractor *extractor = AMediaExtractor_new();
+ ASSERT_NE(extractor, nullptr) << "Failed to create extractor";
+ ASSERT_NO_FATAL_FAILURE(setupExtractor(extractor, trackCount));
+ ASSERT_EQ(trackCount, 1) << "Expected 1 track, saw " << trackCount;
+
+ for (int32_t idx = 0; idx < trackCount; idx++) {
+ AMediaExtractor_selectTrack(extractor, idx);
+ AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, idx);
+ ASSERT_NE(format, nullptr) << "Track format is NULL";
+ ALOGI("Track format = %s", AMediaFormat_toString(format));
+
+ int64_t clipDurationUs;
+ AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &clipDurationUs);
+ int32_t diff = abs((mExpectedDurationInMs * 1000) - clipDurationUs);
+ ASSERT_LE(diff, kToleranceValueInUs)
+ << "Expected duration: " << (mExpectedDurationInMs * 1000)
+ << " Actual duration: " << clipDurationUs << " Difference: " << diff
+ << " Difference is expected to be less than tolerance value: " << kToleranceValueInUs;
+
+ const char *mime = nullptr;
+ AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+ ASSERT_NE(mime, nullptr) << "Track mime is NULL";
+ ALOGI("Track mime = %s", mime);
+
+ int32_t sampleRate, channelCount, bitRate;
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
+ ALOGI("Channel count reported by extractor: %d", channelCount);
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
+ ALOGI("Sample Rate reported by extractor: %d", sampleRate);
+ AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitRate);
+ ALOGI("Bit Rate reported by extractor: %d", bitRate);
+ }
+}
+
+TEST_F(StagefrightRecorderTest, RecordingAudioSanityTest) {
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+
+ int32_t maxAmplitude = -1;
+ status_t status = mStfRecorder->getMaxAmplitude(&maxAmplitude);
+ ASSERT_EQ(maxAmplitude, 0) << "Invalid value of max amplitude";
+
+ ASSERT_NO_FATAL_FAILURE(recordMedia());
+
+ // Verify getMetrics() behavior
+ Parcel parcel;
+ status = mStfRecorder->getMetrics(&parcel);
+ ASSERT_EQ(status, OK) << "Failed to get the parcel from getMetrics";
+ ALOGV("Size of the Parcel returned by getMetrics: %zu", parcel.dataSize());
+ ASSERT_GT(parcel.dataSize(), 0) << "Parcel size reports empty record";
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_P(StagefrightRecorderTest, MultiFormatAudioRecordTest) {
+ output_format outputFormat = GetParam().first;
+ audio_encoder audioEncoder = GetParam().second;
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(outputFormat, audioEncoder));
+ ASSERT_NO_FATAL_FAILURE(recordMedia());
+ // TODO(b/161687761)
+ // Skip for AMR-NB/WB output format
+ if (!(outputFormat == OUTPUT_FORMAT_AMR_NB || outputFormat == OUTPUT_FORMAT_AMR_WB)) {
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ }
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_F(StagefrightRecorderTest, GetActiveMicrophonesTest) {
+ ASSERT_NO_FATAL_FAILURE(
+ setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT, AUDIO_SOURCE_MIC));
+
+ status_t status = mStfRecorder->init();
+ ASSERT_EQ(status, OK) << "Init failed for stagefright recorder";
+
+ status = mStfRecorder->prepare();
+ ASSERT_EQ(status, OK) << "Failed to preapre the reorder";
+
+ status = mStfRecorder->start();
+ ASSERT_EQ(status, OK) << "Failed to start the recorder";
+
+ // Record media for 4 secs
+ std::this_thread::sleep_for(std::chrono::seconds(kClipDurationInSec));
+
+ std::vector<media::MicrophoneInfo> activeMicrophones{};
+ status = mStfRecorder->getActiveMicrophones(&activeMicrophones);
+ ASSERT_EQ(status, OK) << "Failed to get Active Microphones";
+ ASSERT_GT(activeMicrophones.size(), 0) << "No active microphones are found";
+
+ status = mStfRecorder->stop();
+ ASSERT_EQ(status, OK) << "Failed to stop the recorder";
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+TEST_F(StagefrightRecorderTest, MultiStartPauseTest) {
+ ASSERT_NO_FATAL_FAILURE(setAudioRecorderFormat(OUTPUT_FORMAT_DEFAULT, AUDIO_ENCODER_DEFAULT));
+ ASSERT_NO_FATAL_FAILURE(recordMedia(true, kMaxLoopCount, kMaxLoopCount));
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
+ if (kDebug) {
+ ASSERT_NO_FATAL_FAILURE(dumpInfo());
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ StagefrightRecorderTestAll, StagefrightRecorderTest,
+ ::testing::Values(std::make_pair(OUTPUT_FORMAT_AMR_NB, AUDIO_ENCODER_AMR_NB),
+ std::make_pair(OUTPUT_FORMAT_AMR_WB, AUDIO_ENCODER_AMR_WB),
+ std::make_pair(OUTPUT_FORMAT_AAC_ADTS, AUDIO_ENCODER_AAC),
+ std::make_pair(OUTPUT_FORMAT_OGG, AUDIO_ENCODER_OPUS)));
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ ALOGV("Test result = %d\n", status);
+ return status;
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 474313f..4548e91 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -674,8 +674,8 @@
sp<NBLog::Writer> AudioFlinger::newWriter_l(size_t size, const char *name)
{
- // If there is no memory allocated for logs, return a dummy writer that does nothing.
- // Similarly if we can't contact the media.log service, also return a dummy writer.
+ // If there is no memory allocated for logs, return a no-op writer that does nothing.
+ // Similarly if we can't contact the media.log service, also return a no-op writer.
if (mLogMemoryDealer == 0 || sMediaLogService == 0) {
return new NBLog::Writer();
}
@@ -701,7 +701,7 @@
}
}
// Even after garbage-collecting all old writers, there is still not enough memory,
- // so return a dummy writer
+ // so return a no-op writer
return new NBLog::Writer();
}
success:
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 6ef19bf..feb71e3 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -80,7 +80,7 @@
// TODO Permit disabling of logging at compile-time.
-// TODO A non-nullptr dummy implementation that is a nop would be faster than checking for nullptr
+// TODO A non-nullptr stub implementation that is a nop would be faster than checking for nullptr
// in the case when logging is enabled at compile-time and enabled at runtime, but it might be
// slower than nullptr check when logging is enabled at compile-time and disabled at runtime.
@@ -129,8 +129,8 @@
namespace android {
extern "C" {
-// TODO consider adding a thread_local NBLog::Writer tlDummyNBLogWriter and then
-// initialize below tlNBLogWriter to &tlDummyNBLogWriter to remove the need to
+// TODO consider adding a thread_local NBLog::Writer tlStubNBLogWriter and then
+// initialize below tlNBLogWriter to &tlStubNBLogWriter to remove the need to
// check for nullptr every time. Also reduces the need to add a new logging macro above
// each time we want to log a new type.
extern thread_local NBLog::Writer *tlNBLogWriter;