Merge "Camera: Extend HEIC output support" into main
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index b0512ff..4e36e01 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -205,6 +205,7 @@
flag {
namespace: "camera_platform"
+ is_exported: true
name: "color_temperature"
description: "Add keys to manually set color temperature and color tint"
bug: "359409044"
diff --git a/media/audio/aconfig/audio.aconfig b/media/audio/aconfig/audio.aconfig
index c732708..97a3edf 100644
--- a/media/audio/aconfig/audio.aconfig
+++ b/media/audio/aconfig/audio.aconfig
@@ -35,6 +35,13 @@
}
flag {
+ name: "audio_eraser_effect"
+ namespace: "media_audio"
+ description: "Enable audio eraser effect"
+ bug: "367667349"
+}
+
+flag {
name: "bluetooth_mac_address_anonymization"
namespace: "media_audio"
description:
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 1b506e9..95a8a69 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -1802,6 +1802,8 @@
return AUDIO_USAGE_VEHICLE_STATUS;
case AudioUsage::ANNOUNCEMENT:
return AUDIO_USAGE_ANNOUNCEMENT;
+ case AudioUsage::SPEAKER_CLEANUP:
+ return AUDIO_USAGE_SPEAKER_CLEANUP;
}
return unexpected(BAD_VALUE);
}
@@ -1853,6 +1855,8 @@
return AudioUsage::VEHICLE_STATUS;
case AUDIO_USAGE_ANNOUNCEMENT:
return AudioUsage::ANNOUNCEMENT;
+ case AUDIO_USAGE_SPEAKER_CLEANUP:
+ return AudioUsage::SPEAKER_CLEANUP;
}
return unexpected(BAD_VALUE);
}
@@ -2348,6 +2352,15 @@
audio_port_config_device_ext legacy{};
RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
aidl.device, &legacy.type, legacy.address));
+ const bool isInput = false; // speaker_layout_channel_mask only represents output.
+ if (aidl.speakerLayout.has_value()) {
+ legacy.speaker_layout_channel_mask =
+ VALUE_OR_RETURN(aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ aidl.speakerLayout.value(), isInput));
+ } else {
+ // Default to none when the field is null in the AIDL.
+ legacy.speaker_layout_channel_mask = AUDIO_CHANNEL_NONE;
+ }
return legacy;
}
@@ -2356,6 +2369,14 @@
AudioPortDeviceExt aidl;
aidl.device = VALUE_OR_RETURN(
legacy2aidl_audio_device_AudioDevice(legacy.type, legacy.address));
+ const bool isInput = false; // speaker_layout_channel_mask only represents output.
+ // The AIDL speakerLayout is nullable and if set, can only be a layoutMask.
+ if (audio_channel_mask_is_valid(legacy.speaker_layout_channel_mask) &&
+ audio_channel_mask_get_representation(legacy.speaker_layout_channel_mask) ==
+ AUDIO_CHANNEL_REPRESENTATION_POSITION) {
+ aidl.speakerLayout = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ legacy.speaker_layout_channel_mask, isInput));
+ }
return aidl;
}
diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 2076045..2cb5f09 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -689,6 +689,25 @@
AudioEncapsulationMetadataType::FRAMEWORK_TUNER,
AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR));
+TEST(AudioPortDeviceExt_speakerLayoutRoundTripTest, Aidl2Legacy2Aidl_layoutMask) {
+ AudioPortDeviceExt initial{};
+ initial.speakerLayout = make_ACL_Stereo();
+ auto conv = aidl2legacy_AudioPortDeviceExt_audio_port_config_device_ext(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_port_config_device_ext_AudioPortDeviceExt(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
+TEST(AudioPortDeviceExt_speakerLayoutRoundTripTest, Aidl2Legacy2Aidl_null) {
+ const AudioPortDeviceExt initial{}; // speakerLayout is null
+ auto conv = aidl2legacy_AudioPortDeviceExt_audio_port_config_device_ext(initial);
+ ASSERT_TRUE(conv.ok());
+ auto convBack = legacy2aidl_audio_port_config_device_ext_AudioPortDeviceExt(conv.value());
+ ASSERT_TRUE(convBack.ok());
+ EXPECT_EQ(initial, convBack.value());
+}
+
class AudioGainModeRoundTripTest : public testing::TestWithParam<AudioGainMode> {};
TEST_P(AudioGainModeRoundTripTest, Aidl2Legacy2Aidl) {
const auto initial = GetParam();
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 6727562..7964e6d 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -132,7 +132,7 @@
std::string toString(const DeviceIdSet& deviceIds) {
if (deviceIds.empty()) {
- return "Empty device ids";
+ return "AUDIO_PORT_HANDLE_NONE";
}
std::stringstream ss;
for (auto it = deviceIds.begin(); it != deviceIds.end(); ++it) {
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index 44b7d97..d791fab 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -55,8 +55,8 @@
defaults: ["libaudiopreprocessing-defaults"],
relative_install_path: "soundfx",
srcs: ["PreProcessing.cpp"],
- header_libs: [
- "libwebrtc_absl_headers",
+ static_libs: [
+ "libabsl",
],
}
@@ -77,6 +77,7 @@
"libutils",
],
static_libs: [
+ "libabsl",
"webrtc_audio_processing",
],
header_libs: [
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b3d9c5f5..1e233cf 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -55,6 +55,7 @@
#include <com_android_internal_camera_flags.h>
#include <com_android_media_editing_flags.h>
+namespace editing_flags = com::android::media::editing::flags;
#ifndef __predict_false
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
@@ -165,6 +166,7 @@
bool isAvc() const { return mIsAvc; }
bool isHevc() const { return mIsHevc; }
bool isAv1() const { return mIsAv1; }
+ bool isApv() const { return mIsApv; }
bool isHeic() const { return mIsHeic; }
bool isAvif() const { return mIsAvif; }
bool isHeif() const { return mIsHeif; }
@@ -339,6 +341,7 @@
bool mIsAvc;
bool mIsHevc;
bool mIsAv1;
+ bool mIsApv;
bool mIsDovi;
bool mIsAudio;
bool mIsVideo;
@@ -495,6 +498,7 @@
void writeAvccBox();
void writeHvccBox();
void writeAv1cBox();
+ void writeApvcBox();
void writeDoviConfigBox();
void writeUrlBox();
void writeDrefBox();
@@ -696,6 +700,9 @@
return "hvc1";
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AV1, mime)) {
return "av01";
+ } else if (editing_flags::muxer_mp4_enable_apv() &&
+ !strcasecmp(MEDIA_MIMETYPE_VIDEO_APV, mime)) {
+ return "apv1";
}
} else if (!strncasecmp(mime, "application/", 12)) {
return "mett";
@@ -2289,6 +2296,7 @@
mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
mIsHevc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
mIsAv1 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1);
+ mIsApv = editing_flags::muxer_mp4_enable_apv() && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_APV);
mIsDovi = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
mIsAudio = !strncasecmp(mime, "audio/", 6);
mIsVideo = !strncasecmp(mime, "video/", 6);
@@ -2854,6 +2862,9 @@
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1) ||
!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF)) {
mMeta->findData(kKeyAV1C, &type, &data, &size);
+ } else if (editing_flags::muxer_mp4_enable_apv() &&
+ !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_APV)) {
+ mMeta->findData(kKeyAPVC, &type, &data, &size);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
getDolbyVisionProfile();
if (!mMeta->findData(kKeyAVCC, &type, &data, &size) &&
@@ -3755,7 +3766,7 @@
(const uint8_t *)buffer->data()
+ buffer->range_offset(),
buffer->range_length());
- } else if (mIsMPEG4 || mIsAv1) {
+ } else if (mIsMPEG4 || mIsAv1 || mIsApv) {
err = copyCodecSpecificData((const uint8_t *)buffer->data() + buffer->range_offset(),
buffer->range_length());
}
@@ -4548,6 +4559,7 @@
!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime) ||
!strcasecmp(MEDIA_MIMETYPE_VIDEO_AV1, mime) ||
+ (editing_flags::muxer_mp4_enable_apv() && !strcasecmp(MEDIA_MIMETYPE_VIDEO_APV, mime)) ||
!strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime) ||
!strcasecmp(MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, mime) ||
!strcasecmp(MEDIA_MIMETYPE_IMAGE_AVIF, mime)) {
@@ -4722,6 +4734,9 @@
writeHvccBox();
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AV1, mime)) {
writeAv1cBox();
+ } else if (editing_flags::muxer_mp4_enable_apv() &&
+ !strcasecmp(MEDIA_MIMETYPE_VIDEO_APV, mime)) {
+ writeApvcBox();
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, mime)) {
if (mDoviProfile <= DolbyVisionProfileDvheSt) {
writeHvccBox();
@@ -5313,6 +5328,15 @@
mOwner->endBox(); // av1C
}
+void MPEG4Writer::Track::writeApvcBox() {
+ CHECK(mCodecSpecificData);
+ CHECK_GE(mCodecSpecificDataSize, 4u);
+
+ mOwner->beginBox("apvC");
+ mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
+ mOwner->endBox(); // apvC
+}
+
void MPEG4Writer::Track::writeDoviConfigBox() {
CHECK_NE(mDoviProfile, 0u);
diff --git a/media/libstagefright/include/media/stagefright/MetaDataBase.h b/media/libstagefright/include/media/stagefright/MetaDataBase.h
index a7d2eb9..9dce55b 100644
--- a/media/libstagefright/include/media/stagefright/MetaDataBase.h
+++ b/media/libstagefright/include/media/stagefright/MetaDataBase.h
@@ -63,6 +63,7 @@
kKeyDVVC = 'dvvc', // raw data
kKeyDVWC = 'dvwc', // raw data
kKeyAV1C = 'av1c', // raw data
+ kKeyAPVC = 'apvc', // raw data
kKeyThumbnailHVCC = 'thvc', // raw data
kKeyThumbnailAV1C = 'tav1', // raw data
kKeyD263 = 'd263', // raw data
diff --git a/media/module/codecs/amrnb/common/Android.bp b/media/module/codecs/amrnb/common/Android.bp
index 0bc6ed2..35937cb 100644
--- a/media/module/codecs/amrnb/common/Android.bp
+++ b/media/module/codecs/amrnb/common/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_media_codec_framework",
default_applicable_licenses: [
"frameworks_av_media_codecs_amrnb_common_license",
],
@@ -42,8 +43,8 @@
"src/gains_tbl.cpp",
"src/gc_pred.cpp",
"src/gmed_n.cpp",
- "src/grid_tbl.cpp",
"src/gray_tbl.cpp",
+ "src/grid_tbl.cpp",
"src/int_lpc.cpp",
"src/inv_sqrt.cpp",
"src/inv_sqrt_tbl.cpp",
@@ -91,9 +92,9 @@
export_include_dirs: ["include"],
cflags: [
- "-DOSCL_UNUSED_ARG(x)=(void)(x)",
- "-DOSCL_IMPORT_REF=",
"-DOSCL_EXPORT_REF=",
+ "-DOSCL_IMPORT_REF=",
+ "-DOSCL_UNUSED_ARG(x)=(void)(x)",
"-Werror",
],
diff --git a/media/module/codecs/amrnb/dec/Android.bp b/media/module/codecs/amrnb/dec/Android.bp
index 70741d2..a28500a 100644
--- a/media/module/codecs/amrnb/dec/Android.bp
+++ b/media/module/codecs/amrnb/dec/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_media_codec_framework",
default_applicable_licenses: [
"frameworks_av_media_codecs_amrnb_dec_license",
],
@@ -47,12 +48,12 @@
"src/b_cn_cod.cpp",
"src/bgnscd.cpp",
"src/c_g_aver.cpp",
- "src/d1035pf.cpp",
- "src/d2_11pf.cpp",
"src/d2_9pf.cpp",
+ "src/d2_11pf.cpp",
"src/d3_14pf.cpp",
"src/d4_17pf.cpp",
"src/d8_31pf.cpp",
+ "src/d1035pf.cpp",
"src/d_gain_c.cpp",
"src/d_gain_p.cpp",
"src/d_plsf.cpp",
@@ -81,8 +82,8 @@
export_include_dirs: ["src"],
cflags: [
- "-DOSCL_UNUSED_ARG(x)=(void)(x)",
"-DOSCL_IMPORT_REF=",
+ "-DOSCL_UNUSED_ARG(x)=(void)(x)",
"-Werror",
],
@@ -94,8 +95,8 @@
//},
shared_libs: [
- "libstagefright_amrnb_common",
"liblog",
+ "libstagefright_amrnb_common",
],
target: {
@@ -113,19 +114,22 @@
srcs: ["test/amrnbdec_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
local_include_dirs: ["src"],
static_libs: [
- "libstagefright_amrnbdec",
"libsndfile",
+ "libstagefright_amrnbdec",
],
shared_libs: [
- "libstagefright_amrnb_common",
"libaudioutils",
"liblog",
+ "libstagefright_amrnb_common",
],
target: {
diff --git a/media/module/codecs/amrnb/enc/Android.bp b/media/module/codecs/amrnb/enc/Android.bp
index 3c6566e..13bb29c 100644
--- a/media/module/codecs/amrnb/enc/Android.bp
+++ b/media/module/codecs/amrnb/enc/Android.bp
@@ -1,4 +1,5 @@
package {
+ default_team: "trendy_team_media_codec_framework",
default_applicable_licenses: [
"frameworks_av_media_codecs_amrnb_enc_license",
],
@@ -42,12 +43,12 @@
srcs: [
"src/amrencode.cpp",
"src/autocorr.cpp",
- "src/c1035pf.cpp",
- "src/c2_11pf.cpp",
"src/c2_9pf.cpp",
+ "src/c2_11pf.cpp",
"src/c3_14pf.cpp",
"src/c4_17pf.cpp",
"src/c8_31pf.cpp",
+ "src/c1035pf.cpp",
"src/calc_cor.cpp",
"src/calc_en.cpp",
"src/cbsearch.cpp",
@@ -132,7 +133,10 @@
srcs: ["test/amrnb_enc_test.cpp"],
- cflags: ["-Wall", "-Werror"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
local_include_dirs: ["src"],
diff --git a/media/module/codecs/amrnb/enc/fuzzer/Android.bp b/media/module/codecs/amrnb/enc/fuzzer/Android.bp
index bcbcee2..1b2ec87 100644
--- a/media/module/codecs/amrnb/enc/fuzzer/Android.bp
+++ b/media/module/codecs/amrnb/enc/fuzzer/Android.bp
@@ -19,6 +19,7 @@
*/
package {
+ default_team: "trendy_team_media_codec_framework",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_av_media_codecs_amrnb_enc_license"
@@ -39,8 +40,8 @@
static_libs: [
"liblog",
- "libstagefright_amrnbenc",
"libstagefright_amrnb_common",
+ "libstagefright_amrnbenc",
],
fuzz_config: {
diff --git a/media/module/codecs/amrnb/fuzzer/Android.bp b/media/module/codecs/amrnb/fuzzer/Android.bp
index 3f29267..c5cbbe2 100644
--- a/media/module/codecs/amrnb/fuzzer/Android.bp
+++ b/media/module/codecs/amrnb/fuzzer/Android.bp
@@ -19,6 +19,7 @@
*/
package {
+ default_team: "trendy_team_media_codec_framework",
// 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"
@@ -34,9 +35,9 @@
"amrnb_dec_fuzzer.cpp",
],
static_libs: [
- "libstagefright_amrnbdec",
- "libstagefright_amrnb_common",
"liblog",
+ "libstagefright_amrnb_common",
+ "libstagefright_amrnbdec",
],
target: {
darwin: {
diff --git a/media/module/extractors/Android.bp b/media/module/extractors/Android.bp
index e29d3e6..cbaabe3 100644
--- a/media/module/extractors/Android.bp
+++ b/media/module/extractors/Android.bp
@@ -81,6 +81,12 @@
srcs: ["extractor.aconfig"],
}
+java_aconfig_library {
+ name: "android.media.extractor.flags-aconfig-java",
+ aconfig_declarations: "android.media.extractor.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
cc_aconfig_library {
name: "android.media.extractor.flags-aconfig-cc",
aconfig_declarations: "android.media.extractor.flags-aconfig",
diff --git a/media/module/extractors/extractor.aconfig b/media/module/extractors/extractor.aconfig
index c9bf694..a7d3397 100644
--- a/media/module/extractors/extractor.aconfig
+++ b/media/module/extractors/extractor.aconfig
@@ -8,7 +8,16 @@
name: "extractor_sniff_midi_optimizations"
is_exported: true
is_fixed_read_only: true
- namespace: "media_extractor"
+ namespace: "media_solutions"
description: "Enable SniffMidi optimizations."
bug: "359920208"
}
+
+flag {
+ name: "extractor_mp4_enable_apv"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "media_solutions"
+ description: "Enable APV support in mp4 extractor."
+ bug: "370061501"
+}
diff --git a/media/module/extractors/fuzzers/Android.bp b/media/module/extractors/fuzzers/Android.bp
index 3da1589..f3da389 100644
--- a/media/module/extractors/fuzzers/Android.bp
+++ b/media/module/extractors/fuzzers/Android.bp
@@ -129,12 +129,18 @@
],
static_libs: [
+ "android.media.extractor.flags-aconfig-cc",
+ "libaconfig_storage_read_api_cc",
"libstagefright_id3",
"libstagefright_esds",
"libmp4extractor",
"libstagefright_metadatautils",
],
+ shared_libs: [
+ "server_configurable_flags",
+ ],
+
dictionary: "mp4_extractor_fuzzer.dict",
corpus: ["corpus_mp4/*"],
diff --git a/media/module/extractors/mp4/Android.bp b/media/module/extractors/mp4/Android.bp
index 8072002..effd24a 100644
--- a/media/module/extractors/mp4/Android.bp
+++ b/media/module/extractors/mp4/Android.bp
@@ -42,12 +42,18 @@
],
static_libs: [
+ "android.media.extractor.flags-aconfig-cc",
+ "libaconfig_storage_read_api_cc",
"libstagefright_esds",
"libstagefright_foundation",
"libstagefright_id3",
"libutils",
],
+ shared_libs: [
+ "server_configurable_flags",
+ ],
+
host_supported: true,
target: {
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index 12c0aaf..f062491 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -33,6 +33,7 @@
#include "SampleTable.h"
#include "ItemTable.h"
+#include <com_android_media_extractor_flags.h>
#include <media/esds/ESDS.h>
#include <ID3.h>
#include <media/stagefright/DataSourceBase.h>
@@ -147,6 +148,7 @@
bool mIsAVC;
bool mIsHEVC;
+ bool mIsAPV;
bool mIsDolbyVision;
bool mIsAC4;
bool mIsMpegH = false;
@@ -366,6 +368,13 @@
case FOURCC("hev1"):
return MEDIA_MIMETYPE_VIDEO_HEVC;
+ case FOURCC("apv1"):
+ if (!com::android::media::extractor::flags::extractor_mp4_enable_apv()) {
+ ALOGV("APV support not enabled");
+ return "application/octet-stream";
+ }
+ return MEDIA_MIMETYPE_VIDEO_APV;
+
case FOURCC("dvav"):
case FOURCC("dva1"):
case FOURCC("dvhe"):
@@ -2106,6 +2115,7 @@
case FOURCC("dav1"):
case FOURCC("av01"):
case FOURCC("vp09"):
+ case FOURCC("apv1"):
{
uint8_t buffer[78];
if (chunk_data_size < (ssize_t)sizeof(buffer)) {
@@ -2623,8 +2633,16 @@
break;
}
+ case FOURCC("apvC"):
case FOURCC("av1C"):
{
+ if (!com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
+ chunk_type == FOURCC("apvC")) {
+ ALOGV("APV support not enabled");
+ *offset += chunk_size;
+ break;
+ }
+
auto buffer = heapbuffer<uint8_t>(chunk_data_size);
if (buffer.get() == NULL) {
@@ -5145,6 +5163,7 @@
mCurrentSampleInfoOffsets(NULL),
mIsAVC(false),
mIsHEVC(false),
+ mIsAPV(false),
mIsDolbyVision(false),
mIsAC4(false),
mIsPcm(false),
@@ -5187,6 +5206,8 @@
mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC) ||
!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
+ mIsAPV = com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
+ !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_APV);
mIsAC4 = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC4);
mIsDolbyVision = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
mIsHeif = !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) && mItemTable != NULL;
diff --git a/media/module/extractors/tests/Android.bp b/media/module/extractors/tests/Android.bp
index d6e79c7..5f0f4fa 100644
--- a/media/module/extractors/tests/Android.bp
+++ b/media/module/extractors/tests/Android.bp
@@ -21,6 +21,7 @@
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_av_license"],
+ default_team: "trendy_team_android_media_solutions_playback",
}
cc_test {
@@ -31,6 +32,8 @@
srcs: ["ExtractorUnitTest.cpp"],
static_libs: [
+ "android.media.extractor.flags-aconfig-cc",
+ "libaconfig_storage_read_api_cc",
"libaacextractor",
"libamrextractor",
"libmp3extractor",
@@ -77,6 +80,7 @@
"libhidlmemory",
"libhidlbase",
"libbase",
+ "server_configurable_flags",
],
compile_multilib: "first",
diff --git a/media/mtp/OWNERS b/media/mtp/OWNERS
index 6b5336e..bdb6cdb 100644
--- a/media/mtp/OWNERS
+++ b/media/mtp/OWNERS
@@ -1,10 +1,9 @@
set noparent
-aprasath@google.com
anothermark@google.com
-kumarashishg@google.com
-sarup@google.com
+febinthattil@google.com
+aprasath@google.com
jsharkey@android.com
jameswei@google.com
rmojumder@google.com
-
+kumarashishg@google.com
\ No newline at end of file
diff --git a/media/utils/include/mediautils/SharedMemoryAllocator.h b/media/utils/include/mediautils/SharedMemoryAllocator.h
index 4243b9c..7d4f62e 100644
--- a/media/utils/include/mediautils/SharedMemoryAllocator.h
+++ b/media/utils/include/mediautils/SharedMemoryAllocator.h
@@ -28,6 +28,7 @@
#include <type_traits>
#include <unordered_map>
+#include <android-base/thread_annotations.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <log/log_main.h>
@@ -425,8 +426,57 @@
[[no_unique_address]] SecondaryAllocator mSecondary;
};
+// Wrap an allocator with a lock if backs multiple allocators through indirection
+template <typename Allocator>
+class LockedAllocator {
+ public:
+ static size_t alignment() { return Allocator::alignment(); }
+
+ explicit LockedAllocator(Allocator allocator) : mAllocator(allocator) {}
+
+ LockedAllocator() = default;
+
+ template <typename T>
+ AllocationType allocate(T&& request) {
+ static_assert(std::is_base_of_v<android::mediautils::BasicAllocRequest, std::decay_t<T>>);
+ std::lock_guard l_{mMutex};
+ return mAllocator.allocate(std::forward<T>(request));
+ }
+
+ void deallocate(const AllocationType& allocation) {
+ std::lock_guard l_{mMutex};
+ mAllocator.deallocate(allocation);
+ }
+
+ template <typename Enable = void>
+ auto deallocate_all()
+ -> std::enable_if_t<shared_allocator_impl::has_deallocate_all<Allocator>, Enable> {
+ std::lock_guard l_{mMutex};
+ mAllocator.deallocate_all();
+ }
+
+ template <typename Enable = bool>
+ auto owns(const AllocationType& allocation) const
+ -> std::enable_if_t<shared_allocator_impl::has_owns<Allocator>, Enable> {
+ std::lock_guard l_{mMutex};
+ return mAllocator.owns(allocation);
+ }
+
+ template <typename Enable = std::string>
+ auto dump() const -> std::enable_if_t<shared_allocator_impl::has_dump<Allocator>, Enable> {
+ std::lock_guard l_{mMutex};
+ return mAllocator.dump();
+ }
+
+ private:
+ std::mutex mMutex;
+ [[no_unique_address]] Allocator mAllocator GUARDED_BY(mMutex);
+};
+
// An allocator which is backed by a shared_ptr to an allocator, so multiple
// allocators can share the same backing allocator (and thus the same state).
+// When the same backing allocator is used by multiple higher level allocators,
+// locking at the sharing level is necessary.
template <typename Allocator>
class IndirectAllocator {
public:
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 060c72b..91c82a2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -338,28 +338,32 @@
// under #ifdef __cplusplus #endif
static std::string patchSinksToString(const struct audio_patch *patch)
{
- std::stringstream ss;
+ std::string s;
for (size_t i = 0; i < patch->num_sinks; ++i) {
- if (i > 0) {
- ss << "|";
+ if (i > 0) s.append("|");
+ if (patch->sinks[i].ext.device.address[0]) {
+ s.append("(").append(toString(patch->sinks[i].ext.device.type))
+ .append(", ").append(patch->sinks[i].ext.device.address).append(")");
+ } else {
+ s.append(toString(patch->sinks[i].ext.device.type));
}
- ss << "(" << toString(patch->sinks[i].ext.device.type)
- << ", " << patch->sinks[i].ext.device.address << ")";
}
- return ss.str();
+ return s;
}
static std::string patchSourcesToString(const struct audio_patch *patch)
{
- std::stringstream ss;
+ std::string s;
for (size_t i = 0; i < patch->num_sources; ++i) {
- if (i > 0) {
- ss << "|";
+ if (i > 0) s.append("|");
+ if (patch->sources[i].ext.device.address[0]) {
+ s.append("(").append(toString(patch->sources[i].ext.device.type))
+ .append(", ").append(patch->sources[i].ext.device.address).append(")");
+ } else {
+ s.append(toString(patch->sources[i].ext.device.type));
}
- ss << "(" << toString(patch->sources[i].ext.device.type)
- << ", " << patch->sources[i].ext.device.address << ")";
}
- return ss.str();
+ return s;
}
static std::string toString(audio_latency_mode_t mode) {
diff --git a/services/audioflinger/afutils/AllocatorFactory.h b/services/audioflinger/afutils/AllocatorFactory.h
index 7534607..4c290a0 100644
--- a/services/audioflinger/afutils/AllocatorFactory.h
+++ b/services/audioflinger/afutils/AllocatorFactory.h
@@ -33,25 +33,36 @@
constexpr inline size_t SHARED_SIZE_SMALL = SHARED_SIZE - SHARED_SIZE_LARGE; // 20 MiB
constexpr inline size_t SMALL_THRESHOLD = 1024 * 40; // 40 KiB
+template <typename Policy>
+inline auto getSharedPool() {
+ using namespace mediautils;
+ return std::make_shared<LockedAllocator<PolicyAllocator<MemoryHeapBaseAllocator, Policy>>>();
+}
+
+// The following pools are global but lazy initialized. Stored in shared_ptr since they are
+// referred by clients, but they could also be leaked.
+
+// Pool from which every client gets their dedicated, exclusive quota.
inline auto getDedicated() {
using namespace mediautils;
- static const auto allocator =
- std::make_shared<PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<DED_SIZE>>>();
+ static const auto allocator = getSharedPool<SizePolicy<DED_SIZE>>();
return allocator;
}
+// Pool from which clients with large allocation sizes can fall back to when their dedicated
+// allocation is surpassed. More likely to fill.
inline auto getSharedLarge() {
using namespace mediautils;
- static const auto allocator = std::make_shared<
- PolicyAllocator<MemoryHeapBaseAllocator, SizePolicy<SHARED_SIZE_LARGE>>>();
+ static const auto allocator = getSharedPool<SizePolicy<SHARED_SIZE_LARGE>>();
return allocator;
}
+// Pool from which clients with reasonable allocation sizes can fall back to when
+// their dedicated allocation is surpassed, so that small buffer clients are always served.
inline auto getSharedSmall() {
using namespace mediautils;
static const auto allocator =
- std::make_shared<PolicyAllocator<MemoryHeapBaseAllocator,
- SizePolicy<SHARED_SIZE_SMALL, 0, SMALL_THRESHOLD>>>();
+ getSharedPool<SizePolicy<SHARED_SIZE_SMALL, 0, SMALL_THRESHOLD>>();
return allocator;
}
@@ -78,8 +89,7 @@
getSharedLarge(), "Large Shared");
};
const auto makeSmallShared = []() {
- return wrapWithPolicySnooping<
- SizePolicy<SHARED_SIZE_SMALL / ADV_THRESHOLD_INV>>(
+ return wrapWithPolicySnooping<SizePolicy<SHARED_SIZE_SMALL / ADV_THRESHOLD_INV>>(
getSharedSmall(), "Small Shared");
};
diff --git a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
index c4bf64a..229c5e2 100644
--- a/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
+++ b/services/audiopolicy/engine/common/src/EngineDefaultConfig.h
@@ -131,6 +131,8 @@
{AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_BEACON, ""},
{AUDIO_CONTENT_TYPE_ULTRASOUND, AUDIO_USAGE_UNKNOWN, AUDIO_SOURCE_DEFAULT,
+ AUDIO_FLAG_NONE, ""},
+ {AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_SPEAKER_CLEANUP, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""}
}
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index f298541..8d7432d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -24,6 +24,7 @@
#include <android/content/AttributionSourceState.h>
#include <android_media_audiopolicy.h>
#include <com_android_media_audio.h>
+#include <cutils/properties.h>
#include <error/expected_utils.h>
#include <media/AidlConversion.h>
#include <media/AudioPolicy.h>
@@ -425,6 +426,17 @@
}
}
+ //TODO this permission check should extend to all system usages
+ if (attr.usage == AUDIO_USAGE_SPEAKER_CLEANUP) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_ROUTING, attributionSource.uid)
+ : modifyAudioRoutingAllowed())) {
+ ALOGE("%s: permission denied: SPEAKER_CLEANUP not allowed for uid %d pid %d",
+ __func__, attributionSource.uid, attributionSource.pid);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
+ }
+ }
+
AutoCallerClear acc;
AudioPolicyInterface::output_type_t outputType;
bool isSpatialized = false;
@@ -482,8 +494,11 @@
}
if (result == NO_ERROR) {
- attr = VALUE_OR_RETURN_BINDER_STATUS(
- mUsecaseValidator->verifyAudioAttributes(output, attributionSource, attr));
+ // usecase validator is disabled by default
+ if (property_get_bool("ro.audio.usecase_validator_enabled", false /* default */)) {
+ attr = VALUE_OR_RETURN_BINDER_STATUS(
+ mUsecaseValidator->verifyAudioAttributes(output, attributionSource, attr));
+ }
sp<AudioPlaybackClient> client =
new AudioPlaybackClient(attr, output, attributionSource, session,
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 6da1606..f59ad18 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2254,9 +2254,12 @@
int callingPid = getCallingPid();
int callingUid = getCallingUid();
bool systemNativeClient = false;
+ AttributionSourceState resolvedClientAttribution(clientAttribution);
if (callerHasSystemUid() && (clientPackageNameMaybe.size() == 0)) {
std::string systemClient = fmt::sprintf("client.pid<%d>", callingPid);
clientPackageNameMaybe = systemClient;
+ // Pass in packageName since AttributionAndPermissionUtils can't resolve vndk clients.
+ resolvedClientAttribution.packageName = clientPackageNameMaybe;
systemNativeClient = true;
}
@@ -2272,10 +2275,10 @@
bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
- AttributionSourceState resolvedClientAttribution(clientAttribution);
if (!flags::use_context_attribution_source()) {
resolvedClientAttribution.pid = USE_CALLING_PID;
}
+
ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraId);
if (!ret.isOk()) {
logRejected(cameraId, getCallingPid(), clientAttribution.packageName.value_or(""),
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 3361eaa..8b2804d 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -263,8 +263,20 @@
binder::Status resolveAttributionSource(AttributionSourceState& resolvedAttributionSource,
const std::string& methodName,
const std::optional<std::string>& cameraIdMaybe) {
- return mAttributionAndPermissionUtils->resolveAttributionSource(resolvedAttributionSource,
- methodName, cameraIdMaybe);
+ std::string passedPackageName;
+ if (resolvedAttributionSource.packageName.has_value()) {
+ passedPackageName = resolvedAttributionSource.packageName.value();
+ }
+ auto ret = mAttributionAndPermissionUtils->resolveAttributionSource(
+ resolvedAttributionSource, methodName, cameraIdMaybe);
+ if (!ret.isOk()) {
+ return ret;
+ }
+ // Fix up package name
+ if (passedPackageName.size() != 0) {
+ resolvedAttributionSource.packageName = std::move(passedPackageName);
+ }
+ return ret;
}
// The word 'System' here does not refer to callers only on the system
diff --git a/services/mediametrics/StringUtils.cpp b/services/mediametrics/StringUtils.cpp
index 5766f1c..3b2db85 100644
--- a/services/mediametrics/StringUtils.cpp
+++ b/services/mediametrics/StringUtils.cpp
@@ -80,33 +80,40 @@
{
std::vector<std::pair<std::string, std::string>> result;
- // Currently, the device format is EXACTLY
- // (device1, addr1)|(device2, addr2)|...
+ // Currently, the device format is
+ //
+ // devices = device_addr OR device_addr|devices
+ // device_addr = device OR (device, addr)
+ //
+ // EXAMPLE:
+ // device1|(device2, addr2)|...
static constexpr char delim[] = "()|,";
for (auto it = devices.begin(); ; ) {
- auto token = tokenizer(it, devices.end(), delim);
- if (token != "(") return result;
+ std::string address;
+ std::string device = tokenizer(it, devices.end(), delim);
+ if (device.empty()) return result;
+ if (device == "(") { // it is a pair otherwise we consider it a device
+ device = tokenizer(it, devices.end(), delim); // get actual device
+ auto token = tokenizer(it, devices.end(), delim);
+ if (token != ",") return result; // malformed, must have a comma
- auto device = tokenizer(it, devices.end(), delim);
- if (device.empty() || !std::isalnum(device[0])) return result;
-
- token = tokenizer(it, devices.end(), delim);
- if (token != ",") return result;
-
- // special handling here for empty addresses
- auto address = tokenizer(it, devices.end(), delim);
- if (address.empty() || !std::isalnum(device[0])) return result;
- if (address == ")") { // no address, just the ")"
- address.clear();
- } else {
- token = tokenizer(it, devices.end(), delim);
- if (token != ")") return result;
+ // special handling here for empty addresses
+ address = tokenizer(it, devices.end(), delim);
+ if (address.empty()) return result;
+ if (address == ")") { // no address, just the ")"
+ address.clear();
+ } else {
+ token = tokenizer(it, devices.end(), delim);
+ if (token != ")") return result;
+ }
}
+ // misaligned token, device must start alphanumeric.
+ if (!std::isalnum(device[0])) return result;
result.emplace_back(std::move(device), std::move(address));
- token = tokenizer(it, devices.end(), delim);
+ auto token = tokenizer(it, devices.end(), delim);
if (token != "|") return result; // this includes end of string detection
}
}
diff --git a/services/mediametrics/tests/mediametrics_tests.cpp b/services/mediametrics/tests/mediametrics_tests.cpp
index a7684f4..f3933a7 100644
--- a/services/mediametrics/tests/mediametrics_tests.cpp
+++ b/services/mediametrics/tests/mediametrics_tests.cpp
@@ -963,6 +963,31 @@
ASSERT_EQ("B", devaddr[0].second);
ASSERT_EQ("C", devaddr[1].first);
ASSERT_EQ("D2", devaddr[1].second);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " Z ");
+ ASSERT_EQ((size_t)1, devaddr.size());
+ ASSERT_EQ("Z", devaddr[0].first);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " A | B|C ");
+ ASSERT_EQ((size_t)3, devaddr.size());
+ ASSERT_EQ("A", devaddr[0].first);
+ ASSERT_EQ("", devaddr[0].second);
+ ASSERT_EQ("B", devaddr[1].first);
+ ASSERT_EQ("", devaddr[1].second);
+ ASSERT_EQ("C", devaddr[2].first);
+ ASSERT_EQ("", devaddr[2].second);
+
+ devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
+ " A | (B1, 10) |C ");
+ ASSERT_EQ((size_t)3, devaddr.size());
+ ASSERT_EQ("A", devaddr[0].first);
+ ASSERT_EQ("", devaddr[0].second);
+ ASSERT_EQ("B1", devaddr[1].first);
+ ASSERT_EQ("10", devaddr[1].second);
+ ASSERT_EQ("C", devaddr[2].first);
+ ASSERT_EQ("", devaddr[2].second);
}
TEST(mediametrics_tests, timed_action) {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index d663f37..a864c7a 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -422,9 +422,17 @@
return AAUDIO_ERROR_NULL;
}
struct audio_mmap_position position;
- const status_t status = mMmapStream->getMmapPosition(&position);
+ status_t status = mMmapStream->getMmapPosition(&position);
ALOGV("%s() status= %d, pos = %d, nanos = %lld\n",
__func__, status, position.position_frames, (long long) position.time_nanoseconds);
+ if (status == INVALID_OPERATION) {
+ // The HAL can return INVALID_OPERATION when the position is UNKNOWN.
+ // That can cause SHARED MMAP to break. So coerce it to NOT_ENOUGH_DATA.
+ // That will get converted to AAUDIO_ERROR_UNAVAILABLE.
+ ALOGW("%s(): change INVALID_OPERATION to NOT_ENOUGH_DATA", __func__);
+ status = NOT_ENOUGH_DATA; // see b/376467258
+ }
+
const aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
if (result == AAUDIO_ERROR_UNAVAILABLE) {
ALOGW("%s(): getMmapPosition() has no position data available", __func__);