Merge "Codec2: vndk: lock P010 with gralloc4 mapper first"
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index 2377fbb..f272499 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -54,6 +54,10 @@
     static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
 } // unnamed
 
+static bool isAtLeastT() {
+    return android_get_device_api_level() >= __ANDROID_API_T__;
+}
+
 C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
     // gralloc does not support WRITE_PROTECTED
     return C2MemoryUsage(
@@ -768,10 +772,12 @@
         default: {
             // We don't know what it is, let's try to lock it with gralloc4
             android_ycbcr ycbcrLayout;
-            c2_status_t status = Gralloc4Mapper_lock(
-                    const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
-            if (status == C2_OK) {
-                break;
+            if (isAtLeastT()) {
+                c2_status_t status = Gralloc4Mapper_lock(
+                        const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
+                if (status == C2_OK) {
+                    break;
+                }
             }
 
             // fallback to lockYCbCr
diff --git a/media/libeffects/spatializer/benchmarks/Android.bp b/media/libeffects/spatializer/benchmarks/Android.bp
new file mode 100644
index 0000000..ab7e468
--- /dev/null
+++ b/media/libeffects/spatializer/benchmarks/Android.bp
@@ -0,0 +1,21 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_license"],
+}
+
+cc_benchmark {
+    name: "spatializer_benchmark",
+    vendor: true,
+    srcs: ["spatializer_benchmark.cpp"],
+    shared_libs: [
+        "libaudioutils",
+        "liblog",
+    ],
+    header_libs: [
+        "libhardware_headers",
+    ],
+}
diff --git a/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
new file mode 100644
index 0000000..e8ac480
--- /dev/null
+++ b/media/libeffects/spatializer/benchmarks/spatializer_benchmark.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#include <array>
+#include <dlfcn.h>
+#include <random>
+#include <vector>
+
+#include <benchmark/benchmark.h>
+#include <hardware/audio_effect.h>
+#include <log/log.h>
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = [] {
+    audio_effect_library_t symbol{};
+    void* effectLib = dlopen("libspatialaudio.so", RTLD_NOW);
+    if (effectLib) {
+        audio_effect_library_t* effectInterface =
+                (audio_effect_library_t*)dlsym(effectLib, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+        if (effectInterface == nullptr) {
+            ALOGE("dlsym failed: %s", dlerror());
+            exit(-1);
+        }
+        symbol = (audio_effect_library_t)(*effectInterface);
+    } else {
+        ALOGE("dlopen failed: %s", dlerror());
+        exit(-1);
+    }
+    return symbol;
+}();
+
+// channel masks
+constexpr int kInputChMask = AUDIO_CHANNEL_OUT_5POINT1;
+
+// sampleRates
+constexpr size_t kSampleRates[] = {
+        44100,
+        48000,
+        96000,
+};
+constexpr size_t kNumSampleRates = std::size(kSampleRates);
+
+// duration in ms
+constexpr size_t kDurations[] = {2, 5, 10};
+constexpr size_t kNumDurations = std::size(kDurations);
+
+// effect uuids
+constexpr effect_uuid_t kEffectUuid = {
+        0xcc4677de, 0xff72, 0x11eb, 0x9a03, {0x02, 0x42, 0xac, 0x13, 0x00, 0x03}};
+
+constexpr float kMinAmplitude = -1.0f;
+constexpr float kMaxAmplitude = 1.0f;
+
+/*******************************************************************
+ * A test result running on Pixel 5 for comparison.
+ * The first parameter indicates the sample rate.
+ * 0: 44100, 1: 48000, 2: 96000
+ * The second parameter indicates the duration in ms.
+ * 0: 2, 1: 5, 2: 10
+ * -------------------------------------------------------------
+ * Benchmark                   Time             CPU   Iterations
+ * -------------------------------------------------------------
+ * BM_SPATIALIZER/0/0     739848 ns       738497 ns          934
+ * BM_SPATIALIZER/0/1    1250503 ns      1248337 ns          480
+ * BM_SPATIALIZER/0/2    2094092 ns      2090092 ns          310
+ * BM_SPATIALIZER/1/0     783114 ns       781626 ns          683
+ * BM_SPATIALIZER/1/1    1332951 ns      1330473 ns          452
+ * BM_SPATIALIZER/1/2    2258313 ns      2254022 ns          289
+ * BM_SPATIALIZER/2/0    1210332 ns      1207957 ns          477
+ * BM_SPATIALIZER/2/1    2356259 ns      2351764 ns          269
+ * BM_SPATIALIZER/2/2    4267814 ns      4259567 ns          155
+ *******************************************************************/
+
+static void BM_SPATIALIZER(benchmark::State& state) {
+    const size_t sampleRate = kSampleRates[state.range(0)];
+    const size_t durationMs = kDurations[state.range(1)];
+    const size_t frameCount = durationMs * sampleRate / 1000;
+    const size_t inputChannelCount = audio_channel_count_from_out_mask(kInputChMask);
+    const size_t outputChannelCount = audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
+
+    // Initialize input buffer with deterministic pseudo-random values
+    std::minstd_rand gen(kInputChMask);
+    std::uniform_real_distribution<> dis(kMinAmplitude, kMaxAmplitude);
+    std::vector<float> input(frameCount * inputChannelCount);
+    for (auto& in : input) {
+        in = dis(gen);
+    }
+
+    effect_handle_t effectHandle = nullptr;
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.create_effect(&kEffectUuid, 1 /* sessionId */,
+                                                                 1 /* ioId */, &effectHandle);
+        status != 0) {
+        ALOGE("create_effect returned an error = %d\n", status);
+        return;
+    }
+
+    effect_config_t config{};
+    config.inputCfg.samplingRate = config.outputCfg.samplingRate = sampleRate;
+    config.inputCfg.channels = kInputChMask;
+    config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    config.inputCfg.format = config.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+
+    int reply = 0;
+    uint32_t replySize = sizeof(reply);
+    if (int status = (*effectHandle)
+                             ->command(effectHandle, EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t),
+                                       &config, &replySize, &reply);
+        status != 0) {
+        ALOGE("command returned an error = %d\n", status);
+        return;
+    }
+
+    if (int status = (*effectHandle)
+                             ->command(effectHandle, EFFECT_CMD_ENABLE, sizeof(effect_config_t),
+                                       &config, &replySize, &reply);
+        status != 0) {
+        ALOGE("command returned an error = %d\n", status);
+        return;
+    }
+
+    // Run the test
+    std::vector<float> output(frameCount * outputChannelCount);
+    for (auto _ : state) {
+        benchmark::DoNotOptimize(input.data());
+        benchmark::DoNotOptimize(output.data());
+
+        audio_buffer_t inBuffer = {.frameCount = frameCount, .f32 = input.data()};
+        audio_buffer_t outBuffer = {.frameCount = frameCount, .f32 = output.data()};
+        (*effectHandle)->process(effectHandle, &inBuffer, &outBuffer);
+
+        benchmark::ClobberMemory();
+    }
+
+    state.SetComplexityN(frameCount);
+
+    if (int status = AUDIO_EFFECT_LIBRARY_INFO_SYM.release_effect(effectHandle); status != 0) {
+        ALOGE("release_effect returned an error = %d\n", status);
+        return;
+    }
+}
+
+static void SPATIALIZERArgs(benchmark::internal::Benchmark* b) {
+    for (int i = 0; i < kNumSampleRates; i++) {
+        for (int j = 0; j < kNumDurations; ++j) {
+            b->Args({i, j});
+        }
+    }
+}
+
+BENCHMARK(BM_SPATIALIZER)->Apply(SPATIALIZERArgs);
+
+BENCHMARK_MAIN();
diff --git a/services/mediametrics/AudioPowerUsage.h b/services/mediametrics/AudioPowerUsage.h
index 7021902..4d12714 100644
--- a/services/mediametrics/AudioPowerUsage.h
+++ b/services/mediametrics/AudioPowerUsage.h
@@ -49,7 +49,7 @@
      */
     std::pair<std::string, int32_t> dump(int32_t lines = INT32_MAX) const;
 
-    // align with message AudioUsageDataReported in frameworks/base/cmds/statsd/src/atoms.proto
+    // align with message AudioPowerUsageDataReported in frameworks/proto_logging/stats/atoms.proto
     enum AudioType {
         UNKNOWN_TYPE = 0,
         VOICE_CALL_TYPE = 1,            // voice call