Merge "Capture HDR thumbnail from surface control"
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index 7aa655f..98164fd 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -37,6 +37,7 @@
#include <binder/IPCThreadState.h>
#include <utils/Errors.h>
+#include <utils/SystemClock.h>
#include <utils/Timers.h>
#include <utils/Trace.h>
@@ -95,6 +96,8 @@
static const uint32_t kFallbackWidth = 1280; // 720p
static const uint32_t kFallbackHeight = 720;
static const char* kMimeTypeAvc = "video/avc";
+static const char* kMimeTypeApplicationOctetstream = "application/octet-stream";
+static const char* kWinscopeMagicString = "#VV1NSC0PET1ME!#";
// Command-line parameters.
static bool gVerbose = false; // chatty on stdout
@@ -350,6 +353,50 @@
}
/*
+ * Writes an unsigned integer byte-by-byte in little endian order regardless
+ * of the platform endianness.
+ */
+template <typename UINT>
+static void writeValueLE(UINT value, uint8_t* buffer) {
+ for (int i = 0; i < sizeof(UINT); ++i) {
+ buffer[i] = static_cast<uint8_t>(value);
+ value >>= 8;
+ }
+}
+
+/*
+ * Saves frames presentation time relative to the elapsed realtime clock in microseconds
+ * preceded by a Winscope magic string and frame count to a metadata track.
+ * This metadata is used by the Winscope tool to sync video with SurfaceFlinger
+ * and WindowManager traces.
+ *
+ * The metadata is written as a binary array as follows:
+ * - winscope magic string (kWinscopeMagicString constant), without trailing null char,
+ * - the number of recorded frames (as little endian uint32),
+ * - for every frame its presentation time relative to the elapsed realtime clock in microseconds
+ * (as little endian uint64).
+ */
+static status_t writeWinscopeMetadata(const Vector<int64_t>& timestamps,
+ const ssize_t metaTrackIdx, const sp<MediaMuxer>& muxer) {
+ ALOGV("Writing metadata");
+ int64_t systemTimeToElapsedTimeOffsetMicros = (android::elapsedRealtimeNano()
+ - systemTime(SYSTEM_TIME_MONOTONIC)) / 1000;
+ sp<ABuffer> buffer = new ABuffer(timestamps.size() * sizeof(int64_t)
+ + sizeof(uint32_t) + strlen(kWinscopeMagicString));
+ uint8_t* pos = buffer->data();
+ strcpy(reinterpret_cast<char*>(pos), kWinscopeMagicString);
+ pos += strlen(kWinscopeMagicString);
+ writeValueLE<uint32_t>(timestamps.size(), pos);
+ pos += sizeof(uint32_t);
+ for (size_t idx = 0; idx < timestamps.size(); ++idx) {
+ writeValueLE<uint64_t>(static_cast<uint64_t>(timestamps[idx]
+ + systemTimeToElapsedTimeOffsetMicros), pos);
+ pos += sizeof(uint64_t);
+ }
+ return muxer->writeSampleData(buffer, metaTrackIdx, timestamps[0], 0);
+}
+
+/*
* Runs the MediaCodec encoder, sending the output to the MediaMuxer. The
* input frames are coming from the virtual display as fast as SurfaceFlinger
* wants to send them.
@@ -364,10 +411,12 @@
static int kTimeout = 250000; // be responsive on signal
status_t err;
ssize_t trackIdx = -1;
+ ssize_t metaTrackIdx = -1;
uint32_t debugNumFrames = 0;
int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
DisplayInfo mainDpyInfo;
+ Vector<int64_t> timestamps;
assert((rawFp == NULL && muxer != NULL) || (rawFp != NULL && muxer == NULL));
@@ -465,6 +514,9 @@
"Failed writing data to muxer (err=%d)\n", err);
return err;
}
+ if (gOutputFormat == FORMAT_MP4) {
+ timestamps.add(ptsUsec);
+ }
}
debugNumFrames++;
}
@@ -491,6 +543,11 @@
encoder->getOutputFormat(&newFormat);
if (muxer != NULL) {
trackIdx = muxer->addTrack(newFormat);
+ if (gOutputFormat == FORMAT_MP4) {
+ sp<AMessage> metaFormat = new AMessage;
+ metaFormat->setString(KEY_MIME, kMimeTypeApplicationOctetstream);
+ metaTrackIdx = muxer->addTrack(metaFormat);
+ }
ALOGV("Starting muxer");
err = muxer->start();
if (err != NO_ERROR) {
@@ -527,6 +584,13 @@
systemTime(CLOCK_MONOTONIC) - startWhenNsec));
fflush(stdout);
}
+ if (metaTrackIdx >= 0 && !timestamps.isEmpty()) {
+ err = writeWinscopeMetadata(timestamps, metaTrackIdx, muxer);
+ if (err != NO_ERROR) {
+ fprintf(stderr, "Failed writing metadata to muxer (err=%d)\n", err);
+ return err;
+ }
+ }
return NO_ERROR;
}
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 38fd34a..0c8d44a 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -153,9 +153,9 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- filters/argbtorgba.rs \
- filters/nightvision.rs \
- filters/saturation.rs \
+ filters/argbtorgba.rscript \
+ filters/nightvision.rscript \
+ filters/saturation.rscript \
mediafilter.cpp \
LOCAL_SHARED_LIBRARIES := \
diff --git a/cmds/stagefright/filters/argbtorgba.rs b/cmds/stagefright/filters/argbtorgba.rscript
similarity index 100%
rename from cmds/stagefright/filters/argbtorgba.rs
rename to cmds/stagefright/filters/argbtorgba.rscript
diff --git a/cmds/stagefright/filters/nightvision.rs b/cmds/stagefright/filters/nightvision.rscript
similarity index 100%
rename from cmds/stagefright/filters/nightvision.rs
rename to cmds/stagefright/filters/nightvision.rscript
diff --git a/cmds/stagefright/filters/saturation.rs b/cmds/stagefright/filters/saturation.rscript
similarity index 100%
rename from cmds/stagefright/filters/saturation.rs
rename to cmds/stagefright/filters/saturation.rscript
diff --git a/media/codec2/components/flac/Android.bp b/media/codec2/components/flac/Android.bp
index e5eb51d..48cc51b 100644
--- a/media/codec2/components/flac/Android.bp
+++ b/media/codec2/components/flac/Android.bp
@@ -23,8 +23,11 @@
srcs: ["C2SoftFlacEnc.cpp"],
- static_libs: [
+ shared_libs: [
"libaudioutils",
+ ],
+
+ static_libs: [
"libFLAC",
],
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 1548a89..0e1bb0a 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -224,7 +224,7 @@
mFirstValidFrameIndex(0u),
mMetaMode(MODE_NONE),
mInputMetEos(false) {
- mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + kRenderingDepth;
+ mOutputSurface.lock()->maxDequeueBuffers = 2 * kSmoothnessFactor + kRenderingDepth;
{
Mutexed<Input>::Locked input(mInput);
input->buffers.reset(new DummyInputBuffers(""));
@@ -948,7 +948,8 @@
uint32_t outputGeneration;
{
Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->maxDequeueBuffers = numOutputSlots + reorderDepth.value + kRenderingDepth;
+ output->maxDequeueBuffers = numOutputSlots + numInputSlots +
+ reorderDepth.value + kRenderingDepth;
outputSurface = output->surface ?
output->surface->getIGraphicBufferProducer() : nullptr;
if (outputSurface) {
@@ -1332,9 +1333,10 @@
ALOGV("[%s] onWorkDone: updated reorder depth to %u",
mName, reorderDepth.value);
size_t numOutputSlots = mOutput.lock()->numSlots;
+ size_t numInputSlots = mInput.lock()->numSlots;
Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->maxDequeueBuffers =
- numOutputSlots + reorderDepth.value + kRenderingDepth;
+ output->maxDequeueBuffers = numOutputSlots + numInputSlots +
+ reorderDepth.value + kRenderingDepth;
if (output->surface) {
output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
}
@@ -1382,6 +1384,7 @@
bool outputBuffersChanged = false;
size_t numOutputSlots = 0;
+ size_t numInputSlots = mInput.lock()->numSlots;
{
Mutexed<Output>::Locked output(mOutput);
output->outputDelay = outputDelay.value;
@@ -1406,7 +1409,8 @@
uint32_t depth = mReorderStash.lock()->depth();
Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->maxDequeueBuffers = numOutputSlots + depth + kRenderingDepth;
+ output->maxDequeueBuffers = numOutputSlots + numInputSlots +
+ depth + kRenderingDepth;
if (output->surface) {
output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
}
diff --git a/media/codec2/sfplugin/PipelineWatcher.cpp b/media/codec2/sfplugin/PipelineWatcher.cpp
index 74d14e8..0ee9056 100644
--- a/media/codec2/sfplugin/PipelineWatcher.cpp
+++ b/media/codec2/sfplugin/PipelineWatcher.cpp
@@ -146,7 +146,7 @@
std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
durations.push_back(elapsed);
}
- std::nth_element(durations.begin(), durations.end(), durations.begin() + n,
+ std::nth_element(durations.begin(), durations.begin() + n, durations.end(),
std::greater<Clock::duration>());
return durations[n];
}
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 1744d3d..38821fd 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -12,10 +12,10 @@
shared_libs: [
"liblog",
"libmediandk",
+ "libstagefright_flacdec",
],
static_libs: [
- "libstagefright_flacdec",
"libstagefright_foundation",
"libstagefright_metadatautils",
"libwebm",
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index 16958f9..140052f 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -24,7 +24,7 @@
ndk_library {
name: "libaaudio",
// deliberately includes symbols from AAudioTesting.h
- symbol_file: "libaaudio.map.txt",
+ symbol_file: "src/libaaudio.map.txt",
first_version: "26",
unversioned_until: "current",
}
@@ -32,6 +32,5 @@
cc_library_headers {
name: "libaaudio_headers",
export_include_dirs: ["include"],
- version_script: "libaaudio.map.txt",
}
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 1eedb12..56c0170 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -10,14 +10,71 @@
"legacy",
"utility",
],
+ header_libs: ["libaaudio_headers"],
+ export_header_lib_headers: ["libaaudio_headers"],
+ version_script: "libaaudio.map.txt",
+
+ srcs: [
+ "core/AAudioAudio.cpp",
+ ],
+
+ cflags: [
+ "-Wno-unused-parameter",
+ "-Wall",
+ "-Werror",
+
+ // By default, all symbols are hidden.
+ // "-fvisibility=hidden",
+ // AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
+ "-DAAUDIO_API=__attribute__((visibility(\"default\")))",
+ ],
+
+ shared_libs: [
+ "libaaudio_internal",
+ "libaudioclient",
+ "libaudioutils",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libbinder",
+ ],
+}
+
+cc_library {
+ name: "libaaudio_internal",
+
+ local_include_dirs: [
+ "binding",
+ "client",
+ "core",
+ "fifo",
+ "legacy",
+ "utility",
+ ],
+
export_include_dirs: ["."],
header_libs: ["libaaudio_headers"],
export_header_lib_headers: ["libaaudio_headers"],
+ shared_libs: [
+ "libaudioclient",
+ "libaudioutils",
+ "liblog",
+ "libcutils",
+ "libutils",
+ "libbinder",
+ ],
+
+ cflags: [
+ "-Wno-unused-parameter",
+ "-Wall",
+ "-Werror",
+ ],
+
srcs: [
+ "core/AudioGlobal.cpp",
"core/AudioStream.cpp",
"core/AudioStreamBuilder.cpp",
- "core/AAudioAudio.cpp",
"core/AAudioStreamParameters.cpp",
"legacy/AudioStreamLegacy.cpp",
"legacy/AudioStreamRecord.cpp",
@@ -54,24 +111,4 @@
"flowgraph/SourceI16.cpp",
"flowgraph/SourceI24.cpp",
],
-
- cflags: [
- "-Wno-unused-parameter",
- "-Wall",
- "-Werror",
-
- // By default, all symbols are hidden.
- // "-fvisibility=hidden",
- // AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
- "-DAAUDIO_API=__attribute__((visibility(\"default\")))",
- ],
-
- shared_libs: [
- "libaudioclient",
- "libaudioutils",
- "liblog",
- "libcutils",
- "libutils",
- "libbinder",
- ],
}
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 44d5122..8040e6a 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -27,6 +27,7 @@
#include <aaudio/AAudioTesting.h>
#include "AudioClock.h"
+#include "AudioGlobal.h"
#include "AudioStreamBuilder.h"
#include "AudioStream.h"
#include "binding/AAudioCommon.h"
@@ -45,63 +46,14 @@
return AAUDIO_ERROR_NULL; \
}
-#define AAUDIO_CASE_ENUM(name) case name: return #name
-
AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) {
- switch (returnCode) {
- AAUDIO_CASE_ENUM(AAUDIO_OK);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT);
- // reserved
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
- // reserved
- // reserved
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
- // reserved
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE);
- AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE);
- }
- return "Unrecognized AAudio error.";
+ return AudioGlobal_convertResultToText(returnCode);
}
AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) {
- switch (state) {
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING);
- AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED);
- }
- return "Unrecognized AAudio state.";
+ return AudioGlobal_convertStreamStateToText(state);
}
-#undef AAUDIO_CASE_ENUM
-
-
-/******************************************
- * Static globals.
- */
-static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED;
-
static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
{
return (AudioStream*) stream;
@@ -543,23 +495,11 @@
}
AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
- return s_MMapPolicy;
+ return AudioGlobal_getMMapPolicy();
}
AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
- aaudio_result_t result = AAUDIO_OK;
- switch(policy) {
- case AAUDIO_UNSPECIFIED:
- case AAUDIO_POLICY_NEVER:
- case AAUDIO_POLICY_AUTO:
- case AAUDIO_POLICY_ALWAYS:
- s_MMapPolicy = policy;
- break;
- default:
- result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
- break;
- }
- return result;
+ return AudioGlobal_setMMapPolicy(policy);
}
AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
diff --git a/media/libaaudio/src/core/AudioGlobal.cpp b/media/libaaudio/src/core/AudioGlobal.cpp
new file mode 100644
index 0000000..e6d9a0d
--- /dev/null
+++ b/media/libaaudio/src/core/AudioGlobal.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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 <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
+
+#include "AudioGlobal.h"
+
+/******************************************
+ * Static globals.
+ */
+namespace aaudio {
+
+static aaudio_policy_t g_MMapPolicy = AAUDIO_UNSPECIFIED;
+
+aaudio_policy_t AudioGlobal_getMMapPolicy() {
+ return g_MMapPolicy;
+}
+
+aaudio_result_t AudioGlobal_setMMapPolicy(aaudio_policy_t policy) {
+ aaudio_result_t result = AAUDIO_OK;
+ switch(policy) {
+ case AAUDIO_UNSPECIFIED:
+ case AAUDIO_POLICY_NEVER:
+ case AAUDIO_POLICY_AUTO:
+ case AAUDIO_POLICY_ALWAYS:
+ g_MMapPolicy = policy;
+ break;
+ default:
+ result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ break;
+ }
+ return result;
+}
+
+#define AAUDIO_CASE_ENUM(name) case name: return #name
+
+const char* AudioGlobal_convertResultToText(aaudio_result_t returnCode) {
+ switch (returnCode) {
+ AAUDIO_CASE_ENUM(AAUDIO_OK);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT);
+ // reserved
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
+ // reserved
+ // reserved
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
+ // reserved
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE);
+ AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE);
+ }
+ return "Unrecognized AAudio error.";
+}
+
+const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state) {
+ switch (state) {
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING);
+ AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED);
+ }
+ return "Unrecognized AAudio state.";
+}
+
+#undef AAUDIO_CASE_ENUM
+
+} // namespace aaudio
diff --git a/media/libaaudio/src/core/AudioGlobal.h b/media/libaaudio/src/core/AudioGlobal.h
new file mode 100644
index 0000000..312cef2
--- /dev/null
+++ b/media/libaaudio/src/core/AudioGlobal.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 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 AAUDIO_AUDIOGLOBAL_H
+#define AAUDIO_AUDIOGLOBAL_H
+
+#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
+
+
+namespace aaudio {
+
+aaudio_policy_t AudioGlobal_getMMapPolicy();
+aaudio_result_t AudioGlobal_setMMapPolicy(aaudio_policy_t policy);
+
+const char* AudioGlobal_convertResultToText(aaudio_result_t returnCode);
+const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state);
+
+}
+
+#endif // AAUDIO_AUDIOGLOBAL_H
+
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 9b77223..5303631 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -25,8 +25,9 @@
#include "AudioStreamBuilder.h"
#include "AudioStream.h"
#include "AudioClock.h"
+#include "AudioGlobal.h"
-using namespace aaudio;
+namespace aaudio {
// Sequential number assigned to streams solely for debugging purposes.
@@ -51,7 +52,7 @@
|| getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
|| getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
"~AudioStream() - still in use, state = %s",
- AAudio_convertStreamStateToText(getState()));
+ AudioGlobal_convertStreamStateToText(getState()));
mPlayerBase->clearParentReference(); // remove reference to this AudioStream
}
@@ -155,7 +156,7 @@
case AAUDIO_STREAM_STATE_CLOSED:
default:
ALOGW("safePause() stream not running, state = %s",
- AAudio_convertStreamStateToText(getState()));
+ AudioGlobal_convertStreamStateToText(getState()));
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -240,7 +241,7 @@
case AAUDIO_STREAM_STATE_CLOSED:
default:
ALOGW("%s() stream not running, state = %s", __func__,
- AAudio_convertStreamStateToText(getState()));
+ AudioGlobal_convertStreamStateToText(getState()));
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -488,3 +489,5 @@
void AudioStream::MyPlayerBase::destroy() {
unregisterWithAudioManager();
}
+
+} // namespace aaudio
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 08f4958..44f45b3 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -27,6 +27,7 @@
#include "binding/AAudioBinderClient.h"
#include "client/AudioStreamInternalCapture.h"
#include "client/AudioStreamInternalPlay.h"
+#include "core/AudioGlobal.h"
#include "core/AudioStream.h"
#include "core/AudioStreamBuilder.h"
#include "legacy/AudioStreamRecord.h"
@@ -112,7 +113,7 @@
}
// The API setting is the highest priority.
- aaudio_policy_t mmapPolicy = AAudio_getMMapPolicy();
+ aaudio_policy_t mmapPolicy = AudioGlobal_getMMapPolicy();
// If not specified then get from a system property.
if (mmapPolicy == AAUDIO_UNSPECIFIED) {
mmapPolicy = AAudioProperty_getMMapPolicy();
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
similarity index 100%
rename from media/libaaudio/libaaudio.map.txt
rename to media/libaaudio/src/libaaudio.map.txt
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 96ed56a..cdd02c0 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -24,6 +24,7 @@
#include <utils/Errors.h>
#include "aaudio/AAudio.h"
+#include "core/AudioGlobal.h"
#include <aaudio/AAudioTesting.h>
#include <math.h>
#include <system/audio-base.h>
@@ -355,7 +356,7 @@
case AAUDIO_STREAM_STATE_DISCONNECTED:
default:
ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
- AAudio_convertStreamStateToText(state));
+ aaudio::AudioGlobal_convertStreamStateToText(state));
result = AAUDIO_ERROR_INVALID_STATE;
break;
}
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 6101e99..19cd0a0 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -11,7 +11,7 @@
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_marshalling.cpp"],
shared_libs: [
- "libaaudio",
+ "libaaudio_internal",
"libbinder",
"libcutils",
"libutils",
@@ -23,7 +23,7 @@
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_clock_model.cpp"],
shared_libs: [
- "libaaudio",
+ "libaaudio_internal",
"libaudioutils",
"libcutils",
"libutils",
@@ -34,7 +34,7 @@
name: "test_block_adapter",
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_block_adapter.cpp"],
- shared_libs: ["libaaudio"],
+ shared_libs: ["libaaudio_internal"],
}
cc_test {
@@ -170,7 +170,7 @@
name: "test_atomic_fifo",
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_atomic_fifo.cpp"],
- shared_libs: ["libaaudio"],
+ shared_libs: ["libaaudio_internal"],
}
cc_test {
@@ -178,7 +178,7 @@
defaults: ["libaaudio_tests_defaults"],
srcs: ["test_flowgraph.cpp"],
shared_libs: [
- "libaaudio",
+ "libaaudio_internal",
"libbinder",
"libcutils",
"libutils",
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 584c2c0..9803473 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -13,12 +13,6 @@
],
shared_libs: [
- "android.hardware.audio.effect@2.0",
- "android.hardware.audio.effect@4.0",
- "android.hardware.audio.effect@5.0",
- "android.hardware.audio@2.0",
- "android.hardware.audio@4.0",
- "android.hardware.audio@5.0",
"libaudiohal@2.0",
"libaudiohal@4.0",
"libaudiohal@5.0",
@@ -26,7 +20,8 @@
],
header_libs: [
- "libaudiohal_headers"
+ "libaudiohal_headers",
+ "libbase_headers",
]
}
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index f86009c..d5336fa 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -14,26 +14,16 @@
* limitations under the License.
*/
-#include <android/hardware/audio/2.0/IDevicesFactory.h>
-#include <android/hardware/audio/4.0/IDevicesFactory.h>
-#include <android/hardware/audio/5.0/IDevicesFactory.h>
-
#include <libaudiohal/FactoryHalHidl.h>
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+
namespace android {
// static
sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
- if (hardware::audio::V5_0::IDevicesFactory::getService() != nullptr) {
- return V5_0::createDevicesFactoryHal();
- }
- if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
- return V4_0::createDevicesFactoryHal();
- }
- if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
- return V2_0::createDevicesFactoryHal();
- }
- return nullptr;
+ return createPreferedImpl<DevicesFactoryHalInterface>();
}
} // namespace android
+
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index bd3ef61..d15b14e 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,26 +14,15 @@
* limitations under the License.
*/
-#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/5.0/IEffectsFactory.h>
-
#include <libaudiohal/FactoryHalHidl.h>
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
namespace android {
// static
sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
- if (hardware::audio::effect::V5_0::IEffectsFactory::getService() != nullptr) {
- return effect::V5_0::createEffectsFactoryHal();
- }
- if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
- return effect::V4_0::createEffectsFactoryHal();
- }
- if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
- return effect::V2_0::createEffectsFactoryHal();
- }
- return nullptr;
+ return createPreferedImpl<EffectsFactoryHalInterface>();
}
// static
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 5e01e42..1335a0c 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -35,13 +35,10 @@
namespace android {
namespace CPP_VERSION {
-DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
- sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
- if (!defaultFactory) {
- ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
- exit(1);
- }
- mDeviceFactories.push_back(defaultFactory);
+DevicesFactoryHalHidl::DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory) {
+ ALOG_ASSERT(devicesFactory != nullptr, "Provided IDevicesFactory service is NULL");
+
+ mDeviceFactories.push_back(devicesFactory);
if (MAJOR_VERSION >= 4) {
// The MSD factory is optional and only available starting at HAL 4.0
sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 27e0649..8775e7b 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -32,18 +32,14 @@
class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
{
public:
+ DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory);
+
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
private:
- friend class DevicesFactoryHalHybrid;
-
std::vector<sp<IDevicesFactory>> mDeviceFactories;
- // Can not be constructed directly by clients.
- DevicesFactoryHalHidl();
-
virtual ~DevicesFactoryHalHidl() = default;
};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index f337a8b..0e1f1bb 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -17,16 +17,17 @@
#define LOG_TAG "DevicesFactoryHalHybrid"
//#define LOG_NDEBUG 0
+#include "DevicesFactoryHalHidl.h"
#include "DevicesFactoryHalHybrid.h"
#include "DevicesFactoryHalLocal.h"
-#include "DevicesFactoryHalHidl.h"
+#include <libaudiohal/FactoryHalHidl.h>
namespace android {
namespace CPP_VERSION {
-DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
+DevicesFactoryHalHybrid::DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory)
: mLocalFactory(new DevicesFactoryHalLocal()),
- mHidlFactory(new DevicesFactoryHalHidl()) {
+ mHidlFactory(new DevicesFactoryHalHidl(hidlFactory)) {
}
status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
@@ -36,6 +37,12 @@
}
return mLocalFactory->openDevice(name, device);
}
-
} // namespace CPP_VERSION
+
+template <>
+sp<DevicesFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+ auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
+ return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
+}
+
} // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
index 5ac0d0d..545bb70 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -17,17 +17,20 @@
#ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
+#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
#include <media/audiohal/DevicesFactoryHalInterface.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+
namespace android {
namespace CPP_VERSION {
class DevicesFactoryHalHybrid : public DevicesFactoryHalInterface
{
public:
- DevicesFactoryHalHybrid();
+ DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory);
// Opens a device with the specified name. To close the device, it is
// necessary to release references to the returned object.
@@ -38,10 +41,6 @@
sp<DevicesFactoryHalInterface> mHidlFactory;
};
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal() {
- return new DevicesFactoryHalHybrid();
-}
-
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 7fd6bde..ba7b195 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -19,11 +19,12 @@
#include <cutils/native_handle.h>
-#include "EffectsFactoryHalHidl.h"
#include "ConversionHelperHidl.h"
#include "EffectBufferHalHidl.h"
#include "EffectHalHidl.h"
+#include "EffectsFactoryHalHidl.h"
#include "HidlUtils.h"
+#include <libaudiohal/FactoryHalHidl.h>
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::Return;
@@ -35,12 +36,10 @@
using namespace ::android::hardware::audio::common::CPP_VERSION;
using namespace ::android::hardware::audio::effect::CPP_VERSION;
-EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
- mEffectsFactory = IEffectsFactory::getService();
- if (mEffectsFactory == 0) {
- ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
- exit(1);
- }
+EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
+ : ConversionHelperHidl("EffectsFactory") {
+ ALOG_ASSERT(effectsFactory != nullptr, "Provided IDevicesFactory service is NULL");
+ mEffectsFactory = effectsFactory;
}
status_t EffectsFactoryHalHidl::queryAllDescriptors() {
@@ -147,4 +146,11 @@
} // namespace CPP_VERSION
} // namespace effect
+
+template<>
+sp<EffectsFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+ auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
+ return service ? new effect::CPP_VERSION::EffectsFactoryHalHidl(service) : nullptr;
+}
+
} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index 01178ff..2828513 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -18,7 +18,6 @@
#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
#include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
-#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include "ConversionHelperHidl.h"
@@ -34,7 +33,7 @@
class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
{
public:
- EffectsFactoryHalHidl();
+ EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory);
// Returns the number of different effects in all loaded libraries.
virtual status_t queryNumberEffects(uint32_t *pNumEffects);
@@ -66,10 +65,6 @@
status_t queryAllDescriptors();
};
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal() {
- return new EffectsFactoryHalHidl();
-}
-
} // namespace CPP_VERSION
} // namespace effect
} // namespace android
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
index c7319d0..829f99c 100644
--- a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
+++ b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
@@ -23,33 +23,42 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <utils/StrongPointer.h>
+#include <array>
+#include <utility>
+
namespace android {
-namespace effect {
-namespace V2_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V2_0
+/** Supported HAL versions, in order of preference.
+ * Implementation should use specialize the `create*FactoryHal` for their version.
+ * Client should use `createPreferedImpl<*FactoryHal>()` to instantiate
+ * the preferred available impl.
+ */
+enum class AudioHALVersion {
+ V5_0,
+ V4_0,
+ V2_0,
+ end, // used for iterating over supported versions
+};
-namespace V4_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V4_0
+/** Template function to fully specialized for each version and each Interface. */
+template <AudioHALVersion, class Interface>
+sp<Interface> createFactoryHal();
-namespace V5_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V5_0
-} // namespace effect
+/** @Return the preferred available implementation or nullptr if none are available. */
+template <class Interface, AudioHALVersion version = AudioHALVersion{}>
+static sp<Interface> createPreferedImpl() {
+ if constexpr (version == AudioHALVersion::end) {
+ return nullptr; // tried all version, all returned nullptr
+ } else {
+ if (auto created = createFactoryHal<version, Interface>(); created != nullptr) {
+ return created;
+ }
-namespace V2_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V2_0
+ using Raw = std::underlying_type_t<AudioHALVersion>; // cast as enum class do not support ++
+ return createPreferedImpl<Interface, AudioHALVersion(Raw(version) + 1)>();
+ }
+}
-namespace V4_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V4_0
-
-namespace V5_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V5_0
} // namespace android
diff --git a/media/libeffects/downmix/Android.bp b/media/libeffects/downmix/Android.bp
index 9c82b1d..2a2f36e 100644
--- a/media/libeffects/downmix/Android.bp
+++ b/media/libeffects/downmix/Android.bp
@@ -6,6 +6,7 @@
srcs: ["EffectDownmix.c"],
shared_libs: [
+ "libaudioutils",
"libcutils",
"liblog",
],
@@ -23,5 +24,4 @@
"libaudioeffects",
"libhardware_headers",
],
- static_libs: ["libaudioutils" ],
}
diff --git a/media/libstagefright/codecs/flac/enc/Android.bp b/media/libstagefright/codecs/flac/enc/Android.bp
index d7d871a..f35bce1 100644
--- a/media/libstagefright/codecs/flac/enc/Android.bp
+++ b/media/libstagefright/codecs/flac/enc/Android.bp
@@ -15,8 +15,10 @@
},
header_libs: ["libbase_headers"],
- static_libs: [
+ shared_libs: [
"libaudioutils",
+ ],
+ static_libs: [
"libFLAC",
],
}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 359df3d..cf91405 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -269,10 +269,21 @@
Rect bounds(mCropWidth, mCropHeight);
- void *dst;
- CHECK_EQ(0, mapper.lock(buf->handle,
- GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
- bounds, &dst));
+ void *dst = NULL;
+ struct android_ycbcr ycbcr;
+ if ( !mConverter &&
+ (mColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
+ mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar ||
+ mColorFormat == OMX_COLOR_FormatYUV420Planar16)) {
+ CHECK_EQ(0, mapper.lockYCbCr(buf->handle,
+ GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+ bounds, &ycbcr));
+ } else {
+ CHECK_EQ(0, mapper.lock(buf->handle,
+ GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+ bounds, &dst));
+ }
// TODO move the other conversions also into ColorConverter, and
// fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth)
@@ -289,12 +300,10 @@
const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
- uint8_t *dst_y = (uint8_t *)dst;
- size_t dst_y_size = buf->stride * buf->height;
+ uint8_t *dst_y = (uint8_t *)ycbcr.y;
+ uint8_t *dst_v = (uint8_t *)ycbcr.cr;
+ uint8_t *dst_u = (uint8_t *)ycbcr.cb;
size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
dst_y += mCropTop * buf->stride + mCropLeft;
dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
@@ -321,12 +330,10 @@
const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
- uint8_t *dst_y = (uint8_t *)dst;
- size_t dst_y_size = buf->stride * buf->height;
+ uint8_t *dst_y = (uint8_t *)ycbcr.y;
+ uint8_t *dst_v = (uint8_t *)ycbcr.cr;
+ uint8_t *dst_u = (uint8_t *)ycbcr.cb;
size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
dst_y += mCropTop * buf->stride + mCropLeft;
dst_v += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
@@ -361,13 +368,10 @@
src_y += mCropLeft + mCropTop * mWidth;
src_uv += (mCropLeft + mCropTop * mWidth) / 2;
- uint8_t *dst_y = (uint8_t *)dst;
-
- size_t dst_y_size = buf->stride * buf->height;
+ uint8_t *dst_y = (uint8_t *)ycbcr.y;
+ uint8_t *dst_v = (uint8_t *)ycbcr.cr;
+ uint8_t *dst_u = (uint8_t *)ycbcr.cb;
size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
dst_y += mCropTop * buf->stride + mCropLeft;
dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
diff --git a/media/libstagefright/filters/Android.bp b/media/libstagefright/filters/Android.bp
index 7a67e55..b1f62c7 100644
--- a/media/libstagefright/filters/Android.bp
+++ b/media/libstagefright/filters/Android.bp
@@ -8,7 +8,7 @@
"MediaFilter.cpp",
"RSFilter.cpp",
"SaturationFilter.cpp",
- "saturationARGB.rs",
+ "saturationARGB.rscript",
"SimpleFilter.cpp",
"ZeroFilter.cpp",
],
diff --git a/media/libstagefright/filters/saturation.rs b/media/libstagefright/filters/saturation.rscript
similarity index 100%
rename from media/libstagefright/filters/saturation.rs
rename to media/libstagefright/filters/saturation.rscript
diff --git a/media/libstagefright/filters/saturationARGB.rs b/media/libstagefright/filters/saturationARGB.rscript
similarity index 100%
rename from media/libstagefright/filters/saturationARGB.rs
rename to media/libstagefright/filters/saturationARGB.rscript
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index b494e16..7ebe71f 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -1,4 +1,4 @@
-cc_library {
+cc_library_shared {
name: "libstagefright_flacdec",
vendor_available: true,
@@ -18,29 +18,20 @@
cfi: true,
},
- static: {
- whole_static_libs: [
- "libFLAC",
- "libaudioutils",
- ],
- },
-
- shared: {
- static_libs: [
- "libFLAC",
- "libaudioutils",
- ],
- export_static_lib_headers: [
- "libFLAC",
- ],
- },
-
shared_libs: [
+ "libaudioutils",
"liblog",
],
+ static_libs: [
+ "libFLAC",
+ ],
+
+ export_static_lib_headers: [
+ "libFLAC",
+ ],
+
header_libs: [
"libmedia_headers",
- "libFLAC-headers",
],
}
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index cd379bf..d8d425b 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -26,14 +26,31 @@
namespace {
-std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> gConvert;
+const char * utf16_cerror = "__CONVERSION_ERROR__";
+const char16_t * utf8_cerror = u"__CONVERSION_ERROR__";
+
+std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> gConvert(utf16_cerror, utf8_cerror);
static std::string utf16ToUtf8(std::u16string input_str) {
- return gConvert.to_bytes(input_str);
+ std::string conversion = gConvert.to_bytes(input_str);
+
+ if (conversion == utf16_cerror) {
+ ALOGE("Unable to convert UTF-16 string to UTF-8");
+ return "";
+ } else {
+ return conversion;
+ }
}
static std::u16string utf8ToUtf16(std::string input_str) {
- return gConvert.from_bytes(input_str);
+ std::u16string conversion = gConvert.from_bytes(input_str);
+
+ if (conversion == utf8_cerror) {
+ ALOGE("Unable to convert UTF-8 string to UTF-16");
+ return u"";
+ } else {
+ return conversion;
+ }
}
} // namespace
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index 8564576..84a20d3 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -150,6 +150,7 @@
ret += copyFile(oldFile.c_str(), newFile.c_str());
}
}
+ closedir(dir);
return ret;
}
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 1883f63..1145b7b 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -35,6 +35,7 @@
int64_t timestamp, int32_t width, int32_t height, int32_t numPlanes) :
mReader(reader), mFormat(format), mUsage(usage), mBuffer(buffer), mLockedBuffer(nullptr),
mTimestamp(timestamp), mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
+ LOG_FATAL_IF(reader == nullptr, "AImageReader shouldn't be null while creating AImage");
}
AImage::~AImage() {
@@ -57,14 +58,9 @@
if (mIsClosed) {
return;
}
- sp<AImageReader> reader = mReader.promote();
- if (reader != nullptr) {
- reader->releaseImageLocked(this, releaseFenceFd);
- } else if (mBuffer != nullptr) {
- LOG_ALWAYS_FATAL("%s: parent AImageReader closed without releasing image %p",
- __FUNCTION__, this);
+ if (!mReader->mIsClosed) {
+ mReader->releaseImageLocked(this, releaseFenceFd);
}
-
// Should have been set to nullptr in releaseImageLocked
// Set to nullptr here for extra safety only
mBuffer = nullptr;
@@ -83,22 +79,12 @@
void
AImage::lockReader() const {
- sp<AImageReader> reader = mReader.promote();
- if (reader == nullptr) {
- // Reader has been closed
- return;
- }
- reader->mLock.lock();
+ mReader->mLock.lock();
}
void
AImage::unlockReader() const {
- sp<AImageReader> reader = mReader.promote();
- if (reader == nullptr) {
- // Reader has been closed
- return;
- }
- reader->mLock.unlock();
+ mReader->mLock.unlock();
}
media_status_t
diff --git a/media/ndk/NdkImagePriv.h b/media/ndk/NdkImagePriv.h
index e0f16da..0e8cbcb 100644
--- a/media/ndk/NdkImagePriv.h
+++ b/media/ndk/NdkImagePriv.h
@@ -72,7 +72,7 @@
uint32_t getJpegSize() const;
// When reader is close, AImage will only accept close API call
- wp<AImageReader> mReader;
+ const sp<AImageReader> mReader;
const int32_t mFormat;
const uint64_t mUsage; // AHARDWAREBUFFER_USAGE_* flags.
BufferItem* mBuffer;
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 830f752..c0ceb3d 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -272,6 +272,11 @@
mFrameListener(new FrameListener(this)),
mBufferRemovedListener(new BufferRemovedListener(this)) {}
+AImageReader::~AImageReader() {
+ Mutex::Autolock _l(mLock);
+ LOG_FATAL_IF("AImageReader not closed before destruction", mIsClosed != true);
+}
+
media_status_t
AImageReader::init() {
PublicFormat publicFormat = static_cast<PublicFormat>(mFormat);
@@ -347,8 +352,12 @@
return AMEDIA_OK;
}
-AImageReader::~AImageReader() {
+void AImageReader::close() {
Mutex::Autolock _l(mLock);
+ if (mIsClosed) {
+ return;
+ }
+ mIsClosed = true;
AImageReader_ImageListener nullListener = {nullptr, nullptr};
setImageListenerLocked(&nullListener);
@@ -741,6 +750,7 @@
void AImageReader_delete(AImageReader* reader) {
ALOGV("%s", __FUNCTION__);
if (reader != nullptr) {
+ reader->close();
reader->decStrong((void*) AImageReader_delete);
}
return;
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 19bd704..0779a71 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -76,6 +76,7 @@
int32_t getHeight() const { return mHeight; };
int32_t getFormat() const { return mFormat; };
int32_t getMaxImages() const { return mMaxImages; };
+ void close();
private:
@@ -165,6 +166,7 @@
native_handle_t* mWindowHandle = nullptr;
List<AImage*> mAcquiredImages;
+ bool mIsClosed = false;
Mutex mLock;
};
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 3c4fbba..13152d0 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -24,6 +24,7 @@
#include "Configuration.h"
#include <utils/Log.h>
#include <system/audio_effects/effect_aec.h>
+#include <system/audio_effects/effect_dynamicsprocessing.h>
#include <system/audio_effects/effect_ns.h>
#include <system/audio_effects/effect_visualizer.h>
#include <audio_utils/channels.h>
@@ -2569,7 +2570,8 @@
if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
(((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
(memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
- (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
+ (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0) ||
+ (memcmp(&desc.type, SL_IID_DYNAMICSPROCESSING, sizeof(effect_uuid_t)) == 0))) {
return false;
}
return true;
diff --git a/services/audiopolicy/config/audio_policy_volumes.xml b/services/audiopolicy/config/audio_policy_volumes.xml
index ec64a7c..27bd3ff 100644
--- a/services/audiopolicy/config/audio_policy_volumes.xml
+++ b/services/audiopolicy/config/audio_policy_volumes.xml
@@ -44,7 +44,7 @@
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
- ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
+ ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
index 6e72f2a..885b5fa 100644
--- a/services/audiopolicy/engine/config/Android.bp
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -3,7 +3,6 @@
export_include_dirs: ["include"],
include_dirs: [
"external/libxml2/include",
- "external/icu/icu4c/source/common",
],
srcs: [
"src/EngineConfig.cpp",
diff --git a/services/audiopolicy/manager/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
index 7aff6a9..476a1ec 100644
--- a/services/audiopolicy/manager/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -21,7 +21,13 @@
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
- return new AudioPolicyManager(clientInterface);
+ AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
+ status_t status = apm->initialize();
+ if (status != NO_ERROR) {
+ delete apm;
+ apm = nullptr;
+ }
+ return apm;
}
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index edab95a..83ae35e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2408,7 +2408,8 @@
for (size_t i = 0; i < mInputs.size(); i++) {
const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
if (input->clientsList().size() == 0
- || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
+ || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())
+ || (input->getAudioPort()->getFlags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
inputsToClose.push_back(mInputs.keyAt(i));
} else {
bool close = false;
@@ -4305,7 +4306,6 @@
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
loadConfig();
- initialize();
}
void AudioPolicyManager::loadConfig() {
@@ -5694,8 +5694,9 @@
const auto ringVolumeSrc = toVolumeSource(AUDIO_STREAM_RING);
const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC);
const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM);
+ const auto a11yVolumeSrc = toVolumeSource(AUDIO_STREAM_ACCESSIBILITY);
- if (volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY)
+ if (volumeSource == a11yVolumeSrc
&& (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) &&
mOutputs.isActive(ringVolumeSrc, 0)) {
auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING);
@@ -5712,7 +5713,7 @@
volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION) ||
volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
volumeSource == toVolumeSource(AUDIO_STREAM_DTMF) ||
- volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY))) {
+ volumeSource == a11yVolumeSrc)) {
auto &voiceCurves = getVolumeCurves(callVolumeSrc);
int voiceVolumeIndex = voiceCurves.getVolumeIndex(device);
const float maxVoiceVolDb =
@@ -5724,7 +5725,9 @@
// VOICE_CALL stream has minVolumeIndex > 0 : Users cannot set the volume of voice calls to
// 0. We don't want to cap volume when the system has programmatically muted the voice call
// stream. See setVolumeCurveIndex() for more information.
- bool exemptFromCapping = (volumeSource == ringVolumeSrc) && (voiceVolumeIndex == 0);
+ bool exemptFromCapping =
+ ((volumeSource == ringVolumeSrc) || (volumeSource == a11yVolumeSrc))
+ && (voiceVolumeIndex == 0);
ALOGV_IF(exemptFromCapping, "%s volume source %d at vol=%f not capped", __func__,
volumeSource, volumeDb);
if ((volumeDb > maxVoiceVolDb) && !exemptFromCapping) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index d88d1ec..5f651cc 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -307,6 +307,8 @@
return volumeGroup != VOLUME_GROUP_NONE ? NO_ERROR : BAD_VALUE;
}
+ status_t initialize();
+
protected:
// A constructor that allows more fine-grained control over initialization process,
// used in automatic tests.
@@ -321,7 +323,6 @@
// - initialize.
AudioPolicyConfig& getConfig() { return mConfig; }
void loadConfig();
- status_t initialize();
// From AudioPolicyManagerObserver
virtual const AudioPatchCollection &getAudioPatches() const
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 85ea94f..62010e1 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -458,16 +458,20 @@
continue;
}
+ bool isAssistant = mUidPolicy->isAssistantUid(current->uid);
if (appState == APP_STATE_TOP) {
if (current->startTimeNs > topStartNs) {
topActive = current;
topStartNs = current->startTimeNs;
}
- if (mUidPolicy->isAssistantUid(current->uid)) {
+ if (isAssistant) {
isAssistantOnTop = true;
}
}
- if (current->startTimeNs > latestStartNs) {
+ // Assistant capturing for HOTWORD not considered for latest active to avoid
+ // masking regular clients started before
+ if (current->startTimeNs > latestStartNs &&
+ !(current->attributes.source == AUDIO_SOURCE_HOTWORD && isAssistant)) {
latestActive = current;
latestStartNs = current->startTimeNs;
}
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 655f017..1b7a20c 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -43,7 +43,7 @@
],
shared_libs: [
- "libaaudio",
+ "libaaudio_internal",
"libaudioclient",
"libaudioflinger",
"libbase",