Merge "audioflinger: add effect creation probe mode" into rvc-dev
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index 1bbb9c2..446ca4f 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -139,12 +139,20 @@
const int STREAM_WIDTH_OFFSET = 1;
const int STREAM_HEIGHT_OFFSET = 2;
const int STREAM_DURATION_OFFSET = 3;
+
camera_metadata_entry entry = mData->find(tag);
- if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
+
+ if (entry.count == 0) {
+ // Duration keys can be missing when corresponding capture feature is not supported
+ return;
+ }
+
+ if (entry.count % 4 || entry.type != TYPE_INT64) {
ALOGE("%s: malformed duration key %d! count %zu, type %d",
__FUNCTION__, tag, entry.count, entry.type);
return;
}
+
Vector<int64_t> filteredDurations;
filteredDurations.setCapacity(entry.count * 2);
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 7a4e1ae..5292705 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -89,7 +89,7 @@
}
sp<DrmSessionManager> DrmSessionManager::Instance() {
- auto drmSessionManager = new DrmSessionManager();
+ static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
drmSessionManager->init();
return drmSessionManager;
}
@@ -163,7 +163,8 @@
}
auto info = it->second;
- mService->removeResource(info.pid, info.clientId, toResourceVec(sessionId, INT64_MAX));
+ // removeClient instead of removeSession because each client has only one session
+ mService->removeClient(info.pid, info.clientId);
mSessionMap.erase(it);
}
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 5990116..b112249 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -319,10 +319,11 @@
// Obtain Codec2Client
std::vector<Traits> traits = Codec2Client::ListComponents();
- // parse APEX XML first, followed by vendor XML
+ // parse APEX XML first, followed by vendor XML.
+ // Note: APEX XML names do not depend on ro.media.xml_variant.* properties.
MediaCodecsXmlParser parser;
parser.parseXmlFilesInSearchDirs(
- parser.getDefaultXmlNames(),
+ { "media_codecs.xml", "media_codecs_performance.xml" },
{ "/apex/com.android.media.swcodec/etc" });
// TODO: remove these c2-specific files once product moved to default file names
diff --git a/media/libaaudio/src/utility/FixedBlockAdapter.cpp b/media/libaaudio/src/utility/FixedBlockAdapter.cpp
index 63495f0..b55f827 100644
--- a/media/libaaudio/src/utility/FixedBlockAdapter.cpp
+++ b/media/libaaudio/src/utility/FixedBlockAdapter.cpp
@@ -18,22 +18,17 @@
#include "FixedBlockAdapter.h"
-FixedBlockAdapter::~FixedBlockAdapter() {
- close();
-}
-
int32_t FixedBlockAdapter::open(int32_t bytesPerFixedBlock)
{
mSize = bytesPerFixedBlock;
- mStorage = new uint8_t[bytesPerFixedBlock];
+ mStorage = std::make_unique<uint8_t[]>(bytesPerFixedBlock);
mPosition = 0;
return 0;
}
int32_t FixedBlockAdapter::close()
{
- delete[] mStorage;
- mStorage = nullptr;
+ mStorage.reset();
mSize = 0;
mPosition = 0;
return 0;
diff --git a/media/libaaudio/src/utility/FixedBlockAdapter.h b/media/libaaudio/src/utility/FixedBlockAdapter.h
index 7008b25..4dc7e68 100644
--- a/media/libaaudio/src/utility/FixedBlockAdapter.h
+++ b/media/libaaudio/src/utility/FixedBlockAdapter.h
@@ -17,6 +17,7 @@
#ifndef AAUDIO_FIXED_BLOCK_ADAPTER_H
#define AAUDIO_FIXED_BLOCK_ADAPTER_H
+#include <memory>
#include <stdio.h>
/**
@@ -37,7 +38,7 @@
FixedBlockAdapter(FixedBlockProcessor &fixedBlockProcessor)
: mFixedBlockProcessor(fixedBlockProcessor) {}
- virtual ~FixedBlockAdapter();
+ virtual ~FixedBlockAdapter() = default;
/**
* Allocate internal resources needed for buffering data.
@@ -63,7 +64,7 @@
protected:
FixedBlockProcessor &mFixedBlockProcessor;
- uint8_t *mStorage = nullptr; // Store data here while assembling buffers.
+ std::unique_ptr<uint8_t[]> mStorage; // Store data here while assembling buffers.
int32_t mSize = 0; // Size in bytes of the fixed size buffer.
int32_t mPosition = 0; // Offset of the last byte read or written.
};
diff --git a/media/libaaudio/src/utility/FixedBlockReader.cpp b/media/libaaudio/src/utility/FixedBlockReader.cpp
index 21ea70e..7931fa0 100644
--- a/media/libaaudio/src/utility/FixedBlockReader.cpp
+++ b/media/libaaudio/src/utility/FixedBlockReader.cpp
@@ -39,7 +39,7 @@
if (bytesToRead > dataAvailable) {
bytesToRead = dataAvailable;
}
- memcpy(buffer, mStorage + mPosition, bytesToRead);
+ memcpy(buffer, &mStorage[mPosition], bytesToRead);
mPosition += bytesToRead;
return bytesToRead;
}
@@ -60,7 +60,7 @@
bytesLeft -= mSize;
} else {
// Just need a partial block so we have to use storage.
- result = mFixedBlockProcessor.onProcessFixedBlock(mStorage, mSize);
+ result = mFixedBlockProcessor.onProcessFixedBlock(mStorage.get(), mSize);
mPosition = 0;
}
}
diff --git a/media/libaaudio/src/utility/FixedBlockWriter.cpp b/media/libaaudio/src/utility/FixedBlockWriter.cpp
index 2ce8046..afb83c1 100644
--- a/media/libaaudio/src/utility/FixedBlockWriter.cpp
+++ b/media/libaaudio/src/utility/FixedBlockWriter.cpp
@@ -30,7 +30,7 @@
if (bytesToStore > roomAvailable) {
bytesToStore = roomAvailable;
}
- memcpy(mStorage + mPosition, buffer, bytesToStore);
+ memcpy(&mStorage[mPosition], buffer, bytesToStore);
mPosition += bytesToStore;
return bytesToStore;
}
@@ -46,7 +46,7 @@
bytesLeft -= bytesWritten;
// If storage full then flush it out
if (mPosition == mSize) {
- result = mFixedBlockProcessor.onProcessFixedBlock(mStorage, mSize);
+ result = mFixedBlockProcessor.onProcessFixedBlock(mStorage.get(), mSize);
mPosition = 0;
}
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 98c5497..637322f 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -29,9 +29,55 @@
#include <OMX_Video.h>
#include <sys/stat.h>
+#include <array>
+#include <string>
+#include <vector>
+
namespace android {
-constexpr char const * const MediaProfiles::xmlFiles[];
+namespace /* unnamed */ {
+
+// Returns a list of possible paths for the media_profiles XML file.
+std::array<char const*, 5> const& getXmlPaths() {
+ static std::array<std::string const, 5> const paths =
+ []() -> decltype(paths) {
+ // Directories for XML file that will be searched (in this order).
+ constexpr std::array<char const*, 4> searchDirs = {
+ "product/etc/",
+ "odm/etc/",
+ "vendor/etc/",
+ "system/etc/",
+ };
+
+ // The file name may contain a variant if the vendor property
+ // ro.vendor.media_profiles_xml_variant is set.
+ char variant[PROPERTY_VALUE_MAX];
+ property_get("ro.media.xml_variant.profiles",
+ variant,
+ "_V1_0");
+
+ std::string fileName =
+ std::string("media_profiles") + variant + ".xml";
+
+ return { searchDirs[0] + fileName,
+ searchDirs[1] + fileName,
+ searchDirs[2] + fileName,
+ searchDirs[3] + fileName,
+ "system/etc/media_profiles_V1_0.xml" // System fallback
+ };
+ }();
+ static std::array<char const*, 5> const cPaths = {
+ paths[0].data(),
+ paths[1].data(),
+ paths[2].data(),
+ paths[3].data(),
+ paths[4].data()
+ };
+ return cPaths;
+}
+
+} // unnamed namespace
+
Mutex MediaProfiles::sLock;
bool MediaProfiles::sIsInitialized = false;
MediaProfiles *MediaProfiles::sInstance = NULL;
@@ -48,7 +94,7 @@
{"amrwb", AUDIO_ENCODER_AMR_WB},
{"aac", AUDIO_ENCODER_AAC},
{"heaac", AUDIO_ENCODER_HE_AAC},
- {"aaceld", AUDIO_ENCODER_AAC_ELD},
+ {"aaceld", AUDIO_ENCODER_AAC_ELD},
{"opus", AUDIO_ENCODER_OPUS}
};
@@ -610,7 +656,7 @@
char value[PROPERTY_VALUE_MAX];
if (property_get("media.settings.xml", value, NULL) <= 0) {
const char* xmlFile = nullptr;
- for (auto const& f : xmlFiles) {
+ for (auto const& f : getXmlPaths()) {
if (checkXmlFile(f)) {
xmlFile = f;
break;
diff --git a/media/libmedia/include/media/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
index 3e8e7c8..4cc5b95 100644
--- a/media/libmedia/include/media/MediaProfiles.h
+++ b/media/libmedia/include/media/MediaProfiles.h
@@ -1,18 +1,18 @@
/*
- **
- ** Copyright 2010, 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.
+ *
+ * Copyright 2010, The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
#ifndef ANDROID_MEDIAPROFILES_H
@@ -82,29 +82,12 @@
{
public:
- /*
- * If property media.settings.xml is not set:
- *
- * getInstance() will search through paths listed in xmlFiles.
- * The search goes through members of xmlFiles in the order that they are
- * defined, so files at lower indices have higher priority than those at
- * higher indices.
- *
- * TODO: Add runtime validation of xml files. A search should be considered
- * successful only when validation is successful.
- */
- static constexpr char const * const xmlFiles[] = {
- "odm/etc/media_profiles_V1_0.xml",
- "vendor/etc/media_profiles_V1_0.xml",
- "system/etc/media_profiles.xml"
- };
-
/**
* Returns the singleton instance for subsequence queries or NULL if error.
*
* If property media.settings.xml is set, getInstance() will attempt to read
* from file path in media.settings.xml. Otherwise, getInstance() will
- * search through the list xmlFiles as described above.
+ * search through the list of preset XML file paths.
*
* If the search is unsuccessful, the default instance will be created
* instead.
diff --git a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
index 7729d52..4f3951a 100644
--- a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
+++ b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
@@ -14,23 +14,68 @@
* limitations under the License.
*/
+#include <fstream>
#include <string>
#include <android-base/file.h>
#include <android-base/properties.h>
#include "utility/ValidateXml.h"
+bool isFileReadable(std::string const& path) {
+ std::ifstream f(path);
+ return f.good();
+}
+
TEST(CheckConfig, mediaProfilesValidation) {
RecordProperty("description",
"Verify that the media profiles file "
"is valid according to the schema");
+ // Schema path.
+ constexpr char const* xsdPath = "/data/local/tmp/media_profiles.xsd";
+
+ // If "media.settings.xml" is set, it will be used as an absolute path.
std::string mediaSettingsPath = android::base::GetProperty("media.settings.xml", "");
if (mediaSettingsPath.empty()) {
- mediaSettingsPath.assign("/vendor/etc/media_profiles_V1_0.xml");
- }
+ // If "media.settings.xml" is not set, we will search through a list of
+ // file paths.
- EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(android::base::Basename(mediaSettingsPath).c_str(),
- {android::base::Dirname(mediaSettingsPath).c_str()},
- "/data/local/tmp/media_profiles.xsd");
+ constexpr char const* xmlSearchDirs[] = {
+ "/product/etc/",
+ "/odm/etc/",
+ "/vendor/etc/",
+ };
+
+ // The vendor may provide a vendor variant for the file name.
+ std::string variant = android::base::GetProperty(
+ "ro.media.xml_variant.profiles", "_V1_0");
+ std::string fileName = "media_profiles" + variant + ".xml";
+
+ // Fallback path does not depend on the property defined from the vendor
+ // partition.
+ constexpr char const* fallbackXmlPath =
+ "/system/etc/media_profiles_V1_0.xml";
+
+ std::vector<std::string> xmlPaths = {
+ xmlSearchDirs[0] + fileName,
+ xmlSearchDirs[1] + fileName,
+ xmlSearchDirs[2] + fileName,
+ fallbackXmlPath
+ };
+
+ auto findXmlPath =
+ std::find_if(xmlPaths.begin(), xmlPaths.end(), isFileReadable);
+ ASSERT_TRUE(findXmlPath != xmlPaths.end())
+ << "Cannot read from " << fileName
+ << " in any search directories ("
+ << xmlSearchDirs[0] << ", "
+ << xmlSearchDirs[1] << ", "
+ << xmlSearchDirs[2] << ") and from "
+ << fallbackXmlPath << ".";
+
+ char const* xmlPath = findXmlPath->c_str();
+ EXPECT_VALID_XML(xmlPath, xsdPath);
+ } else {
+ EXPECT_VALID_XML(mediaSettingsPath.c_str(), xsdPath);
+ }
}
diff --git a/media/libstagefright/codecs/amrwb/Android.bp b/media/libstagefright/codecs/amrwb/Android.bp
index 88cf7f2..d8cb568 100644
--- a/media/libstagefright/codecs/amrwb/Android.bp
+++ b/media/libstagefright/codecs/amrwb/Android.bp
@@ -1,6 +1,7 @@
cc_library_static {
name: "libstagefright_amrwbdec",
vendor_available: true,
+ host_supported: true,
srcs: [
"src/agc2_amr_wb.cpp",
@@ -44,8 +45,6 @@
"src/weight_amrwb_lpc.cpp",
],
- header_libs: ["libstagefright_headers"],
-
export_include_dirs: [
"src",
"include",
@@ -63,12 +62,19 @@
"signed-integer-overflow",
],
},
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
//###############################################################################
cc_test {
name: "libstagefright_amrwbdec_test",
gtest: false,
+ host_supported: true,
srcs: ["test/amrwbdec_test.cpp"],
@@ -88,4 +94,10 @@
"signed-integer-overflow",
],
},
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/Android.bp b/media/libstagefright/codecs/amrwb/fuzzer/Android.bp
new file mode 100644
index 0000000..46f77e3
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/fuzzer/Android.bp
@@ -0,0 +1,35 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_fuzz {
+ name: "amrwb_dec_fuzzer",
+ host_supported: true,
+ srcs: [
+ "amrwb_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libstagefright_amrwbdec",
+ ],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/README.md b/media/libstagefright/codecs/amrwb/fuzzer/README.md
new file mode 100644
index 0000000..de45784
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/fuzzer/README.md
@@ -0,0 +1,61 @@
+# Fuzzer for libstagefright_amrwbdec decoder
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR-WB is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+AMR-WB supports the following parameters:
+1. Quality (parameter name: `quality`)
+2. Mode (parameter name: `mode`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `quality` | 0. `Bad Quality` 1. `Good quality` | Bit 0 (LSB) of 1st byte of data. |
+| `mode` | 0. `MODE_7k` 1. `MODE_9k` 2. `MODE_12k` 3. `MODE_14k` 4. `MODE_16k ` 5. `MODE_18k` 6. `MODE_20k` 7. `MODE_23k` 8. `MODE_24k` 9. `MRDTX` | Bits 3, 4, 5 and 6 of 1st byte of data. |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+If the decode operation was successful, the input is advanced by the frame size
+which is based on `mode` and `quality` selected.
+If the decode operation was un-successful, the input is still advanced by frame size so
+that the fuzzer can proceed to feed the next frame.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build amrwb_dec_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) amrwb_dec_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some amrwb files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/amrwb_dec_fuzzer/amrwb_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/amrwb_dec_fuzzer/amrwb_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/codecs/amrwb/fuzzer/amrwb_dec_fuzzer.cpp b/media/libstagefright/codecs/amrwb/fuzzer/amrwb_dec_fuzzer.cpp
new file mode 100644
index 0000000..6dc0270
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/fuzzer/amrwb_dec_fuzzer.cpp
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <malloc.h>
+#include <string.h>
+#include <algorithm>
+#include "pvamrwbdecoder.h"
+#include "pvamrwbdecoder_api.h"
+
+// Constants for AMR-WB.
+constexpr int32_t kSamplesPerFrame = 320;
+constexpr int32_t kBitsPerSample = 16;
+constexpr int32_t kMaxSourceDataUnitSize = KAMRWB_NB_BITS_MAX * sizeof(int16_t);
+constexpr int32_t kOutputBufferSize = kSamplesPerFrame * kBitsPerSample / 8;
+constexpr int32_t kFrameSizes[16] = {17, 23, 32, 36, 40, 46, 50, 58,
+ 60, 17, 23, 32, 36, 40, 46, 50};
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(const uint8_t *data, size_t size);
+ void deInitDecoder();
+
+ private:
+ void *mAmrHandle = nullptr;
+ int16_t *mDecoderCookie = nullptr;
+ void *mDecoderBuffer = nullptr;
+};
+
+bool Codec::initDecoder() {
+ mDecoderBuffer = malloc(pvDecoder_AmrWbMemRequirements());
+ if (mDecoderBuffer) {
+ pvDecoder_AmrWb_Init(&mAmrHandle, mDecoderBuffer, &mDecoderCookie);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void Codec::deInitDecoder() {
+ if (mDecoderBuffer) {
+ free(mDecoderBuffer);
+ mDecoderBuffer = nullptr;
+ }
+ mAmrHandle = nullptr;
+ mDecoderCookie = nullptr;
+}
+
+void Codec::decodeFrames(const uint8_t *data, size_t size) {
+ while (size > 0) {
+ uint8_t modeByte = *data;
+ bool quality = modeByte & 0x01;
+ int16 mode = ((modeByte >> 3) & 0x0f);
+ ++data;
+ --size;
+ int32_t frameSize = kFrameSizes[mode];
+ int16_t inputSampleBuf[kMaxSourceDataUnitSize];
+ uint8_t *inputBuf = new uint8_t[frameSize];
+ if (!inputBuf) {
+ return;
+ }
+ int32_t minSize = std::min((int32_t)size, frameSize);
+ memcpy(inputBuf, data, minSize);
+ int16 frameMode = mode;
+ int16 frameType;
+ RX_State_wb rx_state;
+ mime_unsorting(inputBuf, inputSampleBuf, &frameType, &frameMode, quality, &rx_state);
+
+ int16_t numSamplesOutput;
+ int16_t outputBuf[kOutputBufferSize];
+ pvDecoder_AmrWb(frameMode, inputSampleBuf, outputBuf, &numSamplesOutput, mDecoderBuffer,
+ frameType, mDecoderCookie);
+ data += minSize;
+ size -= minSize;
+ delete[] inputBuf;
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < 2) {
+ return 0;
+ }
+ Codec *codec = new Codec();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder()) {
+ codec->decodeFrames(data, size);
+ }
+ delete codec;
+ return 0;
+}
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index d905b8d..a232150 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -21,6 +21,7 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <android-base/properties.h>
#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
@@ -38,8 +39,6 @@
namespace android {
-using MCXP = MediaCodecsXmlParser;
-
namespace {
bool fileExists(const std::string &path) {
@@ -118,8 +117,8 @@
}
}
-MCXP::StringSet parseCommaSeparatedStringSet(const char *s) {
- MCXP::StringSet result;
+MediaCodecsXmlParser::StringSet parseCommaSeparatedStringSet(const char *s) {
+ MediaCodecsXmlParser::StringSet result;
for (const char *ptr = s ? : ""; *ptr; ) {
const char *end = strchrnul(ptr, ',');
if (ptr != end) { // skip empty values
@@ -136,6 +135,23 @@
} // unnamed namespace
+std::vector<std::string> MediaCodecsXmlParser::getDefaultXmlNames() {
+ static constexpr char const* prefixes[] = {
+ "media_codecs",
+ "media_codecs_performance"
+ };
+ static std::vector<std::string> variants = {
+ android::base::GetProperty("ro.media.xml_variant.codecs", ""),
+ android::base::GetProperty("ro.media.xml_variant.codecs_performance", "")
+ };
+ static std::vector<std::string> names = {
+ prefixes[0] + variants[0] + ".xml",
+ prefixes[1] + variants[1] + ".xml"
+ };
+ return names;
+}
+
+
struct MediaCodecsXmlParser::Impl {
// status + error message
struct Result {
diff --git a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
index b666de4..e224452 100644
--- a/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
+++ b/media/libstagefright/xmlparser/include/media/stagefright/xmlparser/MediaCodecsXmlParser.h
@@ -33,13 +33,17 @@
class MediaCodecsXmlParser {
public:
- // Treblized media codec list will be located in /odm/etc or /vendor/etc.
+ // Treblized media codec list will be located in /product/etc, /odm/etc or
+ // /vendor/etc.
static std::vector<std::string> getDefaultSearchDirs() {
- return { "/odm/etc", "/vendor/etc", "/etc" };
+ return { "/product/etc",
+ "/odm/etc",
+ "/vendor/etc",
+ "/system/etc" };
}
- static std::vector<std::string> getDefaultXmlNames() {
- return { "media_codecs.xml", "media_codecs_performance.xml" };
- }
+
+ static std::vector<std::string> getDefaultXmlNames();
+
static constexpr char const* defaultProfilingResultsXmlPath =
"/data/misc/media/media_codecs_profiling_results.xml";
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5a012bf..ffc3a0f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5710,7 +5710,10 @@
patchBuilder.addSink(filteredDevice);
}
- installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
+ // Add half reported latency to delayMs when muteWaitMs is null in order
+ // to avoid disordered sequence of muting volume and changing devices.
+ installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(),
+ muteWaitMs == 0 ? (delayMs + (outputDesc->latency() / 2)) : delayMs);
}
// update stream volumes according to new device